Skip to content

Commit 9917060

Browse files
sgoutham-marvelldavem330
authored andcommitted
octeontx2-pf: Cleanup flow rule management
Current MCAM allocation scheme allocates a single lot of MCAM entries for ntuple filters, unicast filters and VF VLAN rules. This patch attempts to cleanup this logic by segregating MCAM rule allocation and management for Ntuple rules and unicast, VF VLAN rules. This segregation will result in reusing most of the logic for supporting ntuple filters for VF devices. Also added debug messages for MCAM entry allocation failures. Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2d7ff2d commit 9917060

File tree

5 files changed

+181
-63
lines changed

5 files changed

+181
-63
lines changed

drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,8 +2537,11 @@ int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
25372537
rsp->free_count = 0;
25382538

25392539
/* Check if ref_entry is within range */
2540-
if (req->priority && req->ref_entry >= mcam->bmap_entries)
2540+
if (req->priority && req->ref_entry >= mcam->bmap_entries) {
2541+
dev_err(rvu->dev, "%s: reference entry %d is out of range\n",
2542+
__func__, req->ref_entry);
25412543
return NPC_MCAM_INVALID_REQ;
2544+
}
25422545

25432546
/* ref_entry can't be '0' if requested priority is high.
25442547
* Can't be last entry if requested priority is low.
@@ -2551,8 +2554,12 @@ int rvu_mbox_handler_npc_mcam_alloc_entry(struct rvu *rvu,
25512554
/* Since list of allocated indices needs to be sent to requester,
25522555
* max number of non-contiguous entries per mbox msg is limited.
25532556
*/
2554-
if (!req->contig && req->count > NPC_MAX_NONCONTIG_ENTRIES)
2557+
if (!req->contig && req->count > NPC_MAX_NONCONTIG_ENTRIES) {
2558+
dev_err(rvu->dev,
2559+
"%s: %d Non-contiguous MCAM entries requested is morethan max (%d) allowed\n",
2560+
__func__, req->count, NPC_MAX_NONCONTIG_ENTRIES);
25552561
return NPC_MCAM_INVALID_REQ;
2562+
}
25562563

25572564
/* Alloc request from PFFUNC with no NIXLF attached should be denied */
25582565
if (!is_nixlf_attached(rvu, pcifunc))

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -267,24 +267,26 @@ struct otx2_mac_table {
267267

268268
struct otx2_flow_config {
269269
u16 entry[NPC_MAX_NONCONTIG_ENTRIES];
270-
u32 nr_flows;
271-
#define OTX2_MAX_NTUPLE_FLOWS 32
272-
#define OTX2_MAX_UNICAST_FLOWS 8
273-
#define OTX2_MAX_VLAN_FLOWS 1
274-
#define OTX2_MAX_TC_FLOWS OTX2_MAX_NTUPLE_FLOWS
275-
#define OTX2_MCAM_COUNT (OTX2_MAX_NTUPLE_FLOWS + \
270+
u16 *flow_ent;
271+
u16 *def_ent;
272+
u16 nr_flows;
273+
#define OTX2_DEFAULT_FLOWCOUNT 16
274+
#define OTX2_MAX_UNICAST_FLOWS 8
275+
#define OTX2_MAX_VLAN_FLOWS 1
276+
#define OTX2_MAX_TC_FLOWS OTX2_DEFAULT_FLOWCOUNT
277+
#define OTX2_MCAM_COUNT (OTX2_DEFAULT_FLOWCOUNT + \
276278
OTX2_MAX_UNICAST_FLOWS + \
277279
OTX2_MAX_VLAN_FLOWS)
278-
u32 ntuple_offset;
279-
u32 unicast_offset;
280-
u32 rx_vlan_offset;
281-
u32 vf_vlan_offset;
282-
#define OTX2_PER_VF_VLAN_FLOWS 2 /* rx+tx per VF */
280+
u16 ntuple_offset;
281+
u16 unicast_offset;
282+
u16 rx_vlan_offset;
283+
u16 vf_vlan_offset;
284+
#define OTX2_PER_VF_VLAN_FLOWS 2 /* Rx + Tx per VF */
283285
#define OTX2_VF_VLAN_RX_INDEX 0
284286
#define OTX2_VF_VLAN_TX_INDEX 1
285-
u32 tc_flower_offset;
286-
u32 ntuple_max_flows;
287-
u32 tc_max_flows;
287+
u16 tc_flower_offset;
288+
u16 ntuple_max_flows;
289+
u16 tc_max_flows;
288290
struct list_head flow_list;
289291
};
290292

drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c

Lines changed: 150 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,125 @@ struct otx2_flow {
2020
int vf;
2121
};
2222

23+
static void otx2_clear_ntuple_flow_info(struct otx2_nic *pfvf, struct otx2_flow_config *flow_cfg)
24+
{
25+
devm_kfree(pfvf->dev, flow_cfg->flow_ent);
26+
flow_cfg->flow_ent = NULL;
27+
flow_cfg->ntuple_max_flows = 0;
28+
flow_cfg->tc_max_flows = 0;
29+
}
30+
31+
static int otx2_free_ntuple_mcam_entries(struct otx2_nic *pfvf)
32+
{
33+
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
34+
struct npc_mcam_free_entry_req *req;
35+
int ent, err;
36+
37+
if (!flow_cfg->ntuple_max_flows)
38+
return 0;
39+
40+
mutex_lock(&pfvf->mbox.lock);
41+
for (ent = 0; ent < flow_cfg->ntuple_max_flows; ent++) {
42+
req = otx2_mbox_alloc_msg_npc_mcam_free_entry(&pfvf->mbox);
43+
if (!req)
44+
break;
45+
46+
req->entry = flow_cfg->flow_ent[ent];
47+
48+
/* Send message to AF to free MCAM entries */
49+
err = otx2_sync_mbox_msg(&pfvf->mbox);
50+
if (err)
51+
break;
52+
}
53+
mutex_unlock(&pfvf->mbox.lock);
54+
otx2_clear_ntuple_flow_info(pfvf, flow_cfg);
55+
return 0;
56+
}
57+
58+
static int otx2_alloc_ntuple_mcam_entries(struct otx2_nic *pfvf, u16 count)
59+
{
60+
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
61+
struct npc_mcam_alloc_entry_req *req;
62+
struct npc_mcam_alloc_entry_rsp *rsp;
63+
int ent, allocated = 0;
64+
65+
/* Free current ones and allocate new ones with requested count */
66+
otx2_free_ntuple_mcam_entries(pfvf);
67+
68+
if (!count)
69+
return 0;
70+
71+
flow_cfg->flow_ent = devm_kmalloc_array(pfvf->dev, count,
72+
sizeof(u16), GFP_KERNEL);
73+
if (!flow_cfg->flow_ent)
74+
return -ENOMEM;
75+
76+
mutex_lock(&pfvf->mbox.lock);
77+
78+
/* In a single request a max of NPC_MAX_NONCONTIG_ENTRIES MCAM entries
79+
* can only be allocated.
80+
*/
81+
while (allocated < count) {
82+
req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&pfvf->mbox);
83+
if (!req)
84+
goto exit;
85+
86+
req->contig = false;
87+
req->count = (count - allocated) > NPC_MAX_NONCONTIG_ENTRIES ?
88+
NPC_MAX_NONCONTIG_ENTRIES : count - allocated;
89+
req->priority = NPC_MCAM_HIGHER_PRIO;
90+
req->ref_entry = flow_cfg->def_ent[0];
91+
92+
/* Send message to AF */
93+
if (otx2_sync_mbox_msg(&pfvf->mbox))
94+
goto exit;
95+
96+
rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
97+
(&pfvf->mbox.mbox, 0, &req->hdr);
98+
99+
for (ent = 0; ent < rsp->count; ent++)
100+
flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
101+
102+
allocated += rsp->count;
103+
104+
/* If this request is not fulfilled, no need to send
105+
* further requests.
106+
*/
107+
if (rsp->count != req->count)
108+
break;
109+
}
110+
111+
exit:
112+
mutex_unlock(&pfvf->mbox.lock);
113+
114+
flow_cfg->ntuple_offset = 0;
115+
flow_cfg->ntuple_max_flows = allocated;
116+
flow_cfg->tc_max_flows = allocated;
117+
118+
if (allocated != count)
119+
netdev_info(pfvf->netdev,
120+
"Unable to allocate %d MCAM entries for ntuple, got %d\n",
121+
count, allocated);
122+
123+
return allocated;
124+
}
125+
23126
int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
24127
{
25128
struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
26129
struct npc_mcam_alloc_entry_req *req;
27130
struct npc_mcam_alloc_entry_rsp *rsp;
28131
int vf_vlan_max_flows;
29-
int i;
132+
int ent, count;
133+
134+
vf_vlan_max_flows = pfvf->total_vfs * OTX2_PER_VF_VLAN_FLOWS;
135+
count = OTX2_MAX_UNICAST_FLOWS +
136+
OTX2_MAX_VLAN_FLOWS + vf_vlan_max_flows;
137+
138+
flow_cfg->def_ent = devm_kmalloc_array(pfvf->dev, count,
139+
sizeof(u16), GFP_KERNEL);
140+
if (!flow_cfg->def_ent)
141+
return -ENOMEM;
30142

31143
mutex_lock(&pfvf->mbox.lock);
32144

@@ -36,9 +148,8 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
36148
return -ENOMEM;
37149
}
38150

39-
vf_vlan_max_flows = pfvf->total_vfs * OTX2_PER_VF_VLAN_FLOWS;
40151
req->contig = false;
41-
req->count = OTX2_MCAM_COUNT + vf_vlan_max_flows;
152+
req->count = count;
42153

43154
/* Send message to AF */
44155
if (otx2_sync_mbox_msg(&pfvf->mbox)) {
@@ -51,37 +162,36 @@ int otx2_alloc_mcam_entries(struct otx2_nic *pfvf)
51162

52163
if (rsp->count != req->count) {
53164
netdev_info(pfvf->netdev,
54-
"Unable to allocate %d MCAM entries, got %d\n",
55-
req->count, rsp->count);
56-
/* support only ntuples here */
57-
flow_cfg->ntuple_max_flows = rsp->count;
58-
flow_cfg->ntuple_offset = 0;
59-
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
60-
flow_cfg->tc_max_flows = flow_cfg->ntuple_max_flows;
61-
pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
62-
} else {
63-
flow_cfg->vf_vlan_offset = 0;
64-
flow_cfg->ntuple_offset = flow_cfg->vf_vlan_offset +
65-
vf_vlan_max_flows;
66-
flow_cfg->tc_flower_offset = flow_cfg->ntuple_offset;
67-
flow_cfg->unicast_offset = flow_cfg->ntuple_offset +
68-
OTX2_MAX_NTUPLE_FLOWS;
69-
flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
70-
OTX2_MAX_UNICAST_FLOWS;
71-
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
72-
pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
73-
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
74-
pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
75-
pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
76-
}
77-
78-
for (i = 0; i < rsp->count; i++)
79-
flow_cfg->entry[i] = rsp->entry_list[i];
165+
"Unable to allocate MCAM entries for ucast, vlan and vf_vlan\n");
166+
mutex_unlock(&pfvf->mbox.lock);
167+
devm_kfree(pfvf->dev, flow_cfg->def_ent);
168+
return 0;
169+
}
80170

81-
pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
171+
for (ent = 0; ent < rsp->count; ent++)
172+
flow_cfg->def_ent[ent] = rsp->entry_list[ent];
82173

