1/*-
2*******************************************************************************
3Copyright (C) 2015 Annapurna Labs Ltd.
4
5This file may be licensed under the terms of the Annapurna Labs Commercial
6License Agreement.
7
8Alternatively, this file can be distributed under the terms of the GNU General
9Public License V2 as published by the Free Software Foundation and can be
10found at http://www.gnu.org/licenses/gpl-2.0.html
11
12Alternatively, redistribution and use in source and binary forms, with or
13without modification, are permitted provided that the following conditions are
14met:
15
16    *     Redistributions of source code must retain the above copyright notice,
17this list of conditions and the following disclaimer.
18
19    *     Redistributions in binary form must reproduce the above copyright
20notice, this list of conditions and the following disclaimer in
21the documentation and/or other materials provided with the
22distribution.
23
24THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35*******************************************************************************/
36
37/**
38 *  @{
39 * @file   al_hal_eth_main.c
40 *
41 * @brief  XG Ethernet unit HAL driver for main functions (initialization, data path)
42 *
43 */
44
45#include "al_hal_eth.h"
46#include <al_hal_udma_iofic.h>
47#include <al_hal_udma_config.h>
48#include <al_hal_udma.h>
49#include "al_hal_eth_ec_regs.h"
50#include "al_hal_eth_mac_regs.h"
51#include <al_hal_unit_adapter_regs.h>
52#ifdef AL_ETH_EX
53#include "al_hal_eth_ex_internal.h"
54#endif
55
56/* Number of xfi_txclk cycles that accumulate into 100ns */
57#define ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL 52
58
59#define AL_ETH_TX_PKT_UDMA_FLAGS	(AL_ETH_TX_FLAGS_NO_SNOOP | \
60					 AL_ETH_TX_FLAGS_INT)
61
62#define AL_ETH_TX_PKT_META_FLAGS	(AL_ETH_TX_FLAGS_IPV4_L3_CSUM | \
63					 AL_ETH_TX_FLAGS_L4_CSUM |	\
64					 AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM |	\
65					 AL_ETH_TX_FLAGS_L2_MACSEC_PKT | \
66					 AL_ETH_TX_FLAGS_L2_DIS_FCS |\
67					 AL_ETH_TX_FLAGS_TSO |\
68					 AL_ETH_TX_FLAGS_TS)
69
70#define AL_ETH_TX_SRC_VLAN_CNT_MASK	3
71#define AL_ETH_TX_SRC_VLAN_CNT_SHIFT	5
72#define AL_ETH_TX_L4_PROTO_IDX_MASK	0x1F
73#define AL_ETH_TX_L4_PROTO_IDX_SHIFT	8
74#define AL_ETH_TX_TUNNEL_MODE_SHIFT		18
75#define AL_ETH_TX_OUTER_L3_PROTO_SHIFT		20
76#define AL_ETH_TX_VLAN_MOD_ADD_SHIFT		22
77#define AL_ETH_TX_VLAN_MOD_DEL_SHIFT		24
78#define AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT		26
79#define AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT	28
80#define AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT	30
81
82/* tx Meta Descriptor defines */
83#define AL_ETH_TX_META_STORE			(1 << 21)
84#define AL_ETH_TX_META_L3_LEN_MASK		0xff
85#define AL_ETH_TX_META_L3_OFF_MASK		0xff
86#define AL_ETH_TX_META_L3_OFF_SHIFT		8
87#define AL_ETH_TX_META_MSS_LSB_VAL_SHIFT	22
88#define AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT	16
89#define AL_ETH_TX_META_OUTER_L3_LEN_MASK	0x1f
90#define AL_ETH_TX_META_OUTER_L3_LEN_SHIFT	24
91#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK	0x18
92#define AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT	10
93#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK	0x07
94#define AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT	29
95
96/* tx Meta Descriptor defines - MacSec */
97#define AL_ETH_TX_MACSEC_SIGN_SHIFT			  0		/* Sign TX pkt */
98#define AL_ETH_TX_MACSEC_ENCRYPT_SHIFT			  1		/* Encrypt TX pkt */
99#define AL_ETH_TX_MACSEC_AN_LSB_SHIFT			  2		/* Association Number */
100#define AL_ETH_TX_MACSEC_AN_MSB_SHIFT			  3
101#define AL_ETH_TX_MACSEC_SC_LSB_SHIFT			  4		/* Secured Channel */
102#define AL_ETH_TX_MACSEC_SC_MSB_SHIFT			  9
103#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_LSB_SHIFT	 10		/* Secure Payload Length (0x3FFF for non-SL packets) */
104#define AL_ETH_TX_MACSEC_SECURED_PYLD_LEN_MSB_SHIFT	 23
105
106/* Rx Descriptor defines */
107#define AL_ETH_RX_L3_PROTO_IDX_MASK	0x1F
108#define AL_ETH_RX_SRC_VLAN_CNT_MASK	3
109#define AL_ETH_RX_SRC_VLAN_CNT_SHIFT	5
110#define AL_ETH_RX_L4_PROTO_IDX_MASK	0x1F
111#define AL_ETH_RX_L4_PROTO_IDX_SHIFT	8
112
113#define AL_ETH_RX_L3_OFFSET_SHIFT	9
114#define AL_ETH_RX_L3_OFFSET_MASK	(0x7f << AL_ETH_RX_L3_OFFSET_SHIFT)
115#define AL_ETH_RX_HASH_SHIFT		16
116#define AL_ETH_RX_HASH_MASK		(0xffff 	<< AL_ETH_RX_HASH_SHIFT)
117
118#define ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL 5
119#define ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL 7
120
121/* Tx VID Table*/
122#define AL_ETH_TX_VLAN_TABLE_UDMA_MASK		0xF
123#define AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC		(1 << 4)
124
125/* tx gpd defines */
126#define AL_ETH_TX_GPD_L3_PROTO_MASK		0x1f
127#define AL_ETH_TX_GPD_L3_PROTO_SHIFT		0
128#define AL_ETH_TX_GPD_L4_PROTO_MASK		0x1f
129#define AL_ETH_TX_GPD_L4_PROTO_SHIFT		5
130#define AL_ETH_TX_GPD_TUNNEL_CTRL_MASK		0x7
131#define AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT		10
132#define AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK		0x3
133#define AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT	13
134#define AL_ETH_TX_GPD_CAM_DATA_2_SHIFT		32
135#define AL_ETH_TX_GPD_CAM_MASK_2_SHIFT		32
136#define AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT	31
137
138/* tx gcp defines */
139#define AL_ETH_TX_GCP_POLY_SEL_MASK		0x1
140#define AL_ETH_TX_GCP_POLY_SEL_SHIFT		0
141#define AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK	0x1
142#define AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT	1
143#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK	0x1
144#define AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT	2
145#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK	0x1
146#define AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT	3
147#define AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK	0x1
148#define AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT	4
149#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK	0x1
150#define AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT	5
151#define AL_ETH_TX_GCP_TRAIL_SIZE_MASK		0xF
152#define AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT		6
153#define AL_ETH_TX_GCP_HEAD_SIZE_MASK		0xFF
154#define AL_ETH_TX_GCP_HEAD_SIZE_SHIFT		16
155#define AL_ETH_TX_GCP_HEAD_CALC_MASK		0x1
156#define AL_ETH_TX_GCP_HEAD_CALC_SHIFT		24
157#define AL_ETH_TX_GCP_MASK_POLARITY_MASK	0x1
158#define AL_ETH_TX_GCP_MASK_POLARITY_SHIFT	25
159
160#define AL_ETH_TX_GCP_OPCODE_1_MASK		0x3F
161#define AL_ETH_TX_GCP_OPCODE_1_SHIFT		0
162#define AL_ETH_TX_GCP_OPCODE_2_MASK		0x3F
163#define AL_ETH_TX_GCP_OPCODE_2_SHIFT		6
164#define AL_ETH_TX_GCP_OPCODE_3_MASK		0x3F
165#define AL_ETH_TX_GCP_OPCODE_3_SHIFT		12
166#define AL_ETH_TX_GCP_OPSEL_1_MASK		0xF
167#define AL_ETH_TX_GCP_OPSEL_1_SHIFT		0
168#define AL_ETH_TX_GCP_OPSEL_2_MASK		0xF
169#define AL_ETH_TX_GCP_OPSEL_2_SHIFT		4
170#define AL_ETH_TX_GCP_OPSEL_3_MASK		0xF
171#define AL_ETH_TX_GCP_OPSEL_3_SHIFT		8
172#define AL_ETH_TX_GCP_OPSEL_4_MASK		0xF
173#define AL_ETH_TX_GCP_OPSEL_4_SHIFT		12
174
175/*  Tx crc_chksum_replace defines */
176#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS     0x00
177#define L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN      0x20
178#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS      0x40
179#define L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN       0x60
180
181/* rx gpd defines */
182#define AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK		0x1f
183#define AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT		(3 + 0)
184#define AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK		0x1f
185#define AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT		(3 + 8)
186#define AL_ETH_RX_GPD_INNER_L3_PROTO_MASK		0x1f
187#define AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT		(3 + 16)
188#define AL_ETH_RX_GPD_INNER_L4_PROTO_MASK		0x1f
189#define AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT		(3 + 24)
190#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK		0xFF
191#define AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT	32
192#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK		0xFF
193#define AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT	40
194#define AL_ETH_RX_GPD_L3_PRIORITY_MASK			0xFF
195#define AL_ETH_RX_GPD_L3_PRIORITY_SHIFT			48
196#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK		0xFF
197#define AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT		56
198#define AL_ETH_RX_GPD_CAM_DATA_2_SHIFT			32
199#define AL_ETH_RX_GPD_CAM_MASK_2_SHIFT			32
200#define AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT		31
201
202#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET	(106 + 5)
203#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET	(106 + 10)
204#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET	(0 + 5)
205#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET	(0 + 10)
206#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL			(106 + 4)
207#define AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL			4
208#define AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY			(106 + 13)
209#define AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB	(106 + 65)
210
211/* rx gcp defines */
212#define AL_ETH_RX_GCP_POLY_SEL_MASK		0x1
213#define AL_ETH_RX_GCP_POLY_SEL_SHIFT		0
214#define AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK	0x1
215#define AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT	1
216#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK	0x1
217#define AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT	2
218#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK      0x1
219#define AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT	3
220#define AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK	0x1
221#define AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT	4
222#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK       0x1
223#define AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT	5
224#define AL_ETH_RX_GCP_TRAIL_SIZE_MASK		0xF
225#define AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT		6
226#define AL_ETH_RX_GCP_HEAD_SIZE_MASK		0xFF
227#define AL_ETH_RX_GCP_HEAD_SIZE_SHIFT		16
228#define AL_ETH_RX_GCP_HEAD_CALC_MASK		0x1
229#define AL_ETH_RX_GCP_HEAD_CALC_SHIFT		24
230#define AL_ETH_RX_GCP_MASK_POLARITY_MASK	0x1
231#define AL_ETH_RX_GCP_MASK_POLARITY_SHIFT	25
232
233#define AL_ETH_RX_GCP_OPCODE_1_MASK		0x3F
234#define AL_ETH_RX_GCP_OPCODE_1_SHIFT		0
235#define AL_ETH_RX_GCP_OPCODE_2_MASK		0x3F
236#define AL_ETH_RX_GCP_OPCODE_2_SHIFT		6
237#define AL_ETH_RX_GCP_OPCODE_3_MASK		0x3F
238#define AL_ETH_RX_GCP_OPCODE_3_SHIFT		12
239#define AL_ETH_RX_GCP_OPSEL_1_MASK		0xF
240#define AL_ETH_RX_GCP_OPSEL_1_SHIFT		0
241#define AL_ETH_RX_GCP_OPSEL_2_MASK		0xF
242#define AL_ETH_RX_GCP_OPSEL_2_SHIFT		4
243#define AL_ETH_RX_GCP_OPSEL_3_MASK		0xF
244#define AL_ETH_RX_GCP_OPSEL_3_SHIFT		8
245#define AL_ETH_RX_GCP_OPSEL_4_MASK		0xF
246#define AL_ETH_RX_GCP_OPSEL_4_SHIFT		12
247
248#define AL_ETH_MDIO_DELAY_PERIOD	1 /* micro seconds to wait when polling mdio status */
249#define AL_ETH_MDIO_DELAY_COUNT		150 /* number of times to poll */
250#define AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT	200 /* Rx descriptors coalescing timeout in SB clocks */
251
252#define AL_ETH_EPE_ENTRIES_NUM 26
253static struct al_eth_epe_p_reg_entry al_eth_epe_p_regs[AL_ETH_EPE_ENTRIES_NUM] = {
254	{ 0x0, 0x0, 0x0 },
255	{ 0x0, 0x0, 0x1 },
256	{ 0x0, 0x0, 0x2 },
257	{ 0x0, 0x0, 0x3 },
258	{ 0x18100, 0xFFFFF, 0x80000004 },
259	{ 0x188A8, 0xFFFFF, 0x80000005 },
260	{ 0x99100, 0xFFFFF, 0x80000006 },
261	{ 0x98100, 0xFFFFF, 0x80000007 },
262	{ 0x10800, 0x7FFFF, 0x80000008 },
263	{ 0x20000, 0x73FFF, 0x80000009 },
264	{ 0x20000, 0x70000, 0x8000000A },
265	{ 0x186DD, 0x7FFFF, 0x8000000B },
266	{ 0x30600, 0x7FF00, 0x8000000C },
267	{ 0x31100, 0x7FF00, 0x8000000D },
268	{ 0x32F00, 0x7FF00, 0x8000000E },
269	{ 0x32900, 0x7FF00, 0x8000000F },
270	{ 0x105DC, 0x7FFFF, 0x80010010 },
271	{ 0x188E5, 0x7FFFF, 0x80000011 },
272	{ 0x72000, 0x72000, 0x80000012 },
273	{ 0x70000, 0x72000, 0x80000013 },
274	{ 0x46558, 0x7FFFF, 0x80000001 },
275	{ 0x18906, 0x7FFFF, 0x80000015 },
276	{ 0x18915, 0x7FFFF, 0x80000016 },
277	{ 0x31B00, 0x7FF00, 0x80000017 },
278	{ 0x30400, 0x7FF00, 0x80000018 },
279	{ 0x0, 0x0, 0x8000001F }
280};
281
282
283static struct al_eth_epe_control_entry al_eth_epe_control_table[AL_ETH_EPE_ENTRIES_NUM] = {
284	{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},
285	{{ 0x280004C, 0x746000, 0xA46030, 0xE00000, 0x2, 0x400000 }},
286	{{ 0x2800054, 0x746000, 0xA46030, 0x1600000, 0x2, 0x400000 }},
287	{{ 0x280005C, 0x746000, 0xA46030, 0x1E00000, 0x2, 0x400000 }},
288	{{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }},
289	{{ 0x2800042, 0xD42000, 0x0, 0x400000, 0x1010412, 0x400000 }},
290	{{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }},
291	{{ 0x2800042, 0xE42000, 0x0, 0x400000, 0x2020002, 0x400000 }},
292	{{ 0x280B046, 0x0, 0x6C1008, 0x0, 0x4, 0x406800 }},
293	{{ 0x2800049, 0xF44060, 0x1744080, 0x14404, 0x6, 0x400011 }},
294	{{ 0x2015049, 0xF44060, 0x1744080, 0x14404, 0x8080007, 0x400011 }},
295	{{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }},
296	{{ 0x2815042, 0x1F42000, 0x2042010, 0x1414460, 0x10100009, 0x40B800 }},
297	{{ 0x2815042, 0x1F42000, 0x2042010, 0x800000, 0x10100009, 0x40B800 }},
298	{{ 0x280B042, 0x0, 0x0, 0x430400, 0x4040009, 0x0 }},
299	{{ 0x2815580, 0x0, 0x0, 0x0, 0x4040005, 0x0 }},
300	{{ 0x280B000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},
301	{{ 0x2800040, 0x174E000, 0x0, 0x0, 0xE, 0x406800 }},
302	{{ 0x280B000, 0x0, 0x0, 0x600000, 0x1, 0x406800 }},
303	{{ 0x280B000, 0x0, 0x0, 0xE00000, 0x1, 0x406800 }},
304	{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }},
305	{{ 0x280B046, 0x0, 0x0, 0x2800000, 0x7, 0x400000 }},
306	{{ 0x280B046, 0xF60040, 0x6C1004, 0x2800000, 0x6, 0x406811 }},
307	{{ 0x2815042, 0x1F43028, 0x2000000, 0xC00000, 0x10100009, 0x40B800 }},
308	{{ 0x2815400, 0x0, 0x0, 0x0, 0x4040005, 0x0 }},
309	{{ 0x2800000, 0x0, 0x0, 0x0, 0x1, 0x400000 }}
310};
311
312
313#define AL_ETH_IS_1G_MAC(mac_mode) (((mac_mode) == AL_ETH_MAC_MODE_RGMII) || ((mac_mode) == AL_ETH_MAC_MODE_SGMII))
314#define AL_ETH_IS_10G_MAC(mac_mode)	(((mac_mode) == AL_ETH_MAC_MODE_10GbE_Serial) ||	\
315					((mac_mode) == AL_ETH_MAC_MODE_10G_SGMII) ||		\
316					((mac_mode) == AL_ETH_MAC_MODE_SGMII_2_5G))
317#define AL_ETH_IS_25G_MAC(mac_mode) ((mac_mode) == AL_ETH_MAC_MODE_KR_LL_25G)
318
319static const char *al_eth_mac_mode_str(enum al_eth_mac_mode mode)
320{
321	switch(mode) {
322	case AL_ETH_MAC_MODE_RGMII:
323		return "RGMII";
324	case AL_ETH_MAC_MODE_SGMII:
325		return "SGMII";
326	case AL_ETH_MAC_MODE_SGMII_2_5G:
327		return "SGMII_2_5G";
328	case AL_ETH_MAC_MODE_10GbE_Serial:
329		return "KR";
330        case AL_ETH_MAC_MODE_KR_LL_25G:
331		return "KR_LL_25G";
332	case AL_ETH_MAC_MODE_10G_SGMII:
333		return "10G_SGMII";
334	case AL_ETH_MAC_MODE_XLG_LL_40G:
335		return "40G_LL";
336	case AL_ETH_MAC_MODE_XLG_LL_50G:
337		return "50G_LL";
338	default:
339		return "N/A";
340	}
341}
342
343/**
344 * change and wait udma state
345 *
346 * @param dma the udma to change its state
347 * @param new_state
348 *
349 * @return 0 on success. otherwise on failure.
350 */
351static int al_udma_state_set_wait(struct al_udma *dma, enum al_udma_state new_state)
352{
353	enum al_udma_state state;
354	enum al_udma_state expected_state = new_state;
355	int count = 1000;
356	int rc;
357
358	rc = al_udma_state_set(dma, new_state);
359	if (rc != 0) {
360		al_warn("[%s] warn: failed to change state, error %d\n", dma->name, rc);
361		return rc;
362	}
363
364	if ((new_state == UDMA_NORMAL) || (new_state == UDMA_DISABLE))
365		expected_state = UDMA_IDLE;
366
367	do {
368		state = al_udma_state_get(dma);
369		if (state == expected_state)
370			break;
371		al_udelay(1);
372		if (count-- == 0) {
373			al_warn("[%s] warn: dma state didn't change to %s\n",
374				 dma->name, al_udma_states_name[new_state]);
375			return -ETIMEDOUT;
376		}
377	} while (1);
378	return 0;
379}
380
381static void al_eth_epe_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
382		struct al_eth_epe_p_reg_entry *reg_entry,
383		struct al_eth_epe_control_entry *control_entry)
384{
385	al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_data, reg_entry->data);
386	al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_mask, reg_entry->mask);
387	al_reg_write32(&adapter->ec_regs_base->epe_p[idx].comp_ctrl, reg_entry->ctrl);
388
389	al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_data, reg_entry->data);
390	al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_mask, reg_entry->mask);
391	al_reg_write32(&adapter->ec_regs_base->msp_c[idx].p_comp_ctrl, reg_entry->ctrl);
392
393	/*control table  0*/
394	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_addr, idx);
395	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_6,
396			control_entry->data[5]);
397	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_2,
398			control_entry->data[1]);
399	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_3,
400			control_entry->data[2]);
401	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_4,
402			control_entry->data[3]);
403	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_5,
404			control_entry->data[4]);
405	al_reg_write32(&adapter->ec_regs_base->epe[0].act_table_data_1,
406			control_entry->data[0]);
407
408	/*control table 1*/
409	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_addr, idx);
410	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_6,
411			control_entry->data[5]);
412	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_2,
413			control_entry->data[1]);
414	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_3,
415			control_entry->data[2]);
416	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_4,
417			control_entry->data[3]);
418	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_5,
419			control_entry->data[4]);
420	al_reg_write32(&adapter->ec_regs_base->epe[1].act_table_data_1,
421			control_entry->data[0]);
422}
423
424static void al_eth_epe_init(struct al_hal_eth_adapter *adapter)
425{
426	int idx;
427
428	if (adapter->enable_rx_parser == 0) {
429		al_dbg("eth [%s]: disable rx parser\n", adapter->name);
430
431		al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000000);
432		al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7);
433
434		al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000000);
435		al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0x7);
436
437		return;
438	}
439	al_dbg("eth [%s]: enable rx parser\n", adapter->name);
440	for (idx = 0; idx < AL_ETH_EPE_ENTRIES_NUM; idx++)
441		al_eth_epe_entry_set(adapter, idx, &al_eth_epe_p_regs[idx], &al_eth_epe_control_table[idx]);
442
443	al_reg_write32(&adapter->ec_regs_base->epe[0].res_def, 0x08000080);
444	al_reg_write32(&adapter->ec_regs_base->epe[0].res_in, 0x7);
445
446	al_reg_write32(&adapter->ec_regs_base->epe[1].res_def, 0x08000080);
447	al_reg_write32(&adapter->ec_regs_base->epe[1].res_in, 0);
448
449	/* header length as function of 4 bits value, for GRE, when C bit is set, the header len should be increase by 4*/
450	al_reg_write32(&adapter->ec_regs_base->epe_h[8].hdr_len, (4 << 16) | 4);
451
452	/* select the outer information when writing the rx descriptor (l3 protocol index etc) */
453	al_reg_write32(&adapter->ec_regs_base->rfw.meta, EC_RFW_META_L3_LEN_CALC);
454
455	al_reg_write32(&adapter->ec_regs_base->rfw.checksum, EC_RFW_CHECKSUM_HDR_SEL);
456}
457
458/**
459 * read 40G MAC registers (indirect access)
460 *
461 * @param adapter pointer to the private structure
462 * @param reg_addr address in the an registers
463 *
464 * @return the register value
465 */
466static uint32_t al_eth_40g_mac_reg_read(
467			struct al_hal_eth_adapter *adapter,
468			uint32_t reg_addr)
469{
470	uint32_t val;
471
472	/* indirect access */
473	al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr);
474	val = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data);
475
476	al_dbg("[%s]: %s - reg %d. val 0x%x",
477	       adapter->name, __func__, reg_addr, val);
478
479	return val;
480}
481
482/**
483 * write 40G MAC registers (indirect access)
484 *
485 * @param adapter pointer to the private structure
486 * @param reg_addr address in the an registers
487 * @param reg_data value to write to the register
488 *
489 */
490static void al_eth_40g_mac_reg_write(
491			struct al_hal_eth_adapter *adapter,
492			uint32_t reg_addr,
493			uint32_t reg_data)
494{
495	/* indirect access */
496	al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, reg_addr);
497	al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, reg_data);
498
499	al_dbg("[%s]: %s - reg %d. val 0x%x",
500	       adapter->name, __func__, reg_addr, reg_data);
501}
502
503/**
504 * read 40G PCS registers (indirect access)
505 *
506 * @param adapter pointer to the private structure
507 * @param reg_addr address in the an registers
508 *
509 * @return the register value
510 */
511static uint32_t al_eth_40g_pcs_reg_read(
512			struct al_hal_eth_adapter *adapter,
513			uint32_t reg_addr)
514{
515	uint32_t val;
516
517	/* indirect access */
518	al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr);
519	val = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data);
520
521	al_dbg("[%s]: %s - reg %d. val 0x%x",
522	       adapter->name, __func__, reg_addr, val);
523
524	return val;
525}
526
527/**
528 * write 40G PCS registers (indirect access)
529 *
530 * @param adapter pointer to the private structure
531 * @param reg_addr address in the an registers
532 * @param reg_data value to write to the register
533 *
534 */
535static void al_eth_40g_pcs_reg_write(
536			struct al_hal_eth_adapter *adapter,
537			uint32_t reg_addr,
538			uint32_t reg_data)
539{
540	/* indirect access */
541	al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, reg_addr);
542	al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, reg_data);
543
544	al_dbg("[%s]: %s - reg %d. val 0x%x",
545	       adapter->name, __func__, reg_addr, reg_data);
546}
547
548/*****************************API Functions  **********************************/
549/*adapter management */
550/**
551 * initialize the ethernet adapter's DMA
552 */
553int al_eth_adapter_init(struct al_hal_eth_adapter *adapter, struct al_eth_adapter_params *params)
554{
555	struct al_udma_params udma_params;
556	struct al_udma_m2s_pkt_len_conf conf;
557	int i;
558	uint32_t reg;
559	int rc;
560
561	al_dbg("eth [%s]: initialize controller's UDMA. id = %d\n", params->name, params->udma_id);
562	al_dbg("eth [%s]: UDMA base regs: %p\n", params->name, params->udma_regs_base);
563	al_dbg("eth [%s]: EC base regs: %p\n", params->name, params->ec_regs_base);
564	al_dbg("eth [%s]: MAC base regs: %p\n", params->name, params->mac_regs_base);
565	al_dbg("eth [%s]: enable_rx_parser: %x\n", params->name, params->enable_rx_parser);
566
567	adapter->name = params->name;
568	adapter->rev_id = params->rev_id;
569	adapter->udma_id = params->udma_id;
570	adapter->udma_regs_base = params->udma_regs_base;
571	adapter->ec_regs_base = (struct al_ec_regs __iomem*)params->ec_regs_base;
572	adapter->mac_regs_base = (struct al_eth_mac_regs __iomem*)params->mac_regs_base;
573	adapter->unit_regs = (struct unit_regs __iomem *)params->udma_regs_base;
574	adapter->enable_rx_parser = params->enable_rx_parser;
575	adapter->ec_ints_base = (void __iomem *)((uint32_t)adapter->ec_regs_base + 0x1c00);
576	adapter->mac_ints_base = (void __iomem *)((uint32_t)adapter->mac_regs_base + 0x800);
577
578	/* initialize Tx udma */
579	udma_params.udma_regs_base = adapter->unit_regs;
580	udma_params.type = UDMA_TX;
581	udma_params.num_of_queues = AL_ETH_UDMA_TX_QUEUES;
582	udma_params.name = "eth tx";
583	rc = al_udma_init(&adapter->tx_udma, &udma_params);
584
585	if (rc != 0) {
586		al_err("failed to initialize %s, error %d\n",
587			 udma_params.name, rc);
588		return rc;
589	}
590	rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_NORMAL);
591	if (rc != 0) {
592		al_err("[%s]: failed to change state, error %d\n",
593			 udma_params.name, rc);
594		return rc;
595	}
596	/* initialize Rx udma */
597	udma_params.udma_regs_base = adapter->unit_regs;
598	udma_params.type = UDMA_RX;
599	udma_params.num_of_queues = AL_ETH_UDMA_RX_QUEUES;
600	udma_params.name = "eth rx";
601	rc = al_udma_init(&adapter->rx_udma, &udma_params);
602
603	if (rc != 0) {
604		al_err("failed to initialize %s, error %d\n",
605			 udma_params.name, rc);
606		return rc;
607	}
608
609	rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_NORMAL);
610	if (rc != 0) {
611		al_err("[%s]: failed to change state, error %d\n",
612			 udma_params.name, rc);
613		return rc;
614	}
615	al_dbg("eth [%s]: controller's UDMA successfully initialized\n",
616		 params->name);
617
618	/* set max packet size to 1M (for TSO) */
619	conf.encode_64k_as_zero = AL_TRUE;
620	conf.max_pkt_size = 0xfffff;
621	al_udma_m2s_packet_size_cfg_set(&adapter->tx_udma, &conf);
622
623	/* set m2s (tx) max descriptors to max data buffers number and one for
624	 * meta descriptor
625	 */
626	al_udma_m2s_max_descs_set(&adapter->tx_udma, AL_ETH_PKT_MAX_BUFS + 1);
627
628	/* set s2m (rx) max descriptors to max data buffers */
629	al_udma_s2m_max_descs_set(&adapter->rx_udma, AL_ETH_PKT_MAX_BUFS);
630
631	/* set s2m burst lenght when writing completion descriptors to 64 bytes
632	 */
633	al_udma_s2m_compl_desc_burst_config(&adapter->rx_udma, 64);
634
635	/* if pointer to ec regs provided, then init the tx meta cache of this udma*/
636	if (adapter->ec_regs_base != NULL) {
637		// INIT TX CACHE TABLE:
638		for (i = 0; i < 4; i++) {
639			al_reg_write32(&adapter->ec_regs_base->tso.cache_table_addr, i + (adapter->udma_id * 4));
640			al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_1, 0x00000000);
641			al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_2, 0x00000000);
642			al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_3, 0x00000000);
643			al_reg_write32(&adapter->ec_regs_base->tso.cache_table_data_4, 0x00000000);
644		}
645	}
646	// only udma 0 allowed to init ec
647	if (adapter->udma_id != 0) {
648		return 0;
649	}
650	/* enable Ethernet controller: */
651	/* enable internal machines*/
652	al_reg_write32(&adapter->ec_regs_base->gen.en, 0xffffffff);
653	al_reg_write32(&adapter->ec_regs_base->gen.fifo_en, 0xffffffff);
654
655	if (adapter->rev_id > AL_ETH_REV_ID_0) {
656		/* enable A0 descriptor structure */
657		al_reg_write32_masked(&adapter->ec_regs_base->gen.en_ext,
658				      EC_GEN_EN_EXT_CACHE_WORD_SPLIT,
659				      EC_GEN_EN_EXT_CACHE_WORD_SPLIT);
660
661		/* use mss value in the descriptor */
662		al_reg_write32(&adapter->ec_regs_base->tso.cfg_add_0,
663						EC_TSO_CFG_ADD_0_MSS_SEL);
664
665		/* enable tunnel TSO */
666		al_reg_write32(&adapter->ec_regs_base->tso.cfg_tunnel,
667						(EC_TSO_CFG_TUNNEL_EN_TUNNEL_TSO |
668						 EC_TSO_CFG_TUNNEL_EN_UDP_CHKSUM |
669						 EC_TSO_CFG_TUNNEL_EN_UDP_LEN |
670						 EC_TSO_CFG_TUNNEL_EN_IPV6_PLEN |
671						 EC_TSO_CFG_TUNNEL_EN_IPV4_CHKSUM |
672						 EC_TSO_CFG_TUNNEL_EN_IPV4_IDEN |
673						 EC_TSO_CFG_TUNNEL_EN_IPV4_TLEN));
674	}
675
676	/* swap input byts from MAC RX */
677	al_reg_write32(&adapter->ec_regs_base->mac.gen, 0x00000001);
678	/* swap output bytes to MAC TX*/
679	al_reg_write32(&adapter->ec_regs_base->tmi.tx_cfg, EC_TMI_TX_CFG_EN_FWD_TO_RX|EC_TMI_TX_CFG_SWAP_BYTES);
680
681	/* TODO: check if we need this line*/
682	al_reg_write32(&adapter->ec_regs_base->tfw_udma[0].fwd_dec, 0x000003fb);
683
684	/* RFW configuration: default 0 */
685	al_reg_write32(&adapter->ec_regs_base->rfw_default[0].opt_1, 0x00000001);
686
687	/* VLAN table address*/
688	al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, 0x00000000);
689	/* VLAN table data*/
690	al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, 0x00000000);
691	/* HASH config (select toeplitz and bits 7:0 of the thash result, enable
692	 * symmetric hash) */
693	al_reg_write32(&adapter->ec_regs_base->rfw.thash_cfg_1,
694			EC_RFW_THASH_CFG_1_ENABLE_IP_SWAP |
695			EC_RFW_THASH_CFG_1_ENABLE_PORT_SWAP);
696
697	al_eth_epe_init(adapter);
698
699	/* disable TSO padding and use mac padding instead */
700	reg = al_reg_read32(&adapter->ec_regs_base->tso.in_cfg);
701	reg &= ~0x7F00; /*clear bits 14:8 */
702	al_reg_write32(&adapter->ec_regs_base->tso.in_cfg, reg);
703
704	return 0;
705}
706
707/*****************************API Functions  **********************************/
708/*adapter management */
709/**
710 * enable the ec and mac interrupts
711 */
712int al_eth_ec_mac_ints_config(struct al_hal_eth_adapter *adapter)
713{
714
715	al_dbg("eth [%s]: enable ethernet and mac interrupts\n", adapter->name);
716
717	// only udma 0 allowed to init ec
718	if (adapter->udma_id != 0)
719		return -EPERM;
720
721	/* enable mac ints */
722	al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_A,
723		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
724	al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_B,
725		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
726	al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_C,
727		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
728	al_iofic_config(adapter->ec_ints_base, AL_INT_GROUP_D,
729		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
730
731	/* unmask MAC int */
732	al_iofic_unmask(adapter->ec_ints_base, AL_INT_GROUP_A, 8);
733
734	/* enable ec interrupts */
735	al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_A,
736		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
737	al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_B,
738		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
739	al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_C,
740		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
741	al_iofic_config(adapter->mac_ints_base, AL_INT_GROUP_D,
742		INT_CONTROL_GRP_SET_ON_POSEDGE | INT_CONTROL_GRP_CLEAR_ON_READ);
743
744	/* eee active */
745	al_iofic_unmask(adapter->mac_ints_base, AL_INT_GROUP_B, AL_BIT(14));
746
747	al_iofic_unmask(adapter->unit_regs, AL_INT_GROUP_D, AL_BIT(11));
748	return 0;
749}
750
751/**
752 * ec and mac interrupt service routine
753 * read and print asserted interrupts
754 *
755 * @param adapter pointer to the private structure
756 *
757 * @return 0 on success. otherwise on failure.
758 */
759int al_eth_ec_mac_isr(struct al_hal_eth_adapter *adapter)
760{
761	uint32_t cause;
762	al_dbg("[%s]: ethernet interrupts handler\n", adapter->name);
763
764	// only udma 0 allowed to init ec
765	if (adapter->udma_id != 0)
766		return -EPERM;
767
768	/* read ec cause */
769	cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_A);
770	al_dbg("[%s]: ethernet group A cause 0x%08x\n", adapter->name, cause);
771	if (cause & 1)
772	{
773		cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_A);
774		al_dbg("[%s]: mac group A cause 0x%08x\n", adapter->name, cause);
775
776		cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_B);
777		al_dbg("[%s]: mac group B cause 0x%08x\n", adapter->name, cause);
778
779		cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_C);
780		al_dbg("[%s]: mac group C cause 0x%08x\n", adapter->name, cause);
781
782		cause = al_iofic_read_cause(adapter->mac_ints_base, AL_INT_GROUP_D);
783		al_dbg("[%s]: mac group D cause 0x%08x\n", adapter->name, cause);
784	}
785	cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_B);
786	al_dbg("[%s]: ethernet group B cause 0x%08x\n", adapter->name, cause);
787	cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_C);
788	al_dbg("[%s]: ethernet group C cause 0x%08x\n", adapter->name, cause);
789	cause = al_iofic_read_cause(adapter->ec_ints_base, AL_INT_GROUP_D);
790	al_dbg("[%s]: ethernet group D cause 0x%08x\n", adapter->name, cause);
791
792	return 0;
793}
794
795/**
796 * stop the DMA of the ethernet adapter
797 */
798int al_eth_adapter_stop(struct al_hal_eth_adapter *adapter)
799{
800	int rc;
801
802	al_dbg("eth [%s]: stop controller's UDMA\n", adapter->name);
803
804	/* disable Tx dma*/
805	rc = al_udma_state_set_wait(&adapter->tx_udma, UDMA_DISABLE);
806	if (rc != 0) {
807		al_warn("[%s] warn: failed to change state, error %d\n",
808			 adapter->tx_udma.name, rc);
809		return rc;
810	}
811
812	al_dbg("eth [%s]: controller's TX UDMA stopped\n",
813		 adapter->name);
814	/* disable Rx dma*/
815	rc = al_udma_state_set_wait(&adapter->rx_udma, UDMA_DISABLE);
816	if (rc != 0) {
817		al_warn("[%s] warn: failed to change state, error %d\n",
818			 adapter->rx_udma.name, rc);
819		return rc;
820	}
821
822	al_dbg("eth [%s]: controller's RX UDMA stopped\n",
823		 adapter->name);
824	return 0;
825}
826
827int al_eth_adapter_reset(struct al_hal_eth_adapter *adapter)
828{
829	al_dbg("eth [%s]: reset controller's UDMA\n", adapter->name);
830
831	return -EPERM;
832}
833
834/* Q management */
835/**
836 * Configure and enable a queue ring
837 */
838int al_eth_queue_config(struct al_hal_eth_adapter *adapter, enum al_udma_type type, uint32_t qid,
839			     struct al_udma_q_params *q_params)
840{
841	struct al_udma *udma;
842	int rc;
843
844	al_dbg("eth [%s]: config UDMA %s queue %d\n", adapter->name,
845		 type == UDMA_TX ? "Tx" : "Rx", qid);
846
847	if (type == UDMA_TX) {
848		udma = &adapter->tx_udma;
849	} else {
850		udma = &adapter->rx_udma;
851	}
852
853	q_params->adapter_rev_id = adapter->rev_id;
854
855	rc = al_udma_q_init(udma, qid, q_params);
856
857	if (rc)
858		return rc;
859
860	if (type == UDMA_RX) {
861		rc = al_udma_s2m_q_compl_coal_config(&udma->udma_q[qid],
862				AL_TRUE, AL_ETH_S2M_UDMA_COMP_COAL_TIMEOUT);
863
864		al_assert(q_params->cdesc_size <= 32);
865
866		if (q_params->cdesc_size > 16)
867			al_reg_write32_masked(&adapter->ec_regs_base->rfw.out_cfg,
868					EC_RFW_OUT_CFG_META_CNT_MASK, 2);
869	}
870	return rc;
871}
872
873int al_eth_queue_enable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)),
874			enum al_udma_type type __attribute__((__unused__)),
875			uint32_t qid __attribute__((__unused__)))
876{
877	return -EPERM;
878}
879int al_eth_queue_disable(struct al_hal_eth_adapter *adapter __attribute__((__unused__)),
880			 enum al_udma_type type __attribute__((__unused__)),
881			 uint32_t qid __attribute__((__unused__)))
882{
883	return -EPERM;
884}
885
886/* MAC layer */
887int al_eth_rx_pkt_limit_config(struct al_hal_eth_adapter *adapter, uint32_t min_rx_len, uint32_t max_rx_len)
888{
889	al_assert(max_rx_len <= AL_ETH_MAX_FRAME_LEN);
890
891	/* EC minimum packet length [bytes] in RX */
892	al_reg_write32(&adapter->ec_regs_base->mac.min_pkt, min_rx_len);
893	/* EC maximum packet length [bytes] in RX */
894	al_reg_write32(&adapter->ec_regs_base->mac.max_pkt, max_rx_len);
895
896	if (adapter->rev_id > AL_ETH_REV_ID_2) {
897		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, min_rx_len);
898		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, max_rx_len);
899	}
900
901	/* configure the MAC's max rx length, add 16 bytes so the packet get
902	 * trimmed by the EC/Async_fifo rather by the MAC
903	*/
904	if (AL_ETH_IS_1G_MAC(adapter->mac_mode))
905		al_reg_write32(&adapter->mac_regs_base->mac_1g.frm_len, max_rx_len + 16);
906	else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))
907		/* 10G MAC control register  */
908		al_reg_write32(&adapter->mac_regs_base->mac_10g.frm_len, (max_rx_len + 16));
909	else
910		al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_FRM_LENGTH_ADDR, (max_rx_len + 16));
911
912	return 0;
913}
914
915/* configure the mac media type. */
916int al_eth_mac_config(struct al_hal_eth_adapter *adapter, enum al_eth_mac_mode mode)
917{
918	switch(mode) {
919	case AL_ETH_MAC_MODE_RGMII:
920		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);
921
922		/* 1G MAC control register */
923		/* bit[0]  - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start
924		 * bit[1]  - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start
925		 * bit[3]  - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet
926		 * bit[4]  - PROMIS_EN - asserted to enable MAC promiscuous mode
927		 * bit[23] - CNTL_FRM-ENA - asserted to enable control frames
928		 * bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller
929		 */
930		al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010);
931
932		/* RX_SECTION_EMPTY,  */
933		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000);
934		/* RX_SECTION_FULL,  */
935		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */
936		/* RX_ALMOST_EMPTY,  */
937		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008);
938		/* RX_ALMOST_FULL,  */
939		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008);
940
941
942		/* TX_SECTION_EMPTY,  */
943		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */
944		/* TX_SECTION_FULL, 0 - store and forward, */
945		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c);
946		/* TX_ALMOST_EMPTY,  */
947		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008);
948		/* TX_ALMOST_FULL,  */
949		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008);
950
951		/* XAUI MAC control register */
952		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000000);
953
954		/* 1G MACSET 1G */
955		/* taking sel_1000/sel_10 inputs from rgmii PHY, and not from register.
956		 * disabling magic_packets detection in mac */
957		al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002);
958		/* RGMII set 1G */
959		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);
960		al_reg_write32(&adapter->mac_regs_base->gen.rgmii_sel, 0xF);
961		break;
962	case AL_ETH_MAC_MODE_SGMII:
963		if (adapter->rev_id > AL_ETH_REV_ID_2) {
964			/* configure and enable the ASYNC FIFO between the MACs and the EC */
965			/* TX min packet size */
966			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
967			/* TX max packet size */
968			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
969			/* TX input bus configuration */
970			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
971			/* TX output bus configuration */
972			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);
973			/* TX Valid/ready configuration */
974			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000121);
975			/* RX min packet size */
976			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */
977			/* RX max packet size */
978			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */
979			/* RX input bus configuration */
980			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);
981			/* RX output bus configuration */
982			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
983			/* RX Valid/ready configuration */
984			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000212);
985			/* V3 additional MAC selection */
986			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);
987			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000001);
988			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
989			al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);
990			/* ASYNC FIFO ENABLE */
991			al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
992			/* Timestamp_configuration */
993			al_reg_write32(&adapter->mac_regs_base->gen_v3.spare,
994					ETH_MAC_GEN_V3_SPARE_CHICKEN_DISABLE_TIMESTAMP_STRETCH);
995		}
996
997		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40053210);
998
999		/* 1G MAC control register */
1000		/* bit[0]  - TX_ENA - zeroed by default. Should be asserted by al_eth_mac_start
1001		 * bit[1]  - RX_ENA - zeroed by default. Should be asserted by al_eth_mac_start
1002		 * bit[3]  - ETH_SPEED - zeroed to enable 10/100 Mbps Ethernet
1003		 * bit[4]  - PROMIS_EN - asserted to enable MAC promiscuous mode
1004		 * bit[23] - CNTL_FRM-ENA - asserted to enable control frames
1005		 * bit[24] - NO_LGTH_CHECK - asserted to disable length checks, which is done in the controller
1006		 */
1007		al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x01800010);
1008
1009		/* RX_SECTION_EMPTY,  */
1010		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_empty, 0x00000000);
1011		/* RX_SECTION_FULL,  */
1012		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_section_full, 0x0000000c); /* must be larger than almost empty */
1013		/* RX_ALMOST_EMPTY,  */
1014		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_empty, 0x00000008);
1015		/* RX_ALMOST_FULL,  */
1016		al_reg_write32(&adapter->mac_regs_base->mac_1g.rx_almost_full, 0x00000008);
1017
1018
1019		/* TX_SECTION_EMPTY,  */
1020		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_empty, 0x00000008); /* 8 ? */
1021		/* TX_SECTION_FULL, 0 - store and forward, */
1022		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_section_full, 0x0000000c);
1023		/* TX_ALMOST_EMPTY,  */
1024		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_empty, 0x00000008);
1025		/* TX_ALMOST_FULL,  */
1026		al_reg_write32(&adapter->mac_regs_base->mac_1g.tx_almost_full, 0x00000008);
1027
1028		/* XAUI MAC control register */
1029		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x000000c0);
1030
1031		/* 1G MACSET 1G */
1032		/* taking sel_1000/sel_10 inputs from rgmii_converter, and not from register.
1033		 * disabling magic_packets detection in mac */
1034		al_reg_write32(&adapter->mac_regs_base->gen.mac_1g_cfg, 0x00000002);
1035		/* SerDes configuration */
1036		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);
1037		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);
1038		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);
1039
1040		// FAST AN -- Testing only
1041#ifdef AL_HAL_ETH_FAST_AN
1042		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000012);
1043		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000040);
1044		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000013);
1045		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x00000000);
1046#endif
1047
1048		/* Setting PCS i/f mode to SGMII (instead of default 1000Base-X) */
1049		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000014);
1050		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x0000000b);
1051		/* setting dev_ability to have speed of 1000Mb, [11:10] = 2'b10 */
1052		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 0x00000004);
1053		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data, 0x000009A0);
1054		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1055				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1056				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1057		break;
1058
1059	case AL_ETH_MAC_MODE_SGMII_2_5G:
1060		if (adapter->rev_id > AL_ETH_REV_ID_2) {
1061			/* configure and enable the ASYNC FIFO between the MACs and the EC */
1062			/* TX min packet size */
1063			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
1064			/* TX max packet size */
1065			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
1066			/* TX input bus configuration */
1067			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
1068			/* TX output bus configuration */
1069			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);
1070			/* TX Valid/ready configuration */
1071			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);
1072			/* RX input bus configuration */
1073			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);
1074			/* RX output bus configuration */
1075			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
1076			/* RX Valid/ready configuration */
1077			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);
1078			/* V3 additional MAC selection */
1079			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);
1080			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);
1081			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
1082			al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050);
1083			/* ASYNC FIFO ENABLE */
1084			al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
1085		}
1086
1087		/* MAC register file */
1088		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022830);
1089		/* XAUI MAC control register */
1090		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001);
1091		al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x00000028);
1092		al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00001140);
1093		/* RXAUI MAC control register */
1094		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1095/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1096		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1097/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1098		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,
1099				      ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);
1100		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);
1101		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);
1102		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);
1103
1104		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1105				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1106				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1107		break;
1108
1109	case AL_ETH_MAC_MODE_10GbE_Serial:
1110		if (adapter->rev_id > AL_ETH_REV_ID_2) {
1111			/* configure and enable the ASYNC FIFO between the MACs and the EC */
1112			/* TX min packet size */
1113			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
1114			/* TX max packet size */
1115			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
1116			/* TX input bus configuration */
1117			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
1118			/* TX output bus configuration */
1119			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);
1120			/* TX Valid/ready configuration */
1121			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);
1122			/* RX min packet size */
1123			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */
1124			/* RX max packet size */
1125			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */
1126			/* RX input bus configuration */
1127			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);
1128			/* RX output bus configuration */
1129			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
1130			/* RX Valid/ready configuration */
1131			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);
1132			/* V3 additional MAC selection */
1133			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);
1134			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);
1135			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
1136			al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000050);
1137			/* ASYNC FIFO ENABLE */
1138			al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
1139		}
1140
1141		/* MAC register file */
1142		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);
1143		/* XAUI MAC control register */
1144		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);
1145		/* RXAUI MAC control register */
1146		al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);
1147		al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);
1148		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1149/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1150		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1151/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1152		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,
1153					~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910);
1154		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);
1155		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);
1156		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);
1157
1158		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1159				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1160				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1161		break;
1162
1163	case AL_ETH_MAC_MODE_KR_LL_25G:
1164			/* select 25G SERDES lane 0 and lane 1 */
1165			al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x03821101);
1166		if (adapter->rev_id > AL_ETH_REV_ID_2) {
1167			/* configure and enable the ASYNC FIFO between the MACs and the EC */
1168			/* TX min packet size */
1169			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
1170			/* TX max packet size */
1171			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
1172			/* TX input bus configuration */
1173			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
1174			/* TX output bus configuration */
1175			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00030020);
1176			/* TX Valid/ready configuration */
1177			al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);
1178			/* RX min packet size */
1179			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */
1180			/* RX max packet size */
1181			/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */
1182			/* RX input bus configuration */
1183			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00030020);
1184			/* RX output bus configuration */
1185			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
1186			/* RX Valid/ready configuration */
1187			al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000012);
1188			/* V3 additional MAC selection */
1189			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000000);
1190			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);
1191			al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
1192			al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x000000a0);
1193			/* ASYNC FIFO ENABLE */
1194			al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
1195		}
1196
1197		/* MAC register file */
1198		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);
1199		/* XAUI MAC control register */
1200		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);
1201		/* RXAUI MAC control register */
1202		al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);
1203		al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);
1204		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1205/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1206		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1207/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1208		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,
1209					~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910);
1210		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);
1211		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0);
1212		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);
1213
1214		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1215				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1216				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1217		break;
1218
1219	case AL_ETH_MAC_MODE_10G_SGMII:
1220		/* MAC register file */
1221		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810);
1222
1223		/* XAUI MAC control register */
1224		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000001);
1225
1226		al_reg_write32(&adapter->mac_regs_base->mac_10g.if_mode, 0x0000002b);
1227		al_reg_write32(&adapter->mac_regs_base->mac_10g.control, 0x00009140);
1228		// FAST AN -- Testing only
1229#ifdef AL_HAL_ETH_FAST_AN
1230		al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_lo, 0x00000040);
1231		al_reg_write32(&adapter->mac_regs_base->mac_10g.link_timer_hi, 0x00000000);
1232#endif
1233
1234		/* RXAUI MAC control register */
1235		al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);
1236		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1237/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1238		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1239/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1240		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,
1241					~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00063910);
1242		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x40003210);
1243		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401);
1244
1245		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1246				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1247				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1248		break;
1249
1250	case AL_ETH_MAC_MODE_XLG_LL_40G:
1251		/* configure and enable the ASYNC FIFO between the MACs and the EC */
1252		/* TX min packet size */
1253		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
1254		/* TX max packet size */
1255		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
1256		/* TX input bus configuration */
1257		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
1258		/* TX output bus configuration */
1259		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040);
1260		/* TX Valid/ready configuration */
1261		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);
1262		/* RX min packet size */
1263		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */
1264		/* RX max packet size */
1265		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */
1266		/* RX input bus configuration */
1267		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040);
1268		/* RX output bus configuration */
1269		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
1270		/* RX Valid/ready configuration */
1271		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112);
1272		/* V3 additional MAC selection */
1273		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010);
1274		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);
1275		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
1276		al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);
1277		/* ASYNC FIFO ENABLE */
1278		al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
1279
1280		/* cmd_cfg */
1281		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008);
1282		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810);
1283		/* speed_ability //Read-Only */
1284		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */
1285		/* 40G capable */
1286		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */
1287
1288#ifdef AL_HAL_ETH_FAST_AN
1289		al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023);
1290		al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c);
1291		al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c);
1292
1293#endif
1294
1295		/* XAUI MAC control register */
1296		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel,
1297					~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910);
1298		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f);
1299
1300		/* MAC register file */
1301/*		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */
1302		/* XAUI MAC control register */
1303		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);
1304		/* RXAUI MAC control register */
1305		al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);
1306		al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);
1307		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1308/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1309		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1310/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1311/*		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */
1312		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);
1313/*		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */
1314/*		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */
1315
1316		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1317				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1318				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1319		break;
1320
1321	case AL_ETH_MAC_MODE_XLG_LL_50G:
1322
1323		/* configure and enable the ASYNC FIFO between the MACs and the EC */
1324		/* TX min packet size */
1325		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_1, 0x00000037);
1326		/* TX max packet size */
1327		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_2, 0x00002800);
1328		/* TX input bus configuration */
1329		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_3, 0x00000080);
1330		/* TX output bus configuration */
1331		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_4, 0x00010040);
1332		/* TX Valid/ready configuration */
1333		al_reg_write32(&adapter->mac_regs_base->gen_v3.tx_afifo_cfg_5, 0x00000023);
1334		/* RX min packet size */
1335		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_1, 0x00000040); */
1336		/* RX max packet size */
1337		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_2, 0x00002800); */
1338		/* RX input bus configuration */
1339		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_3, 0x00010040);
1340		/* RX output bus configuration */
1341		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_4, 0x00000080);
1342		/* RX Valid/ready configuration */
1343		al_reg_write32(&adapter->mac_regs_base->gen_v3.rx_afifo_cfg_5, 0x00000112);
1344		/* V3 additional MAC selection */
1345		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_sel, 0x00000010);
1346		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_cfg, 0x00000000);
1347		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_10g_ll_ctrl, 0x00000000);
1348		al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_10g_ll_cfg, 0x00000000);
1349		/* ASYNC FIFO ENABLE */
1350		al_reg_write32(&adapter->mac_regs_base->gen_v3.afifo_ctrl, 0x00003333);
1351
1352		/* cmd_cfg */
1353		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_addr, 0x00000008);
1354		al_reg_write32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_data, 0x01022810);
1355		/* speed_ability //Read-Only */
1356		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_addr, 0x00000008); */
1357		/* 40G capable */
1358		/* al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_data, 0x00000002); */
1359
1360		/* select the 25G serdes for lanes 0/1 */
1361		al_reg_write32(&adapter->mac_regs_base->gen_v3.ext_serdes_ctrl, 0x0382110F);
1362		/* configure the PCS to work with 2 lanes */
1363		/* configure which two of the 4 PCS Lanes (VL) are combined to one RXLAUI lane */
1364		/* use VL 0-2 for RXLAUI lane 0, use VL 1-3 for RXLAUI lane 1 */
1365		al_eth_40g_pcs_reg_write(adapter, 0x00010008, 0x0d81);
1366		/* configure the PCS to work 32 bit interface */
1367		al_reg_write32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_cfg, 0x00440000);
1368
1369
1370#ifdef AL_HAL_ETH_FAST_AN
1371		al_eth_40g_pcs_reg_write(adapter, 0x00010004, 1023);
1372		al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0xA04c);
1373		al_eth_40g_pcs_reg_write(adapter, 0x00000000, 0x204c);
1374#endif
1375
1376		/* XAUI MAC control register */
1377		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x06883910);
1378		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x0000040f);
1379
1380		/* MAC register file */
1381/*		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x01022810); */
1382		/* XAUI MAC control register */
1383		al_reg_write32(&adapter->mac_regs_base->gen.cfg, 0x00000005);
1384		/* RXAUI MAC control register */
1385		al_reg_write32(&adapter->mac_regs_base->gen.rxaui_cfg, 0x00000007);
1386		al_reg_write32(&adapter->mac_regs_base->gen.sd_cfg, 0x000001F1);
1387		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_32_64, 0x00000401);
1388/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_out, 0x00000401); */
1389		al_reg_write32(&adapter->mac_regs_base->gen.xgmii_dfifo_64_32, 0x00000401);
1390/*		al_reg_write32(&adapter->mac_regs_base->gen.mac_res_1_in, 0x00000401); */
1391/*		al_reg_write32_masked(&adapter->mac_regs_base->gen.mux_sel, ~ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, 0x00073910); *//* XLG_LL_40G change */
1392		al_reg_write32(&adapter->mac_regs_base->gen.clk_cfg, 0x10003210);
1393/*		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x000004f0); *//* XLG_LL_40G change */
1394/*		al_reg_write32(&adapter->mac_regs_base->gen.sd_fifo_ctrl, 0x00000401); *//* XLG_LL_40G change */
1395
1396		al_reg_write32_masked(&adapter->mac_regs_base->gen.led_cfg,
1397				      ETH_MAC_GEN_LED_CFG_SEL_MASK,
1398				      ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG);
1399		break;
1400
1401
1402	default:
1403		al_err("Eth: unsupported MAC mode %d", mode);
1404		return -EPERM;
1405	}
1406	adapter->mac_mode = mode;
1407	al_info("configured MAC to %s mode:\n", al_eth_mac_mode_str(mode));
1408
1409	return 0;
1410}
1411
1412/* start the mac */
1413int al_eth_mac_start(struct al_hal_eth_adapter *adapter)
1414{
1415	if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
1416		/* 1G MAC control register */
1417		al_reg_write32_masked(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x3, 0x3);
1418	} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {
1419		/* 10G MAC control register  */
1420		al_reg_write32_masked(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x3, 0x3);
1421	} else {
1422		uint32_t cmd_cfg;
1423
1424		cmd_cfg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR);
1425
1426		cmd_cfg |= (ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_TX_ENA |
1427			    ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_RX_ENA);
1428
1429		al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, cmd_cfg);
1430	}
1431
1432	return 0;
1433}
1434
1435/* stop the mac */
1436int al_eth_mac_stop(struct al_hal_eth_adapter *adapter)
1437{
1438	if (AL_ETH_IS_1G_MAC(adapter->mac_mode))
1439		/* 1G MAC control register */
1440		al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, 0x0);
1441	else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))
1442		/* 10G MAC control register  */
1443		al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, 0x0);
1444	else
1445		al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, 0);
1446
1447	return 0;
1448}
1449
1450int al_eth_capabilities_get(struct al_hal_eth_adapter *adapter, struct al_eth_capabilities *caps)
1451{
1452	al_assert(caps);
1453
1454	caps->speed_10_HD = AL_FALSE;
1455	caps->speed_10_FD = AL_FALSE;
1456	caps->speed_100_HD = AL_FALSE;
1457	caps->speed_100_FD = AL_FALSE;
1458	caps->speed_1000_HD = AL_FALSE;
1459	caps->speed_1000_FD = AL_FALSE;
1460	caps->speed_10000_HD = AL_FALSE;
1461	caps->speed_10000_FD = AL_FALSE;
1462	caps->pfc = AL_FALSE;
1463	caps->eee = AL_FALSE;
1464
1465	switch (adapter->mac_mode) {
1466		case AL_ETH_MAC_MODE_RGMII:
1467		case AL_ETH_MAC_MODE_SGMII:
1468			caps->speed_10_HD = AL_TRUE;
1469			caps->speed_10_FD = AL_TRUE;
1470			caps->speed_100_HD = AL_TRUE;
1471			caps->speed_100_FD = AL_TRUE;
1472			caps->speed_1000_FD = AL_TRUE;
1473			caps->eee = AL_TRUE;
1474			break;
1475		case AL_ETH_MAC_MODE_10GbE_Serial:
1476			caps->speed_10000_FD = AL_TRUE;
1477			caps->pfc = AL_TRUE;
1478			break;
1479		default:
1480		al_err("Eth: unsupported MAC mode %d", adapter->mac_mode);
1481		return -EPERM;
1482	}
1483	return 0;
1484}
1485
1486/* update link speed and duplex mode */
1487int al_eth_mac_link_config(struct al_hal_eth_adapter *adapter,
1488			   al_bool force_1000_base_x,
1489			   al_bool an_enable,
1490			   uint32_t speed,
1491			   al_bool full_duplex)
1492{
1493	uint32_t mac_ctrl;
1494	uint32_t sgmii_ctrl = 0;
1495	uint32_t sgmii_if_mode = 0;
1496	uint32_t rgmii_ctrl = 0;
1497
1498	if (!AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
1499		al_err("eth [%s]: this function not supported in this mac mode.\n",
1500			       adapter->name);
1501		return -EINVAL;
1502	}
1503
1504	if ((adapter->mac_mode != AL_ETH_MAC_MODE_RGMII) && (an_enable)) {
1505		/*
1506		 * an_enable is not relevant to RGMII mode.
1507		 * in AN mode speed and duplex aren't relevant.
1508		 */
1509		al_info("eth [%s]: set auto negotiation to enable\n", adapter->name);
1510	} else {
1511		al_info("eth [%s]: set link speed to %dMbps. %s duplex.\n", adapter->name,
1512			speed, full_duplex == AL_TRUE ? "full" : "half");
1513
1514		if ((speed != 10) && (speed != 100) && (speed != 1000)) {
1515			al_err("eth [%s]: bad speed parameter (%d).\n",
1516				       adapter->name, speed);
1517			return -EINVAL;
1518		}
1519		if ((speed == 1000) && (full_duplex == AL_FALSE)) {
1520			al_err("eth [%s]: half duplex in 1Gbps is not supported.\n",
1521				       adapter->name);
1522			return -EINVAL;
1523		}
1524	}
1525
1526	mac_ctrl = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg);
1527
1528	if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {
1529		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,
1530			       ETH_MAC_SGMII_REG_ADDR_CTRL_REG);
1531		sgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);
1532		/*
1533		 * in case bit 0 is off in sgmii_if_mode register all the other
1534		 * bits are ignored.
1535		 */
1536		if (force_1000_base_x == AL_FALSE)
1537			sgmii_if_mode = ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_EN;
1538
1539		if (an_enable == AL_TRUE) {
1540			sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_AN;
1541			sgmii_ctrl |= ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE;
1542		} else {
1543			sgmii_ctrl &= ~(ETH_MAC_SGMII_REG_DATA_CTRL_AN_ENABLE);
1544		}
1545	}
1546
1547	if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) {
1548		/*
1549		 * Use the speed provided by the MAC instead of the PHY
1550		 */
1551		rgmii_ctrl = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_cfg);
1552
1553		AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_ENA_AUTO);
1554		AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_1000_SEL);
1555		AL_REG_MASK_CLEAR(rgmii_ctrl, ETH_MAC_GEN_RGMII_CFG_SET_10_SEL);
1556
1557		al_reg_write32(&adapter->mac_regs_base->gen.rgmii_cfg, rgmii_ctrl);
1558	}
1559
1560	if (full_duplex == AL_TRUE) {
1561		AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN);
1562	} else {
1563		AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_HD_EN);
1564		sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_DUPLEX;
1565	}
1566
1567	if (speed == 1000) {
1568		AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD);
1569		sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_1000;
1570	} else {
1571		AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_1G_SPD);
1572		if (speed == 10) {
1573			AL_REG_MASK_SET(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD);
1574		} else {
1575			sgmii_if_mode |= ETH_MAC_SGMII_REG_DATA_IF_MODE_SGMII_SPEED_100;
1576			AL_REG_MASK_CLEAR(mac_ctrl, AL_ETH_1G_MAC_CTRL_10M_SPD);
1577		}
1578	}
1579
1580	if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {
1581		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,
1582			       ETH_MAC_SGMII_REG_ADDR_IF_MODE_REG);
1583		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data,
1584			       sgmii_if_mode);
1585
1586		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr,
1587			       ETH_MAC_SGMII_REG_ADDR_CTRL_REG);
1588		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_data,
1589			       sgmii_ctrl);
1590	}
1591
1592	al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, mac_ctrl);
1593
1594	return 0;
1595}
1596
1597int al_eth_mac_loopback_config(struct al_hal_eth_adapter *adapter, int enable)
1598{
1599	const char *state = (enable) ? "enable" : "disable";
1600
1601	al_dbg("eth [%s]: loopback %s\n", adapter->name, state);
1602	if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
1603		uint32_t reg;
1604		reg = al_reg_read32(&adapter->mac_regs_base->mac_1g.cmd_cfg);
1605		if (enable)
1606			reg |= AL_BIT(15);
1607		else
1608			reg &= ~AL_BIT(15);
1609		al_reg_write32(&adapter->mac_regs_base->mac_1g.cmd_cfg, reg);
1610	} else if ((AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode))
1611			&& (adapter->rev_id == AL_ETH_REV_ID_3)) {
1612		uint32_t reg;
1613		al_reg_write16(
1614			(uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR);
1615		reg = al_reg_read16(
1616			(uint16_t *)&adapter->mac_regs_base->kr.pcs_data);
1617		if (enable)
1618			reg |= AL_BIT(14);
1619		else
1620			reg &= ~AL_BIT(14);
1621		al_reg_write16(
1622			(uint16_t *)&adapter->mac_regs_base->kr.pcs_addr, ETH_MAC_KR_PCS_CONTROL_1_ADDR);
1623		al_reg_write16(
1624			(uint16_t *)&adapter->mac_regs_base->kr.pcs_data, reg);
1625	} else if (adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G ||
1626			(adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) {
1627		uint32_t reg;
1628		reg = al_eth_40g_pcs_reg_read(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR);
1629		if (enable)
1630			reg |= AL_BIT(14);
1631		else
1632			reg &= ~AL_BIT(14);
1633		al_eth_40g_pcs_reg_write(adapter, ETH_MAC_GEN_V3_PCS_40G_CONTROL_STATUS_ADDR, reg);
1634	} else {
1635		al_err("Eth: mac loopback not supported in this mode %d", adapter->mac_mode);
1636		return -EPERM;
1637	}
1638	return 0;
1639}
1640
1641/* MDIO */
1642int al_eth_mdio_config(
1643	struct al_hal_eth_adapter	*adapter,
1644	enum al_eth_mdio_type		mdio_type,
1645	al_bool				shared_mdio_if,
1646	enum al_eth_ref_clk_freq	ref_clk_freq,
1647	unsigned int			mdio_clk_freq_khz)
1648{
1649	enum al_eth_mdio_if mdio_if = AL_ETH_MDIO_IF_10G_MAC;
1650	const char *if_name = (mdio_if == AL_ETH_MDIO_IF_1G_MAC) ? "10/100/1G MAC" : "10G MAC";
1651	const char *type_name = (mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22) ? "Clause 22" : "Clause 45";
1652	const char *shared_name = (shared_mdio_if == AL_TRUE) ? "Yes" : "No";
1653
1654	unsigned int ref_clk_freq_khz;
1655	uint32_t val;
1656
1657	al_dbg("eth [%s]: mdio config: interface %s. type %s. shared: %s\n", adapter->name, if_name, type_name, shared_name);
1658	adapter->shared_mdio_if = shared_mdio_if;
1659
1660	val = al_reg_read32(&adapter->mac_regs_base->gen.cfg);
1661	al_dbg("eth [%s]: mdio config: 10G mac \n", adapter->name);
1662
1663	switch(mdio_if)
1664	{
1665		case AL_ETH_MDIO_IF_1G_MAC:
1666			val &= ~AL_BIT(10);
1667			break;
1668		case AL_ETH_MDIO_IF_10G_MAC:
1669			val |= AL_BIT(10);
1670			break;
1671	}
1672	al_reg_write32(&adapter->mac_regs_base->gen.cfg, val);
1673	adapter->mdio_if = mdio_if;
1674
1675
1676	if (mdio_if == AL_ETH_MDIO_IF_10G_MAC)
1677	{
1678		val = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);
1679		switch(mdio_type)
1680		{
1681			case AL_ETH_MDIO_TYPE_CLAUSE_22:
1682				val &= ~AL_BIT(6);
1683				break;
1684			case AL_ETH_MDIO_TYPE_CLAUSE_45:
1685				val |= AL_BIT(6);
1686				break;
1687		}
1688
1689		/* set clock div to get 'mdio_clk_freq_khz' */
1690		switch (ref_clk_freq) {
1691		default:
1692			al_err("eth [%s]: %s: invalid reference clock frequency"
1693				" (%d)\n",
1694				adapter->name, __func__, ref_clk_freq);
1695		case AL_ETH_REF_FREQ_375_MHZ:
1696			ref_clk_freq_khz = 375000;
1697			break;
1698		case AL_ETH_REF_FREQ_187_5_MHZ:
1699			ref_clk_freq_khz = 187500;
1700			break;
1701		case AL_ETH_REF_FREQ_250_MHZ:
1702			ref_clk_freq_khz = 250000;
1703			break;
1704		case AL_ETH_REF_FREQ_500_MHZ:
1705			ref_clk_freq_khz = 500000;
1706			break;
1707                case AL_ETH_REF_FREQ_428_MHZ:
1708                        ref_clk_freq_khz = 428000;
1709                        break;
1710		};
1711
1712		val &= ~(0x1FF << 7);
1713		val |= (ref_clk_freq_khz / (2 * mdio_clk_freq_khz)) << 7;
1714		AL_REG_FIELD_SET(val, ETH_10G_MAC_MDIO_CFG_HOLD_TIME_MASK,
1715				 ETH_10G_MAC_MDIO_CFG_HOLD_TIME_SHIFT,
1716				 ETH_10G_MAC_MDIO_CFG_HOLD_TIME_7_CLK);
1717		al_reg_write32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status, val);
1718	}else{
1719		if(mdio_type != AL_ETH_MDIO_TYPE_CLAUSE_22) {
1720			al_err("eth [%s] mdio type not supported for this interface\n",
1721				 adapter->name);
1722			return -EINVAL;
1723		}
1724	}
1725	adapter->mdio_type = mdio_type;
1726
1727	return 0;
1728}
1729
1730static int al_eth_mdio_1g_mac_read(struct al_hal_eth_adapter *adapter,
1731			    uint32_t phy_addr __attribute__((__unused__)),
1732			    uint32_t reg, uint16_t *val)
1733{
1734	*val = al_reg_read32(
1735		&adapter->mac_regs_base->mac_1g.phy_regs_base + reg);
1736	return 0;
1737}
1738
1739static int al_eth_mdio_1g_mac_write(struct al_hal_eth_adapter *adapter,
1740			     uint32_t phy_addr __attribute__((__unused__)),
1741			     uint32_t reg, uint16_t val)
1742{
1743	al_reg_write32(
1744		&adapter->mac_regs_base->mac_1g.phy_regs_base + reg, val);
1745	return 0;
1746}
1747
1748static int al_eth_mdio_10g_mac_wait_busy(struct al_hal_eth_adapter *adapter)
1749{
1750	int	count = 0;
1751	uint32_t mdio_cfg_status;
1752
1753	do {
1754		mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);
1755/*
1756		if (mdio_cfg_status & AL_BIT(1)){ //error
1757			al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n",
1758				udma_params.name, phy_addr, reg);
1759			return -EIO;
1760		}*/
1761		if (mdio_cfg_status & AL_BIT(0)){
1762			if (count > 0)
1763				al_dbg("eth [%s] mdio: still busy!\n", adapter->name);
1764		}else{
1765			return 0;
1766		}
1767		al_udelay(AL_ETH_MDIO_DELAY_PERIOD);
1768	}while(count++ < AL_ETH_MDIO_DELAY_COUNT);
1769
1770	return -ETIMEDOUT;
1771}
1772
1773static int al_eth_mdio_10g_mac_type22(
1774	struct al_hal_eth_adapter *adapter,
1775	int read, uint32_t phy_addr, uint32_t reg, uint16_t *val)
1776{
1777	int rc;
1778	const char *op = (read == 1) ? "read":"write";
1779	uint32_t mdio_cfg_status;
1780	uint16_t mdio_cmd;
1781
1782	//wait if the HW is busy
1783	rc = al_eth_mdio_10g_mac_wait_busy(adapter);
1784	if (rc) {
1785		al_err(" eth [%s] mdio %s failed. HW is busy\n", adapter->name, op);
1786		return rc;
1787	}
1788
1789	mdio_cmd = (uint16_t)(0x1F & reg);
1790	mdio_cmd |= (0x1F & phy_addr) << 5;
1791
1792	if (read)
1793		mdio_cmd |= AL_BIT(15); //READ command
1794
1795	al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd,
1796			mdio_cmd);
1797	if (!read)
1798		al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_data,
1799				*val);
1800
1801	//wait for the busy to clear
1802	rc = al_eth_mdio_10g_mac_wait_busy(adapter);
1803	if (rc != 0) {
1804		al_err(" %s mdio %s failed on timeout\n", adapter->name, op);
1805		return -ETIMEDOUT;
1806	}
1807
1808	mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);
1809
1810	if (mdio_cfg_status & AL_BIT(1)){ //error
1811		al_err(" %s mdio %s failed on error. phy_addr 0x%x reg 0x%x\n",
1812			adapter->name, op, phy_addr, reg);
1813			return -EIO;
1814	}
1815	if (read)
1816		*val = al_reg_read16(
1817			(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data);
1818	return 0;
1819}
1820
1821static int al_eth_mdio_10g_mac_type45(
1822	struct al_hal_eth_adapter *adapter,
1823	int read, uint32_t port_addr, uint32_t device, uint32_t reg, uint16_t *val)
1824{
1825	int rc;
1826	const char *op = (read == 1) ? "read":"write";
1827	uint32_t mdio_cfg_status;
1828	uint16_t mdio_cmd;
1829
1830	//wait if the HW is busy
1831	rc = al_eth_mdio_10g_mac_wait_busy(adapter);
1832	if (rc) {
1833		al_err(" %s mdio %s failed. HW is busy\n", adapter->name, op);
1834		return rc;
1835	}
1836	// set command register
1837	mdio_cmd = (uint16_t)(0x1F & device);
1838	mdio_cmd |= (0x1F & port_addr) << 5;
1839	al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_cmd,
1840			mdio_cmd);
1841
1842	// send address frame
1843	al_reg_write16(&adapter->mac_regs_base->mac_10g.mdio_regaddr, reg);
1844	//wait for the busy to clear
1845	rc = al_eth_mdio_10g_mac_wait_busy(adapter);
1846	if (rc) {
1847		al_err(" %s mdio %s (address frame) failed on timeout\n", adapter->name, op);
1848		return rc;
1849	}
1850
1851	// if read, write again to the command register with READ bit set
1852	if (read) {
1853		mdio_cmd |= AL_BIT(15); //READ command
1854		al_reg_write16(
1855			(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_cmd,
1856			mdio_cmd);
1857	} else {
1858		al_reg_write16(
1859			(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data,
1860			*val);
1861	}
1862	//wait for the busy to clear
1863	rc = al_eth_mdio_10g_mac_wait_busy(adapter);
1864	if (rc) {
1865		al_err(" %s mdio %s failed on timeout\n", adapter->name, op);
1866		return rc;
1867	}
1868
1869	mdio_cfg_status = al_reg_read32(&adapter->mac_regs_base->mac_10g.mdio_cfg_status);
1870
1871	if (mdio_cfg_status & AL_BIT(1)){ //error
1872		al_err(" %s mdio %s failed on error. port 0x%x, device 0x%x reg 0x%x\n",
1873			adapter->name, op, port_addr, device, reg);
1874			return -EIO;
1875	}
1876	if (read)
1877		*val = al_reg_read16(
1878			(uint16_t *)&adapter->mac_regs_base->mac_10g.mdio_data);
1879	return 0;
1880}
1881
1882/**
1883 * acquire mdio interface ownership
1884 * when mdio interface shared between multiple eth controllers, this function waits until the ownership granted for this controller.
1885 * this function does nothing when the mdio interface is used only by this controller.
1886 *
1887 * @param adapter
1888 * @return 0 on success, -ETIMEDOUT  on timeout.
1889 */
1890static int al_eth_mdio_lock(struct al_hal_eth_adapter *adapter)
1891{
1892	int	count = 0;
1893	uint32_t mdio_ctrl_1;
1894
1895	if (adapter->shared_mdio_if == AL_FALSE)
1896		return 0; /* nothing to do when interface is not shared */
1897
1898	do {
1899		mdio_ctrl_1 = al_reg_read32(&adapter->mac_regs_base->gen.mdio_ctrl_1);
1900/*
1901		if (mdio_cfg_status & AL_BIT(1)){ //error
1902			al_err(" %s mdio read failed on error. phy_addr 0x%x reg 0x%x\n",
1903				udma_params.name, phy_addr, reg);
1904			return -EIO;
1905		}*/
1906		if (mdio_ctrl_1 & AL_BIT(0)){
1907			if (count > 0)
1908				al_dbg("eth %s mdio interface still busy!\n", adapter->name);
1909		}else{
1910			return 0;
1911		}
1912		al_udelay(AL_ETH_MDIO_DELAY_PERIOD);
1913	}while(count++ < (AL_ETH_MDIO_DELAY_COUNT * 4));
1914	al_err(" %s mdio failed to take ownership. MDIO info reg: 0x%08x\n",
1915		adapter->name, al_reg_read32(&adapter->mac_regs_base->gen.mdio_1));
1916
1917	return -ETIMEDOUT;
1918}
1919
1920/**
1921 * free mdio interface ownership
1922 * when mdio interface shared between multiple eth controllers, this function releases the ownership granted for this controller.
1923 * this function does nothing when the mdio interface is used only by this controller.
1924 *
1925 * @param adapter
1926 * @return 0.
1927 */
1928static int al_eth_mdio_free(struct al_hal_eth_adapter *adapter)
1929{
1930	if (adapter->shared_mdio_if == AL_FALSE)
1931		return 0; /* nothing to do when interface is not shared */
1932
1933	al_reg_write32(&adapter->mac_regs_base->gen.mdio_ctrl_1, 0);
1934
1935	/*
1936	 * Addressing RMN: 2917
1937	 *
1938	 * RMN description:
1939	 * The HW spin-lock is stateless and doesn't maintain any scheduling
1940	 * policy.
1941	 *
1942	 * Software flow:
1943	 * After getting the lock wait 2 times the delay period in order to give
1944	 * the other port chance to take the lock and prevent starvation.
1945	 * This is not scalable to more than two ports.
1946	 */
1947	al_udelay(2 * AL_ETH_MDIO_DELAY_PERIOD);
1948
1949	return 0;
1950}
1951
1952int al_eth_mdio_read(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t *val)
1953{
1954	int rc;
1955	rc = al_eth_mdio_lock(adapter);
1956
1957	/*"interface ownership taken"*/
1958	if (rc)
1959		return rc;
1960
1961	if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC)
1962		rc = al_eth_mdio_1g_mac_read(adapter, phy_addr, reg, val);
1963	else
1964		if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22)
1965			rc = al_eth_mdio_10g_mac_type22(adapter, 1, phy_addr, reg, val);
1966		else
1967			rc = al_eth_mdio_10g_mac_type45(adapter, 1, phy_addr, device, reg, val);
1968
1969	al_eth_mdio_free(adapter);
1970	al_dbg("eth mdio read: phy_addr %x, device %x, reg %x val %x\n", phy_addr, device, reg, *val);
1971	return rc;
1972}
1973
1974int al_eth_mdio_write(struct al_hal_eth_adapter *adapter, uint32_t phy_addr, uint32_t device, uint32_t reg, uint16_t val)
1975{
1976	int rc;
1977	al_dbg("eth mdio write: phy_addr %x, device %x, reg %x, val %x\n", phy_addr, device, reg, val);
1978	rc = al_eth_mdio_lock(adapter);
1979	/* interface ownership taken */
1980	if (rc)
1981		return rc;
1982
1983	if (adapter->mdio_if == AL_ETH_MDIO_IF_1G_MAC)
1984		rc = al_eth_mdio_1g_mac_write(adapter, phy_addr, reg, val);
1985	else
1986		if (adapter->mdio_type == AL_ETH_MDIO_TYPE_CLAUSE_22)
1987			rc = al_eth_mdio_10g_mac_type22(adapter, 0, phy_addr, reg, &val);
1988		else
1989			rc = al_eth_mdio_10g_mac_type45(adapter, 0, phy_addr, device, reg, &val);
1990
1991	al_eth_mdio_free(adapter);
1992	return rc;
1993}
1994
1995static void al_dump_tx_desc(union al_udma_desc *tx_desc)
1996{
1997	uint32_t *ptr = (uint32_t *)tx_desc;
1998	al_dbg("eth tx desc:\n");
1999	al_dbg("0x%08x\n", *(ptr++));
2000	al_dbg("0x%08x\n", *(ptr++));
2001	al_dbg("0x%08x\n", *(ptr++));
2002	al_dbg("0x%08x\n", *(ptr++));
2003}
2004
2005static void
2006al_dump_tx_pkt(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt)
2007{
2008	const char *tso = (pkt->flags & AL_ETH_TX_FLAGS_TSO) ? "TSO" : "";
2009	const char *l3_csum = (pkt->flags & AL_ETH_TX_FLAGS_IPV4_L3_CSUM) ? "L3 CSUM" : "";
2010	const char *l4_csum = (pkt->flags & AL_ETH_TX_FLAGS_L4_CSUM) ?
2011	  ((pkt->flags & AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM) ? "L4 PARTIAL CSUM" : "L4 FULL CSUM") : "";
2012	const char *fcs = (pkt->flags & AL_ETH_TX_FLAGS_L2_DIS_FCS) ? "Disable FCS" : "";
2013	const char *ptp = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "TX_PTP" : "";
2014	const char *l3_proto_name = "unknown";
2015	const char *l4_proto_name = "unknown";
2016	const char *outer_l3_proto_name = "N/A";
2017	const char *tunnel_mode = ((pkt->tunnel_mode & AL_ETH_TUNNEL_WITH_UDP) ==
2018				  AL_ETH_TUNNEL_WITH_UDP) ?
2019				  "TUNNEL_WITH_UDP" :
2020				  ((pkt->tunnel_mode & AL_ETH_TUNNEL_NO_UDP) ==
2021				  AL_ETH_TUNNEL_NO_UDP) ?
2022				  "TUNNEL_NO_UDP" : "";
2023	uint32_t total_len = 0;
2024	int i;
2025
2026	al_dbg("[%s %d]: flags: %s %s %s %s %s %s\n", tx_dma_q->udma->name, tx_dma_q->qid,
2027		 tso, l3_csum, l4_csum, fcs, ptp, tunnel_mode);
2028
2029	switch (pkt->l3_proto_idx) {
2030	case AL_ETH_PROTO_ID_IPv4:
2031		l3_proto_name = "IPv4";
2032		break;
2033	case AL_ETH_PROTO_ID_IPv6:
2034		l3_proto_name = "IPv6";
2035		break;
2036	default:
2037		l3_proto_name = "unknown";
2038		break;
2039	}
2040
2041	switch (pkt->l4_proto_idx) {
2042	case AL_ETH_PROTO_ID_TCP:
2043		l4_proto_name = "TCP";
2044		break;
2045	case AL_ETH_PROTO_ID_UDP:
2046		l4_proto_name = "UDP";
2047		break;
2048	default:
2049		l4_proto_name = "unknown";
2050		break;
2051	}
2052
2053	switch (pkt->outer_l3_proto_idx) {
2054	case AL_ETH_PROTO_ID_IPv4:
2055		outer_l3_proto_name = "IPv4";
2056		break;
2057	case AL_ETH_PROTO_ID_IPv6:
2058		outer_l3_proto_name = "IPv6";
2059		break;
2060	default:
2061		outer_l3_proto_name = "N/A";
2062		break;
2063	}
2064
2065	al_dbg("[%s %d]: L3 proto: %d (%s). L4 proto: %d (%s). Outer_L3 proto: %d (%s). vlan source count %d. mod add %d. mod del %d\n",
2066			tx_dma_q->udma->name, tx_dma_q->qid, pkt->l3_proto_idx,
2067			l3_proto_name, pkt->l4_proto_idx, l4_proto_name,
2068			pkt->outer_l3_proto_idx, outer_l3_proto_name,
2069			pkt->source_vlan_count, pkt->vlan_mod_add_count,
2070			pkt->vlan_mod_del_count);
2071
2072	if (pkt->meta) {
2073		const char * store = pkt->meta->store ? "Yes" : "No";
2074
2075		al_dbg("[%s %d]: tx pkt with meta data. words valid %x\n",
2076			tx_dma_q->udma->name, tx_dma_q->qid,
2077			pkt->meta->words_valid);
2078		if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0)
2079			al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss sel %d\n"
2080				, tx_dma_q->udma->name, tx_dma_q->qid, store,
2081				pkt->meta->l3_header_len, pkt->meta->l3_header_offset,
2082				pkt->meta->l4_header_len,
2083				pkt->meta->mss_idx_sel);
2084		else {
2085			const char *ptp_val = (pkt->flags & AL_ETH_TX_FLAGS_TS) ? "Yes" : "No";
2086			al_dbg("[%s %d]: meta: store to cache %s. l3 hdr len %d. l3 hdr offset %d. l4 hdr len %d. mss val %d ts_index %d ts_val:%s\n"
2087				, tx_dma_q->udma->name, tx_dma_q->qid, store,
2088				pkt->meta->l3_header_len, pkt->meta->l3_header_offset,
2089				pkt->meta->l4_header_len, pkt->meta->mss_val,
2090				pkt->meta->ts_index, ptp_val);
2091			al_dbg("outer_l3_hdr_offset %d. outer_l3_len %d.\n",
2092				pkt->meta->outer_l3_offset, pkt->meta->outer_l3_len);
2093		}
2094	}
2095
2096	al_dbg("[%s %d]: num of bufs: %d\n", tx_dma_q->udma->name, tx_dma_q->qid,
2097		pkt->num_of_bufs);
2098	for (i = 0; i < pkt->num_of_bufs; i++) {
2099		al_dbg("eth [%s %d]: buf[%d]: len 0x%08x. address 0x%016llx\n", tx_dma_q->udma->name, tx_dma_q->qid,
2100			i, pkt->bufs[i].len, (unsigned long long)pkt->bufs[i].addr);
2101		total_len += pkt->bufs[i].len;
2102	}
2103	al_dbg("[%s %d]: total len: 0x%08x\n", tx_dma_q->udma->name, tx_dma_q->qid, total_len);
2104
2105}
2106
2107/* TX */
2108/**
2109 * add packet to transmission queue
2110 */
2111int al_eth_tx_pkt_prepare(struct al_udma_q *tx_dma_q, struct al_eth_pkt *pkt)
2112{
2113	union al_udma_desc *tx_desc;
2114	uint32_t tx_descs;
2115	uint32_t flags = AL_M2S_DESC_FIRST |
2116			AL_M2S_DESC_CONCAT |
2117			(pkt->flags & AL_ETH_TX_FLAGS_INT);
2118	uint64_t vmid = ((uint64_t)pkt->vmid) << AL_UDMA_DESC_VMID_SHIFT;
2119	uint32_t meta_ctrl;
2120	uint32_t ring_id;
2121	int buf_idx;
2122
2123	al_dbg("[%s %d]: new tx pkt\n", tx_dma_q->udma->name, tx_dma_q->qid);
2124
2125	al_dump_tx_pkt(tx_dma_q, pkt);
2126
2127	tx_descs = pkt->num_of_bufs;
2128	if (pkt->meta) {
2129		tx_descs += 1;
2130	}
2131#ifdef AL_ETH_EX
2132	al_assert((pkt->ext_meta_data == NULL) || (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_2));
2133
2134	tx_descs += al_eth_ext_metadata_needed_descs(pkt->ext_meta_data);
2135	al_dbg("[%s %d]: %d Descriptors: ext_meta (%d). meta (%d). buffer (%d) ",
2136			tx_dma_q->udma->name, tx_dma_q->qid, tx_descs,
2137			al_eth_ext_metadata_needed_descs(pkt->ext_meta_data),
2138			(pkt->meta != NULL), pkt->num_of_bufs);
2139#endif
2140
2141	if (unlikely(al_udma_available_get(tx_dma_q) < tx_descs)) {
2142		al_dbg("[%s %d]: failed to allocate (%d) descriptors",
2143			 tx_dma_q->udma->name, tx_dma_q->qid, tx_descs);
2144		return 0;
2145	}
2146
2147#ifdef AL_ETH_EX
2148	if (pkt->ext_meta_data != NULL) {
2149		al_eth_ext_metadata_create(tx_dma_q, &flags, pkt->ext_meta_data);
2150		flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT);
2151	}
2152#endif
2153
2154	if (pkt->meta) {
2155		uint32_t meta_word_0 = 0;
2156		uint32_t meta_word_1 = 0;
2157		uint32_t meta_word_2 = 0;
2158		uint32_t meta_word_3 = 0;
2159
2160		meta_word_0 |= flags | AL_M2S_DESC_META_DATA;
2161		meta_word_0 &=  ~AL_M2S_DESC_CONCAT;
2162		flags &= ~(AL_M2S_DESC_FIRST | AL_ETH_TX_FLAGS_INT);
2163
2164		tx_desc = al_udma_desc_get(tx_dma_q);
2165		/* get ring id, and clear FIRST and Int flags */
2166		ring_id = al_udma_ring_id_get(tx_dma_q) <<
2167			AL_M2S_DESC_RING_ID_SHIFT;
2168
2169		meta_word_0 |= ring_id;
2170		meta_word_0 |= pkt->meta->words_valid << 12;
2171
2172		if (pkt->meta->store)
2173			meta_word_0 |= AL_ETH_TX_META_STORE;
2174
2175		if (pkt->meta->words_valid & 1) {
2176			meta_word_0 |= pkt->meta->vlan1_cfi_sel;
2177			meta_word_0 |= pkt->meta->vlan2_vid_sel << 2;
2178			meta_word_0 |= pkt->meta->vlan2_cfi_sel << 4;
2179			meta_word_0 |= pkt->meta->vlan2_pbits_sel << 6;
2180			meta_word_0 |= pkt->meta->vlan2_ether_sel << 8;
2181		}
2182
2183		if (pkt->meta->words_valid & 2) {
2184			meta_word_1 = pkt->meta->vlan1_new_vid;
2185			meta_word_1 |= pkt->meta->vlan1_new_cfi << 12;
2186			meta_word_1 |= pkt->meta->vlan1_new_pbits << 13;
2187			meta_word_1 |= pkt->meta->vlan2_new_vid << 16;
2188			meta_word_1 |= pkt->meta->vlan2_new_cfi << 28;
2189			meta_word_1 |= pkt->meta->vlan2_new_pbits << 29;
2190		}
2191
2192		if (pkt->meta->words_valid & 4) {
2193			meta_word_2 = pkt->meta->l3_header_len & AL_ETH_TX_META_L3_LEN_MASK;
2194			meta_word_2 |= (pkt->meta->l3_header_offset & AL_ETH_TX_META_L3_OFF_MASK) <<
2195				AL_ETH_TX_META_L3_OFF_SHIFT;
2196			meta_word_2 |= (pkt->meta->l4_header_len & 0x3f) << 16;
2197
2198			if (tx_dma_q->adapter_rev_id == AL_ETH_REV_ID_0) {
2199				meta_word_2 |= (pkt->meta->mss_idx_sel & 7) << 24;
2200			} else {
2201				uint32_t l3_offset;
2202
2203				if (unlikely(pkt->flags & AL_ETH_TX_FLAGS_TS))
2204					meta_word_0 |= pkt->meta->ts_index << AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT;
2205				else
2206					meta_word_0 |= (((pkt->meta->mss_val & 0x3c00) >> 10)
2207							<< AL_ETH_TX_META_MSS_MSB_TS_VAL_SHIFT);
2208				meta_word_2 |= ((pkt->meta->mss_val & 0x03ff)
2209						<< AL_ETH_TX_META_MSS_LSB_VAL_SHIFT);
2210
2211				/*
2212				 * move from bytes to multiplication of 2 as the HW
2213				 * expect to get it
2214				 */
2215				l3_offset = (pkt->meta->outer_l3_offset >> 1);
2216
2217				meta_word_0 |=
2218					(((l3_offset &
2219					   AL_ETH_TX_META_OUTER_L3_OFF_HIGH_MASK) >> 3)
2220					   << AL_ETH_TX_META_OUTER_L3_OFF_HIGH_SHIFT);
2221
2222				meta_word_3 |=
2223					((l3_offset &
2224					   AL_ETH_TX_META_OUTER_L3_OFF_LOW_MASK)
2225					   << AL_ETH_TX_META_OUTER_L3_OFF_LOW_SHIFT);
2226
2227				/*
2228				 * shift right 2 bits to work in multiplication of 4
2229				 * as the HW expect to get it
2230				 */
2231				meta_word_3 |=
2232					(((pkt->meta->outer_l3_len >> 2) &
2233					   AL_ETH_TX_META_OUTER_L3_LEN_MASK)
2234					   << AL_ETH_TX_META_OUTER_L3_LEN_SHIFT);
2235			}
2236		}
2237
2238		tx_desc->tx_meta.len_ctrl = swap32_to_le(meta_word_0);
2239		tx_desc->tx_meta.meta_ctrl = swap32_to_le(meta_word_1);
2240		tx_desc->tx_meta.meta1 = swap32_to_le(meta_word_2);
2241		tx_desc->tx_meta.meta2 = swap32_to_le(meta_word_3);
2242		al_dump_tx_desc(tx_desc);
2243	}
2244
2245	meta_ctrl = pkt->flags & AL_ETH_TX_PKT_META_FLAGS;
2246
2247	/* L4_PARTIAL_CSUM without L4_CSUM is invalid option  */
2248	al_assert((pkt->flags & (AL_ETH_TX_FLAGS_L4_CSUM|AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM)) !=
2249		  AL_ETH_TX_FLAGS_L4_PARTIAL_CSUM);
2250
2251	/* TSO packets can't have Timestamp enabled */
2252	al_assert((pkt->flags & (AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS)) !=
2253		  (AL_ETH_TX_FLAGS_TSO|AL_ETH_TX_FLAGS_TS));
2254
2255	meta_ctrl |= pkt->l3_proto_idx;
2256	meta_ctrl |= pkt->l4_proto_idx << AL_ETH_TX_L4_PROTO_IDX_SHIFT;
2257	meta_ctrl |= pkt->source_vlan_count << AL_ETH_TX_SRC_VLAN_CNT_SHIFT;
2258	meta_ctrl |= pkt->vlan_mod_add_count << AL_ETH_TX_VLAN_MOD_ADD_SHIFT;
2259	meta_ctrl |= pkt->vlan_mod_del_count << AL_ETH_TX_VLAN_MOD_DEL_SHIFT;
2260	meta_ctrl |= pkt->vlan_mod_v1_ether_sel << AL_ETH_TX_VLAN_MOD_E_SEL_SHIFT;
2261	meta_ctrl |= pkt->vlan_mod_v1_vid_sel << AL_ETH_TX_VLAN_MOD_VID_SEL_SHIFT;
2262	meta_ctrl |= pkt->vlan_mod_v1_pbits_sel << AL_ETH_TX_VLAN_MOD_PBIT_SEL_SHIFT;
2263
2264#ifdef AL_ETH_EX
2265	if ((pkt->ext_meta_data != NULL) && (pkt->ext_meta_data->tx_crypto_data != NULL))
2266		meta_ctrl |= AL_ETH_TX_FLAGS_ENCRYPT;
2267#endif
2268
2269	if (tx_dma_q->adapter_rev_id > AL_ETH_REV_ID_0) {
2270		meta_ctrl |= pkt->tunnel_mode << AL_ETH_TX_TUNNEL_MODE_SHIFT;
2271		if (pkt->outer_l3_proto_idx == AL_ETH_PROTO_ID_IPv4)
2272			meta_ctrl |= 1 << AL_ETH_TX_OUTER_L3_PROTO_SHIFT;
2273	}
2274
2275	flags |= pkt->flags & AL_ETH_TX_PKT_UDMA_FLAGS;
2276	for(buf_idx = 0; buf_idx < pkt->num_of_bufs; buf_idx++ ) {
2277		uint32_t flags_len = flags;
2278
2279		tx_desc = al_udma_desc_get(tx_dma_q);
2280		/* get ring id, and clear FIRST and Int flags */
2281		ring_id = al_udma_ring_id_get(tx_dma_q) <<
2282			AL_M2S_DESC_RING_ID_SHIFT;
2283
2284		flags_len |= ring_id;
2285
2286		if (buf_idx == (pkt->num_of_bufs - 1))
2287			flags_len |= AL_M2S_DESC_LAST;
2288
2289		/* clear First and Int flags */
2290		flags &= AL_ETH_TX_FLAGS_NO_SNOOP;
2291		flags |= AL_M2S_DESC_CONCAT;
2292
2293		flags_len |= pkt->bufs[buf_idx].len & AL_M2S_DESC_LEN_MASK;
2294		tx_desc->tx.len_ctrl = swap32_to_le(flags_len);
2295		if (buf_idx == 0)
2296			tx_desc->tx.meta_ctrl = swap32_to_le(meta_ctrl);
2297		tx_desc->tx.buf_ptr = swap64_to_le(
2298			pkt->bufs[buf_idx].addr | vmid);
2299		al_dump_tx_desc(tx_desc);
2300	}
2301
2302	al_dbg("[%s %d]: pkt descriptors written into the tx queue. descs num (%d)\n",
2303		tx_dma_q->udma->name, tx_dma_q->qid, tx_descs);
2304
2305	return tx_descs;
2306}
2307
2308
2309void al_eth_tx_dma_action(struct al_udma_q *tx_dma_q, uint32_t tx_descs)
2310{
2311	/* add tx descriptors */
2312	al_udma_desc_action_add(tx_dma_q, tx_descs);
2313}
2314
2315/**
2316 * get number of completed tx descriptors, upper layer should derive from
2317 */
2318int al_eth_comp_tx_get(struct al_udma_q *tx_dma_q)
2319{
2320	int rc;
2321
2322	rc = al_udma_cdesc_get_all(tx_dma_q, NULL);
2323	if (rc != 0) {
2324		al_udma_cdesc_ack(tx_dma_q, rc);
2325		al_dbg("[%s %d]: tx completion: descs (%d)\n",
2326			 tx_dma_q->udma->name, tx_dma_q->qid, rc);
2327	}
2328
2329	return rc;
2330}
2331
2332/**
2333 * configure the TSO MSS val
2334 */
2335int al_eth_tso_mss_config(struct al_hal_eth_adapter *adapter, uint8_t idx, uint32_t mss_val)
2336{
2337
2338	al_assert(idx <= 8); /*valid MSS index*/
2339	al_assert(mss_val <= AL_ETH_TSO_MSS_MAX_VAL); /*valid MSS val*/
2340	al_assert(mss_val >= AL_ETH_TSO_MSS_MIN_VAL); /*valid MSS val*/
2341
2342	al_reg_write32(&adapter->ec_regs_base->tso_sel[idx].mss, mss_val);
2343	return 0;
2344}
2345
2346
2347/* RX */
2348/**
2349 * config the rx descriptor fields
2350 */
2351void al_eth_rx_desc_config(
2352			struct al_hal_eth_adapter *adapter,
2353			enum al_eth_rx_desc_lro_context_val_res lro_sel,
2354			enum al_eth_rx_desc_l4_offset_sel l4_offset_sel,
2355			enum al_eth_rx_desc_l3_offset_sel l3_offset_sel,
2356			enum al_eth_rx_desc_l4_chk_res_sel l4_sel,
2357			enum al_eth_rx_desc_l3_chk_res_sel l3_sel,
2358			enum al_eth_rx_desc_l3_proto_idx_sel l3_proto_sel,
2359			enum al_eth_rx_desc_l4_proto_idx_sel l4_proto_sel,
2360			enum al_eth_rx_desc_frag_sel frag_sel)
2361{
2362	uint32_t reg_val = 0;
2363
2364	reg_val |= (lro_sel == AL_ETH_L4_OFFSET) ?
2365			EC_RFW_CFG_A_0_LRO_CONTEXT_SEL : 0;
2366
2367	reg_val |= (l4_sel == AL_ETH_L4_INNER_OUTER_CHK) ?
2368			EC_RFW_CFG_A_0_META_L4_CHK_RES_SEL : 0;
2369
2370	reg_val |= l3_sel << EC_RFW_CFG_A_0_META_L3_CHK_RES_SEL_SHIFT;
2371
2372	al_reg_write32(&adapter->ec_regs_base->rfw.cfg_a_0, reg_val);
2373
2374	reg_val = al_reg_read32(&adapter->ec_regs_base->rfw.meta);
2375	if (l3_proto_sel == AL_ETH_L3_PROTO_IDX_INNER)
2376		reg_val |= EC_RFW_META_L3_PROT_SEL;
2377	else
2378		reg_val &= ~EC_RFW_META_L3_PROT_SEL;
2379
2380	if (l4_proto_sel == AL_ETH_L4_PROTO_IDX_INNER)
2381		reg_val |= EC_RFW_META_L4_PROT_SEL;
2382	else
2383		reg_val &= ~EC_RFW_META_L4_PROT_SEL;
2384
2385	if (l4_offset_sel == AL_ETH_L4_OFFSET_INNER)
2386		reg_val |= EC_RFW_META_L4_OFFSET_SEL;
2387	else
2388		reg_val &= ~EC_RFW_META_L4_OFFSET_SEL;
2389
2390	if (l3_offset_sel == AL_ETH_L3_OFFSET_INNER)
2391		reg_val |= EC_RFW_META_L3_OFFSET_SEL;
2392	else
2393		reg_val &= ~EC_RFW_META_L3_OFFSET_SEL;
2394
2395	if (frag_sel == AL_ETH_FRAG_INNER)
2396		reg_val |= EC_RFW_META_FRAG_SEL;
2397	else
2398		reg_val &= ~EC_RFW_META_FRAG_SEL;
2399
2400
2401	al_reg_write32(&adapter->ec_regs_base->rfw.meta, reg_val);
2402}
2403
2404/**
2405 * Configure RX header split
2406 */
2407int al_eth_rx_header_split_config(struct al_hal_eth_adapter *adapter, al_bool enable, uint32_t header_len)
2408{
2409	uint32_t	reg;
2410
2411	if (adapter->rev_id < AL_ETH_REV_ID_1) {
2412		al_err("[%s]: header split feature not supported by this revision\n", adapter->name);
2413		return -EINVAL;
2414	}
2415	reg = al_reg_read32(&adapter->ec_regs_base->rfw.hdr_split);
2416	if (enable == AL_TRUE)
2417		reg |= EC_RFW_HDR_SPLIT_EN;
2418	else
2419		reg &= ~EC_RFW_HDR_SPLIT_EN;
2420
2421	AL_REG_FIELD_SET(reg, EC_RFW_HDR_SPLIT_DEF_LEN_MASK, EC_RFW_HDR_SPLIT_DEF_LEN_SHIFT, header_len);
2422	al_reg_write32(&adapter->ec_regs_base->rfw.hdr_split, reg);
2423	return 0;
2424}
2425
2426
2427/**
2428 * enable / disable header split in the udma queue.
2429 * length will be taken from the udma configuration to enable different length per queue.
2430 */
2431int al_eth_rx_header_split_force_len_config(struct al_hal_eth_adapter *adapter,
2432					al_bool enable,
2433					uint32_t qid,
2434					uint32_t header_len)
2435{
2436	al_udma_s2m_q_compl_hdr_split_config(&(adapter->rx_udma.udma_q[qid]), enable,
2437					     AL_TRUE, header_len);
2438
2439	return 0;
2440}
2441
2442
2443/**
2444 * add buffer to receive queue
2445 */
2446int al_eth_rx_buffer_add(struct al_udma_q *rx_dma_q,
2447			      struct al_buf *buf, uint32_t flags,
2448			      struct al_buf *header_buf)
2449{
2450	uint64_t vmid = ((uint64_t)flags & AL_ETH_RX_FLAGS_VMID_MASK) <<
2451		AL_UDMA_DESC_VMID_SHIFT;
2452	uint32_t flags_len = flags & ~AL_ETH_RX_FLAGS_VMID_MASK;
2453	union al_udma_desc *rx_desc;
2454
2455	al_dbg("[%s %d]: add rx buffer.\n", rx_dma_q->udma->name, rx_dma_q->qid);
2456
2457#if 1
2458	if (unlikely(al_udma_available_get(rx_dma_q) < 1)) {
2459		al_dbg("[%s]: rx q (%d) has no enough free descriptor",
2460			 rx_dma_q->udma->name, rx_dma_q->qid);
2461		return -ENOSPC;
2462	}
2463#endif
2464	rx_desc = al_udma_desc_get(rx_dma_q);
2465
2466	flags_len |= al_udma_ring_id_get(rx_dma_q) << AL_S2M_DESC_RING_ID_SHIFT;
2467	flags_len |= buf->len & AL_S2M_DESC_LEN_MASK;
2468
2469	if (flags & AL_S2M_DESC_DUAL_BUF) {
2470		al_assert(header_buf != NULL); /*header valid in dual buf */
2471		al_assert((rx_dma_q->udma->rev_id >= AL_UDMA_REV_ID_2) ||
2472			(AL_ADDR_HIGH(buf->addr) == AL_ADDR_HIGH(header_buf->addr)));
2473
2474		flags_len |= ((header_buf->len >> AL_S2M_DESC_LEN2_GRANULARITY_SHIFT)
2475			<< AL_S2M_DESC_LEN2_SHIFT) & AL_S2M_DESC_LEN2_MASK;
2476		rx_desc->rx.buf2_ptr_lo = swap32_to_le(AL_ADDR_LOW(header_buf->addr));
2477	}
2478	rx_desc->rx.len_ctrl = swap32_to_le(flags_len);
2479	rx_desc->rx.buf1_ptr = swap64_to_le(buf->addr | vmid);
2480
2481	return 0;
2482}
2483
2484/**
2485 * notify the hw engine about rx descriptors that were added to the receive queue
2486 */
2487void al_eth_rx_buffer_action(struct al_udma_q *rx_dma_q, uint32_t descs_num)
2488{
2489	al_dbg("[%s]: update the rx engine tail pointer: queue %d. descs %d\n",
2490		 rx_dma_q->udma->name, rx_dma_q->qid, descs_num);
2491
2492	/* add rx descriptor */
2493	al_udma_desc_action_add(rx_dma_q, descs_num);
2494}
2495
2496/**
2497 * get packet from RX completion ring
2498 */
2499uint32_t al_eth_pkt_rx(struct al_udma_q *rx_dma_q,
2500			      struct al_eth_pkt *pkt)
2501{
2502	volatile union al_udma_cdesc *cdesc;
2503	volatile al_eth_rx_cdesc *rx_desc;
2504	uint32_t i;
2505	uint32_t rc;
2506
2507	rc = al_udma_cdesc_packet_get(rx_dma_q, &cdesc);
2508	if (rc == 0)
2509		return 0;
2510
2511	al_assert(rc <= AL_ETH_PKT_MAX_BUFS);
2512
2513	al_dbg("[%s]: fetch rx packet: queue %d.\n",
2514		 rx_dma_q->udma->name, rx_dma_q->qid);
2515
2516	pkt->rx_header_len = 0;
2517	for (i = 0; i < rc; i++) {
2518		uint32_t buf1_len, buf2_len;
2519
2520		/* get next descriptor */
2521		rx_desc = (volatile al_eth_rx_cdesc *)al_cdesc_next(rx_dma_q, cdesc, i);
2522
2523		buf1_len = swap32_from_le(rx_desc->len);
2524
2525		if ((i == 0) && (swap32_from_le(rx_desc->word2) &
2526			AL_UDMA_CDESC_BUF2_USED)) {
2527			buf2_len = swap32_from_le(rx_desc->word2);
2528			pkt->rx_header_len = (buf2_len & AL_S2M_DESC_LEN2_MASK) >>
2529			AL_S2M_DESC_LEN2_SHIFT;
2530			}
2531		if ((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_BUF1_USED) &&
2532			((swap32_from_le(rx_desc->ctrl_meta) & AL_UDMA_CDESC_DDP) == 0))
2533			pkt->bufs[i].len = buf1_len & AL_S2M_DESC_LEN_MASK;
2534		else
2535			pkt->bufs[i].len = 0;
2536	}
2537	/* get flags from last desc */
2538	pkt->flags = swap32_from_le(rx_desc->ctrl_meta);
2539#ifdef AL_ETH_RX_DESC_RAW_GET
2540	pkt->rx_desc_raw[0] = pkt->flags;
2541	pkt->rx_desc_raw[1] = swap32_from_le(rx_desc->len);
2542	pkt->rx_desc_raw[2] = swap32_from_le(rx_desc->word2);
2543	pkt->rx_desc_raw[3] = swap32_from_le(rx_desc->word3);
2544#endif
2545	/* update L3/L4 proto index */
2546	pkt->l3_proto_idx = pkt->flags & AL_ETH_RX_L3_PROTO_IDX_MASK;
2547	pkt->l4_proto_idx = (pkt->flags >> AL_ETH_RX_L4_PROTO_IDX_SHIFT) &
2548				AL_ETH_RX_L4_PROTO_IDX_MASK;
2549	pkt->rxhash = (swap32_from_le(rx_desc->len) & AL_ETH_RX_HASH_MASK) >>
2550			AL_ETH_RX_HASH_SHIFT;
2551	pkt->l3_offset = (swap32_from_le(rx_desc->word2) & AL_ETH_RX_L3_OFFSET_MASK) >> AL_ETH_RX_L3_OFFSET_SHIFT;
2552
2553	al_udma_cdesc_ack(rx_dma_q, rc);
2554	return rc;
2555}
2556
2557
2558int al_eth_rx_parser_entry_update(struct al_hal_eth_adapter *adapter, uint32_t idx,
2559		struct al_eth_epe_p_reg_entry *reg_entry,
2560		struct al_eth_epe_control_entry *control_entry)
2561{
2562	al_eth_epe_entry_set(adapter, idx, reg_entry, control_entry);
2563	return 0;
2564}
2565
2566#define AL_ETH_THASH_UDMA_SHIFT		0
2567#define AL_ETH_THASH_UDMA_MASK		(0xF << AL_ETH_THASH_UDMA_SHIFT)
2568
2569#define AL_ETH_THASH_Q_SHIFT		4
2570#define AL_ETH_THASH_Q_MASK		(0x3 << AL_ETH_THASH_Q_SHIFT)
2571
2572int al_eth_thash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma, uint32_t queue)
2573{
2574	uint32_t entry;
2575	al_assert(idx < AL_ETH_RX_THASH_TABLE_SIZE); /*valid THASH index*/
2576
2577	entry = (udma << AL_ETH_THASH_UDMA_SHIFT) & AL_ETH_THASH_UDMA_MASK;
2578	entry |= (queue << AL_ETH_THASH_Q_SHIFT) & AL_ETH_THASH_Q_MASK;
2579
2580	al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_addr, idx);
2581	al_reg_write32(&adapter->ec_regs_base->rfw.thash_table_data, entry);
2582	return 0;
2583}
2584
2585int al_eth_fsm_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry)
2586{
2587
2588	al_assert(idx < AL_ETH_RX_FSM_TABLE_SIZE); /*valid FSM index*/
2589
2590
2591	al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_addr, idx);
2592	al_reg_write32(&adapter->ec_regs_base->rfw.fsm_table_data, entry);
2593	return 0;
2594}
2595
2596static uint32_t	al_eth_fwd_ctrl_entry_to_val(struct al_eth_fwd_ctrl_table_entry *entry)
2597{
2598	uint32_t val = 0;
2599	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(3,0), 0, entry->prio_sel);
2600	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(7,4), 4, entry->queue_sel_1);
2601	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(9,8), 8, entry->queue_sel_2);
2602	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(13,10), 10, entry->udma_sel);
2603	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(17,15), 15, entry->hdr_split_len_sel);
2604	if (entry->hdr_split_len_sel != AL_ETH_CTRL_TABLE_HDR_SPLIT_LEN_SEL_0)
2605		val |= AL_BIT(18);
2606	AL_REG_BIT_VAL_SET(val, 19, !!(entry->filter == AL_TRUE));
2607
2608	return val;
2609}
2610
2611static int al_eth_ctrl_index_match(struct al_eth_fwd_ctrl_table_index *index, uint32_t i) {
2612	if ((index->vlan_table_out != AL_ETH_FWD_CTRL_IDX_VLAN_TABLE_OUT_ANY)
2613		&& (index->vlan_table_out != AL_REG_BIT_GET(i, 0)))
2614		return 0;
2615	if ((index->tunnel_exist != AL_ETH_FWD_CTRL_IDX_TUNNEL_ANY)
2616		&& (index->tunnel_exist != AL_REG_BIT_GET(i, 1)))
2617		return 0;
2618	if ((index->vlan_exist != AL_ETH_FWD_CTRL_IDX_VLAN_ANY)
2619		&& (index->vlan_exist != AL_REG_BIT_GET(i, 2)))
2620		return 0;
2621	if ((index->mac_table_match != AL_ETH_FWD_CTRL_IDX_MAC_TABLE_ANY)
2622		&& (index->mac_table_match != AL_REG_BIT_GET(i, 3)))
2623		return 0;
2624	if ((index->protocol_id != AL_ETH_PROTO_ID_ANY)
2625		&& (index->protocol_id != AL_REG_FIELD_GET(i, AL_FIELD_MASK(8,4),4)))
2626		return 0;
2627	if ((index->mac_type != AL_ETH_FWD_CTRL_IDX_MAC_DA_TYPE_ANY)
2628		&& (index->mac_type != AL_REG_FIELD_GET(i, AL_FIELD_MASK(10,9),9)))
2629		return 0;
2630	return 1;
2631}
2632
2633int al_eth_ctrl_table_set(struct al_hal_eth_adapter *adapter,
2634			  struct al_eth_fwd_ctrl_table_index *index,
2635			  struct al_eth_fwd_ctrl_table_entry *entry)
2636{
2637	uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry);
2638	uint32_t i;
2639
2640	for (i = 0; i < AL_ETH_RX_CTRL_TABLE_SIZE; i++) {
2641		if (al_eth_ctrl_index_match(index, i)) {
2642			al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, i);
2643			al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, val);
2644		}
2645	}
2646	return 0;
2647}
2648
2649int al_eth_ctrl_table_def_set(struct al_hal_eth_adapter *adapter,
2650			      al_bool use_table,
2651			      struct al_eth_fwd_ctrl_table_entry *entry)
2652{
2653	uint32_t val = al_eth_fwd_ctrl_entry_to_val(entry);
2654
2655	if (use_table)
2656		val |= EC_RFW_CTRL_TABLE_DEF_SEL;
2657
2658	al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val);
2659
2660	return 0;
2661}
2662
2663int al_eth_ctrl_table_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t entry)
2664{
2665
2666	al_assert(idx < AL_ETH_RX_CTRL_TABLE_SIZE); /* valid CTRL index */
2667
2668
2669	al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_addr, idx);
2670	al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_data, entry);
2671	return 0;
2672}
2673
2674int al_eth_ctrl_table_def_raw_set(struct al_hal_eth_adapter *adapter, uint32_t val)
2675{
2676	al_reg_write32(&adapter->ec_regs_base->rfw.ctrl_table_def, val);
2677
2678	return 0;
2679}
2680
2681int al_eth_hash_key_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t val)
2682{
2683
2684	al_assert(idx < AL_ETH_RX_HASH_KEY_NUM); /*valid CTRL index*/
2685
2686	al_reg_write32(&adapter->ec_regs_base->rfw_hash[idx].key, val);
2687
2688	return 0;
2689}
2690
2691static uint32_t	al_eth_fwd_mac_table_entry_to_val(struct al_eth_fwd_mac_table_entry *entry)
2692{
2693	uint32_t val = 0;
2694
2695	val |= (entry->filter == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VAL_DROP : 0;
2696	val |= ((entry->udma_mask << EC_FWD_MAC_CTRL_RX_VAL_UDMA_SHIFT) &
2697					EC_FWD_MAC_CTRL_RX_VAL_UDMA_MASK);
2698
2699	val |= ((entry->qid << EC_FWD_MAC_CTRL_RX_VAL_QID_SHIFT) &
2700					EC_FWD_MAC_CTRL_RX_VAL_QID_MASK);
2701
2702	val |= (entry->rx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_RX_VALID : 0;
2703
2704	val |= ((entry->tx_target << EC_FWD_MAC_CTRL_TX_VAL_SHIFT) &
2705					EC_FWD_MAC_CTRL_TX_VAL_MASK);
2706
2707	val |= (entry->tx_valid == AL_TRUE) ? EC_FWD_MAC_CTRL_TX_VALID : 0;
2708
2709	return val;
2710}
2711
2712int al_eth_fwd_mac_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
2713			     struct al_eth_fwd_mac_table_entry *entry)
2714{
2715	uint32_t val;
2716
2717	al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */
2718
2719	val = (entry->addr[2] << 24) | (entry->addr[3] << 16) |
2720	      (entry->addr[4] << 8) | entry->addr[5];
2721	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, val);
2722	val = (entry->addr[0] << 8) | entry->addr[1];
2723	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, val);
2724	val = (entry->mask[2] << 24) | (entry->mask[3] << 16) |
2725	      (entry->mask[4] << 8) | entry->mask[5];
2726	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, val);
2727	val = (entry->mask[0] << 8) | entry->mask[1];
2728	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, val);
2729
2730	val = al_eth_fwd_mac_table_entry_to_val(entry);
2731	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, val);
2732	return 0;
2733}
2734
2735
2736
2737int al_eth_fwd_mac_addr_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t addr_lo, uint32_t addr_hi, uint32_t mask_lo, uint32_t mask_hi)
2738{
2739	al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */
2740
2741	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_l, addr_lo);
2742	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].data_h, addr_hi);
2743	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_l, mask_lo);
2744	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].mask_h, mask_hi);
2745
2746	return 0;
2747}
2748
2749int al_eth_fwd_mac_ctrl_raw_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint32_t ctrl)
2750{
2751	al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */
2752
2753	al_reg_write32(&adapter->ec_regs_base->fwd_mac[idx].ctrl, ctrl);
2754
2755	return 0;
2756}
2757
2758int al_eth_mac_addr_store(void * __iomem ec_base, uint32_t idx, uint8_t *addr)
2759{
2760	struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base;
2761	uint32_t val;
2762
2763	al_assert(idx < AL_ETH_FWD_MAC_NUM); /*valid FWD MAC index */
2764
2765	val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
2766	al_reg_write32(&ec_regs_base->fwd_mac[idx].data_l, val);
2767	val = (addr[0] << 8) | addr[1];
2768	al_reg_write32(&ec_regs_base->fwd_mac[idx].data_h, val);
2769	return 0;
2770}
2771
2772int al_eth_mac_addr_read(void * __iomem ec_base, uint32_t idx, uint8_t *addr)
2773{
2774	struct al_ec_regs __iomem *ec_regs_base = (struct al_ec_regs __iomem*)ec_base;
2775	uint32_t addr_lo = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_l);
2776	uint16_t addr_hi = al_reg_read32(&ec_regs_base->fwd_mac[idx].data_h);
2777
2778	addr[5] = addr_lo & 0xff;
2779	addr[4] = (addr_lo >> 8) & 0xff;
2780	addr[3] = (addr_lo >> 16) & 0xff;
2781	addr[2] = (addr_lo >> 24) & 0xff;
2782	addr[1] = addr_hi & 0xff;
2783	addr[0] = (addr_hi >> 8) & 0xff;
2784	return 0;
2785}
2786
2787int al_eth_fwd_mhash_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t udma_mask, uint8_t qid)
2788{
2789	uint32_t val = 0;
2790	al_assert(idx < AL_ETH_FWD_MAC_HASH_NUM); /* valid MHASH index */
2791
2792	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(3,0), 0, udma_mask);
2793	AL_REG_FIELD_SET(val,  AL_FIELD_MASK(5,4), 4, qid);
2794
2795	al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_addr, idx);
2796	al_reg_write32(&adapter->ec_regs_base->rfw.mhash_table_data, val);
2797	return 0;
2798}
2799static uint32_t	al_eth_fwd_vid_entry_to_val(struct al_eth_fwd_vid_table_entry *entry)
2800{
2801	uint32_t val = 0;
2802	AL_REG_BIT_VAL_SET(val, 0, entry->control);
2803	AL_REG_BIT_VAL_SET(val, 1, entry->filter);
2804	AL_REG_FIELD_SET(val, AL_FIELD_MASK(5,2), 2, entry->udma_mask);
2805
2806	return val;
2807}
2808
2809int al_eth_fwd_vid_config_set(struct al_hal_eth_adapter *adapter, al_bool use_table,
2810			      struct al_eth_fwd_vid_table_entry *default_entry,
2811			      uint32_t default_vlan)
2812{
2813	uint32_t reg;
2814
2815	reg = al_eth_fwd_vid_entry_to_val(default_entry);
2816	if (use_table)
2817		reg |= EC_RFW_VID_TABLE_DEF_SEL;
2818	else
2819		reg &= ~EC_RFW_VID_TABLE_DEF_SEL;
2820	al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_def, reg);
2821	al_reg_write32(&adapter->ec_regs_base->rfw.default_vlan, default_vlan);
2822
2823	return 0;
2824}
2825
2826int al_eth_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
2827			     struct al_eth_fwd_vid_table_entry *entry)
2828{
2829	uint32_t val;
2830	al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */
2831
2832	val = al_eth_fwd_vid_entry_to_val(entry);
2833	al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_addr, idx);
2834	al_reg_write32(&adapter->ec_regs_base->rfw.vid_table_data, val);
2835	return 0;
2836}
2837
2838int al_eth_fwd_pbits_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)
2839{
2840
2841	al_assert(idx < AL_ETH_FWD_PBITS_TABLE_NUM); /* valid PBIT index */
2842	al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */
2843	al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_addr, idx);
2844	al_reg_write32(&adapter->ec_regs_base->rfw.pbits_table_data, prio);
2845	return 0;
2846}
2847
2848int al_eth_fwd_priority_table_set(struct al_hal_eth_adapter *adapter, uint8_t prio, uint8_t qid)
2849{
2850	al_assert(prio < AL_ETH_FWD_PRIO_TABLE_NUM); /* valid PRIO index */
2851
2852	al_reg_write32(&adapter->ec_regs_base->rfw_priority[prio].queue, qid);
2853	return 0;
2854}
2855
2856
2857int al_eth_fwd_dscp_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)
2858{
2859
2860	al_assert(idx < AL_ETH_FWD_DSCP_TABLE_NUM); /* valid DSCP index */
2861
2862
2863	al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_addr, idx);
2864	al_reg_write32(&adapter->ec_regs_base->rfw.dscp_table_data, prio);
2865	return 0;
2866}
2867
2868int al_eth_fwd_tc_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx, uint8_t prio)
2869{
2870
2871	al_assert(idx < AL_ETH_FWD_TC_TABLE_NUM); /* valid TC index */
2872
2873
2874	al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_addr, idx);
2875	al_reg_write32(&adapter->ec_regs_base->rfw.tc_table_data, prio);
2876	return 0;
2877}
2878
2879/** Configure default UDMA register */
2880int al_eth_fwd_default_udma_config(struct al_hal_eth_adapter *adapter, uint32_t idx,
2881				   uint8_t udma_mask)
2882{
2883	al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,
2884			       EC_RFW_DEFAULT_OPT_1_UDMA_MASK,
2885			       udma_mask << EC_RFW_DEFAULT_OPT_1_UDMA_SHIFT);
2886	return 0;
2887}
2888
2889/** Configure default queue register */
2890int al_eth_fwd_default_queue_config(struct al_hal_eth_adapter *adapter, uint32_t idx,
2891				   uint8_t qid)
2892{
2893	al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,
2894			       EC_RFW_DEFAULT_OPT_1_QUEUE_MASK,
2895			       qid << EC_RFW_DEFAULT_OPT_1_QUEUE_SHIFT);
2896	return 0;
2897}
2898
2899/** Configure default priority register */
2900int al_eth_fwd_default_priority_config(struct al_hal_eth_adapter *adapter, uint32_t idx,
2901				   uint8_t prio)
2902{
2903	al_reg_write32_masked(&adapter->ec_regs_base->rfw_default[idx].opt_1,
2904			       EC_RFW_DEFAULT_OPT_1_PRIORITY_MASK,
2905			       prio << EC_RFW_DEFAULT_OPT_1_PRIORITY_SHIFT);
2906	return 0;
2907}
2908
2909int al_eth_switching_config_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t forward_all_to_mac, uint8_t enable_int_switching,
2910					enum al_eth_tx_switch_vid_sel_type vid_sel_type,
2911					enum al_eth_tx_switch_dec_type uc_dec,
2912					enum al_eth_tx_switch_dec_type mc_dec,
2913					enum al_eth_tx_switch_dec_type bc_dec)
2914{
2915	uint32_t reg;
2916
2917	if (udma_id == 0) {
2918		reg = al_reg_read32(&adapter->ec_regs_base->tfw.tx_gen);
2919		if (forward_all_to_mac)
2920			reg |= EC_TFW_TX_GEN_FWD_ALL_TO_MAC;
2921		else
2922			reg &= ~EC_TFW_TX_GEN_FWD_ALL_TO_MAC;
2923		al_reg_write32(&adapter->ec_regs_base->tfw.tx_gen, reg);
2924	}
2925
2926	reg = enable_int_switching;
2927	reg |= (vid_sel_type & 7) << 1;
2928	reg |= (bc_dec & 3) << 4;
2929	reg |= (mc_dec & 3) << 6;
2930	reg |= (uc_dec & 3) << 8;
2931	al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].fwd_dec, reg);
2932
2933	return 0;
2934}
2935
2936#define AL_ETH_RFW_FILTER_SUPPORTED(rev_id)	\
2937	(AL_ETH_RFW_FILTER_UNDET_MAC | \
2938	AL_ETH_RFW_FILTER_DET_MAC | \
2939	AL_ETH_RFW_FILTER_TAGGED | \
2940	AL_ETH_RFW_FILTER_UNTAGGED | \
2941	AL_ETH_RFW_FILTER_BC | \
2942	AL_ETH_RFW_FILTER_MC | \
2943	AL_ETH_RFW_FILTER_VLAN_VID | \
2944	AL_ETH_RFW_FILTER_CTRL_TABLE | \
2945	AL_ETH_RFW_FILTER_PROT_INDEX | \
2946	((rev_id > AL_ETH_REV_ID_0) ? ((AL_ETH_RFW_FILTER_WOL) | (AL_ETH_RFW_FILTER_PARSE)) : 0))
2947
2948/* Configure the receive filters */
2949int al_eth_filter_config(struct al_hal_eth_adapter *adapter, struct al_eth_filter_params *params)
2950{
2951	uint32_t reg;
2952
2953	al_assert(params); /* valid params pointer */
2954
2955	if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) {
2956		al_err("[%s]: unsupported filter options (0x%08x)\n", adapter->name, params->filters);
2957		return -EINVAL;
2958	}
2959
2960	reg = al_reg_read32(&adapter->ec_regs_base->rfw.out_cfg);
2961	if (params->enable == AL_TRUE)
2962		AL_REG_MASK_SET(reg, EC_RFW_OUT_CFG_DROP_EN);
2963	else
2964		AL_REG_MASK_CLEAR(reg, EC_RFW_OUT_CFG_DROP_EN);
2965	al_reg_write32(&adapter->ec_regs_base->rfw.out_cfg, reg);
2966
2967	al_reg_write32_masked(
2968		&adapter->ec_regs_base->rfw.filter,
2969		AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id),
2970		params->filters);
2971	if (params->filters & AL_ETH_RFW_FILTER_PROT_INDEX) {
2972		int i;
2973		for (i = 0; i < AL_ETH_PROTOCOLS_NUM; i++) {
2974			reg = al_reg_read32(&adapter->ec_regs_base->epe_a[i].prot_act);
2975			if (params->filter_proto[i] == AL_TRUE)
2976				AL_REG_MASK_SET(reg, EC_EPE_A_PROT_ACT_DROP);
2977			else
2978				AL_REG_MASK_CLEAR(reg, EC_EPE_A_PROT_ACT_DROP);
2979			al_reg_write32(&adapter->ec_regs_base->epe_a[i].prot_act, reg);
2980		}
2981	}
2982	return 0;
2983}
2984
2985/* Configure the receive override filters */
2986int al_eth_filter_override_config(struct al_hal_eth_adapter *adapter,
2987				  struct al_eth_filter_override_params *params)
2988{
2989	uint32_t reg;
2990
2991	al_assert(params); /* valid params pointer */
2992
2993	if (params->filters & ~(AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id))) {
2994		al_err("[%s]: unsupported override filter options (0x%08x)\n", adapter->name, params->filters);
2995		return -EINVAL;
2996	}
2997
2998	al_reg_write32_masked(
2999		&adapter->ec_regs_base->rfw.filter,
3000		AL_ETH_RFW_FILTER_SUPPORTED(adapter->rev_id) << 16,
3001		params->filters << 16);
3002
3003	reg = al_reg_read32(&adapter->ec_regs_base->rfw.default_or);
3004	AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_UDMA_MASK, EC_RFW_DEFAULT_OR_UDMA_SHIFT, params->udma);
3005	AL_REG_FIELD_SET(reg, EC_RFW_DEFAULT_OR_QUEUE_MASK, EC_RFW_DEFAULT_OR_QUEUE_SHIFT, params->qid);
3006	al_reg_write32(&adapter->ec_regs_base->rfw.default_or, reg);
3007	return 0;
3008}
3009
3010
3011
3012int al_eth_switching_default_bitmap_set(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint8_t udma_uc_bitmask,
3013						uint8_t udma_mc_bitmask,uint8_t udma_bc_bitmask)
3014{
3015	al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].uc_udma, udma_uc_bitmask);
3016	al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].mc_udma, udma_mc_bitmask);
3017	al_reg_write32(&adapter->ec_regs_base->tfw_udma[udma_id].bc_udma, udma_bc_bitmask);
3018
3019	return 0;
3020}
3021
3022int al_eth_flow_control_config(struct al_hal_eth_adapter *adapter, struct al_eth_flow_control_params *params)
3023{
3024	uint32_t reg;
3025	int i;
3026	al_assert(params); /* valid params pointer */
3027
3028	switch(params->type){
3029	case AL_ETH_FLOW_CONTROL_TYPE_LINK_PAUSE:
3030		al_dbg("[%s]: config flow control to link pause mode.\n", adapter->name);
3031
3032		/* config the mac */
3033		if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
3034			/* set quanta value */
3035			al_reg_write32(
3036				&adapter->mac_regs_base->mac_1g.pause_quant,
3037				params->quanta);
3038			al_reg_write32(
3039				&adapter->ec_regs_base->efc.xoff_timer_1g,
3040				params->quanta_th);
3041
3042		} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {
3043			/* set quanta value */
3044			al_reg_write32(
3045				&adapter->mac_regs_base->mac_10g.cl01_pause_quanta,
3046				params->quanta);
3047			/* set quanta threshold value */
3048			al_reg_write32(
3049				&adapter->mac_regs_base->mac_10g.cl01_quanta_thresh,
3050				params->quanta_th);
3051		} else {
3052			/* set quanta value */
3053			al_eth_40g_mac_reg_write(adapter,
3054				ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR,
3055				params->quanta);
3056			/* set quanta threshold value */
3057			al_eth_40g_mac_reg_write(adapter,
3058				ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR,
3059				params->quanta_th);
3060		}
3061
3062		if (params->obay_enable == AL_TRUE)
3063			/* Tx path FIFO, unmask pause_on from MAC when PAUSE packet received */
3064			al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 1);
3065		else
3066			al_reg_write32(&adapter->ec_regs_base->efc.ec_pause, 0);
3067
3068
3069		/* Rx path */
3070		if (params->gen_enable == AL_TRUE)
3071			/* enable generating xoff from ec fifo almost full indication in hysteresis mode */
3072			al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 1 << EC_EFC_EC_XOFF_MASK_2_SHIFT);
3073		else
3074			al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0);
3075
3076		if (AL_ETH_IS_1G_MAC(adapter->mac_mode))
3077			/* in 1G mode, enable generating xon from ec fifo in hysteresis mode*/
3078			al_reg_write32(&adapter->ec_regs_base->efc.xon, EC_EFC_XON_MASK_2 | EC_EFC_XON_MASK_1);
3079
3080		/* set hysteresis mode thresholds */
3081		al_reg_write32(&adapter->ec_regs_base->efc.rx_fifo_hyst, params->rx_fifo_th_low | (params->rx_fifo_th_high << EC_EFC_RX_FIFO_HYST_TH_HIGH_SHIFT));
3082
3083		for (i = 0; i < 4; i++) {
3084			if (params->obay_enable == AL_TRUE)
3085				/* Tx path UDMA, unmask pause_on for all queues */
3086				al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0,
3087						params->prio_q_map[i][0]);
3088			else
3089				al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0, 0);
3090
3091			if (params->gen_enable == AL_TRUE)
3092				/* Rx path UDMA, enable generating xoff from UDMA queue almost full indication */
3093				al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, params->prio_q_map[i][0]);
3094			else
3095				al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0, 0);
3096		}
3097	break;
3098	case AL_ETH_FLOW_CONTROL_TYPE_PFC:
3099		al_dbg("[%s]: config flow control to PFC mode.\n", adapter->name);
3100		al_assert(!AL_ETH_IS_1G_MAC(adapter->mac_mode)); /* pfc not available for RGMII mode */;
3101
3102		for (i = 0; i < 4; i++) {
3103			int prio;
3104			for (prio = 0; prio < 8; prio++) {
3105				if (params->obay_enable == AL_TRUE)
3106					/* Tx path UDMA, unmask pause_on for all queues */
3107					al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio,
3108							params->prio_q_map[i][prio]);
3109				else
3110					al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_pause_0 + prio,
3111							0);
3112
3113				if (params->gen_enable == AL_TRUE)
3114					al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio,
3115							params->prio_q_map[i][prio]);
3116				else
3117					al_reg_write32(&adapter->ec_regs_base->fc_udma[i].q_xoff_0 + prio,
3118							0);
3119			}
3120		}
3121
3122		/* Rx path */
3123		/* enable generating xoff from ec fifo almost full indication in hysteresis mode */
3124		if (params->gen_enable == AL_TRUE)
3125			al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0xFF << EC_EFC_EC_XOFF_MASK_2_SHIFT);
3126		else
3127			al_reg_write32(&adapter->ec_regs_base->efc.ec_xoff, 0);
3128
3129		/* set hysteresis mode thresholds */
3130		al_reg_write32(&adapter->ec_regs_base->efc.rx_fifo_hyst, params->rx_fifo_th_low | (params->rx_fifo_th_high << EC_EFC_RX_FIFO_HYST_TH_HIGH_SHIFT));
3131
3132		if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {
3133			/* config the 10g_mac */
3134			/* set quanta value (same value for all prios) */
3135			reg = params->quanta | (params->quanta << 16);
3136			al_reg_write32(
3137				&adapter->mac_regs_base->mac_10g.cl01_pause_quanta, reg);
3138			al_reg_write32(
3139				&adapter->mac_regs_base->mac_10g.cl23_pause_quanta, reg);
3140			al_reg_write32(
3141				&adapter->mac_regs_base->mac_10g.cl45_pause_quanta, reg);
3142			al_reg_write32(
3143				&adapter->mac_regs_base->mac_10g.cl67_pause_quanta, reg);
3144			/* set quanta threshold value (same value for all prios) */
3145			reg = params->quanta_th | (params->quanta_th << 16);
3146			al_reg_write32(
3147				&adapter->mac_regs_base->mac_10g.cl01_quanta_thresh, reg);
3148			al_reg_write32(
3149				&adapter->mac_regs_base->mac_10g.cl23_quanta_thresh, reg);
3150			al_reg_write32(
3151				&adapter->mac_regs_base->mac_10g.cl45_quanta_thresh, reg);
3152			al_reg_write32(
3153				&adapter->mac_regs_base->mac_10g.cl67_quanta_thresh, reg);
3154
3155			/* enable PFC in the 10g_MAC */
3156			reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg);
3157			reg |= 1 << 19;
3158			al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg);
3159		} else {
3160			/* config the 40g_mac */
3161			/* set quanta value (same value for all prios) */
3162			reg = params->quanta | (params->quanta << 16);
3163			al_eth_40g_mac_reg_write(adapter,
3164				ETH_MAC_GEN_V3_MAC_40G_CL01_PAUSE_QUANTA_ADDR, reg);
3165			al_eth_40g_mac_reg_write(adapter,
3166				ETH_MAC_GEN_V3_MAC_40G_CL23_PAUSE_QUANTA_ADDR, reg);
3167			al_eth_40g_mac_reg_write(adapter,
3168				ETH_MAC_GEN_V3_MAC_40G_CL45_PAUSE_QUANTA_ADDR, reg);
3169			al_eth_40g_mac_reg_write(adapter,
3170				ETH_MAC_GEN_V3_MAC_40G_CL67_PAUSE_QUANTA_ADDR, reg);
3171			/* set quanta threshold value (same value for all prios) */
3172			reg = params->quanta_th | (params->quanta_th << 16);
3173			al_eth_40g_mac_reg_write(adapter,
3174				ETH_MAC_GEN_V3_MAC_40G_CL01_QUANTA_THRESH_ADDR, reg);
3175			al_eth_40g_mac_reg_write(adapter,
3176				ETH_MAC_GEN_V3_MAC_40G_CL23_QUANTA_THRESH_ADDR, reg);
3177			al_eth_40g_mac_reg_write(adapter,
3178				ETH_MAC_GEN_V3_MAC_40G_CL45_QUANTA_THRESH_ADDR, reg);
3179			al_eth_40g_mac_reg_write(adapter,
3180				ETH_MAC_GEN_V3_MAC_40G_CL67_QUANTA_THRESH_ADDR, reg);
3181
3182			/* enable PFC in the 40g_MAC */
3183			reg = al_reg_read32(&adapter->mac_regs_base->mac_10g.cmd_cfg);
3184			reg |= 1 << 19;
3185			al_reg_write32(&adapter->mac_regs_base->mac_10g.cmd_cfg, reg);
3186			reg = al_eth_40g_mac_reg_read(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR);
3187
3188			reg |= ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_PFC_MODE;
3189
3190			al_eth_40g_mac_reg_write(adapter, ETH_MAC_GEN_V3_MAC_40G_COMMAND_CONFIG_ADDR, reg);
3191		}
3192
3193	break;
3194	default:
3195		al_err("[%s]: unsupported flow control type %d\n", adapter->name, params->type);
3196		return -EINVAL;
3197
3198	}
3199	return 0;
3200}
3201
3202int al_eth_vlan_mod_config(struct al_hal_eth_adapter *adapter, uint8_t udma_id, uint16_t udma_etype, uint16_t vlan1_data, uint16_t vlan2_data)
3203{
3204	al_dbg("[%s]: config vlan modification registers. udma id %d.\n", adapter->name, udma_id);
3205
3206	al_reg_write32(&adapter->ec_regs_base->tpm_sel[udma_id].etype, udma_etype);
3207	al_reg_write32(&adapter->ec_regs_base->tpm_udma[udma_id].vlan_data, vlan1_data | (vlan2_data << 16));
3208
3209	return 0;
3210}
3211
3212int al_eth_eee_get(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params)
3213{
3214	uint32_t reg;
3215
3216	al_dbg("[%s]: getting eee.\n", adapter->name);
3217
3218	reg = al_reg_read32(&adapter->ec_regs_base->eee.cfg_e);
3219	params->enable = (reg & EC_EEE_CFG_E_ENABLE) ? AL_TRUE : AL_FALSE;
3220
3221	params->tx_eee_timer = al_reg_read32(&adapter->ec_regs_base->eee.pre_cnt);
3222	params->min_interval = al_reg_read32(&adapter->ec_regs_base->eee.post_cnt);
3223	params->stop_cnt = al_reg_read32(&adapter->ec_regs_base->eee.stop_cnt);
3224
3225	return 0;
3226}
3227
3228
3229int al_eth_eee_config(struct al_hal_eth_adapter *adapter, struct al_eth_eee_params *params)
3230{
3231	uint32_t reg;
3232	al_dbg("[%s]: config eee.\n", adapter->name);
3233
3234	if (params->enable == 0) {
3235		al_dbg("[%s]: disable eee.\n", adapter->name);
3236		al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, 0);
3237		return 0;
3238	}
3239	if (AL_ETH_IS_10G_MAC(adapter->mac_mode)) {
3240		reg = ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL << ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_SHIFT;
3241		al_reg_write32_masked(
3242			&adapter->mac_regs_base->kr.pcs_cfg,
3243			ETH_MAC_KR_PCS_CFG_EEE_TIMER_VAL_MASK, reg);
3244	}
3245
3246	al_reg_write32(&adapter->ec_regs_base->eee.pre_cnt, params->tx_eee_timer);
3247	al_reg_write32(&adapter->ec_regs_base->eee.post_cnt, params->min_interval);
3248	al_reg_write32(&adapter->ec_regs_base->eee.stop_cnt, params->stop_cnt);
3249
3250	reg = EC_EEE_CFG_E_MASK_EC_TMI_STOP | EC_EEE_CFG_E_MASK_MAC_EEE |
3251	       EC_EEE_CFG_E_ENABLE |
3252	       EC_EEE_CFG_E_USE_EC_TX_FIFO | EC_EEE_CFG_E_USE_EC_RX_FIFO;
3253
3254	/*
3255	 * Addressing RMN: 3732
3256	 *
3257	 * RMN description:
3258	 * When the HW get into eee mode, it can't transmit any pause packet
3259	 * (when flow control policy is enabled).
3260	 * In such case, the HW has no way to handle extreme pushback from
3261	 * the Rx_path fifos.
3262	 *
3263	 * Software flow:
3264	 * Configure RX_FIFO empty as eee mode term.
3265	 * That way, nothing will prevent pause packet transmittion in
3266	 * case of extreme pushback from the Rx_path fifos.
3267	 *
3268	 */
3269
3270	al_reg_write32(&adapter->ec_regs_base->eee.cfg_e, reg);
3271
3272	return 0;
3273}
3274
3275/* Timestamp */
3276/* prepare the adapter for doing Timestamps for Rx packets. */
3277int al_eth_ts_init(struct al_hal_eth_adapter *adapter)
3278{
3279	uint32_t reg;
3280
3281	/*TODO:
3282	 * return error when:
3283	 * - working in 1G mode and MACSEC enabled
3284	 * - RX completion descriptor is not 8 words
3285	 */
3286	reg = al_reg_read32(&adapter->ec_regs_base->gen.en_ext);
3287	if (AL_ETH_IS_1G_MAC(adapter->mac_mode))
3288		reg &= ~EC_GEN_EN_EXT_PTH_1_10_SEL;
3289	else
3290		reg |= EC_GEN_EN_EXT_PTH_1_10_SEL;
3291	/*
3292	 * set completion bypass so tx timestamps won't be inserted to tx cmpl
3293	 * (in order to disable unverified flow)
3294	 */
3295	reg |= EC_GEN_EN_EXT_PTH_COMPLETION_BYPASS;
3296	al_reg_write32(&adapter->ec_regs_base->gen.en_ext, reg);
3297
3298	/*TODO: add the following when we have updated regs file:
3299	 * reg_rfw_out_cfg_timestamp_sample_out
3300		0 (default) – use the timestamp from the SOP info (10G MAC)
3301		1 – use the timestamp from the EOP (1G MAC) (noly when MACSEC is disabled)
3302	 */
3303	return 0;
3304}
3305
3306/* read Timestamp sample value of previously transmitted packet. */
3307int al_eth_tx_ts_val_get(struct al_hal_eth_adapter *adapter, uint8_t ts_index,
3308			 uint32_t *timestamp)
3309{
3310	al_assert(ts_index < AL_ETH_PTH_TX_SAMPLES_NUM);
3311
3312	/* in 1G mode, only indexes 1-7 are allowed*/
3313	if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
3314		al_assert(ts_index <= 7);
3315		al_assert(ts_index >= 1);
3316	}
3317
3318	/*TODO: check if sample is valid */
3319	*timestamp = al_reg_read32(&adapter->ec_regs_base->pth_db[ts_index].ts);
3320	return 0;
3321}
3322
3323/* Read the systime value */
3324int al_eth_pth_systime_read(struct al_hal_eth_adapter *adapter,
3325			    struct al_eth_pth_time *systime)
3326{
3327	uint32_t reg;
3328
3329	/* first we must read the subseconds MSB so the seconds register will be
3330	 * shadowed
3331	 */
3332	reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_subseconds_msb);
3333	systime->femto = (uint64_t)reg << 18;
3334	reg = al_reg_read32(&adapter->ec_regs_base->pth.system_time_seconds);
3335	systime->seconds = reg;
3336
3337	return 0;
3338}
3339
3340/* Set the clock period to a given value. */
3341int al_eth_pth_clk_period_write(struct al_hal_eth_adapter *adapter,
3342				uint64_t clk_period)
3343{
3344	uint32_t reg;
3345	/* first write the LSB so it will be shadowed */
3346	/* bits 31:14 of the clock period lsb register contains bits 17:0 of the
3347	 * period.
3348	 */
3349	reg = (clk_period & AL_BIT_MASK(18)) << EC_PTH_CLOCK_PERIOD_LSB_VAL_SHIFT;
3350	al_reg_write32(&adapter->ec_regs_base->pth.clock_period_lsb, reg);
3351	reg = clk_period >> 18;
3352	al_reg_write32(&adapter->ec_regs_base->pth.clock_period_msb, reg);
3353
3354	return 0;
3355}
3356
3357/* Configure the systime internal update */
3358int al_eth_pth_int_update_config(struct al_hal_eth_adapter *adapter,
3359				 struct al_eth_pth_int_update_params *params)
3360{
3361	uint32_t reg;
3362
3363	reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl);
3364	if (params->enable == AL_FALSE) {
3365		reg &= ~EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN;
3366	} else {
3367		reg |= EC_PTH_INT_UPDATE_CTRL_INT_TRIG_EN;
3368		AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK,
3369				 EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT,
3370				 params->method);
3371		if (params->trigger == AL_ETH_PTH_INT_TRIG_REG_WRITE)
3372			reg |= EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG;
3373		else
3374			reg &= ~EC_PTH_INT_UPDATE_CTRL_UPDATE_TRIG;
3375	}
3376	al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg);
3377	return 0;
3378}
3379/* set internal update time */
3380int al_eth_pth_int_update_time_set(struct al_hal_eth_adapter *adapter,
3381				   struct al_eth_pth_time *time)
3382{
3383	uint32_t reg;
3384
3385	al_reg_write32(&adapter->ec_regs_base->pth.int_update_seconds,
3386		       time->seconds);
3387	reg = time->femto & AL_BIT_MASK(18);
3388	reg = reg << EC_PTH_INT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT;
3389	al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_lsb,
3390		       reg);
3391	reg = time->femto >> 18;
3392	al_reg_write32(&adapter->ec_regs_base->pth.int_update_subseconds_msb,
3393		       reg);
3394
3395	return 0;
3396}
3397
3398/* Configure the systime external update */
3399int al_eth_pth_ext_update_config(struct al_hal_eth_adapter *adapter,
3400				 struct al_eth_pth_ext_update_params * params)
3401{
3402	uint32_t reg;
3403
3404	reg = al_reg_read32(&adapter->ec_regs_base->pth.int_update_ctrl);
3405	AL_REG_FIELD_SET(reg, EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_MASK,
3406			 EC_PTH_INT_UPDATE_CTRL_UPDATE_METHOD_SHIFT,
3407			 params->method);
3408
3409	AL_REG_FIELD_SET(reg, EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_MASK,
3410			 EC_PTH_EXT_UPDATE_CTRL_EXT_TRIG_EN_SHIFT,
3411			 params->triggers);
3412	al_reg_write32(&adapter->ec_regs_base->pth.int_update_ctrl, reg);
3413	return 0;
3414}
3415
3416/* set external update time */
3417int al_eth_pth_ext_update_time_set(struct al_hal_eth_adapter *adapter,
3418				   struct al_eth_pth_time *time)
3419{
3420	uint32_t reg;
3421
3422	al_reg_write32(&adapter->ec_regs_base->pth.ext_update_seconds,
3423		       time->seconds);
3424	reg = time->femto & AL_BIT_MASK(18);
3425	reg = reg << EC_PTH_EXT_UPDATE_SUBSECONDS_LSB_VAL_SHIFT;
3426	al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_lsb,
3427		       reg);
3428	reg = time->femto >> 18;
3429	al_reg_write32(&adapter->ec_regs_base->pth.ext_update_subseconds_msb,
3430		       reg);
3431
3432	return 0;
3433};
3434
3435/* set the read compensation delay */
3436int al_eth_pth_read_compensation_set(struct al_hal_eth_adapter *adapter,
3437				     uint64_t subseconds)
3438{
3439	uint32_t reg;
3440
3441	/* first write to lsb to ensure atomicity */
3442	reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_READ_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;
3443	al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_lsb, reg);
3444
3445	reg = subseconds >> 18;
3446	al_reg_write32(&adapter->ec_regs_base->pth.read_compensation_subseconds_msb, reg);
3447	return 0;
3448}
3449
3450/* set the internal write compensation delay */
3451int al_eth_pth_int_write_compensation_set(struct al_hal_eth_adapter *adapter,
3452					  uint64_t subseconds)
3453{
3454	uint32_t reg;
3455
3456	/* first write to lsb to ensure atomicity */
3457	reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_INT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;
3458	al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_lsb, reg);
3459
3460	reg = subseconds >> 18;
3461	al_reg_write32(&adapter->ec_regs_base->pth.int_write_compensation_subseconds_msb, reg);
3462	return 0;
3463}
3464
3465/* set the external write compensation delay */
3466int al_eth_pth_ext_write_compensation_set(struct al_hal_eth_adapter *adapter,
3467					  uint64_t subseconds)
3468{
3469	uint32_t reg;
3470
3471	/* first write to lsb to ensure atomicity */
3472	reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_EXT_WRITE_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;
3473	al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_lsb, reg);
3474
3475	reg = subseconds >> 18;
3476	al_reg_write32(&adapter->ec_regs_base->pth.ext_write_compensation_subseconds_msb, reg);
3477	return 0;
3478}
3479
3480/* set the sync compensation delay */
3481int al_eth_pth_sync_compensation_set(struct al_hal_eth_adapter *adapter,
3482				     uint64_t subseconds)
3483{
3484	uint32_t reg;
3485
3486	/* first write to lsb to ensure atomicity */
3487	reg = (subseconds & AL_BIT_MASK(18)) << EC_PTH_SYNC_COMPENSATION_SUBSECONDS_LSB_VAL_SHIFT;
3488	al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_lsb, reg);
3489
3490	reg = subseconds >> 18;
3491	al_reg_write32(&adapter->ec_regs_base->pth.sync_compensation_subseconds_msb, reg);
3492	return 0;
3493}
3494
3495/* Configure an output pulse */
3496int al_eth_pth_pulse_out_config(struct al_hal_eth_adapter *adapter,
3497				struct al_eth_pth_pulse_out_params *params)
3498{
3499	uint32_t reg;
3500
3501	if (params->index >= AL_ETH_PTH_PULSE_OUT_NUM) {
3502		al_err("eth [%s] PTH out pulse index out of range\n",
3503				 adapter->name);
3504		return -EINVAL;
3505	}
3506	reg = al_reg_read32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl);
3507	if (params->enable == AL_FALSE) {
3508		reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_EN;
3509	} else {
3510		reg |= EC_PTH_EGRESS_TRIGGER_CTRL_EN;
3511		if (params->periodic == AL_FALSE)
3512			reg &= ~EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC;
3513		else
3514			reg |= EC_PTH_EGRESS_TRIGGER_CTRL_PERIODIC;
3515
3516		AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_MASK,
3517				 EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SUBSEC_SHIFT,
3518				 params->period_us);
3519		AL_REG_FIELD_SET(reg, EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_MASK,
3520				 EC_PTH_EGRESS_TRIGGER_CTRL_PERIOD_SEC_SHIFT,
3521				 params->period_sec);
3522	}
3523	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_ctrl, reg);
3524
3525	/* set trigger time */
3526	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_seconds,
3527		       params->start_time.seconds);
3528	reg = params->start_time.femto & AL_BIT_MASK(18);
3529	reg = reg << EC_PTH_EGRESS_TRIGGER_SUBSECONDS_LSB_VAL_SHIFT;
3530	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_lsb,
3531		       reg);
3532	reg = params->start_time.femto >> 18;
3533	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].trigger_subseconds_msb,
3534		       reg);
3535
3536	/* set pulse width */
3537	reg = params->pulse_width & AL_BIT_MASK(18);
3538	reg = reg << EC_PTH_EGRESS_PULSE_WIDTH_SUBSECONDS_LSB_VAL_SHIFT;
3539	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_lsb, reg);
3540
3541	reg = params->pulse_width  >> 18;
3542	al_reg_write32(&adapter->ec_regs_base->pth_egress[params->index].pulse_width_subseconds_msb, reg);
3543
3544	return 0;
3545}
3546
3547/** get link status */
3548int al_eth_link_status_get(struct al_hal_eth_adapter *adapter,
3549			   struct al_eth_link_status *status)
3550{
3551	uint32_t reg;
3552
3553	if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {
3554		reg = al_reg_read32(&adapter->mac_regs_base->gen.mac_10g_stat);
3555
3556		status->link_up = AL_TRUE;
3557
3558		if (reg & (ETH_MAC_GEN_MAC_10G_STAT_LOC_FAULT |
3559					ETH_MAC_GEN_MAC_10G_STAT_REM_FAULT))
3560			status->link_up = AL_FALSE;
3561
3562	} else if (adapter->mac_mode == AL_ETH_MAC_MODE_SGMII) {
3563		al_reg_write32(&adapter->mac_regs_base->sgmii.reg_addr, 1);
3564		/*
3565		 * This register is latched low so need to read twice to get
3566		 * the current link status
3567		 */
3568		reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);
3569		reg = al_reg_read32(&adapter->mac_regs_base->sgmii.reg_data);
3570
3571		status->link_up = AL_FALSE;
3572
3573		if (reg & AL_BIT(2))
3574			status->link_up = AL_TRUE;
3575
3576		reg = al_reg_read32(&adapter->mac_regs_base->sgmii.link_stat);
3577
3578		if ((reg & AL_BIT(3)) == 0)
3579			status->link_up = AL_FALSE;
3580
3581	} else if (adapter->mac_mode == AL_ETH_MAC_MODE_RGMII) {
3582		reg = al_reg_read32(&adapter->mac_regs_base->gen.rgmii_stat);
3583
3584		status->link_up = AL_FALSE;
3585
3586		if (reg & AL_BIT(4))
3587			status->link_up = AL_TRUE;
3588
3589	} else if ((adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_40G) ||
3590			(adapter->mac_mode == AL_ETH_MAC_MODE_XLG_LL_50G)) {
3591		reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.pcs_40g_ll_status);
3592
3593		status->link_up = AL_FALSE;
3594
3595		if ((reg & 0x1F) == 0x1F) {
3596			reg = al_reg_read32(&adapter->mac_regs_base->gen_v3.mac_40g_ll_status);
3597			if ((reg & (ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_REM_FAULT |
3598ETH_MAC_GEN_V3_MAC_40G_LL_STATUS_LOC_FAULT)) == 0)
3599				status->link_up = AL_TRUE;
3600		}
3601
3602	} else {
3603		/* not implemented yet */
3604		return -EPERM;
3605	}
3606
3607	al_dbg("[%s]: mac %s port. link_status: %s.\n", adapter->name,
3608		al_eth_mac_mode_str(adapter->mac_mode),
3609		(status->link_up == AL_TRUE) ? "LINK_UP" : "LINK_DOWN");
3610
3611	return 0;
3612}
3613
3614/** set LED mode and value */
3615int al_eth_led_set(struct al_hal_eth_adapter *adapter, al_bool link_is_up)
3616{
3617	uint32_t reg = 0;
3618	uint32_t mode  = ETH_MAC_GEN_LED_CFG_SEL_DEFAULT_REG;
3619
3620	if (link_is_up)
3621		mode = ETH_MAC_GEN_LED_CFG_SEL_LINK_ACTIVITY;
3622
3623	AL_REG_FIELD_SET(reg,  ETH_MAC_GEN_LED_CFG_SEL_MASK,
3624			 ETH_MAC_GEN_LED_CFG_SEL_SHIFT, mode);
3625
3626	AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_BLINK_TIMER_MASK,
3627			 ETH_MAC_GEN_LED_CFG_BLINK_TIMER_SHIFT,
3628			 ETH_MAC_GEN_LED_CFG_BLINK_TIMER_VAL);
3629
3630	AL_REG_FIELD_SET(reg, ETH_MAC_GEN_LED_CFG_ACT_TIMER_MASK,
3631			 ETH_MAC_GEN_LED_CFG_ACT_TIMER_SHIFT,
3632			 ETH_MAC_GEN_LED_CFG_ACT_TIMER_VAL);
3633
3634	al_reg_write32(&adapter->mac_regs_base->gen.led_cfg, reg);
3635
3636	return 0;
3637}
3638
3639/* get statistics */
3640int al_eth_mac_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_mac_stats *stats)
3641{
3642	al_assert(stats);
3643
3644	if (AL_ETH_IS_1G_MAC(adapter->mac_mode)) {
3645		void __iomem *mac_1g_regs_base = &adapter->mac_regs_base->mac_1g;
3646
3647		stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x90));
3648		stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x94));
3649		stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x98));
3650		stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xb4));
3651		stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa0));
3652		stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa4));
3653		stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xa8));
3654		stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x88));
3655		stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x8c));
3656
3657		stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x6c));
3658		stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x68));
3659
3660		stats->aOctetsReceivedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x7c));
3661		stats->aOctetsTransmittedOK = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x78));
3662
3663		stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB8));
3664		stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xE0));
3665		stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xDC));
3666		stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xBC));
3667
3668		stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x70));
3669		stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x74));
3670		stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xAC));
3671
3672		stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x80));
3673		stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0x84));
3674		stats->aFrameTooLongErrors = 0; /* N/A */
3675		stats->aInRangeLengthErrors = 0; /* N/A */
3676		stats->VLANTransmittedOK = 0; /* N/A */
3677		stats->VLANReceivedOK = 0; /* N/A */
3678		stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xB0));
3679
3680		stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC0));
3681		stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC4));
3682		stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xC8));
3683		stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xCC));
3684		stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD0));
3685		stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD4));
3686		stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_1g_regs_base + 0xD8));
3687	} else if (AL_ETH_IS_10G_MAC(adapter->mac_mode) || AL_ETH_IS_25G_MAC(adapter->mac_mode)) {
3688		if (adapter->rev_id < AL_ETH_REV_ID_3) {
3689			void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g;
3690			uint64_t octets;
3691
3692			stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE0));
3693			stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xE8));
3694			stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xF0));
3695			stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130));
3696			stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108));
3697			stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x110));
3698			stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x118));
3699			stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x190));
3700			stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xf8));
3701
3702			stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x88));
3703			stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x80));
3704			/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
3705			octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD8));
3706			octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xDC))) << 32;
3707			octets -= 18 * stats->aFramesReceivedOK;
3708			octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8));
3709			stats->aOctetsReceivedOK = octets;
3710
3711			/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
3712			octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD0));
3713			octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xD4))) << 32;
3714			octets -= 18 * stats->aFramesTransmittedOK;
3715			octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0));
3716			stats->aOctetsTransmittedOK = octets;
3717
3718			stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138));
3719			stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x188));
3720			stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x180));
3721			stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base  + 0x178));
3722
3723			stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x90));
3724			stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98));
3725			stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120));
3726
3727			stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA0));
3728			stats->aPAUSEMACCtrlFramesReceived = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xA8));
3729			stats->aFrameTooLongErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB0));
3730			stats->aInRangeLengthErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xB8));
3731			stats->VLANTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC0));
3732			stats->VLANReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0xC8));
3733			stats->etherStatsOctets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128));
3734
3735			stats->etherStatsPkts64Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140));
3736			stats->etherStatsPkts65to127Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148));
3737			stats->etherStatsPkts128to255Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150));
3738			stats->etherStatsPkts256to511Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158));
3739			stats->etherStatsPkts512to1023Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160));
3740			stats->etherStatsPkts1024to1518Octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168));
3741			stats->etherStatsPkts1519toX = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x170));
3742		} else {
3743			void __iomem *mac_10g_regs_base = &adapter->mac_regs_base->mac_10g;
3744			uint64_t octets;
3745			/* TODO - change to 64 bit */
3746			stats->ifInUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x140));
3747			stats->ifInMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x148));
3748			stats->ifInBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x150));
3749			stats->etherStatsPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x160));
3750			stats->ifOutUcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x240));
3751			stats->ifOutMulticastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x248));
3752			stats->ifOutBroadcastPkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x250));
3753			stats->ifInErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x138));
3754			stats->ifOutErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x238));
3755
3756			stats->aFramesReceivedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x120)); /*frames_ok*/
3757			stats->aFramesTransmittedOK = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x220)); /*frames_ok*/
3758			/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
3759			octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x108)); /*OctetsOK*/
3760			octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x10C))) << 32;
3761			octets -= 18 * stats->aFramesReceivedOK;
3762			octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x130)); /*VLANOK*/
3763			stats->aOctetsReceivedOK = octets;
3764
3765			/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
3766			octets = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x208)); /*OctetsOK*/
3767			octets |= (uint64_t)(al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x20c))) << 32;
3768			octets -= 18 * stats->aFramesTransmittedOK;
3769			octets -= 4 * al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x230)); /*VLANOK*/
3770			stats->aOctetsTransmittedOK = octets;
3771
3772			stats->etherStatsUndersizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x168));
3773			stats->etherStatsFragments = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b8));
3774			stats->etherStatsJabbers = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x1b0));
3775			stats->etherStatsOversizePkts = al_reg_read32((void *)((uint32_t)mac_10g_regs_base  + 0x1a8));
3776
3777			stats->aFrameCheckSequenceErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x128)); /* CRCErrors */
3778			/* stats->aAlignmentErrors = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x98)); */ /* not implemented */
3779			stats->etherStatsDropEvents = al_reg_read32((void *)((uint32_t)mac_10g_regs_base + 0x158));
3780		}
3781	} else {
3782		uint64_t octets;
3783		/* TODO - change to 64 bit */
3784		stats->ifInUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x140);
3785		stats->ifInMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x148);
3786		stats->ifInBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x150);
3787		stats->etherStatsPkts = al_eth_40g_mac_reg_read(adapter, 0x160);
3788		stats->ifOutUcastPkts = al_eth_40g_mac_reg_read(adapter, 0x240);
3789		stats->ifOutMulticastPkts = al_eth_40g_mac_reg_read(adapter, 0x248);
3790		stats->ifOutBroadcastPkts = al_eth_40g_mac_reg_read(adapter, 0x250);
3791		stats->ifInErrors = al_eth_40g_mac_reg_read(adapter, 0x138);
3792		stats->ifOutErrors = al_eth_40g_mac_reg_read(adapter, 0x238);
3793		stats->aFramesReceivedOK = al_eth_40g_mac_reg_read(adapter, 0x120);
3794		stats->aFramesTransmittedOK = al_eth_40g_mac_reg_read(adapter, 0x220);
3795
3796		/* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
3797		octets = al_eth_40g_mac_reg_read(adapter, 0x100);
3798		octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x104)) << 32;
3799		octets -= 18 * stats->aFramesReceivedOK;
3800		octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x130); /*VLANOK*/
3801		stats->aOctetsTransmittedOK = octets;
3802
3803		/* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
3804		octets = al_eth_40g_mac_reg_read(adapter, 0x200);
3805		octets |= (uint64_t)(al_eth_40g_mac_reg_read(adapter, 0x204)) << 32;
3806		octets -= 18 * stats->aFramesReceivedOK;
3807		octets -= 4 * al_eth_40g_mac_reg_read(adapter, 0x230); /*VLANOK*/
3808		stats->aOctetsReceivedOK = octets;
3809
3810		stats->etherStatsUndersizePkts = al_eth_40g_mac_reg_read(adapter, 0x168);
3811		stats->etherStatsFragments = al_eth_40g_mac_reg_read(adapter, 0x1b8);
3812		stats->etherStatsJabbers = al_eth_40g_mac_reg_read(adapter, 0x1b0);
3813		stats->etherStatsOversizePkts = al_eth_40g_mac_reg_read(adapter, 0x1a8);
3814		stats->aFrameCheckSequenceErrors = al_eth_40g_mac_reg_read(adapter, 0x128);
3815		stats->aAlignmentErrors = al_eth_40g_mac_reg_read(adapter, 0x110);
3816		stats->etherStatsDropEvents = al_eth_40g_mac_reg_read(adapter, 0x158);
3817	}
3818
3819	stats->eee_in = al_reg_read32(&adapter->mac_regs_base->stat.eee_in);
3820	stats->eee_out = al_reg_read32(&adapter->mac_regs_base->stat.eee_out);
3821
3822/*	stats->etherStatsPkts = 1; */
3823	return 0;
3824}
3825
3826/**
3827* read ec_stat_counters
3828*/
3829int al_eth_ec_stats_get(struct al_hal_eth_adapter *adapter, struct al_eth_ec_stats *stats)
3830{
3831	al_assert(stats);
3832	stats->faf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_pkt);
3833	stats->faf_in_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_short);
3834	stats->faf_in_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_in_rx_long);
3835	stats->faf_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_pkt);
3836	stats->faf_out_rx_short = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_short);
3837	stats->faf_out_rx_long = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_rx_long);
3838	stats->faf_out_drop = al_reg_read32(&adapter->ec_regs_base->stat.faf_out_drop);
3839	stats->rxf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_rx_pkt);
3840	stats->rxf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.rxf_in_fifo_err);
3841	stats->lbf_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_rx_pkt);
3842	stats->lbf_in_fifo_err = al_reg_read32(&adapter->ec_regs_base->stat.lbf_in_fifo_err);
3843	stats->rxf_out_rx_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_1_pkt);
3844	stats->rxf_out_rx_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_rx_2_pkt);
3845	stats->rxf_out_drop_1_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_1_pkt);
3846	stats->rxf_out_drop_2_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rxf_out_drop_2_pkt);
3847	stats->rpe_1_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_in_rx_pkt);
3848	stats->rpe_1_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_1_out_rx_pkt);
3849	stats->rpe_2_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_in_rx_pkt);
3850	stats->rpe_2_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_2_out_rx_pkt);
3851	stats->rpe_3_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_in_rx_pkt);
3852	stats->rpe_3_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rpe_3_out_rx_pkt);
3853	stats->tpe_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_in_tx_pkt);
3854	stats->tpe_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpe_out_tx_pkt);
3855	stats->tpm_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tpm_tx_pkt);
3856	stats->tfw_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_in_tx_pkt);
3857	stats->tfw_out_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.tfw_out_tx_pkt);
3858	stats->rfw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_rx_pkt);
3859	stats->rfw_in_vlan_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_drop);
3860	stats->rfw_in_parse_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_parse_drop);
3861	stats->rfw_in_mc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mc);
3862	stats->rfw_in_bc = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_bc);
3863	stats->rfw_in_vlan_exist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_exist);
3864	stats->rfw_in_vlan_nexist = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_vlan_nexist);
3865	stats->rfw_in_mac_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_drop);
3866	stats->rfw_in_mac_ndet_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_mac_ndet_drop);
3867	stats->rfw_in_ctrl_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_ctrl_drop);
3868	stats->rfw_in_prot_i_drop = al_reg_read32(&adapter->ec_regs_base->stat.rfw_in_prot_i_drop);
3869	stats->eee_in = al_reg_read32(&adapter->ec_regs_base->stat.eee_in);
3870	return 0;
3871}
3872
3873/**
3874 * read per_udma_counters
3875 */
3876int al_eth_ec_stat_udma_get(struct al_hal_eth_adapter *adapter, uint8_t idx, struct al_eth_ec_stat_udma *stats)
3877{
3878
3879	al_assert(idx <= 3); /*valid udma_id*/
3880	al_assert(stats);
3881	stats->rfw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_rx_pkt);
3882	stats->rfw_out_drop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].rfw_out_drop);
3883	stats->msw_in_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_in_rx_pkt);
3884	stats->msw_drop_q_full = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_q_full);
3885	stats->msw_drop_sop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_sop);
3886	stats->msw_drop_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_drop_eop);
3887	stats->msw_wr_eop = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_wr_eop);
3888	stats->msw_out_rx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].msw_out_rx_pkt);
3889	stats->tso_no_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_no_tso_pkt);
3890	stats->tso_tso_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_tso_pkt);
3891	stats->tso_seg_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_seg_pkt);
3892	stats->tso_pad_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tso_pad_pkt);
3893	stats->tpm_tx_spoof = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tpm_tx_spoof);
3894	stats->tmi_in_tx_pkt = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_in_tx_pkt);
3895	stats->tmi_out_to_mac = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_mac);
3896	stats->tmi_out_to_rx = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tmi_out_to_rx);
3897	stats->tx_q0_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_bytes);
3898	stats->tx_q1_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_bytes);
3899	stats->tx_q2_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_bytes);
3900	stats->tx_q3_bytes = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_bytes);
3901	stats->tx_q0_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q0_pkts);
3902	stats->tx_q1_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q1_pkts);
3903	stats->tx_q2_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q2_pkts);
3904	stats->tx_q3_pkts = al_reg_read32(&adapter->ec_regs_base->stat_udma[idx].tx_q3_pkts);
3905	return 0;
3906}
3907
3908/* Traffic control */
3909
3910
3911int al_eth_flr_rmn(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val),
3912		   int (* pci_write_config_u32)(void *handle, int where, uint32_t val),
3913		   void *handle,
3914		   void __iomem	*mac_base)
3915{
3916	struct al_eth_mac_regs __iomem *mac_regs_base =
3917		(struct	al_eth_mac_regs __iomem *)mac_base;
3918	uint32_t cfg_reg_store[6];
3919	uint32_t reg;
3920	uint32_t mux_sel;
3921	int i = 0;
3922
3923	(*pci_read_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, &reg);
3924
3925	/* reset 1G mac */
3926	AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);
3927	(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);
3928	al_udelay(1000);
3929	/* don't reset 1G mac */
3930	AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);
3931	/* prevent 1G mac reset on FLR */
3932	AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR);
3933	/* prevent adapter reset */
3934	(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);
3935
3936	mux_sel = al_reg_read32(&mac_regs_base->gen.mux_sel);
3937
3938	/* save pci register that get reset due to flr*/
3939	(*pci_read_config_u32)(handle, AL_PCI_COMMAND, &cfg_reg_store[i++]);
3940	(*pci_read_config_u32)(handle, 0xC, &cfg_reg_store[i++]);
3941	(*pci_read_config_u32)(handle, 0x10, &cfg_reg_store[i++]);
3942	(*pci_read_config_u32)(handle, 0x18, &cfg_reg_store[i++]);
3943	(*pci_read_config_u32)(handle, 0x20, &cfg_reg_store[i++]);
3944	(*pci_read_config_u32)(handle, 0x110, &cfg_reg_store[i++]);
3945
3946	/* do flr */
3947	(*pci_write_config_u32)(handle, AL_PCI_EXP_CAP_BASE + AL_PCI_EXP_DEVCTL, AL_PCI_EXP_DEVCTL_BCR_FLR);
3948	al_udelay(1000);
3949	/* restore command */
3950	i = 0;
3951	(*pci_write_config_u32)(handle, AL_PCI_COMMAND, cfg_reg_store[i++]);
3952	(*pci_write_config_u32)(handle, 0xC, cfg_reg_store[i++]);
3953	(*pci_write_config_u32)(handle, 0x10, cfg_reg_store[i++]);
3954	(*pci_write_config_u32)(handle, 0x18, cfg_reg_store[i++]);
3955	(*pci_write_config_u32)(handle, 0x20, cfg_reg_store[i++]);
3956	(*pci_write_config_u32)(handle, 0x110, cfg_reg_store[i++]);
3957
3958	al_reg_write32_masked(&mac_regs_base->gen.mux_sel, ETH_MAC_GEN_MUX_SEL_KR_IN_MASK, mux_sel);
3959
3960	/* set SGMII clock to 125MHz */
3961	al_reg_write32(mac_base + 0xB08, 0x03320501);
3962
3963	/* reset 1G mac */
3964	AL_REG_MASK_SET(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);
3965	(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);
3966
3967	al_udelay(1000);
3968
3969	/* clear 1G mac reset */
3970	AL_REG_MASK_CLEAR(reg, AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC);
3971	(*pci_write_config_u32)(handle, AL_ADAPTER_GENERIC_CONTROL_0, reg);
3972
3973	/* reset SGMII mac clock to default */
3974	al_reg_write32(mac_base + 0xB08, 0x00320501);
3975	al_udelay(1000);
3976	/* reset async fifo */
3977	reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c));
3978	AL_REG_MASK_SET(reg, 0xF0);
3979	al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg);
3980	reg = al_reg_read32((void*)((uint32_t)mac_base + 0x95c));
3981	AL_REG_MASK_CLEAR(reg, 0xF0);
3982	al_reg_write32((void*)((uint32_t)mac_base + 0x95c), reg);
3983
3984	return 0;
3985}
3986
3987int al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void *handle, int where, uint32_t *val),
3988		int (* pci_write_config_u32)(void *handle, int where, uint32_t val),
3989		void *handle,
3990		void __iomem    *mac_base,
3991		void __iomem    *ec_base,
3992		int     mac_addresses_num
3993		)
3994{
3995	struct al_eth_board_params params = { .media_type = 0 };
3996	uint8_t mac_addr[6];
3997	int rc;
3998
3999	/* not implemented yet */
4000	if (mac_addresses_num > 1)
4001		return -EPERM;
4002
4003	/* save board params so we restore it after reset */
4004	al_eth_board_params_get(mac_base, &params);
4005	al_eth_mac_addr_read(ec_base, 0, mac_addr);
4006
4007	rc = al_eth_flr_rmn(pci_read_config_u32, pci_write_config_u32, handle, mac_base);
4008	al_eth_board_params_set(mac_base, &params);
4009	al_eth_mac_addr_store(ec_base, 0, mac_addr);
4010
4011	return rc;
4012}
4013
4014/* board params register 1 */
4015#define AL_HAL_ETH_MEDIA_TYPE_MASK	(AL_FIELD_MASK(3, 0))
4016#define AL_HAL_ETH_MEDIA_TYPE_SHIFT	0
4017#define AL_HAL_ETH_EXT_PHY_SHIFT	4
4018#define AL_HAL_ETH_PHY_ADDR_MASK	(AL_FIELD_MASK(9, 5))
4019#define AL_HAL_ETH_PHY_ADDR_SHIFT	5
4020#define AL_HAL_ETH_SFP_EXIST_SHIFT	10
4021#define AL_HAL_ETH_AN_ENABLE_SHIFT	11
4022#define AL_HAL_ETH_KR_LT_ENABLE_SHIFT	12
4023#define AL_HAL_ETH_KR_FEC_ENABLE_SHIFT	13
4024#define AL_HAL_ETH_MDIO_FREQ_MASK	(AL_FIELD_MASK(15, 14))
4025#define AL_HAL_ETH_MDIO_FREQ_SHIFT	14
4026#define AL_HAL_ETH_I2C_ADAPTER_ID_MASK	(AL_FIELD_MASK(19, 16))
4027#define AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT	16
4028#define AL_HAL_ETH_EXT_PHY_IF_MASK	(AL_FIELD_MASK(21, 20))
4029#define AL_HAL_ETH_EXT_PHY_IF_SHIFT	20
4030#define AL_HAL_ETH_AUTO_NEG_MODE_SHIFT	22
4031#define AL_HAL_ETH_SERDES_GRP_MASK	(AL_FIELD_MASK(26, 25))
4032#define AL_HAL_ETH_SERDES_GRP_SHIFT	25
4033#define AL_HAL_ETH_SERDES_LANE_MASK	(AL_FIELD_MASK(28, 27))
4034#define AL_HAL_ETH_SERDES_LANE_SHIFT	27
4035#define AL_HAL_ETH_REF_CLK_FREQ_MASK	(AL_FIELD_MASK(31, 29))
4036#define AL_HAL_ETH_REF_CLK_FREQ_SHIFT	29
4037
4038/* board params register 2 */
4039#define AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT	0
4040#define AL_HAL_ETH_1000_BASE_X_SHIFT		1
4041#define AL_HAL_ETH_1G_AN_DISABLE_SHIFT		2
4042#define AL_HAL_ETH_1G_SPEED_MASK		(AL_FIELD_MASK(4, 3))
4043#define AL_HAL_ETH_1G_SPEED_SHIFT		3
4044#define AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT		5
4045#define AL_HAL_ETH_1G_FC_DISABLE_SHIFT		6
4046#define AL_HAL_ETH_RETIMER_EXIST_SHIFT		7
4047#define AL_HAL_ETH_RETIMER_BUS_ID_MASK		(AL_FIELD_MASK(11, 8))
4048#define AL_HAL_ETH_RETIMER_BUS_ID_SHIFT		8
4049#define AL_HAL_ETH_RETIMER_I2C_ADDR_MASK	(AL_FIELD_MASK(18, 12))
4050#define AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT	12
4051#define AL_HAL_ETH_RETIMER_CHANNEL_SHIFT	19
4052#define AL_HAL_ETH_DAC_LENGTH_MASK		(AL_FIELD_MASK(23, 20))
4053#define AL_HAL_ETH_DAC_LENGTH_SHIFT		20
4054#define AL_HAL_ETH_DAC_SHIFT			24
4055#define AL_HAL_ETH_RETIMER_TYPE_MASK		(AL_FIELD_MASK(26, 25))
4056#define AL_HAL_ETH_RETIMER_TYPE_SHIFT		25
4057#define AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT	27
4058
4059int al_eth_board_params_set(void * __iomem mac_base, struct al_eth_board_params *params){
4060	uint32_t	reg = 0;
4061
4062	/* ************* Setting Board params register 1 **************** */
4063	AL_REG_FIELD_SET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK,
4064			 AL_HAL_ETH_MEDIA_TYPE_SHIFT, params->media_type);
4065	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_EXT_PHY_SHIFT, params->phy_exist == AL_TRUE);
4066	AL_REG_FIELD_SET(reg, AL_HAL_ETH_PHY_ADDR_MASK,
4067			 AL_HAL_ETH_PHY_ADDR_SHIFT, params->phy_mdio_addr);
4068
4069	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT, params->sfp_plus_module_exist == AL_TRUE);
4070
4071	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT, params->autoneg_enable == AL_TRUE);
4072	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT, params->kr_lt_enable == AL_TRUE);
4073	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT, params->kr_fec_enable == AL_TRUE);
4074	AL_REG_FIELD_SET(reg, AL_HAL_ETH_MDIO_FREQ_MASK,
4075			 AL_HAL_ETH_MDIO_FREQ_SHIFT, params->mdio_freq);
4076	AL_REG_FIELD_SET(reg, AL_HAL_ETH_I2C_ADAPTER_ID_MASK,
4077			 AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT, params->i2c_adapter_id);
4078	AL_REG_FIELD_SET(reg, AL_HAL_ETH_EXT_PHY_IF_MASK,
4079			 AL_HAL_ETH_EXT_PHY_IF_SHIFT, params->phy_if);
4080
4081	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT,
4082			   params->an_mode == AL_ETH_BOARD_AUTONEG_IN_BAND);
4083
4084	AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_GRP_MASK,
4085			 AL_HAL_ETH_SERDES_GRP_SHIFT, params->serdes_grp);
4086	AL_REG_FIELD_SET(reg, AL_HAL_ETH_SERDES_LANE_MASK,
4087			 AL_HAL_ETH_SERDES_LANE_SHIFT, params->serdes_lane);
4088
4089	AL_REG_FIELD_SET(reg, AL_HAL_ETH_REF_CLK_FREQ_MASK,
4090			 AL_HAL_ETH_REF_CLK_FREQ_SHIFT, params->ref_clk_freq);
4091
4092	al_assert(reg != 0);
4093
4094	al_reg_write32(mac_base + 0x4, reg);
4095
4096	/* ************* Setting Board params register 2 **************** */
4097	reg = 0;
4098	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT,
4099			   params->dont_override_serdes == AL_TRUE);
4100
4101	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT,
4102			   params->force_1000_base_x == AL_TRUE);
4103
4104	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT,
4105			   params->an_disable == AL_TRUE);
4106
4107	AL_REG_FIELD_SET(reg, AL_HAL_ETH_1G_SPEED_MASK,
4108			 AL_HAL_ETH_1G_SPEED_SHIFT, params->speed);
4109
4110	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT,
4111			   params->half_duplex == AL_TRUE);
4112
4113	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT,
4114			   params->fc_disable == AL_TRUE);
4115
4116	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT, params->retimer_exist == AL_TRUE);
4117	AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_BUS_ID_MASK,
4118			 AL_HAL_ETH_RETIMER_BUS_ID_SHIFT, params->retimer_bus_id);
4119	AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_I2C_ADDR_MASK,
4120			 AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT, params->retimer_i2c_addr);
4121
4122	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT,
4123				((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_B) ||
4124				 (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D)));
4125
4126	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT,
4127				((params->retimer_channel == AL_ETH_RETIMER_CHANNEL_C) ||
4128				 (params->retimer_channel == AL_ETH_RETIMER_CHANNEL_D)));
4129
4130	AL_REG_FIELD_SET(reg, AL_HAL_ETH_DAC_LENGTH_MASK,
4131			 AL_HAL_ETH_DAC_LENGTH_SHIFT, params->dac_len);
4132	AL_REG_BIT_VAL_SET(reg, AL_HAL_ETH_DAC_SHIFT, params->dac);
4133
4134	AL_REG_FIELD_SET(reg, AL_HAL_ETH_RETIMER_TYPE_MASK,
4135			 AL_HAL_ETH_RETIMER_TYPE_SHIFT, params->retimer_type);
4136
4137	al_reg_write32(mac_base + 0x404, reg);
4138	return 0;
4139}
4140
4141int al_eth_board_params_get(void * __iomem mac_base, struct al_eth_board_params *params){
4142	uint32_t	reg = al_reg_read32((void*)((uint32_t)mac_base + 0x4));
4143
4144	/* check if the register was initialized, 0 is not a valid value */
4145	if (reg == 0)
4146		return -ENOENT;
4147
4148	/* ************* Getting Board params register 1 **************** */
4149	params->media_type = AL_REG_FIELD_GET(reg, AL_HAL_ETH_MEDIA_TYPE_MASK,
4150					      AL_HAL_ETH_MEDIA_TYPE_SHIFT);
4151	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_EXT_PHY_SHIFT))
4152		params->phy_exist = AL_TRUE;
4153	else
4154		params->phy_exist = AL_FALSE;
4155
4156	params->phy_mdio_addr = AL_REG_FIELD_GET(reg, AL_HAL_ETH_PHY_ADDR_MASK,
4157						 AL_HAL_ETH_PHY_ADDR_SHIFT);
4158
4159	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_SFP_EXIST_SHIFT))
4160		params->sfp_plus_module_exist = AL_TRUE;
4161	else
4162		params->sfp_plus_module_exist = AL_FALSE;
4163
4164	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AN_ENABLE_SHIFT))
4165		params->autoneg_enable = AL_TRUE;
4166	else
4167		params->autoneg_enable = AL_FALSE;
4168
4169	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_LT_ENABLE_SHIFT))
4170		params->kr_lt_enable = AL_TRUE;
4171	else
4172		params->kr_lt_enable = AL_FALSE;
4173
4174	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_KR_FEC_ENABLE_SHIFT))
4175		params->kr_fec_enable = AL_TRUE;
4176	else
4177		params->kr_fec_enable = AL_FALSE;
4178
4179	params->mdio_freq = AL_REG_FIELD_GET(reg,
4180					     AL_HAL_ETH_MDIO_FREQ_MASK,
4181					     AL_HAL_ETH_MDIO_FREQ_SHIFT);
4182
4183	params->i2c_adapter_id = AL_REG_FIELD_GET(reg,
4184						  AL_HAL_ETH_I2C_ADAPTER_ID_MASK,
4185						  AL_HAL_ETH_I2C_ADAPTER_ID_SHIFT);
4186
4187	params->phy_if = AL_REG_FIELD_GET(reg,
4188					  AL_HAL_ETH_EXT_PHY_IF_MASK,
4189					  AL_HAL_ETH_EXT_PHY_IF_SHIFT);
4190
4191	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_AUTO_NEG_MODE_SHIFT))
4192		params->an_mode = AL_TRUE;
4193	else
4194		params->an_mode = AL_FALSE;
4195
4196	params->serdes_grp = AL_REG_FIELD_GET(reg,
4197					      AL_HAL_ETH_SERDES_GRP_MASK,
4198					      AL_HAL_ETH_SERDES_GRP_SHIFT);
4199
4200	params->serdes_lane = AL_REG_FIELD_GET(reg,
4201					       AL_HAL_ETH_SERDES_LANE_MASK,
4202					       AL_HAL_ETH_SERDES_LANE_SHIFT);
4203
4204	params->ref_clk_freq = AL_REG_FIELD_GET(reg,
4205						AL_HAL_ETH_REF_CLK_FREQ_MASK,
4206						AL_HAL_ETH_REF_CLK_FREQ_SHIFT);
4207
4208	/* ************* Getting Board params register 2 **************** */
4209	reg = al_reg_read32((void*)((uint32_t)mac_base + 0x404));
4210	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DONT_OVERRIDE_SERDES_SHIFT))
4211		params->dont_override_serdes = AL_TRUE;
4212	else
4213		params->dont_override_serdes = AL_FALSE;
4214
4215	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1000_BASE_X_SHIFT))
4216		params->force_1000_base_x = AL_TRUE;
4217	else
4218		params->force_1000_base_x = AL_FALSE;
4219
4220	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_AN_DISABLE_SHIFT))
4221		params->an_disable = AL_TRUE;
4222	else
4223		params->an_disable = AL_FALSE;
4224
4225	params->speed = AL_REG_FIELD_GET(reg,
4226					 AL_HAL_ETH_1G_SPEED_MASK,
4227					 AL_HAL_ETH_1G_SPEED_SHIFT);
4228
4229	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_HALF_DUPLEX_SHIFT))
4230		params->half_duplex = AL_TRUE;
4231	else
4232		params->half_duplex = AL_FALSE;
4233
4234	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_1G_FC_DISABLE_SHIFT))
4235		params->fc_disable = AL_TRUE;
4236	else
4237		params->fc_disable = AL_FALSE;
4238
4239	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_EXIST_SHIFT))
4240		params->retimer_exist = AL_TRUE;
4241	else
4242		params->retimer_exist = AL_FALSE;
4243
4244	params->retimer_bus_id = AL_REG_FIELD_GET(reg,
4245					       AL_HAL_ETH_RETIMER_BUS_ID_MASK,
4246					       AL_HAL_ETH_RETIMER_BUS_ID_SHIFT);
4247	params->retimer_i2c_addr = AL_REG_FIELD_GET(reg,
4248					       AL_HAL_ETH_RETIMER_I2C_ADDR_MASK,
4249					       AL_HAL_ETH_RETIMER_I2C_ADDR_SHIFT);
4250
4251	params->retimer_channel =
4252		((AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_SHIFT)) |
4253		 (AL_REG_BIT_GET(reg, AL_HAL_ETH_RETIMER_CHANNEL_2_SHIFT) << 1));
4254
4255	params->dac_len = AL_REG_FIELD_GET(reg,
4256					   AL_HAL_ETH_DAC_LENGTH_MASK,
4257					   AL_HAL_ETH_DAC_LENGTH_SHIFT);
4258
4259	if (AL_REG_BIT_GET(reg, AL_HAL_ETH_DAC_SHIFT))
4260		params->dac = AL_TRUE;
4261	else
4262		params->dac = AL_FALSE;
4263
4264	params->retimer_type = AL_REG_FIELD_GET(reg,
4265					   AL_HAL_ETH_RETIMER_TYPE_MASK,
4266					   AL_HAL_ETH_RETIMER_TYPE_SHIFT);
4267
4268	return 0;
4269}
4270
4271/* Wake-On-Lan (WoL) */
4272static inline void al_eth_byte_arr_to_reg(
4273		uint32_t *reg, uint8_t *arr, unsigned int num_bytes)
4274{
4275	uint32_t mask = 0xff;
4276	unsigned int i;
4277
4278	al_assert(num_bytes <= 4);
4279
4280	*reg = 0;
4281
4282	for (i = 0 ; i < num_bytes ; i++) {
4283		AL_REG_FIELD_SET(*reg, mask, (sizeof(uint8_t) * i), arr[i]);
4284		mask = mask << sizeof(uint8_t);
4285	}
4286}
4287
4288int al_eth_wol_enable(
4289		struct al_hal_eth_adapter *adapter,
4290		struct al_eth_wol_params *wol)
4291{
4292	uint32_t reg = 0;
4293
4294	if (wol->int_mask & AL_ETH_WOL_INT_MAGIC_PSWD) {
4295		al_assert(wol->pswd != NULL);
4296
4297		al_eth_byte_arr_to_reg(&reg, &wol->pswd[0], 4);
4298		al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_l, reg);
4299
4300		al_eth_byte_arr_to_reg(&reg, &wol->pswd[4], 2);
4301		al_reg_write32(&adapter->ec_regs_base->wol.magic_pswd_h, reg);
4302	}
4303
4304	if (wol->int_mask & AL_ETH_WOL_INT_IPV4) {
4305		al_assert(wol->ipv4 != NULL);
4306
4307		al_eth_byte_arr_to_reg(&reg, &wol->ipv4[0], 4);
4308		al_reg_write32(&adapter->ec_regs_base->wol.ipv4_dip, reg);
4309	}
4310
4311	if (wol->int_mask & AL_ETH_WOL_INT_IPV6) {
4312		al_assert(wol->ipv6 != NULL);
4313
4314		al_eth_byte_arr_to_reg(&reg, &wol->ipv6[0], 4);
4315		al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word0, reg);
4316
4317		al_eth_byte_arr_to_reg(&reg, &wol->ipv6[4], 4);
4318		al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word1, reg);
4319
4320		al_eth_byte_arr_to_reg(&reg, &wol->ipv6[8], 4);
4321		al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word2, reg);
4322
4323		al_eth_byte_arr_to_reg(&reg, &wol->ipv6[12], 4);
4324		al_reg_write32(&adapter->ec_regs_base->wol.ipv6_dip_word3, reg);
4325	}
4326
4327	if (wol->int_mask &
4328		(AL_ETH_WOL_INT_ETHERTYPE_BC | AL_ETH_WOL_INT_ETHERTYPE_DA)) {
4329
4330		reg = ((uint32_t)wol->ethr_type2 << 16);
4331		reg |= wol->ethr_type1;
4332
4333		al_reg_write32(&adapter->ec_regs_base->wol.ethertype, reg);
4334	}
4335
4336	/* make sure we dont forwarding packets without interrupt */
4337	al_assert((wol->forward_mask | wol->int_mask) == wol->int_mask);
4338
4339	reg = ((uint32_t)wol->forward_mask << 16);
4340	reg |= wol->int_mask;
4341	al_reg_write32(&adapter->ec_regs_base->wol.wol_en, reg);
4342
4343	return 0;
4344}
4345
4346int al_eth_wol_disable(
4347		struct al_hal_eth_adapter *adapter)
4348{
4349	al_reg_write32(&adapter->ec_regs_base->wol.wol_en, 0);
4350
4351	return 0;
4352}
4353
4354int al_eth_tx_fwd_vid_table_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4355				uint8_t udma_mask, al_bool fwd_to_mac)
4356{
4357	uint32_t	val = 0;
4358	al_assert(idx < AL_ETH_FWD_VID_TABLE_NUM); /* valid VID index */
4359	AL_REG_FIELD_SET(val,  AL_ETH_TX_VLAN_TABLE_UDMA_MASK, 0, udma_mask);
4360	AL_REG_FIELD_SET(val,  AL_ETH_TX_VLAN_TABLE_FWD_TO_MAC, 4, fwd_to_mac);
4361
4362	al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_addr, idx);
4363	al_reg_write32(&adapter->ec_regs_base->tfw.tx_vid_table_data, val);
4364	return 0;
4365}
4366
4367int al_eth_tx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4368		struct al_eth_tx_gpd_cam_entry *tx_gpd_entry)
4369{
4370	uint64_t gpd_data;
4371	uint64_t gpd_mask;
4372
4373	gpd_data = ((uint64_t)tx_gpd_entry->l3_proto_idx & AL_ETH_TX_GPD_L3_PROTO_MASK) <<
4374		AL_ETH_TX_GPD_L3_PROTO_SHIFT;
4375	gpd_data |= ((uint64_t)tx_gpd_entry->l4_proto_idx & AL_ETH_TX_GPD_L4_PROTO_MASK) <<
4376		AL_ETH_TX_GPD_L4_PROTO_SHIFT;
4377	gpd_data |= ((uint64_t)tx_gpd_entry->tunnel_control & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) <<
4378		AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT;
4379	gpd_data |= ((uint64_t)tx_gpd_entry->source_vlan_count & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) <<
4380		AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT;
4381	gpd_mask  = ((uint64_t)tx_gpd_entry->l3_proto_idx_mask & AL_ETH_TX_GPD_L3_PROTO_MASK) <<
4382		AL_ETH_TX_GPD_L3_PROTO_SHIFT;
4383	gpd_mask |= ((uint64_t)tx_gpd_entry->l4_proto_idx_mask & AL_ETH_TX_GPD_L4_PROTO_MASK) <<
4384		AL_ETH_TX_GPD_L4_PROTO_SHIFT;
4385	gpd_mask |= ((uint64_t)tx_gpd_entry->tunnel_control_mask & AL_ETH_TX_GPD_TUNNEL_CTRL_MASK) <<
4386		AL_ETH_TX_GPD_TUNNEL_CTRL_SHIFT;
4387	gpd_mask |= ((uint64_t)tx_gpd_entry->source_vlan_count_mask & AL_ETH_TX_GPD_SRC_VLAN_CNT_MASK) <<
4388		AL_ETH_TX_GPD_SRC_VLAN_CNT_SHIFT;
4389
4390	/* Tx Generic protocol detect Cam compare table */
4391	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_addr, idx);
4392	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_ctrl,
4393			(uint32_t)((tx_gpd_entry->tx_gpd_cam_ctrl) << AL_ETH_TX_GPD_CAM_CTRL_VALID_SHIFT));
4394	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_ctrl: %#x", idx, tx_gpd_entry->tx_gpd_cam_ctrl);
4395	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_2,
4396			(uint32_t)(gpd_mask >> AL_ETH_TX_GPD_CAM_MASK_2_SHIFT));
4397	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_mask_2: %#x", idx, (uint32_t)(gpd_mask >> AL_ETH_TX_GPD_CAM_MASK_2_SHIFT));
4398	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_mask_1,
4399			(uint32_t)(gpd_mask));
4400	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_mask_1: %#x", idx, (uint32_t)(gpd_mask));
4401	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_2,
4402			(uint32_t)(gpd_data >> AL_ETH_TX_GPD_CAM_DATA_2_SHIFT));
4403	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_data_2: %#x", idx, (uint32_t)(gpd_data >> AL_ETH_TX_GPD_CAM_DATA_2_SHIFT));
4404	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gpd_cam_data_1,
4405			(uint32_t)(gpd_data));
4406	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], tx_gpd_cam_data_1: %#x", idx, (uint32_t)(gpd_data));
4407	return 0;
4408}
4409
4410int al_eth_tx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4411		struct al_eth_tx_gcp_table_entry *tx_gcp_entry)
4412{
4413	uint32_t gcp_table_gen;
4414	uint32_t tx_alu_opcode;
4415	uint32_t tx_alu_opsel;
4416
4417	gcp_table_gen  = (tx_gcp_entry->poly_sel & AL_ETH_TX_GCP_POLY_SEL_MASK) <<
4418		AL_ETH_TX_GCP_POLY_SEL_SHIFT;
4419	gcp_table_gen |= (tx_gcp_entry->crc32_bit_comp & AL_ETH_TX_GCP_CRC32_BIT_COMP_MASK) <<
4420		AL_ETH_TX_GCP_CRC32_BIT_COMP_SHIFT;
4421	gcp_table_gen |= (tx_gcp_entry->crc32_bit_swap & AL_ETH_TX_GCP_CRC32_BIT_SWAP_MASK) <<
4422		AL_ETH_TX_GCP_CRC32_BIT_SWAP_SHIFT;
4423	gcp_table_gen |= (tx_gcp_entry->crc32_byte_swap & AL_ETH_TX_GCP_CRC32_BYTE_SWAP_MASK) <<
4424		AL_ETH_TX_GCP_CRC32_BYTE_SWAP_SHIFT;
4425	gcp_table_gen |= (tx_gcp_entry->data_bit_swap & AL_ETH_TX_GCP_DATA_BIT_SWAP_MASK) <<
4426		AL_ETH_TX_GCP_DATA_BIT_SWAP_SHIFT;
4427	gcp_table_gen |= (tx_gcp_entry->data_byte_swap & AL_ETH_TX_GCP_DATA_BYTE_SWAP_MASK) <<
4428		AL_ETH_TX_GCP_DATA_BYTE_SWAP_SHIFT;
4429	gcp_table_gen |= (tx_gcp_entry->trail_size & AL_ETH_TX_GCP_TRAIL_SIZE_MASK) <<
4430		AL_ETH_TX_GCP_TRAIL_SIZE_SHIFT;
4431	gcp_table_gen |= (tx_gcp_entry->head_size & AL_ETH_TX_GCP_HEAD_SIZE_MASK) <<
4432		AL_ETH_TX_GCP_HEAD_SIZE_SHIFT;
4433	gcp_table_gen |= (tx_gcp_entry->head_calc & AL_ETH_TX_GCP_HEAD_CALC_MASK) <<
4434		AL_ETH_TX_GCP_HEAD_CALC_SHIFT;
4435	gcp_table_gen |= (tx_gcp_entry->mask_polarity & AL_ETH_TX_GCP_MASK_POLARITY_MASK) <<
4436		AL_ETH_TX_GCP_MASK_POLARITY_SHIFT;
4437	al_dbg("al_eth_tx_generic_crc_entry_set, line [%d], gcp_table_gen: %#x", idx, gcp_table_gen);
4438
4439	tx_alu_opcode  = (tx_gcp_entry->tx_alu_opcode_1 & AL_ETH_TX_GCP_OPCODE_1_MASK) <<
4440		AL_ETH_TX_GCP_OPCODE_1_SHIFT;
4441	tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_2 & AL_ETH_TX_GCP_OPCODE_2_MASK) <<
4442		AL_ETH_TX_GCP_OPCODE_2_SHIFT;
4443	tx_alu_opcode |= (tx_gcp_entry->tx_alu_opcode_3 & AL_ETH_TX_GCP_OPCODE_3_MASK) <<
4444		AL_ETH_TX_GCP_OPCODE_3_SHIFT;
4445	tx_alu_opsel  = (tx_gcp_entry->tx_alu_opsel_1 & AL_ETH_TX_GCP_OPSEL_1_MASK) <<
4446		AL_ETH_TX_GCP_OPSEL_1_SHIFT;
4447	tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_2 & AL_ETH_TX_GCP_OPSEL_2_MASK) <<
4448		AL_ETH_TX_GCP_OPSEL_2_SHIFT;
4449	tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_3 & AL_ETH_TX_GCP_OPSEL_3_MASK) <<
4450		AL_ETH_TX_GCP_OPSEL_3_SHIFT;
4451	tx_alu_opsel |= (tx_gcp_entry->tx_alu_opsel_4 & AL_ETH_TX_GCP_OPSEL_4_MASK) <<
4452		AL_ETH_TX_GCP_OPSEL_4_SHIFT;
4453
4454	/*  Tx Generic crc prameters table general */
4455	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_addr, idx);
4456	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_gen,
4457			gcp_table_gen);
4458	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_1,
4459			tx_gcp_entry->gcp_mask[0]);
4460	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_2,
4461			tx_gcp_entry->gcp_mask[1]);
4462	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_3,
4463			tx_gcp_entry->gcp_mask[2]);
4464	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_4,
4465			tx_gcp_entry->gcp_mask[3]);
4466	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_5,
4467			tx_gcp_entry->gcp_mask[4]);
4468	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_mask_6,
4469			tx_gcp_entry->gcp_mask[5]);
4470	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_crc_init,
4471			tx_gcp_entry->crc_init);
4472	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_res,
4473			tx_gcp_entry->gcp_table_res);
4474	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opcode,
4475			tx_alu_opcode);
4476	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_opsel,
4477			tx_alu_opsel);
4478	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_table_alu_val,
4479			tx_gcp_entry->alu_val);
4480	return 0;
4481}
4482
4483int al_eth_tx_crc_chksum_replace_cmd_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4484		struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry *tx_replace_entry)
4485{
4486	uint32_t replace_table_address;
4487	uint32_t tx_replace_cmd;
4488
4489	/*  Tx crc_chksum_replace_cmd */
4490	replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_DIS | idx;
4491	tx_replace_cmd  = (uint32_t)(tx_replace_entry->l3_csum_en_00) << 0;
4492	tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_00) << 1;
4493	tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_00)     << 2;
4494	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);
4495	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,
4496			tx_replace_cmd);
4497	replace_table_address = L4_CHECKSUM_DIS_AND_L3_CHECKSUM_EN | idx;
4498	tx_replace_cmd  = (uint32_t)(tx_replace_entry->l3_csum_en_01) << 0;
4499	tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_01) << 1;
4500	tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_01)     << 2;
4501	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);
4502	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,
4503			tx_replace_cmd);
4504	replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_DIS | idx;
4505	tx_replace_cmd  = (uint32_t)(tx_replace_entry->l3_csum_en_10) << 0;
4506	tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_10) << 1;
4507	tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_10)     << 2;
4508	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);
4509	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,
4510			tx_replace_cmd);
4511	replace_table_address = L4_CHECKSUM_EN_AND_L3_CHECKSUM_EN | idx;
4512	tx_replace_cmd  = (uint32_t)(tx_replace_entry->l3_csum_en_11) << 0;
4513	tx_replace_cmd |= (uint32_t)(tx_replace_entry->l4_csum_en_11) << 1;
4514	tx_replace_cmd |= (uint32_t)(tx_replace_entry->crc_en_11)     << 2;
4515	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table_addr, replace_table_address);
4516	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace_table,
4517			tx_replace_cmd);
4518
4519	return 0;
4520}
4521
4522int al_eth_rx_protocol_detect_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4523		struct al_eth_rx_gpd_cam_entry *rx_gpd_entry)
4524{
4525	uint64_t gpd_data;
4526	uint64_t gpd_mask;
4527
4528	gpd_data  = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) <<
4529		AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT;
4530	gpd_data |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) <<
4531		AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT;
4532	gpd_data |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) <<
4533		AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT;
4534	gpd_data |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) <<
4535		AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT;
4536	gpd_data |= ((uint64_t)rx_gpd_entry->parse_ctrl & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) <<
4537		AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT;
4538	gpd_data |= ((uint64_t)rx_gpd_entry->outer_l3_len & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) <<
4539		AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT;
4540	gpd_data |= ((uint64_t)rx_gpd_entry->l3_priority & AL_ETH_RX_GPD_L3_PRIORITY_MASK) <<
4541		AL_ETH_RX_GPD_L3_PRIORITY_SHIFT;
4542	gpd_data |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) <<
4543		AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT;
4544
4545	gpd_mask  = ((uint64_t)rx_gpd_entry->outer_l3_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L3_PROTO_MASK) <<
4546		AL_ETH_RX_GPD_OUTER_L3_PROTO_SHIFT;
4547	gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l4_proto_idx_mask & AL_ETH_RX_GPD_OUTER_L4_PROTO_MASK) <<
4548		AL_ETH_RX_GPD_OUTER_L4_PROTO_SHIFT;
4549	gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l3_proto_idx_mask & AL_ETH_RX_GPD_INNER_L3_PROTO_MASK) <<
4550		AL_ETH_RX_GPD_INNER_L3_PROTO_SHIFT;
4551	gpd_mask |= ((uint64_t)rx_gpd_entry->inner_l4_proto_idx_mask & AL_ETH_RX_GPD_INNER_L4_PROTO_MASK) <<
4552		AL_ETH_RX_GPD_INNER_L4_PROTO_SHIFT;
4553	gpd_mask |= ((uint64_t)rx_gpd_entry->parse_ctrl_mask & AL_ETH_RX_GPD_OUTER_PARSE_CTRL_MASK) <<
4554		AL_ETH_RX_GPD_OUTER_PARSE_CTRL_SHIFT;
4555	gpd_mask |= ((uint64_t)rx_gpd_entry->outer_l3_len_mask & AL_ETH_RX_GPD_INNER_PARSE_CTRL_MASK) <<
4556		AL_ETH_RX_GPD_INNER_PARSE_CTRL_SHIFT;
4557	gpd_mask |= ((uint64_t)rx_gpd_entry->l3_priority_mask & AL_ETH_RX_GPD_L3_PRIORITY_MASK) <<
4558		AL_ETH_RX_GPD_L3_PRIORITY_SHIFT;
4559	gpd_mask |= ((uint64_t)rx_gpd_entry->l4_dst_port_lsb_mask & AL_ETH_RX_GPD_L4_DST_PORT_LSB_MASK) <<
4560		AL_ETH_RX_GPD_L4_DST_PORT_LSB_SHIFT;
4561
4562	/* Rx Generic protocol detect Cam compare table */
4563	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_addr, idx);
4564	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_ctrl,
4565			(uint32_t)((rx_gpd_entry->rx_gpd_cam_ctrl) << AL_ETH_RX_GPD_CAM_CTRL_VALID_SHIFT));
4566	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_2,
4567			(uint32_t)(gpd_mask >> AL_ETH_RX_GPD_CAM_MASK_2_SHIFT));
4568	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_mask_1,
4569			(uint32_t)(gpd_mask));
4570	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_2,
4571			(uint32_t)(gpd_data >> AL_ETH_RX_GPD_CAM_DATA_2_SHIFT));
4572	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gpd_cam_data_1,
4573			(uint32_t)(gpd_data));
4574	return 0;
4575}
4576
4577int al_eth_rx_generic_crc_table_entry_set(struct al_hal_eth_adapter *adapter, uint32_t idx,
4578		struct al_eth_rx_gcp_table_entry *rx_gcp_entry)
4579{
4580	uint32_t gcp_table_gen;
4581	uint32_t rx_alu_opcode;
4582	uint32_t rx_alu_opsel;
4583
4584	gcp_table_gen  = (rx_gcp_entry->poly_sel & AL_ETH_RX_GCP_POLY_SEL_MASK) <<
4585		AL_ETH_RX_GCP_POLY_SEL_SHIFT;
4586	gcp_table_gen |= (rx_gcp_entry->crc32_bit_comp & AL_ETH_RX_GCP_CRC32_BIT_COMP_MASK) <<
4587		AL_ETH_RX_GCP_CRC32_BIT_COMP_SHIFT;
4588	gcp_table_gen |= (rx_gcp_entry->crc32_bit_swap & AL_ETH_RX_GCP_CRC32_BIT_SWAP_MASK) <<
4589		AL_ETH_RX_GCP_CRC32_BIT_SWAP_SHIFT;
4590	gcp_table_gen |= (rx_gcp_entry->crc32_byte_swap & AL_ETH_RX_GCP_CRC32_BYTE_SWAP_MASK) <<
4591		AL_ETH_RX_GCP_CRC32_BYTE_SWAP_SHIFT;
4592	gcp_table_gen |= (rx_gcp_entry->data_bit_swap & AL_ETH_RX_GCP_DATA_BIT_SWAP_MASK) <<
4593		AL_ETH_RX_GCP_DATA_BIT_SWAP_SHIFT;
4594	gcp_table_gen |= (rx_gcp_entry->data_byte_swap & AL_ETH_RX_GCP_DATA_BYTE_SWAP_MASK) <<
4595		AL_ETH_RX_GCP_DATA_BYTE_SWAP_SHIFT;
4596	gcp_table_gen |= (rx_gcp_entry->trail_size & AL_ETH_RX_GCP_TRAIL_SIZE_MASK) <<
4597		AL_ETH_RX_GCP_TRAIL_SIZE_SHIFT;
4598	gcp_table_gen |= (rx_gcp_entry->head_size & AL_ETH_RX_GCP_HEAD_SIZE_MASK) <<
4599		AL_ETH_RX_GCP_HEAD_SIZE_SHIFT;
4600	gcp_table_gen |= (rx_gcp_entry->head_calc & AL_ETH_RX_GCP_HEAD_CALC_MASK) <<
4601		AL_ETH_RX_GCP_HEAD_CALC_SHIFT;
4602	gcp_table_gen |= (rx_gcp_entry->mask_polarity & AL_ETH_RX_GCP_MASK_POLARITY_MASK) <<
4603		AL_ETH_RX_GCP_MASK_POLARITY_SHIFT;
4604
4605	rx_alu_opcode  = (rx_gcp_entry->rx_alu_opcode_1 & AL_ETH_RX_GCP_OPCODE_1_MASK) <<
4606		AL_ETH_RX_GCP_OPCODE_1_SHIFT;
4607	rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_2 & AL_ETH_RX_GCP_OPCODE_2_MASK) <<
4608		AL_ETH_RX_GCP_OPCODE_2_SHIFT;
4609	rx_alu_opcode |= (rx_gcp_entry->rx_alu_opcode_3 & AL_ETH_RX_GCP_OPCODE_3_MASK) <<
4610		AL_ETH_RX_GCP_OPCODE_3_SHIFT;
4611	rx_alu_opsel  = (rx_gcp_entry->rx_alu_opsel_1 & AL_ETH_RX_GCP_OPSEL_1_MASK) <<
4612		AL_ETH_RX_GCP_OPSEL_1_SHIFT;
4613	rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_2 & AL_ETH_RX_GCP_OPSEL_2_MASK) <<
4614		AL_ETH_RX_GCP_OPSEL_2_SHIFT;
4615	rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_3 & AL_ETH_RX_GCP_OPSEL_3_MASK) <<
4616		AL_ETH_RX_GCP_OPSEL_3_SHIFT;
4617	rx_alu_opsel |= (rx_gcp_entry->rx_alu_opsel_4 & AL_ETH_RX_GCP_OPSEL_4_MASK) <<
4618		AL_ETH_RX_GCP_OPSEL_4_SHIFT;
4619
4620	/*  Rx Generic crc prameters table general */
4621	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_addr, idx);
4622	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_gen,
4623			gcp_table_gen);
4624	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_1,
4625			rx_gcp_entry->gcp_mask[0]);
4626	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_2,
4627			rx_gcp_entry->gcp_mask[1]);
4628	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_3,
4629			rx_gcp_entry->gcp_mask[2]);
4630	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_4,
4631			rx_gcp_entry->gcp_mask[3]);
4632	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_5,
4633			rx_gcp_entry->gcp_mask[4]);
4634	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_mask_6,
4635			rx_gcp_entry->gcp_mask[5]);
4636	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_crc_init,
4637			rx_gcp_entry->crc_init);
4638	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_res,
4639			rx_gcp_entry->gcp_table_res);
4640	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opcode,
4641			rx_alu_opcode);
4642	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_opsel,
4643			rx_alu_opsel);
4644	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_table_alu_val,
4645			rx_gcp_entry->alu_val);
4646	return 0;
4647}
4648
4649
4650#define AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM 9
4651#define AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM 32
4652
4653static struct al_eth_tx_gpd_cam_entry
4654al_eth_generic_tx_crc_gpd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {
4655
4656	/* [0] roce (with grh, bth) */
4657	{22,		0,		0,		0,		1,
4658	 0x1f,		0x0,		0x0,		0x0,		},
4659	/* [1] fcoe */
4660	{21,		0,		0,		0,		1,
4661	 0x1f,		0x0,		0x0,		0x0,		},
4662	/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */
4663	{8,		23,		0,		0,		1,
4664	 0x1f,		0x1f,		0x0,		0x0,		},
4665	/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */
4666	{11,		23,		0,		0,		1,
4667	 0x1f,		0x1f,		0x0,		0x0,		},
4668	/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */
4669	{23,		0,		5,		0,		1,
4670	 0x1f,		0x0,		0x5,		0x0,		},
4671	/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */
4672	{23,		0,		3,		0,		1,
4673	 0x1f,		0x0,		0x5,		0x0		},
4674	/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */
4675	{8,		2,		0,		0,		1,
4676	 0x1f,		0x1f,		0x0,		0x0,		},
4677	/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */
4678	{11,		2,		0,		0,		1,
4679	 0x1f,		0x1f,		0x0,		0x0,		},
4680	/* [8] default match */
4681	{0,		0,		0,		0,		1,
4682	 0x0,		0x0,		0x0,		0x0		}
4683};
4684
4685static struct al_eth_tx_gcp_table_entry
4686al_eth_generic_tx_crc_gcp[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {
4687
4688	/* [0] roce (with grh, bth) */
4689	{0,		1,		1,		0,		1,
4690	 0,		4,		8,		0,		1,
4691	 0,		0,		0,		0,		0,
4692	 0,		0,		{0xffff7f03,	0x00000000,	0x00000000,
4693	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4694	 0},
4695	/* [1] fcoe */
4696	{0,		1,		0,		0,		1,
4697	 0,		8,		14,		1,		1,
4698	 0,		0,		0,		0,		0,
4699	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
4700	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4701	 0},
4702	/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */
4703	{0,		1,		1,		0,		1,
4704	 0,		4,		0,		0,		1,
4705	 0,		0,		0,		0,		0,
4706	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
4707	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4708	 0},
4709	/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */
4710	{0,		1,		1,		0,		1,
4711	 0,		4,		0,		0,		1,
4712	 0,		0,		0,		0,		0,
4713	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
4714	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4715	 0},
4716	/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */
4717	{0,		1,		1,		0,		1,
4718	 0,		4,		0,		0,		1,
4719	 2,		0,		0,		0,		10,
4720	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
4721	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4722	 28},
4723	/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */
4724	{0,		1,		1,		0,		1,
4725	 0,		4,		0,		0,		1,
4726	 2,		0,		0,		0,		10,
4727	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
4728	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4729	 48},
4730	/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */
4731	{1,		1,		1,		0,		1,
4732	 0,		4,		0,		0,		1,
4733	 1,		0,		1,		0,		2,
4734	 10,		0,		{0x00000000,	0x00000000,	0x00000000,
4735	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4736	 8},
4737	/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */
4738	{1,		1,		1,		0,		1,
4739	 0,		4,		0,		0,		1,
4740	 1,		0,		1,		0,		2,
4741	 10,		0,		{0x00000000,	0x00000000,	0x00000000,
4742	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0,
4743	 8},
4744	/* [8] default match */
4745	{0,		0,		0,		0,		0,
4746	 0,		0,		0,		0,		0,
4747	 0,		0,		0,		0,		0,
4748	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
4749	 0x00000000,	0x00000000,	  0x00000000},	0x00000000,	0x0,
4750	 0}
4751};
4752
4753static struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry
4754al_eth_tx_crc_chksum_replace_cmd[AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM] = {
4755
4756	/* [0] roce (with grh, bth) */
4757	{0,1,0,1,		0,0,0,0,		0,0,0,0},
4758	/* [1] fcoe */
4759	{0,1,0,1,		0,0,0,0,		0,0,0,0},
4760	/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */
4761	{0,0,1,1,		0,0,0,0,		0,1,0,1},
4762	/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */
4763	{0,0,1,1,		0,0,0,0,		0,0,0,0},
4764	/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */
4765	{0,1,0,1,		0,0,0,0,		0,0,0,0},
4766	/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */
4767	{0,1,0,1,		0,0,0,0,		0,0,0,0},
4768	/* [6] GENERIC_STORAGE_READ over IPV4 (and udp) */
4769	{0,0,1,1,		0,0,0,0,		0,1,0,1},
4770	/* [7] GENERIC_STORAGE_READ over IPV6 (and udp) */
4771	{0,0,1,1,		0,0,0,0,		0,0,0,0},
4772	/* [8] default match */
4773	{0,0,0,0,		0,0,1,1,		0,1,0,1}
4774};
4775
4776static struct al_eth_rx_gpd_cam_entry
4777al_eth_generic_rx_crc_gpd[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = {
4778
4779	/* [0] roce (with grh, bth) */
4780	{22,		0,		0,		0,
4781	 0,		0,		0,		0,		1,
4782	 0x1f,		0x0,		0x0,		0x0,
4783	 0x4,		0x0,		0x0,		0x0},
4784	/* [1] fcoe */
4785	{21,		0,		0,		0,
4786	 0,		0,		0,		0,		1,
4787	 0x1f,		0x0,		0x0,		0x0,
4788	 0x4,		0x0,		0x0,		0x0},
4789	/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */
4790	{8,		23,		0,		0,
4791	 0,		0,		0,		0,		1,
4792	 0x1f,		0x1f,		0x0,		0x0,
4793	 0x4,		0x0,		0x0,		0x0},
4794	/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */
4795	{11,		23,		0,		0,
4796	 0,		0,		0,		0,		1,
4797	 0x1f,		0x1f,		0x0,		0x0,
4798	 0x4,		0x0,		0x0,		0x0},
4799	/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */
4800	{8,		13,		23,		0,
4801	 0,		0,		0,		0,		1,
4802	 0x1f,		0x1f,		0x1f,		0x0,
4803	 0x4,		0x0,		0x0,		0x0},
4804	/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */
4805	{11,		13,		23,		0,
4806	 0,		0,		0,		0,		1,
4807	 0x1f,		0x1f,		0x1f,		0x0,
4808	 0x4,		0x0,		0x0,		0x0},
4809	/* [6] tunneled roce (with grh, bth) over GRE over IPV4 */
4810	{8,		0,		22,		0,
4811	 4,		0,		0,		0,		1,
4812	 0x1f,		0x0,		0x1f,		0x0,
4813	 0x4,		0x0,		0x0,		0x0},
4814	/* [7] tunneled roce (with grh, bth) over GRE over IPV6 */
4815	{11,		0,		22,		0,
4816	 4,		0,		0,		0,		1,
4817	 0x1f,		0x0,		0x1f,		0x0,
4818	 0x4,		0x0,		0x0,		0x0},
4819	/* [8] tunneled fcoe over IPV4 */
4820	{8,		0,		21,		0,
4821	 4,		0,		0,		0,		1,
4822	 0x1f,		0x0,		0x1f,		0x0,
4823	 0x4,		0x0,		0x0,		0x0},
4824        /* [9] tunneled fcoe over IPV6 */
4825        {11,		0,		21,		0,
4826	 4,		0,		0,		0,		1,
4827         0x1f,		0x0,		0x1f,		0x0,
4828	 0x4,		0x0,		0x0,		0x0},
4829	/* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */
4830	{8,             0,              8,              23,
4831	 4,		0,		0,		0,		1,
4832	0x1f,		0x0,		0x1f,		0x1f,
4833	 0x4,		0x0,		0x0,		0x0},
4834	/* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */
4835	{11,		0,		8,		23,
4836	4,		0,		0,		0,		1,
4837	0x1f,		0x0,		0x1f,		0x1f,
4838	0x4,		0x0,		0x0,		0x0},
4839	/* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */
4840	{8,		0,		11,		23,
4841	4,		0,		0,		0,		1,
4842	0x1f,		0x0,		0x1f,		0x1f,
4843	0x4,		0x0,		0x0,		0x0},
4844	/* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */
4845	{11,		0,		11,		23,
4846	4,		0,		0,		0,		1,
4847	0x1f,		0x0,		0x1f,		0x1f,
4848	0x4,		0x0,		0x0,		0x0},
4849	/* [14] l3_pkt - IPV4 */
4850	{8,		0,		0,		0,
4851	0,		0,		0,		0,		1,
4852	0x1f,		0x1f,		0x0,		0x0,
4853	0x4,		0x0,		0x0,		0x0},
4854	/* [15] l4_hdr over IPV4 */
4855	{8,		12,		0,		0,
4856	0,		0,		0,		0,		1,
4857	0x1f,		0x1e,		0x0,		0x0,
4858	0x4,		0x0,		0x0,		0x0},
4859	/* [16] l3_pkt - IPV6 */
4860	{11,		0,		0,		0,
4861	0,		0,		0,		0,		1,
4862	0x1f,		0x1f,		0x0,		0x0,
4863	0x4,		0x0,		0x0,		0x0},
4864	/* [17] l4_hdr over IPV6 */
4865	{11,		12,		0,		0,
4866	0,		0,		0,		0,		1,
4867	0x1f,		0x1e,		0x0,		0x0,
4868	0x4,		0x0,		0x0,		0x0},
4869	/* [18] IPV4 over IPV4 */
4870	{8,		0,		8,		0,
4871	4,		0,		0,		0,		1,
4872	0x1f,		0x0,		0x1f,		0x1f,
4873	0x4,		0x0,		0x0,		0x0},
4874	/* [19] l4_hdr over IPV4 over IPV4 */
4875	{8,		0,		8,		12,
4876	4,		0,		0,		0,		1,
4877	0x1f,		0x0,		0x1f,		0x1e,
4878	0x4,		0x0,		0x0,		0x0},
4879	/* [20] IPV4 over IPV6 */
4880	{11,		0,		8,		0,
4881	4,		0,		0,		0,		1,
4882	0x1f,		0x0,		0x1f,		0x1f,
4883	0x4,		0x0,		0x0,		0x0},
4884	/* [21] l4_hdr over IPV4 over IPV6 */
4885	{11,		0,		8,		12,
4886	4,		0,		0,		0,		1,
4887	0x1f,		0x0,		0x1f,		0x1e,
4888	0x4,		0x0,		0x0,		0x0},
4889	/* [22] IPV6 over IPV4 */
4890	{8,		0,		11,		0,
4891	4,		0,		0,		0,		1,
4892	0x1f,		0x0,		0x1f,		0x1f,
4893	0x4,		0x0,		0x0,		0x0},
4894	/* [23] l4_hdr over IPV6 over IPV4 */
4895	{8,		0,		11,		12,
4896	4,		0,		0,		0,		1,
4897	0x1f,		0x0,		0x1f,		0x1e,
4898	0x4,		0x0,		0x0,		0x0},
4899	/* [24] IPV6 over IPV6 */
4900	{11,		0,		11,		0,
4901	4,		0,		0,		0,		1,
4902	0x1f,		0x0,		0x1f,		0x1f,
4903	0x4,		0x0,		0x0,		0x0},
4904	/* [25] l4_hdr over IPV6 over IPV6 */
4905	{11,		0,		11,		12,
4906	4,		0,		0,		0,		1,
4907	0x1f,		0x0,		0x1f,		0x1e,
4908	0x4,		0x0,		0x0,		0x0},
4909	/* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */
4910	{8,		2,		0,		0,
4911	0,		0,		0,		0,		1,
4912	0x1f,		0x1f,		0x0,		0x0,
4913	0x4,		0x0,		0x0,		0x0},
4914	/* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */
4915	{11,		2,		0,		0,
4916	0,		0,		0,		0,		1,
4917	0x1f,		0x1f,		0x0,		0x0,
4918	0x4,		0x0,		0x0,		0x0},
4919	/* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */
4920	{8,		0,		8,		2,
4921	4,		0,		0,		0,		1,
4922	0x18,		0x0,		0x1f,		0x1f,
4923	0x4,		0x0,		0x0,		0x0},
4924	/* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp)  over IPV4/IPV6 */
4925	{8,		0,		11,		2,
4926	4,		0,		0,		0,		1,
4927	0x18,		0x0,		0x1f,		0x1f,
4928	0x4,		0x0,		0x0,		0x0},
4929	/* [30] tunneled L2 over GRE over IPV4 */
4930	{8,		0,		0,		0,
4931	 4,		0,		0,		0,		1,
4932	 0x1f,		0x0,		0x1f,		0x0,
4933	 0x4,		0x0,		0x0,		0x0},
4934	/* [31] default match */
4935	{0,		0,		0,		0,
4936	 0,		0,		0,		0,		1,
4937	 0x0,		0x0,		0x0,		0x0,
4938	 0x0,		0x0,		0x0,		0x0}
4939};
4940
4941static struct al_eth_rx_gcp_table_entry
4942al_eth_generic_rx_crc_gcp[AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM] = {
4943
4944	/* [0] roce (with grh, bth) */
4945	{0,		 1,		1,		0,		1,
4946	 0,		4,		8,		0,		1,
4947	 0,		0,		0,		0,		0,
4948	 0,		0,		{0xffff7f03,	0x00000000,	0x00000000,
4949	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
4950	 0},
4951	/* [1] fcoe */
4952	{0,		1,		0,		0,		1,
4953	 0,		8,		14,		1,		1,
4954	 0,		0,		0,		0,		0,
4955	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
4956	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
4957	 0},
4958	/* [2] routable_roce that is refered as l4_protocol, over IPV4 (and udp) */
4959	{0,		1,		1,		0,		1,
4960	 0,		4,		0,		0,		1,
4961	 0,		0,		0,		0,		0,
4962	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
4963	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000011,
4964	 0},
4965	/* [3] routable_roce that is refered as l4_protocol, over IPV6 (and udp) */
4966	{0,		1,		1,		0,		1,
4967	 0,		4,		0,		0,		1,
4968	 0,		0,		0,		0,		0,
4969	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
4970	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
4971	 0},
4972	/* [4] routable_roce that is refered as tunneled_packet, over outer IPV4 and udp */
4973	{0,		1,		1,		0,		1,
4974	 0,		4,		0,		0,		1,
4975	 2,		0,		0,		0,		10,
4976	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
4977	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x0302201c,
4978	 28},
4979	/* [5] routable_roce that is refered as tunneled_packet, over outer IPV6 and udp */
4980	{0,		1,		1,		0,		1,
4981	 0,		4,		0,		0,		1,
4982	 2,		0,		0,		0,		10,
4983	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
4984	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03002018,
4985	 48},
4986	/* [6] tunneled roce (with grh, bth) over IPV4 */
4987	{0,		1,		1,		0,		1,
4988	 0,		4,		8,		0,		1,
4989	 0,		0,		0,		1,		0,
4990	 0,		0,		{0xffff7f03,	0x00000000,	0x00000000,
4991	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03020014,
4992	 0},
4993	/* [7] tunneled roce (with grh, bth) over IPV6 */
4994	{0,		1,		1,		0,		1,
4995	 0,		4,		8,		0,		1,
4996	 0,		0,		0,		1,		0,
4997	 0,		0,		{0xffff7f03,	0x00000000,	0x00000000,
4998	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
4999	 0},
5000	/* [8] tunneled fcoe over IPV4 */
5001	{0,		1,		0,		0,		1,
5002	 0,		8,		14,		1,		1,
5003	 0,		0,		0,		1,		0,
5004	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5005	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03020014,
5006	 0},
5007	/* [9] tunneled fcoe over IPV6 */
5008	{0,		1,		0,		0,		1,
5009	 0,		8,		14,		1,		1,
5010	 0,		0,		0,		1,		0,
5011	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5012	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
5013	 0},
5014	/* [10] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV4 */
5015	{0,		1,		1,		0,		1,
5016	 0,		4,		0,		0,		1,
5017	 0,		0,		0,		1,		0,
5018	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
5019	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03020015,
5020	 0},
5021	/* [11] tunneled routable_roce that is refered as l4_protocol, over IPV4 (and udp) over IPV6 */
5022	{0,		1,		1,		0,		1,
5023	 0,		4,		0,		0,		1,
5024	 0,		0,		0,		1,		0,
5025	 0,		0,		{0x3000cf00,	0x00000f00,	0xc0000000,
5026	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000011,
5027	 0},
5028	/* [12] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV4 */
5029	{0,		1,		1,		0,		1,
5030	 0,		4,		0,		0,		1,
5031	 0,		0,		0,		1,		0,
5032	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
5033	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03020014,
5034	 0},
5035	/* [13] tunneled routable_roce that is refered as l4_protocol, over IPV6 (and udp) over IPV6 */
5036	{0,		1,		1,		0,		1,
5037	 0,		4,		0,		0,		1,
5038	 0,		0,		0,		1,		0,
5039	 0,		0,		{0x7f030000,	0x00000000,	0x00000003,
5040	 0x00c00000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
5041	 0},
5042	/* [14] l3_pkt - IPV4 */
5043	{0,		0,		0,		0,		0,
5044	 0,		0,		0,		0,		0,
5045	 0,		0,		0,		0,		0,
5046	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5047	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000001,
5048	 0},
5049	/* [15] l4_hdr over IPV4 */
5050	{0,		0,		0,		0,		0,
5051	 0,		0,		0,		0,		0,
5052	 0,		0,		0,		0,		0,
5053	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5054	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000003,
5055	 0},
5056	/* [16] l3_pkt - IPV6 */
5057	{0,		0,		0,		0,		0,
5058	 0,		0,		0,		0,		0,
5059	 0,		0,		0,		0,		0,
5060	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5061	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000000,
5062	 0},
5063	/* [17] l4_hdr over IPV6 */
5064	{0,		0,		0,		0,		0,
5065	 0,		0,		0,		0,		0,
5066	 0,		0,		0,		0,		0,
5067	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5068	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000002,
5069	 0},
5070	/* [18] IPV4 over IPV4 */
5071	{0,		0,		0,		0,		0,
5072	 0,		0,		0,		0,		0,
5073	 0,		0,		0,		0,		0,
5074	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5075	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00020005,
5076	 0},
5077	/* [19] l4_hdr over IPV4 over IPV4 */
5078	{0,		0,		0,		0,		0,
5079	 0,		0,		0,		0,		0,
5080	 0,		0,		0,		0,		0,
5081	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5082	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00020007,
5083	 0},
5084	/* [20] IPV4 over IPV6 */
5085	{0,		0,		0,		0,		0,
5086	 0,		0,		0,		0,		0,
5087	 0,		0,		0,		0,		0,
5088	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5089	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000001,
5090	 0},
5091	/* [21] l4_hdr over IPV4 over IPV6 */
5092	{0,		0,		0,		0,		0,
5093	 0,		0,		0,		0,		0,
5094	 0,		0,		0,		0,		0,
5095	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5096	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000003,
5097	 0},
5098	/* [22] IPV6 over IPV4 */
5099	{0,		0,		0,		0,		0,
5100	 0,		0,		0,		0,		0,
5101	 0,		0,		0,		0,		0,
5102	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5103	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00020004,
5104	 0},
5105	/* [23] l4_hdr over IPV6 over IPV4 */
5106	{0,		0,		0,		0,		0,
5107	 0,		0,		0,		0,		0,
5108	 0,		0,		0,		0,		0,
5109	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5110	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00020006,
5111	 0},
5112	/* [24] IPV6 over IPV6 */
5113	{0,		0,		0,		0,		0,
5114	 0,		0,		0,		0,		0,
5115	 0,		0,		0,		0,		0,
5116	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5117	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000000,
5118	 0},
5119	/* [25] l4_hdr over IPV6 over IPV6 */
5120	{0,		0,		0,		0,		0,
5121	 0,		0,		0,		0,		0,
5122	 0,		0,		0,		0,		0,
5123	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5124	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00000002,
5125	 0},
5126	/* [26] GENERIC_STORAGE_READ, over IPV4 (and udp) */
5127	{1,		1,		1,		0,		1,
5128	 0,		4,		0,		0,		1,
5129	 0,		0,		0,		2,		0,
5130	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5131	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000011,
5132	 0},
5133	/* [27] GENERIC_STORAGE_READ, over IPV6 (and udp) */
5134	{1,		1,		1,		0,		1,
5135	 0,		4,		0,		0,		1,
5136	 0,		0,		0,		2,		0,
5137	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5138	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
5139	 0},
5140	/* [28] tunneled GENERIC_STORAGE_READ over IPV4 (and udp) over IPV4/IPV6 */
5141	{1,		1,		1,		0,		1,
5142	 0,		4,		0,		0,		1,
5143	 0,		0,		0,		3,		0,
5144	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5145	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000011,
5146	 0},
5147	/* [29] tunneled GENERIC_STORAGE_READ over IPV6 (and udp)  over IPV4/IPV6 */
5148	{1,		1,		1,		0,		1,
5149	 0,		4,		0,		0,		1,
5150	 0,		0,		0,		3,		0,
5151	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5152	 0x00000000,	0x00000000,	0x00000000},	0xffffffff,	0x03000010,
5153	 0},
5154	/* [30] tunneled L2 over GRE over IPV4 */
5155	{0,		0,		0,		0,		0,
5156	 0,		0,		0,		0,		0,
5157	 0,		0,		0,		0,		0,
5158	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5159	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x00020004,
5160	 0},
5161	/* [31] default match */
5162	{0,		0,		0,		0,		0,
5163	 0,		0,		0,		0,		0,
5164	 0,		0,		0,		0,		0,
5165	 0,		0,		{0x00000000,	0x00000000,	0x00000000,
5166	 0x00000000,	0x00000000,	0x00000000},	0x00000000,	0x0,
5167	 0}
5168};
5169
5170int al_eth_tx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter)
5171{
5172	int idx;
5173	al_assert((adapter->rev_id > AL_ETH_REV_ID_2));
5174
5175	for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)
5176		al_eth_tx_protocol_detect_table_entry_set(adapter, idx,
5177				&al_eth_generic_tx_crc_gpd[idx]);
5178
5179	return 0;
5180}
5181
5182int al_eth_tx_generic_crc_table_init(struct al_hal_eth_adapter *adapter)
5183{
5184	int idx;
5185	al_assert((adapter->rev_id > AL_ETH_REV_ID_2));
5186
5187	al_dbg("eth [%s]: enable tx_generic_crc\n", adapter->name);
5188	al_reg_write32(&adapter->ec_regs_base->tfw_v3.tx_gcp_legacy, 0x0);
5189	al_reg_write32(&adapter->ec_regs_base->tfw_v3.crc_csum_replace, 0x0);
5190	for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)
5191		al_eth_tx_generic_crc_table_entry_set(adapter, idx,
5192				&al_eth_generic_tx_crc_gcp[idx]);
5193
5194	return 0;
5195}
5196
5197int al_eth_tx_crc_chksum_replace_cmd_init(struct al_hal_eth_adapter *adapter)
5198{
5199	int idx;
5200	al_assert((adapter->rev_id > AL_ETH_REV_ID_2));
5201
5202	for (idx = 0; idx < AL_ETH_TX_GENERIC_CRC_ENTRIES_NUM; idx++)
5203		al_eth_tx_crc_chksum_replace_cmd_entry_set(adapter, idx,
5204				&al_eth_tx_crc_chksum_replace_cmd[idx]);
5205
5206	return 0;
5207}
5208
5209int al_eth_rx_protocol_detect_table_init(struct al_hal_eth_adapter *adapter)
5210{
5211	int idx;
5212	al_assert((adapter->rev_id > AL_ETH_REV_ID_2));
5213	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p1,
5214			AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L3_PROTO_IDX_OFFSET);
5215	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p2,
5216			AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_PROTO_IDX_OFFSET);
5217	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p3,
5218			AL_ETH_RX_GPD_PARSE_RESULT_INNER_L3_PROTO_IDX_OFFSET);
5219	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p4,
5220			AL_ETH_RX_GPD_PARSE_RESULT_INNER_L4_PROTO_IDX_OFFSET);
5221	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p5,
5222			AL_ETH_RX_GPD_PARSE_RESULT_OUTER_PARSE_CTRL);
5223	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p6,
5224			AL_ETH_RX_GPD_PARSE_RESULT_INNER_PARSE_CTRL);
5225	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p7,
5226			AL_ETH_RX_GPD_PARSE_RESULT_L3_PRIORITY);
5227	al_reg_write32(&adapter->ec_regs_base->rfw_v3.gpd_p8,
5228			AL_ETH_RX_GPD_PARSE_RESULT_OUTER_L4_DST_PORT_LSB);
5229
5230	for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++)
5231		al_eth_rx_protocol_detect_table_entry_set(adapter, idx,
5232				&al_eth_generic_rx_crc_gpd[idx]);
5233	return 0;
5234}
5235
5236int al_eth_rx_generic_crc_table_init(struct al_hal_eth_adapter *adapter)
5237	{
5238	int idx;
5239	uint32_t val;
5240
5241	al_assert((adapter->rev_id > AL_ETH_REV_ID_2));
5242
5243	al_dbg("eth [%s]: enable rx_generic_crc\n", adapter->name);
5244	al_reg_write32(&adapter->ec_regs_base->rfw_v3.rx_gcp_legacy, 0x0);
5245
5246	for (idx = 0; idx < AL_ETH_RX_PROTOCOL_DETECT_ENTRIES_NUM; idx++)
5247		al_eth_rx_generic_crc_table_entry_set(adapter, idx,
5248				&al_eth_generic_rx_crc_gcp[idx]);
5249
5250	val = EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_15_CRC_RES_SEL |
5251			EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_14_L3_CKS_RES_SEL |
5252			EC_GEN_V3_RX_COMP_DESC_W3_DEC_STAT_13_L4_CKS_RES_SEL |
5253			EC_GEN_V3_RX_COMP_DESC_W0_L3_CKS_RES_SEL;
5254	al_reg_write32_masked(&adapter->ec_regs_base->gen_v3.rx_comp_desc,
5255			val, val);
5256	return 0;
5257}
5258
5259/** @} end of Ethernet group */
5260
5261