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 ******************************************************************************/
30static 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
38static void aq_mss_mdio_sem_put(struct aq_hw_s *hw)
39{
40 hw_atl_reg_glb_cpu_sem_set(aq_hw: hw, glb_cpu_sem: 1U, HW_ATL_FW_SM_MDIO);
41}
42
43static int aq_mss_mdio_read(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 *data)
44{
45 *data = aq_mdio_read_word(aq_hw: hw, mmd, addr);
46 return (*data != 0xffff) ? 0 : -ETIME;
47}
48
49static int aq_mss_mdio_write(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 data)
50{
51 aq_mdio_write_word(aq_hw: hw, mmd, addr, data);
52 return 0;
53}
54
55/*******************************************************************************
56 * MACSEC config and status
57 ******************************************************************************/
58
59static 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 data: packed_record[i]);
86 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
87 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i +
88 1,
89 data: 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 data: 0);
97 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
98 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, data: 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 data: lut_sel_reg.word_0);
111 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_INGRESS_LUT_CTL_REGISTER_ADDR,
112 data: 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 */
120static 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 data: 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 data: 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 data: &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 data: &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. */
169static 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 data: packed_record[i]);
183 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
184 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
185 data: 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, data: 0);
192 aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
193 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
194 data: 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 data: lut_sel_reg.word_0);
207 aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_EGRESS_LUT_CTL_REGISTER_ADDR,
208 data: lut_op_reg.word_0);
209
210 return 0;
211}
212
213static 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 data: 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 data: 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 data: &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 data: &packed_record[i + 1]);
254 if (unlikely(ret))
255 return ret;
256 }
257
258 return 0;
259}
260
261static int
262set_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, num_words: 6, table_id: 0,
282 ROWOFFSET_INGRESSPRECTLFRECORD +
283 table_index);
284}
285
286int 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
294static 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, num_words: 6, table_id: 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, num_words: 6, table_id: 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
340int 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
350static int
351set_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, num_words: 20, table_id: 1,
432 ROWOFFSET_INGRESSPRECLASSRECORD +
433 table_index);
434}
435
436int 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
448static int
449get_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, num_words: 20, table_id: 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, num_words: 20, table_id: 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
548int 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
558static 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, num_words: 8, table_id: 3,
595 ROWOFFSET_INGRESSSCRECORD + table_index);
596}
597
598int 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
609static 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, num_words: 8, table_id: 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
652int 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
661static 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, num_words: 8, table_id: 3,
693 ROWOFFSET_INGRESSSARECORD + table_index);
694}
695
696int 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
707static 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, num_words: 8, table_id: 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
745int 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
754static int
755set_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 int ret;
761
762 if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
763 return -EINVAL;
764
765 memset(packed_record, 0, sizeof(u16) * 18);
766
767 packed_record[0] = rec->key[0] & 0xFFFF;
768 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
769
770 packed_record[2] = rec->key[1] & 0xFFFF;
771 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
772
773 packed_record[4] = rec->key[2] & 0xFFFF;
774 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
775
776 packed_record[6] = rec->key[3] & 0xFFFF;
777 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
778
779 packed_record[8] = rec->key[4] & 0xFFFF;
780 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
781
782 packed_record[10] = rec->key[5] & 0xFFFF;
783 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
784
785 packed_record[12] = rec->key[6] & 0xFFFF;
786 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
787
788 packed_record[14] = rec->key[7] & 0xFFFF;
789 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
790
791 packed_record[16] = rec->key_len & 0x3;
792
793 ret = set_raw_ingress_record(hw, packed_record, num_words: 18, table_id: 2,
794 ROWOFFSET_INGRESSSAKEYRECORD +
795 table_index);
796
797 memzero_explicit(s: packed_record, count: sizeof(packed_record));
798 return ret;
799}
800
801int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw,
802 const struct aq_mss_ingress_sakey_record *rec,
803 u16 table_index)
804{
805 int err = AQ_API_CALL_SAFE(set_ingress_sakey_record, hw, rec,
806 table_index);
807
808 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
809
810 return err;
811}
812
813static int get_ingress_sakey_record(struct aq_hw_s *hw,
814 struct aq_mss_ingress_sakey_record *rec,
815 u16 table_index)
816{
817 u16 packed_record[18];
818 int ret;
819
820 if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
821 return -EINVAL;
822
823 ret = get_raw_ingress_record(hw, packed_record, num_words: 18, table_id: 2,
824 ROWOFFSET_INGRESSSAKEYRECORD +
825 table_index);
826 if (unlikely(ret))
827 return ret;
828
829 rec->key[0] = packed_record[0];
830 rec->key[0] |= packed_record[1] << 16;
831
832 rec->key[1] = packed_record[2];
833 rec->key[1] |= packed_record[3] << 16;
834
835 rec->key[2] = packed_record[4];
836 rec->key[2] |= packed_record[5] << 16;
837
838 rec->key[3] = packed_record[6];
839 rec->key[3] |= packed_record[7] << 16;
840
841 rec->key[4] = packed_record[8];
842 rec->key[4] |= packed_record[9] << 16;
843
844 rec->key[5] = packed_record[10];
845 rec->key[5] |= packed_record[11] << 16;
846
847 rec->key[6] = packed_record[12];
848 rec->key[6] |= packed_record[13] << 16;
849
850 rec->key[7] = packed_record[14];
851 rec->key[7] |= packed_record[15] << 16;
852
853 rec->key_len = packed_record[16] & 0x3;
854
855 return 0;
856}
857
858int aq_mss_get_ingress_sakey_record(struct aq_hw_s *hw,
859 struct aq_mss_ingress_sakey_record *rec,
860 u16 table_index)
861{
862 memset(rec, 0, sizeof(*rec));
863
864 return AQ_API_CALL_SAFE(get_ingress_sakey_record, hw, rec, table_index);
865}
866
867static int
868set_ingress_postclass_record(struct aq_hw_s *hw,
869 const struct aq_mss_ingress_postclass_record *rec,
870 u16 table_index)
871{
872 u16 packed_record[8];
873
874 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
875 return -EINVAL;
876
877 memset(packed_record, 0, sizeof(u16) * 8);
878
879 packed_record[0] = rec->byte0 & 0xFF;
880
881 packed_record[0] |= (rec->byte1 & 0xFF) << 8;
882
883 packed_record[1] = rec->byte2 & 0xFF;
884
885 packed_record[1] |= (rec->byte3 & 0xFF) << 8;
886
887 packed_record[2] = rec->eth_type & 0xFFFF;
888
889 packed_record[3] = rec->eth_type_valid & 0x1;
890
891 packed_record[3] |= (rec->vlan_id & 0xFFF) << 1;
892
893 packed_record[3] |= (rec->vlan_up & 0x7) << 13;
894
895 packed_record[4] = rec->vlan_valid & 0x1;
896
897 packed_record[4] |= (rec->sai & 0x1F) << 1;
898
899 packed_record[4] |= (rec->sai_hit & 0x1) << 6;
900
901 packed_record[4] |= (rec->eth_type_mask & 0xF) << 7;
902
903 packed_record[4] |= (rec->byte3_location & 0x1F) << 11;
904 packed_record[5] = (rec->byte3_location >> 5) & 0x1;
905
906 packed_record[5] |= (rec->byte3_mask & 0x3) << 1;
907
908 packed_record[5] |= (rec->byte2_location & 0x3F) << 3;
909
910 packed_record[5] |= (rec->byte2_mask & 0x3) << 9;
911
912 packed_record[5] |= (rec->byte1_location & 0x1F) << 11;
913 packed_record[6] = (rec->byte1_location >> 5) & 0x1;
914
915 packed_record[6] |= (rec->byte1_mask & 0x3) << 1;
916
917 packed_record[6] |= (rec->byte0_location & 0x3F) << 3;
918
919 packed_record[6] |= (rec->byte0_mask & 0x3) << 9;
920
921 packed_record[6] |= (rec->eth_type_valid_mask & 0x3) << 11;
922
923 packed_record[6] |= (rec->vlan_id_mask & 0x7) << 13;
924 packed_record[7] = (rec->vlan_id_mask >> 3) & 0x1;
925
926 packed_record[7] |= (rec->vlan_up_mask & 0x3) << 1;
927
928 packed_record[7] |= (rec->vlan_valid_mask & 0x3) << 3;
929
930 packed_record[7] |= (rec->sai_mask & 0x3) << 5;
931
932 packed_record[7] |= (rec->sai_hit_mask & 0x3) << 7;
933
934 packed_record[7] |= (rec->firstlevel_actions & 0x1) << 9;
935
936 packed_record[7] |= (rec->secondlevel_actions & 0x1) << 10;
937
938 packed_record[7] |= (rec->reserved & 0xF) << 11;
939
940 packed_record[7] |= (rec->valid & 0x1) << 15;
941
942 return set_raw_ingress_record(hw, packed_record, num_words: 8, table_id: 4,
943 ROWOFFSET_INGRESSPOSTCLASSRECORD +
944 table_index);
945}
946
947int aq_mss_set_ingress_postclass_record(struct aq_hw_s *hw,
948 const struct aq_mss_ingress_postclass_record *rec,
949 u16 table_index)
950{
951 return AQ_API_CALL_SAFE(set_ingress_postclass_record, hw, rec,
952 table_index);
953}
954
955static int
956get_ingress_postclass_record(struct aq_hw_s *hw,
957 struct aq_mss_ingress_postclass_record *rec,
958 u16 table_index)
959{
960 u16 packed_record[8];
961 int ret;
962
963 if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
964 return -EINVAL;
965
966 /* If the row that we want to read is odd, first read the previous even
967 * row, throw that value away, and finally read the desired row.
968 */
969 if ((table_index % 2) > 0) {
970 ret = get_raw_ingress_record(hw, packed_record, num_words: 8, table_id: 4,
971 ROWOFFSET_INGRESSPOSTCLASSRECORD +
972 table_index - 1);
973 if (unlikely(ret))
974 return ret;
975 }
976
977 ret = get_raw_ingress_record(hw, packed_record, num_words: 8, table_id: 4,
978 ROWOFFSET_INGRESSPOSTCLASSRECORD +
979 table_index);
980 if (unlikely(ret))
981 return ret;
982
983 rec->byte0 = packed_record[0] & 0xFF;
984
985 rec->byte1 = (packed_record[0] >> 8) & 0xFF;
986
987 rec->byte2 = packed_record[1] & 0xFF;
988
989 rec->byte3 = (packed_record[1] >> 8) & 0xFF;
990
991 rec->eth_type = packed_record[2];
992
993 rec->eth_type_valid = packed_record[3] & 0x1;
994
995 rec->vlan_id = (packed_record[3] >> 1) & 0xFFF;
996
997 rec->vlan_up = (packed_record[3] >> 13) & 0x7;
998
999 rec->vlan_valid = packed_record[4] & 0x1;
1000
1001 rec->sai = (packed_record[4] >> 1) & 0x1F;
1002
1003 rec->sai_hit = (packed_record[4] >> 6) & 0x1;
1004
1005 rec->eth_type_mask = (packed_record[4] >> 7) & 0xF;
1006
1007 rec->byte3_location = (packed_record[4] >> 11) & 0x1F;
1008 rec->byte3_location |= (packed_record[5] & 0x1) << 5;
1009
1010 rec->byte3_mask = (packed_record[5] >> 1) & 0x3;
1011
1012 rec->byte2_location = (packed_record[5] >> 3) & 0x3F;
1013
1014 rec->byte2_mask = (packed_record[5] >> 9) & 0x3;
1015
1016 rec->byte1_location = (packed_record[5] >> 11) & 0x1F;
1017 rec->byte1_location |= (packed_record[6] & 0x1) << 5;
1018
1019 rec->byte1_mask = (packed_record[6] >> 1) & 0x3;
1020
1021 rec->byte0_location = (packed_record[6] >> 3) & 0x3F;
1022
1023 rec->byte0_mask = (packed_record[6] >> 9) & 0x3;
1024
1025 rec->eth_type_valid_mask = (packed_record[6] >> 11) & 0x3;
1026
1027 rec->vlan_id_mask = (packed_record[6] >> 13) & 0x7;
1028 rec->vlan_id_mask |= (packed_record[7] & 0x1) << 3;
1029
1030 rec->vlan_up_mask = (packed_record[7] >> 1) & 0x3;
1031
1032 rec->vlan_valid_mask = (packed_record[7] >> 3) & 0x3;
1033
1034 rec->sai_mask = (packed_record[7] >> 5) & 0x3;
1035
1036 rec->sai_hit_mask = (packed_record[7] >> 7) & 0x3;
1037
1038 rec->firstlevel_actions = (packed_record[7] >> 9) & 0x1;
1039
1040 rec->secondlevel_actions = (packed_record[7] >> 10) & 0x1;
1041
1042 rec->reserved = (packed_record[7] >> 11) & 0xF;
1043
1044 rec->valid = (packed_record[7] >> 15) & 0x1;
1045
1046 return 0;
1047}
1048
1049int aq_mss_get_ingress_postclass_record(struct aq_hw_s *hw,
1050 struct aq_mss_ingress_postclass_record *rec,
1051 u16 table_index)
1052{
1053 memset(rec, 0, sizeof(*rec));
1054
1055 return AQ_API_CALL_SAFE(get_ingress_postclass_record, hw, rec,
1056 table_index);
1057}
1058
1059static int
1060set_ingress_postctlf_record(struct aq_hw_s *hw,
1061 const struct aq_mss_ingress_postctlf_record *rec,
1062 u16 table_index)
1063{
1064 u16 packed_record[6];
1065
1066 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1067 return -EINVAL;
1068
1069 memset(packed_record, 0, sizeof(u16) * 6);
1070
1071 packed_record[0] = rec->sa_da[0] & 0xFFFF;
1072 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
1073
1074 packed_record[2] = rec->sa_da[1] & 0xFFFF;
1075
1076 packed_record[3] = rec->eth_type & 0xFFFF;
1077
1078 packed_record[4] = rec->match_mask & 0xFFFF;
1079
1080 packed_record[5] = rec->match_type & 0xF;
1081
1082 packed_record[5] |= (rec->action & 0x1) << 4;
1083
1084 return set_raw_ingress_record(hw, packed_record, num_words: 6, table_id: 5,
1085 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1086 table_index);
1087}
1088
1089int aq_mss_set_ingress_postctlf_record(struct aq_hw_s *hw,
1090 const struct aq_mss_ingress_postctlf_record *rec,
1091 u16 table_index)
1092{
1093 return AQ_API_CALL_SAFE(set_ingress_postctlf_record, hw, rec,
1094 table_index);
1095}
1096
1097static int
1098get_ingress_postctlf_record(struct aq_hw_s *hw,
1099 struct aq_mss_ingress_postctlf_record *rec,
1100 u16 table_index)
1101{
1102 u16 packed_record[6];
1103 int ret;
1104
1105 if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1106 return -EINVAL;
1107
1108 /* If the row that we want to read is odd, first read the previous even
1109 * row, throw that value away, and finally read the desired row.
1110 */
1111 if ((table_index % 2) > 0) {
1112 ret = get_raw_ingress_record(hw, packed_record, num_words: 6, table_id: 5,
1113 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1114 table_index - 1);
1115 if (unlikely(ret))
1116 return ret;
1117 }
1118
1119 ret = get_raw_ingress_record(hw, packed_record, num_words: 6, table_id: 5,
1120 ROWOFFSET_INGRESSPOSTCTLFRECORD +
1121 table_index);
1122 if (unlikely(ret))
1123 return ret;
1124
1125 rec->sa_da[0] = packed_record[0];
1126 rec->sa_da[0] |= packed_record[1] << 16;
1127
1128 rec->sa_da[1] = packed_record[2];
1129
1130 rec->eth_type = packed_record[3];
1131
1132 rec->match_mask = packed_record[4];
1133
1134 rec->match_type = packed_record[5] & 0xF;
1135
1136 rec->action = (packed_record[5] >> 4) & 0x1;
1137
1138 return 0;
1139}
1140
1141int aq_mss_get_ingress_postctlf_record(struct aq_hw_s *hw,
1142 struct aq_mss_ingress_postctlf_record *rec,
1143 u16 table_index)
1144{
1145 memset(rec, 0, sizeof(*rec));
1146
1147 return AQ_API_CALL_SAFE(get_ingress_postctlf_record, hw, rec,
1148 table_index);
1149}
1150
1151static int set_egress_ctlf_record(struct aq_hw_s *hw,
1152 const struct aq_mss_egress_ctlf_record *rec,
1153 u16 table_index)
1154{
1155 u16 packed_record[6];
1156
1157 if (table_index >= NUMROWS_EGRESSCTLFRECORD)
1158 return -EINVAL;
1159
1160 memset(packed_record, 0, sizeof(u16) * 6);
1161
1162 packed_record[0] = rec->sa_da[0] & 0xFFFF;
1163 packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
1164
1165 packed_record[2] = rec->sa_da[1] & 0xFFFF;
1166
1167 packed_record[3] = rec->eth_type & 0xFFFF;
1168
1169 packed_record[4] = rec->match_mask & 0xFFFF;
1170
1171 packed_record[5] = rec->match_type & 0xF;
1172
1173 packed_record[5] |= (rec->action & 0x1) << 4;
1174
1175 return set_raw_egress_record(hw, packed_record, num_words: 6, table_id: 0,
1176 ROWOFFSET_EGRESSCTLFRECORD + table_index);
1177}
1178
1179int aq_mss_set_egress_ctlf_record(struct aq_hw_s *hw,
1180 const struct aq_mss_egress_ctlf_record *rec,
1181 u16 table_index)
1182{
1183 return AQ_API_CALL_SAFE(set_egress_ctlf_record, hw, rec, table_index);
1184}
1185
1186static int get_egress_ctlf_record(struct aq_hw_s *hw,
1187 struct aq_mss_egress_ctlf_record *rec,
1188 u16 table_index)
1189{
1190 u16 packed_record[6];
1191 int ret;
1192
1193 if (table_index >= NUMROWS_EGRESSCTLFRECORD)
1194 return -EINVAL;
1195
1196 /* If the row that we want to read is odd, first read the previous even
1197 * row, throw that value away, and finally read the desired row.
1198 */
1199 if ((table_index % 2) > 0) {
1200 ret = get_raw_egress_record(hw, packed_record, num_words: 6, table_id: 0,
1201 ROWOFFSET_EGRESSCTLFRECORD +
1202 table_index - 1);
1203 if (unlikely(ret))
1204 return ret;
1205 }
1206
1207 ret = get_raw_egress_record(hw, packed_record, num_words: 6, table_id: 0,
1208 ROWOFFSET_EGRESSCTLFRECORD + table_index);
1209 if (unlikely(ret))
1210 return ret;
1211
1212 rec->sa_da[0] = packed_record[0];
1213 rec->sa_da[0] |= packed_record[1] << 16;
1214
1215 rec->sa_da[1] = packed_record[2];
1216
1217 rec->eth_type = packed_record[3];
1218
1219 rec->match_mask = packed_record[4];
1220
1221 rec->match_type = packed_record[5] & 0xF;
1222
1223 rec->action = (packed_record[5] >> 4) & 0x1;
1224
1225 return 0;
1226}
1227
1228int aq_mss_get_egress_ctlf_record(struct aq_hw_s *hw,
1229 struct aq_mss_egress_ctlf_record *rec,
1230 u16 table_index)
1231{
1232 memset(rec, 0, sizeof(*rec));
1233
1234 return AQ_API_CALL_SAFE(get_egress_ctlf_record, hw, rec, table_index);
1235}
1236
1237static int set_egress_class_record(struct aq_hw_s *hw,
1238 const struct aq_mss_egress_class_record *rec,
1239 u16 table_index)
1240{
1241 u16 packed_record[28];
1242
1243 if (table_index >= NUMROWS_EGRESSCLASSRECORD)
1244 return -EINVAL;
1245
1246 memset(packed_record, 0, sizeof(u16) * 28);
1247
1248 packed_record[0] = rec->vlan_id & 0xFFF;
1249
1250 packed_record[0] |= (rec->vlan_up & 0x7) << 12;
1251
1252 packed_record[0] |= (rec->vlan_valid & 0x1) << 15;
1253
1254 packed_record[1] = rec->byte3 & 0xFF;
1255
1256 packed_record[1] |= (rec->byte2 & 0xFF) << 8;
1257
1258 packed_record[2] = rec->byte1 & 0xFF;
1259
1260 packed_record[2] |= (rec->byte0 & 0xFF) << 8;
1261
1262 packed_record[3] = rec->tci & 0xFF;
1263
1264 packed_record[3] |= (rec->sci[0] & 0xFF) << 8;
1265 packed_record[4] = (rec->sci[0] >> 8) & 0xFFFF;
1266 packed_record[5] = (rec->sci[0] >> 24) & 0xFF;
1267
1268 packed_record[5] |= (rec->sci[1] & 0xFF) << 8;
1269 packed_record[6] = (rec->sci[1] >> 8) & 0xFFFF;
1270 packed_record[7] = (rec->sci[1] >> 24) & 0xFF;
1271
1272 packed_record[7] |= (rec->eth_type & 0xFF) << 8;
1273 packed_record[8] = (rec->eth_type >> 8) & 0xFF;
1274
1275 packed_record[8] |= (rec->snap[0] & 0xFF) << 8;
1276 packed_record[9] = (rec->snap[0] >> 8) & 0xFFFF;
1277 packed_record[10] = (rec->snap[0] >> 24) & 0xFF;
1278
1279 packed_record[10] |= (rec->snap[1] & 0xFF) << 8;
1280
1281 packed_record[11] = rec->llc & 0xFFFF;
1282 packed_record[12] = (rec->llc >> 16) & 0xFF;
1283
1284 packed_record[12] |= (rec->mac_sa[0] & 0xFF) << 8;
1285 packed_record[13] = (rec->mac_sa[0] >> 8) & 0xFFFF;
1286 packed_record[14] = (rec->mac_sa[0] >> 24) & 0xFF;
1287
1288 packed_record[14] |= (rec->mac_sa[1] & 0xFF) << 8;
1289 packed_record[15] = (rec->mac_sa[1] >> 8) & 0xFF;
1290
1291 packed_record[15] |= (rec->mac_da[0] & 0xFF) << 8;
1292 packed_record[16] = (rec->mac_da[0] >> 8) & 0xFFFF;
1293 packed_record[17] = (rec->mac_da[0] >> 24) & 0xFF;
1294
1295 packed_record[17] |= (rec->mac_da[1] & 0xFF) << 8;
1296 packed_record[18] = (rec->mac_da[1] >> 8) & 0xFF;
1297
1298 packed_record[18] |= (rec->pn & 0xFF) << 8;
1299 packed_record[19] = (rec->pn >> 8) & 0xFFFF;
1300 packed_record[20] = (rec->pn >> 24) & 0xFF;
1301
1302 packed_record[20] |= (rec->byte3_location & 0x3F) << 8;
1303
1304 packed_record[20] |= (rec->byte3_mask & 0x1) << 14;
1305
1306 packed_record[20] |= (rec->byte2_location & 0x1) << 15;
1307 packed_record[21] = (rec->byte2_location >> 1) & 0x1F;
1308
1309 packed_record[21] |= (rec->byte2_mask & 0x1) << 5;
1310
1311 packed_record[21] |= (rec->byte1_location & 0x3F) << 6;
1312
1313 packed_record[21] |= (rec->byte1_mask & 0x1) << 12;
1314
1315 packed_record[21] |= (rec->byte0_location & 0x7) << 13;
1316 packed_record[22] = (rec->byte0_location >> 3) & 0x7;
1317
1318 packed_record[22] |= (rec->byte0_mask & 0x1) << 3;
1319
1320 packed_record[22] |= (rec->vlan_id_mask & 0x3) << 4;
1321
1322 packed_record[22] |= (rec->vlan_up_mask & 0x1) << 6;
1323
1324 packed_record[22] |= (rec->vlan_valid_mask & 0x1) << 7;
1325
1326 packed_record[22] |= (rec->tci_mask & 0xFF) << 8;
1327
1328 packed_record[23] = rec->sci_mask & 0xFF;
1329
1330 packed_record[23] |= (rec->eth_type_mask & 0x3) << 8;
1331
1332 packed_record[23] |= (rec->snap_mask & 0x1F) << 10;
1333
1334 packed_record[23] |= (rec->llc_mask & 0x1) << 15;
1335 packed_record[24] = (rec->llc_mask >> 1) & 0x3;
1336
1337 packed_record[24] |= (rec->sa_mask & 0x3F) << 2;
1338
1339 packed_record[24] |= (rec->da_mask & 0x3F) << 8;
1340
1341 packed_record[24] |= (rec->pn_mask & 0x3) << 14;
1342 packed_record[25] = (rec->pn_mask >> 2) & 0x3;
1343
1344 packed_record[25] |= (rec->eight02dot2 & 0x1) << 2;
1345
1346 packed_record[25] |= (rec->tci_sc & 0x1) << 3;
1347
1348 packed_record[25] |= (rec->tci_87543 & 0x1) << 4;
1349
1350 packed_record[25] |= (rec->exp_sectag_en & 0x1) << 5;
1351
1352 packed_record[25] |= (rec->sc_idx & 0x1F) << 6;
1353
1354 packed_record[25] |= (rec->sc_sa & 0x3) << 11;
1355
1356 packed_record[25] |= (rec->debug & 0x1) << 13;
1357
1358 packed_record[25] |= (rec->action & 0x3) << 14;
1359
1360 packed_record[26] = (rec->valid & 0x1) << 3;
1361
1362 return set_raw_egress_record(hw, packed_record, num_words: 28, table_id: 1,
1363 ROWOFFSET_EGRESSCLASSRECORD + table_index);
1364}
1365
1366int aq_mss_set_egress_class_record(struct aq_hw_s *hw,
1367 const struct aq_mss_egress_class_record *rec,
1368 u16 table_index)
1369{
1370 return AQ_API_CALL_SAFE(set_egress_class_record, hw, rec, table_index);
1371}
1372
1373static int get_egress_class_record(struct aq_hw_s *hw,
1374 struct aq_mss_egress_class_record *rec,
1375 u16 table_index)
1376{
1377 u16 packed_record[28];
1378 int ret;
1379
1380 if (table_index >= NUMROWS_EGRESSCLASSRECORD)
1381 return -EINVAL;
1382
1383 /* If the row that we want to read is odd, first read the previous even
1384 * row, throw that value away, and finally read the desired row.
1385 */
1386 if ((table_index % 2) > 0) {
1387 ret = get_raw_egress_record(hw, packed_record, num_words: 28, table_id: 1,
1388 ROWOFFSET_EGRESSCLASSRECORD +
1389 table_index - 1);
1390 if (unlikely(ret))
1391 return ret;
1392 }
1393
1394 ret = get_raw_egress_record(hw, packed_record, num_words: 28, table_id: 1,
1395 ROWOFFSET_EGRESSCLASSRECORD + table_index);
1396 if (unlikely(ret))
1397 return ret;
1398
1399 rec->vlan_id = packed_record[0] & 0xFFF;
1400
1401 rec->vlan_up = (packed_record[0] >> 12) & 0x7;
1402
1403 rec->vlan_valid = (packed_record[0] >> 15) & 0x1;
1404
1405 rec->byte3 = packed_record[1] & 0xFF;
1406
1407 rec->byte2 = (packed_record[1] >> 8) & 0xFF;
1408
1409 rec->byte1 = packed_record[2] & 0xFF;
1410
1411 rec->byte0 = (packed_record[2] >> 8) & 0xFF;
1412
1413 rec->tci = packed_record[3] & 0xFF;
1414
1415 rec->sci[0] = (packed_record[3] >> 8) & 0xFF;
1416 rec->sci[0] |= packed_record[4] << 8;
1417 rec->sci[0] |= (packed_record[5] & 0xFF) << 24;
1418
1419 rec->sci[1] = (packed_record[5] >> 8) & 0xFF;
1420 rec->sci[1] |= packed_record[6] << 8;
1421 rec->sci[1] |= (packed_record[7] & 0xFF) << 24;
1422
1423 rec->eth_type = (packed_record[7] >> 8) & 0xFF;
1424 rec->eth_type |= (packed_record[8] & 0xFF) << 8;
1425
1426 rec->snap[0] = (packed_record[8] >> 8) & 0xFF;
1427 rec->snap[0] |= packed_record[9] << 8;
1428 rec->snap[0] |= (packed_record[10] & 0xFF) << 24;
1429
1430 rec->snap[1] = (packed_record[10] >> 8) & 0xFF;
1431
1432 rec->llc = packed_record[11];
1433 rec->llc |= (packed_record[12] & 0xFF) << 16;
1434
1435 rec->mac_sa[0] = (packed_record[12] >> 8) & 0xFF;
1436 rec->mac_sa[0] |= packed_record[13] << 8;
1437 rec->mac_sa[0] |= (packed_record[14] & 0xFF) << 24;
1438
1439 rec->mac_sa[1] = (packed_record[14] >> 8) & 0xFF;
1440 rec->mac_sa[1] |= (packed_record[15] & 0xFF) << 8;
1441
1442 rec->mac_da[0] = (packed_record[15] >> 8) & 0xFF;
1443 rec->mac_da[0] |= packed_record[16] << 8;
1444 rec->mac_da[0] |= (packed_record[17] & 0xFF) << 24;
1445
1446 rec->mac_da[1] = (packed_record[17] >> 8) & 0xFF;
1447 rec->mac_da[1] |= (packed_record[18] & 0xFF) << 8;
1448
1449 rec->pn = (packed_record[18] >> 8) & 0xFF;
1450 rec->pn |= packed_record[19] << 8;
1451 rec->pn |= (packed_record[20] & 0xFF) << 24;
1452
1453 rec->byte3_location = (packed_record[20] >> 8) & 0x3F;
1454
1455 rec->byte3_mask = (packed_record[20] >> 14) & 0x1;
1456
1457 rec->byte2_location = (packed_record[20] >> 15) & 0x1;
1458 rec->byte2_location |= (packed_record[21] & 0x1F) << 1;
1459
1460 rec->byte2_mask = (packed_record[21] >> 5) & 0x1;
1461
1462 rec->byte1_location = (packed_record[21] >> 6) & 0x3F;
1463
1464 rec->byte1_mask = (packed_record[21] >> 12) & 0x1;
1465
1466 rec->byte0_location = (packed_record[21] >> 13) & 0x7;
1467 rec->byte0_location |= (packed_record[22] & 0x7) << 3;
1468
1469 rec->byte0_mask = (packed_record[22] >> 3) & 0x1;
1470
1471 rec->vlan_id_mask = (packed_record[22] >> 4) & 0x3;
1472
1473 rec->vlan_up_mask = (packed_record[22] >> 6) & 0x1;
1474
1475 rec->vlan_valid_mask = (packed_record[22] >> 7) & 0x1;
1476
1477 rec->tci_mask = (packed_record[22] >> 8) & 0xFF;
1478
1479 rec->sci_mask = packed_record[23] & 0xFF;
1480
1481 rec->eth_type_mask = (packed_record[23] >> 8) & 0x3;
1482
1483 rec->snap_mask = (packed_record[23] >> 10) & 0x1F;
1484
1485 rec->llc_mask = (packed_record[23] >> 15) & 0x1;
1486 rec->llc_mask |= (packed_record[24] & 0x3) << 1;
1487
1488 rec->sa_mask = (packed_record[24] >> 2) & 0x3F;
1489
1490 rec->da_mask = (packed_record[24] >> 8) & 0x3F;
1491
1492 rec->pn_mask = (packed_record[24] >> 14) & 0x3;
1493 rec->pn_mask |= (packed_record[25] & 0x3) << 2;
1494
1495 rec->eight02dot2 = (packed_record[25] >> 2) & 0x1;
1496
1497 rec->tci_sc = (packed_record[25] >> 3) & 0x1;
1498
1499 rec->tci_87543 = (packed_record[25] >> 4) & 0x1;
1500
1501 rec->exp_sectag_en = (packed_record[25] >> 5) & 0x1;
1502
1503 rec->sc_idx = (packed_record[25] >> 6) & 0x1F;
1504
1505 rec->sc_sa = (packed_record[25] >> 11) & 0x3;
1506
1507 rec->debug = (packed_record[25] >> 13) & 0x1;
1508
1509 rec->action = (packed_record[25] >> 14) & 0x3;
1510
1511 rec->valid = (packed_record[26] >> 3) & 0x1;
1512
1513 return 0;
1514}
1515
1516int aq_mss_get_egress_class_record(struct aq_hw_s *hw,
1517 struct aq_mss_egress_class_record *rec,
1518 u16 table_index)
1519{
1520 memset(rec, 0, sizeof(*rec));
1521
1522 return AQ_API_CALL_SAFE(get_egress_class_record, hw, rec, table_index);
1523}
1524
1525static int set_egress_sc_record(struct aq_hw_s *hw,
1526 const struct aq_mss_egress_sc_record *rec,
1527 u16 table_index)
1528{
1529 u16 packed_record[8];
1530
1531 if (table_index >= NUMROWS_EGRESSSCRECORD)
1532 return -EINVAL;
1533
1534 memset(packed_record, 0, sizeof(u16) * 8);
1535
1536 packed_record[0] = rec->start_time & 0xFFFF;
1537 packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
1538
1539 packed_record[2] = rec->stop_time & 0xFFFF;
1540 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
1541
1542 packed_record[4] = rec->curr_an & 0x3;
1543
1544 packed_record[4] |= (rec->an_roll & 0x1) << 2;
1545
1546 packed_record[4] |= (rec->tci & 0x3F) << 3;
1547
1548 packed_record[4] |= (rec->enc_off & 0x7F) << 9;
1549 packed_record[5] = (rec->enc_off >> 7) & 0x1;
1550
1551 packed_record[5] |= (rec->protect & 0x1) << 1;
1552
1553 packed_record[5] |= (rec->recv & 0x1) << 2;
1554
1555 packed_record[5] |= (rec->fresh & 0x1) << 3;
1556
1557 packed_record[5] |= (rec->sak_len & 0x3) << 4;
1558
1559 packed_record[7] = (rec->valid & 0x1) << 15;
1560
1561 return set_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1562 ROWOFFSET_EGRESSSCRECORD + table_index);
1563}
1564
1565int aq_mss_set_egress_sc_record(struct aq_hw_s *hw,
1566 const struct aq_mss_egress_sc_record *rec,
1567 u16 table_index)
1568{
1569 return AQ_API_CALL_SAFE(set_egress_sc_record, hw, rec, table_index);
1570}
1571
1572static int get_egress_sc_record(struct aq_hw_s *hw,
1573 struct aq_mss_egress_sc_record *rec,
1574 u16 table_index)
1575{
1576 u16 packed_record[8];
1577 int ret;
1578
1579 if (table_index >= NUMROWS_EGRESSSCRECORD)
1580 return -EINVAL;
1581
1582 ret = get_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1583 ROWOFFSET_EGRESSSCRECORD + table_index);
1584 if (unlikely(ret))
1585 return ret;
1586
1587 rec->start_time = packed_record[0];
1588 rec->start_time |= packed_record[1] << 16;
1589
1590 rec->stop_time = packed_record[2];
1591 rec->stop_time |= packed_record[3] << 16;
1592
1593 rec->curr_an = packed_record[4] & 0x3;
1594
1595 rec->an_roll = (packed_record[4] >> 2) & 0x1;
1596
1597 rec->tci = (packed_record[4] >> 3) & 0x3F;
1598
1599 rec->enc_off = (packed_record[4] >> 9) & 0x7F;
1600 rec->enc_off |= (packed_record[5] & 0x1) << 7;
1601
1602 rec->protect = (packed_record[5] >> 1) & 0x1;
1603
1604 rec->recv = (packed_record[5] >> 2) & 0x1;
1605
1606 rec->fresh = (packed_record[5] >> 3) & 0x1;
1607
1608 rec->sak_len = (packed_record[5] >> 4) & 0x3;
1609
1610 rec->valid = (packed_record[7] >> 15) & 0x1;
1611
1612 return 0;
1613}
1614
1615int aq_mss_get_egress_sc_record(struct aq_hw_s *hw,
1616 struct aq_mss_egress_sc_record *rec,
1617 u16 table_index)
1618{
1619 memset(rec, 0, sizeof(*rec));
1620
1621 return AQ_API_CALL_SAFE(get_egress_sc_record, hw, rec, table_index);
1622}
1623
1624static int set_egress_sa_record(struct aq_hw_s *hw,
1625 const struct aq_mss_egress_sa_record *rec,
1626 u16 table_index)
1627{
1628 u16 packed_record[8];
1629
1630 if (table_index >= NUMROWS_EGRESSSARECORD)
1631 return -EINVAL;
1632
1633 memset(packed_record, 0, sizeof(u16) * 8);
1634
1635 packed_record[0] = rec->start_time & 0xFFFF;
1636 packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
1637
1638 packed_record[2] = rec->stop_time & 0xFFFF;
1639 packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
1640
1641 packed_record[4] = rec->next_pn & 0xFFFF;
1642 packed_record[5] = (rec->next_pn >> 16) & 0xFFFF;
1643
1644 packed_record[6] = rec->sat_pn & 0x1;
1645
1646 packed_record[6] |= (rec->fresh & 0x1) << 1;
1647
1648 packed_record[7] = (rec->valid & 0x1) << 15;
1649
1650 return set_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1651 ROWOFFSET_EGRESSSARECORD + table_index);
1652}
1653
1654int aq_mss_set_egress_sa_record(struct aq_hw_s *hw,
1655 const struct aq_mss_egress_sa_record *rec,
1656 u16 table_index)
1657{
1658 int err = AQ_API_CALL_SAFE(set_egress_sa_record, hw, rec, table_index);
1659
1660 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
1661
1662 return err;
1663}
1664
1665static int get_egress_sa_record(struct aq_hw_s *hw,
1666 struct aq_mss_egress_sa_record *rec,
1667 u16 table_index)
1668{
1669 u16 packed_record[8];
1670 int ret;
1671
1672 if (table_index >= NUMROWS_EGRESSSARECORD)
1673 return -EINVAL;
1674
1675 ret = get_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1676 ROWOFFSET_EGRESSSARECORD + table_index);
1677 if (unlikely(ret))
1678 return ret;
1679
1680 rec->start_time = packed_record[0];
1681 rec->start_time |= packed_record[1] << 16;
1682
1683 rec->stop_time = packed_record[2];
1684 rec->stop_time |= packed_record[3] << 16;
1685
1686 rec->next_pn = packed_record[4];
1687 rec->next_pn |= packed_record[5] << 16;
1688
1689 rec->sat_pn = packed_record[6] & 0x1;
1690
1691 rec->fresh = (packed_record[6] >> 1) & 0x1;
1692
1693 rec->valid = (packed_record[7] >> 15) & 0x1;
1694
1695 return 0;
1696}
1697
1698int aq_mss_get_egress_sa_record(struct aq_hw_s *hw,
1699 struct aq_mss_egress_sa_record *rec,
1700 u16 table_index)
1701{
1702 memset(rec, 0, sizeof(*rec));
1703
1704 return AQ_API_CALL_SAFE(get_egress_sa_record, hw, rec, table_index);
1705}
1706
1707static int set_egress_sakey_record(struct aq_hw_s *hw,
1708 const struct aq_mss_egress_sakey_record *rec,
1709 u16 table_index)
1710{
1711 u16 packed_record[16];
1712 int ret;
1713
1714 if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
1715 return -EINVAL;
1716
1717 memset(packed_record, 0, sizeof(u16) * 16);
1718
1719 packed_record[0] = rec->key[0] & 0xFFFF;
1720 packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
1721
1722 packed_record[2] = rec->key[1] & 0xFFFF;
1723 packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
1724
1725 packed_record[4] = rec->key[2] & 0xFFFF;
1726 packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
1727
1728 packed_record[6] = rec->key[3] & 0xFFFF;
1729 packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
1730
1731 packed_record[8] = rec->key[4] & 0xFFFF;
1732 packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
1733
1734 packed_record[10] = rec->key[5] & 0xFFFF;
1735 packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
1736
1737 packed_record[12] = rec->key[6] & 0xFFFF;
1738 packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
1739
1740 packed_record[14] = rec->key[7] & 0xFFFF;
1741 packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
1742
1743 ret = set_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1744 ROWOFFSET_EGRESSSAKEYRECORD + table_index);
1745 if (unlikely(ret))
1746 goto clear_key;
1747 ret = set_raw_egress_record(hw, packed_record: packed_record + 8, num_words: 8, table_id: 2,
1748 ROWOFFSET_EGRESSSAKEYRECORD + table_index -
1749 32);
1750
1751clear_key:
1752 memzero_explicit(s: packed_record, count: sizeof(packed_record));
1753 return ret;
1754}
1755
1756int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw,
1757 const struct aq_mss_egress_sakey_record *rec,
1758 u16 table_index)
1759{
1760 int err = AQ_API_CALL_SAFE(set_egress_sakey_record, hw, rec,
1761 table_index);
1762
1763 WARN_ONCE(err, "%s failed with %d\n", __func__, err);
1764
1765 return err;
1766}
1767
1768static int get_egress_sakey_record(struct aq_hw_s *hw,
1769 struct aq_mss_egress_sakey_record *rec,
1770 u16 table_index)
1771{
1772 u16 packed_record[16];
1773 int ret;
1774
1775 if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
1776 return -EINVAL;
1777
1778 ret = get_raw_egress_record(hw, packed_record, num_words: 8, table_id: 2,
1779 ROWOFFSET_EGRESSSAKEYRECORD + table_index);
1780 if (unlikely(ret))
1781 return ret;
1782 ret = get_raw_egress_record(hw, packed_record: packed_record + 8, num_words: 8, table_id: 2,
1783 ROWOFFSET_EGRESSSAKEYRECORD + table_index -
1784 32);
1785 if (unlikely(ret))
1786 return ret;
1787
1788 rec->key[0] = packed_record[0];
1789 rec->key[0] |= packed_record[1] << 16;
1790
1791 rec->key[1] = packed_record[2];
1792 rec->key[1] |= packed_record[3] << 16;
1793
1794 rec->key[2] = packed_record[4];
1795 rec->key[2] |= packed_record[5] << 16;
1796
1797 rec->key[3] = packed_record[6];
1798 rec->key[3] |= packed_record[7] << 16;
1799
1800 rec->key[4] = packed_record[8];
1801 rec->key[4] |= packed_record[9] << 16;
1802
1803 rec->key[5] = packed_record[10];
1804 rec->key[5] |= packed_record[11] << 16;
1805
1806 rec->key[6] = packed_record[12];
1807 rec->key[6] |= packed_record[13] << 16;
1808
1809 rec->key[7] = packed_record[14];
1810 rec->key[7] |= packed_record[15] << 16;
1811
1812 return 0;
1813}
1814
1815int aq_mss_get_egress_sakey_record(struct aq_hw_s *hw,
1816 struct aq_mss_egress_sakey_record *rec,
1817 u16 table_index)
1818{
1819 memset(rec, 0, sizeof(*rec));
1820
1821 return AQ_API_CALL_SAFE(get_egress_sakey_record, hw, rec, table_index);
1822}
1823
1824static int get_egress_sc_counters(struct aq_hw_s *hw,
1825 struct aq_mss_egress_sc_counters *counters,
1826 u16 sc_index)
1827{
1828 u16 packed_record[4];
1829 int ret;
1830
1831 if (sc_index >= NUMROWS_EGRESSSCRECORD)
1832 return -EINVAL;
1833
1834 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sc_index * 8 + 4);
1835 if (unlikely(ret))
1836 return ret;
1837 counters->sc_protected_pkts[0] =
1838 packed_record[0] | (packed_record[1] << 16);
1839 counters->sc_protected_pkts[1] =
1840 packed_record[2] | (packed_record[3] << 16);
1841
1842 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sc_index * 8 + 5);
1843 if (unlikely(ret))
1844 return ret;
1845 counters->sc_encrypted_pkts[0] =
1846 packed_record[0] | (packed_record[1] << 16);
1847 counters->sc_encrypted_pkts[1] =
1848 packed_record[2] | (packed_record[3] << 16);
1849
1850 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sc_index * 8 + 6);
1851 if (unlikely(ret))
1852 return ret;
1853 counters->sc_protected_octets[0] =
1854 packed_record[0] | (packed_record[1] << 16);
1855 counters->sc_protected_octets[1] =
1856 packed_record[2] | (packed_record[3] << 16);
1857
1858 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sc_index * 8 + 7);
1859 if (unlikely(ret))
1860 return ret;
1861 counters->sc_encrypted_octets[0] =
1862 packed_record[0] | (packed_record[1] << 16);
1863 counters->sc_encrypted_octets[1] =
1864 packed_record[2] | (packed_record[3] << 16);
1865
1866 return 0;
1867}
1868
1869int aq_mss_get_egress_sc_counters(struct aq_hw_s *hw,
1870 struct aq_mss_egress_sc_counters *counters,
1871 u16 sc_index)
1872{
1873 memset(counters, 0, sizeof(*counters));
1874
1875 return AQ_API_CALL_SAFE(get_egress_sc_counters, hw, counters, sc_index);
1876}
1877
1878static int get_egress_sa_counters(struct aq_hw_s *hw,
1879 struct aq_mss_egress_sa_counters *counters,
1880 u16 sa_index)
1881{
1882 u16 packed_record[4];
1883 int ret;
1884
1885 if (sa_index >= NUMROWS_EGRESSSARECORD)
1886 return -EINVAL;
1887
1888 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sa_index * 8 + 0);
1889 if (unlikely(ret))
1890 return ret;
1891 counters->sa_hit_drop_redirect[0] =
1892 packed_record[0] | (packed_record[1] << 16);
1893 counters->sa_hit_drop_redirect[1] =
1894 packed_record[2] | (packed_record[3] << 16);
1895
1896 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sa_index * 8 + 1);
1897 if (unlikely(ret))
1898 return ret;
1899 counters->sa_protected2_pkts[0] =
1900 packed_record[0] | (packed_record[1] << 16);
1901 counters->sa_protected2_pkts[1] =
1902 packed_record[2] | (packed_record[3] << 16);
1903
1904 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sa_index * 8 + 2);
1905 if (unlikely(ret))
1906 return ret;
1907 counters->sa_protected_pkts[0] =
1908 packed_record[0] | (packed_record[1] << 16);
1909 counters->sa_protected_pkts[1] =
1910 packed_record[2] | (packed_record[3] << 16);
1911
1912 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: sa_index * 8 + 3);
1913 if (unlikely(ret))
1914 return ret;
1915 counters->sa_encrypted_pkts[0] =
1916 packed_record[0] | (packed_record[1] << 16);
1917 counters->sa_encrypted_pkts[1] =
1918 packed_record[2] | (packed_record[3] << 16);
1919
1920 return 0;
1921}
1922
1923int aq_mss_get_egress_sa_counters(struct aq_hw_s *hw,
1924 struct aq_mss_egress_sa_counters *counters,
1925 u16 sa_index)
1926{
1927 memset(counters, 0, sizeof(*counters));
1928
1929 return AQ_API_CALL_SAFE(get_egress_sa_counters, hw, counters, sa_index);
1930}
1931
1932static int
1933get_egress_common_counters(struct aq_hw_s *hw,
1934 struct aq_mss_egress_common_counters *counters)
1935{
1936 u16 packed_record[4];
1937 int ret;
1938
1939 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 0);
1940 if (unlikely(ret))
1941 return ret;
1942 counters->ctl_pkt[0] = packed_record[0] | (packed_record[1] << 16);
1943 counters->ctl_pkt[1] = packed_record[2] | (packed_record[3] << 16);
1944
1945 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 1);
1946 if (unlikely(ret))
1947 return ret;
1948 counters->unknown_sa_pkts[0] =
1949 packed_record[0] | (packed_record[1] << 16);
1950 counters->unknown_sa_pkts[1] =
1951 packed_record[2] | (packed_record[3] << 16);
1952
1953 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 2);
1954 if (unlikely(ret))
1955 return ret;
1956 counters->untagged_pkts[0] =
1957 packed_record[0] | (packed_record[1] << 16);
1958 counters->untagged_pkts[1] =
1959 packed_record[2] | (packed_record[3] << 16);
1960
1961 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 3);
1962 if (unlikely(ret))
1963 return ret;
1964 counters->too_long[0] = packed_record[0] | (packed_record[1] << 16);
1965 counters->too_long[1] = packed_record[2] | (packed_record[3] << 16);
1966
1967 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 4);
1968 if (unlikely(ret))
1969 return ret;
1970 counters->ecc_error_pkts[0] =
1971 packed_record[0] | (packed_record[1] << 16);
1972 counters->ecc_error_pkts[1] =
1973 packed_record[2] | (packed_record[3] << 16);
1974
1975 ret = get_raw_egress_record(hw, packed_record, num_words: 4, table_id: 3, table_index: 256 + 5);
1976 if (unlikely(ret))
1977 return ret;
1978 counters->unctrl_hit_drop_redir[0] =
1979 packed_record[0] | (packed_record[1] << 16);
1980 counters->unctrl_hit_drop_redir[1] =
1981 packed_record[2] | (packed_record[3] << 16);
1982
1983 return 0;
1984}
1985
1986int aq_mss_get_egress_common_counters(struct aq_hw_s *hw,
1987 struct aq_mss_egress_common_counters *counters)
1988{
1989 memset(counters, 0, sizeof(*counters));
1990
1991 return AQ_API_CALL_SAFE(get_egress_common_counters, hw, counters);
1992}
1993
1994static int clear_egress_counters(struct aq_hw_s *hw)
1995{
1996 struct mss_egress_ctl_register ctl_reg;
1997 int ret;
1998
1999 memset(&ctl_reg, 0, sizeof(ctl_reg));
2000
2001 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, MSS_EGRESS_CTL_REGISTER_ADDR,
2002 data: &ctl_reg.word_0);
2003 if (unlikely(ret))
2004 return ret;
2005 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2006 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2007 data: &ctl_reg.word_1);
2008 if (unlikely(ret))
2009 return ret;
2010
2011 /* Toggle the Egress MIB clear bit 0->1->0 */
2012 ctl_reg.bits_0.clear_counter = 0;
2013 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2014 MSS_EGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2015 if (unlikely(ret))
2016 return ret;
2017 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2018 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2019 data: ctl_reg.word_1);
2020 if (unlikely(ret))
2021 return ret;
2022
2023 ctl_reg.bits_0.clear_counter = 1;
2024 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2025 MSS_EGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2026 if (unlikely(ret))
2027 return ret;
2028 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2029 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2030 data: ctl_reg.word_1);
2031 if (unlikely(ret))
2032 return ret;
2033
2034 ctl_reg.bits_0.clear_counter = 0;
2035 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2036 MSS_EGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2037 if (unlikely(ret))
2038 return ret;
2039 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2040 MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2041 data: ctl_reg.word_1);
2042 if (unlikely(ret))
2043 return ret;
2044
2045 return 0;
2046}
2047
2048int aq_mss_clear_egress_counters(struct aq_hw_s *hw)
2049{
2050 return AQ_API_CALL_SAFE(clear_egress_counters, hw);
2051}
2052
2053static int get_ingress_sa_counters(struct aq_hw_s *hw,
2054 struct aq_mss_ingress_sa_counters *counters,
2055 u16 sa_index)
2056{
2057 u16 packed_record[4];
2058 int ret;
2059
2060 if (sa_index >= NUMROWS_INGRESSSARECORD)
2061 return -EINVAL;
2062
2063 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2064 table_index: sa_index * 12 + 0);
2065 if (unlikely(ret))
2066 return ret;
2067 counters->untagged_hit_pkts[0] =
2068 packed_record[0] | (packed_record[1] << 16);
2069 counters->untagged_hit_pkts[1] =
2070 packed_record[2] | (packed_record[3] << 16);
2071
2072 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2073 table_index: sa_index * 12 + 1);
2074 if (unlikely(ret))
2075 return ret;
2076 counters->ctrl_hit_drop_redir_pkts[0] =
2077 packed_record[0] | (packed_record[1] << 16);
2078 counters->ctrl_hit_drop_redir_pkts[1] =
2079 packed_record[2] | (packed_record[3] << 16);
2080
2081 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2082 table_index: sa_index * 12 + 2);
2083 if (unlikely(ret))
2084 return ret;
2085 counters->not_using_sa[0] = packed_record[0] | (packed_record[1] << 16);
2086 counters->not_using_sa[1] = packed_record[2] | (packed_record[3] << 16);
2087
2088 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2089 table_index: sa_index * 12 + 3);
2090 if (unlikely(ret))
2091 return ret;
2092 counters->unused_sa[0] = packed_record[0] | (packed_record[1] << 16);
2093 counters->unused_sa[1] = packed_record[2] | (packed_record[3] << 16);
2094
2095 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2096 table_index: sa_index * 12 + 4);
2097 if (unlikely(ret))
2098 return ret;
2099 counters->not_valid_pkts[0] =
2100 packed_record[0] | (packed_record[1] << 16);
2101 counters->not_valid_pkts[1] =
2102 packed_record[2] | (packed_record[3] << 16);
2103
2104 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2105 table_index: sa_index * 12 + 5);
2106 if (unlikely(ret))
2107 return ret;
2108 counters->invalid_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2109 counters->invalid_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2110
2111 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2112 table_index: sa_index * 12 + 6);
2113 if (unlikely(ret))
2114 return ret;
2115 counters->ok_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2116 counters->ok_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2117
2118 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2119 table_index: sa_index * 12 + 7);
2120 if (unlikely(ret))
2121 return ret;
2122 counters->late_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2123 counters->late_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2124
2125 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2126 table_index: sa_index * 12 + 8);
2127 if (unlikely(ret))
2128 return ret;
2129 counters->delayed_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2130 counters->delayed_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2131
2132 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2133 table_index: sa_index * 12 + 9);
2134 if (unlikely(ret))
2135 return ret;
2136 counters->unchecked_pkts[0] =
2137 packed_record[0] | (packed_record[1] << 16);
2138 counters->unchecked_pkts[1] =
2139 packed_record[2] | (packed_record[3] << 16);
2140
2141 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2142 table_index: sa_index * 12 + 10);
2143 if (unlikely(ret))
2144 return ret;
2145 counters->validated_octets[0] =
2146 packed_record[0] | (packed_record[1] << 16);
2147 counters->validated_octets[1] =
2148 packed_record[2] | (packed_record[3] << 16);
2149
2150 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6,
2151 table_index: sa_index * 12 + 11);
2152 if (unlikely(ret))
2153 return ret;
2154 counters->decrypted_octets[0] =
2155 packed_record[0] | (packed_record[1] << 16);
2156 counters->decrypted_octets[1] =
2157 packed_record[2] | (packed_record[3] << 16);
2158
2159 return 0;
2160}
2161
2162int aq_mss_get_ingress_sa_counters(struct aq_hw_s *hw,
2163 struct aq_mss_ingress_sa_counters *counters,
2164 u16 sa_index)
2165{
2166 memset(counters, 0, sizeof(*counters));
2167
2168 return AQ_API_CALL_SAFE(get_ingress_sa_counters, hw, counters,
2169 sa_index);
2170}
2171
2172static int
2173get_ingress_common_counters(struct aq_hw_s *hw,
2174 struct aq_mss_ingress_common_counters *counters)
2175{
2176 u16 packed_record[4];
2177 int ret;
2178
2179 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 0);
2180 if (unlikely(ret))
2181 return ret;
2182 counters->ctl_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2183 counters->ctl_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2184
2185 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 1);
2186 if (unlikely(ret))
2187 return ret;
2188 counters->tagged_miss_pkts[0] =
2189 packed_record[0] | (packed_record[1] << 16);
2190 counters->tagged_miss_pkts[1] =
2191 packed_record[2] | (packed_record[3] << 16);
2192
2193 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 2);
2194 if (unlikely(ret))
2195 return ret;
2196 counters->untagged_miss_pkts[0] =
2197 packed_record[0] | (packed_record[1] << 16);
2198 counters->untagged_miss_pkts[1] =
2199 packed_record[2] | (packed_record[3] << 16);
2200
2201 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 3);
2202 if (unlikely(ret))
2203 return ret;
2204 counters->notag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2205 counters->notag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2206
2207 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 4);
2208 if (unlikely(ret))
2209 return ret;
2210 counters->untagged_pkts[0] =
2211 packed_record[0] | (packed_record[1] << 16);
2212 counters->untagged_pkts[1] =
2213 packed_record[2] | (packed_record[3] << 16);
2214
2215 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 5);
2216 if (unlikely(ret))
2217 return ret;
2218 counters->bad_tag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2219 counters->bad_tag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2220
2221 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 6);
2222 if (unlikely(ret))
2223 return ret;
2224 counters->no_sci_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2225 counters->no_sci_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2226
2227 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 7);
2228 if (unlikely(ret))
2229 return ret;
2230 counters->unknown_sci_pkts[0] =
2231 packed_record[0] | (packed_record[1] << 16);
2232 counters->unknown_sci_pkts[1] =
2233 packed_record[2] | (packed_record[3] << 16);
2234
2235 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 8);
2236 if (unlikely(ret))
2237 return ret;
2238 counters->ctrl_prt_pass_pkts[0] =
2239 packed_record[0] | (packed_record[1] << 16);
2240 counters->ctrl_prt_pass_pkts[1] =
2241 packed_record[2] | (packed_record[3] << 16);
2242
2243 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 9);
2244 if (unlikely(ret))
2245 return ret;
2246 counters->unctrl_prt_pass_pkts[0] =
2247 packed_record[0] | (packed_record[1] << 16);
2248 counters->unctrl_prt_pass_pkts[1] =
2249 packed_record[2] | (packed_record[3] << 16);
2250
2251 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 10);
2252 if (unlikely(ret))
2253 return ret;
2254 counters->ctrl_prt_fail_pkts[0] =
2255 packed_record[0] | (packed_record[1] << 16);
2256 counters->ctrl_prt_fail_pkts[1] =
2257 packed_record[2] | (packed_record[3] << 16);
2258
2259 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 11);
2260 if (unlikely(ret))
2261 return ret;
2262 counters->unctrl_prt_fail_pkts[0] =
2263 packed_record[0] | (packed_record[1] << 16);
2264 counters->unctrl_prt_fail_pkts[1] =
2265 packed_record[2] | (packed_record[3] << 16);
2266
2267 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 12);
2268 if (unlikely(ret))
2269 return ret;
2270 counters->too_long_pkts[0] =
2271 packed_record[0] | (packed_record[1] << 16);
2272 counters->too_long_pkts[1] =
2273 packed_record[2] | (packed_record[3] << 16);
2274
2275 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 13);
2276 if (unlikely(ret))
2277 return ret;
2278 counters->igpoc_ctl_pkts[0] =
2279 packed_record[0] | (packed_record[1] << 16);
2280 counters->igpoc_ctl_pkts[1] =
2281 packed_record[2] | (packed_record[3] << 16);
2282
2283 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 14);
2284 if (unlikely(ret))
2285 return ret;
2286 counters->ecc_error_pkts[0] =
2287 packed_record[0] | (packed_record[1] << 16);
2288 counters->ecc_error_pkts[1] =
2289 packed_record[2] | (packed_record[3] << 16);
2290
2291 ret = get_raw_ingress_record(hw, packed_record, num_words: 4, table_id: 6, table_index: 385 + 15);
2292 if (unlikely(ret))
2293 return ret;
2294 counters->unctrl_hit_drop_redir[0] =
2295 packed_record[0] | (packed_record[1] << 16);
2296 counters->unctrl_hit_drop_redir[1] =
2297 packed_record[2] | (packed_record[3] << 16);
2298
2299 return 0;
2300}
2301
2302int aq_mss_get_ingress_common_counters(struct aq_hw_s *hw,
2303 struct aq_mss_ingress_common_counters *counters)
2304{
2305 memset(counters, 0, sizeof(*counters));
2306
2307 return AQ_API_CALL_SAFE(get_ingress_common_counters, hw, counters);
2308}
2309
2310static int clear_ingress_counters(struct aq_hw_s *hw)
2311{
2312 struct mss_ingress_ctl_register ctl_reg;
2313 int ret;
2314
2315 memset(&ctl_reg, 0, sizeof(ctl_reg));
2316
2317 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2318 MSS_INGRESS_CTL_REGISTER_ADDR, data: &ctl_reg.word_0);
2319 if (unlikely(ret))
2320 return ret;
2321 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2322 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2323 data: &ctl_reg.word_1);
2324 if (unlikely(ret))
2325 return ret;
2326
2327 /* Toggle the Ingress MIB clear bit 0->1->0 */
2328 ctl_reg.bits_0.clear_count = 0;
2329 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2330 MSS_INGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2331 if (unlikely(ret))
2332 return ret;
2333 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2334 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2335 data: ctl_reg.word_1);
2336 if (unlikely(ret))
2337 return ret;
2338
2339 ctl_reg.bits_0.clear_count = 1;
2340 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2341 MSS_INGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2342 if (unlikely(ret))
2343 return ret;
2344 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2345 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2346 data: ctl_reg.word_1);
2347 if (unlikely(ret))
2348 return ret;
2349
2350 ctl_reg.bits_0.clear_count = 0;
2351 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2352 MSS_INGRESS_CTL_REGISTER_ADDR, data: ctl_reg.word_0);
2353 if (unlikely(ret))
2354 return ret;
2355 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2356 MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2357 data: ctl_reg.word_1);
2358 if (unlikely(ret))
2359 return ret;
2360
2361 return 0;
2362}
2363
2364int aq_mss_clear_ingress_counters(struct aq_hw_s *hw)
2365{
2366 return AQ_API_CALL_SAFE(clear_ingress_counters, hw);
2367}
2368
2369static int get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
2370{
2371 u16 val;
2372 int ret;
2373
2374 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2375 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
2376 data: &val);
2377 if (unlikely(ret))
2378 return ret;
2379
2380 *expired = val;
2381
2382 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2383 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
2384 data: &val);
2385 if (unlikely(ret))
2386 return ret;
2387
2388 *expired |= val << 16;
2389
2390 return 0;
2391}
2392
2393int aq_mss_get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
2394{
2395 *expired = 0;
2396
2397 return AQ_API_CALL_SAFE(get_egress_sa_expired, hw, expired);
2398}
2399
2400static int get_egress_sa_threshold_expired(struct aq_hw_s *hw,
2401 u32 *expired)
2402{
2403 u16 val;
2404 int ret;
2405
2406 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2407 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, data: &val);
2408 if (unlikely(ret))
2409 return ret;
2410
2411 *expired = val;
2412
2413 ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2414 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, data: &val);
2415 if (unlikely(ret))
2416 return ret;
2417
2418 *expired |= val << 16;
2419
2420 return 0;
2421}
2422
2423int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s *hw,
2424 u32 *expired)
2425{
2426 *expired = 0;
2427
2428 return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired, hw, expired);
2429}
2430
2431static int set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
2432{
2433 int ret;
2434
2435 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2436 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
2437 data: expired & 0xFFFF);
2438 if (unlikely(ret))
2439 return ret;
2440
2441 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2442 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
2443 data: expired >> 16);
2444 if (unlikely(ret))
2445 return ret;
2446
2447 return 0;
2448}
2449
2450int aq_mss_set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
2451{
2452 return AQ_API_CALL_SAFE(set_egress_sa_expired, hw, expired);
2453}
2454
2455static int set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
2456{
2457 int ret;
2458
2459 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2460 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR,
2461 data: expired & 0xFFFF);
2462 if (unlikely(ret))
2463 return ret;
2464
2465 ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2466 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1,
2467 data: expired >> 16);
2468 if (unlikely(ret))
2469 return ret;
2470
2471 return 0;
2472}
2473
2474int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
2475{
2476 return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired, hw, expired);
2477}
2478

source code of linux/drivers/net/ethernet/aquantia/atlantic/macsec/macsec_api.c