]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
dpaa2-switch: create a central dpaa2_switch_acl_tbl structure
authorIoana Ciornei <ioana.ciornei@nxp.com>
Tue, 13 Apr 2021 13:24:44 +0000 (16:24 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 13 Apr 2021 22:12:18 +0000 (15:12 -0700)
Introduce a new structure - dpaa2_switch_acl_tbl - to hold all data
related to an ACL table: number of rules added, ACL table id, etc.
This will be used more in the next patches when adding support for
sharing an ACL table between ports.

Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h

index 80efc81169636ac8c66ecc088856236004df1819..351ee8f7461c08edbf3c038dc32d6dada54818f7 100644 (file)
@@ -40,6 +40,17 @@ static struct dpaa2_switch_fdb *dpaa2_switch_fdb_get_unused(struct ethsw_core *e
        return NULL;
 }
 
+static struct dpaa2_switch_acl_tbl *
+dpaa2_switch_acl_tbl_get_unused(struct ethsw_core *ethsw)
+{
+       int i;
+
+       for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
+               if (!ethsw->acls[i].in_use)
+                       return &ethsw->acls[i];
+       return NULL;
+}
+
 static u16 dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv,
                                     struct net_device *bridge_dev)
 {
@@ -2689,7 +2700,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv,
        acl_h = &acl_key.match;
        acl_m = &acl_key.mask;
 
-       if (port_priv->acl_num_rules >= DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) {
+       if (port_priv->acl_tbl->num_rules >= DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) {
                netdev_err(netdev, "ACL full\n");
                return -ENOMEM;
        }
@@ -2707,7 +2718,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv,
        dpsw_acl_prepare_entry_cfg(&acl_key, cmd_buff);
 
        memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg));
-       acl_entry_cfg.precedence = port_priv->acl_num_rules;
+       acl_entry_cfg.precedence = port_priv->acl_tbl->num_rules;
        acl_entry_cfg.result.action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF;
        acl_entry_cfg.key_iova = dma_map_single(dev, cmd_buff,
                                                DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE,
@@ -2719,7 +2730,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv,
 
        err = dpsw_acl_add_entry(port_priv->ethsw_data->mc_io, 0,
                                 port_priv->ethsw_data->dpsw_handle,
-                                port_priv->acl_tbl, &acl_entry_cfg);
+                                port_priv->acl_tbl->id, &acl_entry_cfg);
 
        dma_unmap_single(dev, acl_entry_cfg.key_iova, sizeof(cmd_buff),
                         DMA_TO_DEVICE);
@@ -2728,7 +2739,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv,
                return err;
        }
 
-       port_priv->acl_num_rules++;
+       port_priv->acl_tbl->num_rules++;
 
        return 0;
 }
@@ -2743,12 +2754,13 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port)
        };
        struct net_device *netdev = port_priv->netdev;
        struct ethsw_core *ethsw = port_priv->ethsw_data;
+       struct dpaa2_switch_acl_tbl *acl_tbl;
        struct dpsw_fdb_cfg fdb_cfg = {0};
        struct dpsw_acl_if_cfg acl_if_cfg;
        struct dpsw_if_attr dpsw_if_attr;
        struct dpaa2_switch_fdb *fdb;
        struct dpsw_acl_cfg acl_cfg;
-       u16 fdb_id;
+       u16 fdb_id, acl_tbl_id;
        int err;
 
        /* Get the Tx queue for this specific port */
@@ -2792,7 +2804,7 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port)
        /* Create an ACL table to be used by this switch port */
        acl_cfg.max_entries = DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES;
        err = dpsw_acl_add(ethsw->mc_io, 0, ethsw->dpsw_handle,
-                          &port_priv->acl_tbl, &acl_cfg);
+                          &acl_tbl_id, &acl_cfg);
        if (err) {
                netdev_err(netdev, "dpsw_acl_add err %d\n", err);
                return err;
@@ -2801,13 +2813,19 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port)
        acl_if_cfg.if_id[0] = port_priv->idx;
        acl_if_cfg.num_ifs = 1;
        err = dpsw_acl_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle,
-                             port_priv->acl_tbl, &acl_if_cfg);
+                             acl_tbl_id, &acl_if_cfg);
        if (err) {
                netdev_err(netdev, "dpsw_acl_add_if err %d\n", err);
                dpsw_acl_remove(ethsw->mc_io, 0, ethsw->dpsw_handle,
-                               port_priv->acl_tbl);
+                               acl_tbl_id);
        }
 
+       acl_tbl = dpaa2_switch_acl_tbl_get_unused(ethsw);
+       acl_tbl->id = acl_tbl_id;
+       acl_tbl->in_use = true;
+       acl_tbl->num_rules = 0;
+       port_priv->acl_tbl = acl_tbl;
+
        err = dpaa2_switch_port_trap_mac_addr(port_priv, stpa);
        if (err)
                return err;
@@ -2858,6 +2876,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev)
        }
 
        kfree(ethsw->fdbs);
+       kfree(ethsw->acls);
        kfree(ethsw->ports);
 
        dpaa2_switch_takedown(sw_dev);
@@ -2983,6 +3002,13 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev)
                goto err_free_ports;
        }
 
+       ethsw->acls = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->acls),
+                             GFP_KERNEL);
+       if (!ethsw->acls) {
+               err = -ENOMEM;
+               goto err_free_fdbs;
+       }
+
        for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
                err = dpaa2_switch_probe_port(ethsw, i);
                if (err)
@@ -3031,6 +3057,8 @@ err_stop:
 err_free_netdev:
        for (i--; i >= 0; i--)
                free_netdev(ethsw->ports[i]->netdev);
+       kfree(ethsw->acls);
+err_free_fdbs:
        kfree(ethsw->fdbs);
 err_free_ports:
        kfree(ethsw->ports);
index 0ae1d27c811e15bf853a99d668b461ff7d4a7069..a2c0ff23c7e96cd155977f9ea401020e58cf567a 100644 (file)
@@ -101,6 +101,12 @@ struct dpaa2_switch_fdb {
        bool                    in_use;
 };
 
+struct dpaa2_switch_acl_tbl {
+       u16                     id;
+       u8                      num_rules;
+       bool                    in_use;
+};
+
 /* Per port private data */
 struct ethsw_port_priv {
        struct net_device       *netdev;
@@ -118,8 +124,7 @@ struct ethsw_port_priv {
        bool                    ucast_flood;
        bool                    learn_ena;
 
-       u16                     acl_tbl;
-       u8                      acl_num_rules;
+       struct dpaa2_switch_acl_tbl *acl_tbl;
 };
 
 /* Switch data */
@@ -145,6 +150,7 @@ struct ethsw_core {
        int                             napi_users;
 
        struct dpaa2_switch_fdb         *fdbs;
+       struct dpaa2_switch_acl_tbl     *acls;
 };
 
 static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw)