1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Atlantic Network Driver
3 * Copyright (C) 2020 Marvell International Ltd.
4 */
5
6 #include "macsec_api.h"
7 #include <linux/mdio.h>
8 #include "MSS_Ingress_registers.h"
9 #include "MSS_Egress_registers.h"
10 #include "aq_phy.h"
11
12 #define AQ_API_CALL_SAFE(func, ...) \
13 ({ \
14 int ret; \
15 do { \
16 ret = aq_mss_mdio_sem_get(hw); \
17 if (unlikely(ret)) \
18 break; \
19 \
20 ret = func(__VA_ARGS__); \
21 \
22 aq_mss_mdio_sem_put(hw); \
23 } while (0); \
24 ret; \
25 })
26
27 /*******************************************************************************
28 * MDIO wrappers
29 ******************************************************************************/
aq_mss_mdio_sem_get(struct aq_hw_s * hw)30 static int aq_mss_mdio_sem_get(struct aq_hw_s *hw)
31 {
32 u32 val;
33
34 return readx_poll_timeout_atomic(hw_atl_sem_mdio_get, hw, val,
35 val == 1U, 10U, 100000U);
36 }
37
aq_mss_mdio_sem_put(struct aq_hw_s * hw)38 static void aq_mss_mdio_sem_put(struct aq_hw_s *hw)
39 {
40 hw_atl_reg_glb_cpu_sem_set(hw, 1U, HW_ATL_FW_SM_MDIO);
41 }
42
aq_mss_mdio_read(struct aq_hw_s * hw,u16 mmd,u16 addr,u16 * data)43 static int aq_mss_mdio_read(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 *data)
44 {
45 *data = aq_mdio_read_word(hw, mmd, addr);
46 return (*data != 0xffff) ? 0 : -ETIME;
47 }
48
aq_mss_mdio_write(struct aq_hw_s * hw,u16 mmd,u16 addr,u16 data)49 static int aq_mss_mdio_write(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 data)
50 {
51 aq_mdio_write_word(hw, mmd, addr, data);
52 return 0;
53 }
54
55 /*******************************************************************************
56 * MACSEC config and status
57 ******************************************************************************/
58
set_raw_ingress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)59 static int set_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record,
60 u8 num_words, u8 table_id,
61 u16 table_index)
62 {
63 struct mss_ingress_lut_addr_ctl_register lut_sel_reg;
64 struct mss_ingress_lut_ctl_register lut_op_reg;
65
66 unsigned int i;
67
68 /* NOTE: MSS registers must always be read/written as adjacent pairs.
69 * For instance, to write either or both 1E.80A0 and 80A1, we have to:
70 * 1. Write 1E.80A0 first
71 * 2. Then write 1E.80A1
72 *
73 * For HHD devices: These writes need to be performed consecutively, and
74 * to ensure this we use the PIF mailbox to delegate the reads/writes to
75 * the FW.
76 *
77 * For EUR devices: Not need to use the PIF mailbox; it is safe to
78 * write to the registers directly.
79 */
80
81 /* Write the packed record words to the data buffer registers. */
82 for (i = 0; i < num_words; i += 2) {
83 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
84 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
85 packed_record[i]);
86 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
87 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i +
88 1,
89 packed_record[i + 1]);
90 }
91
92 /* Clear out the unused data buffer registers. */
93 for (i = num_words; i < 24; i += 2) {
94 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
95 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
96 0);
97 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
98 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, 0);
99 }
100
101 /* Select the table and row index to write to */
102 lut_sel_reg.bits_0.lut_select = table_id;
103 lut_sel_reg.bits_0.lut_addr = table_index;
104
105 lut_op_reg.bits_0.lut_read = 0;
106 lut_op_reg.bits_0.lut_write = 1;
107
108 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
109 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
110 lut_sel_reg.word_0);
111 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_INGRESS_LUT_CTL_REGISTER_ADDR,
112 lut_op_reg.word_0);
113
114 return 0;
115 }
116
117 /*! Read the specified Ingress LUT table row.
118 * packed_record - [OUT] The table row data (raw).
119 */
get_raw_ingress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)120 static int get_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record,
121 u8 num_words, u8 table_id,
122 u16 table_index)
123 {
124 struct mss_ingress_lut_addr_ctl_register lut_sel_reg;
125 struct mss_ingress_lut_ctl_register lut_op_reg;
126 int ret;
127
128 unsigned int i;
129
130 /* Select the table and row index to read */
131 lut_sel_reg.bits_0.lut_select = table_id;
132 lut_sel_reg.bits_0.lut_addr = table_index;
133
134 lut_op_reg.bits_0.lut_read = 1;
135 lut_op_reg.bits_0.lut_write = 0;
136
137 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
138 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
139 lut_sel_reg.word_0);
140 if (unlikely(ret))
141 return ret;
142 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
143 MSS_INGRESS_LUT_CTL_REGISTER_ADDR,
144 lut_op_reg.word_0);
145 if (unlikely(ret))
146 return ret;
147
148 memset(packed_record, 0, sizeof(u16) * num_words);
149
150 for (i = 0; i < num_words; i += 2) {
151 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
152 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR +
153 i,
154 &packed_record[i]);
155 if (unlikely(ret))
156 return ret;
157 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
158 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR +
159 i + 1,
160 &packed_record[i + 1]);
161 if (unlikely(ret))
162 return ret;
163 }
164
165 return 0;
166 }
167
168 /*! Write packed_record to the specified Egress LUT table row. */
set_raw_egress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)169 static int set_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record,
170 u8 num_words, u8 table_id,
171 u16 table_index)
172 {
173 struct mss_egress_lut_addr_ctl_register lut_sel_reg;
174 struct mss_egress_lut_ctl_register lut_op_reg;
175
176 unsigned int i;
177
178 /* Write the packed record words to the data buffer registers. */
179 for (i = 0; i < num_words; i += 2) {
180 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
181 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
182 packed_record[i]);
183 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
184 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
185 packed_record[i + 1]);
186 }
187
188 /* Clear out the unused data buffer registers. */
189 for (i = num_words; i < 28; i += 2) {
190 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
191 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 0);
192 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
193 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
194 0);
195 }
196
197 /* Select the table and row index to write to */
198 lut_sel_reg.bits_0.lut_select = table_id;
199 lut_sel_reg.bits_0.lut_addr = table_index;
200
201 lut_op_reg.bits_0.lut_read = 0;
202 lut_op_reg.bits_0.lut_write = 1;
203
204 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
205 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
206 lut_sel_reg.word_0);
207 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_EGRESS_LUT_CTL_REGISTER_ADDR,
208 lut_op_reg.word_0);
209
210 return 0;
211 }
212
get_raw_egress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)213 static int get_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record,
214 u8 num_words, u8 table_id,
215 u16 table_index)
216 {
217 struct mss_egress_lut_addr_ctl_register lut_sel_reg;
218 struct mss_egress_lut_ctl_register lut_op_reg;
219 int ret;
220
221 unsigned int i;
222
223 /* Select the table and row index to read */
224 lut_sel_reg.bits_0.lut_select = table_id;
225 lut_sel_reg.bits_0.lut_addr = table_index;
226
227 lut_op_reg.bits_0.lut_read = 1;
228 lut_op_reg.bits_0.lut_write = 0;
229
230 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
231 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
232 lut_sel_reg.word_0);
233 if (unlikely(ret))
234 return ret;
235 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
236 MSS_EGRESS_LUT_CTL_REGISTER_ADDR,
237 lut_op_reg.word_0);
238 if (unlikely(ret))
239 return ret;
240
241 memset(packed_record, 0, sizeof(u16) * num_words);
242
243 for (i = 0; i < num_words; i += 2) {
244 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
245 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR +
246 i,
247 &packed_record[i]);
248 if (unlikely(ret))
249 return ret;
250 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
251 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR +
252 i + 1,
253 &packed_record[i + 1]);
254 if (unlikely(ret))
255 return ret;
256 }
257
258 return 0;
259 }
260
261 static int
set_ingress_prectlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_prectlf_record * rec,u16 table_index)262 set_ingress_prectlf_record(struct aq_hw_s *hw,
263 const struct aq_mss_ingress_prectlf_record *rec,
264 u16 table_index)
265 {
266 u16 packed_record[6];
267
268 if (table_index >= NUMROWS_INGRESSPRECTLFRECORD)
269 return -EINVAL;
270
271 memset(packed_record, 0, sizeof(u16) * 6);
272
273 packed_record[0] = rec->sa_da[0] & 0xFFFF;
274 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
275 packed_record[2] = rec->sa_da[1] & 0xFFFF;
276 packed_record[3] = rec->eth_type & 0xFFFF;
277 packed_record[4] = rec->match_mask & 0xFFFF;
278 packed_record[5] = rec->match_type & 0xF;
279 packed_record[5] |= (rec->action & 0x1) << 4;
280
281 return set_raw_ingress_record(hw, packed_record, 6, 0,
282 ROWOFFSET_INGRESSPRECTLFRECORD +
283 table_index);
284 }
285
aq_mss_set_ingress_prectlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_prectlf_record * rec,u16 table_index)286 int aq_mss_set_ingress_prectlf_record(struct aq_hw_s *hw,
287 const struct aq_mss_ingress_prectlf_record *rec,
288 u16 table_index)
289 {
290 return AQ_API_CALL_SAFE(set_ingress_prectlf_record, hw, rec,
291 table_index);
292 }
293
get_ingress_prectlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_prectlf_record * rec,u16 table_index)294 static int get_ingress_prectlf_record(struct aq_hw_s *hw,
295 struct aq_mss_ingress_prectlf_record *rec,
296 u16 table_index)
297 {
298 u16 packed_record[6];
299 int ret;
300
301 if (table_index >= NUMROWS_INGRESSPRECTLFRECORD)
302 return -EINVAL;
303
304 /* If the row that we want to read is odd, first read the previous even
305 * row, throw that value away, and finally read the desired row.
306 * This is a workaround for EUR devices that allows us to read
307 * odd-numbered rows. For HHD devices: this workaround will not work,
308 * so don't bother; odd-numbered rows are not readable.
309 */
310 if ((table_index % 2) > 0) {
311 ret = get_raw_ingress_record(hw, packed_record, 6, 0,
312 ROWOFFSET_INGRESSPRECTLFRECORD +
313 table_index - 1);
314 if (unlikely(ret))
315 return ret;
316 }
317
318 ret = get_raw_ingress_record(hw, packed_record, 6, 0,
319 ROWOFFSET_INGRESSPRECTLFRECORD +
320 table_index);
321 if (unlikely(ret))
322 return ret;
323
324 rec->sa_da[0] = packed_record[0];
325 rec->sa_da[0] |= packed_record[1] << 16;
326
327 rec->sa_da[1] = packed_record[2];
328
329 rec->eth_type = packed_record[3];
330
331 rec->match_mask = packed_record[4];
332
333 rec->match_type = packed_record[5] & 0xF;
334
335 rec->action = (packed_record[5] >> 4) & 0x1;
336
337 return 0;
338 }
339
aq_mss_get_ingress_prectlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_prectlf_record * rec,u16 table_index)340 int aq_mss_get_ingress_prectlf_record(struct aq_hw_s *hw,
341 struct aq_mss_ingress_prectlf_record *rec,
342 u16 table_index)
343 {
344 memset(rec, 0, sizeof(*rec));
345
346 return AQ_API_CALL_SAFE(get_ingress_prectlf_record, hw, rec,
347 table_index);
348 }
349
350 static int
set_ingress_preclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_preclass_record * rec,u16 table_index)351 set_ingress_preclass_record(struct aq_hw_s *hw,
352 const struct aq_mss_ingress_preclass_record *rec,
353 u16 table_index)
354 {
355 u16 packed_record[20];
356
357 if (table_index >= NUMROWS_INGRESSPRECLASSRECORD)
358 return -EINVAL;
359
360 memset(packed_record, 0, sizeof(u16) * 20);
361
362 packed_record[0] = rec->sci[0] & 0xFFFF;
363 packed_record[1] = (rec->sci[0] >> 16) & 0xFFFF;
364
365 packed_record[2] = rec->sci[1] & 0xFFFF;
366 packed_record[3] = (rec->sci[1] >> 16) & 0xFFFF;
367
368 packed_record[4] = rec->tci & 0xFF;
369
370 packed_record[4] |= (rec->encr_offset & 0xFF) << 8;
371
372 packed_record[5] = rec->eth_type & 0xFFFF;
373
374 packed_record[6] = rec->snap[0] & 0xFFFF;
375 packed_record[7] = (rec->snap[0] >> 16) & 0xFFFF;
376
377 packed_record[8] = rec->snap[1] & 0xFF;
378
379 packed_record[8] |= (rec->llc & 0xFF) << 8;
380 packed_record[9] = (rec->llc >> 8) & 0xFFFF;
381
382 packed_record[10] = rec->mac_sa[0] & 0xFFFF;
383 packed_record[11] = (rec->mac_sa[0] >> 16) & 0xFFFF;
384
385 packed_record[12] = rec->mac_sa[1] & 0xFFFF;
386
387 packed_record[13] = rec->mac_da[0] & 0xFFFF;
388 packed_record[14] = (rec->mac_da[0] >> 16) & 0xFFFF;
389
390 packed_record[15] = rec->mac_da[1] & 0xFFFF;
391
392 packed_record[16] = rec->lpbk_packet & 0x1;
393
394 packed_record[16] |= (rec->an_mask & 0x3) << 1;
395
396 packed_record[16] |= (rec->tci_mask & 0x3F) << 3;
397
398 packed_record[16] |= (rec->sci_mask & 0x7F) << 9;
399 packed_record[17] = (rec->sci_mask >> 7) & 0x1;
400
401 packed_record[17] |= (rec->eth_type_mask & 0x3) << 1;
402
403 packed_record[17] |= (rec->snap_mask & 0x1F) << 3;
404
405 packed_record[17] |= (rec->llc_mask & 0x7) << 8;
406
407 packed_record[17] |= (rec->_802_2_encapsulate & 0x1) << 11;
408
409 packed_record[17] |= (rec->sa_mask & 0xF) << 12;
410 packed_record[18] = (rec->sa_mask >> 4) & 0x3;
411
412 packed_record[18] |= (rec->da_mask & 0x3F) << 2;
413
414 packed_record[18] |= (rec->lpbk_mask & 0x1) << 8;
415
416 packed_record[18] |= (rec->sc_idx & 0x1F) << 9;
417
418 packed_record[18] |= (rec->proc_dest & 0x1) << 14;
419
420 packed_record[18] |= (rec->action & 0x1) << 15;
421 packed_record[19] = (rec->action >> 1) & 0x1;
422
423 packed_record[19] |= (rec->ctrl_unctrl & 0x1) << 1;
424
425 packed_record[19] |= (rec->sci_from_table & 0x1) << 2;
426
427 packed_record[19] |= (rec->reserved & 0xF) << 3;
428
429 packed_record[19] |= (rec->valid & 0x1) << 7;
430
431 return set_raw_ingress_record(hw, packed_record, 20, 1,
432 ROWOFFSET_INGRESSPRECLASSRECORD +
433 table_index);
434 }
435
aq_mss_set_ingress_preclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_preclass_record * rec,u16 table_index)436 int aq_mss_set_ingress_preclass_record(struct aq_hw_s *hw,
437 const struct aq_mss_ingress_preclass_record *rec,
438 u16 table_index)
439 {
440 int err = AQ_API_CALL_SAFE(set_ingress_preclass_record, hw, rec,
441 table_index);
442
443 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
444
445 return err;
446 }
447
448 static int
get_ingress_preclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_preclass_record * rec,u16 table_index)449 get_ingress_preclass_record(struct aq_hw_s *hw,
450 struct aq_mss_ingress_preclass_record *rec,
451 u16 table_index)
452 {
453 u16 packed_record[20];
454 int ret;
455
456 if (table_index >= NUMROWS_INGRESSPRECLASSRECORD)
457 return -EINVAL;
458
459 /* If the row that we want to read is odd, first read the previous even
460 * row, throw that value away, and finally read the desired row.
461 */
462 if ((table_index % 2) > 0) {
463 ret = get_raw_ingress_record(hw, packed_record, 20, 1,
464 ROWOFFSET_INGRESSPRECLASSRECORD +
465 table_index - 1);
466 if (unlikely(ret))
467 return ret;
468 }
469
470 ret = get_raw_ingress_record(hw, packed_record, 20, 1,
471 ROWOFFSET_INGRESSPRECLASSRECORD +
472 table_index);
473 if (unlikely(ret))
474 return ret;
475
476 rec->sci[0] = packed_record[0];
477 rec->sci[0] |= packed_record[1] << 16;
478
479 rec->sci[1] = packed_record[2];
480 rec->sci[1] |= packed_record[3] << 16;
481
482 rec->tci = packed_record[4] & 0xFF;
483
484 rec->encr_offset = (packed_record[4] >> 8) & 0xFF;
485
486 rec->eth_type = packed_record[5];
487
488 rec->snap[0] = packed_record[6];
489 rec->snap[0] |= packed_record[7] << 16;
490
491 rec->snap[1] = packed_record[8] & 0xFF;
492
493 rec->llc = (packed_record[8] >> 8) & 0xFF;
494 rec->llc |= packed_record[9] << 8;
495
496 rec->mac_sa[0] = packed_record[10];
497 rec->mac_sa[0] |= packed_record[11] << 16;
498
499 rec->mac_sa[1] = packed_record[12];
500
501 rec->mac_da[0] = packed_record[13];
502 rec->mac_da[0] |= packed_record[14] << 16;
503
504 rec->mac_da[1] = packed_record[15];
505
506 rec->lpbk_packet = packed_record[16] & 0x1;
507
508 rec->an_mask = (packed_record[16] >> 1) & 0x3;
509
510 rec->tci_mask = (packed_record[16] >> 3) & 0x3F;
511
512 rec->sci_mask = (packed_record[16] >> 9) & 0x7F;
513 rec->sci_mask |= (packed_record[17] & 0x1) << 7;
514
515 rec->eth_type_mask = (packed_record[17] >> 1) & 0x3;
516
517 rec->snap_mask = (packed_record[17] >> 3) & 0x1F;
518
519 rec->llc_mask = (packed_record[17] >> 8) & 0x7;
520
521 rec->_802_2_encapsulate = (packed_record[17] >> 11) & 0x1;
522
523 rec->sa_mask = (packed_record[17] >> 12) & 0xF;
524 rec->sa_mask |= (packed_record[18] & 0x3) << 4;
525
526 rec->da_mask = (packed_record[18] >> 2) & 0x3F;
527
528 rec->lpbk_mask = (packed_record[18] >> 8) & 0x1;
529
530 rec->sc_idx = (packed_record[18] >> 9) & 0x1F;
531
532 rec->proc_dest = (packed_record[18] >> 14) & 0x1;
533
534 rec->action = (packed_record[18] >> 15) & 0x1;
535 rec->action |= (packed_record[19] & 0x1) << 1;
536
537 rec->ctrl_unctrl = (packed_record[19] >> 1) & 0x1;
538
539 rec->sci_from_table = (packed_record[19] >> 2) & 0x1;
540
541 rec->reserved = (packed_record[19] >> 3) & 0xF;
542
543 rec->valid = (packed_record[19] >> 7) & 0x1;
544
545 return 0;
546 }
547
aq_mss_get_ingress_preclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_preclass_record * rec,u16 table_index)548 int aq_mss_get_ingress_preclass_record(struct aq_hw_s *hw,
549 struct aq_mss_ingress_preclass_record *rec,
550 u16 table_index)
551 {
552 memset(rec, 0, sizeof(*rec));
553
554 return AQ_API_CALL_SAFE(get_ingress_preclass_record, hw, rec,
555 table_index);
556 }
557
set_ingress_sc_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sc_record * rec,u16 table_index)558 static int set_ingress_sc_record(struct aq_hw_s *hw,
559 const struct aq_mss_ingress_sc_record *rec,
560 u16 table_index)
561 {
562 u16 packed_record[8];
563
564 if (table_index >= NUMROWS_INGRESSSCRECORD)
565 return -EINVAL;
566
567 memset(packed_record, 0, sizeof(u16) * 8);
568
569 packed_record[0] = rec->stop_time & 0xFFFF;
570 packed_record[1] = (rec->stop_time >> 16) & 0xFFFF;
571
572 packed_record[2] = rec->start_time & 0xFFFF;
573 packed_record[3] = (rec->start_time >> 16) & 0xFFFF;
574
575 packed_record[4] = rec->validate_frames & 0x3;
576
577 packed_record[4] |= (rec->replay_protect & 0x1) << 2;
578
579 packed_record[4] |= (rec->anti_replay_window & 0x1FFF) << 3;
580 packed_record[5] = (rec->anti_replay_window >> 13) & 0xFFFF;
581 packed_record[6] = (rec->anti_replay_window >> 29) & 0x7;
582
583 packed_record[6] |= (rec->receiving & 0x1) << 3;
584
585 packed_record[6] |= (rec->fresh & 0x1) << 4;
586
587 packed_record[6] |= (rec->an_rol & 0x1) << 5;
588
589 packed_record[6] |= (rec->reserved & 0x3FF) << 6;
590 packed_record[7] = (rec->reserved >> 10) & 0x7FFF;
591
592 packed_record[7] |= (rec->valid & 0x1) << 15;
593
594 return set_raw_ingress_record(hw, packed_record, 8, 3,
595 ROWOFFSET_INGRESSSCRECORD + table_index);
596 }
597
aq_mss_set_ingress_sc_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sc_record * rec,u16 table_index)598 int aq_mss_set_ingress_sc_record(struct aq_hw_s *hw,
599 const struct aq_mss_ingress_sc_record *rec,
600 u16 table_index)
601 {
602 int err = AQ_API_CALL_SAFE(set_ingress_sc_record, hw, rec, table_index);
603
604 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
605
606 return err;
607 }
608
get_ingress_sc_record(struct aq_hw_s * hw,struct aq_mss_ingress_sc_record * rec,u16 table_index)609 static int get_ingress_sc_record(struct aq_hw_s *hw,
610 struct aq_mss_ingress_sc_record *rec,
611 u16 table_index)
612 {
613 u16 packed_record[8];
614 int ret;
615
616 if (table_index >= NUMROWS_INGRESSSCRECORD)
617 return -EINVAL;
618
619 ret = get_raw_ingress_record(hw, packed_record, 8, 3,
620 ROWOFFSET_INGRESSSCRECORD + table_index);
621 if (unlikely(ret))
622 return ret;
623
624 rec->stop_time = packed_record[0];
625 rec->stop_time |= packed_record[1] << 16;
626
627 rec->start_time = packed_record[2];
628 rec->start_time |= packed_record[3] << 16;
629
630 rec->validate_frames = packed_record[4] & 0x3;
631
632 rec->replay_protect = (packed_record[4] >> 2) & 0x1;
633
634 rec->anti_replay_window = (packed_record[4] >> 3) & 0x1FFF;
635 rec->anti_replay_window |= packed_record[5] << 13;
636 rec->anti_replay_window |= (packed_record[6] & 0x7) << 29;
637
638 rec->receiving = (packed_record[6] >> 3) & 0x1;
639
640 rec->fresh = (packed_record[6] >> 4) & 0x1;
641
642 rec->an_rol = (packed_record[6] >> 5) & 0x1;
643
644 rec->reserved = (packed_record[6] >> 6) & 0x3FF;
645 rec->reserved |= (packed_record[7] & 0x7FFF) << 10;
646
647 rec->valid = (packed_record[7] >> 15) & 0x1;
648
649 return 0;
650 }
651
aq_mss_get_ingress_sc_record(struct aq_hw_s * hw,struct aq_mss_ingress_sc_record * rec,u16 table_index)652 int aq_mss_get_ingress_sc_record(struct aq_hw_s *hw,
653 struct aq_mss_ingress_sc_record *rec,
654 u16 table_index)
655 {
656 memset(rec, 0, sizeof(*rec));
657
658 return AQ_API_CALL_SAFE(get_ingress_sc_record, hw, rec, table_index);
659 }
660
set_ingress_sa_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sa_record * rec,u16 table_index)661 static int set_ingress_sa_record(struct aq_hw_s *hw,
662 const struct aq_mss_ingress_sa_record *rec,
663 u16 table_index)
664 {
665 u16 packed_record[8];
666
667 if (table_index >= NUMROWS_INGRESSSARECORD)
668 return -EINVAL;
669
670 memset(packed_record, 0, sizeof(u16) * 8);
671
672 packed_record[0] = rec->stop_time & 0xFFFF;
673 packed_record[1] = (rec->stop_time >> 16) & 0xFFFF;
674
675 packed_record[2] = rec->start_time & 0xFFFF;
676 packed_record[3] = (rec->start_time >> 16) & 0xFFFF;
677
678 packed_record[4] = rec->next_pn & 0xFFFF;
679 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF;
680
681 packed_record[6] = rec->sat_nextpn & 0x1;
682
683 packed_record[6] |= (rec->in_use & 0x1) << 1;
684
685 packed_record[6] |= (rec->fresh & 0x1) << 2;
686
687 packed_record[6] |= (rec->reserved & 0x1FFF) << 3;
688 packed_record[7] = (rec->reserved >> 13) & 0x7FFF;
689
690 packed_record[7] |= (rec->valid & 0x1) << 15;
691
692 return set_raw_ingress_record(hw, packed_record, 8, 3,
693 ROWOFFSET_INGRESSSARECORD + table_index);
694 }
695
aq_mss_set_ingress_sa_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sa_record * rec,u16 table_index)696 int aq_mss_set_ingress_sa_record(struct aq_hw_s *hw,
697 const struct aq_mss_ingress_sa_record *rec,
698 u16 table_index)
699 {
700 int err = AQ_API_CALL_SAFE(set_ingress_sa_record, hw, rec, table_index);
701
702 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
703
704 return err;
705 }
706
get_ingress_sa_record(struct aq_hw_s * hw,struct aq_mss_ingress_sa_record * rec,u16 table_index)707 static int get_ingress_sa_record(struct aq_hw_s *hw,
708 struct aq_mss_ingress_sa_record *rec,
709 u16 table_index)
710 {
711 u16 packed_record[8];
712 int ret;
713
714 if (table_index >= NUMROWS_INGRESSSARECORD)
715 return -EINVAL;
716
717 ret = get_raw_ingress_record(hw, packed_record, 8, 3,
718 ROWOFFSET_INGRESSSARECORD + table_index);
719 if (unlikely(ret))
720 return ret;
721
722 rec->stop_time = packed_record[0];
723 rec->stop_time |= packed_record[1] << 16;
724
725 rec->start_time = packed_record[2];
726 rec->start_time |= packed_record[3] << 16;
727
728 rec->next_pn = packed_record[4];
729 rec->next_pn |= packed_record[5] << 16;
730
731 rec->sat_nextpn = packed_record[6] & 0x1;
732
733 rec->in_use = (packed_record[6] >> 1) & 0x1;
734
735 rec->fresh = (packed_record[6] >> 2) & 0x1;
736
737 rec->reserved = (packed_record[6] >> 3) & 0x1FFF;
738 rec->reserved |= (packed_record[7] & 0x7FFF) << 13;
739
740 rec->valid = (packed_record[7] >> 15) & 0x1;
741
742 return 0;
743 }
744
aq_mss_get_ingress_sa_record(struct aq_hw_s * hw,struct aq_mss_ingress_sa_record * rec,u16 table_index)745 int aq_mss_get_ingress_sa_record(struct aq_hw_s *hw,
746 struct aq_mss_ingress_sa_record *rec,
747 u16 table_index)
748 {
749 memset(rec, 0, sizeof(*rec));
750
751 return AQ_API_CALL_SAFE(get_ingress_sa_record, hw, rec, table_index);
752 }
753
754 static int
set_ingress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sakey_record * rec,u16 table_index)755 set_ingress_sakey_record(struct aq_hw_s *hw,
756 const struct aq_mss_ingress_sakey_record *rec,
757 u16 table_index)
758 {
759 u16 packed_record[18];
760
761 if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
762 return -EINVAL;
763
764 memset(packed_record, 0, sizeof(u16) * 18);
765
766 packed_record[0] = rec->key[0] & 0xFFFF;
767 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
768
769 packed_record[2] = rec->key[1] & 0xFFFF;
770 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
771
772 packed_record[4] = rec->key[2] & 0xFFFF;
773 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
774
775 packed_record[6] = rec->key[3] & 0xFFFF;
776 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
777
778 packed_record[8] = rec->key[4] & 0xFFFF;
779 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
780
781 packed_record[10] = rec->key[5] & 0xFFFF;
782 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
783
784 packed_record[12] = rec->key[6] & 0xFFFF;
785 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
786
787 packed_record[14] = rec->key[7] & 0xFFFF;
788 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
789
790 packed_record[16] = rec->key_len & 0x3;
791
792 return set_raw_ingress_record(hw, packed_record, 18, 2,
793 ROWOFFSET_INGRESSSAKEYRECORD +
794 table_index);
795 }
796
aq_mss_set_ingress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sakey_record * rec,u16 table_index)797 int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw,
798 const struct aq_mss_ingress_sakey_record *rec,
799 u16 table_index)
800 {
801 int err = AQ_API_CALL_SAFE(set_ingress_sakey_record, hw, rec,
802 table_index);
803
804 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
805
806 return err;
807 }
808
get_ingress_sakey_record(struct aq_hw_s * hw,struct aq_mss_ingress_sakey_record * rec,u16 table_index)809 static int get_ingress_sakey_record(struct aq_hw_s *hw,
810 struct aq_mss_ingress_sakey_record *rec,
811 u16 table_index)
812 {
813 u16 packed_record[18];
814 int ret;
815
816 if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
817 return -EINVAL;
818
819 ret = get_raw_ingress_record(hw, packed_record, 18, 2,
820 ROWOFFSET_INGRESSSAKEYRECORD +
821 table_index);
822 if (unlikely(ret))
823 return ret;
824
825 rec->key[0] = packed_record[0];
826 rec->key[0] |= packed_record[1] << 16;
827
828 rec->key[1] = packed_record[2];
829 rec->key[1] |= packed_record[3] << 16;
830
831 rec->key[2] = packed_record[4];
832 rec->key[2] |= packed_record[5] << 16;
833
834 rec->key[3] = packed_record[6];
835 rec->key[3] |= packed_record[7] << 16;
836
837 rec->key[4] = packed_record[8];
838 rec->key[4] |= packed_record[9] << 16;
839
840 rec->key[5] = packed_record[10];
841 rec->key[5] |= packed_record[11] << 16;
842
843 rec->key[6] = packed_record[12];
844 rec->key[6] |= packed_record[13] << 16;
845
846 rec->key[7] = packed_record[14];
847 rec->key[7] |= packed_record[15] << 16;
848
849 rec->key_len = packed_record[16] & 0x3;
850
851 return 0;
852 }
853
aq_mss_get_ingress_sakey_record(struct aq_hw_s * hw,struct aq_mss_ingress_sakey_record * rec,u16 table_index)854 int aq_mss_get_ingress_sakey_record(struct aq_hw_s *hw,
855 struct aq_mss_ingress_sakey_record *rec,
856 u16 table_index)
857 {
858 memset(rec, 0, sizeof(*rec));
859
860 return AQ_API_CALL_SAFE(get_ingress_sakey_record, hw, rec, table_index);
861 }
862
863 static int
set_ingress_postclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postclass_record * rec,u16 table_index)864 set_ingress_postclass_record(struct aq_hw_s *hw,
865 const struct aq_mss_ingress_postclass_record *rec,
866 u16 table_index)
867 {
868 u16 packed_record[8];
869
870 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
871 return -EINVAL;
872
873 memset(packed_record, 0, sizeof(u16) * 8);
874
875 packed_record[0] = rec->byte0 & 0xFF;
876
877 packed_record[0] |= (rec->byte1 & 0xFF) << 8;
878
879 packed_record[1] = rec->byte2 & 0xFF;
880
881 packed_record[1] |= (rec->byte3 & 0xFF) << 8;
882
883 packed_record[2] = rec->eth_type & 0xFFFF;
884
885 packed_record[3] = rec->eth_type_valid & 0x1;
886
887 packed_record[3] |= (rec->vlan_id & 0xFFF) << 1;
888
889 packed_record[3] |= (rec->vlan_up & 0x7) << 13;
890
891 packed_record[4] = rec->vlan_valid & 0x1;
892
893 packed_record[4] |= (rec->sai & 0x1F) << 1;
894
895 packed_record[4] |= (rec->sai_hit & 0x1) << 6;
896
897 packed_record[4] |= (rec->eth_type_mask & 0xF) << 7;
898
899 packed_record[4] |= (rec->byte3_location & 0x1F) << 11;
900 packed_record[5] = (rec->byte3_location >> 5) & 0x1;
901
902 packed_record[5] |= (rec->byte3_mask & 0x3) << 1;
903
904 packed_record[5] |= (rec->byte2_location & 0x3F) << 3;
905
906 packed_record[5] |= (rec->byte2_mask & 0x3) << 9;
907
908 packed_record[5] |= (rec->byte1_location & 0x1F) << 11;
909 packed_record[6] = (rec->byte1_location >> 5) & 0x1;
910
911 packed_record[6] |= (rec->byte1_mask & 0x3) << 1;
912
913 packed_record[6] |= (rec->byte0_location & 0x3F) << 3;
914
915 packed_record[6] |= (rec->byte0_mask & 0x3) << 9;
916
917 packed_record[6] |= (rec->eth_type_valid_mask & 0x3) << 11;
918
919 packed_record[6] |= (rec->vlan_id_mask & 0x7) << 13;
920 packed_record[7] = (rec->vlan_id_mask >> 3) & 0x1;
921
922 packed_record[7] |= (rec->vlan_up_mask & 0x3) << 1;
923
924 packed_record[7] |= (rec->vlan_valid_mask & 0x3) << 3;
925
926 packed_record[7] |= (rec->sai_mask & 0x3) << 5;
927
928 packed_record[7] |= (rec->sai_hit_mask & 0x3) << 7;
929
930 packed_record[7] |= (rec->firstlevel_actions & 0x1) << 9;
931
932 packed_record[7] |= (rec->secondlevel_actions & 0x1) << 10;
933
934 packed_record[7] |= (rec->reserved & 0xF) << 11;
935
936 packed_record[7] |= (rec->valid & 0x1) << 15;
937
938 return set_raw_ingress_record(hw, packed_record, 8, 4,
939 ROWOFFSET_INGRESSPOSTCLASSRECORD +
940 table_index);
941 }
942
aq_mss_set_ingress_postclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postclass_record * rec,u16 table_index)943 int aq_mss_set_ingress_postclass_record(struct aq_hw_s *hw,
944 const struct aq_mss_ingress_postclass_record *rec,
945 u16 table_index)
946 {
947 return AQ_API_CALL_SAFE(set_ingress_postclass_record, hw, rec,
948 table_index);
949 }
950
951 static int
get_ingress_postclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_postclass_record * rec,u16 table_index)952 get_ingress_postclass_record(struct aq_hw_s *hw,
953 struct aq_mss_ingress_postclass_record *rec,
954 u16 table_index)
955 {
956 u16 packed_record[8];
957 int ret;
958
959 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
960 return -EINVAL;
961
962 /* If the row that we want to read is odd, first read the previous even
963 * row, throw that value away, and finally read the desired row.
964 */
965 if ((table_index % 2) > 0) {
966 ret = get_raw_ingress_record(hw, packed_record, 8, 4,
967 ROWOFFSET_INGRESSPOSTCLASSRECORD +
968 table_index - 1);
969 if (unlikely(ret))
970 return ret;
971 }
972
973 ret = get_raw_ingress_record(hw, packed_record, 8, 4,
974 ROWOFFSET_INGRESSPOSTCLASSRECORD +
975 table_index);
976 if (unlikely(ret))
977 return ret;
978
979 rec->byte0 = packed_record[0] & 0xFF;
980
981 rec->byte1 = (packed_record[0] >> 8) & 0xFF;
982
983 rec->byte2 = packed_record[1] & 0xFF;
984
985 rec->byte3 = (packed_record[1] >> 8) & 0xFF;
986
987 rec->eth_type = packed_record[2];
988
989 rec->eth_type_valid = packed_record[3] & 0x1;
990
991 rec->vlan_id = (packed_record[3] >> 1) & 0xFFF;
992
993 rec->vlan_up = (packed_record[3] >> 13) & 0x7;
994
995 rec->vlan_valid = packed_record[4] & 0x1;
996
997 rec->sai = (packed_record[4] >> 1) & 0x1F;
998
999 rec->sai_hit = (packed_record[4] >> 6) & 0x1;
1000
1001 rec->eth_type_mask = (packed_record[4] >> 7) & 0xF;
1002
1003 rec->byte3_location = (packed_record[4] >> 11) & 0x1F;
1004 rec->byte3_location |= (packed_record[5] & 0x1) << 5;
1005
1006 rec->byte3_mask = (packed_record[5] >> 1) & 0x3;
1007
1008 rec->byte2_location = (packed_record[5] >> 3) & 0x3F;
1009
1010 rec->byte2_mask = (packed_record[5] >> 9) & 0x3;
1011
1012 rec->byte1_location = (packed_record[5] >> 11) & 0x1F;
1013 rec->byte1_location |= (packed_record[6] & 0x1) << 5;
1014
1015 rec->byte1_mask = (packed_record[6] >> 1) & 0x3;
1016
1017 rec->byte0_location = (packed_record[6] >> 3) & 0x3F;
1018
1019 rec->byte0_mask = (packed_record[6] >> 9) & 0x3;
1020
1021 rec->eth_type_valid_mask = (packed_record[6] >> 11) & 0x3;
1022
1023 rec->vlan_id_mask = (packed_record[6] >> 13) & 0x7;
1024 rec->vlan_id_mask |= (packed_record[7] & 0x1) << 3;
1025
1026 rec->vlan_up_mask = (packed_record[7] >> 1) & 0x3;
1027
1028 rec->vlan_valid_mask = (packed_record[7] >> 3) & 0x3;
1029
1030 rec->sai_mask = (packed_record[7] >> 5) & 0x3;
1031
1032 rec->sai_hit_mask = (packed_record[7] >> 7) & 0x3;
1033
1034 rec->firstlevel_actions = (packed_record[7] >> 9) & 0x1;
1035
1036 rec->secondlevel_actions = (packed_record[7] >> 10) & 0x1;
1037
1038 rec->reserved = (packed_record[7] >> 11) & 0xF;
1039
1040 rec->valid = (packed_record[7] >> 15) & 0x1;
1041
1042 return 0;
1043 }
1044
aq_mss_get_ingress_postclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_postclass_record * rec,u16 table_index)1045 int aq_mss_get_ingress_postclass_record(struct aq_hw_s *hw,
1046 struct aq_mss_ingress_postclass_record *rec,
1047 u16 table_index)
1048 {
1049 memset(rec, 0, sizeof(*rec));
1050
1051 return AQ_API_CALL_SAFE(get_ingress_postclass_record, hw, rec,
1052 table_index);
1053 }
1054
1055 static int
set_ingress_postctlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1056 set_ingress_postctlf_record(struct aq_hw_s *hw,
1057 const struct aq_mss_ingress_postctlf_record *rec,
1058 u16 table_index)
1059 {
1060 u16 packed_record[6];
1061
1062 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1063 return -EINVAL;
1064
1065 memset(packed_record, 0, sizeof(u16) * 6);
1066
1067 packed_record[0] = rec->sa_da[0] & 0xFFFF;
1068 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
1069
1070 packed_record[2] = rec->sa_da[1] & 0xFFFF;
1071
1072 packed_record[3] = rec->eth_type & 0xFFFF;
1073
1074 packed_record[4] = rec->match_mask & 0xFFFF;
1075
1076 packed_record[5] = rec->match_type & 0xF;
1077
1078 packed_record[5] |= (rec->action & 0x1) << 4;
1079
1080 return set_raw_ingress_record(hw, packed_record, 6, 5,
1081 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1082 table_index);
1083 }
1084
aq_mss_set_ingress_postctlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1085 int aq_mss_set_ingress_postctlf_record(struct aq_hw_s *hw,
1086 const struct aq_mss_ingress_postctlf_record *rec,
1087 u16 table_index)
1088 {
1089 return AQ_API_CALL_SAFE(set_ingress_postctlf_record, hw, rec,
1090 table_index);
1091 }
1092
1093 static int
get_ingress_postctlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1094 get_ingress_postctlf_record(struct aq_hw_s *hw,
1095 struct aq_mss_ingress_postctlf_record *rec,
1096 u16 table_index)
1097 {
1098 u16 packed_record[6];
1099 int ret;
1100
1101 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1102 return -EINVAL;
1103
1104 /* If the row that we want to read is odd, first read the previous even
1105 * row, throw that value away, and finally read the desired row.
1106 */
1107 if ((table_index % 2) > 0) {
1108 ret = get_raw_ingress_record(hw, packed_record, 6, 5,
1109 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1110 table_index - 1);
1111 if (unlikely(ret))
1112 return ret;
1113 }
1114
1115 ret = get_raw_ingress_record(hw, packed_record, 6, 5,
1116 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1117 table_index);
1118 if (unlikely(ret))
1119 return ret;
1120
1121 rec->sa_da[0] = packed_record[0];
1122 rec->sa_da[0] |= packed_record[1] << 16;
1123
1124 rec->sa_da[1] = packed_record[2];
1125
1126 rec->eth_type = packed_record[3];
1127
1128 rec->match_mask = packed_record[4];
1129
1130 rec->match_type = packed_record[5] & 0xF;
1131
1132 rec->action = (packed_record[5] >> 4) & 0x1;
1133
1134 return 0;
1135 }
1136
aq_mss_get_ingress_postctlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1137 int aq_mss_get_ingress_postctlf_record(struct aq_hw_s *hw,
1138 struct aq_mss_ingress_postctlf_record *rec,
1139 u16 table_index)
1140 {
1141 memset(rec, 0, sizeof(*rec));
1142
1143 return AQ_API_CALL_SAFE(get_ingress_postctlf_record, hw, rec,
1144 table_index);
1145 }
1146
set_egress_ctlf_record(struct aq_hw_s * hw,const struct aq_mss_egress_ctlf_record * rec,u16 table_index)1147 static int set_egress_ctlf_record(struct aq_hw_s *hw,
1148 const struct aq_mss_egress_ctlf_record *rec,
1149 u16 table_index)
1150 {
1151 u16 packed_record[6];
1152
1153 if (table_index >= NUMROWS_EGRESSCTLFRECORD)
1154 return -EINVAL;
1155
1156 memset(packed_record, 0, sizeof(u16) * 6);
1157
1158 packed_record[0] = rec->sa_da[0] & 0xFFFF;
1159 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
1160
1161 packed_record[2] = rec->sa_da[1] & 0xFFFF;
1162
1163 packed_record[3] = rec->eth_type & 0xFFFF;
1164
1165 packed_record[4] = rec->match_mask & 0xFFFF;
1166
1167 packed_record[5] = rec->match_type & 0xF;
1168
1169 packed_record[5] |= (rec->action & 0x1) << 4;
1170
1171 return set_raw_egress_record(hw, packed_record, 6, 0,
1172 ROWOFFSET_EGRESSCTLFRECORD + table_index);
1173 }
1174
aq_mss_set_egress_ctlf_record(struct aq_hw_s * hw,const struct aq_mss_egress_ctlf_record * rec,u16 table_index)1175 int aq_mss_set_egress_ctlf_record(struct aq_hw_s *hw,
1176 const struct aq_mss_egress_ctlf_record *rec,
1177 u16 table_index)
1178 {
1179 return AQ_API_CALL_SAFE(set_egress_ctlf_record, hw, rec, table_index);
1180 }
1181
get_egress_ctlf_record(struct aq_hw_s * hw,struct aq_mss_egress_ctlf_record * rec,u16 table_index)1182 static int get_egress_ctlf_record(struct aq_hw_s *hw,
1183 struct aq_mss_egress_ctlf_record *rec,
1184 u16 table_index)
1185 {
1186 u16 packed_record[6];
1187 int ret;
1188
1189 if (table_index >= NUMROWS_EGRESSCTLFRECORD)
1190 return -EINVAL;
1191
1192 /* If the row that we want to read is odd, first read the previous even
1193 * row, throw that value away, and finally read the desired row.
1194 */
1195 if ((table_index % 2) > 0) {
1196 ret = get_raw_egress_record(hw, packed_record, 6, 0,
1197 ROWOFFSET_EGRESSCTLFRECORD +
1198 table_index - 1);
1199 if (unlikely(ret))
1200 return ret;
1201 }
1202
1203 ret = get_raw_egress_record(hw, packed_record, 6, 0,
1204 ROWOFFSET_EGRESSCTLFRECORD + table_index);
1205 if (unlikely(ret))
1206 return ret;
1207
1208 rec->sa_da[0] = packed_record[0];
1209 rec->sa_da[0] |= packed_record[1] << 16;
1210
1211 rec->sa_da[1] = packed_record[2];
1212
1213 rec->eth_type = packed_record[3];
1214
1215 rec->match_mask = packed_record[4];
1216
1217 rec->match_type = packed_record[5] & 0xF;
1218
1219 rec->action = (packed_record[5] >> 4) & 0x1;
1220
1221 return 0;
1222 }
1223
aq_mss_get_egress_ctlf_record(struct aq_hw_s * hw,struct aq_mss_egress_ctlf_record * rec,u16 table_index)1224 int aq_mss_get_egress_ctlf_record(struct aq_hw_s *hw,
1225 struct aq_mss_egress_ctlf_record *rec,
1226 u16 table_index)
1227 {
1228 memset(rec, 0, sizeof(*rec));
1229
1230 return AQ_API_CALL_SAFE(get_egress_ctlf_record, hw, rec, table_index);
1231 }
1232
set_egress_class_record(struct aq_hw_s * hw,const struct aq_mss_egress_class_record * rec,u16 table_index)1233 static int set_egress_class_record(struct aq_hw_s *hw,
1234 const struct aq_mss_egress_class_record *rec,
1235 u16 table_index)
1236 {
1237 u16 packed_record[28];
1238
1239 if (table_index >= NUMROWS_EGRESSCLASSRECORD)
1240 return -EINVAL;
1241
1242 memset(packed_record, 0, sizeof(u16) * 28);
1243
1244 packed_record[0] = rec->vlan_id & 0xFFF;
1245
1246 packed_record[0] |= (rec->vlan_up & 0x7) << 12;
1247
1248 packed_record[0] |= (rec->vlan_valid & 0x1) << 15;
1249
1250 packed_record[1] = rec->byte3 & 0xFF;
1251
1252 packed_record[1] |= (rec->byte2 & 0xFF) << 8;
1253
1254 packed_record[2] = rec->byte1 & 0xFF;
1255
1256 packed_record[2] |= (rec->byte0 & 0xFF) << 8;
1257
1258 packed_record[3] = rec->tci & 0xFF;
1259
1260 packed_record[3] |= (rec->sci[0] & 0xFF) << 8;
1261 packed_record[4] = (rec->sci[0] >> 8) & 0xFFFF;
1262 packed_record[5] = (rec->sci[0] >> 24) & 0xFF;
1263
1264 packed_record[5] |= (rec->sci[1] & 0xFF) << 8;
1265 packed_record[6] = (rec->sci[1] >> 8) & 0xFFFF;
1266 packed_record[7] = (rec->sci[1] >> 24) & 0xFF;
1267
1268 packed_record[7] |= (rec->eth_type & 0xFF) << 8;
1269 packed_record[8] = (rec->eth_type >> 8) & 0xFF;
1270
1271 packed_record[8] |= (rec->snap[0] & 0xFF) << 8;
1272 packed_record[9] = (rec->snap[0] >> 8) & 0xFFFF;
1273 packed_record[10] = (rec->snap[0] >> 24) & 0xFF;
1274
1275 packed_record[10] |= (rec->snap[1] & 0xFF) << 8;
1276
1277 packed_record[11] = rec->llc & 0xFFFF;
1278 packed_record[12] = (rec->llc >> 16) & 0xFF;
1279
1280 packed_record[12] |= (rec->mac_sa[0] & 0xFF) << 8;
1281 packed_record[13] = (rec->mac_sa[0] >> 8) & 0xFFFF;
1282 packed_record[14] = (rec->mac_sa[0] >> 24) & 0xFF;
1283
1284 packed_record[14] |= (rec->mac_sa[1] & 0xFF) << 8;
1285 packed_record[15] = (rec->mac_sa[1] >> 8) & 0xFF;
1286
1287 packed_record[15] |= (rec->mac_da[0] & 0xFF) << 8;
1288 packed_record[16] = (rec->mac_da[0] >> 8) & 0xFFFF;
1289 packed_record[17] = (rec->mac_da[0] >> 24) & 0xFF;
1290
1291 packed_record[17] |= (rec->mac_da[1] & 0xFF) << 8;
1292 packed_record[18] = (rec->mac_da[1] >> 8) & 0xFF;
1293
1294 packed_record[18] |= (rec->pn & 0xFF) << 8;
1295 packed_record[19] = (rec->pn >> 8) & 0xFFFF;
1296 packed_record[20] = (rec->pn >> 24) & 0xFF;
1297
1298 packed_record[20] |= (rec->byte3_location & 0x3F) << 8;
1299
1300 packed_record[20] |= (rec->byte3_mask & 0x1) << 14;
1301
1302 packed_record[20] |= (rec->byte2_location & 0x1) << 15;
1303 packed_record[21] = (rec->byte2_location >> 1) & 0x1F;
1304
1305 packed_record[21] |= (rec->byte2_mask & 0x1) << 5;
1306
1307 packed_record[21] |= (rec->byte1_location & 0x3F) << 6;
1308
1309 packed_record[21] |= (rec->byte1_mask & 0x1) << 12;
1310
1311 packed_record[21] |= (rec->byte0_location & 0x7) << 13;
1312 packed_record[22] = (rec->byte0_location >> 3) & 0x7;
1313
1314 packed_record[22] |= (rec->byte0_mask & 0x1) << 3;
1315
1316 packed_record[22] |= (rec->vlan_id_mask & 0x3) << 4;
1317
1318 packed_record[22] |= (rec->vlan_up_mask & 0x1) << 6;
1319
1320 packed_record[22] |= (rec->vlan_valid_mask & 0x1) << 7;
1321
1322 packed_record[22] |= (rec->tci_mask & 0xFF) << 8;
1323
1324 packed_record[23] = rec->sci_mask & 0xFF;
1325
1326 packed_record[23] |= (rec->eth_type_mask & 0x3) << 8;
1327
1328 packed_record[23] |= (rec->snap_mask & 0x1F) << 10;
1329
1330 packed_record[23] |= (rec->llc_mask & 0x1) << 15;
1331 packed_record[24] = (rec->llc_mask >> 1) & 0x3;
1332
1333 packed_record[24] |= (rec->sa_mask & 0x3F) << 2;
1334
1335 packed_record[24] |= (rec->da_mask & 0x3F) << 8;
1336
1337 packed_record[24] |= (rec->pn_mask & 0x3) << 14;
1338 packed_record[25] = (rec->pn_mask >> 2) & 0x3;
1339
1340 packed_record[25] |= (rec->eight02dot2 & 0x1) << 2;
1341
1342 packed_record[25] |= (rec->tci_sc & 0x1) << 3;
1343
1344 packed_record[25] |= (rec->tci_87543 & 0x1) << 4;
1345
1346 packed_record[25] |= (rec->exp_sectag_en & 0x1) << 5;
1347
1348 packed_record[25] |= (rec->sc_idx & 0x1F) << 6;
1349
1350 packed_record[25] |= (rec->sc_sa & 0x3) << 11;
1351
1352 packed_record[25] |= (rec->debug & 0x1) << 13;
1353
1354 packed_record[25] |= (rec->action & 0x3) << 14;
1355
1356 packed_record[26] = (rec->valid & 0x1) << 3;
1357
1358 return set_raw_egress_record(hw, packed_record, 28, 1,
1359 ROWOFFSET_EGRESSCLASSRECORD + table_index);
1360 }
1361
aq_mss_set_egress_class_record(struct aq_hw_s * hw,const struct aq_mss_egress_class_record * rec,u16 table_index)1362 int aq_mss_set_egress_class_record(struct aq_hw_s *hw,
1363 const struct aq_mss_egress_class_record *rec,
1364 u16 table_index)
1365 {
1366 return AQ_API_CALL_SAFE(set_egress_class_record, hw, rec, table_index);
1367 }
1368
get_egress_class_record(struct aq_hw_s * hw,struct aq_mss_egress_class_record * rec,u16 table_index)1369 static int get_egress_class_record(struct aq_hw_s *hw,
1370 struct aq_mss_egress_class_record *rec,
1371 u16 table_index)
1372 {
1373 u16 packed_record[28];
1374 int ret;
1375
1376 if (table_index >= NUMROWS_EGRESSCLASSRECORD)
1377 return -EINVAL;
1378
1379 /* If the row that we want to read is odd, first read the previous even
1380 * row, throw that value away, and finally read the desired row.
1381 */
1382 if ((table_index % 2) > 0) {
1383 ret = get_raw_egress_record(hw, packed_record, 28, 1,
1384 ROWOFFSET_EGRESSCLASSRECORD +
1385 table_index - 1);
1386 if (unlikely(ret))
1387 return ret;
1388 }
1389
1390 ret = get_raw_egress_record(hw, packed_record, 28, 1,
1391 ROWOFFSET_EGRESSCLASSRECORD + table_index);
1392 if (unlikely(ret))
1393 return ret;
1394
1395 rec->vlan_id = packed_record[0] & 0xFFF;
1396
1397 rec->vlan_up = (packed_record[0] >> 12) & 0x7;
1398
1399 rec->vlan_valid = (packed_record[0] >> 15) & 0x1;
1400
1401 rec->byte3 = packed_record[1] & 0xFF;
1402
1403 rec->byte2 = (packed_record[1] >> 8) & 0xFF;
1404
1405 rec->byte1 = packed_record[2] & 0xFF;
1406
1407 rec->byte0 = (packed_record[2] >> 8) & 0xFF;
1408
1409 rec->tci = packed_record[3] & 0xFF;
1410
1411 rec->sci[0] = (packed_record[3] >> 8) & 0xFF;
1412 rec->sci[0] |= packed_record[4] << 8;
1413 rec->sci[0] |= (packed_record[5] & 0xFF) << 24;
1414
1415 rec->sci[1] = (packed_record[5] >> 8) & 0xFF;
1416 rec->sci[1] |= packed_record[6] << 8;
1417 rec->sci[1] |= (packed_record[7] & 0xFF) << 24;
1418
1419 rec->eth_type = (packed_record[7] >> 8) & 0xFF;
1420 rec->eth_type |= (packed_record[8] & 0xFF) << 8;
1421
1422 rec->snap[0] = (packed_record[8] >> 8) & 0xFF;
1423 rec->snap[0] |= packed_record[9] << 8;
1424 rec->snap[0] |= (packed_record[10] & 0xFF) << 24;
1425
1426 rec->snap[1] = (packed_record[10] >> 8) & 0xFF;
1427
1428 rec->llc = packed_record[11];
1429 rec->llc |= (packed_record[12] & 0xFF) << 16;
1430
1431 rec->mac_sa[0] = (packed_record[12] >> 8) & 0xFF;
1432 rec->mac_sa[0] |= packed_record[13] << 8;
1433 rec->mac_sa[0] |= (packed_record[14] & 0xFF) << 24;
1434
1435 rec->mac_sa[1] = (packed_record[14] >> 8) & 0xFF;
1436 rec->mac_sa[1] |= (packed_record[15] & 0xFF) << 8;
1437
1438 rec->mac_da[0] = (packed_record[15] >> 8) & 0xFF;
1439 rec->mac_da[0] |= packed_record[16] << 8;
1440 rec->mac_da[0] |= (packed_record[17] & 0xFF) << 24;
1441
1442 rec->mac_da[1] = (packed_record[17] >> 8) & 0xFF;
1443 rec->mac_da[1] |= (packed_record[18] & 0xFF) << 8;
1444
1445 rec->pn = (packed_record[18] >> 8) & 0xFF;
1446 rec->pn |= packed_record[19] << 8;
1447 rec->pn |= (packed_record[20] & 0xFF) << 24;
1448
1449 rec->byte3_location = (packed_record[20] >> 8) & 0x3F;
1450
1451 rec->byte3_mask = (packed_record[20] >> 14) & 0x1;
1452
1453 rec->byte2_location = (packed_record[20] >> 15) & 0x1;
1454 rec->byte2_location |= (packed_record[21] & 0x1F) << 1;
1455
1456 rec->byte2_mask = (packed_record[21] >> 5) & 0x1;
1457
1458 rec->byte1_location = (packed_record[21] >> 6) & 0x3F;
1459
1460 rec->byte1_mask = (packed_record[21] >> 12) & 0x1;
1461
1462 rec->byte0_location = (packed_record[21] >> 13) & 0x7;
1463 rec->byte0_location |= (packed_record[22] & 0x7) << 3;
1464
1465 rec->byte0_mask = (packed_record[22] >> 3) & 0x1;
1466
1467 rec->vlan_id_mask = (packed_record[22] >> 4) & 0x3;
1468
1469 rec->vlan_up_mask = (packed_record[22] >> 6) & 0x1;
1470
1471 rec->vlan_valid_mask = (packed_record[22] >> 7) & 0x1;
1472
1473 rec->tci_mask = (packed_record[22] >> 8) & 0xFF;
1474
1475 rec->sci_mask = packed_record[23] & 0xFF;
1476
1477 rec->eth_type_mask = (packed_record[23] >> 8) & 0x3;
1478
1479 rec->snap_mask = (packed_record[23] >> 10) & 0x1F;
1480
1481 rec->llc_mask = (packed_record[23] >> 15) & 0x1;
1482 rec->llc_mask |= (packed_record[24] & 0x3) << 1;
1483
1484 rec->sa_mask = (packed_record[24] >> 2) & 0x3F;
1485
1486 rec->da_mask = (packed_record[24] >> 8) & 0x3F;
1487
1488 rec->pn_mask = (packed_record[24] >> 14) & 0x3;
1489 rec->pn_mask |= (packed_record[25] & 0x3) << 2;
1490
1491 rec->eight02dot2 = (packed_record[25] >> 2) & 0x1;
1492
1493 rec->tci_sc = (packed_record[25] >> 3) & 0x1;
1494
1495 rec->tci_87543 = (packed_record[25] >> 4) & 0x1;
1496
1497 rec->exp_sectag_en = (packed_record[25] >> 5) & 0x1;
1498
1499 rec->sc_idx = (packed_record[25] >> 6) & 0x1F;
1500
1501 rec->sc_sa = (packed_record[25] >> 11) & 0x3;
1502
1503 rec->debug = (packed_record[25] >> 13) & 0x1;
1504
1505 rec->action = (packed_record[25] >> 14) & 0x3;
1506
1507 rec->valid = (packed_record[26] >> 3) & 0x1;
1508
1509 return 0;
1510 }
1511
aq_mss_get_egress_class_record(struct aq_hw_s * hw,struct aq_mss_egress_class_record * rec,u16 table_index)1512 int aq_mss_get_egress_class_record(struct aq_hw_s *hw,
1513 struct aq_mss_egress_class_record *rec,
1514 u16 table_index)
1515 {
1516 memset(rec, 0, sizeof(*rec));
1517
1518 return AQ_API_CALL_SAFE(get_egress_class_record, hw, rec, table_index);
1519 }
1520
set_egress_sc_record(struct aq_hw_s * hw,const struct aq_mss_egress_sc_record * rec,u16 table_index)1521 static int set_egress_sc_record(struct aq_hw_s *hw,
1522 const struct aq_mss_egress_sc_record *rec,
1523 u16 table_index)
1524 {
1525 u16 packed_record[8];
1526
1527 if (table_index >= NUMROWS_EGRESSSCRECORD)
1528 return -EINVAL;
1529
1530 memset(packed_record, 0, sizeof(u16) * 8);
1531
1532 packed_record[0] = rec->start_time & 0xFFFF;
1533 packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
1534
1535 packed_record[2] = rec->stop_time & 0xFFFF;
1536 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
1537
1538 packed_record[4] = rec->curr_an & 0x3;
1539
1540 packed_record[4] |= (rec->an_roll & 0x1) << 2;
1541
1542 packed_record[4] |= (rec->tci & 0x3F) << 3;
1543
1544 packed_record[4] |= (rec->enc_off & 0x7F) << 9;
1545 packed_record[5] = (rec->enc_off >> 7) & 0x1;
1546
1547 packed_record[5] |= (rec->protect & 0x1) << 1;
1548
1549 packed_record[5] |= (rec->recv & 0x1) << 2;
1550
1551 packed_record[5] |= (rec->fresh & 0x1) << 3;
1552
1553 packed_record[5] |= (rec->sak_len & 0x3) << 4;
1554
1555 packed_record[7] = (rec->valid & 0x1) << 15;
1556
1557 return set_raw_egress_record(hw, packed_record, 8, 2,
1558 ROWOFFSET_EGRESSSCRECORD + table_index);
1559 }
1560
aq_mss_set_egress_sc_record(struct aq_hw_s * hw,const struct aq_mss_egress_sc_record * rec,u16 table_index)1561 int aq_mss_set_egress_sc_record(struct aq_hw_s *hw,
1562 const struct aq_mss_egress_sc_record *rec,
1563 u16 table_index)
1564 {
1565 return AQ_API_CALL_SAFE(set_egress_sc_record, hw, rec, table_index);
1566 }
1567
get_egress_sc_record(struct aq_hw_s * hw,struct aq_mss_egress_sc_record * rec,u16 table_index)1568 static int get_egress_sc_record(struct aq_hw_s *hw,
1569 struct aq_mss_egress_sc_record *rec,
1570 u16 table_index)
1571 {
1572 u16 packed_record[8];
1573 int ret;
1574
1575 if (table_index >= NUMROWS_EGRESSSCRECORD)
1576 return -EINVAL;
1577
1578 ret = get_raw_egress_record(hw, packed_record, 8, 2,
1579 ROWOFFSET_EGRESSSCRECORD + table_index);
1580 if (unlikely(ret))
1581 return ret;
1582
1583 rec->start_time = packed_record[0];
1584 rec->start_time |= packed_record[1] << 16;
1585
1586 rec->stop_time = packed_record[2];
1587 rec->stop_time |= packed_record[3] << 16;
1588
1589 rec->curr_an = packed_record[4] & 0x3;
1590
1591 rec->an_roll = (packed_record[4] >> 2) & 0x1;
1592
1593 rec->tci = (packed_record[4] >> 3) & 0x3F;
1594
1595 rec->enc_off = (packed_record[4] >> 9) & 0x7F;
1596 rec->enc_off |= (packed_record[5] & 0x1) << 7;
1597
1598 rec->protect = (packed_record[5] >> 1) & 0x1;
1599
1600 rec->recv = (packed_record[5] >> 2) & 0x1;
1601
1602 rec->fresh = (packed_record[5] >> 3) & 0x1;
1603
1604 rec->sak_len = (packed_record[5] >> 4) & 0x3;
1605
1606 rec->valid = (packed_record[7] >> 15) & 0x1;
1607
1608 return 0;
1609 }
1610
aq_mss_get_egress_sc_record(struct aq_hw_s * hw,struct aq_mss_egress_sc_record * rec,u16 table_index)1611 int aq_mss_get_egress_sc_record(struct aq_hw_s *hw,
1612 struct aq_mss_egress_sc_record *rec,
1613 u16 table_index)
1614 {
1615 memset(rec, 0, sizeof(*rec));
1616
1617 return AQ_API_CALL_SAFE(get_egress_sc_record, hw, rec, table_index);
1618 }
1619
set_egress_sa_record(struct aq_hw_s * hw,const struct aq_mss_egress_sa_record * rec,u16 table_index)1620 static int set_egress_sa_record(struct aq_hw_s *hw,
1621 const struct aq_mss_egress_sa_record *rec,
1622 u16 table_index)
1623 {
1624 u16 packed_record[8];
1625
1626 if (table_index >= NUMROWS_EGRESSSARECORD)
1627 return -EINVAL;
1628
1629 memset(packed_record, 0, sizeof(u16) * 8);
1630
1631 packed_record[0] = rec->start_time & 0xFFFF;
1632 packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
1633
1634 packed_record[2] = rec->stop_time & 0xFFFF;
1635 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
1636
1637 packed_record[4] = rec->next_pn & 0xFFFF;
1638 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF;
1639
1640 packed_record[6] = rec->sat_pn & 0x1;
1641
1642 packed_record[6] |= (rec->fresh & 0x1) << 1;
1643
1644 packed_record[7] = (rec->valid & 0x1) << 15;
1645
1646 return set_raw_egress_record(hw, packed_record, 8, 2,
1647 ROWOFFSET_EGRESSSARECORD + table_index);
1648 }
1649
aq_mss_set_egress_sa_record(struct aq_hw_s * hw,const struct aq_mss_egress_sa_record * rec,u16 table_index)1650 int aq_mss_set_egress_sa_record(struct aq_hw_s *hw,
1651 const struct aq_mss_egress_sa_record *rec,
1652 u16 table_index)
1653 {
1654 int err = AQ_API_CALL_SAFE(set_egress_sa_record, hw, rec, table_index);
1655
1656 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
1657
1658 return err;
1659 }
1660
get_egress_sa_record(struct aq_hw_s * hw,struct aq_mss_egress_sa_record * rec,u16 table_index)1661 static int get_egress_sa_record(struct aq_hw_s *hw,
1662 struct aq_mss_egress_sa_record *rec,
1663 u16 table_index)
1664 {
1665 u16 packed_record[8];
1666 int ret;
1667
1668 if (table_index >= NUMROWS_EGRESSSARECORD)
1669 return -EINVAL;
1670
1671 ret = get_raw_egress_record(hw, packed_record, 8, 2,
1672 ROWOFFSET_EGRESSSARECORD + table_index);
1673 if (unlikely(ret))
1674 return ret;
1675
1676 rec->start_time = packed_record[0];
1677 rec->start_time |= packed_record[1] << 16;
1678
1679 rec->stop_time = packed_record[2];
1680 rec->stop_time |= packed_record[3] << 16;
1681
1682 rec->next_pn = packed_record[4];
1683 rec->next_pn |= packed_record[5] << 16;
1684
1685 rec->sat_pn = packed_record[6] & 0x1;
1686
1687 rec->fresh = (packed_record[6] >> 1) & 0x1;
1688
1689 rec->valid = (packed_record[7] >> 15) & 0x1;
1690
1691 return 0;
1692 }
1693
aq_mss_get_egress_sa_record(struct aq_hw_s * hw,struct aq_mss_egress_sa_record * rec,u16 table_index)1694 int aq_mss_get_egress_sa_record(struct aq_hw_s *hw,
1695 struct aq_mss_egress_sa_record *rec,
1696 u16 table_index)
1697 {
1698 memset(rec, 0, sizeof(*rec));
1699
1700 return AQ_API_CALL_SAFE(get_egress_sa_record, hw, rec, table_index);
1701 }
1702
set_egress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_egress_sakey_record * rec,u16 table_index)1703 static int set_egress_sakey_record(struct aq_hw_s *hw,
1704 const struct aq_mss_egress_sakey_record *rec,
1705 u16 table_index)
1706 {
1707 u16 packed_record[16];
1708 int ret;
1709
1710 if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
1711 return -EINVAL;
1712
1713 memset(packed_record, 0, sizeof(u16) * 16);
1714
1715 packed_record[0] = rec->key[0] & 0xFFFF;
1716 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
1717
1718 packed_record[2] = rec->key[1] & 0xFFFF;
1719 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
1720
1721 packed_record[4] = rec->key[2] & 0xFFFF;
1722 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
1723
1724 packed_record[6] = rec->key[3] & 0xFFFF;
1725 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
1726
1727 packed_record[8] = rec->key[4] & 0xFFFF;
1728 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
1729
1730 packed_record[10] = rec->key[5] & 0xFFFF;
1731 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
1732
1733 packed_record[12] = rec->key[6] & 0xFFFF;
1734 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
1735
1736 packed_record[14] = rec->key[7] & 0xFFFF;
1737 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
1738
1739 ret = set_raw_egress_record(hw, packed_record, 8, 2,
1740 ROWOFFSET_EGRESSSAKEYRECORD + table_index);
1741 if (unlikely(ret))
1742 return ret;
1743 ret = set_raw_egress_record(hw, packed_record + 8, 8, 2,
1744 ROWOFFSET_EGRESSSAKEYRECORD + table_index -
1745 32);
1746 if (unlikely(ret))
1747 return ret;
1748
1749 return 0;
1750 }
1751
aq_mss_set_egress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_egress_sakey_record * rec,u16 table_index)1752 int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw,
1753 const struct aq_mss_egress_sakey_record *rec,
1754 u16 table_index)
1755 {
1756 int err = AQ_API_CALL_SAFE(set_egress_sakey_record, hw, rec,
1757 table_index);
1758
1759 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
1760
1761 return err;
1762 }
1763
get_egress_sakey_record(struct aq_hw_s * hw,struct aq_mss_egress_sakey_record * rec,u16 table_index)1764 static int get_egress_sakey_record(struct aq_hw_s *hw,
1765 struct aq_mss_egress_sakey_record *rec,
1766 u16 table_index)
1767 {
1768 u16 packed_record[16];
1769 int ret;
1770
1771 if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
1772 return -EINVAL;
1773
1774 ret = get_raw_egress_record(hw, packed_record, 8, 2,
1775 ROWOFFSET_EGRESSSAKEYRECORD + table_index);
1776 if (unlikely(ret))
1777 return ret;
1778 ret = get_raw_egress_record(hw, packed_record + 8, 8, 2,
1779 ROWOFFSET_EGRESSSAKEYRECORD + table_index -
1780 32);
1781 if (unlikely(ret))
1782 return ret;
1783
1784 rec->key[0] = packed_record[0];
1785 rec->key[0] |= packed_record[1] << 16;
1786
1787 rec->key[1] = packed_record[2];
1788 rec->key[1] |= packed_record[3] << 16;
1789
1790 rec->key[2] = packed_record[4];
1791 rec->key[2] |= packed_record[5] << 16;
1792
1793 rec->key[3] = packed_record[6];
1794 rec->key[3] |= packed_record[7] << 16;
1795
1796 rec->key[4] = packed_record[8];
1797 rec->key[4] |= packed_record[9] << 16;
1798
1799 rec->key[5] = packed_record[10];
1800 rec->key[5] |= packed_record[11] << 16;
1801
1802 rec->key[6] = packed_record[12];
1803 rec->key[6] |= packed_record[13] << 16;
1804
1805 rec->key[7] = packed_record[14];
1806 rec->key[7] |= packed_record[15] << 16;
1807
1808 return 0;
1809 }
1810
aq_mss_get_egress_sakey_record(struct aq_hw_s * hw,struct aq_mss_egress_sakey_record * rec,u16 table_index)1811 int aq_mss_get_egress_sakey_record(struct aq_hw_s *hw,
1812 struct aq_mss_egress_sakey_record *rec,
1813 u16 table_index)
1814 {
1815 memset(rec, 0, sizeof(*rec));
1816
1817 return AQ_API_CALL_SAFE(get_egress_sakey_record, hw, rec, table_index);
1818 }
1819
get_egress_sc_counters(struct aq_hw_s * hw,struct aq_mss_egress_sc_counters * counters,u16 sc_index)1820 static int get_egress_sc_counters(struct aq_hw_s *hw,
1821 struct aq_mss_egress_sc_counters *counters,
1822 u16 sc_index)
1823 {
1824 u16 packed_record[4];
1825 int ret;
1826
1827 if (sc_index >= NUMROWS_EGRESSSCRECORD)
1828 return -EINVAL;
1829
1830 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 4);
1831 if (unlikely(ret))
1832 return ret;
1833 counters->sc_protected_pkts[0] =
1834 packed_record[0] | (packed_record[1] << 16);
1835 counters->sc_protected_pkts[1] =
1836 packed_record[2] | (packed_record[3] << 16);
1837
1838 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 5);
1839 if (unlikely(ret))
1840 return ret;
1841 counters->sc_encrypted_pkts[0] =
1842 packed_record[0] | (packed_record[1] << 16);
1843 counters->sc_encrypted_pkts[1] =
1844 packed_record[2] | (packed_record[3] << 16);
1845
1846 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 6);
1847 if (unlikely(ret))
1848 return ret;
1849 counters->sc_protected_octets[0] =
1850 packed_record[0] | (packed_record[1] << 16);
1851 counters->sc_protected_octets[1] =
1852 packed_record[2] | (packed_record[3] << 16);
1853
1854 ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 7);
1855 if (unlikely(ret))
1856 return ret;
1857 counters->sc_encrypted_octets[0] =
1858 packed_record[0] | (packed_record[1] << 16);
1859 counters->sc_encrypted_octets[1] =
1860 packed_record[2] | (packed_record[3] << 16);
1861
1862 return 0;
1863 }
1864
aq_mss_get_egress_sc_counters(struct aq_hw_s * hw,struct aq_mss_egress_sc_counters * counters,u16 sc_index)1865 int aq_mss_get_egress_sc_counters(struct aq_hw_s *hw,
1866 struct aq_mss_egress_sc_counters *counters,
1867 u16 sc_index)
1868 {
1869 memset(counters, 0, sizeof(*counters));
1870
1871 return AQ_API_CALL_SAFE(get_egress_sc_counters, hw, counters, sc_index);
1872 }
1873
get_egress_sa_counters(struct aq_hw_s * hw,struct aq_mss_egress_sa_counters * counters,u16 sa_index)1874 static int get_egress_sa_counters(struct aq_hw_s *hw,
1875 struct aq_mss_egress_sa_counters *counters,
1876 u16 sa_index)
1877 {
1878 u16 packed_record[4];
1879 int ret;
1880
1881 if (sa_index >= NUMROWS_EGRESSSARECORD)
1882 return -EINVAL;
1883
1884 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 0);
1885 if (unlikely(ret))
1886 return ret;
1887 counters->sa_hit_drop_redirect[0] =
1888 packed_record[0] | (packed_record[1] << 16);
1889 counters->sa_hit_drop_redirect[1] =
1890 packed_record[2] | (packed_record[3] << 16);
1891
1892 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 1);
1893 if (unlikely(ret))
1894 return ret;
1895 counters->sa_protected2_pkts[0] =
1896 packed_record[0] | (packed_record[1] << 16);
1897 counters->sa_protected2_pkts[1] =
1898 packed_record[2] | (packed_record[3] << 16);
1899
1900 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 2);
1901 if (unlikely(ret))
1902 return ret;
1903 counters->sa_protected_pkts[0] =
1904 packed_record[0] | (packed_record[1] << 16);
1905 counters->sa_protected_pkts[1] =
1906 packed_record[2] | (packed_record[3] << 16);
1907
1908 ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 3);
1909 if (unlikely(ret))
1910 return ret;
1911 counters->sa_encrypted_pkts[0] =
1912 packed_record[0] | (packed_record[1] << 16);
1913 counters->sa_encrypted_pkts[1] =
1914 packed_record[2] | (packed_record[3] << 16);
1915
1916 return 0;
1917 }
1918
aq_mss_get_egress_sa_counters(struct aq_hw_s * hw,struct aq_mss_egress_sa_counters * counters,u16 sa_index)1919 int aq_mss_get_egress_sa_counters(struct aq_hw_s *hw,
1920 struct aq_mss_egress_sa_counters *counters,
1921 u16 sa_index)
1922 {
1923 memset(counters, 0, sizeof(*counters));
1924
1925 return AQ_API_CALL_SAFE(get_egress_sa_counters, hw, counters, sa_index);
1926 }
1927
1928 static int
get_egress_common_counters(struct aq_hw_s * hw,struct aq_mss_egress_common_counters * counters)1929 get_egress_common_counters(struct aq_hw_s *hw,
1930 struct aq_mss_egress_common_counters *counters)
1931 {
1932 u16 packed_record[4];
1933 int ret;
1934
1935 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 0);
1936 if (unlikely(ret))
1937 return ret;
1938 counters->ctl_pkt[0] = packed_record[0] | (packed_record[1] << 16);
1939 counters->ctl_pkt[1] = packed_record[2] | (packed_record[3] << 16);
1940
1941 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 1);
1942 if (unlikely(ret))
1943 return ret;
1944 counters->unknown_sa_pkts[0] =
1945 packed_record[0] | (packed_record[1] << 16);
1946 counters->unknown_sa_pkts[1] =
1947 packed_record[2] | (packed_record[3] << 16);
1948
1949 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 2);
1950 if (unlikely(ret))
1951 return ret;
1952 counters->untagged_pkts[0] =
1953 packed_record[0] | (packed_record[1] << 16);
1954 counters->untagged_pkts[1] =
1955 packed_record[2] | (packed_record[3] << 16);
1956
1957 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 3);
1958 if (unlikely(ret))
1959 return ret;
1960 counters->too_long[0] = packed_record[0] | (packed_record[1] << 16);
1961 counters->too_long[1] = packed_record[2] | (packed_record[3] << 16);
1962
1963 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 4);
1964 if (unlikely(ret))
1965 return ret;
1966 counters->ecc_error_pkts[0] =
1967 packed_record[0] | (packed_record[1] << 16);
1968 counters->ecc_error_pkts[1] =
1969 packed_record[2] | (packed_record[3] << 16);
1970
1971 ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 5);
1972 if (unlikely(ret))
1973 return ret;
1974 counters->unctrl_hit_drop_redir[0] =
1975 packed_record[0] | (packed_record[1] << 16);
1976 counters->unctrl_hit_drop_redir[1] =
1977 packed_record[2] | (packed_record[3] << 16);
1978
1979 return 0;
1980 }
1981
aq_mss_get_egress_common_counters(struct aq_hw_s * hw,struct aq_mss_egress_common_counters * counters)1982 int aq_mss_get_egress_common_counters(struct aq_hw_s *hw,
1983 struct aq_mss_egress_common_counters *counters)
1984 {
1985 memset(counters, 0, sizeof(*counters));
1986
1987 return AQ_API_CALL_SAFE(get_egress_common_counters, hw, counters);
1988 }
1989
clear_egress_counters(struct aq_hw_s * hw)1990 static int clear_egress_counters(struct aq_hw_s *hw)
1991 {
1992 struct mss_egress_ctl_register ctl_reg;
1993 int ret;
1994
1995 memset(&ctl_reg, 0, sizeof(ctl_reg));
1996
1997 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, MSS_EGRESS_CTL_REGISTER_ADDR,
1998 &ctl_reg.word_0);
1999 if (unlikely(ret))
2000 return ret;
2001 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2002 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2003 &ctl_reg.word_1);
2004 if (unlikely(ret))
2005 return ret;
2006
2007 /* Toggle the Egress MIB clear bit 0->1->0 */
2008 ctl_reg.bits_0.clear_counter = 0;
2009 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2010 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2011 if (unlikely(ret))
2012 return ret;
2013 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2014 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2015 ctl_reg.word_1);
2016 if (unlikely(ret))
2017 return ret;
2018
2019 ctl_reg.bits_0.clear_counter = 1;
2020 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2021 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2022 if (unlikely(ret))
2023 return ret;
2024 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2025 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2026 ctl_reg.word_1);
2027 if (unlikely(ret))
2028 return ret;
2029
2030 ctl_reg.bits_0.clear_counter = 0;
2031 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2032 MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2033 if (unlikely(ret))
2034 return ret;
2035 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2036 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2037 ctl_reg.word_1);
2038 if (unlikely(ret))
2039 return ret;
2040
2041 return 0;
2042 }
2043
aq_mss_clear_egress_counters(struct aq_hw_s * hw)2044 int aq_mss_clear_egress_counters(struct aq_hw_s *hw)
2045 {
2046 return AQ_API_CALL_SAFE(clear_egress_counters, hw);
2047 }
2048
get_ingress_sa_counters(struct aq_hw_s * hw,struct aq_mss_ingress_sa_counters * counters,u16 sa_index)2049 static int get_ingress_sa_counters(struct aq_hw_s *hw,
2050 struct aq_mss_ingress_sa_counters *counters,
2051 u16 sa_index)
2052 {
2053 u16 packed_record[4];
2054 int ret;
2055
2056 if (sa_index >= NUMROWS_INGRESSSARECORD)
2057 return -EINVAL;
2058
2059 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2060 sa_index * 12 + 0);
2061 if (unlikely(ret))
2062 return ret;
2063 counters->untagged_hit_pkts[0] =
2064 packed_record[0] | (packed_record[1] << 16);
2065 counters->untagged_hit_pkts[1] =
2066 packed_record[2] | (packed_record[3] << 16);
2067
2068 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2069 sa_index * 12 + 1);
2070 if (unlikely(ret))
2071 return ret;
2072 counters->ctrl_hit_drop_redir_pkts[0] =
2073 packed_record[0] | (packed_record[1] << 16);
2074 counters->ctrl_hit_drop_redir_pkts[1] =
2075 packed_record[2] | (packed_record[3] << 16);
2076
2077 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2078 sa_index * 12 + 2);
2079 if (unlikely(ret))
2080 return ret;
2081 counters->not_using_sa[0] = packed_record[0] | (packed_record[1] << 16);
2082 counters->not_using_sa[1] = packed_record[2] | (packed_record[3] << 16);
2083
2084 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2085 sa_index * 12 + 3);
2086 if (unlikely(ret))
2087 return ret;
2088 counters->unused_sa[0] = packed_record[0] | (packed_record[1] << 16);
2089 counters->unused_sa[1] = packed_record[2] | (packed_record[3] << 16);
2090
2091 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2092 sa_index * 12 + 4);
2093 if (unlikely(ret))
2094 return ret;
2095 counters->not_valid_pkts[0] =
2096 packed_record[0] | (packed_record[1] << 16);
2097 counters->not_valid_pkts[1] =
2098 packed_record[2] | (packed_record[3] << 16);
2099
2100 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2101 sa_index * 12 + 5);
2102 if (unlikely(ret))
2103 return ret;
2104 counters->invalid_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2105 counters->invalid_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2106
2107 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2108 sa_index * 12 + 6);
2109 if (unlikely(ret))
2110 return ret;
2111 counters->ok_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2112 counters->ok_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2113
2114 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2115 sa_index * 12 + 7);
2116 if (unlikely(ret))
2117 return ret;
2118 counters->late_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2119 counters->late_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2120
2121 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2122 sa_index * 12 + 8);
2123 if (unlikely(ret))
2124 return ret;
2125 counters->delayed_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2126 counters->delayed_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2127
2128 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2129 sa_index * 12 + 9);
2130 if (unlikely(ret))
2131 return ret;
2132 counters->unchecked_pkts[0] =
2133 packed_record[0] | (packed_record[1] << 16);
2134 counters->unchecked_pkts[1] =
2135 packed_record[2] | (packed_record[3] << 16);
2136
2137 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2138 sa_index * 12 + 10);
2139 if (unlikely(ret))
2140 return ret;
2141 counters->validated_octets[0] =
2142 packed_record[0] | (packed_record[1] << 16);
2143 counters->validated_octets[1] =
2144 packed_record[2] | (packed_record[3] << 16);
2145
2146 ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2147 sa_index * 12 + 11);
2148 if (unlikely(ret))
2149 return ret;
2150 counters->decrypted_octets[0] =
2151 packed_record[0] | (packed_record[1] << 16);
2152 counters->decrypted_octets[1] =
2153 packed_record[2] | (packed_record[3] << 16);
2154
2155 return 0;
2156 }
2157
aq_mss_get_ingress_sa_counters(struct aq_hw_s * hw,struct aq_mss_ingress_sa_counters * counters,u16 sa_index)2158 int aq_mss_get_ingress_sa_counters(struct aq_hw_s *hw,
2159 struct aq_mss_ingress_sa_counters *counters,
2160 u16 sa_index)
2161 {
2162 memset(counters, 0, sizeof(*counters));
2163
2164 return AQ_API_CALL_SAFE(get_ingress_sa_counters, hw, counters,
2165 sa_index);
2166 }
2167
2168 static int
get_ingress_common_counters(struct aq_hw_s * hw,struct aq_mss_ingress_common_counters * counters)2169 get_ingress_common_counters(struct aq_hw_s *hw,
2170 struct aq_mss_ingress_common_counters *counters)
2171 {
2172 u16 packed_record[4];
2173 int ret;
2174
2175 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 0);
2176 if (unlikely(ret))
2177 return ret;
2178 counters->ctl_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2179 counters->ctl_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2180
2181 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 1);
2182 if (unlikely(ret))
2183 return ret;
2184 counters->tagged_miss_pkts[0] =
2185 packed_record[0] | (packed_record[1] << 16);
2186 counters->tagged_miss_pkts[1] =
2187 packed_record[2] | (packed_record[3] << 16);
2188
2189 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 2);
2190 if (unlikely(ret))
2191 return ret;
2192 counters->untagged_miss_pkts[0] =
2193 packed_record[0] | (packed_record[1] << 16);
2194 counters->untagged_miss_pkts[1] =
2195 packed_record[2] | (packed_record[3] << 16);
2196
2197 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 3);
2198 if (unlikely(ret))
2199 return ret;
2200 counters->notag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2201 counters->notag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2202
2203 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 4);
2204 if (unlikely(ret))
2205 return ret;
2206 counters->untagged_pkts[0] =
2207 packed_record[0] | (packed_record[1] << 16);
2208 counters->untagged_pkts[1] =
2209 packed_record[2] | (packed_record[3] << 16);
2210
2211 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 5);
2212 if (unlikely(ret))
2213 return ret;
2214 counters->bad_tag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2215 counters->bad_tag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2216
2217 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 6);
2218 if (unlikely(ret))
2219 return ret;
2220 counters->no_sci_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2221 counters->no_sci_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2222
2223 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 7);
2224 if (unlikely(ret))
2225 return ret;
2226 counters->unknown_sci_pkts[0] =
2227 packed_record[0] | (packed_record[1] << 16);
2228 counters->unknown_sci_pkts[1] =
2229 packed_record[2] | (packed_record[3] << 16);
2230
2231 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 8);
2232 if (unlikely(ret))
2233 return ret;
2234 counters->ctrl_prt_pass_pkts[0] =
2235 packed_record[0] | (packed_record[1] << 16);
2236 counters->ctrl_prt_pass_pkts[1] =
2237 packed_record[2] | (packed_record[3] << 16);
2238
2239 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 9);
2240 if (unlikely(ret))
2241 return ret;
2242 counters->unctrl_prt_pass_pkts[0] =
2243 packed_record[0] | (packed_record[1] << 16);
2244 counters->unctrl_prt_pass_pkts[1] =
2245 packed_record[2] | (packed_record[3] << 16);
2246
2247 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 10);
2248 if (unlikely(ret))
2249 return ret;
2250 counters->ctrl_prt_fail_pkts[0] =
2251 packed_record[0] | (packed_record[1] << 16);
2252 counters->ctrl_prt_fail_pkts[1] =
2253 packed_record[2] | (packed_record[3] << 16);
2254
2255 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 11);
2256 if (unlikely(ret))
2257 return ret;
2258 counters->unctrl_prt_fail_pkts[0] =
2259 packed_record[0] | (packed_record[1] << 16);
2260 counters->unctrl_prt_fail_pkts[1] =
2261 packed_record[2] | (packed_record[3] << 16);
2262
2263 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 12);
2264 if (unlikely(ret))
2265 return ret;
2266 counters->too_long_pkts[0] =
2267 packed_record[0] | (packed_record[1] << 16);
2268 counters->too_long_pkts[1] =
2269 packed_record[2] | (packed_record[3] << 16);
2270
2271 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 13);
2272 if (unlikely(ret))
2273 return ret;
2274 counters->igpoc_ctl_pkts[0] =
2275 packed_record[0] | (packed_record[1] << 16);
2276 counters->igpoc_ctl_pkts[1] =
2277 packed_record[2] | (packed_record[3] << 16);
2278
2279 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 14);
2280 if (unlikely(ret))
2281 return ret;
2282 counters->ecc_error_pkts[0] =
2283 packed_record[0] | (packed_record[1] << 16);
2284 counters->ecc_error_pkts[1] =
2285 packed_record[2] | (packed_record[3] << 16);
2286
2287 ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 15);
2288 if (unlikely(ret))
2289 return ret;
2290 counters->unctrl_hit_drop_redir[0] =
2291 packed_record[0] | (packed_record[1] << 16);
2292 counters->unctrl_hit_drop_redir[1] =
2293 packed_record[2] | (packed_record[3] << 16);
2294
2295 return 0;
2296 }
2297
aq_mss_get_ingress_common_counters(struct aq_hw_s * hw,struct aq_mss_ingress_common_counters * counters)2298 int aq_mss_get_ingress_common_counters(struct aq_hw_s *hw,
2299 struct aq_mss_ingress_common_counters *counters)
2300 {
2301 memset(counters, 0, sizeof(*counters));
2302
2303 return AQ_API_CALL_SAFE(get_ingress_common_counters, hw, counters);
2304 }
2305
clear_ingress_counters(struct aq_hw_s * hw)2306 static int clear_ingress_counters(struct aq_hw_s *hw)
2307 {
2308 struct mss_ingress_ctl_register ctl_reg;
2309 int ret;
2310
2311 memset(&ctl_reg, 0, sizeof(ctl_reg));
2312
2313 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2314 MSS_INGRESS_CTL_REGISTER_ADDR, &ctl_reg.word_0);
2315 if (unlikely(ret))
2316 return ret;
2317 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2318 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2319 &ctl_reg.word_1);
2320 if (unlikely(ret))
2321 return ret;
2322
2323 /* Toggle the Ingress MIB clear bit 0->1->0 */
2324 ctl_reg.bits_0.clear_count = 0;
2325 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2326 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2327 if (unlikely(ret))
2328 return ret;
2329 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2330 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2331 ctl_reg.word_1);
2332 if (unlikely(ret))
2333 return ret;
2334
2335 ctl_reg.bits_0.clear_count = 1;
2336 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2337 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2338 if (unlikely(ret))
2339 return ret;
2340 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2341 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2342 ctl_reg.word_1);
2343 if (unlikely(ret))
2344 return ret;
2345
2346 ctl_reg.bits_0.clear_count = 0;
2347 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2348 MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2349 if (unlikely(ret))
2350 return ret;
2351 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2352 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2353 ctl_reg.word_1);
2354 if (unlikely(ret))
2355 return ret;
2356
2357 return 0;
2358 }
2359
aq_mss_clear_ingress_counters(struct aq_hw_s * hw)2360 int aq_mss_clear_ingress_counters(struct aq_hw_s *hw)
2361 {
2362 return AQ_API_CALL_SAFE(clear_ingress_counters, hw);
2363 }
2364
get_egress_sa_expired(struct aq_hw_s * hw,u32 * expired)2365 static int get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
2366 {
2367 u16 val;
2368 int ret;
2369
2370 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2371 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
2372 &val);
2373 if (unlikely(ret))
2374 return ret;
2375
2376 *expired = val;
2377
2378 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2379 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
2380 &val);
2381 if (unlikely(ret))
2382 return ret;
2383
2384 *expired |= val << 16;
2385
2386 return 0;
2387 }
2388
aq_mss_get_egress_sa_expired(struct aq_hw_s * hw,u32 * expired)2389 int aq_mss_get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
2390 {
2391 *expired = 0;
2392
2393 return AQ_API_CALL_SAFE(get_egress_sa_expired, hw, expired);
2394 }
2395
get_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 * expired)2396 static int get_egress_sa_threshold_expired(struct aq_hw_s *hw,
2397 u32 *expired)
2398 {
2399 u16 val;
2400 int ret;
2401
2402 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2403 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, &val);
2404 if (unlikely(ret))
2405 return ret;
2406
2407 *expired = val;
2408
2409 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2410 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, &val);
2411 if (unlikely(ret))
2412 return ret;
2413
2414 *expired |= val << 16;
2415
2416 return 0;
2417 }
2418
aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 * expired)2419 int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s *hw,
2420 u32 *expired)
2421 {
2422 *expired = 0;
2423
2424 return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired, hw, expired);
2425 }
2426
set_egress_sa_expired(struct aq_hw_s * hw,u32 expired)2427 static int set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
2428 {
2429 int ret;
2430
2431 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2432 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
2433 expired & 0xFFFF);
2434 if (unlikely(ret))
2435 return ret;
2436
2437 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2438 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
2439 expired >> 16);
2440 if (unlikely(ret))
2441 return ret;
2442
2443 return 0;
2444 }
2445
aq_mss_set_egress_sa_expired(struct aq_hw_s * hw,u32 expired)2446 int aq_mss_set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
2447 {
2448 return AQ_API_CALL_SAFE(set_egress_sa_expired, hw, expired);
2449 }
2450
set_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 expired)2451 static int set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
2452 {
2453 int ret;
2454
2455 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2456 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR,
2457 expired & 0xFFFF);
2458 if (unlikely(ret))
2459 return ret;
2460
2461 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2462 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1,
2463 expired >> 16);
2464 if (unlikely(ret))
2465 return ret;
2466
2467 return 0;
2468 }
2469
aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 expired)2470 int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
2471 {
2472 return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired, hw, expired);
2473 }
2474