octeontx2-pf: Add support for exact match table.
authorRatheesh Kannoth <rkannoth@marvell.com>
Wed, 6 Jul 2022 03:44:41 +0000 (09:14 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 6 Jul 2022 07:16:48 +0000 (08:16 +0100)
NPC exact match table can support more entries than RPM
dmac filters. This requires field size of DMAC filter count
and index to be increased.

Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

index ce27663..e795f9e 100644 (file)
@@ -314,8 +314,8 @@ struct otx2_flow_config {
 #define OTX2_VF_VLAN_TX_INDEX  1
        u16                     max_flows;
        u8                      dmacflt_max_flows;
-       u                     *bmap_to_dmacindex;
-       unsigned long           dmacflt_bmap;
+       u32                     *bmap_to_dmacindex;
+       unsigned long           *dmacflt_bmap;
        struct list_head        flow_list;
 };
 
@@ -895,9 +895,9 @@ int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type,
 int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic);
 /* CGX/RPM DMAC filters support */
 int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf);
-int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
-int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, u8 bit_pos);
-int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos);
+int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos);
+int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac, u32 bit_pos);
+int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos);
 void otx2_dmacflt_reinstall_flows(struct otx2_nic *pf);
 void otx2_dmacflt_update_pfmac_flow(struct otx2_nic *pfvf);
 
index 142d877..846a029 100644 (file)
@@ -8,7 +8,7 @@
 #include "otx2_common.h"
 
 static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
-                              u8 *dmac_index)
+                              u32 *dmac_index)
 {
        struct cgx_mac_addr_add_req *req;
        struct cgx_mac_addr_add_rsp *rsp;
@@ -35,9 +35,10 @@ static int otx2_dmacflt_do_add(struct otx2_nic *pf, const u8 *mac,
        return err;
 }
 
-static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
+static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf, u32 *dmac_index)
 {
        struct cgx_mac_addr_set_or_get *req;
+       struct cgx_mac_addr_set_or_get *rsp;
        int err;
 
        mutex_lock(&pf->mbox.lock);
@@ -48,16 +49,24 @@ static int otx2_dmacflt_add_pfmac(struct otx2_nic *pf)
                return -ENOMEM;
        }
 
+       req->index = *dmac_index;
+
        ether_addr_copy(req->mac_addr, pf->netdev->dev_addr);
        err = otx2_sync_mbox_msg(&pf->mbox);
 
+       if (!err) {
+               rsp = (struct cgx_mac_addr_set_or_get *)
+                        otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
+               *dmac_index = rsp->index;
+       }
+
        mutex_unlock(&pf->mbox.lock);
        return err;
 }
 
-int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
+int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos)
 {
-       u8 *dmacindex;
+       u32 *dmacindex;
 
        /* Store dmacindex returned by CGX/RPM driver which will
         * be used for macaddr update/remove
@@ -65,13 +74,13 @@ int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u8 bit_pos)
        dmacindex = &pf->flow_cfg->bmap_to_dmacindex[bit_pos];
 
        if (ether_addr_equal(mac, pf->netdev->dev_addr))
-               return otx2_dmacflt_add_pfmac(pf);
+               return otx2_dmacflt_add_pfmac(pf, dmacindex);
        else
                return otx2_dmacflt_do_add(pf, mac, dmacindex);
 }
 
 static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
-                                 u8 dmac_index)
+                                 u32 dmac_index)
 {
        struct cgx_mac_addr_del_req *req;
        int err;
@@ -91,7 +100,7 @@ static int otx2_dmacflt_do_remove(struct otx2_nic *pfvf, const u8 *mac,
        return err;
 }
 
-static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
+static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf, u32 dmac_index)
 {
        struct cgx_mac_addr_reset_req *req;
        int err;
@@ -102,6 +111,7 @@ static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
                mutex_unlock(&pf->mbox.lock);
                return -ENOMEM;
        }
+       req->index = dmac_index;
 
        err = otx2_sync_mbox_msg(&pf->mbox);
 
@@ -110,12 +120,12 @@ static int otx2_dmacflt_remove_pfmac(struct otx2_nic *pf)
 }
 
 int otx2_dmacflt_remove(struct otx2_nic *pf, const u8 *mac,
-                       u8 bit_pos)
+                       u32 bit_pos)
 {
-       u8 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
+       u32 dmacindex = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
 
        if (ether_addr_equal(mac, pf->netdev->dev_addr))
-               return otx2_dmacflt_remove_pfmac(pf);
+               return otx2_dmacflt_remove_pfmac(pf, dmacindex);
        else
                return otx2_dmacflt_do_remove(pf, mac, dmacindex);
 }
@@ -151,9 +161,10 @@ out:
        return err;
 }
 
-int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
+int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u32 bit_pos)
 {
        struct cgx_mac_addr_update_req *req;
+       struct cgx_mac_addr_update_rsp *rsp;
        int rc;
 
        mutex_lock(&pf->mbox.lock);
@@ -167,8 +178,19 @@ int otx2_dmacflt_update(struct otx2_nic *pf, u8 *mac, u8 bit_pos)
 
        ether_addr_copy(req->mac_addr, mac);
        req->index = pf->flow_cfg->bmap_to_dmacindex[bit_pos];
+
+       /* check the response and change index */
+
        rc = otx2_sync_mbox_msg(&pf->mbox);
+       if (rc)
+               goto out;
 
+       rsp = (struct cgx_mac_addr_update_rsp *)
+               otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
+
+       pf->flow_cfg->bmap_to_dmacindex[bit_pos] = rsp->index;
+
+out:
        mutex_unlock(&pf->mbox.lock);
        return rc;
 }