174+
flow_cfg->vf_vlan_offset = 0;
175+
flow_cfg->unicast_offset = vf_vlan_max_flows;
176+
flow_cfg->rx_vlan_offset = flow_cfg->unicast_offset +
177+
OTX2_MAX_UNICAST_FLOWS;
178+
pfvf->flags |= OTX2_FLAG_UCAST_FLTR_SUPPORT;
179+
pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
180+
pfvf->flags |= OTX2_FLAG_VF_VLAN_SUPPORT;
181+
182+
pfvf->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC;
83183
mutex_unlock(&pfvf->mbox.lock);
84184

185+
/* Allocate entries for Ntuple filters */
186+
count = otx2_alloc_ntuple_mcam_entries(pfvf, OTX2_DEFAULT_FLOWCOUNT);
187+
if (count <= 0) {
188+
otx2_clear_ntuple_flow_info(pfvf, flow_cfg);
189+
return 0;
190+
}
191+
192+
pfvf->flags |= OTX2_FLAG_NTUPLE_SUPPORT;
193+
pfvf->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT;
194+
85195
return 0;
86196
}
87197

@@ -96,13 +206,14 @@ int otx2_mcam_flow_init(struct otx2_nic *pf)
96206

97207
INIT_LIST_HEAD(&pf->flow_cfg->flow_list);
98208

99-
pf->flow_cfg->ntuple_max_flows = OTX2_MAX_NTUPLE_FLOWS;
100-
pf->flow_cfg->tc_max_flows = pf->flow_cfg->ntuple_max_flows;
101-
102209
err = otx2_alloc_mcam_entries(pf);
103210
if (err)
104211
return err;
105212

213+
/* Check if MCAM entries are allocate or not */
214+
if (!(pf->flags & OTX2_FLAG_UCAST_FLTR_SUPPORT))
215+
return 0;
216+
106217
pf->mac_table = devm_kzalloc(pf->dev, sizeof(struct otx2_mac_table)
107218
* OTX2_MAX_UNICAST_FLOWS, GFP_KERNEL);
108219
if (!pf->mac_table)
@@ -146,7 +257,7 @@ static int otx2_do_add_macfilter(struct otx2_nic *pf, const u8 *mac)
146257
ether_addr_copy(pf->mac_table[i].addr, mac);
147258
pf->mac_table[i].inuse = true;
148259
pf->mac_table[i].mcam_entry =
149-
flow_cfg->entry[i + flow_cfg->unicast_offset];
260+
flow_cfg->def_ent[i + flow_cfg->unicast_offset];
150261
req->entry = pf->mac_table[i].mcam_entry;
151262
break;
152263
}
@@ -732,8 +843,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc)
732843
if (!flow)
733844
return -ENOMEM;
734845
flow->location = fsp->location;
735-
flow->entry = flow_cfg->entry[flow_cfg->ntuple_offset +
736-
flow->location];
846+
flow->entry = flow_cfg->flow_ent[flow->location];
737847
new = true;
738848
}
739849
/* struct copy */
@@ -837,9 +947,8 @@ int otx2_destroy_ntuple_flows(struct otx2_nic *pfvf)
837947
return -ENOMEM;
838948
}
839949

840-
req->start = flow_cfg->entry[flow_cfg->ntuple_offset];
841-
req->end = flow_cfg->entry[flow_cfg->ntuple_offset +
842-
flow_cfg->ntuple_max_flows - 1];
950+
req->start = flow_cfg->flow_ent[0];
951+
req->end = flow_cfg->flow_ent[flow_cfg->ntuple_max_flows - 1];
843952
err = otx2_sync_mbox_msg(&pfvf->mbox);
844953
mutex_unlock(&pfvf->mbox.lock);
845954

@@ -906,7 +1015,7 @@ int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf)
9061015
return -ENOMEM;
9071016
}
9081017

