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