index 2dd192b..709fc01 100644 (file)
@@ -18,7 +18,7 @@ struct otx2_flow {
        struct ethtool_rx_flow_spec flow_spec;
        struct list_head list;
        u32 location;
-       u16 entry;
+       u32 entry;
        bool is_vf;
        u8 rss_ctx_id;
 #define DMAC_FILTER_RULE               BIT(0)
@@ -232,6 +232,9 @@ static int otx2_mcam_entry_init(struct otx2_nic *pfvf)
        return 0;
 }
 
+/* TODO : revisit on size */
+#define OTX2_DMAC_FLTR_BITMAP_SZ (4 * 2048 + 32)
+
 int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
 {
        struct otx2_flow_config *flow_cfg;
@@ -242,6 +245,12 @@ int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)
        if (!pfvf->flow_cfg)
                return -ENOMEM;
 
+       pfvf->flow_cfg->dmacflt_bmap = devm_kcalloc(pfvf->dev,
+                                                   BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),
+                                                   sizeof(long), GFP_KERNEL);
+       if (!pfvf->flow_cfg->dmacflt_bmap)
+               return -ENOMEM;
+
        flow_cfg = pfvf->flow_cfg;
        INIT_LIST_HEAD(&flow_cfg->flow_list);
        flow_cfg->max_flows = 0;
@@ -259,6 +268,12 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
        if (!pf->flow_cfg)
                return -ENOMEM;
 
+       pf->flow_cfg->dmacflt_bmap = devm_kcalloc(pf->dev,
+                                                 BITS_TO_LONGS(OTX2_DMAC_FLTR_BITMAP_SZ),
+                                                 sizeof(long), GFP_KERNEL);
+       if (!pf->flow_cfg->dmacflt_bmap)
+               return -ENOMEM;
+
        INIT_LIST_HEAD(&pf->flow_cfg->flow_list);
 
        /* Allocate bare minimum number of MCAM entries needed for
@@ -284,7 +299,7 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
                return 0;
 
        pf->flow_cfg->bmap_to_dmacindex =
-                       devm_kzalloc(pf->dev, sizeof(u8) *
+                       devm_kzalloc(pf->dev, sizeof(u32) *
                                     pf->flow_cfg->dmacflt_max_flows,
                                     GFP_KERNEL);
 
@@ -355,7 +370,7 @@ int otx2_add_macfilter(struct net_device *netdev, const u8 *mac)
 {
        struct otx2_nic *pf = netdev_priv(netdev);
 
-       if (!bitmap_empty(&pf->flow_cfg->dmacflt_bmap,
+       if (!bitmap_empty(pf->flow_cfg->dmacflt_bmap,
                          pf->flow_cfg->dmacflt_max_flows))
                netdev_warn(netdev,
                            "Add %pM to CGX/RPM DMAC filters list as well\n",
@@ -438,7 +453,7 @@ int otx2_get_maxflows(struct otx2_flow_config *flow_cfg)
                return 0;
 
        if (flow_cfg->nr_flows == flow_cfg->max_flows ||
-           !bitmap_empty(&flow_cfg->dmacflt_bmap,
+           !bitmap_empty(flow_cfg->dmacflt_bmap,
                          flow_cfg->dmacflt_max_flows))
                return flow_cfg->max_flows + flow_cfg->dmacflt_max_flows;
        else
@@ -1010,7 +1025,7 @@ static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf,
 
        otx2_add_flow_to_list(pfvf, pf_mac);
        pfvf->flow_cfg->nr_flows++;
-       set_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
+       set_bit(0, pfvf->flow_cfg->dmacflt_bmap);
 
        return 0;
 }
@@ -1064,7 +1079,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
                        return otx2_dmacflt_update(pfvf, eth_hdr->h_dest,
                                                   flow->entry);
 
-               if (bitmap_full(&flow_cfg->dmacflt_bmap,
+               if (bitmap_full(flow_cfg->dmacflt_bmap,
                                flow_cfg->dmacflt_max_flows)) {
                        netdev_warn(pfvf->netdev,
                                    "Can't insert the rule %d as max allowed dmac filters are %d\n",
@@ -1078,17 +1093,17 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
                }
 
                /* Install PF mac address to DMAC filter list */