909-
req->entry = flow_cfg->entry[flow_cfg->rx_vlan_offset];
1018+
req->entry = flow_cfg->def_ent[flow_cfg->rx_vlan_offset];
9101019
req->intf = NIX_INTF_RX;
9111020
ether_addr_copy(req->packet.dmac, pfvf->netdev->dev_addr);
9121021
eth_broadcast_addr((u8 *)&req->mask.dmac);
@@ -935,7 +1044,7 @@ static int otx2_delete_rxvlan_offload_flow(struct otx2_nic *pfvf)
9351044
return -ENOMEM;
9361045
}
9371046

938-
req->entry = flow_cfg->entry[flow_cfg->rx_vlan_offset];
1047+
req->entry = flow_cfg->def_ent[flow_cfg->rx_vlan_offset];
9391048
/* Send message to AF */
9401049
err = otx2_sync_mbox_msg(&pfvf->mbox);
9411050
mutex_unlock(&pfvf->mbox.lock);

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,7 +2109,7 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
21092109
}
21102110
idx = ((vf * OTX2_PER_VF_VLAN_FLOWS) + OTX2_VF_VLAN_RX_INDEX);
21112111
del_req->entry =
2112-
flow_cfg->entry[flow_cfg->vf_vlan_offset + idx];
2112+
flow_cfg->def_ent[flow_cfg->vf_vlan_offset + idx];
21132113
err = otx2_sync_mbox_msg(&pf->mbox);
21142114
if (err)
21152115
goto out;
@@ -2122,7 +2122,7 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
21222122
}
21232123
idx = ((vf * OTX2_PER_VF_VLAN_FLOWS) + OTX2_VF_VLAN_TX_INDEX);
21242124
del_req->entry =
2125-
flow_cfg->entry[flow_cfg->vf_vlan_offset + idx];
2125+
flow_cfg->def_ent[flow_cfg->vf_vlan_offset + idx];
21262126
err = otx2_sync_mbox_msg(&pf->mbox);
21272127

21282128
goto out;
@@ -2136,7 +2136,7 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
21362136
}
21372137

21382138
idx = ((vf * OTX2_PER_VF_VLAN_FLOWS) + OTX2_VF_VLAN_RX_INDEX);
2139-
req->entry = flow_cfg->entry[flow_cfg->vf_vlan_offset + idx];
2139+
req->entry = flow_cfg->def_ent[flow_cfg->vf_vlan_offset + idx];
21402140
req->packet.vlan_tci = htons(vlan);
21412141
req->mask.vlan_tci = htons(VLAN_VID_MASK);
21422142
/* af fills the destination mac addr */
@@ -2187,7 +2187,7 @@ static int otx2_do_set_vf_vlan(struct otx2_nic *pf, int vf, u16 vlan, u8 qos,
21872187

21882188
eth_zero_addr((u8 *)&req->mask.dmac);
21892189
idx = ((vf * OTX2_PER_VF_VLAN_FLOWS) + OTX2_VF_VLAN_TX_INDEX);
2190-
req->entry = flow_cfg->entry[flow_cfg->vf_vlan_offset + idx];
2190+
req->entry = flow_cfg->def_ent[flow_cfg->vf_vlan_offset + idx];
21912191
req->features = BIT_ULL(NPC_DMAC);
21922192
req->channel = pf->hw.tx_chan_base;
21932193
req->intf = NIX_INTF_TX;

drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,8 @@ static int otx2_tc_add_flow(struct otx2_nic *nic,
570570
new_node->bitpos = find_first_zero_bit(tc_info->tc_entries_bitmap,
571571
nic->flow_cfg->tc_max_flows);
572572
req->channel = nic->hw.rx_chan_base;
573-
req->entry = nic->flow_cfg->entry[nic->flow_cfg->tc_flower_offset +
574-
nic->flow_cfg->tc_max_flows - new_node->bitpos];
573+
req->entry = nic->flow_cfg->flow_ent[nic->flow_cfg->tc_flower_offset +
574+
nic->flow_cfg->tc_max_flows - new_node->bitpos];
575575
req->intf = NIX_INTF_RX;
576576
req->set_cntr = 1;
577577
new_node->entry = req->entry;

0 commit comments

Comments
 (0)