forked from Minki/linux
octeontx2-pf: Add support for exact match table.
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>
This commit is contained in:
parent
84926eb57d
commit
e56468377f
@ -314,8 +314,8 @@ struct otx2_flow_config {
|
||||
#define OTX2_VF_VLAN_TX_INDEX 1
|
||||
u16 max_flows;
|
||||
u8 dmacflt_max_flows;
|
||||
u8 *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);
|
||||
|
||||
|
@ -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];
|
||||
rc = otx2_sync_mbox_msg(&pf->mbox);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user