-               if (!test_bit(0, &flow_cfg->dmacflt_bmap))
+               if (!test_bit(0, flow_cfg->dmacflt_bmap))
                        otx2_add_flow_with_pfmac(pfvf, flow);
 
                flow->rule_type |= DMAC_FILTER_RULE;
-               flow->entry = find_first_zero_bit(&flow_cfg->dmacflt_bmap,
+               flow->entry = find_first_zero_bit(flow_cfg->dmacflt_bmap,
                                                  flow_cfg->dmacflt_max_flows);
                fsp->location = flow_cfg->max_flows + flow->entry;
                flow->flow_spec.location = fsp->location;
                flow->location = fsp->location;
 
-               set_bit(flow->entry, &flow_cfg->dmacflt_bmap);
+               set_bit(flow->entry, flow_cfg->dmacflt_bmap);
                otx2_dmacflt_add(pfvf, eth_hdr->h_dest, flow->entry);
 
        } else {
@@ -1154,11 +1169,12 @@ static void otx2_update_rem_pfmac(struct otx2_nic *pfvf, int req)
                        if (req == DMAC_ADDR_DEL) {
                                otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
                                                    0);
-                               clear_bit(0, &pfvf->flow_cfg->dmacflt_bmap);
+                               clear_bit(0, pfvf->flow_cfg->dmacflt_bmap);
                                found = true;
                        } else {
                                ether_addr_copy(eth_hdr->h_dest,
                                                pfvf->netdev->dev_addr);
+
                                otx2_dmacflt_update(pfvf, eth_hdr->h_dest, 0);
                        }
                        break;
@@ -1194,12 +1210,12 @@ int otx2_remove_flow(struct otx2_nic *pfvf, u32 location)
 
                err = otx2_dmacflt_remove(pfvf, eth_hdr->h_dest,
                                          flow->entry);
-               clear_bit(flow->entry, &flow_cfg->dmacflt_bmap);
+               clear_bit(flow->entry, flow_cfg->dmacflt_bmap);
                /* If all dmac filters are removed delete macfilter with
                 * interface mac address and configure CGX/RPM block in
                 * promiscuous mode
                 */
-               if (bitmap_weight(&flow_cfg->dmacflt_bmap,
+               if (bitmap_weight(flow_cfg->dmacflt_bmap,
                                  flow_cfg->dmacflt_max_flows) == 1)
                        otx2_update_rem_pfmac(pfvf, DMAC_ADDR_DEL);
        } else {
index 9106c35..9376d0e 100644 (file)
@@ -1120,7 +1120,7 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
        struct msg_req *msg;
        int err;
 
-       if (enable && !bitmap_empty(&pf->flow_cfg->dmacflt_bmap,
+       if (enable && !bitmap_empty(pf->flow_cfg->dmacflt_bmap,
                                    pf->flow_cfg->dmacflt_max_flows))
                netdev_warn(pf->netdev,
                            "CGX/RPM internal loopback might not work as DMAC filters are active\n");