Linux-libre 5.7.6-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / mscc / ocelot_ace.c
1 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
2 /* Microsemi Ocelot Switch driver
3  * Copyright (c) 2019 Microsemi Corporation
4  */
5
6 #include <linux/iopoll.h>
7 #include <linux/proc_fs.h>
8
9 #include <soc/mscc/ocelot_vcap.h>
10 #include "ocelot_police.h"
11 #include "ocelot_ace.h"
12 #include "ocelot_s2.h"
13
14 #define OCELOT_POLICER_DISCARD 0x17f
15 #define ENTRY_WIDTH 32
16
17 enum vcap_sel {
18         VCAP_SEL_ENTRY = 0x1,
19         VCAP_SEL_ACTION = 0x2,
20         VCAP_SEL_COUNTER = 0x4,
21         VCAP_SEL_ALL = 0x7,
22 };
23
24 enum vcap_cmd {
25         VCAP_CMD_WRITE = 0, /* Copy from Cache to TCAM */
26         VCAP_CMD_READ = 1, /* Copy from TCAM to Cache */
27         VCAP_CMD_MOVE_UP = 2, /* Move <count> up */
28         VCAP_CMD_MOVE_DOWN = 3, /* Move <count> down */
29         VCAP_CMD_INITIALIZE = 4, /* Write all (from cache) */
30 };
31
32 #define VCAP_ENTRY_WIDTH 12 /* Max entry width (32bit words) */
33 #define VCAP_COUNTER_WIDTH 4 /* Max counter width (32bit words) */
34
35 struct vcap_data {
36         u32 entry[VCAP_ENTRY_WIDTH]; /* ENTRY_DAT */
37         u32 mask[VCAP_ENTRY_WIDTH]; /* MASK_DAT */
38         u32 action[VCAP_ENTRY_WIDTH]; /* ACTION_DAT */
39         u32 counter[VCAP_COUNTER_WIDTH]; /* CNT_DAT */
40         u32 tg; /* TG_DAT */
41         u32 type; /* Action type */
42         u32 tg_sw; /* Current type-group */
43         u32 cnt; /* Current counter */
44         u32 key_offset; /* Current entry offset */
45         u32 action_offset; /* Current action offset */
46         u32 counter_offset; /* Current counter offset */
47         u32 tg_value; /* Current type-group value */
48         u32 tg_mask; /* Current type-group mask */
49 };
50
51 static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot)
52 {
53         return ocelot_read(ocelot, S2_CORE_UPDATE_CTRL);
54 }
55
56 static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel)
57 {
58         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
59
60         u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
61                      S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
62                      S2_CORE_UPDATE_CTRL_UPDATE_SHOT);
63
64         if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2->entry_count)
65                 return;
66
67         if (!(sel & VCAP_SEL_ENTRY))
68                 value |= S2_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS;
69
70         if (!(sel & VCAP_SEL_ACTION))
71                 value |= S2_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS;
72
73         if (!(sel & VCAP_SEL_COUNTER))
74                 value |= S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;
75
76         ocelot_write(ocelot, value, S2_CORE_UPDATE_CTRL);
77         readx_poll_timeout(vcap_s2_read_update_ctrl, ocelot, value,
78                                 (value & S2_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
79                                 10, 100000);
80 }
81
82 /* Convert from 0-based row to VCAP entry row and run command */
83 static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel)
84 {
85         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
86
87         vcap_cmd(ocelot, vcap_is2->entry_count - row - 1, cmd, sel);
88 }
89
90 static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data)
91 {
92         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
93         u32 entry_words, i;
94
95         entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
96
97         for (i = 0; i < entry_words; i++) {
98                 ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i);
99                 ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i);
100         }
101         ocelot_write(ocelot, data->tg, S2_CACHE_TG_DAT);
102 }
103
104 static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data)
105 {
106         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
107         u32 entry_words, i;
108
109         entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH);
110
111         for (i = 0; i < entry_words; i++) {
112                 data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i);
113                 // Invert mask
114                 data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i);
115         }
116         data->tg = ocelot_read(ocelot, S2_CACHE_TG_DAT);
117 }
118
119 static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data)
120 {
121         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
122         u32 action_words, i, width, mask;
123
124         /* Encode action type */
125         width = vcap_is2->action_type_width;
126         if (width) {
127                 mask = GENMASK(width, 0);
128                 data->action[0] = ((data->action[0] & ~mask) | data->type);
129         }
130
131         action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
132
133         for (i = 0; i < action_words; i++)
134                 ocelot_write_rix(ocelot, data->action[i], S2_CACHE_ACTION_DAT,
135                                  i);
136
137         for (i = 0; i < vcap_is2->counter_words; i++)
138                 ocelot_write_rix(ocelot, data->counter[i], S2_CACHE_CNT_DAT, i);
139 }
140
141 static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data)
142 {
143         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
144         u32 action_words, i, width;
145
146         action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH);
147
148         for (i = 0; i < action_words; i++)
149                 data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT,
150                                                   i);
151
152         for (i = 0; i < vcap_is2->counter_words; i++)
153                 data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i);
154
155         /* Extract action type */
156         width = vcap_is2->action_type_width;
157         data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
158 }
159
160 /* Calculate offsets for entry */
161 static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix)
162 {
163         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
164         u32 i, col, offset, count, cnt, base;
165         u32 width = vcap_is2->tg_width;
166
167         count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4);
168         col = (ix % 2);
169         cnt = (vcap_is2->sw_count / count);
170         base = (vcap_is2->sw_count - col * cnt - cnt);
171         data->tg_value = 0;
172         data->tg_mask = 0;
173         for (i = 0; i < cnt; i++) {
174                 offset = ((base + i) * width);
175                 data->tg_value |= (data->tg_sw << offset);
176                 data->tg_mask |= GENMASK(offset + width - 1, offset);
177         }
178
179         /* Calculate key/action/counter offsets */
180         col = (count - col - 1);
181         data->key_offset = (base * vcap_is2->entry_width) / vcap_is2->sw_count;
182         data->counter_offset = (cnt * col * vcap_is2->counter_width);
183         i = data->type;
184         width = vcap_is2->action_table[i].width;
185         cnt = vcap_is2->action_table[i].count;
186         data->action_offset =
187                 (((cnt * col * width) / count) + vcap_is2->action_type_width);
188 }
189
190 static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
191 {
192         u32 i, v, m;
193
194         for (i = 0; i < len; i++, offset++) {
195                 v = data[offset / ENTRY_WIDTH];
196                 m = (1 << (offset % ENTRY_WIDTH));
197                 if (value & (1 << i))
198                         v |= m;
199                 else
200                         v &= ~m;
201                 data[offset / ENTRY_WIDTH] = v;
202         }
203 }
204
205 static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
206 {
207         u32 i, v, m, value = 0;
208
209         for (i = 0; i < len; i++, offset++) {
210                 v = data[offset / ENTRY_WIDTH];
211                 m = (1 << (offset % ENTRY_WIDTH));
212                 if (v & m)
213                         value |= (1 << i);
214         }
215         return value;
216 }
217
218 static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
219                                u32 value, u32 mask)
220 {
221         vcap_data_set(data->entry, offset + data->key_offset, width, value);
222         vcap_data_set(data->mask, offset + data->key_offset, width, mask);
223 }
224
225 static void vcap_key_set(struct ocelot *ocelot, struct vcap_data *data,
226                          enum vcap_is2_half_key_field field,
227                          u32 value, u32 mask)
228 {
229         u32 offset = ocelot->vcap_is2_keys[field].offset;
230         u32 length = ocelot->vcap_is2_keys[field].length;
231
232         vcap_key_field_set(data, offset, length, value, mask);
233 }
234
235 static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data,
236                                enum vcap_is2_half_key_field field,
237                                u8 *val, u8 *msk)
238 {
239         u32 offset = ocelot->vcap_is2_keys[field].offset;
240         u32 count  = ocelot->vcap_is2_keys[field].length;
241         u32 i, j, n = 0, value = 0, mask = 0;
242
243         WARN_ON(count % 8);
244
245         /* Data wider than 32 bits are split up in chunks of maximum 32 bits.
246          * The 32 LSB of the data are written to the 32 MSB of the TCAM.
247          */
248         offset += count;
249         count /= 8;
250
251         for (i = 0; i < count; i++) {
252                 j = (count - i - 1);
253                 value += (val[j] << n);
254                 mask += (msk[j] << n);
255                 n += 8;
256                 if (n == ENTRY_WIDTH || (i + 1) == count) {
257                         offset -= n;
258                         vcap_key_field_set(data, offset, n, value, mask);
259                         n = 0;
260                         value = 0;
261                         mask = 0;
262                 }
263         }
264 }
265
266 static void vcap_key_l4_port_set(struct ocelot *ocelot, struct vcap_data *data,
267                                  enum vcap_is2_half_key_field field,
268                                  struct ocelot_vcap_udp_tcp *port)
269 {
270         u32 offset = ocelot->vcap_is2_keys[field].offset;
271         u32 length = ocelot->vcap_is2_keys[field].length;
272
273         WARN_ON(length != 16);
274
275         vcap_key_field_set(data, offset, length, port->value, port->mask);
276 }
277
278 static void vcap_key_bit_set(struct ocelot *ocelot, struct vcap_data *data,
279                              enum vcap_is2_half_key_field field,
280                              enum ocelot_vcap_bit val)
281 {
282         u32 offset = ocelot->vcap_is2_keys[field].offset;
283         u32 length = ocelot->vcap_is2_keys[field].length;
284         u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
285         u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
286
287         WARN_ON(length != 1);
288
289         vcap_key_field_set(data, offset, length, value, msk);
290 }
291
292 static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data,
293                             enum vcap_is2_action_field field, u32 value)
294 {
295         int offset = ocelot->vcap_is2_actions[field].offset;
296         int length = ocelot->vcap_is2_actions[field].length;
297
298         vcap_data_set(data->action, offset + data->action_offset, length,
299                       value);
300 }
301
302 static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
303                            struct ocelot_ace_rule *ace)
304 {
305         switch (ace->action) {
306         case OCELOT_ACL_ACTION_DROP:
307                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
308                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
309                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
310                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
311                                 OCELOT_POLICER_DISCARD);
312                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
313                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
314                 break;
315         case OCELOT_ACL_ACTION_TRAP:
316                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
317                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
318                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0);
319                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, 0);
320                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
321                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1);
322                 break;
323         case OCELOT_ACL_ACTION_POLICE:
324                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
325                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 0);
326                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
327                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
328                                 ace->pol_ix);
329                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
330                 vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
331                 break;
332         }
333 }
334
335 static void is2_entry_set(struct ocelot *ocelot, int ix,
336                           struct ocelot_ace_rule *ace)
337 {
338         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
339         u32 val, msk, type, type_mask = 0xf, i, count;
340         struct ocelot_ace_vlan *tag = &ace->vlan;
341         struct ocelot_vcap_u64 payload;
342         struct vcap_data data;
343         int row = (ix / 2);
344
345         memset(&payload, 0, sizeof(payload));
346         memset(&data, 0, sizeof(data));
347
348         /* Read row */
349         vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_ALL);
350         vcap_cache2entry(ocelot, &data);
351         vcap_cache2action(ocelot, &data);
352
353         data.tg_sw = VCAP_TG_HALF;
354         is2_data_get(ocelot, &data, ix);
355         data.tg = (data.tg & ~data.tg_mask);
356         if (ace->prio != 0)
357                 data.tg |= data.tg_value;
358
359         data.type = IS2_ACTION_TYPE_NORMAL;
360
361         vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0);
362         vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
363                      ~ace->ingress_port_mask);
364         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1);
365         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH,
366                          OCELOT_VCAP_BIT_ANY);
367         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc);
368         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc);
369         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
370         vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID,
371                      tag->vid.value, tag->vid.mask);
372         vcap_key_set(ocelot, &data, VCAP_IS2_HK_PCP,
373                      tag->pcp.value[0], tag->pcp.mask[0]);
374         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei);
375
376         switch (ace->type) {
377         case OCELOT_ACE_TYPE_ETYPE: {
378                 struct ocelot_ace_frame_etype *etype = &ace->frame.etype;
379
380                 type = IS2_TYPE_ETYPE;
381                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
382                                    etype->dmac.value, etype->dmac.mask);
383                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
384                                    etype->smac.value, etype->smac.mask);
385                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
386                                    etype->etype.value, etype->etype.mask);
387                 /* Clear unused bits */
388                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
389                              0, 0);
390                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
391                              0, 0);
392                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
393                              0, 0);
394                 vcap_key_bytes_set(ocelot, &data,
395                                    VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
396                                    etype->data.value, etype->data.mask);
397                 break;
398         }
399         case OCELOT_ACE_TYPE_LLC: {
400                 struct ocelot_ace_frame_llc *llc = &ace->frame.llc;
401
402                 type = IS2_TYPE_LLC;
403                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
404                                    llc->dmac.value, llc->dmac.mask);
405                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
406                                    llc->smac.value, llc->smac.mask);
407                 for (i = 0; i < 4; i++) {
408                         payload.value[i] = llc->llc.value[i];
409                         payload.mask[i] = llc->llc.mask[i];
410                 }
411                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
412                                    payload.value, payload.mask);
413                 break;
414         }
415         case OCELOT_ACE_TYPE_SNAP: {
416                 struct ocelot_ace_frame_snap *snap = &ace->frame.snap;
417
418                 type = IS2_TYPE_SNAP;
419                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC,
420                                    snap->dmac.value, snap->dmac.mask);
421                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC,
422                                    snap->smac.value, snap->smac.mask);
423                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
424                                    ace->frame.snap.snap.value,
425                                    ace->frame.snap.snap.mask);
426                 break;
427         }
428         case OCELOT_ACE_TYPE_ARP: {
429                 struct ocelot_ace_frame_arp *arp = &ace->frame.arp;
430
431                 type = IS2_TYPE_ARP;
432                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
433                                    arp->smac.value, arp->smac.mask);
434                 vcap_key_bit_set(ocelot, &data,
435                                  VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
436                                  arp->ethernet);
437                 vcap_key_bit_set(ocelot, &data,
438                                  VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
439                                  arp->ip);
440                 vcap_key_bit_set(ocelot, &data,
441                                  VCAP_IS2_HK_MAC_ARP_LEN_OK,
442                                  arp->length);
443                 vcap_key_bit_set(ocelot, &data,
444                                  VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
445                                  arp->dmac_match);
446                 vcap_key_bit_set(ocelot, &data,
447                                  VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
448                                  arp->smac_match);
449                 vcap_key_bit_set(ocelot, &data,
450                                  VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
451                                  arp->unknown);
452
453                 /* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
454                 val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
455                        (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0));
456                 msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) |
457                        (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2));
458                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
459                              val, msk);
460                 vcap_key_bytes_set(ocelot, &data,
461                                    VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
462                                    arp->dip.value.addr, arp->dip.mask.addr);
463                 vcap_key_bytes_set(ocelot, &data,
464                                    VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
465                                    arp->sip.value.addr, arp->sip.mask.addr);
466                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
467                              0, 0);
468                 break;
469         }
470         case OCELOT_ACE_TYPE_IPV4:
471         case OCELOT_ACE_TYPE_IPV6: {
472                 enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport, seq_zero, tcp;
473                 enum ocelot_vcap_bit ttl, fragment, options, tcp_ack, tcp_urg;
474                 enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh;
475                 struct ocelot_ace_frame_ipv4 *ipv4 = NULL;
476                 struct ocelot_ace_frame_ipv6 *ipv6 = NULL;
477                 struct ocelot_vcap_udp_tcp *sport, *dport;
478                 struct ocelot_vcap_ipv4 sip, dip;
479                 struct ocelot_vcap_u8 proto, ds;
480                 struct ocelot_vcap_u48 *ip_data;
481
482                 if (ace->type == OCELOT_ACE_TYPE_IPV4) {
483                         ipv4 = &ace->frame.ipv4;
484                         ttl = ipv4->ttl;
485                         fragment = ipv4->fragment;
486                         options = ipv4->options;
487                         proto = ipv4->proto;
488                         ds = ipv4->ds;
489                         ip_data = &ipv4->data;
490                         sip = ipv4->sip;
491                         dip = ipv4->dip;
492                         sport = &ipv4->sport;
493                         dport = &ipv4->dport;
494                         tcp_fin = ipv4->tcp_fin;
495                         tcp_syn = ipv4->tcp_syn;
496                         tcp_rst = ipv4->tcp_rst;
497                         tcp_psh = ipv4->tcp_psh;
498                         tcp_ack = ipv4->tcp_ack;
499                         tcp_urg = ipv4->tcp_urg;
500                         sip_eq_dip = ipv4->sip_eq_dip;
501                         sport_eq_dport = ipv4->sport_eq_dport;
502                         seq_zero = ipv4->seq_zero;
503                 } else {
504                         ipv6 = &ace->frame.ipv6;
505                         ttl = ipv6->ttl;
506                         fragment = OCELOT_VCAP_BIT_ANY;
507                         options = OCELOT_VCAP_BIT_ANY;
508                         proto = ipv6->proto;
509                         ds = ipv6->ds;
510                         ip_data = &ipv6->data;
511                         for (i = 0; i < 8; i++) {
512                                 val = ipv6->sip.value[i + 8];
513                                 msk = ipv6->sip.mask[i + 8];
514                                 if (i < 4) {
515                                         dip.value.addr[i] = val;
516                                         dip.mask.addr[i] = msk;
517                                 } else {
518                                         sip.value.addr[i - 4] = val;
519                                         sip.mask.addr[i - 4] = msk;
520                                 }
521                         }
522                         sport = &ipv6->sport;
523                         dport = &ipv6->dport;
524                         tcp_fin = ipv6->tcp_fin;
525                         tcp_syn = ipv6->tcp_syn;
526                         tcp_rst = ipv6->tcp_rst;
527                         tcp_psh = ipv6->tcp_psh;
528                         tcp_ack = ipv6->tcp_ack;
529                         tcp_urg = ipv6->tcp_urg;
530                         sip_eq_dip = ipv6->sip_eq_dip;
531                         sport_eq_dport = ipv6->sport_eq_dport;
532                         seq_zero = ipv6->seq_zero;
533                 }
534
535                 vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4,
536                                  ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
537                 vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_FRAGMENT,
538                                  fragment);
539                 vcap_key_set(ocelot, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0);
540                 vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_OPTIONS,
541                                  options);
542                 vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
543                                  ttl);
544                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_TOS,
545                                    ds.value, ds.mask);
546                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_DIP,
547                                    dip.value.addr, dip.mask.addr);
548                 vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_SIP,
549                                    sip.value.addr, sip.mask.addr);
550                 vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DIP_EQ_SIP,
551                                  sip_eq_dip);
552                 val = proto.value[0];
553                 msk = proto.mask[0];
554                 type = IS2_TYPE_IP_UDP_TCP;
555                 if (msk == 0xff && (val == 6 || val == 17)) {
556                         /* UDP/TCP protocol match */
557                         tcp = (val == 6 ?
558                                OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
559                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_TCP, tcp);
560                         vcap_key_l4_port_set(ocelot, &data,
561                                              VCAP_IS2_HK_L4_DPORT, dport);
562                         vcap_key_l4_port_set(ocelot, &data,
563                                              VCAP_IS2_HK_L4_SPORT, sport);
564                         vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
565                         vcap_key_bit_set(ocelot, &data,
566                                          VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
567                                          sport_eq_dport);
568                         vcap_key_bit_set(ocelot, &data,
569                                          VCAP_IS2_HK_L4_SEQUENCE_EQ0,
570                                          seq_zero);
571                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_FIN,
572                                          tcp_fin);
573                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_SYN,
574                                          tcp_syn);
575                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_RST,
576                                          tcp_rst);
577                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_PSH,
578                                          tcp_psh);
579                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_ACK,
580                                          tcp_ack);
581                         vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_URG,
582                                          tcp_urg);
583                         vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_DOM,
584                                      0, 0);
585                         vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_VER,
586                                      0, 0);
587                 } else {
588                         if (msk == 0) {
589                                 /* Any IP protocol match */
590                                 type_mask = IS2_TYPE_MASK_IP_ANY;
591                         } else {
592                                 /* Non-UDP/TCP protocol match */
593                                 type = IS2_TYPE_IP_OTHER;
594                                 for (i = 0; i < 6; i++) {
595                                         payload.value[i] = ip_data->value[i];
596                                         payload.mask[i] = ip_data->mask[i];
597                                 }
598                         }
599                         vcap_key_bytes_set(ocelot, &data,
600                                            VCAP_IS2_HK_IP4_L3_PROTO,
601                                            proto.value, proto.mask);
602                         vcap_key_bytes_set(ocelot, &data,
603                                            VCAP_IS2_HK_L3_PAYLOAD,
604                                            payload.value, payload.mask);
605                 }
606                 break;
607         }
608         case OCELOT_ACE_TYPE_ANY:
609         default:
610                 type = 0;
611                 type_mask = 0;
612                 count = vcap_is2->entry_width / 2;
613                 /* Iterate over the non-common part of the key and
614                  * clear entry data
615                  */
616                 for (i = ocelot->vcap_is2_keys[VCAP_IS2_HK_L2_DMAC].offset;
617                      i < count; i += ENTRY_WIDTH) {
618                         vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
619                 }
620                 break;
621         }
622
623         vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
624         is2_action_set(ocelot, &data, ace);
625         vcap_data_set(data.counter, data.counter_offset,
626                       vcap_is2->counter_width, ace->stats.pkts);
627
628         /* Write row */
629         vcap_entry2cache(ocelot, &data);
630         vcap_action2cache(ocelot, &data);
631         vcap_row_cmd(ocelot, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
632 }
633
634 static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
635                           int ix)
636 {
637         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
638         struct vcap_data data;
639         int row = (ix / 2);
640         u32 cnt;
641
642         vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
643         vcap_cache2action(ocelot, &data);
644         data.tg_sw = VCAP_TG_HALF;
645         is2_data_get(ocelot, &data, ix);
646         cnt = vcap_data_get(data.counter, data.counter_offset,
647                             vcap_is2->counter_width);
648
649         rule->stats.pkts = cnt;
650 }
651
652 static void ocelot_ace_rule_add(struct ocelot *ocelot,
653                                 struct ocelot_acl_block *block,
654                                 struct ocelot_ace_rule *rule)
655 {
656         struct ocelot_ace_rule *tmp;
657         struct list_head *pos, *n;
658
659         if (rule->action == OCELOT_ACL_ACTION_POLICE) {
660                 block->pol_lpr--;
661                 rule->pol_ix = block->pol_lpr;
662                 ocelot_ace_policer_add(ocelot, rule->pol_ix, &rule->pol);
663         }
664
665         block->count++;
666
667         if (list_empty(&block->rules)) {
668                 list_add(&rule->list, &block->rules);
669                 return;
670         }
671
672         list_for_each_safe(pos, n, &block->rules) {
673                 tmp = list_entry(pos, struct ocelot_ace_rule, list);
674                 if (rule->prio < tmp->prio)
675                         break;
676         }
677         list_add(&rule->list, pos->prev);
678 }
679
680 static int ocelot_ace_rule_get_index_id(struct ocelot_acl_block *block,
681                                         struct ocelot_ace_rule *rule)
682 {
683         struct ocelot_ace_rule *tmp;
684         int index = -1;
685
686         list_for_each_entry(tmp, &block->rules, list) {
687                 ++index;
688                 if (rule->id == tmp->id)
689                         break;
690         }
691         return index;
692 }
693
694 static struct ocelot_ace_rule*
695 ocelot_ace_rule_get_rule_index(struct ocelot_acl_block *block, int index)
696 {
697         struct ocelot_ace_rule *tmp;
698         int i = 0;
699
700         list_for_each_entry(tmp, &block->rules, list) {
701                 if (i == index)
702                         return tmp;
703                 ++i;
704         }
705
706         return NULL;
707 }
708
709 /* If @on=false, then SNAP, ARP, IP and OAM frames will not match on keys based
710  * on destination and source MAC addresses, but only on higher-level protocol
711  * information. The only frame types to match on keys containing MAC addresses
712  * in this case are non-SNAP, non-ARP, non-IP and non-OAM frames.
713  *
714  * If @on=true, then the above frame types (SNAP, ARP, IP and OAM) will match
715  * on MAC_ETYPE keys such as destination and source MAC on this ingress port.
716  * However the setting has the side effect of making these frames not matching
717  * on any _other_ keys than MAC_ETYPE ones.
718  */
719 static void ocelot_match_all_as_mac_etype(struct ocelot *ocelot, int port,
720                                           bool on)
721 {
722         u32 val = 0;
723
724         if (on)
725                 val = ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(3) |
726                       ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(3) |
727                       ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(3) |
728                       ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(3) |
729                       ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(3);
730
731         ocelot_rmw_gix(ocelot, val,
732                        ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS_M |
733                        ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS_M |
734                        ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS_M |
735                        ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS_M |
736                        ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS_M,
737                        ANA_PORT_VCAP_S2_CFG, port);
738 }
739
740 static bool ocelot_ace_is_problematic_mac_etype(struct ocelot_ace_rule *ace)
741 {
742         if (ace->type != OCELOT_ACE_TYPE_ETYPE)
743                 return false;
744         if (ether_addr_to_u64(ace->frame.etype.dmac.value) &
745             ether_addr_to_u64(ace->frame.etype.dmac.mask))
746                 return true;
747         if (ether_addr_to_u64(ace->frame.etype.smac.value) &
748             ether_addr_to_u64(ace->frame.etype.smac.mask))
749                 return true;
750         return false;
751 }
752
753 static bool ocelot_ace_is_problematic_non_mac_etype(struct ocelot_ace_rule *ace)
754 {
755         if (ace->type == OCELOT_ACE_TYPE_SNAP)
756                 return true;
757         if (ace->type == OCELOT_ACE_TYPE_ARP)
758                 return true;
759         if (ace->type == OCELOT_ACE_TYPE_IPV4)
760                 return true;
761         if (ace->type == OCELOT_ACE_TYPE_IPV6)
762                 return true;
763         return false;
764 }
765
766 static bool ocelot_exclusive_mac_etype_ace_rules(struct ocelot *ocelot,
767                                                  struct ocelot_ace_rule *ace)
768 {
769         struct ocelot_acl_block *block = &ocelot->acl_block;
770         struct ocelot_ace_rule *tmp;
771         unsigned long port;
772         int i;
773
774         if (ocelot_ace_is_problematic_mac_etype(ace)) {
775                 /* Search for any non-MAC_ETYPE rules on the port */
776                 for (i = 0; i < block->count; i++) {
777                         tmp = ocelot_ace_rule_get_rule_index(block, i);
778                         if (tmp->ingress_port_mask & ace->ingress_port_mask &&
779                             ocelot_ace_is_problematic_non_mac_etype(tmp))
780                                 return false;
781                 }
782
783                 for_each_set_bit(port, &ace->ingress_port_mask,
784                                  ocelot->num_phys_ports)
785                         ocelot_match_all_as_mac_etype(ocelot, port, true);
786         } else if (ocelot_ace_is_problematic_non_mac_etype(ace)) {
787                 /* Search for any MAC_ETYPE rules on the port */
788                 for (i = 0; i < block->count; i++) {
789                         tmp = ocelot_ace_rule_get_rule_index(block, i);
790                         if (tmp->ingress_port_mask & ace->ingress_port_mask &&
791                             ocelot_ace_is_problematic_mac_etype(tmp))
792                                 return false;
793                 }
794
795                 for_each_set_bit(port, &ace->ingress_port_mask,
796                                  ocelot->num_phys_ports)
797                         ocelot_match_all_as_mac_etype(ocelot, port, false);
798         }
799
800         return true;
801 }
802
803 int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
804                                 struct ocelot_ace_rule *rule,
805                                 struct netlink_ext_ack *extack)
806 {
807         struct ocelot_acl_block *block = &ocelot->acl_block;
808         struct ocelot_ace_rule *ace;
809         int i, index;
810
811         if (!ocelot_exclusive_mac_etype_ace_rules(ocelot, rule)) {
812                 NL_SET_ERR_MSG_MOD(extack,
813                                    "Cannot mix MAC_ETYPE with non-MAC_ETYPE rules");
814                 return -EBUSY;
815         }
816
817         /* Add rule to the linked list */
818         ocelot_ace_rule_add(ocelot, block, rule);
819
820         /* Get the index of the inserted rule */
821         index = ocelot_ace_rule_get_index_id(block, rule);
822
823         /* Move down the rules to make place for the new rule */
824         for (i = block->count - 1; i > index; i--) {
825                 ace = ocelot_ace_rule_get_rule_index(block, i);
826                 is2_entry_set(ocelot, i, ace);
827         }
828
829         /* Now insert the new rule */
830         is2_entry_set(ocelot, index, rule);
831         return 0;
832 }
833
834 static void ocelot_ace_police_del(struct ocelot *ocelot,
835                                   struct ocelot_acl_block *block,
836                                   u32 ix)
837 {
838         struct ocelot_ace_rule *ace;
839         int index = -1;
840
841         if (ix < block->pol_lpr)
842                 return;
843
844         list_for_each_entry(ace, &block->rules, list) {
845                 index++;
846                 if (ace->action == OCELOT_ACL_ACTION_POLICE &&
847                     ace->pol_ix < ix) {
848                         ace->pol_ix += 1;
849                         ocelot_ace_policer_add(ocelot, ace->pol_ix,
850                                                &ace->pol);
851                         is2_entry_set(ocelot, index, ace);
852                 }
853         }
854
855         ocelot_ace_policer_del(ocelot, block->pol_lpr);
856         block->pol_lpr++;
857 }
858
859 static void ocelot_ace_rule_del(struct ocelot *ocelot,
860                                 struct ocelot_acl_block *block,
861                                 struct ocelot_ace_rule *rule)
862 {
863         struct ocelot_ace_rule *tmp;
864         struct list_head *pos, *q;
865
866         list_for_each_safe(pos, q, &block->rules) {
867                 tmp = list_entry(pos, struct ocelot_ace_rule, list);
868                 if (tmp->id == rule->id) {
869                         if (tmp->action == OCELOT_ACL_ACTION_POLICE)
870                                 ocelot_ace_police_del(ocelot, block,
871                                                       tmp->pol_ix);
872
873                         list_del(pos);
874                         kfree(tmp);
875                 }
876         }
877
878         block->count--;
879 }
880
881 int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
882                                 struct ocelot_ace_rule *rule)
883 {
884         struct ocelot_acl_block *block = &ocelot->acl_block;
885         struct ocelot_ace_rule del_ace;
886         struct ocelot_ace_rule *ace;
887         int i, index;
888
889         memset(&del_ace, 0, sizeof(del_ace));
890
891         /* Gets index of the rule */
892         index = ocelot_ace_rule_get_index_id(block, rule);
893
894         /* Delete rule */
895         ocelot_ace_rule_del(ocelot, block, rule);
896
897         /* Move up all the blocks over the deleted rule */
898         for (i = index; i < block->count; i++) {
899                 ace = ocelot_ace_rule_get_rule_index(block, i);
900                 is2_entry_set(ocelot, i, ace);
901         }
902
903         /* Now delete the last rule, because it is duplicated */
904         is2_entry_set(ocelot, block->count, &del_ace);
905
906         return 0;
907 }
908
909 int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
910                                  struct ocelot_ace_rule *rule)
911 {
912         struct ocelot_acl_block *block = &ocelot->acl_block;
913         struct ocelot_ace_rule *tmp;
914         int index;
915
916         index = ocelot_ace_rule_get_index_id(block, rule);
917         is2_entry_get(ocelot, rule, index);
918
919         /* After we get the result we need to clear the counters */
920         tmp = ocelot_ace_rule_get_rule_index(block, index);
921         tmp->stats.pkts = 0;
922         is2_entry_set(ocelot, index, tmp);
923
924         return 0;
925 }
926
927 int ocelot_ace_init(struct ocelot *ocelot)
928 {
929         const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
930         struct ocelot_acl_block *block = &ocelot->acl_block;
931         struct vcap_data data;
932
933         memset(&data, 0, sizeof(data));
934
935         vcap_entry2cache(ocelot, &data);
936         ocelot_write(ocelot, vcap_is2->entry_count, S2_CORE_MV_CFG);
937         vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
938
939         vcap_action2cache(ocelot, &data);
940         ocelot_write(ocelot, vcap_is2->action_count, S2_CORE_MV_CFG);
941         vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE,
942                  VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
943
944         /* Create a policer that will drop the frames for the cpu.
945          * This policer will be used as action in the acl rules to drop
946          * frames.
947          */
948         ocelot_write_gix(ocelot, 0x299, ANA_POL_MODE_CFG,
949                          OCELOT_POLICER_DISCARD);
950         ocelot_write_gix(ocelot, 0x1, ANA_POL_PIR_CFG,
951                          OCELOT_POLICER_DISCARD);
952         ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_PIR_STATE,
953                          OCELOT_POLICER_DISCARD);
954         ocelot_write_gix(ocelot, 0x0, ANA_POL_CIR_CFG,
955                          OCELOT_POLICER_DISCARD);
956         ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE,
957                          OCELOT_POLICER_DISCARD);
958
959         block->pol_lpr = OCELOT_POLICER_DISCARD - 1;
960
961         INIT_LIST_HEAD(&ocelot->acl_block.rules);
962
963         return 0;
964 }