Skip to content

Commit

Permalink
octeontx2-pf: Unify flow management variables
Browse files Browse the repository at this point in the history
Variables used for TC flow management like maximum number
of flows, number of flows installed etc are a copy of ntuple
flow management variables. Since both TC and NTUPLE are not
supported at the same time, it's better to unify these with
common variables.

This patch addresses this unification and also does cleanup of
other minor stuff wrt TC.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Sunil Goutham authored and David S. Miller committed Aug 17, 2021
1 parent cc65fca commit 2e2a812
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 46 deletions.
17 changes: 7 additions & 10 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ struct otx2_mac_table {
};

struct otx2_flow_config {
u16 entry[NPC_MAX_NONCONTIG_ENTRIES];
u16 *flow_ent;
u16 *def_ent;
u16 nr_flows;
Expand All @@ -279,16 +278,13 @@ struct otx2_flow_config {
#define OTX2_MCAM_COUNT (OTX2_DEFAULT_FLOWCOUNT + \
OTX2_MAX_UNICAST_FLOWS + \
OTX2_MAX_VLAN_FLOWS)
u16 ntuple_offset;
u16 unicast_offset;
u16 rx_vlan_offset;
u16 vf_vlan_offset;
#define OTX2_PER_VF_VLAN_FLOWS 2 /* Rx + Tx per VF */
#define OTX2_VF_VLAN_RX_INDEX 0
#define OTX2_VF_VLAN_TX_INDEX 1
u16 tc_flower_offset;
u16 ntuple_max_flows;
u16 tc_max_flows;
u16 max_flows;
u8 dmacflt_max_flows;
u8 *bmap_to_dmacindex;
unsigned long dmacflt_bmap;
Expand All @@ -299,8 +295,7 @@ struct otx2_tc_info {
/* hash table to store TC offloaded flows */
struct rhashtable flow_table;
struct rhashtable_params flow_ht_params;
DECLARE_BITMAP(tc_entries_bitmap, OTX2_MAX_TC_FLOWS);
unsigned long num_entries;
unsigned long *tc_entries_bitmap;
};

struct dev_hw_ops {
Expand Down Expand Up @@ -353,14 +348,18 @@ struct otx2_nic {
struct otx2_vf_config *vf_configs;
struct cgx_link_user_info linfo;

/* NPC MCAM */
struct otx2_flow_config *flow_cfg;
struct otx2_mac_table *mac_table;
struct otx2_tc_info tc_info;

u64 reset_count;
struct work_struct reset_task;
struct workqueue_struct *flr_wq;
struct flr_work *flr_wrk;
struct refill_work *refill_wrk;
struct workqueue_struct *otx2_wq;
struct work_struct rx_mode_work;
struct otx2_mac_table *mac_table;

/* Ethtool stuff */
u32 msg_enable;
Expand All @@ -376,8 +375,6 @@ struct otx2_nic {
struct otx2_ptp *ptp;
struct hwtstamp_config tstamp;

struct otx2_flow_config *flow_cfg;
struct otx2_tc_info tc_info;
unsigned long rq_bmap;
};

Expand Down
29 changes: 13 additions & 16 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ static void otx2_clear_ntuple_flow_info(struct otx2_nic *pfvf, struct otx2_flow_
{
devm_kfree(pfvf->dev, flow_cfg->flow_ent);
flow_cfg->flow_ent = NULL;
flow_cfg->ntuple_max_flows = 0;
flow_cfg->tc_max_flows = 0;
flow_cfg->max_flows = 0;
}

static int otx2_free_ntuple_mcam_entries(struct otx2_nic *pfvf)
Expand All @@ -41,11 +40,11 @@ static int otx2_free_ntuple_mcam_entries(struct otx2_nic *pfvf)
struct npc_mcam_free_entry_req *req;
int ent, err;

if (!flow_cfg->ntuple_max_flows)
if (!flow_cfg->max_flows)
return 0;

mutex_lock(&pfvf->mbox.lock);
for (ent = 0; ent < flow_cfg->ntuple_max_flows; ent++) {
for (ent = 0; ent < flow_cfg->max_flows; ent++) {
req = otx2_mbox_alloc_msg_npc_mcam_free_entry(&pfvf->mbox);
if (!req)
break;
Expand Down Expand Up @@ -138,9 +137,7 @@ static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count)
exit:
mutex_unlock(&pfvf->mbox.lock);

flow_cfg->ntuple_offset = 0;
flow_cfg->ntuple_max_flows = allocated;
flow_cfg->tc_max_flows = allocated;
flow_cfg->max_flows = allocated;

pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
Expand Down Expand Up @@ -236,7 +233,7 @@ int otx2vf_mcam_flow_init(struct otx2_nic *pfvf)

flow_cfg = pfvf->flow_cfg;
INIT_LIST_HEAD(&flow_cfg->flow_list);
flow_cfg->ntuple_max_flows = 0;
flow_cfg->max_flows = 0;

count = otx2_alloc_ntuple_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);
if (count <= 0)
Expand Down Expand Up @@ -430,12 +427,12 @@ int otx2_get_maxflows(struct otx2_flow_config *flow_cfg)
if (!flow_cfg)
return 0;

if (flow_cfg->nr_flows == flow_cfg->ntuple_max_flows ||
if (flow_cfg->nr_flows == flow_cfg->max_flows ||
bitmap_weight(&flow_cfg->dmacflt_bmap,
flow_cfg->dmacflt_max_flows))
return flow_cfg->ntuple_max_flows + flow_cfg->dmacflt_max_flows;
return flow_cfg->max_flows + flow_cfg->dmacflt_max_flows;
else
return flow_cfg->ntuple_max_flows;
return flow_cfg->max_flows;
}
EXPORT_SYMBOL(otx2_get_maxflows);

Expand Down Expand Up @@ -944,7 +941,7 @@ static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf,

pf_mac->entry = 0;
pf_mac->dmac_filter = true;
pf_mac->location = pfvf->flow_cfg->ntuple_max_flows;
pf_mac->location = pfvf->flow_cfg->max_flows;
memcpy(&pf_mac->flow_spec, &flow->flow_spec,
sizeof(struct ethtool_rx_flow_spec));
pf_mac->flow_spec.location = pf_mac->location;
Expand Down Expand Up @@ -1025,19 +1022,19 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
flow->dmac_filter = true;
flow->entry = find_first_zero_bit(&flow_cfg->dmacflt_bmap,
flow_cfg->dmacflt_max_flows);
fsp->location = flow_cfg->ntuple_max_flows + flow->entry;
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);
otx2_dmacflt_add(pfvf, eth_hdr->h_dest, flow->entry);

} else {
if (flow->location >= pfvf->flow_cfg->ntuple_max_flows) {
if (flow->location >= pfvf->flow_cfg->max_flows) {
netdev_warn(pfvf->netdev,
"Can't insert non dmac ntuple rule at %d, allowed range %d-0\n",
flow->location,
flow_cfg->ntuple_max_flows - 1);
flow_cfg->max_flows - 1);
err = -EINVAL;
} else {
flow->entry = flow_cfg->flow_ent[flow->location];
Expand Down Expand Up @@ -1192,7 +1189,7 @@ int otx2_destroy_ntuple_flows(struct otx2_nic *pfvf)
}

req->start = flow_cfg->flow_ent[0];
req->end = flow_cfg->flow_ent[flow_cfg->ntuple_max_flows - 1];
req->end = flow_cfg->flow_ent[flow_cfg->max_flows - 1];
err = otx2_sync_mbox_msg(&pfvf->mbox);
mutex_unlock(&pfvf->mbox.lock);

Expand Down
34 changes: 21 additions & 13 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1787,17 +1787,10 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
static netdev_features_t otx2_fix_features(struct net_device *dev,
netdev_features_t features)
{
/* check if n-tuple filters are ON */
if ((features & NETIF_F_HW_TC) && (dev->features & NETIF_F_NTUPLE)) {
netdev_info(dev, "Disabling n-tuple filters\n");
features &= ~NETIF_F_NTUPLE;
}

/* check if tc hw offload is ON */
if ((features & NETIF_F_NTUPLE) && (dev->features & NETIF_F_HW_TC)) {
netdev_info(dev, "Disabling TC hardware offload\n");
features &= ~NETIF_F_HW_TC;
}
if (features & NETIF_F_HW_VLAN_CTAG_RX)
features |= NETIF_F_HW_VLAN_STAG_RX;
else
features &= ~NETIF_F_HW_VLAN_STAG_RX;

return features;
}
Expand Down Expand Up @@ -1854,6 +1847,7 @@ static int otx2_set_features(struct net_device *netdev,
netdev_features_t changed = features ^ netdev->features;
bool ntuple = !!(features & NETIF_F_NTUPLE);
struct otx2_nic *pf = netdev_priv(netdev);
bool tc = !!(features & NETIF_F_HW_TC);

if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
return otx2_cgx_config_loopback(pf,
Expand All @@ -1866,12 +1860,26 @@ static int otx2_set_features(struct net_device *netdev,
if ((changed & NETIF_F_NTUPLE) && !ntuple)
otx2_destroy_ntuple_flows(pf);

if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
pf->tc_info.num_entries) {
if ((changed & NETIF_F_HW_TC) && !tc &&
pf->flow_cfg && pf->flow_cfg->nr_flows) {
netdev_err(netdev, "Can't disable TC hardware offload while flows are active\n");
return -EBUSY;
}

if ((changed & NETIF_F_NTUPLE) && ntuple &&
(netdev->features & NETIF_F_HW_TC) && !(changed & NETIF_F_HW_TC)) {
netdev_err(netdev,
"Can't enable NTUPLE when TC is active, disable TC and retry\n");
return -EINVAL;
}

if ((changed & NETIF_F_HW_TC) && tc &&
(netdev->features & NETIF_F_NTUPLE) && !(changed & NETIF_F_NTUPLE)) {
netdev_err(netdev,
"Can't enable TC when NTUPLE is active, disable NTUPLE and retry\n");
return -EINVAL;
}

return 0;
}

Expand Down
46 changes: 39 additions & 7 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ struct otx2_tc_flow {
bool is_act_police;
};

static int otx2_tc_alloc_ent_bitmap(struct otx2_nic *nic)
{
struct otx2_tc_info *tc = &nic->tc_info;

if (!nic->flow_cfg->max_flows)
return 0;

tc->tc_entries_bitmap =
kcalloc(BITS_TO_LONGS(nic->flow_cfg->max_flows),
sizeof(long), GFP_KERNEL);
if (!tc->tc_entries_bitmap) {
netdev_err(nic->netdev,
"Unable to alloc TC flow entries bitmap\n");
return -ENOMEM;
}

return 0;
}

static void otx2_get_egress_burst_cfg(u32 burst, u32 *burst_exp,
u32 *burst_mantissa)
{
Expand Down Expand Up @@ -596,6 +615,7 @@ static int otx2_del_mcam_flow_entry(struct otx2_nic *nic, u16 entry)
static int otx2_tc_del_flow(struct otx2_nic *nic,
struct flow_cls_offload *tc_flow_cmd)
{
struct otx2_flow_config *flow_cfg = nic->flow_cfg;
struct otx2_tc_info *tc_info = &nic->tc_info;
struct otx2_tc_flow *flow_node;
int err;
Expand Down Expand Up @@ -638,7 +658,7 @@ static int otx2_tc_del_flow(struct otx2_nic *nic,
kfree_rcu(flow_node, rcu);

clear_bit(flow_node->bitpos, tc_info->tc_entries_bitmap);
tc_info->num_entries--;
flow_cfg->nr_flows--;

return 0;
}
Expand All @@ -647,6 +667,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
struct flow_cls_offload *tc_flow_cmd)
{
struct netlink_ext_ack *extack = tc_flow_cmd->common.extack;
struct otx2_flow_config *flow_cfg = nic->flow_cfg;
struct otx2_tc_info *tc_info = &nic->tc_info;
struct otx2_tc_flow *new_node, *old_node;
struct npc_install_flow_req *req, dummy;
Expand All @@ -655,9 +676,9 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
if (!(nic->flags & OTX2_FLAG_TC_FLOWER_SUPPORT))
return -ENOMEM;

if (bitmap_full(tc_info->tc_entries_bitmap, nic->flow_cfg->tc_max_flows)) {
if (bitmap_full(tc_info->tc_entries_bitmap, flow_cfg->max_flows)) {
NL_SET_ERR_MSG_MOD(extack,
"Not enough MCAM space to add the flow");
"Free MCAM entry not available to add the flow");
return -ENOMEM;
}

Expand Down Expand Up @@ -695,10 +716,9 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
memcpy(req, &dummy, sizeof(struct npc_install_flow_req));

new_node->bitpos = find_first_zero_bit(tc_info->tc_entries_bitmap,
nic->flow_cfg->tc_max_flows);
flow_cfg->max_flows);
req->channel = nic->hw.rx_chan_base;
req->entry = nic->flow_cfg->flow_ent[nic->flow_cfg->tc_flower_offset +
nic->flow_cfg->tc_max_flows - new_node->bitpos];
req->entry = flow_cfg->flow_ent[flow_cfg->max_flows - new_node->bitpos - 1];
req->intf = NIX_INTF_RX;
req->set_cntr = 1;
new_node->entry = req->entry;
Expand All @@ -723,7 +743,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
}

set_bit(new_node->bitpos, tc_info->tc_entries_bitmap);
tc_info->num_entries++;
flow_cfg->nr_flows++;

return 0;

Expand Down Expand Up @@ -1008,10 +1028,21 @@ static const struct rhashtable_params tc_flow_ht_params = {
int otx2_init_tc(struct otx2_nic *nic)
{
struct otx2_tc_info *tc = &nic->tc_info;
int err;

/* Exclude receive queue 0 being used for police action */
set_bit(0, &nic->rq_bmap);

if (!nic->flow_cfg) {
netdev_err(nic->netdev,
"Can't init TC, nic->flow_cfg is not setup\n");
return -EINVAL;
}

err = otx2_tc_alloc_ent_bitmap(nic);
if (err)
return err;

tc->flow_ht_params = tc_flow_ht_params;
return rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
}
Expand All @@ -1020,5 +1051,6 @@ void otx2_shutdown_tc(struct otx2_nic *nic)
{
struct otx2_tc_info *tc = &nic->tc_info;

kfree(tc->tc_entries_bitmap);
rhashtable_destroy(&tc->flow_table);
}

0 comments on commit 2e2a812

Please sign in to comment.