1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Atlantic Network Driver
3 * Copyright (C) 2020 Marvell International Ltd.
6 #include "macsec_api.h"
7 #include <linux/mdio.h>
8 #include "MSS_Ingress_registers.h"
9 #include "MSS_Egress_registers.h"
12 #define AQ_API_CALL_SAFE(func, ...) \
16 ret = aq_mss_mdio_sem_get(hw); \
20 ret = func(__VA_ARGS__); \
22 aq_mss_mdio_sem_put(hw); \
27 /*******************************************************************************
29 ******************************************************************************/
30 static int aq_mss_mdio_sem_get(struct aq_hw_s
*hw
)
34 return readx_poll_timeout_atomic(hw_atl_sem_mdio_get
, hw
, val
,
35 val
== 1U, 10U, 100000U);
38 static void aq_mss_mdio_sem_put(struct aq_hw_s
*hw
)
40 hw_atl_reg_glb_cpu_sem_set(hw
, 1U, HW_ATL_FW_SM_MDIO
);
43 static int aq_mss_mdio_read(struct aq_hw_s
*hw
, u16 mmd
, u16 addr
, u16
*data
)
45 *data
= aq_mdio_read_word(hw
, mmd
, addr
);
46 return (*data
!= 0xffff) ? 0 : -ETIME
;
49 static int aq_mss_mdio_write(struct aq_hw_s
*hw
, u16 mmd
, u16 addr
, u16 data
)
51 aq_mdio_write_word(hw
, mmd
, addr
, data
);
55 /*******************************************************************************
56 * MACSEC config and status
57 ******************************************************************************/
59 static int set_raw_ingress_record(struct aq_hw_s
*hw
, u16
*packed_record
,
60 u8 num_words
, u8 table_id
,
63 struct mss_ingress_lut_addr_ctl_register lut_sel_reg
;
64 struct mss_ingress_lut_ctl_register lut_op_reg
;
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
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
77 * For EUR devices: Not need to use the PIF mailbox; it is safe to
78 * write to the registers directly.
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
,
86 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
87 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR
+ i
+
89 packed_record
[i
+ 1]);
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
,
97 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
98 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR
+ i
+ 1, 0);
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
;
105 lut_op_reg
.bits_0
.lut_read
= 0;
106 lut_op_reg
.bits_0
.lut_write
= 1;
108 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
109 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR
,
111 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
, MSS_INGRESS_LUT_CTL_REGISTER_ADDR
,
117 /*! Read the specified Ingress LUT table row.
118 * packed_record - [OUT] The table row data (raw).
120 static int get_raw_ingress_record(struct aq_hw_s
*hw
, u16
*packed_record
,
121 u8 num_words
, u8 table_id
,
124 struct mss_ingress_lut_addr_ctl_register lut_sel_reg
;
125 struct mss_ingress_lut_ctl_register lut_op_reg
;
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
;
134 lut_op_reg
.bits_0
.lut_read
= 1;
135 lut_op_reg
.bits_0
.lut_write
= 0;
137 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
138 MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR
,
142 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
143 MSS_INGRESS_LUT_CTL_REGISTER_ADDR
,
148 memset(packed_record
, 0, sizeof(u16
) * num_words
);
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
+
157 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
158 MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR
+
160 &packed_record
[i
+ 1]);
168 /*! Write packed_record to the specified Egress LUT table row. */
169 static int set_raw_egress_record(struct aq_hw_s
*hw
, u16
*packed_record
,
170 u8 num_words
, u8 table_id
,
173 struct mss_egress_lut_addr_ctl_register lut_sel_reg
;
174 struct mss_egress_lut_ctl_register lut_op_reg
;
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
,
183 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
184 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR
+ i
+ 1,
185 packed_record
[i
+ 1]);
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,
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
;
201 lut_op_reg
.bits_0
.lut_read
= 0;
202 lut_op_reg
.bits_0
.lut_write
= 1;
204 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
205 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR
,
207 aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
, MSS_EGRESS_LUT_CTL_REGISTER_ADDR
,
213 static int get_raw_egress_record(struct aq_hw_s
*hw
, u16
*packed_record
,
214 u8 num_words
, u8 table_id
,
217 struct mss_egress_lut_addr_ctl_register lut_sel_reg
;
218 struct mss_egress_lut_ctl_register lut_op_reg
;
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
;
227 lut_op_reg
.bits_0
.lut_read
= 1;
228 lut_op_reg
.bits_0
.lut_write
= 0;
230 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
231 MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR
,
235 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
236 MSS_EGRESS_LUT_CTL_REGISTER_ADDR
,
241 memset(packed_record
, 0, sizeof(u16
) * num_words
);
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
+
250 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
251 MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR
+
253 &packed_record
[i
+ 1]);
262 set_ingress_prectlf_record(struct aq_hw_s
*hw
,
263 const struct aq_mss_ingress_prectlf_record
*rec
,
266 u16 packed_record
[6];
268 if (table_index
>= NUMROWS_INGRESSPRECTLFRECORD
)
271 memset(packed_record
, 0, sizeof(u16
) * 6);
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;
281 return set_raw_ingress_record(hw
, packed_record
, 6, 0,
282 ROWOFFSET_INGRESSPRECTLFRECORD
+
286 int aq_mss_set_ingress_prectlf_record(struct aq_hw_s
*hw
,
287 const struct aq_mss_ingress_prectlf_record
*rec
,
290 return AQ_API_CALL_SAFE(set_ingress_prectlf_record
, hw
, rec
,
294 static int get_ingress_prectlf_record(struct aq_hw_s
*hw
,
295 struct aq_mss_ingress_prectlf_record
*rec
,
298 u16 packed_record
[6];
301 if (table_index
>= NUMROWS_INGRESSPRECTLFRECORD
)
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.
310 if ((table_index
% 2) > 0) {
311 ret
= get_raw_ingress_record(hw
, packed_record
, 6, 0,
312 ROWOFFSET_INGRESSPRECTLFRECORD
+
318 ret
= get_raw_ingress_record(hw
, packed_record
, 6, 0,
319 ROWOFFSET_INGRESSPRECTLFRECORD
+
324 rec
->sa_da
[0] = packed_record
[0];
325 rec
->sa_da
[0] |= packed_record
[1] << 16;
327 rec
->sa_da
[1] = packed_record
[2];
329 rec
->eth_type
= packed_record
[3];
331 rec
->match_mask
= packed_record
[4];
333 rec
->match_type
= packed_record
[5] & 0xF;
335 rec
->action
= (packed_record
[5] >> 4) & 0x1;
340 int aq_mss_get_ingress_prectlf_record(struct aq_hw_s
*hw
,
341 struct aq_mss_ingress_prectlf_record
*rec
,
344 memset(rec
, 0, sizeof(*rec
));
346 return AQ_API_CALL_SAFE(get_ingress_prectlf_record
, hw
, rec
,
351 set_ingress_preclass_record(struct aq_hw_s
*hw
,
352 const struct aq_mss_ingress_preclass_record
*rec
,
355 u16 packed_record
[20];
357 if (table_index
>= NUMROWS_INGRESSPRECLASSRECORD
)
360 memset(packed_record
, 0, sizeof(u16
) * 20);
362 packed_record
[0] = rec
->sci
[0] & 0xFFFF;
363 packed_record
[1] = (rec
->sci
[0] >> 16) & 0xFFFF;
365 packed_record
[2] = rec
->sci
[1] & 0xFFFF;
366 packed_record
[3] = (rec
->sci
[1] >> 16) & 0xFFFF;
368 packed_record
[4] = rec
->tci
& 0xFF;
370 packed_record
[4] |= (rec
->encr_offset
& 0xFF) << 8;
372 packed_record
[5] = rec
->eth_type
& 0xFFFF;
374 packed_record
[6] = rec
->snap
[0] & 0xFFFF;
375 packed_record
[7] = (rec
->snap
[0] >> 16) & 0xFFFF;
377 packed_record
[8] = rec
->snap
[1] & 0xFF;
379 packed_record
[8] |= (rec
->llc
& 0xFF) << 8;
380 packed_record
[9] = (rec
->llc
>> 8) & 0xFFFF;
382 packed_record
[10] = rec
->mac_sa
[0] & 0xFFFF;
383 packed_record
[11] = (rec
->mac_sa
[0] >> 16) & 0xFFFF;
385 packed_record
[12] = rec
->mac_sa
[1] & 0xFFFF;
387 packed_record
[13] = rec
->mac_da
[0] & 0xFFFF;
388 packed_record
[14] = (rec
->mac_da
[0] >> 16) & 0xFFFF;
390 packed_record
[15] = rec
->mac_da
[1] & 0xFFFF;
392 packed_record
[16] = rec
->lpbk_packet
& 0x1;
394 packed_record
[16] |= (rec
->an_mask
& 0x3) << 1;
396 packed_record
[16] |= (rec
->tci_mask
& 0x3F) << 3;
398 packed_record
[16] |= (rec
->sci_mask
& 0x7F) << 9;
399 packed_record
[17] = (rec
->sci_mask
>> 7) & 0x1;
401 packed_record
[17] |= (rec
->eth_type_mask
& 0x3) << 1;
403 packed_record
[17] |= (rec
->snap_mask
& 0x1F) << 3;
405 packed_record
[17] |= (rec
->llc_mask
& 0x7) << 8;
407 packed_record
[17] |= (rec
->_802_2_encapsulate
& 0x1) << 11;
409 packed_record
[17] |= (rec
->sa_mask
& 0xF) << 12;
410 packed_record
[18] = (rec
->sa_mask
>> 4) & 0x3;
412 packed_record
[18] |= (rec
->da_mask
& 0x3F) << 2;
414 packed_record
[18] |= (rec
->lpbk_mask
& 0x1) << 8;
416 packed_record
[18] |= (rec
->sc_idx
& 0x1F) << 9;
418 packed_record
[18] |= (rec
->proc_dest
& 0x1) << 14;
420 packed_record
[18] |= (rec
->action
& 0x1) << 15;
421 packed_record
[19] = (rec
->action
>> 1) & 0x1;
423 packed_record
[19] |= (rec
->ctrl_unctrl
& 0x1) << 1;
425 packed_record
[19] |= (rec
->sci_from_table
& 0x1) << 2;
427 packed_record
[19] |= (rec
->reserved
& 0xF) << 3;
429 packed_record
[19] |= (rec
->valid
& 0x1) << 7;
431 return set_raw_ingress_record(hw
, packed_record
, 20, 1,
432 ROWOFFSET_INGRESSPRECLASSRECORD
+
436 int aq_mss_set_ingress_preclass_record(struct aq_hw_s
*hw
,
437 const struct aq_mss_ingress_preclass_record
*rec
,
440 int err
= AQ_API_CALL_SAFE(set_ingress_preclass_record
, hw
, rec
,
443 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
449 get_ingress_preclass_record(struct aq_hw_s
*hw
,
450 struct aq_mss_ingress_preclass_record
*rec
,
453 u16 packed_record
[20];
456 if (table_index
>= NUMROWS_INGRESSPRECLASSRECORD
)
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.
462 if ((table_index
% 2) > 0) {
463 ret
= get_raw_ingress_record(hw
, packed_record
, 20, 1,
464 ROWOFFSET_INGRESSPRECLASSRECORD
+
470 ret
= get_raw_ingress_record(hw
, packed_record
, 20, 1,
471 ROWOFFSET_INGRESSPRECLASSRECORD
+
476 rec
->sci
[0] = packed_record
[0];
477 rec
->sci
[0] |= packed_record
[1] << 16;
479 rec
->sci
[1] = packed_record
[2];
480 rec
->sci
[1] |= packed_record
[3] << 16;
482 rec
->tci
= packed_record
[4] & 0xFF;
484 rec
->encr_offset
= (packed_record
[4] >> 8) & 0xFF;
486 rec
->eth_type
= packed_record
[5];
488 rec
->snap
[0] = packed_record
[6];
489 rec
->snap
[0] |= packed_record
[7] << 16;
491 rec
->snap
[1] = packed_record
[8] & 0xFF;
493 rec
->llc
= (packed_record
[8] >> 8) & 0xFF;
494 rec
->llc
|= packed_record
[9] << 8;
496 rec
->mac_sa
[0] = packed_record
[10];
497 rec
->mac_sa
[0] |= packed_record
[11] << 16;
499 rec
->mac_sa
[1] = packed_record
[12];
501 rec
->mac_da
[0] = packed_record
[13];
502 rec
->mac_da
[0] |= packed_record
[14] << 16;
504 rec
->mac_da
[1] = packed_record
[15];
506 rec
->lpbk_packet
= packed_record
[16] & 0x1;
508 rec
->an_mask
= (packed_record
[16] >> 1) & 0x3;
510 rec
->tci_mask
= (packed_record
[16] >> 3) & 0x3F;
512 rec
->sci_mask
= (packed_record
[16] >> 9) & 0x7F;
513 rec
->sci_mask
|= (packed_record
[17] & 0x1) << 7;
515 rec
->eth_type_mask
= (packed_record
[17] >> 1) & 0x3;
517 rec
->snap_mask
= (packed_record
[17] >> 3) & 0x1F;
519 rec
->llc_mask
= (packed_record
[17] >> 8) & 0x7;
521 rec
->_802_2_encapsulate
= (packed_record
[17] >> 11) & 0x1;
523 rec
->sa_mask
= (packed_record
[17] >> 12) & 0xF;
524 rec
->sa_mask
|= (packed_record
[18] & 0x3) << 4;
526 rec
->da_mask
= (packed_record
[18] >> 2) & 0x3F;
528 rec
->lpbk_mask
= (packed_record
[18] >> 8) & 0x1;
530 rec
->sc_idx
= (packed_record
[18] >> 9) & 0x1F;
532 rec
->proc_dest
= (packed_record
[18] >> 14) & 0x1;
534 rec
->action
= (packed_record
[18] >> 15) & 0x1;
535 rec
->action
|= (packed_record
[19] & 0x1) << 1;
537 rec
->ctrl_unctrl
= (packed_record
[19] >> 1) & 0x1;
539 rec
->sci_from_table
= (packed_record
[19] >> 2) & 0x1;
541 rec
->reserved
= (packed_record
[19] >> 3) & 0xF;
543 rec
->valid
= (packed_record
[19] >> 7) & 0x1;
548 int aq_mss_get_ingress_preclass_record(struct aq_hw_s
*hw
,
549 struct aq_mss_ingress_preclass_record
*rec
,
552 memset(rec
, 0, sizeof(*rec
));
554 return AQ_API_CALL_SAFE(get_ingress_preclass_record
, hw
, rec
,
558 static int set_ingress_sc_record(struct aq_hw_s
*hw
,
559 const struct aq_mss_ingress_sc_record
*rec
,
562 u16 packed_record
[8];
564 if (table_index
>= NUMROWS_INGRESSSCRECORD
)
567 memset(packed_record
, 0, sizeof(u16
) * 8);
569 packed_record
[0] = rec
->stop_time
& 0xFFFF;
570 packed_record
[1] = (rec
->stop_time
>> 16) & 0xFFFF;
572 packed_record
[2] = rec
->start_time
& 0xFFFF;
573 packed_record
[3] = (rec
->start_time
>> 16) & 0xFFFF;
575 packed_record
[4] = rec
->validate_frames
& 0x3;
577 packed_record
[4] |= (rec
->replay_protect
& 0x1) << 2;
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;
583 packed_record
[6] |= (rec
->receiving
& 0x1) << 3;
585 packed_record
[6] |= (rec
->fresh
& 0x1) << 4;
587 packed_record
[6] |= (rec
->an_rol
& 0x1) << 5;
589 packed_record
[6] |= (rec
->reserved
& 0x3FF) << 6;
590 packed_record
[7] = (rec
->reserved
>> 10) & 0x7FFF;
592 packed_record
[7] |= (rec
->valid
& 0x1) << 15;
594 return set_raw_ingress_record(hw
, packed_record
, 8, 3,
595 ROWOFFSET_INGRESSSCRECORD
+ table_index
);
598 int aq_mss_set_ingress_sc_record(struct aq_hw_s
*hw
,
599 const struct aq_mss_ingress_sc_record
*rec
,
602 int err
= AQ_API_CALL_SAFE(set_ingress_sc_record
, hw
, rec
, table_index
);
604 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
609 static int get_ingress_sc_record(struct aq_hw_s
*hw
,
610 struct aq_mss_ingress_sc_record
*rec
,
613 u16 packed_record
[8];
616 if (table_index
>= NUMROWS_INGRESSSCRECORD
)
619 ret
= get_raw_ingress_record(hw
, packed_record
, 8, 3,
620 ROWOFFSET_INGRESSSCRECORD
+ table_index
);
624 rec
->stop_time
= packed_record
[0];
625 rec
->stop_time
|= packed_record
[1] << 16;
627 rec
->start_time
= packed_record
[2];
628 rec
->start_time
|= packed_record
[3] << 16;
630 rec
->validate_frames
= packed_record
[4] & 0x3;
632 rec
->replay_protect
= (packed_record
[4] >> 2) & 0x1;
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;
638 rec
->receiving
= (packed_record
[6] >> 3) & 0x1;
640 rec
->fresh
= (packed_record
[6] >> 4) & 0x1;
642 rec
->an_rol
= (packed_record
[6] >> 5) & 0x1;
644 rec
->reserved
= (packed_record
[6] >> 6) & 0x3FF;
645 rec
->reserved
|= (packed_record
[7] & 0x7FFF) << 10;
647 rec
->valid
= (packed_record
[7] >> 15) & 0x1;
652 int aq_mss_get_ingress_sc_record(struct aq_hw_s
*hw
,
653 struct aq_mss_ingress_sc_record
*rec
,
656 memset(rec
, 0, sizeof(*rec
));
658 return AQ_API_CALL_SAFE(get_ingress_sc_record
, hw
, rec
, table_index
);
661 static int set_ingress_sa_record(struct aq_hw_s
*hw
,
662 const struct aq_mss_ingress_sa_record
*rec
,
665 u16 packed_record
[8];
667 if (table_index
>= NUMROWS_INGRESSSARECORD
)
670 memset(packed_record
, 0, sizeof(u16
) * 8);
672 packed_record
[0] = rec
->stop_time
& 0xFFFF;
673 packed_record
[1] = (rec
->stop_time
>> 16) & 0xFFFF;
675 packed_record
[2] = rec
->start_time
& 0xFFFF;
676 packed_record
[3] = (rec
->start_time
>> 16) & 0xFFFF;
678 packed_record
[4] = rec
->next_pn
& 0xFFFF;
679 packed_record
[5] = (rec
->next_pn
>> 16) & 0xFFFF;
681 packed_record
[6] = rec
->sat_nextpn
& 0x1;
683 packed_record
[6] |= (rec
->in_use
& 0x1) << 1;
685 packed_record
[6] |= (rec
->fresh
& 0x1) << 2;
687 packed_record
[6] |= (rec
->reserved
& 0x1FFF) << 3;
688 packed_record
[7] = (rec
->reserved
>> 13) & 0x7FFF;
690 packed_record
[7] |= (rec
->valid
& 0x1) << 15;
692 return set_raw_ingress_record(hw
, packed_record
, 8, 3,
693 ROWOFFSET_INGRESSSARECORD
+ table_index
);
696 int aq_mss_set_ingress_sa_record(struct aq_hw_s
*hw
,
697 const struct aq_mss_ingress_sa_record
*rec
,
700 int err
= AQ_API_CALL_SAFE(set_ingress_sa_record
, hw
, rec
, table_index
);
702 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
707 static int get_ingress_sa_record(struct aq_hw_s
*hw
,
708 struct aq_mss_ingress_sa_record
*rec
,
711 u16 packed_record
[8];
714 if (table_index
>= NUMROWS_INGRESSSARECORD
)
717 ret
= get_raw_ingress_record(hw
, packed_record
, 8, 3,
718 ROWOFFSET_INGRESSSARECORD
+ table_index
);
722 rec
->stop_time
= packed_record
[0];
723 rec
->stop_time
|= packed_record
[1] << 16;
725 rec
->start_time
= packed_record
[2];
726 rec
->start_time
|= packed_record
[3] << 16;
728 rec
->next_pn
= packed_record
[4];
729 rec
->next_pn
|= packed_record
[5] << 16;
731 rec
->sat_nextpn
= packed_record
[6] & 0x1;
733 rec
->in_use
= (packed_record
[6] >> 1) & 0x1;
735 rec
->fresh
= (packed_record
[6] >> 2) & 0x1;
737 rec
->reserved
= (packed_record
[6] >> 3) & 0x1FFF;
738 rec
->reserved
|= (packed_record
[7] & 0x7FFF) << 13;
740 rec
->valid
= (packed_record
[7] >> 15) & 0x1;
745 int aq_mss_get_ingress_sa_record(struct aq_hw_s
*hw
,
746 struct aq_mss_ingress_sa_record
*rec
,
749 memset(rec
, 0, sizeof(*rec
));
751 return AQ_API_CALL_SAFE(get_ingress_sa_record
, hw
, rec
, table_index
);
755 set_ingress_sakey_record(struct aq_hw_s
*hw
,
756 const struct aq_mss_ingress_sakey_record
*rec
,
759 u16 packed_record
[18];
761 if (table_index
>= NUMROWS_INGRESSSAKEYRECORD
)
764 memset(packed_record
, 0, sizeof(u16
) * 18);
766 packed_record
[0] = rec
->key
[0] & 0xFFFF;
767 packed_record
[1] = (rec
->key
[0] >> 16) & 0xFFFF;
769 packed_record
[2] = rec
->key
[1] & 0xFFFF;
770 packed_record
[3] = (rec
->key
[1] >> 16) & 0xFFFF;
772 packed_record
[4] = rec
->key
[2] & 0xFFFF;
773 packed_record
[5] = (rec
->key
[2] >> 16) & 0xFFFF;
775 packed_record
[6] = rec
->key
[3] & 0xFFFF;
776 packed_record
[7] = (rec
->key
[3] >> 16) & 0xFFFF;
778 packed_record
[8] = rec
->key
[4] & 0xFFFF;
779 packed_record
[9] = (rec
->key
[4] >> 16) & 0xFFFF;
781 packed_record
[10] = rec
->key
[5] & 0xFFFF;
782 packed_record
[11] = (rec
->key
[5] >> 16) & 0xFFFF;
784 packed_record
[12] = rec
->key
[6] & 0xFFFF;
785 packed_record
[13] = (rec
->key
[6] >> 16) & 0xFFFF;
787 packed_record
[14] = rec
->key
[7] & 0xFFFF;
788 packed_record
[15] = (rec
->key
[7] >> 16) & 0xFFFF;
790 packed_record
[16] = rec
->key_len
& 0x3;
792 return set_raw_ingress_record(hw
, packed_record
, 18, 2,
793 ROWOFFSET_INGRESSSAKEYRECORD
+
797 int aq_mss_set_ingress_sakey_record(struct aq_hw_s
*hw
,
798 const struct aq_mss_ingress_sakey_record
*rec
,
801 int err
= AQ_API_CALL_SAFE(set_ingress_sakey_record
, hw
, rec
,
804 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
809 static int get_ingress_sakey_record(struct aq_hw_s
*hw
,
810 struct aq_mss_ingress_sakey_record
*rec
,
813 u16 packed_record
[18];
816 if (table_index
>= NUMROWS_INGRESSSAKEYRECORD
)
819 ret
= get_raw_ingress_record(hw
, packed_record
, 18, 2,
820 ROWOFFSET_INGRESSSAKEYRECORD
+
825 rec
->key
[0] = packed_record
[0];
826 rec
->key
[0] |= packed_record
[1] << 16;
828 rec
->key
[1] = packed_record
[2];
829 rec
->key
[1] |= packed_record
[3] << 16;
831 rec
->key
[2] = packed_record
[4];
832 rec
->key
[2] |= packed_record
[5] << 16;
834 rec
->key
[3] = packed_record
[6];
835 rec
->key
[3] |= packed_record
[7] << 16;
837 rec
->key
[4] = packed_record
[8];
838 rec
->key
[4] |= packed_record
[9] << 16;
840 rec
->key
[5] = packed_record
[10];
841 rec
->key
[5] |= packed_record
[11] << 16;
843 rec
->key
[6] = packed_record
[12];
844 rec
->key
[6] |= packed_record
[13] << 16;
846 rec
->key
[7] = packed_record
[14];
847 rec
->key
[7] |= packed_record
[15] << 16;
849 rec
->key_len
= packed_record
[16] & 0x3;
854 int aq_mss_get_ingress_sakey_record(struct aq_hw_s
*hw
,
855 struct aq_mss_ingress_sakey_record
*rec
,
858 memset(rec
, 0, sizeof(*rec
));
860 return AQ_API_CALL_SAFE(get_ingress_sakey_record
, hw
, rec
, table_index
);
864 set_ingress_postclass_record(struct aq_hw_s
*hw
,
865 const struct aq_mss_ingress_postclass_record
*rec
,
868 u16 packed_record
[8];
870 if (table_index
>= NUMROWS_INGRESSPOSTCLASSRECORD
)
873 memset(packed_record
, 0, sizeof(u16
) * 8);
875 packed_record
[0] = rec
->byte0
& 0xFF;
877 packed_record
[0] |= (rec
->byte1
& 0xFF) << 8;
879 packed_record
[1] = rec
->byte2
& 0xFF;
881 packed_record
[1] |= (rec
->byte3
& 0xFF) << 8;
883 packed_record
[2] = rec
->eth_type
& 0xFFFF;
885 packed_record
[3] = rec
->eth_type_valid
& 0x1;
887 packed_record
[3] |= (rec
->vlan_id
& 0xFFF) << 1;
889 packed_record
[3] |= (rec
->vlan_up
& 0x7) << 13;
891 packed_record
[4] = rec
->vlan_valid
& 0x1;
893 packed_record
[4] |= (rec
->sai
& 0x1F) << 1;
895 packed_record
[4] |= (rec
->sai_hit
& 0x1) << 6;
897 packed_record
[4] |= (rec
->eth_type_mask
& 0xF) << 7;
899 packed_record
[4] |= (rec
->byte3_location
& 0x1F) << 11;
900 packed_record
[5] = (rec
->byte3_location
>> 5) & 0x1;
902 packed_record
[5] |= (rec
->byte3_mask
& 0x3) << 1;
904 packed_record
[5] |= (rec
->byte2_location
& 0x3F) << 3;
906 packed_record
[5] |= (rec
->byte2_mask
& 0x3) << 9;
908 packed_record
[5] |= (rec
->byte1_location
& 0x1F) << 11;
909 packed_record
[6] = (rec
->byte1_location
>> 5) & 0x1;
911 packed_record
[6] |= (rec
->byte1_mask
& 0x3) << 1;
913 packed_record
[6] |= (rec
->byte0_location
& 0x3F) << 3;
915 packed_record
[6] |= (rec
->byte0_mask
& 0x3) << 9;
917 packed_record
[6] |= (rec
->eth_type_valid_mask
& 0x3) << 11;
919 packed_record
[6] |= (rec
->vlan_id_mask
& 0x7) << 13;
920 packed_record
[7] = (rec
->vlan_id_mask
>> 3) & 0x1;
922 packed_record
[7] |= (rec
->vlan_up_mask
& 0x3) << 1;
924 packed_record
[7] |= (rec
->vlan_valid_mask
& 0x3) << 3;
926 packed_record
[7] |= (rec
->sai_mask
& 0x3) << 5;
928 packed_record
[7] |= (rec
->sai_hit_mask
& 0x3) << 7;
930 packed_record
[7] |= (rec
->firstlevel_actions
& 0x1) << 9;
932 packed_record
[7] |= (rec
->secondlevel_actions
& 0x1) << 10;
934 packed_record
[7] |= (rec
->reserved
& 0xF) << 11;
936 packed_record
[7] |= (rec
->valid
& 0x1) << 15;
938 return set_raw_ingress_record(hw
, packed_record
, 8, 4,
939 ROWOFFSET_INGRESSPOSTCLASSRECORD
+
943 int aq_mss_set_ingress_postclass_record(struct aq_hw_s
*hw
,
944 const struct aq_mss_ingress_postclass_record
*rec
,
947 return AQ_API_CALL_SAFE(set_ingress_postclass_record
, hw
, rec
,
952 get_ingress_postclass_record(struct aq_hw_s
*hw
,
953 struct aq_mss_ingress_postclass_record
*rec
,
956 u16 packed_record
[8];
959 if (table_index
>= NUMROWS_INGRESSPOSTCLASSRECORD
)
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.
965 if ((table_index
% 2) > 0) {
966 ret
= get_raw_ingress_record(hw
, packed_record
, 8, 4,
967 ROWOFFSET_INGRESSPOSTCLASSRECORD
+
973 ret
= get_raw_ingress_record(hw
, packed_record
, 8, 4,
974 ROWOFFSET_INGRESSPOSTCLASSRECORD
+
979 rec
->byte0
= packed_record
[0] & 0xFF;
981 rec
->byte1
= (packed_record
[0] >> 8) & 0xFF;
983 rec
->byte2
= packed_record
[1] & 0xFF;
985 rec
->byte3
= (packed_record
[1] >> 8) & 0xFF;
987 rec
->eth_type
= packed_record
[2];
989 rec
->eth_type_valid
= packed_record
[3] & 0x1;
991 rec
->vlan_id
= (packed_record
[3] >> 1) & 0xFFF;
993 rec
->vlan_up
= (packed_record
[3] >> 13) & 0x7;
995 rec
->vlan_valid
= packed_record
[4] & 0x1;
997 rec
->sai
= (packed_record
[4] >> 1) & 0x1F;
999 rec
->sai_hit
= (packed_record
[4] >> 6) & 0x1;
1001 rec
->eth_type_mask
= (packed_record
[4] >> 7) & 0xF;
1003 rec
->byte3_location
= (packed_record
[4] >> 11) & 0x1F;
1004 rec
->byte3_location
|= (packed_record
[5] & 0x1) << 5;
1006 rec
->byte3_mask
= (packed_record
[5] >> 1) & 0x3;
1008 rec
->byte2_location
= (packed_record
[5] >> 3) & 0x3F;
1010 rec
->byte2_mask
= (packed_record
[5] >> 9) & 0x3;
1012 rec
->byte1_location
= (packed_record
[5] >> 11) & 0x1F;
1013 rec
->byte1_location
|= (packed_record
[6] & 0x1) << 5;
1015 rec
->byte1_mask
= (packed_record
[6] >> 1) & 0x3;
1017 rec
->byte0_location
= (packed_record
[6] >> 3) & 0x3F;
1019 rec
->byte0_mask
= (packed_record
[6] >> 9) & 0x3;
1021 rec
->eth_type_valid_mask
= (packed_record
[6] >> 11) & 0x3;
1023 rec
->vlan_id_mask
= (packed_record
[6] >> 13) & 0x7;
1024 rec
->vlan_id_mask
|= (packed_record
[7] & 0x1) << 3;
1026 rec
->vlan_up_mask
= (packed_record
[7] >> 1) & 0x3;
1028 rec
->vlan_valid_mask
= (packed_record
[7] >> 3) & 0x3;
1030 rec
->sai_mask
= (packed_record
[7] >> 5) & 0x3;
1032 rec
->sai_hit_mask
= (packed_record
[7] >> 7) & 0x3;
1034 rec
->firstlevel_actions
= (packed_record
[7] >> 9) & 0x1;
1036 rec
->secondlevel_actions
= (packed_record
[7] >> 10) & 0x1;
1038 rec
->reserved
= (packed_record
[7] >> 11) & 0xF;
1040 rec
->valid
= (packed_record
[7] >> 15) & 0x1;
1045 int aq_mss_get_ingress_postclass_record(struct aq_hw_s
*hw
,
1046 struct aq_mss_ingress_postclass_record
*rec
,
1049 memset(rec
, 0, sizeof(*rec
));
1051 return AQ_API_CALL_SAFE(get_ingress_postclass_record
, hw
, rec
,
1056 set_ingress_postctlf_record(struct aq_hw_s
*hw
,
1057 const struct aq_mss_ingress_postctlf_record
*rec
,
1060 u16 packed_record
[6];
1062 if (table_index
>= NUMROWS_INGRESSPOSTCTLFRECORD
)
1065 memset(packed_record
, 0, sizeof(u16
) * 6);
1067 packed_record
[0] = rec
->sa_da
[0] & 0xFFFF;
1068 packed_record
[1] = (rec
->sa_da
[0] >> 16) & 0xFFFF;
1070 packed_record
[2] = rec
->sa_da
[1] & 0xFFFF;
1072 packed_record
[3] = rec
->eth_type
& 0xFFFF;
1074 packed_record
[4] = rec
->match_mask
& 0xFFFF;
1076 packed_record
[5] = rec
->match_type
& 0xF;
1078 packed_record
[5] |= (rec
->action
& 0x1) << 4;
1080 return set_raw_ingress_record(hw
, packed_record
, 6, 5,
1081 ROWOFFSET_INGRESSPOSTCTLFRECORD
+
1085 int aq_mss_set_ingress_postctlf_record(struct aq_hw_s
*hw
,
1086 const struct aq_mss_ingress_postctlf_record
*rec
,
1089 return AQ_API_CALL_SAFE(set_ingress_postctlf_record
, hw
, rec
,
1094 get_ingress_postctlf_record(struct aq_hw_s
*hw
,
1095 struct aq_mss_ingress_postctlf_record
*rec
,
1098 u16 packed_record
[6];
1101 if (table_index
>= NUMROWS_INGRESSPOSTCTLFRECORD
)
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.
1107 if ((table_index
% 2) > 0) {
1108 ret
= get_raw_ingress_record(hw
, packed_record
, 6, 5,
1109 ROWOFFSET_INGRESSPOSTCTLFRECORD
+
1115 ret
= get_raw_ingress_record(hw
, packed_record
, 6, 5,
1116 ROWOFFSET_INGRESSPOSTCTLFRECORD
+
1121 rec
->sa_da
[0] = packed_record
[0];
1122 rec
->sa_da
[0] |= packed_record
[1] << 16;
1124 rec
->sa_da
[1] = packed_record
[2];
1126 rec
->eth_type
= packed_record
[3];
1128 rec
->match_mask
= packed_record
[4];
1130 rec
->match_type
= packed_record
[5] & 0xF;
1132 rec
->action
= (packed_record
[5] >> 4) & 0x1;
1137 int aq_mss_get_ingress_postctlf_record(struct aq_hw_s
*hw
,
1138 struct aq_mss_ingress_postctlf_record
*rec
,
1141 memset(rec
, 0, sizeof(*rec
));
1143 return AQ_API_CALL_SAFE(get_ingress_postctlf_record
, hw
, rec
,
1147 static int set_egress_ctlf_record(struct aq_hw_s
*hw
,
1148 const struct aq_mss_egress_ctlf_record
*rec
,
1151 u16 packed_record
[6];
1153 if (table_index
>= NUMROWS_EGRESSCTLFRECORD
)
1156 memset(packed_record
, 0, sizeof(u16
) * 6);
1158 packed_record
[0] = rec
->sa_da
[0] & 0xFFFF;
1159 packed_record
[1] = (rec
->sa_da
[0] >> 16) & 0xFFFF;
1161 packed_record
[2] = rec
->sa_da
[1] & 0xFFFF;
1163 packed_record
[3] = rec
->eth_type
& 0xFFFF;
1165 packed_record
[4] = rec
->match_mask
& 0xFFFF;
1167 packed_record
[5] = rec
->match_type
& 0xF;
1169 packed_record
[5] |= (rec
->action
& 0x1) << 4;
1171 return set_raw_egress_record(hw
, packed_record
, 6, 0,
1172 ROWOFFSET_EGRESSCTLFRECORD
+ table_index
);
1175 int aq_mss_set_egress_ctlf_record(struct aq_hw_s
*hw
,
1176 const struct aq_mss_egress_ctlf_record
*rec
,
1179 return AQ_API_CALL_SAFE(set_egress_ctlf_record
, hw
, rec
, table_index
);
1182 static int get_egress_ctlf_record(struct aq_hw_s
*hw
,
1183 struct aq_mss_egress_ctlf_record
*rec
,
1186 u16 packed_record
[6];
1189 if (table_index
>= NUMROWS_EGRESSCTLFRECORD
)
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.
1195 if ((table_index
% 2) > 0) {
1196 ret
= get_raw_egress_record(hw
, packed_record
, 6, 0,
1197 ROWOFFSET_EGRESSCTLFRECORD
+
1203 ret
= get_raw_egress_record(hw
, packed_record
, 6, 0,
1204 ROWOFFSET_EGRESSCTLFRECORD
+ table_index
);
1208 rec
->sa_da
[0] = packed_record
[0];
1209 rec
->sa_da
[0] |= packed_record
[1] << 16;
1211 rec
->sa_da
[1] = packed_record
[2];
1213 rec
->eth_type
= packed_record
[3];
1215 rec
->match_mask
= packed_record
[4];
1217 rec
->match_type
= packed_record
[5] & 0xF;
1219 rec
->action
= (packed_record
[5] >> 4) & 0x1;
1224 int aq_mss_get_egress_ctlf_record(struct aq_hw_s
*hw
,
1225 struct aq_mss_egress_ctlf_record
*rec
,
1228 memset(rec
, 0, sizeof(*rec
));
1230 return AQ_API_CALL_SAFE(get_egress_ctlf_record
, hw
, rec
, table_index
);
1233 static int set_egress_class_record(struct aq_hw_s
*hw
,
1234 const struct aq_mss_egress_class_record
*rec
,
1237 u16 packed_record
[28];
1239 if (table_index
>= NUMROWS_EGRESSCLASSRECORD
)
1242 memset(packed_record
, 0, sizeof(u16
) * 28);
1244 packed_record
[0] = rec
->vlan_id
& 0xFFF;
1246 packed_record
[0] |= (rec
->vlan_up
& 0x7) << 12;
1248 packed_record
[0] |= (rec
->vlan_valid
& 0x1) << 15;
1250 packed_record
[1] = rec
->byte3
& 0xFF;
1252 packed_record
[1] |= (rec
->byte2
& 0xFF) << 8;
1254 packed_record
[2] = rec
->byte1
& 0xFF;
1256 packed_record
[2] |= (rec
->byte0
& 0xFF) << 8;
1258 packed_record
[3] = rec
->tci
& 0xFF;
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;
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;
1268 packed_record
[7] |= (rec
->eth_type
& 0xFF) << 8;
1269 packed_record
[8] = (rec
->eth_type
>> 8) & 0xFF;
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;
1275 packed_record
[10] |= (rec
->snap
[1] & 0xFF) << 8;
1277 packed_record
[11] = rec
->llc
& 0xFFFF;
1278 packed_record
[12] = (rec
->llc
>> 16) & 0xFF;
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;
1284 packed_record
[14] |= (rec
->mac_sa
[1] & 0xFF) << 8;
1285 packed_record
[15] = (rec
->mac_sa
[1] >> 8) & 0xFF;
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;
1291 packed_record
[17] |= (rec
->mac_da
[1] & 0xFF) << 8;
1292 packed_record
[18] = (rec
->mac_da
[1] >> 8) & 0xFF;
1294 packed_record
[18] |= (rec
->pn
& 0xFF) << 8;
1295 packed_record
[19] = (rec
->pn
>> 8) & 0xFFFF;
1296 packed_record
[20] = (rec
->pn
>> 24) & 0xFF;
1298 packed_record
[20] |= (rec
->byte3_location
& 0x3F) << 8;
1300 packed_record
[20] |= (rec
->byte3_mask
& 0x1) << 14;
1302 packed_record
[20] |= (rec
->byte2_location
& 0x1) << 15;
1303 packed_record
[21] = (rec
->byte2_location
>> 1) & 0x1F;
1305 packed_record
[21] |= (rec
->byte2_mask
& 0x1) << 5;
1307 packed_record
[21] |= (rec
->byte1_location
& 0x3F) << 6;
1309 packed_record
[21] |= (rec
->byte1_mask
& 0x1) << 12;
1311 packed_record
[21] |= (rec
->byte0_location
& 0x7) << 13;
1312 packed_record
[22] = (rec
->byte0_location
>> 3) & 0x7;
1314 packed_record
[22] |= (rec
->byte0_mask
& 0x1) << 3;
1316 packed_record
[22] |= (rec
->vlan_id_mask
& 0x3) << 4;
1318 packed_record
[22] |= (rec
->vlan_up_mask
& 0x1) << 6;
1320 packed_record
[22] |= (rec
->vlan_valid_mask
& 0x1) << 7;
1322 packed_record
[22] |= (rec
->tci_mask
& 0xFF) << 8;
1324 packed_record
[23] = rec
->sci_mask
& 0xFF;
1326 packed_record
[23] |= (rec
->eth_type_mask
& 0x3) << 8;
1328 packed_record
[23] |= (rec
->snap_mask
& 0x1F) << 10;
1330 packed_record
[23] |= (rec
->llc_mask
& 0x1) << 15;
1331 packed_record
[24] = (rec
->llc_mask
>> 1) & 0x3;
1333 packed_record
[24] |= (rec
->sa_mask
& 0x3F) << 2;
1335 packed_record
[24] |= (rec
->da_mask
& 0x3F) << 8;
1337 packed_record
[24] |= (rec
->pn_mask
& 0x3) << 14;
1338 packed_record
[25] = (rec
->pn_mask
>> 2) & 0x3;
1340 packed_record
[25] |= (rec
->eight02dot2
& 0x1) << 2;
1342 packed_record
[25] |= (rec
->tci_sc
& 0x1) << 3;
1344 packed_record
[25] |= (rec
->tci_87543
& 0x1) << 4;
1346 packed_record
[25] |= (rec
->exp_sectag_en
& 0x1) << 5;
1348 packed_record
[25] |= (rec
->sc_idx
& 0x1F) << 6;
1350 packed_record
[25] |= (rec
->sc_sa
& 0x3) << 11;
1352 packed_record
[25] |= (rec
->debug
& 0x1) << 13;
1354 packed_record
[25] |= (rec
->action
& 0x3) << 14;
1356 packed_record
[26] = (rec
->valid
& 0x1) << 3;
1358 return set_raw_egress_record(hw
, packed_record
, 28, 1,
1359 ROWOFFSET_EGRESSCLASSRECORD
+ table_index
);
1362 int aq_mss_set_egress_class_record(struct aq_hw_s
*hw
,
1363 const struct aq_mss_egress_class_record
*rec
,
1366 return AQ_API_CALL_SAFE(set_egress_class_record
, hw
, rec
, table_index
);
1369 static int get_egress_class_record(struct aq_hw_s
*hw
,
1370 struct aq_mss_egress_class_record
*rec
,
1373 u16 packed_record
[28];
1376 if (table_index
>= NUMROWS_EGRESSCLASSRECORD
)
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.
1382 if ((table_index
% 2) > 0) {
1383 ret
= get_raw_egress_record(hw
, packed_record
, 28, 1,
1384 ROWOFFSET_EGRESSCLASSRECORD
+
1390 ret
= get_raw_egress_record(hw
, packed_record
, 28, 1,
1391 ROWOFFSET_EGRESSCLASSRECORD
+ table_index
);
1395 rec
->vlan_id
= packed_record
[0] & 0xFFF;
1397 rec
->vlan_up
= (packed_record
[0] >> 12) & 0x7;
1399 rec
->vlan_valid
= (packed_record
[0] >> 15) & 0x1;
1401 rec
->byte3
= packed_record
[1] & 0xFF;
1403 rec
->byte2
= (packed_record
[1] >> 8) & 0xFF;
1405 rec
->byte1
= packed_record
[2] & 0xFF;
1407 rec
->byte0
= (packed_record
[2] >> 8) & 0xFF;
1409 rec
->tci
= packed_record
[3] & 0xFF;
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;
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;
1419 rec
->eth_type
= (packed_record
[7] >> 8) & 0xFF;
1420 rec
->eth_type
|= (packed_record
[8] & 0xFF) << 8;
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;
1426 rec
->snap
[1] = (packed_record
[10] >> 8) & 0xFF;
1428 rec
->llc
= packed_record
[11];
1429 rec
->llc
|= (packed_record
[12] & 0xFF) << 16;
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;
1435 rec
->mac_sa
[1] = (packed_record
[14] >> 8) & 0xFF;
1436 rec
->mac_sa
[1] |= (packed_record
[15] & 0xFF) << 8;
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;
1442 rec
->mac_da
[1] = (packed_record
[17] >> 8) & 0xFF;
1443 rec
->mac_da
[1] |= (packed_record
[18] & 0xFF) << 8;
1445 rec
->pn
= (packed_record
[18] >> 8) & 0xFF;
1446 rec
->pn
|= packed_record
[19] << 8;
1447 rec
->pn
|= (packed_record
[20] & 0xFF) << 24;
1449 rec
->byte3_location
= (packed_record
[20] >> 8) & 0x3F;
1451 rec
->byte3_mask
= (packed_record
[20] >> 14) & 0x1;
1453 rec
->byte2_location
= (packed_record
[20] >> 15) & 0x1;
1454 rec
->byte2_location
|= (packed_record
[21] & 0x1F) << 1;
1456 rec
->byte2_mask
= (packed_record
[21] >> 5) & 0x1;
1458 rec
->byte1_location
= (packed_record
[21] >> 6) & 0x3F;
1460 rec
->byte1_mask
= (packed_record
[21] >> 12) & 0x1;
1462 rec
->byte0_location
= (packed_record
[21] >> 13) & 0x7;
1463 rec
->byte0_location
|= (packed_record
[22] & 0x7) << 3;
1465 rec
->byte0_mask
= (packed_record
[22] >> 3) & 0x1;
1467 rec
->vlan_id_mask
= (packed_record
[22] >> 4) & 0x3;
1469 rec
->vlan_up_mask
= (packed_record
[22] >> 6) & 0x1;
1471 rec
->vlan_valid_mask
= (packed_record
[22] >> 7) & 0x1;
1473 rec
->tci_mask
= (packed_record
[22] >> 8) & 0xFF;
1475 rec
->sci_mask
= packed_record
[23] & 0xFF;
1477 rec
->eth_type_mask
= (packed_record
[23] >> 8) & 0x3;
1479 rec
->snap_mask
= (packed_record
[23] >> 10) & 0x1F;
1481 rec
->llc_mask
= (packed_record
[23] >> 15) & 0x1;
1482 rec
->llc_mask
|= (packed_record
[24] & 0x3) << 1;
1484 rec
->sa_mask
= (packed_record
[24] >> 2) & 0x3F;
1486 rec
->da_mask
= (packed_record
[24] >> 8) & 0x3F;
1488 rec
->pn_mask
= (packed_record
[24] >> 14) & 0x3;
1489 rec
->pn_mask
|= (packed_record
[25] & 0x3) << 2;
1491 rec
->eight02dot2
= (packed_record
[25] >> 2) & 0x1;
1493 rec
->tci_sc
= (packed_record
[25] >> 3) & 0x1;
1495 rec
->tci_87543
= (packed_record
[25] >> 4) & 0x1;
1497 rec
->exp_sectag_en
= (packed_record
[25] >> 5) & 0x1;
1499 rec
->sc_idx
= (packed_record
[25] >> 6) & 0x1F;
1501 rec
->sc_sa
= (packed_record
[25] >> 11) & 0x3;
1503 rec
->debug
= (packed_record
[25] >> 13) & 0x1;
1505 rec
->action
= (packed_record
[25] >> 14) & 0x3;
1507 rec
->valid
= (packed_record
[26] >> 3) & 0x1;
1512 int aq_mss_get_egress_class_record(struct aq_hw_s
*hw
,
1513 struct aq_mss_egress_class_record
*rec
,
1516 memset(rec
, 0, sizeof(*rec
));
1518 return AQ_API_CALL_SAFE(get_egress_class_record
, hw
, rec
, table_index
);
1521 static int set_egress_sc_record(struct aq_hw_s
*hw
,
1522 const struct aq_mss_egress_sc_record
*rec
,
1525 u16 packed_record
[8];
1527 if (table_index
>= NUMROWS_EGRESSSCRECORD
)
1530 memset(packed_record
, 0, sizeof(u16
) * 8);
1532 packed_record
[0] = rec
->start_time
& 0xFFFF;
1533 packed_record
[1] = (rec
->start_time
>> 16) & 0xFFFF;
1535 packed_record
[2] = rec
->stop_time
& 0xFFFF;
1536 packed_record
[3] = (rec
->stop_time
>> 16) & 0xFFFF;
1538 packed_record
[4] = rec
->curr_an
& 0x3;
1540 packed_record
[4] |= (rec
->an_roll
& 0x1) << 2;
1542 packed_record
[4] |= (rec
->tci
& 0x3F) << 3;
1544 packed_record
[4] |= (rec
->enc_off
& 0x7F) << 9;
1545 packed_record
[5] = (rec
->enc_off
>> 7) & 0x1;
1547 packed_record
[5] |= (rec
->protect
& 0x1) << 1;
1549 packed_record
[5] |= (rec
->recv
& 0x1) << 2;
1551 packed_record
[5] |= (rec
->fresh
& 0x1) << 3;
1553 packed_record
[5] |= (rec
->sak_len
& 0x3) << 4;
1555 packed_record
[7] = (rec
->valid
& 0x1) << 15;
1557 return set_raw_egress_record(hw
, packed_record
, 8, 2,
1558 ROWOFFSET_EGRESSSCRECORD
+ table_index
);
1561 int aq_mss_set_egress_sc_record(struct aq_hw_s
*hw
,
1562 const struct aq_mss_egress_sc_record
*rec
,
1565 return AQ_API_CALL_SAFE(set_egress_sc_record
, hw
, rec
, table_index
);
1568 static int get_egress_sc_record(struct aq_hw_s
*hw
,
1569 struct aq_mss_egress_sc_record
*rec
,
1572 u16 packed_record
[8];
1575 if (table_index
>= NUMROWS_EGRESSSCRECORD
)
1578 ret
= get_raw_egress_record(hw
, packed_record
, 8, 2,
1579 ROWOFFSET_EGRESSSCRECORD
+ table_index
);
1583 rec
->start_time
= packed_record
[0];
1584 rec
->start_time
|= packed_record
[1] << 16;
1586 rec
->stop_time
= packed_record
[2];
1587 rec
->stop_time
|= packed_record
[3] << 16;
1589 rec
->curr_an
= packed_record
[4] & 0x3;
1591 rec
->an_roll
= (packed_record
[4] >> 2) & 0x1;
1593 rec
->tci
= (packed_record
[4] >> 3) & 0x3F;
1595 rec
->enc_off
= (packed_record
[4] >> 9) & 0x7F;
1596 rec
->enc_off
|= (packed_record
[5] & 0x1) << 7;
1598 rec
->protect
= (packed_record
[5] >> 1) & 0x1;
1600 rec
->recv
= (packed_record
[5] >> 2) & 0x1;
1602 rec
->fresh
= (packed_record
[5] >> 3) & 0x1;
1604 rec
->sak_len
= (packed_record
[5] >> 4) & 0x3;
1606 rec
->valid
= (packed_record
[7] >> 15) & 0x1;
1611 int aq_mss_get_egress_sc_record(struct aq_hw_s
*hw
,
1612 struct aq_mss_egress_sc_record
*rec
,
1615 memset(rec
, 0, sizeof(*rec
));
1617 return AQ_API_CALL_SAFE(get_egress_sc_record
, hw
, rec
, table_index
);
1620 static int set_egress_sa_record(struct aq_hw_s
*hw
,
1621 const struct aq_mss_egress_sa_record
*rec
,
1624 u16 packed_record
[8];
1626 if (table_index
>= NUMROWS_EGRESSSARECORD
)
1629 memset(packed_record
, 0, sizeof(u16
) * 8);
1631 packed_record
[0] = rec
->start_time
& 0xFFFF;
1632 packed_record
[1] = (rec
->start_time
>> 16) & 0xFFFF;
1634 packed_record
[2] = rec
->stop_time
& 0xFFFF;
1635 packed_record
[3] = (rec
->stop_time
>> 16) & 0xFFFF;
1637 packed_record
[4] = rec
->next_pn
& 0xFFFF;
1638 packed_record
[5] = (rec
->next_pn
>> 16) & 0xFFFF;
1640 packed_record
[6] = rec
->sat_pn
& 0x1;
1642 packed_record
[6] |= (rec
->fresh
& 0x1) << 1;
1644 packed_record
[7] = (rec
->valid
& 0x1) << 15;
1646 return set_raw_egress_record(hw
, packed_record
, 8, 2,
1647 ROWOFFSET_EGRESSSARECORD
+ table_index
);
1650 int aq_mss_set_egress_sa_record(struct aq_hw_s
*hw
,
1651 const struct aq_mss_egress_sa_record
*rec
,
1654 int err
= AQ_API_CALL_SAFE(set_egress_sa_record
, hw
, rec
, table_index
);
1656 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
1661 static int get_egress_sa_record(struct aq_hw_s
*hw
,
1662 struct aq_mss_egress_sa_record
*rec
,
1665 u16 packed_record
[8];
1668 if (table_index
>= NUMROWS_EGRESSSARECORD
)
1671 ret
= get_raw_egress_record(hw
, packed_record
, 8, 2,
1672 ROWOFFSET_EGRESSSARECORD
+ table_index
);
1676 rec
->start_time
= packed_record
[0];
1677 rec
->start_time
|= packed_record
[1] << 16;
1679 rec
->stop_time
= packed_record
[2];
1680 rec
->stop_time
|= packed_record
[3] << 16;
1682 rec
->next_pn
= packed_record
[4];
1683 rec
->next_pn
|= packed_record
[5] << 16;
1685 rec
->sat_pn
= packed_record
[6] & 0x1;
1687 rec
->fresh
= (packed_record
[6] >> 1) & 0x1;
1689 rec
->valid
= (packed_record
[7] >> 15) & 0x1;
1694 int aq_mss_get_egress_sa_record(struct aq_hw_s
*hw
,
1695 struct aq_mss_egress_sa_record
*rec
,
1698 memset(rec
, 0, sizeof(*rec
));
1700 return AQ_API_CALL_SAFE(get_egress_sa_record
, hw
, rec
, table_index
);
1703 static int set_egress_sakey_record(struct aq_hw_s
*hw
,
1704 const struct aq_mss_egress_sakey_record
*rec
,
1707 u16 packed_record
[16];
1710 if (table_index
>= NUMROWS_EGRESSSAKEYRECORD
)
1713 memset(packed_record
, 0, sizeof(u16
) * 16);
1715 packed_record
[0] = rec
->key
[0] & 0xFFFF;
1716 packed_record
[1] = (rec
->key
[0] >> 16) & 0xFFFF;
1718 packed_record
[2] = rec
->key
[1] & 0xFFFF;
1719 packed_record
[3] = (rec
->key
[1] >> 16) & 0xFFFF;
1721 packed_record
[4] = rec
->key
[2] & 0xFFFF;
1722 packed_record
[5] = (rec
->key
[2] >> 16) & 0xFFFF;
1724 packed_record
[6] = rec
->key
[3] & 0xFFFF;
1725 packed_record
[7] = (rec
->key
[3] >> 16) & 0xFFFF;
1727 packed_record
[8] = rec
->key
[4] & 0xFFFF;
1728 packed_record
[9] = (rec
->key
[4] >> 16) & 0xFFFF;
1730 packed_record
[10] = rec
->key
[5] & 0xFFFF;
1731 packed_record
[11] = (rec
->key
[5] >> 16) & 0xFFFF;
1733 packed_record
[12] = rec
->key
[6] & 0xFFFF;
1734 packed_record
[13] = (rec
->key
[6] >> 16) & 0xFFFF;
1736 packed_record
[14] = rec
->key
[7] & 0xFFFF;
1737 packed_record
[15] = (rec
->key
[7] >> 16) & 0xFFFF;
1739 ret
= set_raw_egress_record(hw
, packed_record
, 8, 2,
1740 ROWOFFSET_EGRESSSAKEYRECORD
+ table_index
);
1743 ret
= set_raw_egress_record(hw
, packed_record
+ 8, 8, 2,
1744 ROWOFFSET_EGRESSSAKEYRECORD
+ table_index
-
1752 int aq_mss_set_egress_sakey_record(struct aq_hw_s
*hw
,
1753 const struct aq_mss_egress_sakey_record
*rec
,
1756 int err
= AQ_API_CALL_SAFE(set_egress_sakey_record
, hw
, rec
,
1759 WARN_ONCE(err
, "%s failed with %d\n", __func__
, err
);
1764 static int get_egress_sakey_record(struct aq_hw_s
*hw
,
1765 struct aq_mss_egress_sakey_record
*rec
,
1768 u16 packed_record
[16];
1771 if (table_index
>= NUMROWS_EGRESSSAKEYRECORD
)
1774 ret
= get_raw_egress_record(hw
, packed_record
, 8, 2,
1775 ROWOFFSET_EGRESSSAKEYRECORD
+ table_index
);
1778 ret
= get_raw_egress_record(hw
, packed_record
+ 8, 8, 2,
1779 ROWOFFSET_EGRESSSAKEYRECORD
+ table_index
-
1784 rec
->key
[0] = packed_record
[0];
1785 rec
->key
[0] |= packed_record
[1] << 16;
1787 rec
->key
[1] = packed_record
[2];
1788 rec
->key
[1] |= packed_record
[3] << 16;
1790 rec
->key
[2] = packed_record
[4];
1791 rec
->key
[2] |= packed_record
[5] << 16;
1793 rec
->key
[3] = packed_record
[6];
1794 rec
->key
[3] |= packed_record
[7] << 16;
1796 rec
->key
[4] = packed_record
[8];
1797 rec
->key
[4] |= packed_record
[9] << 16;
1799 rec
->key
[5] = packed_record
[10];
1800 rec
->key
[5] |= packed_record
[11] << 16;
1802 rec
->key
[6] = packed_record
[12];
1803 rec
->key
[6] |= packed_record
[13] << 16;
1805 rec
->key
[7] = packed_record
[14];
1806 rec
->key
[7] |= packed_record
[15] << 16;
1811 int aq_mss_get_egress_sakey_record(struct aq_hw_s
*hw
,
1812 struct aq_mss_egress_sakey_record
*rec
,
1815 memset(rec
, 0, sizeof(*rec
));
1817 return AQ_API_CALL_SAFE(get_egress_sakey_record
, hw
, rec
, table_index
);
1820 static int get_egress_sc_counters(struct aq_hw_s
*hw
,
1821 struct aq_mss_egress_sc_counters
*counters
,
1824 u16 packed_record
[4];
1827 if (sc_index
>= NUMROWS_EGRESSSCRECORD
)
1830 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sc_index
* 8 + 4);
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);
1838 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sc_index
* 8 + 5);
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);
1846 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sc_index
* 8 + 6);
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);
1854 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sc_index
* 8 + 7);
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);
1865 int aq_mss_get_egress_sc_counters(struct aq_hw_s
*hw
,
1866 struct aq_mss_egress_sc_counters
*counters
,
1869 memset(counters
, 0, sizeof(*counters
));
1871 return AQ_API_CALL_SAFE(get_egress_sc_counters
, hw
, counters
, sc_index
);
1874 static int get_egress_sa_counters(struct aq_hw_s
*hw
,
1875 struct aq_mss_egress_sa_counters
*counters
,
1878 u16 packed_record
[4];
1881 if (sa_index
>= NUMROWS_EGRESSSARECORD
)
1884 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sa_index
* 8 + 0);
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);
1892 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sa_index
* 8 + 1);
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);
1900 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sa_index
* 8 + 2);
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);
1908 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, sa_index
* 8 + 3);
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);
1919 int aq_mss_get_egress_sa_counters(struct aq_hw_s
*hw
,
1920 struct aq_mss_egress_sa_counters
*counters
,
1923 memset(counters
, 0, sizeof(*counters
));
1925 return AQ_API_CALL_SAFE(get_egress_sa_counters
, hw
, counters
, sa_index
);
1929 get_egress_common_counters(struct aq_hw_s
*hw
,
1930 struct aq_mss_egress_common_counters
*counters
)
1932 u16 packed_record
[4];
1935 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 0);
1938 counters
->ctl_pkt
[0] = packed_record
[0] | (packed_record
[1] << 16);
1939 counters
->ctl_pkt
[1] = packed_record
[2] | (packed_record
[3] << 16);
1941 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 1);
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);
1949 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 2);
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);
1957 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 3);
1960 counters
->too_long
[0] = packed_record
[0] | (packed_record
[1] << 16);
1961 counters
->too_long
[1] = packed_record
[2] | (packed_record
[3] << 16);
1963 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 4);
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);
1971 ret
= get_raw_egress_record(hw
, packed_record
, 4, 3, 256 + 5);
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);
1982 int aq_mss_get_egress_common_counters(struct aq_hw_s
*hw
,
1983 struct aq_mss_egress_common_counters
*counters
)
1985 memset(counters
, 0, sizeof(*counters
));
1987 return AQ_API_CALL_SAFE(get_egress_common_counters
, hw
, counters
);
1990 static int clear_egress_counters(struct aq_hw_s
*hw
)
1992 struct mss_egress_ctl_register ctl_reg
;
1995 memset(&ctl_reg
, 0, sizeof(ctl_reg
));
1997 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
, MSS_EGRESS_CTL_REGISTER_ADDR
,
2001 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2002 MSS_EGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2013 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2014 MSS_EGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2024 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2025 MSS_EGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2035 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2036 MSS_EGRESS_CTL_REGISTER_ADDR
+ 4,
2044 int aq_mss_clear_egress_counters(struct aq_hw_s
*hw
)
2046 return AQ_API_CALL_SAFE(clear_egress_counters
, hw
);
2049 static int get_ingress_sa_counters(struct aq_hw_s
*hw
,
2050 struct aq_mss_ingress_sa_counters
*counters
,
2053 u16 packed_record
[4];
2056 if (sa_index
>= NUMROWS_INGRESSSARECORD
)
2059 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
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);
2068 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
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);
2077 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
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);
2084 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2088 counters
->unused_sa
[0] = packed_record
[0] | (packed_record
[1] << 16);
2089 counters
->unused_sa
[1] = packed_record
[2] | (packed_record
[3] << 16);
2091 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
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);
2100 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2104 counters
->invalid_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2105 counters
->invalid_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2107 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2111 counters
->ok_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2112 counters
->ok_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2114 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2118 counters
->late_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2119 counters
->late_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2121 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2125 counters
->delayed_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2126 counters
->delayed_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2128 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
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);
2137 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2138 sa_index
* 12 + 10);
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);
2146 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6,
2147 sa_index
* 12 + 11);
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);
2158 int aq_mss_get_ingress_sa_counters(struct aq_hw_s
*hw
,
2159 struct aq_mss_ingress_sa_counters
*counters
,
2162 memset(counters
, 0, sizeof(*counters
));
2164 return AQ_API_CALL_SAFE(get_ingress_sa_counters
, hw
, counters
,
2169 get_ingress_common_counters(struct aq_hw_s
*hw
,
2170 struct aq_mss_ingress_common_counters
*counters
)
2172 u16 packed_record
[4];
2175 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 0);
2178 counters
->ctl_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2179 counters
->ctl_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2181 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 1);
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);
2189 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 2);
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);
2197 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 3);
2200 counters
->notag_pkts
[0] = packed_record
[0] | (packed_record
[1] << 16);
2201 counters
->notag_pkts
[1] = packed_record
[2] | (packed_record
[3] << 16);
2203 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 4);
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);
2211 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 5);
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);
2217 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 6);
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);
2223 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 7);
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);
2231 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 8);
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);
2239 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 9);
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);
2247 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 10);
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);
2255 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 11);
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);
2263 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 12);
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);
2271 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 13);
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);
2279 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 14);
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);
2287 ret
= get_raw_ingress_record(hw
, packed_record
, 4, 6, 385 + 15);
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);
2298 int aq_mss_get_ingress_common_counters(struct aq_hw_s
*hw
,
2299 struct aq_mss_ingress_common_counters
*counters
)
2301 memset(counters
, 0, sizeof(*counters
));
2303 return AQ_API_CALL_SAFE(get_ingress_common_counters
, hw
, counters
);
2306 static int clear_ingress_counters(struct aq_hw_s
*hw
)
2308 struct mss_ingress_ctl_register ctl_reg
;
2311 memset(&ctl_reg
, 0, sizeof(ctl_reg
));
2313 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2314 MSS_INGRESS_CTL_REGISTER_ADDR
, &ctl_reg
.word_0
);
2317 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2318 MSS_INGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2329 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2330 MSS_INGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2340 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2341 MSS_INGRESS_CTL_REGISTER_ADDR
+ 4,
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
);
2351 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2352 MSS_INGRESS_CTL_REGISTER_ADDR
+ 4,
2360 int aq_mss_clear_ingress_counters(struct aq_hw_s
*hw
)
2362 return AQ_API_CALL_SAFE(clear_ingress_counters
, hw
);
2365 static int get_egress_sa_expired(struct aq_hw_s
*hw
, u32
*expired
)
2370 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2371 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR
,
2378 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2379 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR
+ 1,
2384 *expired
|= val
<< 16;
2389 int aq_mss_get_egress_sa_expired(struct aq_hw_s
*hw
, u32
*expired
)
2393 return AQ_API_CALL_SAFE(get_egress_sa_expired
, hw
, expired
);
2396 static int get_egress_sa_threshold_expired(struct aq_hw_s
*hw
,
2402 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2403 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR
, &val
);
2409 ret
= aq_mss_mdio_read(hw
, MDIO_MMD_VEND1
,
2410 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR
+ 1, &val
);
2414 *expired
|= val
<< 16;
2419 int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s
*hw
,
2424 return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired
, hw
, expired
);
2427 static int set_egress_sa_expired(struct aq_hw_s
*hw
, u32 expired
)
2431 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2432 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR
,
2437 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2438 MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR
+ 1,
2446 int aq_mss_set_egress_sa_expired(struct aq_hw_s
*hw
, u32 expired
)
2448 return AQ_API_CALL_SAFE(set_egress_sa_expired
, hw
, expired
);
2451 static int set_egress_sa_threshold_expired(struct aq_hw_s
*hw
, u32 expired
)
2455 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2456 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR
,
2461 ret
= aq_mss_mdio_write(hw
, MDIO_MMD_VEND1
,
2462 MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR
+ 1,
2470 int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s
*hw
, u32 expired
)
2472 return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired
, hw
, expired
);