19d106c6dSDmitry Bogdanov // SPDX-License-Identifier: GPL-2.0-only
29d106c6dSDmitry Bogdanov /* Atlantic Network Driver
39d106c6dSDmitry Bogdanov  * Copyright (C) 2020 Marvell International Ltd.
49d106c6dSDmitry Bogdanov  */
59d106c6dSDmitry Bogdanov 
69d106c6dSDmitry Bogdanov #include "macsec_api.h"
79d106c6dSDmitry Bogdanov #include <linux/mdio.h>
8b8f8a0b7SMark Starovoytov #include "MSS_Ingress_registers.h"
99d106c6dSDmitry Bogdanov #include "MSS_Egress_registers.h"
109d106c6dSDmitry Bogdanov #include "aq_phy.h"
119d106c6dSDmitry Bogdanov 
129d106c6dSDmitry Bogdanov #define AQ_API_CALL_SAFE(func, ...)                                            \
139d106c6dSDmitry Bogdanov ({                                                                             \
149d106c6dSDmitry Bogdanov 	int ret;                                                               \
159d106c6dSDmitry Bogdanov 	do {                                                                   \
169d106c6dSDmitry Bogdanov 		ret = aq_mss_mdio_sem_get(hw);                                 \
179d106c6dSDmitry Bogdanov 		if (unlikely(ret))                                             \
189d106c6dSDmitry Bogdanov 			break;                                                 \
199d106c6dSDmitry Bogdanov 									       \
209d106c6dSDmitry Bogdanov 		ret = func(__VA_ARGS__);                                       \
219d106c6dSDmitry Bogdanov 									       \
229d106c6dSDmitry Bogdanov 		aq_mss_mdio_sem_put(hw);                                       \
239d106c6dSDmitry Bogdanov 	} while (0);                                                           \
249d106c6dSDmitry Bogdanov 	ret;                                                                   \
259d106c6dSDmitry Bogdanov })
269d106c6dSDmitry Bogdanov 
279d106c6dSDmitry Bogdanov /*******************************************************************************
289d106c6dSDmitry Bogdanov  *                               MDIO wrappers
299d106c6dSDmitry Bogdanov  ******************************************************************************/
aq_mss_mdio_sem_get(struct aq_hw_s * hw)309d106c6dSDmitry Bogdanov static int aq_mss_mdio_sem_get(struct aq_hw_s *hw)
319d106c6dSDmitry Bogdanov {
329d106c6dSDmitry Bogdanov 	u32 val;
339d106c6dSDmitry Bogdanov 
349d106c6dSDmitry Bogdanov 	return readx_poll_timeout_atomic(hw_atl_sem_mdio_get, hw, val,
359d106c6dSDmitry Bogdanov 					 val == 1U, 10U, 100000U);
369d106c6dSDmitry Bogdanov }
379d106c6dSDmitry Bogdanov 
aq_mss_mdio_sem_put(struct aq_hw_s * hw)389d106c6dSDmitry Bogdanov static void aq_mss_mdio_sem_put(struct aq_hw_s *hw)
399d106c6dSDmitry Bogdanov {
409d106c6dSDmitry Bogdanov 	hw_atl_reg_glb_cpu_sem_set(hw, 1U, HW_ATL_FW_SM_MDIO);
419d106c6dSDmitry Bogdanov }
429d106c6dSDmitry Bogdanov 
aq_mss_mdio_read(struct aq_hw_s * hw,u16 mmd,u16 addr,u16 * data)439d106c6dSDmitry Bogdanov static int aq_mss_mdio_read(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 *data)
449d106c6dSDmitry Bogdanov {
459d106c6dSDmitry Bogdanov 	*data = aq_mdio_read_word(hw, mmd, addr);
469d106c6dSDmitry Bogdanov 	return (*data != 0xffff) ? 0 : -ETIME;
479d106c6dSDmitry Bogdanov }
489d106c6dSDmitry Bogdanov 
aq_mss_mdio_write(struct aq_hw_s * hw,u16 mmd,u16 addr,u16 data)499d106c6dSDmitry Bogdanov static int aq_mss_mdio_write(struct aq_hw_s *hw, u16 mmd, u16 addr, u16 data)
509d106c6dSDmitry Bogdanov {
519d106c6dSDmitry Bogdanov 	aq_mdio_write_word(hw, mmd, addr, data);
529d106c6dSDmitry Bogdanov 	return 0;
539d106c6dSDmitry Bogdanov }
549d106c6dSDmitry Bogdanov 
559d106c6dSDmitry Bogdanov /*******************************************************************************
569d106c6dSDmitry Bogdanov  *                          MACSEC config and status
579d106c6dSDmitry Bogdanov  ******************************************************************************/
589d106c6dSDmitry Bogdanov 
set_raw_ingress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)59b8f8a0b7SMark Starovoytov static int set_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record,
60b8f8a0b7SMark Starovoytov 				  u8 num_words, u8 table_id,
61b8f8a0b7SMark Starovoytov 				  u16 table_index)
62b8f8a0b7SMark Starovoytov {
63b8f8a0b7SMark Starovoytov 	struct mss_ingress_lut_addr_ctl_register lut_sel_reg;
64b8f8a0b7SMark Starovoytov 	struct mss_ingress_lut_ctl_register lut_op_reg;
65b8f8a0b7SMark Starovoytov 
66b8f8a0b7SMark Starovoytov 	unsigned int i;
67b8f8a0b7SMark Starovoytov 
68b8f8a0b7SMark Starovoytov 	/* NOTE: MSS registers must always be read/written as adjacent pairs.
69b8f8a0b7SMark Starovoytov 	 * For instance, to write either or both 1E.80A0 and 80A1, we have to:
70b8f8a0b7SMark Starovoytov 	 * 1. Write 1E.80A0 first
71b8f8a0b7SMark Starovoytov 	 * 2. Then write 1E.80A1
72b8f8a0b7SMark Starovoytov 	 *
73b8f8a0b7SMark Starovoytov 	 * For HHD devices: These writes need to be performed consecutively, and
74b8f8a0b7SMark Starovoytov 	 * to ensure this we use the PIF mailbox to delegate the reads/writes to
75b8f8a0b7SMark Starovoytov 	 * the FW.
76b8f8a0b7SMark Starovoytov 	 *
77b8f8a0b7SMark Starovoytov 	 * For EUR devices: Not need to use the PIF mailbox; it is safe to
78b8f8a0b7SMark Starovoytov 	 * write to the registers directly.
79b8f8a0b7SMark Starovoytov 	 */
80b8f8a0b7SMark Starovoytov 
81b8f8a0b7SMark Starovoytov 	/* Write the packed record words to the data buffer registers. */
82b8f8a0b7SMark Starovoytov 	for (i = 0; i < num_words; i += 2) {
83b8f8a0b7SMark Starovoytov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
84b8f8a0b7SMark Starovoytov 				  MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
85b8f8a0b7SMark Starovoytov 				  packed_record[i]);
86b8f8a0b7SMark Starovoytov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
87b8f8a0b7SMark Starovoytov 				  MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i +
88b8f8a0b7SMark Starovoytov 					  1,
89b8f8a0b7SMark Starovoytov 				  packed_record[i + 1]);
90b8f8a0b7SMark Starovoytov 	}
91b8f8a0b7SMark Starovoytov 
92b8f8a0b7SMark Starovoytov 	/* Clear out the unused data buffer registers. */
93b8f8a0b7SMark Starovoytov 	for (i = num_words; i < 24; i += 2) {
94b8f8a0b7SMark Starovoytov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
95b8f8a0b7SMark Starovoytov 				  MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
96b8f8a0b7SMark Starovoytov 				  0);
97b8f8a0b7SMark Starovoytov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
98b8f8a0b7SMark Starovoytov 			MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1, 0);
99b8f8a0b7SMark Starovoytov 	}
100b8f8a0b7SMark Starovoytov 
101b8f8a0b7SMark Starovoytov 	/* Select the table and row index to write to */
102b8f8a0b7SMark Starovoytov 	lut_sel_reg.bits_0.lut_select = table_id;
103b8f8a0b7SMark Starovoytov 	lut_sel_reg.bits_0.lut_addr = table_index;
104b8f8a0b7SMark Starovoytov 
105b8f8a0b7SMark Starovoytov 	lut_op_reg.bits_0.lut_read = 0;
106b8f8a0b7SMark Starovoytov 	lut_op_reg.bits_0.lut_write = 1;
107b8f8a0b7SMark Starovoytov 
108b8f8a0b7SMark Starovoytov 	aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
109b8f8a0b7SMark Starovoytov 			  MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
110b8f8a0b7SMark Starovoytov 			  lut_sel_reg.word_0);
111b8f8a0b7SMark Starovoytov 	aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_INGRESS_LUT_CTL_REGISTER_ADDR,
112b8f8a0b7SMark Starovoytov 			  lut_op_reg.word_0);
113b8f8a0b7SMark Starovoytov 
114b8f8a0b7SMark Starovoytov 	return 0;
115b8f8a0b7SMark Starovoytov }
116b8f8a0b7SMark Starovoytov 
117b8f8a0b7SMark Starovoytov /*! Read the specified Ingress LUT table row.
118b8f8a0b7SMark Starovoytov  *  packed_record - [OUT] The table row data (raw).
119b8f8a0b7SMark Starovoytov  */
get_raw_ingress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)120b8f8a0b7SMark Starovoytov static int get_raw_ingress_record(struct aq_hw_s *hw, u16 *packed_record,
121b8f8a0b7SMark Starovoytov 				  u8 num_words, u8 table_id,
122b8f8a0b7SMark Starovoytov 				  u16 table_index)
123b8f8a0b7SMark Starovoytov {
124b8f8a0b7SMark Starovoytov 	struct mss_ingress_lut_addr_ctl_register lut_sel_reg;
125b8f8a0b7SMark Starovoytov 	struct mss_ingress_lut_ctl_register lut_op_reg;
126b8f8a0b7SMark Starovoytov 	int ret;
127b8f8a0b7SMark Starovoytov 
128b8f8a0b7SMark Starovoytov 	unsigned int i;
129b8f8a0b7SMark Starovoytov 
130b8f8a0b7SMark Starovoytov 	/* Select the table and row index to read */
131b8f8a0b7SMark Starovoytov 	lut_sel_reg.bits_0.lut_select = table_id;
132b8f8a0b7SMark Starovoytov 	lut_sel_reg.bits_0.lut_addr = table_index;
133b8f8a0b7SMark Starovoytov 
134b8f8a0b7SMark Starovoytov 	lut_op_reg.bits_0.lut_read = 1;
135b8f8a0b7SMark Starovoytov 	lut_op_reg.bits_0.lut_write = 0;
136b8f8a0b7SMark Starovoytov 
137b8f8a0b7SMark Starovoytov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
138b8f8a0b7SMark Starovoytov 				MSS_INGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
139b8f8a0b7SMark Starovoytov 				lut_sel_reg.word_0);
140b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
141b8f8a0b7SMark Starovoytov 		return ret;
142b8f8a0b7SMark Starovoytov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
143b8f8a0b7SMark Starovoytov 				MSS_INGRESS_LUT_CTL_REGISTER_ADDR,
144b8f8a0b7SMark Starovoytov 				lut_op_reg.word_0);
145b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
146b8f8a0b7SMark Starovoytov 		return ret;
147b8f8a0b7SMark Starovoytov 
148b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * num_words);
149b8f8a0b7SMark Starovoytov 
150b8f8a0b7SMark Starovoytov 	for (i = 0; i < num_words; i += 2) {
151b8f8a0b7SMark Starovoytov 		ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
152b8f8a0b7SMark Starovoytov 				       MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR +
153b8f8a0b7SMark Starovoytov 					       i,
154b8f8a0b7SMark Starovoytov 				       &packed_record[i]);
155b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
156b8f8a0b7SMark Starovoytov 			return ret;
157b8f8a0b7SMark Starovoytov 		ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
158b8f8a0b7SMark Starovoytov 				       MSS_INGRESS_LUT_DATA_CTL_REGISTER_ADDR +
159b8f8a0b7SMark Starovoytov 					       i + 1,
160b8f8a0b7SMark Starovoytov 				       &packed_record[i + 1]);
161b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
162b8f8a0b7SMark Starovoytov 			return ret;
163b8f8a0b7SMark Starovoytov 	}
164b8f8a0b7SMark Starovoytov 
165b8f8a0b7SMark Starovoytov 	return 0;
166b8f8a0b7SMark Starovoytov }
167b8f8a0b7SMark Starovoytov 
1689d106c6dSDmitry Bogdanov /*! Write packed_record to the specified Egress LUT table row. */
set_raw_egress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)1699d106c6dSDmitry Bogdanov static int set_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record,
1709d106c6dSDmitry Bogdanov 				 u8 num_words, u8 table_id,
1719d106c6dSDmitry Bogdanov 				 u16 table_index)
1729d106c6dSDmitry Bogdanov {
1739d106c6dSDmitry Bogdanov 	struct mss_egress_lut_addr_ctl_register lut_sel_reg;
1749d106c6dSDmitry Bogdanov 	struct mss_egress_lut_ctl_register lut_op_reg;
1759d106c6dSDmitry Bogdanov 
1769d106c6dSDmitry Bogdanov 	unsigned int i;
1779d106c6dSDmitry Bogdanov 
1789d106c6dSDmitry Bogdanov 	/* Write the packed record words to the data buffer registers. */
1799d106c6dSDmitry Bogdanov 	for (i = 0; i < num_words; i += 2) {
1809d106c6dSDmitry Bogdanov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
1819d106c6dSDmitry Bogdanov 				  MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i,
1829d106c6dSDmitry Bogdanov 				  packed_record[i]);
1839d106c6dSDmitry Bogdanov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
1849d106c6dSDmitry Bogdanov 				  MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
1859d106c6dSDmitry Bogdanov 				  packed_record[i + 1]);
1869d106c6dSDmitry Bogdanov 	}
1879d106c6dSDmitry Bogdanov 
1889d106c6dSDmitry Bogdanov 	/* Clear out the unused data buffer registers. */
1899d106c6dSDmitry Bogdanov 	for (i = num_words; i < 28; i += 2) {
1909d106c6dSDmitry Bogdanov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
1919d106c6dSDmitry Bogdanov 				  MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i, 0);
1929d106c6dSDmitry Bogdanov 		aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
1939d106c6dSDmitry Bogdanov 				  MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR + i + 1,
1949d106c6dSDmitry Bogdanov 				  0);
1959d106c6dSDmitry Bogdanov 	}
1969d106c6dSDmitry Bogdanov 
1979d106c6dSDmitry Bogdanov 	/* Select the table and row index to write to */
1989d106c6dSDmitry Bogdanov 	lut_sel_reg.bits_0.lut_select = table_id;
1999d106c6dSDmitry Bogdanov 	lut_sel_reg.bits_0.lut_addr = table_index;
2009d106c6dSDmitry Bogdanov 
2019d106c6dSDmitry Bogdanov 	lut_op_reg.bits_0.lut_read = 0;
2029d106c6dSDmitry Bogdanov 	lut_op_reg.bits_0.lut_write = 1;
2039d106c6dSDmitry Bogdanov 
2049d106c6dSDmitry Bogdanov 	aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2059d106c6dSDmitry Bogdanov 			  MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
2069d106c6dSDmitry Bogdanov 			  lut_sel_reg.word_0);
2079d106c6dSDmitry Bogdanov 	aq_mss_mdio_write(hw, MDIO_MMD_VEND1, MSS_EGRESS_LUT_CTL_REGISTER_ADDR,
2089d106c6dSDmitry Bogdanov 			  lut_op_reg.word_0);
2099d106c6dSDmitry Bogdanov 
2109d106c6dSDmitry Bogdanov 	return 0;
2119d106c6dSDmitry Bogdanov }
2129d106c6dSDmitry Bogdanov 
get_raw_egress_record(struct aq_hw_s * hw,u16 * packed_record,u8 num_words,u8 table_id,u16 table_index)2139d106c6dSDmitry Bogdanov static int get_raw_egress_record(struct aq_hw_s *hw, u16 *packed_record,
2149d106c6dSDmitry Bogdanov 				 u8 num_words, u8 table_id,
2159d106c6dSDmitry Bogdanov 				 u16 table_index)
2169d106c6dSDmitry Bogdanov {
2179d106c6dSDmitry Bogdanov 	struct mss_egress_lut_addr_ctl_register lut_sel_reg;
2189d106c6dSDmitry Bogdanov 	struct mss_egress_lut_ctl_register lut_op_reg;
2199d106c6dSDmitry Bogdanov 	int ret;
2209d106c6dSDmitry Bogdanov 
2219d106c6dSDmitry Bogdanov 	unsigned int i;
2229d106c6dSDmitry Bogdanov 
2239d106c6dSDmitry Bogdanov 	/* Select the table and row index to read */
2249d106c6dSDmitry Bogdanov 	lut_sel_reg.bits_0.lut_select = table_id;
2259d106c6dSDmitry Bogdanov 	lut_sel_reg.bits_0.lut_addr = table_index;
2269d106c6dSDmitry Bogdanov 
2279d106c6dSDmitry Bogdanov 	lut_op_reg.bits_0.lut_read = 1;
2289d106c6dSDmitry Bogdanov 	lut_op_reg.bits_0.lut_write = 0;
2299d106c6dSDmitry Bogdanov 
2309d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2319d106c6dSDmitry Bogdanov 				MSS_EGRESS_LUT_ADDR_CTL_REGISTER_ADDR,
2329d106c6dSDmitry Bogdanov 				lut_sel_reg.word_0);
2339d106c6dSDmitry Bogdanov 	if (unlikely(ret))
2349d106c6dSDmitry Bogdanov 		return ret;
2359d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2369d106c6dSDmitry Bogdanov 				MSS_EGRESS_LUT_CTL_REGISTER_ADDR,
2379d106c6dSDmitry Bogdanov 				lut_op_reg.word_0);
2389d106c6dSDmitry Bogdanov 	if (unlikely(ret))
2399d106c6dSDmitry Bogdanov 		return ret;
2409d106c6dSDmitry Bogdanov 
2419d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * num_words);
2429d106c6dSDmitry Bogdanov 
2439d106c6dSDmitry Bogdanov 	for (i = 0; i < num_words; i += 2) {
2449d106c6dSDmitry Bogdanov 		ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2459d106c6dSDmitry Bogdanov 				       MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR +
2469d106c6dSDmitry Bogdanov 					       i,
2479d106c6dSDmitry Bogdanov 				       &packed_record[i]);
2489d106c6dSDmitry Bogdanov 		if (unlikely(ret))
2499d106c6dSDmitry Bogdanov 			return ret;
2509d106c6dSDmitry Bogdanov 		ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2519d106c6dSDmitry Bogdanov 				       MSS_EGRESS_LUT_DATA_CTL_REGISTER_ADDR +
2529d106c6dSDmitry Bogdanov 					       i + 1,
2539d106c6dSDmitry Bogdanov 				       &packed_record[i + 1]);
2549d106c6dSDmitry Bogdanov 		if (unlikely(ret))
2559d106c6dSDmitry Bogdanov 			return ret;
2569d106c6dSDmitry Bogdanov 	}
2579d106c6dSDmitry Bogdanov 
2589d106c6dSDmitry Bogdanov 	return 0;
2599d106c6dSDmitry Bogdanov }
2609d106c6dSDmitry Bogdanov 
261b8f8a0b7SMark Starovoytov static int
set_ingress_prectlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_prectlf_record * rec,u16 table_index)262b8f8a0b7SMark Starovoytov set_ingress_prectlf_record(struct aq_hw_s *hw,
263b8f8a0b7SMark Starovoytov 			   const struct aq_mss_ingress_prectlf_record *rec,
264b8f8a0b7SMark Starovoytov 			   u16 table_index)
265b8f8a0b7SMark Starovoytov {
266b8f8a0b7SMark Starovoytov 	u16 packed_record[6];
267b8f8a0b7SMark Starovoytov 
268b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPRECTLFRECORD)
269b8f8a0b7SMark Starovoytov 		return -EINVAL;
270b8f8a0b7SMark Starovoytov 
271b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 6);
272b8f8a0b7SMark Starovoytov 
273b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->sa_da[0] & 0xFFFF;
274b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
275b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->sa_da[1] & 0xFFFF;
276b8f8a0b7SMark Starovoytov 	packed_record[3] = rec->eth_type & 0xFFFF;
277b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->match_mask & 0xFFFF;
278b8f8a0b7SMark Starovoytov 	packed_record[5] = rec->match_type & 0xF;
279b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->action & 0x1) << 4;
280b8f8a0b7SMark Starovoytov 
281b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 6, 0,
282b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSPRECTLFRECORD +
283b8f8a0b7SMark Starovoytov 					      table_index);
284b8f8a0b7SMark Starovoytov }
285b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_prectlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_prectlf_record * rec,u16 table_index)286b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_prectlf_record(struct aq_hw_s *hw,
287b8f8a0b7SMark Starovoytov 	const struct aq_mss_ingress_prectlf_record *rec,
288b8f8a0b7SMark Starovoytov 	u16 table_index)
289b8f8a0b7SMark Starovoytov {
290b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(set_ingress_prectlf_record, hw, rec,
291b8f8a0b7SMark Starovoytov 				table_index);
292b8f8a0b7SMark Starovoytov }
293b8f8a0b7SMark Starovoytov 
get_ingress_prectlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_prectlf_record * rec,u16 table_index)294b8f8a0b7SMark Starovoytov static int get_ingress_prectlf_record(struct aq_hw_s *hw,
295b8f8a0b7SMark Starovoytov 				      struct aq_mss_ingress_prectlf_record *rec,
296b8f8a0b7SMark Starovoytov 				      u16 table_index)
297b8f8a0b7SMark Starovoytov {
298b8f8a0b7SMark Starovoytov 	u16 packed_record[6];
299b8f8a0b7SMark Starovoytov 	int ret;
300b8f8a0b7SMark Starovoytov 
301b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPRECTLFRECORD)
302b8f8a0b7SMark Starovoytov 		return -EINVAL;
303b8f8a0b7SMark Starovoytov 
304b8f8a0b7SMark Starovoytov 	/* If the row that we want to read is odd, first read the previous even
305b8f8a0b7SMark Starovoytov 	 * row, throw that value away, and finally read the desired row.
306b8f8a0b7SMark Starovoytov 	 * This is a workaround for EUR devices that allows us to read
307b8f8a0b7SMark Starovoytov 	 * odd-numbered rows.  For HHD devices: this workaround will not work,
308b8f8a0b7SMark Starovoytov 	 * so don't bother; odd-numbered rows are not readable.
309b8f8a0b7SMark Starovoytov 	 */
310b8f8a0b7SMark Starovoytov 	if ((table_index % 2) > 0) {
311b8f8a0b7SMark Starovoytov 		ret = get_raw_ingress_record(hw, packed_record, 6, 0,
312b8f8a0b7SMark Starovoytov 					     ROWOFFSET_INGRESSPRECTLFRECORD +
313b8f8a0b7SMark Starovoytov 						     table_index - 1);
314b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
315b8f8a0b7SMark Starovoytov 			return ret;
316b8f8a0b7SMark Starovoytov 	}
317b8f8a0b7SMark Starovoytov 
318b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 6, 0,
319b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSPRECTLFRECORD +
320b8f8a0b7SMark Starovoytov 					     table_index);
321b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
322b8f8a0b7SMark Starovoytov 		return ret;
323b8f8a0b7SMark Starovoytov 
324b8f8a0b7SMark Starovoytov 	rec->sa_da[0] = packed_record[0];
325b8f8a0b7SMark Starovoytov 	rec->sa_da[0] |= packed_record[1] << 16;
326b8f8a0b7SMark Starovoytov 
327b8f8a0b7SMark Starovoytov 	rec->sa_da[1] = packed_record[2];
328b8f8a0b7SMark Starovoytov 
329b8f8a0b7SMark Starovoytov 	rec->eth_type = packed_record[3];
330b8f8a0b7SMark Starovoytov 
331b8f8a0b7SMark Starovoytov 	rec->match_mask = packed_record[4];
332b8f8a0b7SMark Starovoytov 
333b8f8a0b7SMark Starovoytov 	rec->match_type = packed_record[5] & 0xF;
334b8f8a0b7SMark Starovoytov 
335b8f8a0b7SMark Starovoytov 	rec->action = (packed_record[5] >> 4) & 0x1;
336b8f8a0b7SMark Starovoytov 
337b8f8a0b7SMark Starovoytov 	return 0;
338b8f8a0b7SMark Starovoytov }
339b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_prectlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_prectlf_record * rec,u16 table_index)340b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_prectlf_record(struct aq_hw_s *hw,
341b8f8a0b7SMark Starovoytov 				      struct aq_mss_ingress_prectlf_record *rec,
342b8f8a0b7SMark Starovoytov 				      u16 table_index)
343b8f8a0b7SMark Starovoytov {
344b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
345b8f8a0b7SMark Starovoytov 
346b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_prectlf_record, hw, rec,
347b8f8a0b7SMark Starovoytov 				table_index);
348b8f8a0b7SMark Starovoytov }
349b8f8a0b7SMark Starovoytov 
350b8f8a0b7SMark Starovoytov static int
set_ingress_preclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_preclass_record * rec,u16 table_index)351b8f8a0b7SMark Starovoytov set_ingress_preclass_record(struct aq_hw_s *hw,
352b8f8a0b7SMark Starovoytov 			    const struct aq_mss_ingress_preclass_record *rec,
353b8f8a0b7SMark Starovoytov 			    u16 table_index)
354b8f8a0b7SMark Starovoytov {
355b8f8a0b7SMark Starovoytov 	u16 packed_record[20];
356b8f8a0b7SMark Starovoytov 
357b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPRECLASSRECORD)
358b8f8a0b7SMark Starovoytov 		return -EINVAL;
359b8f8a0b7SMark Starovoytov 
360b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 20);
361b8f8a0b7SMark Starovoytov 
362b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->sci[0] & 0xFFFF;
363b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->sci[0] >> 16) & 0xFFFF;
364b8f8a0b7SMark Starovoytov 
365b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->sci[1] & 0xFFFF;
366b8f8a0b7SMark Starovoytov 	packed_record[3] = (rec->sci[1] >> 16) & 0xFFFF;
367b8f8a0b7SMark Starovoytov 
368b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->tci & 0xFF;
369b8f8a0b7SMark Starovoytov 
370b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->encr_offset & 0xFF) << 8;
371b8f8a0b7SMark Starovoytov 
372b8f8a0b7SMark Starovoytov 	packed_record[5] = rec->eth_type & 0xFFFF;
373b8f8a0b7SMark Starovoytov 
374b8f8a0b7SMark Starovoytov 	packed_record[6] = rec->snap[0] & 0xFFFF;
375b8f8a0b7SMark Starovoytov 	packed_record[7] = (rec->snap[0] >> 16) & 0xFFFF;
376b8f8a0b7SMark Starovoytov 
377b8f8a0b7SMark Starovoytov 	packed_record[8] = rec->snap[1] & 0xFF;
378b8f8a0b7SMark Starovoytov 
379b8f8a0b7SMark Starovoytov 	packed_record[8] |= (rec->llc & 0xFF) << 8;
380b8f8a0b7SMark Starovoytov 	packed_record[9] = (rec->llc >> 8) & 0xFFFF;
381b8f8a0b7SMark Starovoytov 
382b8f8a0b7SMark Starovoytov 	packed_record[10] = rec->mac_sa[0] & 0xFFFF;
383b8f8a0b7SMark Starovoytov 	packed_record[11] = (rec->mac_sa[0] >> 16) & 0xFFFF;
384b8f8a0b7SMark Starovoytov 
385b8f8a0b7SMark Starovoytov 	packed_record[12] = rec->mac_sa[1] & 0xFFFF;
386b8f8a0b7SMark Starovoytov 
387b8f8a0b7SMark Starovoytov 	packed_record[13] = rec->mac_da[0] & 0xFFFF;
388b8f8a0b7SMark Starovoytov 	packed_record[14] = (rec->mac_da[0] >> 16) & 0xFFFF;
389b8f8a0b7SMark Starovoytov 
390b8f8a0b7SMark Starovoytov 	packed_record[15] = rec->mac_da[1] & 0xFFFF;
391b8f8a0b7SMark Starovoytov 
392b8f8a0b7SMark Starovoytov 	packed_record[16] = rec->lpbk_packet & 0x1;
393b8f8a0b7SMark Starovoytov 
394b8f8a0b7SMark Starovoytov 	packed_record[16] |= (rec->an_mask & 0x3) << 1;
395b8f8a0b7SMark Starovoytov 
396b8f8a0b7SMark Starovoytov 	packed_record[16] |= (rec->tci_mask & 0x3F) << 3;
397b8f8a0b7SMark Starovoytov 
398b8f8a0b7SMark Starovoytov 	packed_record[16] |= (rec->sci_mask & 0x7F) << 9;
399b8f8a0b7SMark Starovoytov 	packed_record[17] = (rec->sci_mask >> 7) & 0x1;
400b8f8a0b7SMark Starovoytov 
401b8f8a0b7SMark Starovoytov 	packed_record[17] |= (rec->eth_type_mask & 0x3) << 1;
402b8f8a0b7SMark Starovoytov 
403b8f8a0b7SMark Starovoytov 	packed_record[17] |= (rec->snap_mask & 0x1F) << 3;
404b8f8a0b7SMark Starovoytov 
405b8f8a0b7SMark Starovoytov 	packed_record[17] |= (rec->llc_mask & 0x7) << 8;
406b8f8a0b7SMark Starovoytov 
407b8f8a0b7SMark Starovoytov 	packed_record[17] |= (rec->_802_2_encapsulate & 0x1) << 11;
408b8f8a0b7SMark Starovoytov 
409b8f8a0b7SMark Starovoytov 	packed_record[17] |= (rec->sa_mask & 0xF) << 12;
410b8f8a0b7SMark Starovoytov 	packed_record[18] = (rec->sa_mask >> 4) & 0x3;
411b8f8a0b7SMark Starovoytov 
412b8f8a0b7SMark Starovoytov 	packed_record[18] |= (rec->da_mask & 0x3F) << 2;
413b8f8a0b7SMark Starovoytov 
414b8f8a0b7SMark Starovoytov 	packed_record[18] |= (rec->lpbk_mask & 0x1) << 8;
415b8f8a0b7SMark Starovoytov 
416b8f8a0b7SMark Starovoytov 	packed_record[18] |= (rec->sc_idx & 0x1F) << 9;
417b8f8a0b7SMark Starovoytov 
418b8f8a0b7SMark Starovoytov 	packed_record[18] |= (rec->proc_dest & 0x1) << 14;
419b8f8a0b7SMark Starovoytov 
420b8f8a0b7SMark Starovoytov 	packed_record[18] |= (rec->action & 0x1) << 15;
421b8f8a0b7SMark Starovoytov 	packed_record[19] = (rec->action >> 1) & 0x1;
422b8f8a0b7SMark Starovoytov 
423b8f8a0b7SMark Starovoytov 	packed_record[19] |= (rec->ctrl_unctrl & 0x1) << 1;
424b8f8a0b7SMark Starovoytov 
425b8f8a0b7SMark Starovoytov 	packed_record[19] |= (rec->sci_from_table & 0x1) << 2;
426b8f8a0b7SMark Starovoytov 
427b8f8a0b7SMark Starovoytov 	packed_record[19] |= (rec->reserved & 0xF) << 3;
428b8f8a0b7SMark Starovoytov 
429b8f8a0b7SMark Starovoytov 	packed_record[19] |= (rec->valid & 0x1) << 7;
430b8f8a0b7SMark Starovoytov 
431b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 20, 1,
432b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSPRECLASSRECORD +
433b8f8a0b7SMark Starovoytov 					      table_index);
434b8f8a0b7SMark Starovoytov }
435b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_preclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_preclass_record * rec,u16 table_index)436b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_preclass_record(struct aq_hw_s *hw,
437b8f8a0b7SMark Starovoytov 	const struct aq_mss_ingress_preclass_record *rec,
438b8f8a0b7SMark Starovoytov 	u16 table_index)
439b8f8a0b7SMark Starovoytov {
440b8f8a0b7SMark Starovoytov 	int err = AQ_API_CALL_SAFE(set_ingress_preclass_record, hw, rec,
441b8f8a0b7SMark Starovoytov 				   table_index);
442b8f8a0b7SMark Starovoytov 
443b8f8a0b7SMark Starovoytov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
444b8f8a0b7SMark Starovoytov 
445b8f8a0b7SMark Starovoytov 	return err;
446b8f8a0b7SMark Starovoytov }
447b8f8a0b7SMark Starovoytov 
448b8f8a0b7SMark Starovoytov static int
get_ingress_preclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_preclass_record * rec,u16 table_index)449b8f8a0b7SMark Starovoytov get_ingress_preclass_record(struct aq_hw_s *hw,
450b8f8a0b7SMark Starovoytov 			    struct aq_mss_ingress_preclass_record *rec,
451b8f8a0b7SMark Starovoytov 			    u16 table_index)
452b8f8a0b7SMark Starovoytov {
453b8f8a0b7SMark Starovoytov 	u16 packed_record[20];
454b8f8a0b7SMark Starovoytov 	int ret;
455b8f8a0b7SMark Starovoytov 
456b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPRECLASSRECORD)
457b8f8a0b7SMark Starovoytov 		return -EINVAL;
458b8f8a0b7SMark Starovoytov 
459b8f8a0b7SMark Starovoytov 	/* If the row that we want to read is odd, first read the previous even
460b8f8a0b7SMark Starovoytov 	 * row, throw that value away, and finally read the desired row.
461b8f8a0b7SMark Starovoytov 	 */
462b8f8a0b7SMark Starovoytov 	if ((table_index % 2) > 0) {
463b8f8a0b7SMark Starovoytov 		ret = get_raw_ingress_record(hw, packed_record, 20, 1,
464b8f8a0b7SMark Starovoytov 					     ROWOFFSET_INGRESSPRECLASSRECORD +
465b8f8a0b7SMark Starovoytov 						     table_index - 1);
466b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
467b8f8a0b7SMark Starovoytov 			return ret;
468b8f8a0b7SMark Starovoytov 	}
469b8f8a0b7SMark Starovoytov 
470b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 20, 1,
471b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSPRECLASSRECORD +
472b8f8a0b7SMark Starovoytov 					     table_index);
473b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
474b8f8a0b7SMark Starovoytov 		return ret;
475b8f8a0b7SMark Starovoytov 
476b8f8a0b7SMark Starovoytov 	rec->sci[0] = packed_record[0];
477b8f8a0b7SMark Starovoytov 	rec->sci[0] |= packed_record[1] << 16;
478b8f8a0b7SMark Starovoytov 
479b8f8a0b7SMark Starovoytov 	rec->sci[1] = packed_record[2];
480b8f8a0b7SMark Starovoytov 	rec->sci[1] |= packed_record[3] << 16;
481b8f8a0b7SMark Starovoytov 
482b8f8a0b7SMark Starovoytov 	rec->tci = packed_record[4] & 0xFF;
483b8f8a0b7SMark Starovoytov 
484b8f8a0b7SMark Starovoytov 	rec->encr_offset = (packed_record[4] >> 8) & 0xFF;
485b8f8a0b7SMark Starovoytov 
486b8f8a0b7SMark Starovoytov 	rec->eth_type = packed_record[5];
487b8f8a0b7SMark Starovoytov 
488b8f8a0b7SMark Starovoytov 	rec->snap[0] = packed_record[6];
489b8f8a0b7SMark Starovoytov 	rec->snap[0] |= packed_record[7] << 16;
490b8f8a0b7SMark Starovoytov 
491b8f8a0b7SMark Starovoytov 	rec->snap[1] = packed_record[8] & 0xFF;
492b8f8a0b7SMark Starovoytov 
493b8f8a0b7SMark Starovoytov 	rec->llc = (packed_record[8] >> 8) & 0xFF;
49486287543SColin Ian King 	rec->llc |= packed_record[9] << 8;
495b8f8a0b7SMark Starovoytov 
496b8f8a0b7SMark Starovoytov 	rec->mac_sa[0] = packed_record[10];
497b8f8a0b7SMark Starovoytov 	rec->mac_sa[0] |= packed_record[11] << 16;
498b8f8a0b7SMark Starovoytov 
499b8f8a0b7SMark Starovoytov 	rec->mac_sa[1] = packed_record[12];
500b8f8a0b7SMark Starovoytov 
501b8f8a0b7SMark Starovoytov 	rec->mac_da[0] = packed_record[13];
502b8f8a0b7SMark Starovoytov 	rec->mac_da[0] |= packed_record[14] << 16;
503b8f8a0b7SMark Starovoytov 
504b8f8a0b7SMark Starovoytov 	rec->mac_da[1] = packed_record[15];
505b8f8a0b7SMark Starovoytov 
506b8f8a0b7SMark Starovoytov 	rec->lpbk_packet = packed_record[16] & 0x1;
507b8f8a0b7SMark Starovoytov 
508b8f8a0b7SMark Starovoytov 	rec->an_mask = (packed_record[16] >> 1) & 0x3;
509b8f8a0b7SMark Starovoytov 
510b8f8a0b7SMark Starovoytov 	rec->tci_mask = (packed_record[16] >> 3) & 0x3F;
511b8f8a0b7SMark Starovoytov 
512b8f8a0b7SMark Starovoytov 	rec->sci_mask = (packed_record[16] >> 9) & 0x7F;
513b8f8a0b7SMark Starovoytov 	rec->sci_mask |= (packed_record[17] & 0x1) << 7;
514b8f8a0b7SMark Starovoytov 
515b8f8a0b7SMark Starovoytov 	rec->eth_type_mask = (packed_record[17] >> 1) & 0x3;
516b8f8a0b7SMark Starovoytov 
517b8f8a0b7SMark Starovoytov 	rec->snap_mask = (packed_record[17] >> 3) & 0x1F;
518b8f8a0b7SMark Starovoytov 
519b8f8a0b7SMark Starovoytov 	rec->llc_mask = (packed_record[17] >> 8) & 0x7;
520b8f8a0b7SMark Starovoytov 
521b8f8a0b7SMark Starovoytov 	rec->_802_2_encapsulate = (packed_record[17] >> 11) & 0x1;
522b8f8a0b7SMark Starovoytov 
523b8f8a0b7SMark Starovoytov 	rec->sa_mask = (packed_record[17] >> 12) & 0xF;
524b8f8a0b7SMark Starovoytov 	rec->sa_mask |= (packed_record[18] & 0x3) << 4;
525b8f8a0b7SMark Starovoytov 
526b8f8a0b7SMark Starovoytov 	rec->da_mask = (packed_record[18] >> 2) & 0x3F;
527b8f8a0b7SMark Starovoytov 
528b8f8a0b7SMark Starovoytov 	rec->lpbk_mask = (packed_record[18] >> 8) & 0x1;
529b8f8a0b7SMark Starovoytov 
530b8f8a0b7SMark Starovoytov 	rec->sc_idx = (packed_record[18] >> 9) & 0x1F;
531b8f8a0b7SMark Starovoytov 
532b8f8a0b7SMark Starovoytov 	rec->proc_dest = (packed_record[18] >> 14) & 0x1;
533b8f8a0b7SMark Starovoytov 
534b8f8a0b7SMark Starovoytov 	rec->action = (packed_record[18] >> 15) & 0x1;
535b8f8a0b7SMark Starovoytov 	rec->action |= (packed_record[19] & 0x1) << 1;
536b8f8a0b7SMark Starovoytov 
537b8f8a0b7SMark Starovoytov 	rec->ctrl_unctrl = (packed_record[19] >> 1) & 0x1;
538b8f8a0b7SMark Starovoytov 
539b8f8a0b7SMark Starovoytov 	rec->sci_from_table = (packed_record[19] >> 2) & 0x1;
540b8f8a0b7SMark Starovoytov 
541b8f8a0b7SMark Starovoytov 	rec->reserved = (packed_record[19] >> 3) & 0xF;
542b8f8a0b7SMark Starovoytov 
543b8f8a0b7SMark Starovoytov 	rec->valid = (packed_record[19] >> 7) & 0x1;
544b8f8a0b7SMark Starovoytov 
545b8f8a0b7SMark Starovoytov 	return 0;
546b8f8a0b7SMark Starovoytov }
547b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_preclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_preclass_record * rec,u16 table_index)548b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_preclass_record(struct aq_hw_s *hw,
549b8f8a0b7SMark Starovoytov 	struct aq_mss_ingress_preclass_record *rec,
550b8f8a0b7SMark Starovoytov 	u16 table_index)
551b8f8a0b7SMark Starovoytov {
552b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
553b8f8a0b7SMark Starovoytov 
554b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_preclass_record, hw, rec,
555b8f8a0b7SMark Starovoytov 				table_index);
556b8f8a0b7SMark Starovoytov }
557b8f8a0b7SMark Starovoytov 
set_ingress_sc_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sc_record * rec,u16 table_index)558b8f8a0b7SMark Starovoytov static int set_ingress_sc_record(struct aq_hw_s *hw,
559b8f8a0b7SMark Starovoytov 				 const struct aq_mss_ingress_sc_record *rec,
560b8f8a0b7SMark Starovoytov 				 u16 table_index)
561b8f8a0b7SMark Starovoytov {
562b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
563b8f8a0b7SMark Starovoytov 
564b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSCRECORD)
565b8f8a0b7SMark Starovoytov 		return -EINVAL;
566b8f8a0b7SMark Starovoytov 
567b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 8);
568b8f8a0b7SMark Starovoytov 
569b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->stop_time & 0xFFFF;
570b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->stop_time >> 16) & 0xFFFF;
571b8f8a0b7SMark Starovoytov 
572b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->start_time & 0xFFFF;
573b8f8a0b7SMark Starovoytov 	packed_record[3] = (rec->start_time >> 16) & 0xFFFF;
574b8f8a0b7SMark Starovoytov 
575b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->validate_frames & 0x3;
576b8f8a0b7SMark Starovoytov 
577b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->replay_protect & 0x1) << 2;
578b8f8a0b7SMark Starovoytov 
579b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->anti_replay_window & 0x1FFF) << 3;
580b8f8a0b7SMark Starovoytov 	packed_record[5] = (rec->anti_replay_window >> 13) & 0xFFFF;
581b8f8a0b7SMark Starovoytov 	packed_record[6] = (rec->anti_replay_window >> 29) & 0x7;
582b8f8a0b7SMark Starovoytov 
583b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->receiving & 0x1) << 3;
584b8f8a0b7SMark Starovoytov 
585b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->fresh & 0x1) << 4;
586b8f8a0b7SMark Starovoytov 
587b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->an_rol & 0x1) << 5;
588b8f8a0b7SMark Starovoytov 
589b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->reserved & 0x3FF) << 6;
590b8f8a0b7SMark Starovoytov 	packed_record[7] = (rec->reserved >> 10) & 0x7FFF;
591b8f8a0b7SMark Starovoytov 
592b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->valid & 0x1) << 15;
593b8f8a0b7SMark Starovoytov 
594b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 8, 3,
595b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSSCRECORD + table_index);
596b8f8a0b7SMark Starovoytov }
597b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_sc_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sc_record * rec,u16 table_index)598b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_sc_record(struct aq_hw_s *hw,
599b8f8a0b7SMark Starovoytov 				 const struct aq_mss_ingress_sc_record *rec,
600b8f8a0b7SMark Starovoytov 				 u16 table_index)
601b8f8a0b7SMark Starovoytov {
602b8f8a0b7SMark Starovoytov 	int err = AQ_API_CALL_SAFE(set_ingress_sc_record, hw, rec, table_index);
603b8f8a0b7SMark Starovoytov 
604b8f8a0b7SMark Starovoytov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
605b8f8a0b7SMark Starovoytov 
606b8f8a0b7SMark Starovoytov 	return err;
607b8f8a0b7SMark Starovoytov }
608b8f8a0b7SMark Starovoytov 
get_ingress_sc_record(struct aq_hw_s * hw,struct aq_mss_ingress_sc_record * rec,u16 table_index)609b8f8a0b7SMark Starovoytov static int get_ingress_sc_record(struct aq_hw_s *hw,
610b8f8a0b7SMark Starovoytov 				 struct aq_mss_ingress_sc_record *rec,
611b8f8a0b7SMark Starovoytov 				 u16 table_index)
612b8f8a0b7SMark Starovoytov {
613b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
614b8f8a0b7SMark Starovoytov 	int ret;
615b8f8a0b7SMark Starovoytov 
616b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSCRECORD)
617b8f8a0b7SMark Starovoytov 		return -EINVAL;
618b8f8a0b7SMark Starovoytov 
619b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 8, 3,
620b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSSCRECORD + table_index);
621b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
622b8f8a0b7SMark Starovoytov 		return ret;
623b8f8a0b7SMark Starovoytov 
624b8f8a0b7SMark Starovoytov 	rec->stop_time = packed_record[0];
625b8f8a0b7SMark Starovoytov 	rec->stop_time |= packed_record[1] << 16;
626b8f8a0b7SMark Starovoytov 
627b8f8a0b7SMark Starovoytov 	rec->start_time = packed_record[2];
628b8f8a0b7SMark Starovoytov 	rec->start_time |= packed_record[3] << 16;
629b8f8a0b7SMark Starovoytov 
630b8f8a0b7SMark Starovoytov 	rec->validate_frames = packed_record[4] & 0x3;
631b8f8a0b7SMark Starovoytov 
632b8f8a0b7SMark Starovoytov 	rec->replay_protect = (packed_record[4] >> 2) & 0x1;
633b8f8a0b7SMark Starovoytov 
634b8f8a0b7SMark Starovoytov 	rec->anti_replay_window = (packed_record[4] >> 3) & 0x1FFF;
635b8f8a0b7SMark Starovoytov 	rec->anti_replay_window |= packed_record[5] << 13;
636b8f8a0b7SMark Starovoytov 	rec->anti_replay_window |= (packed_record[6] & 0x7) << 29;
637b8f8a0b7SMark Starovoytov 
638b8f8a0b7SMark Starovoytov 	rec->receiving = (packed_record[6] >> 3) & 0x1;
639b8f8a0b7SMark Starovoytov 
640b8f8a0b7SMark Starovoytov 	rec->fresh = (packed_record[6] >> 4) & 0x1;
641b8f8a0b7SMark Starovoytov 
642b8f8a0b7SMark Starovoytov 	rec->an_rol = (packed_record[6] >> 5) & 0x1;
643b8f8a0b7SMark Starovoytov 
644b8f8a0b7SMark Starovoytov 	rec->reserved = (packed_record[6] >> 6) & 0x3FF;
645b8f8a0b7SMark Starovoytov 	rec->reserved |= (packed_record[7] & 0x7FFF) << 10;
646b8f8a0b7SMark Starovoytov 
647b8f8a0b7SMark Starovoytov 	rec->valid = (packed_record[7] >> 15) & 0x1;
648b8f8a0b7SMark Starovoytov 
649b8f8a0b7SMark Starovoytov 	return 0;
650b8f8a0b7SMark Starovoytov }
651b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_sc_record(struct aq_hw_s * hw,struct aq_mss_ingress_sc_record * rec,u16 table_index)652b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_sc_record(struct aq_hw_s *hw,
653b8f8a0b7SMark Starovoytov 				 struct aq_mss_ingress_sc_record *rec,
654b8f8a0b7SMark Starovoytov 				 u16 table_index)
655b8f8a0b7SMark Starovoytov {
656b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
657b8f8a0b7SMark Starovoytov 
658b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_sc_record, hw, rec, table_index);
659b8f8a0b7SMark Starovoytov }
660b8f8a0b7SMark Starovoytov 
set_ingress_sa_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sa_record * rec,u16 table_index)661b8f8a0b7SMark Starovoytov static int set_ingress_sa_record(struct aq_hw_s *hw,
662b8f8a0b7SMark Starovoytov 				 const struct aq_mss_ingress_sa_record *rec,
663b8f8a0b7SMark Starovoytov 				 u16 table_index)
664b8f8a0b7SMark Starovoytov {
665b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
666b8f8a0b7SMark Starovoytov 
667b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSARECORD)
668b8f8a0b7SMark Starovoytov 		return -EINVAL;
669b8f8a0b7SMark Starovoytov 
670b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 8);
671b8f8a0b7SMark Starovoytov 
672b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->stop_time & 0xFFFF;
673b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->stop_time >> 16) & 0xFFFF;
674b8f8a0b7SMark Starovoytov 
675b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->start_time & 0xFFFF;
676b8f8a0b7SMark Starovoytov 	packed_record[3] = (rec->start_time >> 16) & 0xFFFF;
677b8f8a0b7SMark Starovoytov 
678b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->next_pn & 0xFFFF;
679b8f8a0b7SMark Starovoytov 	packed_record[5] = (rec->next_pn >> 16) & 0xFFFF;
680b8f8a0b7SMark Starovoytov 
681b8f8a0b7SMark Starovoytov 	packed_record[6] = rec->sat_nextpn & 0x1;
682b8f8a0b7SMark Starovoytov 
683b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->in_use & 0x1) << 1;
684b8f8a0b7SMark Starovoytov 
685b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->fresh & 0x1) << 2;
686b8f8a0b7SMark Starovoytov 
687b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->reserved & 0x1FFF) << 3;
688b8f8a0b7SMark Starovoytov 	packed_record[7] = (rec->reserved >> 13) & 0x7FFF;
689b8f8a0b7SMark Starovoytov 
690b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->valid & 0x1) << 15;
691b8f8a0b7SMark Starovoytov 
692b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 8, 3,
693b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSSARECORD + table_index);
694b8f8a0b7SMark Starovoytov }
695b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_sa_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sa_record * rec,u16 table_index)696b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_sa_record(struct aq_hw_s *hw,
697b8f8a0b7SMark Starovoytov 				 const struct aq_mss_ingress_sa_record *rec,
698b8f8a0b7SMark Starovoytov 				 u16 table_index)
699b8f8a0b7SMark Starovoytov {
700b8f8a0b7SMark Starovoytov 	int err = AQ_API_CALL_SAFE(set_ingress_sa_record, hw, rec, table_index);
701b8f8a0b7SMark Starovoytov 
702b8f8a0b7SMark Starovoytov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
703b8f8a0b7SMark Starovoytov 
704b8f8a0b7SMark Starovoytov 	return err;
705b8f8a0b7SMark Starovoytov }
706b8f8a0b7SMark Starovoytov 
get_ingress_sa_record(struct aq_hw_s * hw,struct aq_mss_ingress_sa_record * rec,u16 table_index)707b8f8a0b7SMark Starovoytov static int get_ingress_sa_record(struct aq_hw_s *hw,
708b8f8a0b7SMark Starovoytov 				 struct aq_mss_ingress_sa_record *rec,
709b8f8a0b7SMark Starovoytov 				 u16 table_index)
710b8f8a0b7SMark Starovoytov {
711b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
712b8f8a0b7SMark Starovoytov 	int ret;
713b8f8a0b7SMark Starovoytov 
714b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSARECORD)
715b8f8a0b7SMark Starovoytov 		return -EINVAL;
716b8f8a0b7SMark Starovoytov 
717b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 8, 3,
718b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSSARECORD + table_index);
719b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
720b8f8a0b7SMark Starovoytov 		return ret;
721b8f8a0b7SMark Starovoytov 
722b8f8a0b7SMark Starovoytov 	rec->stop_time = packed_record[0];
723b8f8a0b7SMark Starovoytov 	rec->stop_time |= packed_record[1] << 16;
724b8f8a0b7SMark Starovoytov 
725b8f8a0b7SMark Starovoytov 	rec->start_time = packed_record[2];
726b8f8a0b7SMark Starovoytov 	rec->start_time |= packed_record[3] << 16;
727b8f8a0b7SMark Starovoytov 
728b8f8a0b7SMark Starovoytov 	rec->next_pn = packed_record[4];
729b8f8a0b7SMark Starovoytov 	rec->next_pn |= packed_record[5] << 16;
730b8f8a0b7SMark Starovoytov 
731b8f8a0b7SMark Starovoytov 	rec->sat_nextpn = packed_record[6] & 0x1;
732b8f8a0b7SMark Starovoytov 
733b8f8a0b7SMark Starovoytov 	rec->in_use = (packed_record[6] >> 1) & 0x1;
734b8f8a0b7SMark Starovoytov 
735b8f8a0b7SMark Starovoytov 	rec->fresh = (packed_record[6] >> 2) & 0x1;
736b8f8a0b7SMark Starovoytov 
737b8f8a0b7SMark Starovoytov 	rec->reserved = (packed_record[6] >> 3) & 0x1FFF;
738b8f8a0b7SMark Starovoytov 	rec->reserved |= (packed_record[7] & 0x7FFF) << 13;
739b8f8a0b7SMark Starovoytov 
740b8f8a0b7SMark Starovoytov 	rec->valid = (packed_record[7] >> 15) & 0x1;
741b8f8a0b7SMark Starovoytov 
742b8f8a0b7SMark Starovoytov 	return 0;
743b8f8a0b7SMark Starovoytov }
744b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_sa_record(struct aq_hw_s * hw,struct aq_mss_ingress_sa_record * rec,u16 table_index)745b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_sa_record(struct aq_hw_s *hw,
746b8f8a0b7SMark Starovoytov 				 struct aq_mss_ingress_sa_record *rec,
747b8f8a0b7SMark Starovoytov 				 u16 table_index)
748b8f8a0b7SMark Starovoytov {
749b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
750b8f8a0b7SMark Starovoytov 
751b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_sa_record, hw, rec, table_index);
752b8f8a0b7SMark Starovoytov }
753b8f8a0b7SMark Starovoytov 
754b8f8a0b7SMark Starovoytov static int
set_ingress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sakey_record * rec,u16 table_index)755b8f8a0b7SMark Starovoytov set_ingress_sakey_record(struct aq_hw_s *hw,
756b8f8a0b7SMark Starovoytov 			 const struct aq_mss_ingress_sakey_record *rec,
757b8f8a0b7SMark Starovoytov 			 u16 table_index)
758b8f8a0b7SMark Starovoytov {
759b8f8a0b7SMark Starovoytov 	u16 packed_record[18];
7603652f1f8SAntoine Tenart 	int ret;
761b8f8a0b7SMark Starovoytov 
762b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
763b8f8a0b7SMark Starovoytov 		return -EINVAL;
764b8f8a0b7SMark Starovoytov 
765b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 18);
766b8f8a0b7SMark Starovoytov 
767b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->key[0] & 0xFFFF;
768b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
769b8f8a0b7SMark Starovoytov 
770b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->key[1] & 0xFFFF;
771b8f8a0b7SMark Starovoytov 	packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
772b8f8a0b7SMark Starovoytov 
773b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->key[2] & 0xFFFF;
774b8f8a0b7SMark Starovoytov 	packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
775b8f8a0b7SMark Starovoytov 
776b8f8a0b7SMark Starovoytov 	packed_record[6] = rec->key[3] & 0xFFFF;
777b8f8a0b7SMark Starovoytov 	packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
778b8f8a0b7SMark Starovoytov 
779b8f8a0b7SMark Starovoytov 	packed_record[8] = rec->key[4] & 0xFFFF;
780b8f8a0b7SMark Starovoytov 	packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
781b8f8a0b7SMark Starovoytov 
782b8f8a0b7SMark Starovoytov 	packed_record[10] = rec->key[5] & 0xFFFF;
783b8f8a0b7SMark Starovoytov 	packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
784b8f8a0b7SMark Starovoytov 
785b8f8a0b7SMark Starovoytov 	packed_record[12] = rec->key[6] & 0xFFFF;
786b8f8a0b7SMark Starovoytov 	packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
787b8f8a0b7SMark Starovoytov 
788b8f8a0b7SMark Starovoytov 	packed_record[14] = rec->key[7] & 0xFFFF;
789b8f8a0b7SMark Starovoytov 	packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
790b8f8a0b7SMark Starovoytov 
791b8f8a0b7SMark Starovoytov 	packed_record[16] = rec->key_len & 0x3;
792b8f8a0b7SMark Starovoytov 
7933652f1f8SAntoine Tenart 	ret = set_raw_ingress_record(hw, packed_record, 18, 2,
794b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSSAKEYRECORD +
795b8f8a0b7SMark Starovoytov 				     table_index);
7963652f1f8SAntoine Tenart 
7973652f1f8SAntoine Tenart 	memzero_explicit(packed_record, sizeof(packed_record));
7983652f1f8SAntoine Tenart 	return ret;
799b8f8a0b7SMark Starovoytov }
800b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_ingress_sakey_record * rec,u16 table_index)801b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw,
802b8f8a0b7SMark Starovoytov 	const struct aq_mss_ingress_sakey_record *rec,
803b8f8a0b7SMark Starovoytov 	u16 table_index)
804b8f8a0b7SMark Starovoytov {
805b8f8a0b7SMark Starovoytov 	int err = AQ_API_CALL_SAFE(set_ingress_sakey_record, hw, rec,
806b8f8a0b7SMark Starovoytov 				   table_index);
807b8f8a0b7SMark Starovoytov 
808b8f8a0b7SMark Starovoytov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
809b8f8a0b7SMark Starovoytov 
810b8f8a0b7SMark Starovoytov 	return err;
811b8f8a0b7SMark Starovoytov }
812b8f8a0b7SMark Starovoytov 
get_ingress_sakey_record(struct aq_hw_s * hw,struct aq_mss_ingress_sakey_record * rec,u16 table_index)813b8f8a0b7SMark Starovoytov static int get_ingress_sakey_record(struct aq_hw_s *hw,
814b8f8a0b7SMark Starovoytov 				    struct aq_mss_ingress_sakey_record *rec,
815b8f8a0b7SMark Starovoytov 				    u16 table_index)
816b8f8a0b7SMark Starovoytov {
817b8f8a0b7SMark Starovoytov 	u16 packed_record[18];
818b8f8a0b7SMark Starovoytov 	int ret;
819b8f8a0b7SMark Starovoytov 
820b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSSAKEYRECORD)
821b8f8a0b7SMark Starovoytov 		return -EINVAL;
822b8f8a0b7SMark Starovoytov 
823b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 18, 2,
824b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSSAKEYRECORD +
825b8f8a0b7SMark Starovoytov 					     table_index);
826b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
827b8f8a0b7SMark Starovoytov 		return ret;
828b8f8a0b7SMark Starovoytov 
829b8f8a0b7SMark Starovoytov 	rec->key[0] = packed_record[0];
830b8f8a0b7SMark Starovoytov 	rec->key[0] |= packed_record[1] << 16;
831b8f8a0b7SMark Starovoytov 
832b8f8a0b7SMark Starovoytov 	rec->key[1] = packed_record[2];
833b8f8a0b7SMark Starovoytov 	rec->key[1] |= packed_record[3] << 16;
834b8f8a0b7SMark Starovoytov 
835b8f8a0b7SMark Starovoytov 	rec->key[2] = packed_record[4];
836b8f8a0b7SMark Starovoytov 	rec->key[2] |= packed_record[5] << 16;
837b8f8a0b7SMark Starovoytov 
838b8f8a0b7SMark Starovoytov 	rec->key[3] = packed_record[6];
839b8f8a0b7SMark Starovoytov 	rec->key[3] |= packed_record[7] << 16;
840b8f8a0b7SMark Starovoytov 
841b8f8a0b7SMark Starovoytov 	rec->key[4] = packed_record[8];
842b8f8a0b7SMark Starovoytov 	rec->key[4] |= packed_record[9] << 16;
843b8f8a0b7SMark Starovoytov 
844b8f8a0b7SMark Starovoytov 	rec->key[5] = packed_record[10];
845b8f8a0b7SMark Starovoytov 	rec->key[5] |= packed_record[11] << 16;
846b8f8a0b7SMark Starovoytov 
847b8f8a0b7SMark Starovoytov 	rec->key[6] = packed_record[12];
848b8f8a0b7SMark Starovoytov 	rec->key[6] |= packed_record[13] << 16;
849b8f8a0b7SMark Starovoytov 
850b8f8a0b7SMark Starovoytov 	rec->key[7] = packed_record[14];
851b8f8a0b7SMark Starovoytov 	rec->key[7] |= packed_record[15] << 16;
852b8f8a0b7SMark Starovoytov 
8537bb37710SMark Starovoytov 	rec->key_len = packed_record[16] & 0x3;
854b8f8a0b7SMark Starovoytov 
855b8f8a0b7SMark Starovoytov 	return 0;
856b8f8a0b7SMark Starovoytov }
857b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_sakey_record(struct aq_hw_s * hw,struct aq_mss_ingress_sakey_record * rec,u16 table_index)858b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_sakey_record(struct aq_hw_s *hw,
859b8f8a0b7SMark Starovoytov 				    struct aq_mss_ingress_sakey_record *rec,
860b8f8a0b7SMark Starovoytov 				    u16 table_index)
861b8f8a0b7SMark Starovoytov {
862b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
863b8f8a0b7SMark Starovoytov 
864b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_sakey_record, hw, rec, table_index);
865b8f8a0b7SMark Starovoytov }
866b8f8a0b7SMark Starovoytov 
867b8f8a0b7SMark Starovoytov static int
set_ingress_postclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postclass_record * rec,u16 table_index)868b8f8a0b7SMark Starovoytov set_ingress_postclass_record(struct aq_hw_s *hw,
869b8f8a0b7SMark Starovoytov 			     const struct aq_mss_ingress_postclass_record *rec,
870b8f8a0b7SMark Starovoytov 			     u16 table_index)
871b8f8a0b7SMark Starovoytov {
872b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
873b8f8a0b7SMark Starovoytov 
874b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
875b8f8a0b7SMark Starovoytov 		return -EINVAL;
876b8f8a0b7SMark Starovoytov 
877b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 8);
878b8f8a0b7SMark Starovoytov 
879b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->byte0 & 0xFF;
880b8f8a0b7SMark Starovoytov 
881b8f8a0b7SMark Starovoytov 	packed_record[0] |= (rec->byte1 & 0xFF) << 8;
882b8f8a0b7SMark Starovoytov 
883b8f8a0b7SMark Starovoytov 	packed_record[1] = rec->byte2 & 0xFF;
884b8f8a0b7SMark Starovoytov 
885b8f8a0b7SMark Starovoytov 	packed_record[1] |= (rec->byte3 & 0xFF) << 8;
886b8f8a0b7SMark Starovoytov 
887b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->eth_type & 0xFFFF;
888b8f8a0b7SMark Starovoytov 
889b8f8a0b7SMark Starovoytov 	packed_record[3] = rec->eth_type_valid & 0x1;
890b8f8a0b7SMark Starovoytov 
891b8f8a0b7SMark Starovoytov 	packed_record[3] |= (rec->vlan_id & 0xFFF) << 1;
892b8f8a0b7SMark Starovoytov 
893b8f8a0b7SMark Starovoytov 	packed_record[3] |= (rec->vlan_up & 0x7) << 13;
894b8f8a0b7SMark Starovoytov 
895b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->vlan_valid & 0x1;
896b8f8a0b7SMark Starovoytov 
897b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->sai & 0x1F) << 1;
898b8f8a0b7SMark Starovoytov 
899b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->sai_hit & 0x1) << 6;
900b8f8a0b7SMark Starovoytov 
901b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->eth_type_mask & 0xF) << 7;
902b8f8a0b7SMark Starovoytov 
903b8f8a0b7SMark Starovoytov 	packed_record[4] |= (rec->byte3_location & 0x1F) << 11;
904b8f8a0b7SMark Starovoytov 	packed_record[5] = (rec->byte3_location >> 5) & 0x1;
905b8f8a0b7SMark Starovoytov 
906b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->byte3_mask & 0x3) << 1;
907b8f8a0b7SMark Starovoytov 
908b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->byte2_location & 0x3F) << 3;
909b8f8a0b7SMark Starovoytov 
910b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->byte2_mask & 0x3) << 9;
911b8f8a0b7SMark Starovoytov 
912b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->byte1_location & 0x1F) << 11;
913b8f8a0b7SMark Starovoytov 	packed_record[6] = (rec->byte1_location >> 5) & 0x1;
914b8f8a0b7SMark Starovoytov 
915b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->byte1_mask & 0x3) << 1;
916b8f8a0b7SMark Starovoytov 
917b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->byte0_location & 0x3F) << 3;
918b8f8a0b7SMark Starovoytov 
919b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->byte0_mask & 0x3) << 9;
920b8f8a0b7SMark Starovoytov 
921b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->eth_type_valid_mask & 0x3) << 11;
922b8f8a0b7SMark Starovoytov 
923b8f8a0b7SMark Starovoytov 	packed_record[6] |= (rec->vlan_id_mask & 0x7) << 13;
924b8f8a0b7SMark Starovoytov 	packed_record[7] = (rec->vlan_id_mask >> 3) & 0x1;
925b8f8a0b7SMark Starovoytov 
926b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->vlan_up_mask & 0x3) << 1;
927b8f8a0b7SMark Starovoytov 
928b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->vlan_valid_mask & 0x3) << 3;
929b8f8a0b7SMark Starovoytov 
930b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->sai_mask & 0x3) << 5;
931b8f8a0b7SMark Starovoytov 
932b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->sai_hit_mask & 0x3) << 7;
933b8f8a0b7SMark Starovoytov 
934b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->firstlevel_actions & 0x1) << 9;
935b8f8a0b7SMark Starovoytov 
936b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->secondlevel_actions & 0x1) << 10;
937b8f8a0b7SMark Starovoytov 
938b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->reserved & 0xF) << 11;
939b8f8a0b7SMark Starovoytov 
940b8f8a0b7SMark Starovoytov 	packed_record[7] |= (rec->valid & 0x1) << 15;
941b8f8a0b7SMark Starovoytov 
942b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 8, 4,
943b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSPOSTCLASSRECORD +
944b8f8a0b7SMark Starovoytov 					      table_index);
945b8f8a0b7SMark Starovoytov }
946b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_postclass_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postclass_record * rec,u16 table_index)947b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_postclass_record(struct aq_hw_s *hw,
948b8f8a0b7SMark Starovoytov 	const struct aq_mss_ingress_postclass_record *rec,
949b8f8a0b7SMark Starovoytov 	u16 table_index)
950b8f8a0b7SMark Starovoytov {
951b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(set_ingress_postclass_record, hw, rec,
952b8f8a0b7SMark Starovoytov 				table_index);
953b8f8a0b7SMark Starovoytov }
954b8f8a0b7SMark Starovoytov 
955b8f8a0b7SMark Starovoytov static int
get_ingress_postclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_postclass_record * rec,u16 table_index)956b8f8a0b7SMark Starovoytov get_ingress_postclass_record(struct aq_hw_s *hw,
957b8f8a0b7SMark Starovoytov 			     struct aq_mss_ingress_postclass_record *rec,
958b8f8a0b7SMark Starovoytov 			     u16 table_index)
959b8f8a0b7SMark Starovoytov {
960b8f8a0b7SMark Starovoytov 	u16 packed_record[8];
961b8f8a0b7SMark Starovoytov 	int ret;
962b8f8a0b7SMark Starovoytov 
963b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPOSTCLASSRECORD)
964b8f8a0b7SMark Starovoytov 		return -EINVAL;
965b8f8a0b7SMark Starovoytov 
966b8f8a0b7SMark Starovoytov 	/* If the row that we want to read is odd, first read the previous even
967b8f8a0b7SMark Starovoytov 	 * row, throw that value away, and finally read the desired row.
968b8f8a0b7SMark Starovoytov 	 */
969b8f8a0b7SMark Starovoytov 	if ((table_index % 2) > 0) {
970b8f8a0b7SMark Starovoytov 		ret = get_raw_ingress_record(hw, packed_record, 8, 4,
971b8f8a0b7SMark Starovoytov 					     ROWOFFSET_INGRESSPOSTCLASSRECORD +
972b8f8a0b7SMark Starovoytov 						     table_index - 1);
973b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
974b8f8a0b7SMark Starovoytov 			return ret;
975b8f8a0b7SMark Starovoytov 	}
976b8f8a0b7SMark Starovoytov 
977b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 8, 4,
978b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSPOSTCLASSRECORD +
979b8f8a0b7SMark Starovoytov 					     table_index);
980b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
981b8f8a0b7SMark Starovoytov 		return ret;
982b8f8a0b7SMark Starovoytov 
983b8f8a0b7SMark Starovoytov 	rec->byte0 = packed_record[0] & 0xFF;
984b8f8a0b7SMark Starovoytov 
985b8f8a0b7SMark Starovoytov 	rec->byte1 = (packed_record[0] >> 8) & 0xFF;
986b8f8a0b7SMark Starovoytov 
987b8f8a0b7SMark Starovoytov 	rec->byte2 = packed_record[1] & 0xFF;
988b8f8a0b7SMark Starovoytov 
989b8f8a0b7SMark Starovoytov 	rec->byte3 = (packed_record[1] >> 8) & 0xFF;
990b8f8a0b7SMark Starovoytov 
991b8f8a0b7SMark Starovoytov 	rec->eth_type = packed_record[2];
992b8f8a0b7SMark Starovoytov 
993b8f8a0b7SMark Starovoytov 	rec->eth_type_valid = packed_record[3] & 0x1;
994b8f8a0b7SMark Starovoytov 
995b8f8a0b7SMark Starovoytov 	rec->vlan_id = (packed_record[3] >> 1) & 0xFFF;
996b8f8a0b7SMark Starovoytov 
997b8f8a0b7SMark Starovoytov 	rec->vlan_up = (packed_record[3] >> 13) & 0x7;
998b8f8a0b7SMark Starovoytov 
999b8f8a0b7SMark Starovoytov 	rec->vlan_valid = packed_record[4] & 0x1;
1000b8f8a0b7SMark Starovoytov 
1001b8f8a0b7SMark Starovoytov 	rec->sai = (packed_record[4] >> 1) & 0x1F;
1002b8f8a0b7SMark Starovoytov 
1003b8f8a0b7SMark Starovoytov 	rec->sai_hit = (packed_record[4] >> 6) & 0x1;
1004b8f8a0b7SMark Starovoytov 
1005b8f8a0b7SMark Starovoytov 	rec->eth_type_mask = (packed_record[4] >> 7) & 0xF;
1006b8f8a0b7SMark Starovoytov 
1007b8f8a0b7SMark Starovoytov 	rec->byte3_location = (packed_record[4] >> 11) & 0x1F;
1008b8f8a0b7SMark Starovoytov 	rec->byte3_location |= (packed_record[5] & 0x1) << 5;
1009b8f8a0b7SMark Starovoytov 
1010b8f8a0b7SMark Starovoytov 	rec->byte3_mask = (packed_record[5] >> 1) & 0x3;
1011b8f8a0b7SMark Starovoytov 
1012b8f8a0b7SMark Starovoytov 	rec->byte2_location = (packed_record[5] >> 3) & 0x3F;
1013b8f8a0b7SMark Starovoytov 
1014b8f8a0b7SMark Starovoytov 	rec->byte2_mask = (packed_record[5] >> 9) & 0x3;
1015b8f8a0b7SMark Starovoytov 
1016b8f8a0b7SMark Starovoytov 	rec->byte1_location = (packed_record[5] >> 11) & 0x1F;
1017b8f8a0b7SMark Starovoytov 	rec->byte1_location |= (packed_record[6] & 0x1) << 5;
1018b8f8a0b7SMark Starovoytov 
1019b8f8a0b7SMark Starovoytov 	rec->byte1_mask = (packed_record[6] >> 1) & 0x3;
1020b8f8a0b7SMark Starovoytov 
1021b8f8a0b7SMark Starovoytov 	rec->byte0_location = (packed_record[6] >> 3) & 0x3F;
1022b8f8a0b7SMark Starovoytov 
1023b8f8a0b7SMark Starovoytov 	rec->byte0_mask = (packed_record[6] >> 9) & 0x3;
1024b8f8a0b7SMark Starovoytov 
1025b8f8a0b7SMark Starovoytov 	rec->eth_type_valid_mask = (packed_record[6] >> 11) & 0x3;
1026b8f8a0b7SMark Starovoytov 
1027b8f8a0b7SMark Starovoytov 	rec->vlan_id_mask = (packed_record[6] >> 13) & 0x7;
1028b8f8a0b7SMark Starovoytov 	rec->vlan_id_mask |= (packed_record[7] & 0x1) << 3;
1029b8f8a0b7SMark Starovoytov 
1030b8f8a0b7SMark Starovoytov 	rec->vlan_up_mask = (packed_record[7] >> 1) & 0x3;
1031b8f8a0b7SMark Starovoytov 
1032b8f8a0b7SMark Starovoytov 	rec->vlan_valid_mask = (packed_record[7] >> 3) & 0x3;
1033b8f8a0b7SMark Starovoytov 
1034b8f8a0b7SMark Starovoytov 	rec->sai_mask = (packed_record[7] >> 5) & 0x3;
1035b8f8a0b7SMark Starovoytov 
1036b8f8a0b7SMark Starovoytov 	rec->sai_hit_mask = (packed_record[7] >> 7) & 0x3;
1037b8f8a0b7SMark Starovoytov 
1038b8f8a0b7SMark Starovoytov 	rec->firstlevel_actions = (packed_record[7] >> 9) & 0x1;
1039b8f8a0b7SMark Starovoytov 
1040b8f8a0b7SMark Starovoytov 	rec->secondlevel_actions = (packed_record[7] >> 10) & 0x1;
1041b8f8a0b7SMark Starovoytov 
1042b8f8a0b7SMark Starovoytov 	rec->reserved = (packed_record[7] >> 11) & 0xF;
1043b8f8a0b7SMark Starovoytov 
1044b8f8a0b7SMark Starovoytov 	rec->valid = (packed_record[7] >> 15) & 0x1;
1045b8f8a0b7SMark Starovoytov 
1046b8f8a0b7SMark Starovoytov 	return 0;
1047b8f8a0b7SMark Starovoytov }
1048b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_postclass_record(struct aq_hw_s * hw,struct aq_mss_ingress_postclass_record * rec,u16 table_index)1049b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_postclass_record(struct aq_hw_s *hw,
1050b8f8a0b7SMark Starovoytov 	struct aq_mss_ingress_postclass_record *rec,
1051b8f8a0b7SMark Starovoytov 	u16 table_index)
1052b8f8a0b7SMark Starovoytov {
1053b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
1054b8f8a0b7SMark Starovoytov 
1055b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_postclass_record, hw, rec,
1056b8f8a0b7SMark Starovoytov 				table_index);
1057b8f8a0b7SMark Starovoytov }
1058b8f8a0b7SMark Starovoytov 
1059b8f8a0b7SMark Starovoytov static int
set_ingress_postctlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1060b8f8a0b7SMark Starovoytov set_ingress_postctlf_record(struct aq_hw_s *hw,
1061b8f8a0b7SMark Starovoytov 			    const struct aq_mss_ingress_postctlf_record *rec,
1062b8f8a0b7SMark Starovoytov 			    u16 table_index)
1063b8f8a0b7SMark Starovoytov {
1064b8f8a0b7SMark Starovoytov 	u16 packed_record[6];
1065b8f8a0b7SMark Starovoytov 
1066b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1067b8f8a0b7SMark Starovoytov 		return -EINVAL;
1068b8f8a0b7SMark Starovoytov 
1069b8f8a0b7SMark Starovoytov 	memset(packed_record, 0, sizeof(u16) * 6);
1070b8f8a0b7SMark Starovoytov 
1071b8f8a0b7SMark Starovoytov 	packed_record[0] = rec->sa_da[0] & 0xFFFF;
1072b8f8a0b7SMark Starovoytov 	packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
1073b8f8a0b7SMark Starovoytov 
1074b8f8a0b7SMark Starovoytov 	packed_record[2] = rec->sa_da[1] & 0xFFFF;
1075b8f8a0b7SMark Starovoytov 
1076b8f8a0b7SMark Starovoytov 	packed_record[3] = rec->eth_type & 0xFFFF;
1077b8f8a0b7SMark Starovoytov 
1078b8f8a0b7SMark Starovoytov 	packed_record[4] = rec->match_mask & 0xFFFF;
1079b8f8a0b7SMark Starovoytov 
1080b8f8a0b7SMark Starovoytov 	packed_record[5] = rec->match_type & 0xF;
1081b8f8a0b7SMark Starovoytov 
1082b8f8a0b7SMark Starovoytov 	packed_record[5] |= (rec->action & 0x1) << 4;
1083b8f8a0b7SMark Starovoytov 
1084b8f8a0b7SMark Starovoytov 	return set_raw_ingress_record(hw, packed_record, 6, 5,
1085b8f8a0b7SMark Starovoytov 				      ROWOFFSET_INGRESSPOSTCTLFRECORD +
1086b8f8a0b7SMark Starovoytov 					      table_index);
1087b8f8a0b7SMark Starovoytov }
1088b8f8a0b7SMark Starovoytov 
aq_mss_set_ingress_postctlf_record(struct aq_hw_s * hw,const struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1089b8f8a0b7SMark Starovoytov int aq_mss_set_ingress_postctlf_record(struct aq_hw_s *hw,
1090b8f8a0b7SMark Starovoytov 	const struct aq_mss_ingress_postctlf_record *rec,
1091b8f8a0b7SMark Starovoytov 	u16 table_index)
1092b8f8a0b7SMark Starovoytov {
1093b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(set_ingress_postctlf_record, hw, rec,
1094b8f8a0b7SMark Starovoytov 				table_index);
1095b8f8a0b7SMark Starovoytov }
1096b8f8a0b7SMark Starovoytov 
1097b8f8a0b7SMark Starovoytov static int
get_ingress_postctlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1098b8f8a0b7SMark Starovoytov get_ingress_postctlf_record(struct aq_hw_s *hw,
1099b8f8a0b7SMark Starovoytov 			    struct aq_mss_ingress_postctlf_record *rec,
1100b8f8a0b7SMark Starovoytov 			    u16 table_index)
1101b8f8a0b7SMark Starovoytov {
1102b8f8a0b7SMark Starovoytov 	u16 packed_record[6];
1103b8f8a0b7SMark Starovoytov 	int ret;
1104b8f8a0b7SMark Starovoytov 
1105b8f8a0b7SMark Starovoytov 	if (table_index >= NUMROWS_INGRESSPOSTCTLFRECORD)
1106b8f8a0b7SMark Starovoytov 		return -EINVAL;
1107b8f8a0b7SMark Starovoytov 
1108b8f8a0b7SMark Starovoytov 	/* If the row that we want to read is odd, first read the previous even
1109b8f8a0b7SMark Starovoytov 	 * row, throw that value away, and finally read the desired row.
1110b8f8a0b7SMark Starovoytov 	 */
1111b8f8a0b7SMark Starovoytov 	if ((table_index % 2) > 0) {
1112b8f8a0b7SMark Starovoytov 		ret = get_raw_ingress_record(hw, packed_record, 6, 5,
1113b8f8a0b7SMark Starovoytov 					     ROWOFFSET_INGRESSPOSTCTLFRECORD +
1114b8f8a0b7SMark Starovoytov 						     table_index - 1);
1115b8f8a0b7SMark Starovoytov 		if (unlikely(ret))
1116b8f8a0b7SMark Starovoytov 			return ret;
1117b8f8a0b7SMark Starovoytov 	}
1118b8f8a0b7SMark Starovoytov 
1119b8f8a0b7SMark Starovoytov 	ret = get_raw_ingress_record(hw, packed_record, 6, 5,
1120b8f8a0b7SMark Starovoytov 				     ROWOFFSET_INGRESSPOSTCTLFRECORD +
1121b8f8a0b7SMark Starovoytov 					     table_index);
1122b8f8a0b7SMark Starovoytov 	if (unlikely(ret))
1123b8f8a0b7SMark Starovoytov 		return ret;
1124b8f8a0b7SMark Starovoytov 
1125b8f8a0b7SMark Starovoytov 	rec->sa_da[0] = packed_record[0];
1126b8f8a0b7SMark Starovoytov 	rec->sa_da[0] |= packed_record[1] << 16;
1127b8f8a0b7SMark Starovoytov 
1128b8f8a0b7SMark Starovoytov 	rec->sa_da[1] = packed_record[2];
1129b8f8a0b7SMark Starovoytov 
1130b8f8a0b7SMark Starovoytov 	rec->eth_type = packed_record[3];
1131b8f8a0b7SMark Starovoytov 
1132b8f8a0b7SMark Starovoytov 	rec->match_mask = packed_record[4];
1133b8f8a0b7SMark Starovoytov 
1134b8f8a0b7SMark Starovoytov 	rec->match_type = packed_record[5] & 0xF;
1135b8f8a0b7SMark Starovoytov 
1136b8f8a0b7SMark Starovoytov 	rec->action = (packed_record[5] >> 4) & 0x1;
1137b8f8a0b7SMark Starovoytov 
1138b8f8a0b7SMark Starovoytov 	return 0;
1139b8f8a0b7SMark Starovoytov }
1140b8f8a0b7SMark Starovoytov 
aq_mss_get_ingress_postctlf_record(struct aq_hw_s * hw,struct aq_mss_ingress_postctlf_record * rec,u16 table_index)1141b8f8a0b7SMark Starovoytov int aq_mss_get_ingress_postctlf_record(struct aq_hw_s *hw,
1142b8f8a0b7SMark Starovoytov 	struct aq_mss_ingress_postctlf_record *rec,
1143b8f8a0b7SMark Starovoytov 	u16 table_index)
1144b8f8a0b7SMark Starovoytov {
1145b8f8a0b7SMark Starovoytov 	memset(rec, 0, sizeof(*rec));
1146b8f8a0b7SMark Starovoytov 
1147b8f8a0b7SMark Starovoytov 	return AQ_API_CALL_SAFE(get_ingress_postctlf_record, hw, rec,
1148b8f8a0b7SMark Starovoytov 				table_index);
1149b8f8a0b7SMark Starovoytov }
1150b8f8a0b7SMark Starovoytov 
set_egress_ctlf_record(struct aq_hw_s * hw,const struct aq_mss_egress_ctlf_record * rec,u16 table_index)11519d106c6dSDmitry Bogdanov static int set_egress_ctlf_record(struct aq_hw_s *hw,
11529d106c6dSDmitry Bogdanov 				  const struct aq_mss_egress_ctlf_record *rec,
11539d106c6dSDmitry Bogdanov 				  u16 table_index)
11549d106c6dSDmitry Bogdanov {
11559d106c6dSDmitry Bogdanov 	u16 packed_record[6];
11569d106c6dSDmitry Bogdanov 
11579d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSCTLFRECORD)
11589d106c6dSDmitry Bogdanov 		return -EINVAL;
11599d106c6dSDmitry Bogdanov 
11609d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * 6);
11619d106c6dSDmitry Bogdanov 
11629d106c6dSDmitry Bogdanov 	packed_record[0] = rec->sa_da[0] & 0xFFFF;
11639d106c6dSDmitry Bogdanov 	packed_record[1] = (rec->sa_da[0] >> 16) & 0xFFFF;
11647bb37710SMark Starovoytov 
11659d106c6dSDmitry Bogdanov 	packed_record[2] = rec->sa_da[1] & 0xFFFF;
11669d106c6dSDmitry Bogdanov 
11679d106c6dSDmitry Bogdanov 	packed_record[3] = rec->eth_type & 0xFFFF;
11689d106c6dSDmitry Bogdanov 
11699d106c6dSDmitry Bogdanov 	packed_record[4] = rec->match_mask & 0xFFFF;
11709d106c6dSDmitry Bogdanov 
11719d106c6dSDmitry Bogdanov 	packed_record[5] = rec->match_type & 0xF;
11729d106c6dSDmitry Bogdanov 
11739d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->action & 0x1) << 4;
11749d106c6dSDmitry Bogdanov 
11759d106c6dSDmitry Bogdanov 	return set_raw_egress_record(hw, packed_record, 6, 0,
11769d106c6dSDmitry Bogdanov 				     ROWOFFSET_EGRESSCTLFRECORD + table_index);
11779d106c6dSDmitry Bogdanov }
11789d106c6dSDmitry Bogdanov 
aq_mss_set_egress_ctlf_record(struct aq_hw_s * hw,const struct aq_mss_egress_ctlf_record * rec,u16 table_index)11799d106c6dSDmitry Bogdanov int aq_mss_set_egress_ctlf_record(struct aq_hw_s *hw,
11809d106c6dSDmitry Bogdanov 				  const struct aq_mss_egress_ctlf_record *rec,
11819d106c6dSDmitry Bogdanov 				  u16 table_index)
11829d106c6dSDmitry Bogdanov {
11839d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(set_egress_ctlf_record, hw, rec, table_index);
11849d106c6dSDmitry Bogdanov }
11859d106c6dSDmitry Bogdanov 
get_egress_ctlf_record(struct aq_hw_s * hw,struct aq_mss_egress_ctlf_record * rec,u16 table_index)11869d106c6dSDmitry Bogdanov static int get_egress_ctlf_record(struct aq_hw_s *hw,
11879d106c6dSDmitry Bogdanov 				  struct aq_mss_egress_ctlf_record *rec,
11889d106c6dSDmitry Bogdanov 				  u16 table_index)
11899d106c6dSDmitry Bogdanov {
11909d106c6dSDmitry Bogdanov 	u16 packed_record[6];
11919d106c6dSDmitry Bogdanov 	int ret;
11929d106c6dSDmitry Bogdanov 
11939d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSCTLFRECORD)
11949d106c6dSDmitry Bogdanov 		return -EINVAL;
11959d106c6dSDmitry Bogdanov 
11969d106c6dSDmitry Bogdanov 	/* If the row that we want to read is odd, first read the previous even
11979d106c6dSDmitry Bogdanov 	 * row, throw that value away, and finally read the desired row.
11989d106c6dSDmitry Bogdanov 	 */
11999d106c6dSDmitry Bogdanov 	if ((table_index % 2) > 0) {
12009d106c6dSDmitry Bogdanov 		ret = get_raw_egress_record(hw, packed_record, 6, 0,
12019d106c6dSDmitry Bogdanov 					    ROWOFFSET_EGRESSCTLFRECORD +
12029d106c6dSDmitry Bogdanov 						    table_index - 1);
12039d106c6dSDmitry Bogdanov 		if (unlikely(ret))
12049d106c6dSDmitry Bogdanov 			return ret;
12059d106c6dSDmitry Bogdanov 	}
12069d106c6dSDmitry Bogdanov 
12079d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 6, 0,
12089d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSCTLFRECORD + table_index);
12099d106c6dSDmitry Bogdanov 	if (unlikely(ret))
12109d106c6dSDmitry Bogdanov 		return ret;
12119d106c6dSDmitry Bogdanov 
12129d106c6dSDmitry Bogdanov 	rec->sa_da[0] = packed_record[0];
12139d106c6dSDmitry Bogdanov 	rec->sa_da[0] |= packed_record[1] << 16;
12149d106c6dSDmitry Bogdanov 
12159d106c6dSDmitry Bogdanov 	rec->sa_da[1] = packed_record[2];
12169d106c6dSDmitry Bogdanov 
12179d106c6dSDmitry Bogdanov 	rec->eth_type = packed_record[3];
12189d106c6dSDmitry Bogdanov 
12199d106c6dSDmitry Bogdanov 	rec->match_mask = packed_record[4];
12209d106c6dSDmitry Bogdanov 
12219d106c6dSDmitry Bogdanov 	rec->match_type = packed_record[5] & 0xF;
12229d106c6dSDmitry Bogdanov 
12239d106c6dSDmitry Bogdanov 	rec->action = (packed_record[5] >> 4) & 0x1;
12249d106c6dSDmitry Bogdanov 
12259d106c6dSDmitry Bogdanov 	return 0;
12269d106c6dSDmitry Bogdanov }
12279d106c6dSDmitry Bogdanov 
aq_mss_get_egress_ctlf_record(struct aq_hw_s * hw,struct aq_mss_egress_ctlf_record * rec,u16 table_index)12289d106c6dSDmitry Bogdanov int aq_mss_get_egress_ctlf_record(struct aq_hw_s *hw,
12299d106c6dSDmitry Bogdanov 				  struct aq_mss_egress_ctlf_record *rec,
12309d106c6dSDmitry Bogdanov 				  u16 table_index)
12319d106c6dSDmitry Bogdanov {
12329d106c6dSDmitry Bogdanov 	memset(rec, 0, sizeof(*rec));
12339d106c6dSDmitry Bogdanov 
12349d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_ctlf_record, hw, rec, table_index);
12359d106c6dSDmitry Bogdanov }
12369d106c6dSDmitry Bogdanov 
set_egress_class_record(struct aq_hw_s * hw,const struct aq_mss_egress_class_record * rec,u16 table_index)12379d106c6dSDmitry Bogdanov static int set_egress_class_record(struct aq_hw_s *hw,
12389d106c6dSDmitry Bogdanov 				   const struct aq_mss_egress_class_record *rec,
12399d106c6dSDmitry Bogdanov 				   u16 table_index)
12409d106c6dSDmitry Bogdanov {
12419d106c6dSDmitry Bogdanov 	u16 packed_record[28];
12429d106c6dSDmitry Bogdanov 
12439d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSCLASSRECORD)
12449d106c6dSDmitry Bogdanov 		return -EINVAL;
12459d106c6dSDmitry Bogdanov 
12469d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * 28);
12479d106c6dSDmitry Bogdanov 
12489d106c6dSDmitry Bogdanov 	packed_record[0] = rec->vlan_id & 0xFFF;
12499d106c6dSDmitry Bogdanov 
12509d106c6dSDmitry Bogdanov 	packed_record[0] |= (rec->vlan_up & 0x7) << 12;
12519d106c6dSDmitry Bogdanov 
12529d106c6dSDmitry Bogdanov 	packed_record[0] |= (rec->vlan_valid & 0x1) << 15;
12539d106c6dSDmitry Bogdanov 
12549d106c6dSDmitry Bogdanov 	packed_record[1] = rec->byte3 & 0xFF;
12559d106c6dSDmitry Bogdanov 
12569d106c6dSDmitry Bogdanov 	packed_record[1] |= (rec->byte2 & 0xFF) << 8;
12579d106c6dSDmitry Bogdanov 
12589d106c6dSDmitry Bogdanov 	packed_record[2] = rec->byte1 & 0xFF;
12599d106c6dSDmitry Bogdanov 
12609d106c6dSDmitry Bogdanov 	packed_record[2] |= (rec->byte0 & 0xFF) << 8;
12619d106c6dSDmitry Bogdanov 
12629d106c6dSDmitry Bogdanov 	packed_record[3] = rec->tci & 0xFF;
12639d106c6dSDmitry Bogdanov 
12649d106c6dSDmitry Bogdanov 	packed_record[3] |= (rec->sci[0] & 0xFF) << 8;
12659d106c6dSDmitry Bogdanov 	packed_record[4] = (rec->sci[0] >> 8) & 0xFFFF;
12669d106c6dSDmitry Bogdanov 	packed_record[5] = (rec->sci[0] >> 24) & 0xFF;
12679d106c6dSDmitry Bogdanov 
12689d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->sci[1] & 0xFF) << 8;
12699d106c6dSDmitry Bogdanov 	packed_record[6] = (rec->sci[1] >> 8) & 0xFFFF;
12709d106c6dSDmitry Bogdanov 	packed_record[7] = (rec->sci[1] >> 24) & 0xFF;
12719d106c6dSDmitry Bogdanov 
12729d106c6dSDmitry Bogdanov 	packed_record[7] |= (rec->eth_type & 0xFF) << 8;
12739d106c6dSDmitry Bogdanov 	packed_record[8] = (rec->eth_type >> 8) & 0xFF;
12749d106c6dSDmitry Bogdanov 
12759d106c6dSDmitry Bogdanov 	packed_record[8] |= (rec->snap[0] & 0xFF) << 8;
12769d106c6dSDmitry Bogdanov 	packed_record[9] = (rec->snap[0] >> 8) & 0xFFFF;
12779d106c6dSDmitry Bogdanov 	packed_record[10] = (rec->snap[0] >> 24) & 0xFF;
12789d106c6dSDmitry Bogdanov 
12799d106c6dSDmitry Bogdanov 	packed_record[10] |= (rec->snap[1] & 0xFF) << 8;
12809d106c6dSDmitry Bogdanov 
12819d106c6dSDmitry Bogdanov 	packed_record[11] = rec->llc & 0xFFFF;
12829d106c6dSDmitry Bogdanov 	packed_record[12] = (rec->llc >> 16) & 0xFF;
12839d106c6dSDmitry Bogdanov 
12849d106c6dSDmitry Bogdanov 	packed_record[12] |= (rec->mac_sa[0] & 0xFF) << 8;
12859d106c6dSDmitry Bogdanov 	packed_record[13] = (rec->mac_sa[0] >> 8) & 0xFFFF;
12869d106c6dSDmitry Bogdanov 	packed_record[14] = (rec->mac_sa[0] >> 24) & 0xFF;
12879d106c6dSDmitry Bogdanov 
12889d106c6dSDmitry Bogdanov 	packed_record[14] |= (rec->mac_sa[1] & 0xFF) << 8;
12899d106c6dSDmitry Bogdanov 	packed_record[15] = (rec->mac_sa[1] >> 8) & 0xFF;
12909d106c6dSDmitry Bogdanov 
12919d106c6dSDmitry Bogdanov 	packed_record[15] |= (rec->mac_da[0] & 0xFF) << 8;
12929d106c6dSDmitry Bogdanov 	packed_record[16] = (rec->mac_da[0] >> 8) & 0xFFFF;
12939d106c6dSDmitry Bogdanov 	packed_record[17] = (rec->mac_da[0] >> 24) & 0xFF;
12949d106c6dSDmitry Bogdanov 
12959d106c6dSDmitry Bogdanov 	packed_record[17] |= (rec->mac_da[1] & 0xFF) << 8;
12969d106c6dSDmitry Bogdanov 	packed_record[18] = (rec->mac_da[1] >> 8) & 0xFF;
12979d106c6dSDmitry Bogdanov 
12989d106c6dSDmitry Bogdanov 	packed_record[18] |= (rec->pn & 0xFF) << 8;
12999d106c6dSDmitry Bogdanov 	packed_record[19] = (rec->pn >> 8) & 0xFFFF;
13009d106c6dSDmitry Bogdanov 	packed_record[20] = (rec->pn >> 24) & 0xFF;
13019d106c6dSDmitry Bogdanov 
13029d106c6dSDmitry Bogdanov 	packed_record[20] |= (rec->byte3_location & 0x3F) << 8;
13039d106c6dSDmitry Bogdanov 
13049d106c6dSDmitry Bogdanov 	packed_record[20] |= (rec->byte3_mask & 0x1) << 14;
13059d106c6dSDmitry Bogdanov 
13069d106c6dSDmitry Bogdanov 	packed_record[20] |= (rec->byte2_location & 0x1) << 15;
13079d106c6dSDmitry Bogdanov 	packed_record[21] = (rec->byte2_location >> 1) & 0x1F;
13089d106c6dSDmitry Bogdanov 
13099d106c6dSDmitry Bogdanov 	packed_record[21] |= (rec->byte2_mask & 0x1) << 5;
13109d106c6dSDmitry Bogdanov 
13119d106c6dSDmitry Bogdanov 	packed_record[21] |= (rec->byte1_location & 0x3F) << 6;
13129d106c6dSDmitry Bogdanov 
13139d106c6dSDmitry Bogdanov 	packed_record[21] |= (rec->byte1_mask & 0x1) << 12;
13149d106c6dSDmitry Bogdanov 
13159d106c6dSDmitry Bogdanov 	packed_record[21] |= (rec->byte0_location & 0x7) << 13;
13169d106c6dSDmitry Bogdanov 	packed_record[22] = (rec->byte0_location >> 3) & 0x7;
13179d106c6dSDmitry Bogdanov 
13189d106c6dSDmitry Bogdanov 	packed_record[22] |= (rec->byte0_mask & 0x1) << 3;
13199d106c6dSDmitry Bogdanov 
13209d106c6dSDmitry Bogdanov 	packed_record[22] |= (rec->vlan_id_mask & 0x3) << 4;
13219d106c6dSDmitry Bogdanov 
13229d106c6dSDmitry Bogdanov 	packed_record[22] |= (rec->vlan_up_mask & 0x1) << 6;
13239d106c6dSDmitry Bogdanov 
13249d106c6dSDmitry Bogdanov 	packed_record[22] |= (rec->vlan_valid_mask & 0x1) << 7;
13259d106c6dSDmitry Bogdanov 
13269d106c6dSDmitry Bogdanov 	packed_record[22] |= (rec->tci_mask & 0xFF) << 8;
13279d106c6dSDmitry Bogdanov 
13289d106c6dSDmitry Bogdanov 	packed_record[23] = rec->sci_mask & 0xFF;
13299d106c6dSDmitry Bogdanov 
13309d106c6dSDmitry Bogdanov 	packed_record[23] |= (rec->eth_type_mask & 0x3) << 8;
13319d106c6dSDmitry Bogdanov 
13329d106c6dSDmitry Bogdanov 	packed_record[23] |= (rec->snap_mask & 0x1F) << 10;
13339d106c6dSDmitry Bogdanov 
13349d106c6dSDmitry Bogdanov 	packed_record[23] |= (rec->llc_mask & 0x1) << 15;
13359d106c6dSDmitry Bogdanov 	packed_record[24] = (rec->llc_mask >> 1) & 0x3;
13369d106c6dSDmitry Bogdanov 
13379d106c6dSDmitry Bogdanov 	packed_record[24] |= (rec->sa_mask & 0x3F) << 2;
13389d106c6dSDmitry Bogdanov 
13399d106c6dSDmitry Bogdanov 	packed_record[24] |= (rec->da_mask & 0x3F) << 8;
13409d106c6dSDmitry Bogdanov 
13419d106c6dSDmitry Bogdanov 	packed_record[24] |= (rec->pn_mask & 0x3) << 14;
13429d106c6dSDmitry Bogdanov 	packed_record[25] = (rec->pn_mask >> 2) & 0x3;
13439d106c6dSDmitry Bogdanov 
13449d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->eight02dot2 & 0x1) << 2;
13459d106c6dSDmitry Bogdanov 
13469d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->tci_sc & 0x1) << 3;
13479d106c6dSDmitry Bogdanov 
13489d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->tci_87543 & 0x1) << 4;
13499d106c6dSDmitry Bogdanov 
13509d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->exp_sectag_en & 0x1) << 5;
13519d106c6dSDmitry Bogdanov 
13529d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->sc_idx & 0x1F) << 6;
13539d106c6dSDmitry Bogdanov 
13549d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->sc_sa & 0x3) << 11;
13559d106c6dSDmitry Bogdanov 
13569d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->debug & 0x1) << 13;
13579d106c6dSDmitry Bogdanov 
13589d106c6dSDmitry Bogdanov 	packed_record[25] |= (rec->action & 0x3) << 14;
13599d106c6dSDmitry Bogdanov 
13609d106c6dSDmitry Bogdanov 	packed_record[26] = (rec->valid & 0x1) << 3;
13619d106c6dSDmitry Bogdanov 
13629d106c6dSDmitry Bogdanov 	return set_raw_egress_record(hw, packed_record, 28, 1,
13639d106c6dSDmitry Bogdanov 				     ROWOFFSET_EGRESSCLASSRECORD + table_index);
13649d106c6dSDmitry Bogdanov }
13659d106c6dSDmitry Bogdanov 
aq_mss_set_egress_class_record(struct aq_hw_s * hw,const struct aq_mss_egress_class_record * rec,u16 table_index)13669d106c6dSDmitry Bogdanov int aq_mss_set_egress_class_record(struct aq_hw_s *hw,
13679d106c6dSDmitry Bogdanov 				   const struct aq_mss_egress_class_record *rec,
13689d106c6dSDmitry Bogdanov 				   u16 table_index)
13699d106c6dSDmitry Bogdanov {
13709d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(set_egress_class_record, hw, rec, table_index);
13719d106c6dSDmitry Bogdanov }
13729d106c6dSDmitry Bogdanov 
get_egress_class_record(struct aq_hw_s * hw,struct aq_mss_egress_class_record * rec,u16 table_index)13739d106c6dSDmitry Bogdanov static int get_egress_class_record(struct aq_hw_s *hw,
13749d106c6dSDmitry Bogdanov 				   struct aq_mss_egress_class_record *rec,
13759d106c6dSDmitry Bogdanov 				   u16 table_index)
13769d106c6dSDmitry Bogdanov {
13779d106c6dSDmitry Bogdanov 	u16 packed_record[28];
13789d106c6dSDmitry Bogdanov 	int ret;
13799d106c6dSDmitry Bogdanov 
13809d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSCLASSRECORD)
13819d106c6dSDmitry Bogdanov 		return -EINVAL;
13829d106c6dSDmitry Bogdanov 
13839d106c6dSDmitry Bogdanov 	/* If the row that we want to read is odd, first read the previous even
13849d106c6dSDmitry Bogdanov 	 * row, throw that value away, and finally read the desired row.
13859d106c6dSDmitry Bogdanov 	 */
13869d106c6dSDmitry Bogdanov 	if ((table_index % 2) > 0) {
13879d106c6dSDmitry Bogdanov 		ret = get_raw_egress_record(hw, packed_record, 28, 1,
13889d106c6dSDmitry Bogdanov 					    ROWOFFSET_EGRESSCLASSRECORD +
13899d106c6dSDmitry Bogdanov 						    table_index - 1);
13909d106c6dSDmitry Bogdanov 		if (unlikely(ret))
13919d106c6dSDmitry Bogdanov 			return ret;
13929d106c6dSDmitry Bogdanov 	}
13939d106c6dSDmitry Bogdanov 
13949d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 28, 1,
13959d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSCLASSRECORD + table_index);
13969d106c6dSDmitry Bogdanov 	if (unlikely(ret))
13979d106c6dSDmitry Bogdanov 		return ret;
13989d106c6dSDmitry Bogdanov 
13999d106c6dSDmitry Bogdanov 	rec->vlan_id = packed_record[0] & 0xFFF;
14009d106c6dSDmitry Bogdanov 
14019d106c6dSDmitry Bogdanov 	rec->vlan_up = (packed_record[0] >> 12) & 0x7;
14029d106c6dSDmitry Bogdanov 
14039d106c6dSDmitry Bogdanov 	rec->vlan_valid = (packed_record[0] >> 15) & 0x1;
14049d106c6dSDmitry Bogdanov 
14059d106c6dSDmitry Bogdanov 	rec->byte3 = packed_record[1] & 0xFF;
14069d106c6dSDmitry Bogdanov 
14079d106c6dSDmitry Bogdanov 	rec->byte2 = (packed_record[1] >> 8) & 0xFF;
14089d106c6dSDmitry Bogdanov 
14099d106c6dSDmitry Bogdanov 	rec->byte1 = packed_record[2] & 0xFF;
14109d106c6dSDmitry Bogdanov 
14119d106c6dSDmitry Bogdanov 	rec->byte0 = (packed_record[2] >> 8) & 0xFF;
14129d106c6dSDmitry Bogdanov 
14139d106c6dSDmitry Bogdanov 	rec->tci = packed_record[3] & 0xFF;
14149d106c6dSDmitry Bogdanov 
14159d106c6dSDmitry Bogdanov 	rec->sci[0] = (packed_record[3] >> 8) & 0xFF;
14169d106c6dSDmitry Bogdanov 	rec->sci[0] |= packed_record[4] << 8;
14179d106c6dSDmitry Bogdanov 	rec->sci[0] |= (packed_record[5] & 0xFF) << 24;
14189d106c6dSDmitry Bogdanov 
14199d106c6dSDmitry Bogdanov 	rec->sci[1] = (packed_record[5] >> 8) & 0xFF;
14209d106c6dSDmitry Bogdanov 	rec->sci[1] |= packed_record[6] << 8;
14219d106c6dSDmitry Bogdanov 	rec->sci[1] |= (packed_record[7] & 0xFF) << 24;
14229d106c6dSDmitry Bogdanov 
14239d106c6dSDmitry Bogdanov 	rec->eth_type = (packed_record[7] >> 8) & 0xFF;
14249d106c6dSDmitry Bogdanov 	rec->eth_type |= (packed_record[8] & 0xFF) << 8;
14259d106c6dSDmitry Bogdanov 
14269d106c6dSDmitry Bogdanov 	rec->snap[0] = (packed_record[8] >> 8) & 0xFF;
14279d106c6dSDmitry Bogdanov 	rec->snap[0] |= packed_record[9] << 8;
14289d106c6dSDmitry Bogdanov 	rec->snap[0] |= (packed_record[10] & 0xFF) << 24;
14299d106c6dSDmitry Bogdanov 
14309d106c6dSDmitry Bogdanov 	rec->snap[1] = (packed_record[10] >> 8) & 0xFF;
14319d106c6dSDmitry Bogdanov 
14329d106c6dSDmitry Bogdanov 	rec->llc = packed_record[11];
14339d106c6dSDmitry Bogdanov 	rec->llc |= (packed_record[12] & 0xFF) << 16;
14349d106c6dSDmitry Bogdanov 
14359d106c6dSDmitry Bogdanov 	rec->mac_sa[0] = (packed_record[12] >> 8) & 0xFF;
14369d106c6dSDmitry Bogdanov 	rec->mac_sa[0] |= packed_record[13] << 8;
14379d106c6dSDmitry Bogdanov 	rec->mac_sa[0] |= (packed_record[14] & 0xFF) << 24;
14389d106c6dSDmitry Bogdanov 
14399d106c6dSDmitry Bogdanov 	rec->mac_sa[1] = (packed_record[14] >> 8) & 0xFF;
14409d106c6dSDmitry Bogdanov 	rec->mac_sa[1] |= (packed_record[15] & 0xFF) << 8;
14419d106c6dSDmitry Bogdanov 
14429d106c6dSDmitry Bogdanov 	rec->mac_da[0] = (packed_record[15] >> 8) & 0xFF;
14439d106c6dSDmitry Bogdanov 	rec->mac_da[0] |= packed_record[16] << 8;
14449d106c6dSDmitry Bogdanov 	rec->mac_da[0] |= (packed_record[17] & 0xFF) << 24;
14459d106c6dSDmitry Bogdanov 
14469d106c6dSDmitry Bogdanov 	rec->mac_da[1] = (packed_record[17] >> 8) & 0xFF;
14479d106c6dSDmitry Bogdanov 	rec->mac_da[1] |= (packed_record[18] & 0xFF) << 8;
14489d106c6dSDmitry Bogdanov 
14499d106c6dSDmitry Bogdanov 	rec->pn = (packed_record[18] >> 8) & 0xFF;
14509d106c6dSDmitry Bogdanov 	rec->pn |= packed_record[19] << 8;
14519d106c6dSDmitry Bogdanov 	rec->pn |= (packed_record[20] & 0xFF) << 24;
14529d106c6dSDmitry Bogdanov 
14539d106c6dSDmitry Bogdanov 	rec->byte3_location = (packed_record[20] >> 8) & 0x3F;
14549d106c6dSDmitry Bogdanov 
14559d106c6dSDmitry Bogdanov 	rec->byte3_mask = (packed_record[20] >> 14) & 0x1;
14569d106c6dSDmitry Bogdanov 
14579d106c6dSDmitry Bogdanov 	rec->byte2_location = (packed_record[20] >> 15) & 0x1;
14589d106c6dSDmitry Bogdanov 	rec->byte2_location |= (packed_record[21] & 0x1F) << 1;
14599d106c6dSDmitry Bogdanov 
14609d106c6dSDmitry Bogdanov 	rec->byte2_mask = (packed_record[21] >> 5) & 0x1;
14619d106c6dSDmitry Bogdanov 
14629d106c6dSDmitry Bogdanov 	rec->byte1_location = (packed_record[21] >> 6) & 0x3F;
14639d106c6dSDmitry Bogdanov 
14649d106c6dSDmitry Bogdanov 	rec->byte1_mask = (packed_record[21] >> 12) & 0x1;
14659d106c6dSDmitry Bogdanov 
14669d106c6dSDmitry Bogdanov 	rec->byte0_location = (packed_record[21] >> 13) & 0x7;
14679d106c6dSDmitry Bogdanov 	rec->byte0_location |= (packed_record[22] & 0x7) << 3;
14689d106c6dSDmitry Bogdanov 
14699d106c6dSDmitry Bogdanov 	rec->byte0_mask = (packed_record[22] >> 3) & 0x1;
14709d106c6dSDmitry Bogdanov 
14719d106c6dSDmitry Bogdanov 	rec->vlan_id_mask = (packed_record[22] >> 4) & 0x3;
14729d106c6dSDmitry Bogdanov 
14739d106c6dSDmitry Bogdanov 	rec->vlan_up_mask = (packed_record[22] >> 6) & 0x1;
14749d106c6dSDmitry Bogdanov 
14759d106c6dSDmitry Bogdanov 	rec->vlan_valid_mask = (packed_record[22] >> 7) & 0x1;
14769d106c6dSDmitry Bogdanov 
14779d106c6dSDmitry Bogdanov 	rec->tci_mask = (packed_record[22] >> 8) & 0xFF;
14789d106c6dSDmitry Bogdanov 
14799d106c6dSDmitry Bogdanov 	rec->sci_mask = packed_record[23] & 0xFF;
14809d106c6dSDmitry Bogdanov 
14819d106c6dSDmitry Bogdanov 	rec->eth_type_mask = (packed_record[23] >> 8) & 0x3;
14829d106c6dSDmitry Bogdanov 
14839d106c6dSDmitry Bogdanov 	rec->snap_mask = (packed_record[23] >> 10) & 0x1F;
14849d106c6dSDmitry Bogdanov 
14859d106c6dSDmitry Bogdanov 	rec->llc_mask = (packed_record[23] >> 15) & 0x1;
14869d106c6dSDmitry Bogdanov 	rec->llc_mask |= (packed_record[24] & 0x3) << 1;
14879d106c6dSDmitry Bogdanov 
14889d106c6dSDmitry Bogdanov 	rec->sa_mask = (packed_record[24] >> 2) & 0x3F;
14899d106c6dSDmitry Bogdanov 
14909d106c6dSDmitry Bogdanov 	rec->da_mask = (packed_record[24] >> 8) & 0x3F;
14919d106c6dSDmitry Bogdanov 
14929d106c6dSDmitry Bogdanov 	rec->pn_mask = (packed_record[24] >> 14) & 0x3;
14939d106c6dSDmitry Bogdanov 	rec->pn_mask |= (packed_record[25] & 0x3) << 2;
14949d106c6dSDmitry Bogdanov 
14959d106c6dSDmitry Bogdanov 	rec->eight02dot2 = (packed_record[25] >> 2) & 0x1;
14969d106c6dSDmitry Bogdanov 
14979d106c6dSDmitry Bogdanov 	rec->tci_sc = (packed_record[25] >> 3) & 0x1;
14989d106c6dSDmitry Bogdanov 
14999d106c6dSDmitry Bogdanov 	rec->tci_87543 = (packed_record[25] >> 4) & 0x1;
15009d106c6dSDmitry Bogdanov 
15019d106c6dSDmitry Bogdanov 	rec->exp_sectag_en = (packed_record[25] >> 5) & 0x1;
15029d106c6dSDmitry Bogdanov 
15039d106c6dSDmitry Bogdanov 	rec->sc_idx = (packed_record[25] >> 6) & 0x1F;
15049d106c6dSDmitry Bogdanov 
15059d106c6dSDmitry Bogdanov 	rec->sc_sa = (packed_record[25] >> 11) & 0x3;
15069d106c6dSDmitry Bogdanov 
15079d106c6dSDmitry Bogdanov 	rec->debug = (packed_record[25] >> 13) & 0x1;
15089d106c6dSDmitry Bogdanov 
15099d106c6dSDmitry Bogdanov 	rec->action = (packed_record[25] >> 14) & 0x3;
15109d106c6dSDmitry Bogdanov 
15119d106c6dSDmitry Bogdanov 	rec->valid = (packed_record[26] >> 3) & 0x1;
15129d106c6dSDmitry Bogdanov 
15139d106c6dSDmitry Bogdanov 	return 0;
15149d106c6dSDmitry Bogdanov }
15159d106c6dSDmitry Bogdanov 
aq_mss_get_egress_class_record(struct aq_hw_s * hw,struct aq_mss_egress_class_record * rec,u16 table_index)15169d106c6dSDmitry Bogdanov int aq_mss_get_egress_class_record(struct aq_hw_s *hw,
15179d106c6dSDmitry Bogdanov 				   struct aq_mss_egress_class_record *rec,
15189d106c6dSDmitry Bogdanov 				   u16 table_index)
15199d106c6dSDmitry Bogdanov {
15209d106c6dSDmitry Bogdanov 	memset(rec, 0, sizeof(*rec));
15219d106c6dSDmitry Bogdanov 
15229d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_class_record, hw, rec, table_index);
15239d106c6dSDmitry Bogdanov }
15249d106c6dSDmitry Bogdanov 
set_egress_sc_record(struct aq_hw_s * hw,const struct aq_mss_egress_sc_record * rec,u16 table_index)15259d106c6dSDmitry Bogdanov static int set_egress_sc_record(struct aq_hw_s *hw,
15269d106c6dSDmitry Bogdanov 				const struct aq_mss_egress_sc_record *rec,
15279d106c6dSDmitry Bogdanov 				u16 table_index)
15289d106c6dSDmitry Bogdanov {
15299d106c6dSDmitry Bogdanov 	u16 packed_record[8];
15309d106c6dSDmitry Bogdanov 
15319d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSCRECORD)
15329d106c6dSDmitry Bogdanov 		return -EINVAL;
15339d106c6dSDmitry Bogdanov 
15349d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * 8);
15359d106c6dSDmitry Bogdanov 
15369d106c6dSDmitry Bogdanov 	packed_record[0] = rec->start_time & 0xFFFF;
15379d106c6dSDmitry Bogdanov 	packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
15389d106c6dSDmitry Bogdanov 
15399d106c6dSDmitry Bogdanov 	packed_record[2] = rec->stop_time & 0xFFFF;
15409d106c6dSDmitry Bogdanov 	packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
15419d106c6dSDmitry Bogdanov 
15429d106c6dSDmitry Bogdanov 	packed_record[4] = rec->curr_an & 0x3;
15439d106c6dSDmitry Bogdanov 
15449d106c6dSDmitry Bogdanov 	packed_record[4] |= (rec->an_roll & 0x1) << 2;
15459d106c6dSDmitry Bogdanov 
15469d106c6dSDmitry Bogdanov 	packed_record[4] |= (rec->tci & 0x3F) << 3;
15479d106c6dSDmitry Bogdanov 
15489d106c6dSDmitry Bogdanov 	packed_record[4] |= (rec->enc_off & 0x7F) << 9;
15499d106c6dSDmitry Bogdanov 	packed_record[5] = (rec->enc_off >> 7) & 0x1;
15509d106c6dSDmitry Bogdanov 
15519d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->protect & 0x1) << 1;
15529d106c6dSDmitry Bogdanov 
15539d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->recv & 0x1) << 2;
15549d106c6dSDmitry Bogdanov 
15559d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->fresh & 0x1) << 3;
15569d106c6dSDmitry Bogdanov 
15579d106c6dSDmitry Bogdanov 	packed_record[5] |= (rec->sak_len & 0x3) << 4;
15589d106c6dSDmitry Bogdanov 
15597bb37710SMark Starovoytov 	packed_record[7] = (rec->valid & 0x1) << 15;
15609d106c6dSDmitry Bogdanov 
15619d106c6dSDmitry Bogdanov 	return set_raw_egress_record(hw, packed_record, 8, 2,
15629d106c6dSDmitry Bogdanov 				     ROWOFFSET_EGRESSSCRECORD + table_index);
15639d106c6dSDmitry Bogdanov }
15649d106c6dSDmitry Bogdanov 
aq_mss_set_egress_sc_record(struct aq_hw_s * hw,const struct aq_mss_egress_sc_record * rec,u16 table_index)15659d106c6dSDmitry Bogdanov int aq_mss_set_egress_sc_record(struct aq_hw_s *hw,
15669d106c6dSDmitry Bogdanov 				const struct aq_mss_egress_sc_record *rec,
15679d106c6dSDmitry Bogdanov 				u16 table_index)
15689d106c6dSDmitry Bogdanov {
15699d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(set_egress_sc_record, hw, rec, table_index);
15709d106c6dSDmitry Bogdanov }
15719d106c6dSDmitry Bogdanov 
get_egress_sc_record(struct aq_hw_s * hw,struct aq_mss_egress_sc_record * rec,u16 table_index)15729d106c6dSDmitry Bogdanov static int get_egress_sc_record(struct aq_hw_s *hw,
15739d106c6dSDmitry Bogdanov 				struct aq_mss_egress_sc_record *rec,
15749d106c6dSDmitry Bogdanov 				u16 table_index)
15759d106c6dSDmitry Bogdanov {
15769d106c6dSDmitry Bogdanov 	u16 packed_record[8];
15779d106c6dSDmitry Bogdanov 	int ret;
15789d106c6dSDmitry Bogdanov 
15799d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSCRECORD)
15809d106c6dSDmitry Bogdanov 		return -EINVAL;
15819d106c6dSDmitry Bogdanov 
15829d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 8, 2,
15839d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSCRECORD + table_index);
15849d106c6dSDmitry Bogdanov 	if (unlikely(ret))
15859d106c6dSDmitry Bogdanov 		return ret;
15869d106c6dSDmitry Bogdanov 
15879d106c6dSDmitry Bogdanov 	rec->start_time = packed_record[0];
15889d106c6dSDmitry Bogdanov 	rec->start_time |= packed_record[1] << 16;
15899d106c6dSDmitry Bogdanov 
15909d106c6dSDmitry Bogdanov 	rec->stop_time = packed_record[2];
15919d106c6dSDmitry Bogdanov 	rec->stop_time |= packed_record[3] << 16;
15929d106c6dSDmitry Bogdanov 
15939d106c6dSDmitry Bogdanov 	rec->curr_an = packed_record[4] & 0x3;
15949d106c6dSDmitry Bogdanov 
15959d106c6dSDmitry Bogdanov 	rec->an_roll = (packed_record[4] >> 2) & 0x1;
15969d106c6dSDmitry Bogdanov 
15979d106c6dSDmitry Bogdanov 	rec->tci = (packed_record[4] >> 3) & 0x3F;
15989d106c6dSDmitry Bogdanov 
15999d106c6dSDmitry Bogdanov 	rec->enc_off = (packed_record[4] >> 9) & 0x7F;
16009d106c6dSDmitry Bogdanov 	rec->enc_off |= (packed_record[5] & 0x1) << 7;
16019d106c6dSDmitry Bogdanov 
16029d106c6dSDmitry Bogdanov 	rec->protect = (packed_record[5] >> 1) & 0x1;
16039d106c6dSDmitry Bogdanov 
16049d106c6dSDmitry Bogdanov 	rec->recv = (packed_record[5] >> 2) & 0x1;
16059d106c6dSDmitry Bogdanov 
16069d106c6dSDmitry Bogdanov 	rec->fresh = (packed_record[5] >> 3) & 0x1;
16079d106c6dSDmitry Bogdanov 
16089d106c6dSDmitry Bogdanov 	rec->sak_len = (packed_record[5] >> 4) & 0x3;
16099d106c6dSDmitry Bogdanov 
16109d106c6dSDmitry Bogdanov 	rec->valid = (packed_record[7] >> 15) & 0x1;
16119d106c6dSDmitry Bogdanov 
16129d106c6dSDmitry Bogdanov 	return 0;
16139d106c6dSDmitry Bogdanov }
16149d106c6dSDmitry Bogdanov 
aq_mss_get_egress_sc_record(struct aq_hw_s * hw,struct aq_mss_egress_sc_record * rec,u16 table_index)16159d106c6dSDmitry Bogdanov int aq_mss_get_egress_sc_record(struct aq_hw_s *hw,
16169d106c6dSDmitry Bogdanov 				struct aq_mss_egress_sc_record *rec,
16179d106c6dSDmitry Bogdanov 				u16 table_index)
16189d106c6dSDmitry Bogdanov {
16199d106c6dSDmitry Bogdanov 	memset(rec, 0, sizeof(*rec));
16209d106c6dSDmitry Bogdanov 
16219d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sc_record, hw, rec, table_index);
16229d106c6dSDmitry Bogdanov }
16239d106c6dSDmitry Bogdanov 
set_egress_sa_record(struct aq_hw_s * hw,const struct aq_mss_egress_sa_record * rec,u16 table_index)16249d106c6dSDmitry Bogdanov static int set_egress_sa_record(struct aq_hw_s *hw,
16259d106c6dSDmitry Bogdanov 				const struct aq_mss_egress_sa_record *rec,
16269d106c6dSDmitry Bogdanov 				u16 table_index)
16279d106c6dSDmitry Bogdanov {
16289d106c6dSDmitry Bogdanov 	u16 packed_record[8];
16299d106c6dSDmitry Bogdanov 
16309d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSARECORD)
16319d106c6dSDmitry Bogdanov 		return -EINVAL;
16329d106c6dSDmitry Bogdanov 
16339d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * 8);
16349d106c6dSDmitry Bogdanov 
16359d106c6dSDmitry Bogdanov 	packed_record[0] = rec->start_time & 0xFFFF;
16369d106c6dSDmitry Bogdanov 	packed_record[1] = (rec->start_time >> 16) & 0xFFFF;
16379d106c6dSDmitry Bogdanov 
16389d106c6dSDmitry Bogdanov 	packed_record[2] = rec->stop_time & 0xFFFF;
16399d106c6dSDmitry Bogdanov 	packed_record[3] = (rec->stop_time >> 16) & 0xFFFF;
16409d106c6dSDmitry Bogdanov 
16419d106c6dSDmitry Bogdanov 	packed_record[4] = rec->next_pn & 0xFFFF;
16429d106c6dSDmitry Bogdanov 	packed_record[5] = (rec->next_pn >> 16) & 0xFFFF;
16439d106c6dSDmitry Bogdanov 
16449d106c6dSDmitry Bogdanov 	packed_record[6] = rec->sat_pn & 0x1;
16459d106c6dSDmitry Bogdanov 
16469d106c6dSDmitry Bogdanov 	packed_record[6] |= (rec->fresh & 0x1) << 1;
16479d106c6dSDmitry Bogdanov 
16489d106c6dSDmitry Bogdanov 	packed_record[7] = (rec->valid & 0x1) << 15;
16499d106c6dSDmitry Bogdanov 
16509d106c6dSDmitry Bogdanov 	return set_raw_egress_record(hw, packed_record, 8, 2,
16519d106c6dSDmitry Bogdanov 				     ROWOFFSET_EGRESSSARECORD + table_index);
16529d106c6dSDmitry Bogdanov }
16539d106c6dSDmitry Bogdanov 
aq_mss_set_egress_sa_record(struct aq_hw_s * hw,const struct aq_mss_egress_sa_record * rec,u16 table_index)16549d106c6dSDmitry Bogdanov int aq_mss_set_egress_sa_record(struct aq_hw_s *hw,
16559d106c6dSDmitry Bogdanov 				const struct aq_mss_egress_sa_record *rec,
16569d106c6dSDmitry Bogdanov 				u16 table_index)
16579d106c6dSDmitry Bogdanov {
16589d106c6dSDmitry Bogdanov 	int err = AQ_API_CALL_SAFE(set_egress_sa_record, hw, rec, table_index);
16599d106c6dSDmitry Bogdanov 
16609d106c6dSDmitry Bogdanov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
16619d106c6dSDmitry Bogdanov 
16629d106c6dSDmitry Bogdanov 	return err;
16639d106c6dSDmitry Bogdanov }
16649d106c6dSDmitry Bogdanov 
get_egress_sa_record(struct aq_hw_s * hw,struct aq_mss_egress_sa_record * rec,u16 table_index)16659d106c6dSDmitry Bogdanov static int get_egress_sa_record(struct aq_hw_s *hw,
16669d106c6dSDmitry Bogdanov 				struct aq_mss_egress_sa_record *rec,
16679d106c6dSDmitry Bogdanov 				u16 table_index)
16689d106c6dSDmitry Bogdanov {
16699d106c6dSDmitry Bogdanov 	u16 packed_record[8];
16709d106c6dSDmitry Bogdanov 	int ret;
16719d106c6dSDmitry Bogdanov 
16729d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSARECORD)
16739d106c6dSDmitry Bogdanov 		return -EINVAL;
16749d106c6dSDmitry Bogdanov 
16759d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 8, 2,
16769d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSARECORD + table_index);
16779d106c6dSDmitry Bogdanov 	if (unlikely(ret))
16789d106c6dSDmitry Bogdanov 		return ret;
16799d106c6dSDmitry Bogdanov 
16809d106c6dSDmitry Bogdanov 	rec->start_time = packed_record[0];
16819d106c6dSDmitry Bogdanov 	rec->start_time |= packed_record[1] << 16;
16829d106c6dSDmitry Bogdanov 
16839d106c6dSDmitry Bogdanov 	rec->stop_time = packed_record[2];
16849d106c6dSDmitry Bogdanov 	rec->stop_time |= packed_record[3] << 16;
16859d106c6dSDmitry Bogdanov 
16869d106c6dSDmitry Bogdanov 	rec->next_pn = packed_record[4];
16879d106c6dSDmitry Bogdanov 	rec->next_pn |= packed_record[5] << 16;
16889d106c6dSDmitry Bogdanov 
16899d106c6dSDmitry Bogdanov 	rec->sat_pn = packed_record[6] & 0x1;
16909d106c6dSDmitry Bogdanov 
16919d106c6dSDmitry Bogdanov 	rec->fresh = (packed_record[6] >> 1) & 0x1;
16929d106c6dSDmitry Bogdanov 
16939d106c6dSDmitry Bogdanov 	rec->valid = (packed_record[7] >> 15) & 0x1;
16949d106c6dSDmitry Bogdanov 
16959d106c6dSDmitry Bogdanov 	return 0;
16969d106c6dSDmitry Bogdanov }
16979d106c6dSDmitry Bogdanov 
aq_mss_get_egress_sa_record(struct aq_hw_s * hw,struct aq_mss_egress_sa_record * rec,u16 table_index)16989d106c6dSDmitry Bogdanov int aq_mss_get_egress_sa_record(struct aq_hw_s *hw,
16999d106c6dSDmitry Bogdanov 				struct aq_mss_egress_sa_record *rec,
17009d106c6dSDmitry Bogdanov 				u16 table_index)
17019d106c6dSDmitry Bogdanov {
17029d106c6dSDmitry Bogdanov 	memset(rec, 0, sizeof(*rec));
17039d106c6dSDmitry Bogdanov 
17049d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sa_record, hw, rec, table_index);
17059d106c6dSDmitry Bogdanov }
17069d106c6dSDmitry Bogdanov 
set_egress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_egress_sakey_record * rec,u16 table_index)17079d106c6dSDmitry Bogdanov static int set_egress_sakey_record(struct aq_hw_s *hw,
17089d106c6dSDmitry Bogdanov 				   const struct aq_mss_egress_sakey_record *rec,
17099d106c6dSDmitry Bogdanov 				   u16 table_index)
17109d106c6dSDmitry Bogdanov {
17119d106c6dSDmitry Bogdanov 	u16 packed_record[16];
17129d106c6dSDmitry Bogdanov 	int ret;
17139d106c6dSDmitry Bogdanov 
17149d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
17159d106c6dSDmitry Bogdanov 		return -EINVAL;
17169d106c6dSDmitry Bogdanov 
17179d106c6dSDmitry Bogdanov 	memset(packed_record, 0, sizeof(u16) * 16);
17189d106c6dSDmitry Bogdanov 
17199d106c6dSDmitry Bogdanov 	packed_record[0] = rec->key[0] & 0xFFFF;
17209d106c6dSDmitry Bogdanov 	packed_record[1] = (rec->key[0] >> 16) & 0xFFFF;
17219d106c6dSDmitry Bogdanov 
17229d106c6dSDmitry Bogdanov 	packed_record[2] = rec->key[1] & 0xFFFF;
17239d106c6dSDmitry Bogdanov 	packed_record[3] = (rec->key[1] >> 16) & 0xFFFF;
17249d106c6dSDmitry Bogdanov 
17259d106c6dSDmitry Bogdanov 	packed_record[4] = rec->key[2] & 0xFFFF;
17269d106c6dSDmitry Bogdanov 	packed_record[5] = (rec->key[2] >> 16) & 0xFFFF;
17279d106c6dSDmitry Bogdanov 
17289d106c6dSDmitry Bogdanov 	packed_record[6] = rec->key[3] & 0xFFFF;
17299d106c6dSDmitry Bogdanov 	packed_record[7] = (rec->key[3] >> 16) & 0xFFFF;
17309d106c6dSDmitry Bogdanov 
17319d106c6dSDmitry Bogdanov 	packed_record[8] = rec->key[4] & 0xFFFF;
17329d106c6dSDmitry Bogdanov 	packed_record[9] = (rec->key[4] >> 16) & 0xFFFF;
17339d106c6dSDmitry Bogdanov 
17349d106c6dSDmitry Bogdanov 	packed_record[10] = rec->key[5] & 0xFFFF;
17359d106c6dSDmitry Bogdanov 	packed_record[11] = (rec->key[5] >> 16) & 0xFFFF;
17369d106c6dSDmitry Bogdanov 
17379d106c6dSDmitry Bogdanov 	packed_record[12] = rec->key[6] & 0xFFFF;
17389d106c6dSDmitry Bogdanov 	packed_record[13] = (rec->key[6] >> 16) & 0xFFFF;
17399d106c6dSDmitry Bogdanov 
17409d106c6dSDmitry Bogdanov 	packed_record[14] = rec->key[7] & 0xFFFF;
17419d106c6dSDmitry Bogdanov 	packed_record[15] = (rec->key[7] >> 16) & 0xFFFF;
17429d106c6dSDmitry Bogdanov 
17439d106c6dSDmitry Bogdanov 	ret = set_raw_egress_record(hw, packed_record, 8, 2,
17449d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index);
17459d106c6dSDmitry Bogdanov 	if (unlikely(ret))
17463652f1f8SAntoine Tenart 		goto clear_key;
17479d106c6dSDmitry Bogdanov 	ret = set_raw_egress_record(hw, packed_record + 8, 8, 2,
17489d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index -
17499d106c6dSDmitry Bogdanov 					    32);
17509d106c6dSDmitry Bogdanov 
17513652f1f8SAntoine Tenart clear_key:
17523652f1f8SAntoine Tenart 	memzero_explicit(packed_record, sizeof(packed_record));
17533652f1f8SAntoine Tenart 	return ret;
17549d106c6dSDmitry Bogdanov }
17559d106c6dSDmitry Bogdanov 
aq_mss_set_egress_sakey_record(struct aq_hw_s * hw,const struct aq_mss_egress_sakey_record * rec,u16 table_index)17569d106c6dSDmitry Bogdanov int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw,
17579d106c6dSDmitry Bogdanov 				   const struct aq_mss_egress_sakey_record *rec,
17589d106c6dSDmitry Bogdanov 				   u16 table_index)
17599d106c6dSDmitry Bogdanov {
17609d106c6dSDmitry Bogdanov 	int err = AQ_API_CALL_SAFE(set_egress_sakey_record, hw, rec,
17619d106c6dSDmitry Bogdanov 				   table_index);
17629d106c6dSDmitry Bogdanov 
17639d106c6dSDmitry Bogdanov 	WARN_ONCE(err, "%s failed with %d\n", __func__, err);
17649d106c6dSDmitry Bogdanov 
17659d106c6dSDmitry Bogdanov 	return err;
17669d106c6dSDmitry Bogdanov }
17679d106c6dSDmitry Bogdanov 
get_egress_sakey_record(struct aq_hw_s * hw,struct aq_mss_egress_sakey_record * rec,u16 table_index)17689d106c6dSDmitry Bogdanov static int get_egress_sakey_record(struct aq_hw_s *hw,
17699d106c6dSDmitry Bogdanov 				   struct aq_mss_egress_sakey_record *rec,
17709d106c6dSDmitry Bogdanov 				   u16 table_index)
17719d106c6dSDmitry Bogdanov {
17729d106c6dSDmitry Bogdanov 	u16 packed_record[16];
17739d106c6dSDmitry Bogdanov 	int ret;
17749d106c6dSDmitry Bogdanov 
17759d106c6dSDmitry Bogdanov 	if (table_index >= NUMROWS_EGRESSSAKEYRECORD)
17769d106c6dSDmitry Bogdanov 		return -EINVAL;
17779d106c6dSDmitry Bogdanov 
17789d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 8, 2,
17799d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index);
17809d106c6dSDmitry Bogdanov 	if (unlikely(ret))
17819d106c6dSDmitry Bogdanov 		return ret;
17829d106c6dSDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record + 8, 8, 2,
17839d106c6dSDmitry Bogdanov 				    ROWOFFSET_EGRESSSAKEYRECORD + table_index -
17849d106c6dSDmitry Bogdanov 					    32);
17859d106c6dSDmitry Bogdanov 	if (unlikely(ret))
17869d106c6dSDmitry Bogdanov 		return ret;
17879d106c6dSDmitry Bogdanov 
17889d106c6dSDmitry Bogdanov 	rec->key[0] = packed_record[0];
17899d106c6dSDmitry Bogdanov 	rec->key[0] |= packed_record[1] << 16;
17909d106c6dSDmitry Bogdanov 
17919d106c6dSDmitry Bogdanov 	rec->key[1] = packed_record[2];
17929d106c6dSDmitry Bogdanov 	rec->key[1] |= packed_record[3] << 16;
17939d106c6dSDmitry Bogdanov 
17949d106c6dSDmitry Bogdanov 	rec->key[2] = packed_record[4];
17959d106c6dSDmitry Bogdanov 	rec->key[2] |= packed_record[5] << 16;
17969d106c6dSDmitry Bogdanov 
17979d106c6dSDmitry Bogdanov 	rec->key[3] = packed_record[6];
17989d106c6dSDmitry Bogdanov 	rec->key[3] |= packed_record[7] << 16;
17999d106c6dSDmitry Bogdanov 
18009d106c6dSDmitry Bogdanov 	rec->key[4] = packed_record[8];
18019d106c6dSDmitry Bogdanov 	rec->key[4] |= packed_record[9] << 16;
18029d106c6dSDmitry Bogdanov 
18039d106c6dSDmitry Bogdanov 	rec->key[5] = packed_record[10];
18049d106c6dSDmitry Bogdanov 	rec->key[5] |= packed_record[11] << 16;
18059d106c6dSDmitry Bogdanov 
18069d106c6dSDmitry Bogdanov 	rec->key[6] = packed_record[12];
18079d106c6dSDmitry Bogdanov 	rec->key[6] |= packed_record[13] << 16;
18089d106c6dSDmitry Bogdanov 
18099d106c6dSDmitry Bogdanov 	rec->key[7] = packed_record[14];
18109d106c6dSDmitry Bogdanov 	rec->key[7] |= packed_record[15] << 16;
18119d106c6dSDmitry Bogdanov 
18129d106c6dSDmitry Bogdanov 	return 0;
18139d106c6dSDmitry Bogdanov }
18149d106c6dSDmitry Bogdanov 
aq_mss_get_egress_sakey_record(struct aq_hw_s * hw,struct aq_mss_egress_sakey_record * rec,u16 table_index)18159d106c6dSDmitry Bogdanov int aq_mss_get_egress_sakey_record(struct aq_hw_s *hw,
18169d106c6dSDmitry Bogdanov 				   struct aq_mss_egress_sakey_record *rec,
18179d106c6dSDmitry Bogdanov 				   u16 table_index)
18189d106c6dSDmitry Bogdanov {
18199d106c6dSDmitry Bogdanov 	memset(rec, 0, sizeof(*rec));
18209d106c6dSDmitry Bogdanov 
18219d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sakey_record, hw, rec, table_index);
18229d106c6dSDmitry Bogdanov }
18239d106c6dSDmitry Bogdanov 
get_egress_sc_counters(struct aq_hw_s * hw,struct aq_mss_egress_sc_counters * counters,u16 sc_index)1824aaa36515SDmitry Bogdanov static int get_egress_sc_counters(struct aq_hw_s *hw,
1825aaa36515SDmitry Bogdanov 				  struct aq_mss_egress_sc_counters *counters,
1826aaa36515SDmitry Bogdanov 				  u16 sc_index)
1827aaa36515SDmitry Bogdanov {
1828aaa36515SDmitry Bogdanov 	u16 packed_record[4];
1829aaa36515SDmitry Bogdanov 	int ret;
1830aaa36515SDmitry Bogdanov 
1831aaa36515SDmitry Bogdanov 	if (sc_index >= NUMROWS_EGRESSSCRECORD)
1832aaa36515SDmitry Bogdanov 		return -EINVAL;
1833aaa36515SDmitry Bogdanov 
1834aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 4);
1835aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1836aaa36515SDmitry Bogdanov 		return ret;
1837aaa36515SDmitry Bogdanov 	counters->sc_protected_pkts[0] =
1838aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1839aaa36515SDmitry Bogdanov 	counters->sc_protected_pkts[1] =
1840aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1841aaa36515SDmitry Bogdanov 
1842aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 5);
1843aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1844aaa36515SDmitry Bogdanov 		return ret;
1845aaa36515SDmitry Bogdanov 	counters->sc_encrypted_pkts[0] =
1846aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1847aaa36515SDmitry Bogdanov 	counters->sc_encrypted_pkts[1] =
1848aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1849aaa36515SDmitry Bogdanov 
1850aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 6);
1851aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1852aaa36515SDmitry Bogdanov 		return ret;
1853aaa36515SDmitry Bogdanov 	counters->sc_protected_octets[0] =
1854aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1855aaa36515SDmitry Bogdanov 	counters->sc_protected_octets[1] =
1856aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1857aaa36515SDmitry Bogdanov 
1858aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sc_index * 8 + 7);
1859aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1860aaa36515SDmitry Bogdanov 		return ret;
1861aaa36515SDmitry Bogdanov 	counters->sc_encrypted_octets[0] =
1862aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1863aaa36515SDmitry Bogdanov 	counters->sc_encrypted_octets[1] =
1864aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1865aaa36515SDmitry Bogdanov 
1866aaa36515SDmitry Bogdanov 	return 0;
1867aaa36515SDmitry Bogdanov }
1868aaa36515SDmitry Bogdanov 
aq_mss_get_egress_sc_counters(struct aq_hw_s * hw,struct aq_mss_egress_sc_counters * counters,u16 sc_index)1869aaa36515SDmitry Bogdanov int aq_mss_get_egress_sc_counters(struct aq_hw_s *hw,
1870aaa36515SDmitry Bogdanov 				  struct aq_mss_egress_sc_counters *counters,
1871aaa36515SDmitry Bogdanov 				  u16 sc_index)
1872aaa36515SDmitry Bogdanov {
1873aaa36515SDmitry Bogdanov 	memset(counters, 0, sizeof(*counters));
1874aaa36515SDmitry Bogdanov 
1875aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sc_counters, hw, counters, sc_index);
1876aaa36515SDmitry Bogdanov }
1877aaa36515SDmitry Bogdanov 
get_egress_sa_counters(struct aq_hw_s * hw,struct aq_mss_egress_sa_counters * counters,u16 sa_index)1878aaa36515SDmitry Bogdanov static int get_egress_sa_counters(struct aq_hw_s *hw,
1879aaa36515SDmitry Bogdanov 				  struct aq_mss_egress_sa_counters *counters,
1880aaa36515SDmitry Bogdanov 				  u16 sa_index)
1881aaa36515SDmitry Bogdanov {
1882aaa36515SDmitry Bogdanov 	u16 packed_record[4];
1883aaa36515SDmitry Bogdanov 	int ret;
1884aaa36515SDmitry Bogdanov 
1885aaa36515SDmitry Bogdanov 	if (sa_index >= NUMROWS_EGRESSSARECORD)
1886aaa36515SDmitry Bogdanov 		return -EINVAL;
1887aaa36515SDmitry Bogdanov 
1888aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 0);
1889aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1890aaa36515SDmitry Bogdanov 		return ret;
1891aaa36515SDmitry Bogdanov 	counters->sa_hit_drop_redirect[0] =
1892aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1893aaa36515SDmitry Bogdanov 	counters->sa_hit_drop_redirect[1] =
1894aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1895aaa36515SDmitry Bogdanov 
1896aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 1);
1897aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1898aaa36515SDmitry Bogdanov 		return ret;
1899aaa36515SDmitry Bogdanov 	counters->sa_protected2_pkts[0] =
1900aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1901aaa36515SDmitry Bogdanov 	counters->sa_protected2_pkts[1] =
1902aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1903aaa36515SDmitry Bogdanov 
1904aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 2);
1905aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1906aaa36515SDmitry Bogdanov 		return ret;
1907aaa36515SDmitry Bogdanov 	counters->sa_protected_pkts[0] =
1908aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1909aaa36515SDmitry Bogdanov 	counters->sa_protected_pkts[1] =
1910aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1911aaa36515SDmitry Bogdanov 
1912aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, sa_index * 8 + 3);
1913aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1914aaa36515SDmitry Bogdanov 		return ret;
1915aaa36515SDmitry Bogdanov 	counters->sa_encrypted_pkts[0] =
1916aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1917aaa36515SDmitry Bogdanov 	counters->sa_encrypted_pkts[1] =
1918aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1919aaa36515SDmitry Bogdanov 
1920aaa36515SDmitry Bogdanov 	return 0;
1921aaa36515SDmitry Bogdanov }
1922aaa36515SDmitry Bogdanov 
aq_mss_get_egress_sa_counters(struct aq_hw_s * hw,struct aq_mss_egress_sa_counters * counters,u16 sa_index)1923aaa36515SDmitry Bogdanov int aq_mss_get_egress_sa_counters(struct aq_hw_s *hw,
1924aaa36515SDmitry Bogdanov 				  struct aq_mss_egress_sa_counters *counters,
1925aaa36515SDmitry Bogdanov 				  u16 sa_index)
1926aaa36515SDmitry Bogdanov {
1927aaa36515SDmitry Bogdanov 	memset(counters, 0, sizeof(*counters));
1928aaa36515SDmitry Bogdanov 
1929aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sa_counters, hw, counters, sa_index);
1930aaa36515SDmitry Bogdanov }
1931aaa36515SDmitry Bogdanov 
1932aaa36515SDmitry Bogdanov static int
get_egress_common_counters(struct aq_hw_s * hw,struct aq_mss_egress_common_counters * counters)1933aaa36515SDmitry Bogdanov get_egress_common_counters(struct aq_hw_s *hw,
1934aaa36515SDmitry Bogdanov 			   struct aq_mss_egress_common_counters *counters)
1935aaa36515SDmitry Bogdanov {
1936aaa36515SDmitry Bogdanov 	u16 packed_record[4];
1937aaa36515SDmitry Bogdanov 	int ret;
1938aaa36515SDmitry Bogdanov 
1939aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 0);
1940aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1941aaa36515SDmitry Bogdanov 		return ret;
1942aaa36515SDmitry Bogdanov 	counters->ctl_pkt[0] = packed_record[0] | (packed_record[1] << 16);
1943aaa36515SDmitry Bogdanov 	counters->ctl_pkt[1] = packed_record[2] | (packed_record[3] << 16);
1944aaa36515SDmitry Bogdanov 
1945aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 1);
1946aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1947aaa36515SDmitry Bogdanov 		return ret;
1948aaa36515SDmitry Bogdanov 	counters->unknown_sa_pkts[0] =
1949aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1950aaa36515SDmitry Bogdanov 	counters->unknown_sa_pkts[1] =
1951aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1952aaa36515SDmitry Bogdanov 
1953aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 2);
1954aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1955aaa36515SDmitry Bogdanov 		return ret;
1956aaa36515SDmitry Bogdanov 	counters->untagged_pkts[0] =
1957aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1958aaa36515SDmitry Bogdanov 	counters->untagged_pkts[1] =
1959aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1960aaa36515SDmitry Bogdanov 
1961aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 3);
1962aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1963aaa36515SDmitry Bogdanov 		return ret;
1964aaa36515SDmitry Bogdanov 	counters->too_long[0] = packed_record[0] | (packed_record[1] << 16);
1965aaa36515SDmitry Bogdanov 	counters->too_long[1] = packed_record[2] | (packed_record[3] << 16);
1966aaa36515SDmitry Bogdanov 
1967aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 4);
1968aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1969aaa36515SDmitry Bogdanov 		return ret;
1970aaa36515SDmitry Bogdanov 	counters->ecc_error_pkts[0] =
1971aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1972aaa36515SDmitry Bogdanov 	counters->ecc_error_pkts[1] =
1973aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1974aaa36515SDmitry Bogdanov 
1975aaa36515SDmitry Bogdanov 	ret = get_raw_egress_record(hw, packed_record, 4, 3, 256 + 5);
1976aaa36515SDmitry Bogdanov 	if (unlikely(ret))
1977aaa36515SDmitry Bogdanov 		return ret;
1978aaa36515SDmitry Bogdanov 	counters->unctrl_hit_drop_redir[0] =
1979aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
1980aaa36515SDmitry Bogdanov 	counters->unctrl_hit_drop_redir[1] =
1981aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
1982aaa36515SDmitry Bogdanov 
1983aaa36515SDmitry Bogdanov 	return 0;
1984aaa36515SDmitry Bogdanov }
1985aaa36515SDmitry Bogdanov 
aq_mss_get_egress_common_counters(struct aq_hw_s * hw,struct aq_mss_egress_common_counters * counters)1986aaa36515SDmitry Bogdanov int aq_mss_get_egress_common_counters(struct aq_hw_s *hw,
1987aaa36515SDmitry Bogdanov 	struct aq_mss_egress_common_counters *counters)
1988aaa36515SDmitry Bogdanov {
1989aaa36515SDmitry Bogdanov 	memset(counters, 0, sizeof(*counters));
1990aaa36515SDmitry Bogdanov 
1991aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_common_counters, hw, counters);
1992aaa36515SDmitry Bogdanov }
1993aaa36515SDmitry Bogdanov 
clear_egress_counters(struct aq_hw_s * hw)1994aaa36515SDmitry Bogdanov static int clear_egress_counters(struct aq_hw_s *hw)
1995aaa36515SDmitry Bogdanov {
1996aaa36515SDmitry Bogdanov 	struct mss_egress_ctl_register ctl_reg;
1997aaa36515SDmitry Bogdanov 	int ret;
1998aaa36515SDmitry Bogdanov 
1999aaa36515SDmitry Bogdanov 	memset(&ctl_reg, 0, sizeof(ctl_reg));
2000aaa36515SDmitry Bogdanov 
2001aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1, MSS_EGRESS_CTL_REGISTER_ADDR,
2002aaa36515SDmitry Bogdanov 			       &ctl_reg.word_0);
2003aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2004aaa36515SDmitry Bogdanov 		return ret;
2005aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2006aaa36515SDmitry Bogdanov 			       MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2007aaa36515SDmitry Bogdanov 			       &ctl_reg.word_1);
2008aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2009aaa36515SDmitry Bogdanov 		return ret;
2010aaa36515SDmitry Bogdanov 
2011aaa36515SDmitry Bogdanov 	/* Toggle the Egress MIB clear bit 0->1->0 */
2012aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_counter = 0;
2013aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2014aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2015aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2016aaa36515SDmitry Bogdanov 		return ret;
2017aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2018aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2019aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2020aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2021aaa36515SDmitry Bogdanov 		return ret;
2022aaa36515SDmitry Bogdanov 
2023aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_counter = 1;
2024aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2025aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2026aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2027aaa36515SDmitry Bogdanov 		return ret;
2028aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2029aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2030aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2031aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2032aaa36515SDmitry Bogdanov 		return ret;
2033aaa36515SDmitry Bogdanov 
2034aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_counter = 0;
2035aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2036aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2037aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2038aaa36515SDmitry Bogdanov 		return ret;
2039aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2040aaa36515SDmitry Bogdanov 				MSS_EGRESS_CTL_REGISTER_ADDR + 4,
2041aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2042aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2043aaa36515SDmitry Bogdanov 		return ret;
2044aaa36515SDmitry Bogdanov 
2045aaa36515SDmitry Bogdanov 	return 0;
2046aaa36515SDmitry Bogdanov }
2047aaa36515SDmitry Bogdanov 
aq_mss_clear_egress_counters(struct aq_hw_s * hw)2048aaa36515SDmitry Bogdanov int aq_mss_clear_egress_counters(struct aq_hw_s *hw)
2049aaa36515SDmitry Bogdanov {
2050aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(clear_egress_counters, hw);
2051aaa36515SDmitry Bogdanov }
2052aaa36515SDmitry Bogdanov 
get_ingress_sa_counters(struct aq_hw_s * hw,struct aq_mss_ingress_sa_counters * counters,u16 sa_index)2053aaa36515SDmitry Bogdanov static int get_ingress_sa_counters(struct aq_hw_s *hw,
2054aaa36515SDmitry Bogdanov 				   struct aq_mss_ingress_sa_counters *counters,
2055aaa36515SDmitry Bogdanov 				   u16 sa_index)
2056aaa36515SDmitry Bogdanov {
2057aaa36515SDmitry Bogdanov 	u16 packed_record[4];
2058aaa36515SDmitry Bogdanov 	int ret;
2059aaa36515SDmitry Bogdanov 
2060aaa36515SDmitry Bogdanov 	if (sa_index >= NUMROWS_INGRESSSARECORD)
2061aaa36515SDmitry Bogdanov 		return -EINVAL;
2062aaa36515SDmitry Bogdanov 
2063aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2064aaa36515SDmitry Bogdanov 				     sa_index * 12 + 0);
2065aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2066aaa36515SDmitry Bogdanov 		return ret;
2067aaa36515SDmitry Bogdanov 	counters->untagged_hit_pkts[0] =
2068aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2069aaa36515SDmitry Bogdanov 	counters->untagged_hit_pkts[1] =
2070aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2071aaa36515SDmitry Bogdanov 
2072aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2073aaa36515SDmitry Bogdanov 				     sa_index * 12 + 1);
2074aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2075aaa36515SDmitry Bogdanov 		return ret;
2076aaa36515SDmitry Bogdanov 	counters->ctrl_hit_drop_redir_pkts[0] =
2077aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2078aaa36515SDmitry Bogdanov 	counters->ctrl_hit_drop_redir_pkts[1] =
2079aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2080aaa36515SDmitry Bogdanov 
2081aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2082aaa36515SDmitry Bogdanov 				     sa_index * 12 + 2);
2083aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2084aaa36515SDmitry Bogdanov 		return ret;
2085aaa36515SDmitry Bogdanov 	counters->not_using_sa[0] = packed_record[0] | (packed_record[1] << 16);
2086aaa36515SDmitry Bogdanov 	counters->not_using_sa[1] = packed_record[2] | (packed_record[3] << 16);
2087aaa36515SDmitry Bogdanov 
2088aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2089aaa36515SDmitry Bogdanov 				     sa_index * 12 + 3);
2090aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2091aaa36515SDmitry Bogdanov 		return ret;
2092aaa36515SDmitry Bogdanov 	counters->unused_sa[0] = packed_record[0] | (packed_record[1] << 16);
2093aaa36515SDmitry Bogdanov 	counters->unused_sa[1] = packed_record[2] | (packed_record[3] << 16);
2094aaa36515SDmitry Bogdanov 
2095aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2096aaa36515SDmitry Bogdanov 				     sa_index * 12 + 4);
2097aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2098aaa36515SDmitry Bogdanov 		return ret;
2099aaa36515SDmitry Bogdanov 	counters->not_valid_pkts[0] =
2100aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2101aaa36515SDmitry Bogdanov 	counters->not_valid_pkts[1] =
2102aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2103aaa36515SDmitry Bogdanov 
2104aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2105aaa36515SDmitry Bogdanov 				     sa_index * 12 + 5);
2106aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2107aaa36515SDmitry Bogdanov 		return ret;
2108aaa36515SDmitry Bogdanov 	counters->invalid_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2109aaa36515SDmitry Bogdanov 	counters->invalid_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2110aaa36515SDmitry Bogdanov 
2111aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2112aaa36515SDmitry Bogdanov 				     sa_index * 12 + 6);
2113aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2114aaa36515SDmitry Bogdanov 		return ret;
2115aaa36515SDmitry Bogdanov 	counters->ok_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2116aaa36515SDmitry Bogdanov 	counters->ok_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2117aaa36515SDmitry Bogdanov 
2118aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2119aaa36515SDmitry Bogdanov 				     sa_index * 12 + 7);
2120aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2121aaa36515SDmitry Bogdanov 		return ret;
2122aaa36515SDmitry Bogdanov 	counters->late_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2123aaa36515SDmitry Bogdanov 	counters->late_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2124aaa36515SDmitry Bogdanov 
2125aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2126aaa36515SDmitry Bogdanov 				     sa_index * 12 + 8);
2127aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2128aaa36515SDmitry Bogdanov 		return ret;
2129aaa36515SDmitry Bogdanov 	counters->delayed_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2130aaa36515SDmitry Bogdanov 	counters->delayed_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2131aaa36515SDmitry Bogdanov 
2132aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2133aaa36515SDmitry Bogdanov 				     sa_index * 12 + 9);
2134aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2135aaa36515SDmitry Bogdanov 		return ret;
2136aaa36515SDmitry Bogdanov 	counters->unchecked_pkts[0] =
2137aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2138aaa36515SDmitry Bogdanov 	counters->unchecked_pkts[1] =
2139aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2140aaa36515SDmitry Bogdanov 
2141aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2142aaa36515SDmitry Bogdanov 				     sa_index * 12 + 10);
2143aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2144aaa36515SDmitry Bogdanov 		return ret;
2145aaa36515SDmitry Bogdanov 	counters->validated_octets[0] =
2146aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2147aaa36515SDmitry Bogdanov 	counters->validated_octets[1] =
2148aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2149aaa36515SDmitry Bogdanov 
2150aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6,
2151aaa36515SDmitry Bogdanov 				     sa_index * 12 + 11);
2152aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2153aaa36515SDmitry Bogdanov 		return ret;
2154aaa36515SDmitry Bogdanov 	counters->decrypted_octets[0] =
2155aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2156aaa36515SDmitry Bogdanov 	counters->decrypted_octets[1] =
2157aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2158aaa36515SDmitry Bogdanov 
2159aaa36515SDmitry Bogdanov 	return 0;
2160aaa36515SDmitry Bogdanov }
2161aaa36515SDmitry Bogdanov 
aq_mss_get_ingress_sa_counters(struct aq_hw_s * hw,struct aq_mss_ingress_sa_counters * counters,u16 sa_index)2162aaa36515SDmitry Bogdanov int aq_mss_get_ingress_sa_counters(struct aq_hw_s *hw,
2163aaa36515SDmitry Bogdanov 				   struct aq_mss_ingress_sa_counters *counters,
2164aaa36515SDmitry Bogdanov 				   u16 sa_index)
2165aaa36515SDmitry Bogdanov {
2166aaa36515SDmitry Bogdanov 	memset(counters, 0, sizeof(*counters));
2167aaa36515SDmitry Bogdanov 
2168aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_ingress_sa_counters, hw, counters,
2169aaa36515SDmitry Bogdanov 				sa_index);
2170aaa36515SDmitry Bogdanov }
2171aaa36515SDmitry Bogdanov 
2172aaa36515SDmitry Bogdanov static int
get_ingress_common_counters(struct aq_hw_s * hw,struct aq_mss_ingress_common_counters * counters)2173aaa36515SDmitry Bogdanov get_ingress_common_counters(struct aq_hw_s *hw,
2174aaa36515SDmitry Bogdanov 			    struct aq_mss_ingress_common_counters *counters)
2175aaa36515SDmitry Bogdanov {
2176aaa36515SDmitry Bogdanov 	u16 packed_record[4];
2177aaa36515SDmitry Bogdanov 	int ret;
2178aaa36515SDmitry Bogdanov 
2179aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 0);
2180aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2181aaa36515SDmitry Bogdanov 		return ret;
2182aaa36515SDmitry Bogdanov 	counters->ctl_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2183aaa36515SDmitry Bogdanov 	counters->ctl_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2184aaa36515SDmitry Bogdanov 
2185aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 1);
2186aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2187aaa36515SDmitry Bogdanov 		return ret;
2188aaa36515SDmitry Bogdanov 	counters->tagged_miss_pkts[0] =
2189aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2190aaa36515SDmitry Bogdanov 	counters->tagged_miss_pkts[1] =
2191aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2192aaa36515SDmitry Bogdanov 
2193aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 2);
2194aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2195aaa36515SDmitry Bogdanov 		return ret;
2196aaa36515SDmitry Bogdanov 	counters->untagged_miss_pkts[0] =
2197aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2198aaa36515SDmitry Bogdanov 	counters->untagged_miss_pkts[1] =
2199aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2200aaa36515SDmitry Bogdanov 
2201aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 3);
2202aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2203aaa36515SDmitry Bogdanov 		return ret;
2204aaa36515SDmitry Bogdanov 	counters->notag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2205aaa36515SDmitry Bogdanov 	counters->notag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2206aaa36515SDmitry Bogdanov 
2207aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 4);
2208aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2209aaa36515SDmitry Bogdanov 		return ret;
2210aaa36515SDmitry Bogdanov 	counters->untagged_pkts[0] =
2211aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2212aaa36515SDmitry Bogdanov 	counters->untagged_pkts[1] =
2213aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2214aaa36515SDmitry Bogdanov 
2215aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 5);
2216aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2217aaa36515SDmitry Bogdanov 		return ret;
2218aaa36515SDmitry Bogdanov 	counters->bad_tag_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2219aaa36515SDmitry Bogdanov 	counters->bad_tag_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2220aaa36515SDmitry Bogdanov 
2221aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 6);
2222aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2223aaa36515SDmitry Bogdanov 		return ret;
2224aaa36515SDmitry Bogdanov 	counters->no_sci_pkts[0] = packed_record[0] | (packed_record[1] << 16);
2225aaa36515SDmitry Bogdanov 	counters->no_sci_pkts[1] = packed_record[2] | (packed_record[3] << 16);
2226aaa36515SDmitry Bogdanov 
2227aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 7);
2228aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2229aaa36515SDmitry Bogdanov 		return ret;
2230aaa36515SDmitry Bogdanov 	counters->unknown_sci_pkts[0] =
2231aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2232aaa36515SDmitry Bogdanov 	counters->unknown_sci_pkts[1] =
2233aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2234aaa36515SDmitry Bogdanov 
2235aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 8);
2236aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2237aaa36515SDmitry Bogdanov 		return ret;
2238aaa36515SDmitry Bogdanov 	counters->ctrl_prt_pass_pkts[0] =
2239aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2240aaa36515SDmitry Bogdanov 	counters->ctrl_prt_pass_pkts[1] =
2241aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2242aaa36515SDmitry Bogdanov 
2243aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 9);
2244aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2245aaa36515SDmitry Bogdanov 		return ret;
2246aaa36515SDmitry Bogdanov 	counters->unctrl_prt_pass_pkts[0] =
2247aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2248aaa36515SDmitry Bogdanov 	counters->unctrl_prt_pass_pkts[1] =
2249aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2250aaa36515SDmitry Bogdanov 
2251aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 10);
2252aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2253aaa36515SDmitry Bogdanov 		return ret;
2254aaa36515SDmitry Bogdanov 	counters->ctrl_prt_fail_pkts[0] =
2255aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2256aaa36515SDmitry Bogdanov 	counters->ctrl_prt_fail_pkts[1] =
2257aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2258aaa36515SDmitry Bogdanov 
2259aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 11);
2260aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2261aaa36515SDmitry Bogdanov 		return ret;
2262aaa36515SDmitry Bogdanov 	counters->unctrl_prt_fail_pkts[0] =
2263aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2264aaa36515SDmitry Bogdanov 	counters->unctrl_prt_fail_pkts[1] =
2265aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2266aaa36515SDmitry Bogdanov 
2267aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 12);
2268aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2269aaa36515SDmitry Bogdanov 		return ret;
2270aaa36515SDmitry Bogdanov 	counters->too_long_pkts[0] =
2271aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2272aaa36515SDmitry Bogdanov 	counters->too_long_pkts[1] =
2273aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2274aaa36515SDmitry Bogdanov 
2275aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 13);
2276aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2277aaa36515SDmitry Bogdanov 		return ret;
2278aaa36515SDmitry Bogdanov 	counters->igpoc_ctl_pkts[0] =
2279aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2280aaa36515SDmitry Bogdanov 	counters->igpoc_ctl_pkts[1] =
2281aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2282aaa36515SDmitry Bogdanov 
2283aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 14);
2284aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2285aaa36515SDmitry Bogdanov 		return ret;
2286aaa36515SDmitry Bogdanov 	counters->ecc_error_pkts[0] =
2287aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2288aaa36515SDmitry Bogdanov 	counters->ecc_error_pkts[1] =
2289aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2290aaa36515SDmitry Bogdanov 
2291aaa36515SDmitry Bogdanov 	ret = get_raw_ingress_record(hw, packed_record, 4, 6, 385 + 15);
2292aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2293aaa36515SDmitry Bogdanov 		return ret;
2294aaa36515SDmitry Bogdanov 	counters->unctrl_hit_drop_redir[0] =
2295aaa36515SDmitry Bogdanov 		packed_record[0] | (packed_record[1] << 16);
2296aaa36515SDmitry Bogdanov 	counters->unctrl_hit_drop_redir[1] =
2297aaa36515SDmitry Bogdanov 		packed_record[2] | (packed_record[3] << 16);
2298aaa36515SDmitry Bogdanov 
2299aaa36515SDmitry Bogdanov 	return 0;
2300aaa36515SDmitry Bogdanov }
2301aaa36515SDmitry Bogdanov 
aq_mss_get_ingress_common_counters(struct aq_hw_s * hw,struct aq_mss_ingress_common_counters * counters)2302aaa36515SDmitry Bogdanov int aq_mss_get_ingress_common_counters(struct aq_hw_s *hw,
2303aaa36515SDmitry Bogdanov 	struct aq_mss_ingress_common_counters *counters)
2304aaa36515SDmitry Bogdanov {
2305aaa36515SDmitry Bogdanov 	memset(counters, 0, sizeof(*counters));
2306aaa36515SDmitry Bogdanov 
2307aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_ingress_common_counters, hw, counters);
2308aaa36515SDmitry Bogdanov }
2309aaa36515SDmitry Bogdanov 
clear_ingress_counters(struct aq_hw_s * hw)2310aaa36515SDmitry Bogdanov static int clear_ingress_counters(struct aq_hw_s *hw)
2311aaa36515SDmitry Bogdanov {
2312aaa36515SDmitry Bogdanov 	struct mss_ingress_ctl_register ctl_reg;
2313aaa36515SDmitry Bogdanov 	int ret;
2314aaa36515SDmitry Bogdanov 
2315aaa36515SDmitry Bogdanov 	memset(&ctl_reg, 0, sizeof(ctl_reg));
2316aaa36515SDmitry Bogdanov 
2317aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2318aaa36515SDmitry Bogdanov 			       MSS_INGRESS_CTL_REGISTER_ADDR, &ctl_reg.word_0);
2319aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2320aaa36515SDmitry Bogdanov 		return ret;
2321aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
2322aaa36515SDmitry Bogdanov 			       MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2323aaa36515SDmitry Bogdanov 			       &ctl_reg.word_1);
2324aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2325aaa36515SDmitry Bogdanov 		return ret;
2326aaa36515SDmitry Bogdanov 
2327aaa36515SDmitry Bogdanov 	/* Toggle the Ingress MIB clear bit 0->1->0 */
2328aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_count = 0;
2329aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2330aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2331aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2332aaa36515SDmitry Bogdanov 		return ret;
2333aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2334aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2335aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2336aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2337aaa36515SDmitry Bogdanov 		return ret;
2338aaa36515SDmitry Bogdanov 
2339aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_count = 1;
2340aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2341aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2342aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2343aaa36515SDmitry Bogdanov 		return ret;
2344aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2345aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2346aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2347aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2348aaa36515SDmitry Bogdanov 		return ret;
2349aaa36515SDmitry Bogdanov 
2350aaa36515SDmitry Bogdanov 	ctl_reg.bits_0.clear_count = 0;
2351aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2352aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR, ctl_reg.word_0);
2353aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2354aaa36515SDmitry Bogdanov 		return ret;
2355aaa36515SDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
2356aaa36515SDmitry Bogdanov 				MSS_INGRESS_CTL_REGISTER_ADDR + 4,
2357aaa36515SDmitry Bogdanov 				ctl_reg.word_1);
2358aaa36515SDmitry Bogdanov 	if (unlikely(ret))
2359aaa36515SDmitry Bogdanov 		return ret;
2360aaa36515SDmitry Bogdanov 
2361aaa36515SDmitry Bogdanov 	return 0;
2362aaa36515SDmitry Bogdanov }
2363aaa36515SDmitry Bogdanov 
aq_mss_clear_ingress_counters(struct aq_hw_s * hw)2364aaa36515SDmitry Bogdanov int aq_mss_clear_ingress_counters(struct aq_hw_s *hw)
2365aaa36515SDmitry Bogdanov {
2366aaa36515SDmitry Bogdanov 	return AQ_API_CALL_SAFE(clear_ingress_counters, hw);
2367aaa36515SDmitry Bogdanov }
2368aaa36515SDmitry Bogdanov 
get_egress_sa_expired(struct aq_hw_s * hw,u32 * expired)23699d106c6dSDmitry Bogdanov static int get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
23709d106c6dSDmitry Bogdanov {
23719d106c6dSDmitry Bogdanov 	u16 val;
23729d106c6dSDmitry Bogdanov 	int ret;
23739d106c6dSDmitry Bogdanov 
23749d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
23759d106c6dSDmitry Bogdanov 			       MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
23769d106c6dSDmitry Bogdanov 			       &val);
23779d106c6dSDmitry Bogdanov 	if (unlikely(ret))
23789d106c6dSDmitry Bogdanov 		return ret;
23799d106c6dSDmitry Bogdanov 
23809d106c6dSDmitry Bogdanov 	*expired = val;
23819d106c6dSDmitry Bogdanov 
23829d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
23839d106c6dSDmitry Bogdanov 			       MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
23849d106c6dSDmitry Bogdanov 			       &val);
23859d106c6dSDmitry Bogdanov 	if (unlikely(ret))
23869d106c6dSDmitry Bogdanov 		return ret;
23879d106c6dSDmitry Bogdanov 
23889d106c6dSDmitry Bogdanov 	*expired |= val << 16;
23899d106c6dSDmitry Bogdanov 
23909d106c6dSDmitry Bogdanov 	return 0;
23919d106c6dSDmitry Bogdanov }
23929d106c6dSDmitry Bogdanov 
aq_mss_get_egress_sa_expired(struct aq_hw_s * hw,u32 * expired)23939d106c6dSDmitry Bogdanov int aq_mss_get_egress_sa_expired(struct aq_hw_s *hw, u32 *expired)
23949d106c6dSDmitry Bogdanov {
23959d106c6dSDmitry Bogdanov 	*expired = 0;
23969d106c6dSDmitry Bogdanov 
23979d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sa_expired, hw, expired);
23989d106c6dSDmitry Bogdanov }
23999d106c6dSDmitry Bogdanov 
get_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 * expired)24009d106c6dSDmitry Bogdanov static int get_egress_sa_threshold_expired(struct aq_hw_s *hw,
24019d106c6dSDmitry Bogdanov 					   u32 *expired)
24029d106c6dSDmitry Bogdanov {
24039d106c6dSDmitry Bogdanov 	u16 val;
24049d106c6dSDmitry Bogdanov 	int ret;
24059d106c6dSDmitry Bogdanov 
24069d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
24079d106c6dSDmitry Bogdanov 		MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR, &val);
24089d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24099d106c6dSDmitry Bogdanov 		return ret;
24109d106c6dSDmitry Bogdanov 
24119d106c6dSDmitry Bogdanov 	*expired = val;
24129d106c6dSDmitry Bogdanov 
24139d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_read(hw, MDIO_MMD_VEND1,
24149d106c6dSDmitry Bogdanov 		MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1, &val);
24159d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24169d106c6dSDmitry Bogdanov 		return ret;
24179d106c6dSDmitry Bogdanov 
24189d106c6dSDmitry Bogdanov 	*expired |= val << 16;
24199d106c6dSDmitry Bogdanov 
24209d106c6dSDmitry Bogdanov 	return 0;
24219d106c6dSDmitry Bogdanov }
24229d106c6dSDmitry Bogdanov 
aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 * expired)24239d106c6dSDmitry Bogdanov int aq_mss_get_egress_sa_threshold_expired(struct aq_hw_s *hw,
24249d106c6dSDmitry Bogdanov 					   u32 *expired)
24259d106c6dSDmitry Bogdanov {
24269d106c6dSDmitry Bogdanov 	*expired = 0;
24279d106c6dSDmitry Bogdanov 
24289d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(get_egress_sa_threshold_expired, hw, expired);
24299d106c6dSDmitry Bogdanov }
24309d106c6dSDmitry Bogdanov 
set_egress_sa_expired(struct aq_hw_s * hw,u32 expired)24319d106c6dSDmitry Bogdanov static int set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
24329d106c6dSDmitry Bogdanov {
24339d106c6dSDmitry Bogdanov 	int ret;
24349d106c6dSDmitry Bogdanov 
24359d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
24369d106c6dSDmitry Bogdanov 				MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR,
24379d106c6dSDmitry Bogdanov 				expired & 0xFFFF);
24389d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24399d106c6dSDmitry Bogdanov 		return ret;
24409d106c6dSDmitry Bogdanov 
24419d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
24429d106c6dSDmitry Bogdanov 				MSS_EGRESS_SA_EXPIRED_STATUS_REGISTER_ADDR + 1,
24439d106c6dSDmitry Bogdanov 				expired >> 16);
24449d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24459d106c6dSDmitry Bogdanov 		return ret;
24469d106c6dSDmitry Bogdanov 
24479d106c6dSDmitry Bogdanov 	return 0;
24489d106c6dSDmitry Bogdanov }
24499d106c6dSDmitry Bogdanov 
aq_mss_set_egress_sa_expired(struct aq_hw_s * hw,u32 expired)24509d106c6dSDmitry Bogdanov int aq_mss_set_egress_sa_expired(struct aq_hw_s *hw, u32 expired)
24519d106c6dSDmitry Bogdanov {
24529d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(set_egress_sa_expired, hw, expired);
24539d106c6dSDmitry Bogdanov }
24549d106c6dSDmitry Bogdanov 
set_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 expired)24559d106c6dSDmitry Bogdanov static int set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
24569d106c6dSDmitry Bogdanov {
24579d106c6dSDmitry Bogdanov 	int ret;
24589d106c6dSDmitry Bogdanov 
24599d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
24609d106c6dSDmitry Bogdanov 		MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR,
24619d106c6dSDmitry Bogdanov 		expired & 0xFFFF);
24629d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24639d106c6dSDmitry Bogdanov 		return ret;
24649d106c6dSDmitry Bogdanov 
24659d106c6dSDmitry Bogdanov 	ret = aq_mss_mdio_write(hw, MDIO_MMD_VEND1,
24669d106c6dSDmitry Bogdanov 		MSS_EGRESS_SA_THRESHOLD_EXPIRED_STATUS_REGISTER_ADDR + 1,
24679d106c6dSDmitry Bogdanov 		expired >> 16);
24689d106c6dSDmitry Bogdanov 	if (unlikely(ret))
24699d106c6dSDmitry Bogdanov 		return ret;
24709d106c6dSDmitry Bogdanov 
24719d106c6dSDmitry Bogdanov 	return 0;
24729d106c6dSDmitry Bogdanov }
24739d106c6dSDmitry Bogdanov 
aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s * hw,u32 expired)24749d106c6dSDmitry Bogdanov int aq_mss_set_egress_sa_threshold_expired(struct aq_hw_s *hw, u32 expired)
24759d106c6dSDmitry Bogdanov {
24769d106c6dSDmitry Bogdanov 	return AQ_API_CALL_SAFE(set_egress_sa_threshold_expired, hw, expired);
24779d106c6dSDmitry Bogdanov }
2478