Skip to content

Commit 9912e6b

Browse files
jpirkodavem330
authored andcommitted
mlxsw: spectrum_acl: Add initial Spectrum-2 ACL implementation
Utilize only C-TCAM for now. Do very minimal A-TCAM initialization in order to make C-TCAM work. Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a6b9c87 commit 9912e6b

File tree

7 files changed

+334
-1
lines changed

7 files changed

+334
-1
lines changed

drivers/net/ethernet/mellanox/mlxsw/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
1818
spectrum1_kvdl.o spectrum2_kvdl.o \
1919
spectrum_kvdl.o \
2020
spectrum_acl_tcam.o spectrum_acl_ctcam.o \
21-
spectrum1_acl_tcam.o \
21+
spectrum_acl_atcam.o \
22+
spectrum1_acl_tcam.o spectrum2_acl_tcam.o \
2223
spectrum_acl.o \
2324
spectrum_flower.o spectrum_cnt.o \
2425
spectrum_fid.o spectrum_ipip.o \

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,12 @@ char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block)
430430
}
431431
EXPORT_SYMBOL(mlxsw_afa_block_first_set);
432432

433+
char *mlxsw_afa_block_cur_set(struct mlxsw_afa_block *block)
434+
{
435+
return block->cur_set->ht_key.enc_actions;
436+
}
437+
EXPORT_SYMBOL(mlxsw_afa_block_cur_set);
438+
433439
u32 mlxsw_afa_block_first_kvdl_index(struct mlxsw_afa_block *block)
434440
{
435441
/* First set is never in KVD linear. So the first set

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa);
6767
void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block);
6868
int mlxsw_afa_block_commit(struct mlxsw_afa_block *block);
6969
char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block);
70+
char *mlxsw_afa_block_cur_set(struct mlxsw_afa_block *block);
7071
u32 mlxsw_afa_block_first_kvdl_index(struct mlxsw_afa_block *block);
7172
int mlxsw_afa_block_activity_get(struct mlxsw_afa_block *block, bool *activity);
7273
int mlxsw_afa_block_continue(struct mlxsw_afa_block *block);

drivers/net/ethernet/mellanox/mlxsw/spectrum.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,9 @@ struct mlxsw_sp_acl_tcam_ops {
646646
/* spectrum1_acl_tcam.c */
647647
extern const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops;
648648

649+
/* spectrum2_acl_tcam.c */
650+
extern const struct mlxsw_sp_acl_tcam_ops mlxsw_sp2_acl_tcam_ops;
651+
649652
/* spectrum_acl_flex_actions.c */
650653
extern const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops;
651654
extern const struct mlxsw_afa_ops mlxsw_sp2_act_afa_ops;
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/*
2+
* drivers/net/ethernet/mellanox/mlxsw/spectrum2_acl_tcam.c
3+
* Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4+
* Copyright (c) 2018 Jiri Pirko <[email protected]>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in the
13+
* documentation and/or other materials provided with the distribution.
14+
* 3. Neither the names of the copyright holders nor the names of its
15+
* contributors may be used to endorse or promote products derived from
16+
* this software without specific prior written permission.
17+
*
18+
* Alternatively, this software may be distributed under the terms of the
19+
* GNU General Public License ("GPL") version 2 as published by the Free
20+
* Software Foundation.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32+
* POSSIBILITY OF SUCH DAMAGE.
33+
*/
34+
35+
#include <linux/kernel.h>
36+
37+
#include "spectrum.h"
38+
#include "spectrum_acl_tcam.h"
39+
#include "core_acl_flex_actions.h"
40+
41+
struct mlxsw_sp2_acl_tcam {
42+
u32 kvdl_index;
43+
unsigned int kvdl_count;
44+
};
45+
46+
struct mlxsw_sp2_acl_tcam_region {
47+
struct mlxsw_sp_acl_ctcam_region cregion;
48+
};
49+
50+
struct mlxsw_sp2_acl_tcam_chunk {
51+
struct mlxsw_sp_acl_ctcam_chunk cchunk;
52+
};
53+
54+
struct mlxsw_sp2_acl_tcam_entry {
55+
struct mlxsw_sp_acl_ctcam_entry centry;
56+
struct mlxsw_afa_block *act_block;
57+
};
58+
59+
static int mlxsw_sp2_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
60+
struct mlxsw_sp_acl_tcam *_tcam)
61+
{
62+
struct mlxsw_sp2_acl_tcam *tcam = priv;
63+
struct mlxsw_afa_block *afa_block;
64+
char pefa_pl[MLXSW_REG_PEFA_LEN];
65+
char pgcr_pl[MLXSW_REG_PGCR_LEN];
66+
char *enc_actions;
67+
int i;
68+
int err;
69+
70+
tcam->kvdl_count = _tcam->max_regions;
71+
err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
72+
tcam->kvdl_count, &tcam->kvdl_index);
73+
if (err)
74+
return err;
75+
76+
/* Create flex action block, set default action (continue)
77+
* but don't commit. We need just the current set encoding
78+
* to be written using PEFA register to all indexes for all regions.
79+
*/
80+
afa_block = mlxsw_afa_block_create(mlxsw_sp->afa);
81+
if (!afa_block) {
82+
err = -ENOMEM;
83+
goto err_afa_block;
84+
}
85+
err = mlxsw_afa_block_continue(afa_block);
86+
if (WARN_ON(err))
87+
goto err_afa_block_continue;
88+
enc_actions = mlxsw_afa_block_cur_set(afa_block);
89+
90+
for (i = 0; i < tcam->kvdl_count; i++) {
91+
mlxsw_reg_pefa_pack(pefa_pl, tcam->kvdl_index + i,
92+
true, enc_actions);
93+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pefa), pefa_pl);
94+
if (err)
95+
goto err_pefa_write;
96+
}
97+
mlxsw_reg_pgcr_pack(pgcr_pl, tcam->kvdl_index);
98+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pgcr), pgcr_pl);
99+
if (err)
100+
goto err_pgcr_write;
101+
102+
mlxsw_afa_block_destroy(afa_block);
103+
return 0;
104+
105+
err_pgcr_write:
106+
err_pefa_write:
107+
err_afa_block_continue:
108+
mlxsw_afa_block_destroy(afa_block);
109+
err_afa_block:
110+
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
111+
tcam->kvdl_count, tcam->kvdl_index);
112+
return err;
113+
}
114+
115+
static void mlxsw_sp2_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv)
116+
{
117+
struct mlxsw_sp2_acl_tcam *tcam = priv;
118+
119+
mlxsw_sp_kvdl_free(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_ACTSET,
120+
tcam->kvdl_count, tcam->kvdl_index);
121+
}
122+
123+
static int
124+
mlxsw_sp2_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv,
125+
struct mlxsw_sp_acl_tcam_region *_region)
126+
{
127+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
128+
int err;
129+
130+
err = mlxsw_sp_acl_atcam_region_init(mlxsw_sp, _region);
131+
if (err)
132+
return err;
133+
return mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &region->cregion,
134+
_region);
135+
}
136+
137+
static void
138+
mlxsw_sp2_acl_tcam_region_fini(struct mlxsw_sp *mlxsw_sp, void *region_priv)
139+
{
140+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
141+
142+
mlxsw_sp_acl_ctcam_region_fini(&region->cregion);
143+
}
144+
145+
static int
146+
mlxsw_sp2_acl_tcam_region_associate(struct mlxsw_sp *mlxsw_sp,
147+
struct mlxsw_sp_acl_tcam_region *region)
148+
{
149+
return mlxsw_sp_acl_atcam_region_associate(mlxsw_sp, region->id);
150+
}
151+
152+
static void mlxsw_sp2_acl_tcam_chunk_init(void *region_priv, void *chunk_priv,
153+
unsigned int priority)
154+
{
155+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
156+
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
157+
158+
mlxsw_sp_acl_ctcam_chunk_init(&region->cregion, &chunk->cchunk,
159+
priority);
160+
}
161+
162+
static void mlxsw_sp2_acl_tcam_chunk_fini(void *chunk_priv)
163+
{
164+
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
165+
166+
mlxsw_sp_acl_ctcam_chunk_fini(&chunk->cchunk);
167+
}
168+
169+
static int mlxsw_sp2_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
170+
void *region_priv, void *chunk_priv,
171+
void *entry_priv,
172+
struct mlxsw_sp_acl_rule_info *rulei)
173+
{
174+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
175+
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
176+
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
177+
178+
entry->act_block = rulei->act_block;
179+
return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->cregion,
180+
&chunk->cchunk, &entry->centry,
181+
rulei, true);
182+
}
183+
184+
static void mlxsw_sp2_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
185+
void *region_priv, void *chunk_priv,
186+
void *entry_priv)
187+
{
188+
struct mlxsw_sp2_acl_tcam_region *region = region_priv;
189+
struct mlxsw_sp2_acl_tcam_chunk *chunk = chunk_priv;
190+
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
191+
192+
mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->cregion,
193+
&chunk->cchunk, &entry->centry);
194+
}
195+
196+
static int
197+
mlxsw_sp2_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
198+
void *region_priv, void *entry_priv,
199+
bool *activity)
200+
{
201+
struct mlxsw_sp2_acl_tcam_entry *entry = entry_priv;
202+
203+
return mlxsw_afa_block_activity_get(entry->act_block, activity);
204+
}
205+
206+
const struct mlxsw_sp_acl_tcam_ops mlxsw_sp2_acl_tcam_ops = {
207+
.key_type = MLXSW_REG_PTAR_KEY_TYPE_FLEX2,
208+
.priv_size = sizeof(struct mlxsw_sp2_acl_tcam),
209+
.init = mlxsw_sp2_acl_tcam_init,
210+
.fini = mlxsw_sp2_acl_tcam_fini,
211+
.region_priv_size = sizeof(struct mlxsw_sp2_acl_tcam_region),
212+
.region_init = mlxsw_sp2_acl_tcam_region_init,
213+
.region_fini = mlxsw_sp2_acl_tcam_region_fini,
214+
.region_associate = mlxsw_sp2_acl_tcam_region_associate,
215+
.chunk_priv_size = sizeof(struct mlxsw_sp2_acl_tcam_chunk),
216+
.chunk_init = mlxsw_sp2_acl_tcam_chunk_init,
217+
.chunk_fini = mlxsw_sp2_acl_tcam_chunk_fini,
218+
.entry_priv_size = sizeof(struct mlxsw_sp2_acl_tcam_entry),
219+
.entry_add = mlxsw_sp2_acl_tcam_entry_add,
220+
.entry_del = mlxsw_sp2_acl_tcam_entry_del,
221+
.entry_activity_get = mlxsw_sp2_acl_tcam_entry_activity_get,
222+
};
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
3+
* Copyright (c) 2018 Mellanox Technologies. All rights reserved.
4+
* Copyright (c) 2018 Jiri Pirko <[email protected]>
5+
* Copyright (c) 2018 Ido Schimmel <[email protected]>
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. Neither the names of the copyright holders nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* Alternatively, this software may be distributed under the terms of the
20+
* GNU General Public License ("GPL") version 2 as published by the Free
21+
* Software Foundation.
22+
*
23+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33+
* POSSIBILITY OF SUCH DAMAGE.
34+
*/
35+
36+
#include <linux/kernel.h>
37+
#include <linux/errno.h>
38+
39+
#include "reg.h"
40+
#include "core.h"
41+
#include "spectrum.h"
42+
#include "spectrum_acl_tcam.h"
43+
44+
int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
45+
u16 region_id)
46+
{
47+
char perar_pl[MLXSW_REG_PERAR_LEN];
48+
/* For now, just assume that every region has 12 key blocks */
49+
u16 hw_region = region_id * 3;
50+
u64 max_regions;
51+
52+
max_regions = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_REGIONS);
53+
if (hw_region >= max_regions)
54+
return -ENOBUFS;
55+
56+
mlxsw_reg_perar_pack(perar_pl, region_id, hw_region);
57+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(perar), perar_pl);
58+
}
59+
60+
static int mlxsw_sp_acl_atcam_region_param_init(struct mlxsw_sp *mlxsw_sp,
61+
u16 region_id)
62+
{
63+
char percr_pl[MLXSW_REG_PERCR_LEN];
64+
65+
mlxsw_reg_percr_pack(percr_pl, region_id);
66+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl);
67+
}
68+
69+
static int
70+
mlxsw_sp_acl_atcam_region_erp_init(struct mlxsw_sp *mlxsw_sp,
71+
u16 region_id)
72+
{
73+
char pererp_pl[MLXSW_REG_PERERP_LEN];
74+
75+
mlxsw_reg_pererp_pack(pererp_pl, region_id);
76+
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
77+
}
78+
79+
int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
80+
struct mlxsw_sp_acl_tcam_region *region)
81+
{
82+
int err;
83+
84+
err = mlxsw_sp_acl_atcam_region_associate(mlxsw_sp, region->id);
85+
if (err)
86+
return err;
87+
err = mlxsw_sp_acl_atcam_region_param_init(mlxsw_sp, region->id);
88+
if (err)
89+
return err;
90+
err = mlxsw_sp_acl_atcam_region_erp_init(mlxsw_sp, region->id);
91+
if (err)
92+
return err;
93+
94+
return 0;
95+
}

drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,9 @@ mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
143143
return centry->parman_item.index;
144144
}
145145

146+
int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
147+
u16 region_id);
148+
int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
149+
struct mlxsw_sp_acl_tcam_region *region);
150+
146151
#endif

0 commit comments

Comments
 (0)