1 /*-
2 *******************************************************************************
3 Copyright (C) 2015 Annapurna Labs Ltd.
4
5 This file may be licensed under the terms of the Annapurna Labs Commercial
6 License Agreement.
7
8 Alternatively, this file can be distributed under the terms of the GNU General
9 Public License V2 as published by the Free Software Foundation and can be
10 found at http://www.gnu.org/licenses/gpl-2.0.html
11
12 Alternatively, redistribution and use in source and binary forms, with or
13 without modification, are permitted provided that the following conditions are
14 met:
15
16 * Redistributions of source code must retain the above copyright notice,
17 this list of conditions and the following disclaimer.
18
19 * Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in
21 the documentation and/or other materials provided with the
22 distribution.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
28 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ANY 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
33 SOFTWARE, 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
255 static 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
285 static 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
al_eth_mac_mode_str(enum al_eth_mac_mode mode)321 static 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 */
al_udma_state_set_wait(struct al_udma * dma,enum al_udma_state new_state)355 static 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
al_eth_epe_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_epe_p_reg_entry * reg_entry,struct al_eth_epe_control_entry * control_entry)385 static 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
al_eth_epe_init(struct al_hal_eth_adapter * adapter)428 static 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 */
al_eth_40g_mac_reg_read(struct al_hal_eth_adapter * adapter,uint32_t reg_addr)470 static 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 */
al_eth_40g_mac_reg_write(struct al_hal_eth_adapter * adapter,uint32_t reg_addr,uint32_t reg_data)494 static 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 */
al_eth_40g_pcs_reg_read(struct al_hal_eth_adapter * adapter,uint32_t reg_addr)515 static 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 */
al_eth_40g_pcs_reg_write(struct al_hal_eth_adapter * adapter,uint32_t reg_addr,uint32_t reg_data)539 static 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 */
al_eth_adapter_init(struct al_hal_eth_adapter * adapter,struct al_eth_adapter_params * params)557 int 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 */
al_eth_ec_mac_ints_config(struct al_hal_eth_adapter * adapter)718 int 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 */
al_eth_ec_mac_isr(struct al_hal_eth_adapter * adapter)765 int 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 */
al_eth_adapter_stop(struct al_hal_eth_adapter * adapter)804 int 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
al_eth_adapter_reset(struct al_hal_eth_adapter * adapter)833 int 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 */
al_eth_queue_config(struct al_hal_eth_adapter * adapter,enum al_udma_type type,uint32_t qid,struct al_udma_q_params * q_params)844 int 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
al_eth_queue_enable(struct al_hal_eth_adapter * adapter,enum al_udma_type type,uint32_t qid)879 int 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 }
al_eth_queue_disable(struct al_hal_eth_adapter * adapter,enum al_udma_type type,uint32_t qid)885 int 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 */
al_eth_rx_pkt_limit_config(struct al_hal_eth_adapter * adapter,uint32_t min_rx_len,uint32_t max_rx_len)893 int 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. */
al_eth_mac_config(struct al_hal_eth_adapter * adapter,enum al_eth_mac_mode mode)922 int 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 */
al_eth_mac_start(struct al_hal_eth_adapter * adapter)1525 int 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 */
al_eth_mac_stop(struct al_hal_eth_adapter * adapter)1555 int 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
al_eth_gearbox_reset(struct al_hal_eth_adapter * adapter,al_bool tx_reset,al_bool rx_reset)1584 void 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
al_eth_fec_enable(struct al_hal_eth_adapter * adapter,al_bool enable)1612 int 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
al_eth_fec_stats_get(struct al_hal_eth_adapter * adapter,uint32_t * corrected,uint32_t * uncorrectable)1631 int 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
al_eth_capabilities_get(struct al_hal_eth_adapter * adapter,struct al_eth_capabilities * caps)1644 int 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
al_eth_mac_link_config_1g_mac(struct al_hal_eth_adapter * adapter,al_bool force_1000_base_x,al_bool an_enable,uint32_t speed,al_bool full_duplex)1680 static 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
al_eth_mac_link_config_10g_mac(struct al_hal_eth_adapter * adapter,al_bool force_1000_base_x,al_bool an_enable,uint32_t speed,al_bool full_duplex)1761 static 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 */
al_eth_mac_link_config(struct al_hal_eth_adapter * adapter,al_bool force_1000_base_x,al_bool an_enable,uint32_t speed,al_bool full_duplex)1819 int 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
al_eth_mac_loopback_config(struct al_hal_eth_adapter * adapter,int enable)1870 int 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 */
al_eth_mdio_config(struct al_hal_eth_adapter * adapter,enum al_eth_mdio_type mdio_type,al_bool shared_mdio_if,enum al_eth_ref_clk_freq ref_clk_freq,unsigned int mdio_clk_freq_khz)1915 int 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
al_eth_mdio_1g_mac_read(struct al_hal_eth_adapter * adapter,uint32_t phy_addr,uint32_t reg,uint16_t * val)2003 static 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
al_eth_mdio_1g_mac_write(struct al_hal_eth_adapter * adapter,uint32_t phy_addr,uint32_t reg,uint16_t val)2012 static 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
al_eth_mdio_10g_mac_wait_busy(struct al_hal_eth_adapter * adapter)2021 static 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
al_eth_mdio_10g_mac_type22(struct al_hal_eth_adapter * adapter,int read,uint32_t phy_addr,uint32_t reg,uint16_t * val)2046 static 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
al_eth_mdio_10g_mac_type45(struct al_hal_eth_adapter * adapter,int read,uint32_t port_addr,uint32_t device,uint32_t reg,uint16_t * val)2094 static 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 */
al_eth_mdio_lock(struct al_hal_eth_adapter * adapter)2163 static 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 */
al_eth_mdio_free(struct al_hal_eth_adapter * adapter)2201 static 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
al_eth_mdio_read(struct al_hal_eth_adapter * adapter,uint32_t phy_addr,uint32_t device,uint32_t reg,uint16_t * val)2225 int 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
al_eth_mdio_write(struct al_hal_eth_adapter * adapter,uint32_t phy_addr,uint32_t device,uint32_t reg,uint16_t val)2247 int 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
al_dump_tx_desc(union al_udma_desc * tx_desc)2268 static 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
2278 static void
al_dump_tx_pkt(struct al_udma_q * tx_dma_q,struct al_eth_pkt * pkt)2279 al_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 */
al_eth_tx_pkt_prepare(struct al_udma_q * tx_dma_q,struct al_eth_pkt * pkt)2377 int 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
al_eth_tx_dma_action(struct al_udma_q * tx_dma_q,uint32_t tx_descs)2570 void 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 */
al_eth_comp_tx_get(struct al_udma_q * tx_dma_q)2579 int 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 */
al_eth_tso_mss_config(struct al_hal_eth_adapter * adapter,uint8_t idx,uint32_t mss_val)2596 int 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 */
al_eth_rx_desc_config(struct al_hal_eth_adapter * adapter,enum al_eth_rx_desc_lro_context_val_res lro_sel,enum al_eth_rx_desc_l4_offset_sel l4_offset_sel,enum al_eth_rx_desc_l3_offset_sel l3_offset_sel,enum al_eth_rx_desc_l4_chk_res_sel l4_sel,enum al_eth_rx_desc_l3_chk_res_sel l3_sel,enum al_eth_rx_desc_l3_proto_idx_sel l3_proto_sel,enum al_eth_rx_desc_l4_proto_idx_sel l4_proto_sel,enum al_eth_rx_desc_frag_sel frag_sel)2612 void 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 */
al_eth_rx_header_split_config(struct al_hal_eth_adapter * adapter,al_bool enable,uint32_t header_len)2668 int 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 */
al_eth_rx_header_split_force_len_config(struct al_hal_eth_adapter * adapter,al_bool enable,uint32_t qid,uint32_t header_len)2688 int 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 */
al_eth_rx_buffer_add(struct al_udma_q * rx_dma_q,struct al_buf * buf,uint32_t flags,struct al_buf * header_buf)2703 int 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 */
al_eth_rx_buffer_action(struct al_udma_q * rx_dma_q,uint32_t descs_num)2744 void 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 */
al_eth_pkt_rx(struct al_udma_q * rx_dma_q,struct al_eth_pkt * pkt)2756 uint32_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
al_eth_rx_parser_entry_update(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_epe_p_reg_entry * reg_entry,struct al_eth_epe_control_entry * control_entry)2815 int 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
al_eth_thash_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t udma,uint32_t queue)2829 int 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
al_eth_fsm_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint32_t entry)2842 int 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
al_eth_fwd_ctrl_entry_to_val(struct al_eth_fwd_ctrl_table_entry * entry)2853 static 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
al_eth_ctrl_index_match(struct al_eth_fwd_ctrl_table_index * index,uint32_t i)2868 static 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
al_eth_ctrl_table_set(struct al_hal_eth_adapter * adapter,struct al_eth_fwd_ctrl_table_index * index,struct al_eth_fwd_ctrl_table_entry * entry)2890 int 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
al_eth_ctrl_table_def_set(struct al_hal_eth_adapter * adapter,al_bool use_table,struct al_eth_fwd_ctrl_table_entry * entry)2906 int 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
al_eth_ctrl_table_raw_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint32_t entry)2920 int 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
al_eth_ctrl_table_def_raw_set(struct al_hal_eth_adapter * adapter,uint32_t val)2931 int 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
al_eth_hash_key_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint32_t val)2938 int 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
al_eth_fwd_mac_table_entry_to_val(struct al_eth_fwd_mac_table_entry * entry)2948 static 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
al_eth_fwd_mac_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_fwd_mac_table_entry * entry)2969 int 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
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)2994 int 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
al_eth_fwd_mac_ctrl_raw_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint32_t ctrl)3006 int 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
al_eth_mac_addr_store(void * __iomem ec_base,uint32_t idx,uint8_t * addr)3015 int 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
al_eth_mac_addr_read(void * __iomem ec_base,uint32_t idx,uint8_t * addr)3029 int 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
al_eth_fwd_mhash_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t udma_mask,uint8_t qid)3044 int 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 }
al_eth_fwd_vid_entry_to_val(struct al_eth_fwd_vid_table_entry * entry)3056 static 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
al_eth_fwd_vid_config_set(struct al_hal_eth_adapter * adapter,al_bool use_table,struct al_eth_fwd_vid_table_entry * default_entry,uint32_t default_vlan)3066 int 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
al_eth_fwd_vid_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_fwd_vid_table_entry * entry)3083 int 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
al_eth_fwd_pbits_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t prio)3095 int 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
al_eth_fwd_priority_table_set(struct al_hal_eth_adapter * adapter,uint8_t prio,uint8_t qid)3105 int 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
al_eth_fwd_dscp_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t prio)3114 int 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
al_eth_fwd_tc_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t prio)3125 int 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 */
al_eth_fwd_default_udma_config(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t udma_mask)3137 int 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 */
al_eth_fwd_default_queue_config(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t qid)3147 int 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 */
al_eth_fwd_default_priority_config(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t prio)3157 int 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
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,enum al_eth_tx_switch_vid_sel_type vid_sel_type,enum al_eth_tx_switch_dec_type uc_dec,enum al_eth_tx_switch_dec_type mc_dec,enum al_eth_tx_switch_dec_type bc_dec)3166 int 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 */
al_eth_filter_config(struct al_hal_eth_adapter * adapter,struct al_eth_filter_params * params)3207 int 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 */
al_eth_filter_override_config(struct al_hal_eth_adapter * adapter,struct al_eth_filter_override_params * params)3244 int 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
al_eth_switching_default_bitmap_set(struct al_hal_eth_adapter * adapter,uint8_t udma_id,uint8_t udma_uc_bitmask,uint8_t udma_mc_bitmask,uint8_t udma_bc_bitmask)3270 int 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
al_eth_flow_control_config(struct al_hal_eth_adapter * adapter,struct al_eth_flow_control_params * params)3280 int 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
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)3460 int 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
al_eth_eee_get(struct al_hal_eth_adapter * adapter,struct al_eth_eee_params * params)3470 int 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
al_eth_eee_config(struct al_hal_eth_adapter * adapter,struct al_eth_eee_params * params)3487 int 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. */
al_eth_ts_init(struct al_hal_eth_adapter * adapter)3551 int 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. */
al_eth_tx_ts_val_get(struct al_hal_eth_adapter * adapter,uint8_t ts_index,uint32_t * timestamp)3581 int 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 */
al_eth_pth_systime_read(struct al_hal_eth_adapter * adapter,struct al_eth_pth_time * systime)3598 int 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. */
al_eth_pth_clk_period_write(struct al_hal_eth_adapter * adapter,uint64_t clk_period)3615 int 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 */
al_eth_pth_int_update_config(struct al_hal_eth_adapter * adapter,struct al_eth_pth_int_update_params * params)3632 int 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 */
al_eth_pth_int_update_time_set(struct al_hal_eth_adapter * adapter,struct al_eth_pth_time * time)3654 int 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 */
al_eth_pth_ext_update_config(struct al_hal_eth_adapter * adapter,struct al_eth_pth_ext_update_params * params)3673 int 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 */
al_eth_pth_ext_update_time_set(struct al_hal_eth_adapter * adapter,struct al_eth_pth_time * time)3691 int 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 */
al_eth_pth_read_compensation_set(struct al_hal_eth_adapter * adapter,uint64_t subseconds)3710 int 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 */
al_eth_pth_int_write_compensation_set(struct al_hal_eth_adapter * adapter,uint64_t subseconds)3725 int 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 */
al_eth_pth_ext_write_compensation_set(struct al_hal_eth_adapter * adapter,uint64_t subseconds)3740 int 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 */
al_eth_pth_sync_compensation_set(struct al_hal_eth_adapter * adapter,uint64_t subseconds)3755 int 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 */
al_eth_pth_pulse_out_config(struct al_hal_eth_adapter * adapter,struct al_eth_pth_pulse_out_params * params)3770 int 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 */
al_eth_link_status_get(struct al_hal_eth_adapter * adapter,struct al_eth_link_status * status)3822 int 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
al_eth_link_status_clear(struct al_hal_eth_adapter * adapter)3920 int 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 */
al_eth_led_set(struct al_hal_eth_adapter * adapter,al_bool link_is_up)3937 int 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 */
al_eth_mac_stats_get(struct al_hal_eth_adapter * adapter,struct al_eth_mac_stats * stats)3962 int 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(®_stats->ifInUcastPkts);
3973 stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts);
3974 stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts);
3975 stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts);
3976 stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts);
3977 stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts);
3978 stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts);
3979 stats->ifInErrors = al_reg_read32(®_stats->ifInErrors);
3980 stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors);
3981 stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK);
3982 stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK);
3983 stats->aOctetsReceivedOK = al_reg_read32(®_stats->aOctetsReceivedOK);
3984 stats->aOctetsTransmittedOK = al_reg_read32(®_stats->aOctetsTransmittedOK);
3985 stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts);
3986 stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments);
3987 stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers);
3988 stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts);
3989 stats->aFrameCheckSequenceErrors =
3990 al_reg_read32(®_stats->aFrameCheckSequenceErrors);
3991 stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors);
3992 stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents);
3993 stats->aPAUSEMACCtrlFramesTransmitted =
3994 al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted);
3995 stats->aPAUSEMACCtrlFramesReceived =
3996 al_reg_read32(®_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(®_stats->etherStatsOctets);
4002 stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets);
4003 stats->etherStatsPkts65to127Octets =
4004 al_reg_read32(®_stats->etherStatsPkts65to127Octets);
4005 stats->etherStatsPkts128to255Octets =
4006 al_reg_read32(®_stats->etherStatsPkts128to255Octets);
4007 stats->etherStatsPkts256to511Octets =
4008 al_reg_read32(®_stats->etherStatsPkts256to511Octets);
4009 stats->etherStatsPkts512to1023Octets =
4010 al_reg_read32(®_stats->etherStatsPkts512to1023Octets);
4011 stats->etherStatsPkts1024to1518Octets =
4012 al_reg_read32(®_stats->etherStatsPkts1024to1518Octets);
4013 stats->etherStatsPkts1519toX = al_reg_read32(®_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(®_stats->ifInUcastPkts);
4021 stats->ifInMulticastPkts = al_reg_read32(®_stats->ifInMulticastPkts);
4022 stats->ifInBroadcastPkts = al_reg_read32(®_stats->ifInBroadcastPkts);
4023 stats->etherStatsPkts = al_reg_read32(®_stats->etherStatsPkts);
4024 stats->ifOutUcastPkts = al_reg_read32(®_stats->ifOutUcastPkts);
4025 stats->ifOutMulticastPkts = al_reg_read32(®_stats->ifOutMulticastPkts);
4026 stats->ifOutBroadcastPkts = al_reg_read32(®_stats->ifOutBroadcastPkts);
4027 stats->ifInErrors = al_reg_read32(®_stats->ifInErrors);
4028 stats->ifOutErrors = al_reg_read32(®_stats->ifOutErrors);
4029 stats->aFramesReceivedOK = al_reg_read32(®_stats->aFramesReceivedOK);
4030 stats->aFramesTransmittedOK = al_reg_read32(®_stats->aFramesTransmittedOK);
4031
4032 /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
4033 octets = al_reg_read32(®_stats->ifInOctetsL);
4034 octets |= (uint64_t)(al_reg_read32(®_stats->ifInOctetsH)) << 32;
4035 octets -= 18 * stats->aFramesReceivedOK;
4036 octets -= 4 * al_reg_read32(®_stats->VLANReceivedOK);
4037 stats->aOctetsReceivedOK = octets;
4038
4039 /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
4040 octets = al_reg_read32(®_stats->ifOutOctetsL);
4041 octets |= (uint64_t)(al_reg_read32(®_stats->ifOutOctetsH)) << 32;
4042 octets -= 18 * stats->aFramesTransmittedOK;
4043 octets -= 4 * al_reg_read32(®_stats->VLANTransmittedOK);
4044 stats->aOctetsTransmittedOK = octets;
4045
4046 stats->etherStatsUndersizePkts = al_reg_read32(®_stats->etherStatsUndersizePkts);
4047 stats->etherStatsFragments = al_reg_read32(®_stats->etherStatsFragments);
4048 stats->etherStatsJabbers = al_reg_read32(®_stats->etherStatsJabbers);
4049 stats->etherStatsOversizePkts = al_reg_read32(®_stats->etherStatsOversizePkts);
4050 stats->aFrameCheckSequenceErrors = al_reg_read32(®_stats->aFrameCheckSequenceErrors);
4051 stats->aAlignmentErrors = al_reg_read32(®_stats->aAlignmentErrors);
4052 stats->etherStatsDropEvents = al_reg_read32(®_stats->etherStatsDropEvents);
4053 stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_stats->aPAUSEMACCtrlFramesTransmitted);
4054 stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_stats->aPAUSEMACCtrlFramesReceived);
4055 stats->aFrameTooLongErrors = al_reg_read32(®_stats->aFrameTooLongErrors);
4056 stats->aInRangeLengthErrors = al_reg_read32(®_stats->aInRangeLengthErrors);
4057 stats->VLANTransmittedOK = al_reg_read32(®_stats->VLANTransmittedOK);
4058 stats->VLANReceivedOK = al_reg_read32(®_stats->VLANReceivedOK);
4059 stats->etherStatsOctets = al_reg_read32(®_stats->etherStatsOctets);
4060 stats->etherStatsPkts64Octets = al_reg_read32(®_stats->etherStatsPkts64Octets);
4061 stats->etherStatsPkts65to127Octets = al_reg_read32(®_stats->etherStatsPkts65to127Octets);
4062 stats->etherStatsPkts128to255Octets = al_reg_read32(®_stats->etherStatsPkts128to255Octets);
4063 stats->etherStatsPkts256to511Octets = al_reg_read32(®_stats->etherStatsPkts256to511Octets);
4064 stats->etherStatsPkts512to1023Octets = al_reg_read32(®_stats->etherStatsPkts512to1023Octets);
4065 stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_stats->etherStatsPkts1024to1518Octets);
4066 stats->etherStatsPkts1519toX = al_reg_read32(®_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(®_rx_stats->ifInUcastPkts);
4075 stats->ifInMulticastPkts = al_reg_read32(®_rx_stats->ifInMulticastPkts);
4076 stats->ifInBroadcastPkts = al_reg_read32(®_rx_stats->ifInBroadcastPkts);
4077 stats->etherStatsPkts = al_reg_read32(®_rx_stats->etherStatsPkts);
4078 stats->ifOutUcastPkts = al_reg_read32(®_tx_stats->ifUcastPkts);
4079 stats->ifOutMulticastPkts = al_reg_read32(®_tx_stats->ifMulticastPkts);
4080 stats->ifOutBroadcastPkts = al_reg_read32(®_tx_stats->ifBroadcastPkts);
4081 stats->ifInErrors = al_reg_read32(®_rx_stats->ifInErrors);
4082 stats->ifOutErrors = al_reg_read32(®_tx_stats->ifOutErrors);
4083 stats->aFramesReceivedOK = al_reg_read32(®_rx_stats->FramesOK);
4084 stats->aFramesTransmittedOK = al_reg_read32(®_tx_stats->FramesOK);
4085
4086 /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
4087 octets = al_reg_read32(®_rx_stats->ifOctetsL);
4088 octets |= (uint64_t)(al_reg_read32(®_rx_stats->ifOctetsH)) << 32;
4089 octets -= 18 * stats->aFramesReceivedOK;
4090 octets -= 4 * al_reg_read32(®_rx_stats->VLANOK);
4091 stats->aOctetsReceivedOK = octets;
4092
4093 /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
4094 octets = al_reg_read32(®_tx_stats->ifOctetsL);
4095 octets |= (uint64_t)(al_reg_read32(®_tx_stats->ifOctetsH)) << 32;
4096 octets -= 18 * stats->aFramesTransmittedOK;
4097 octets -= 4 * al_reg_read32(®_tx_stats->VLANOK);
4098 stats->aOctetsTransmittedOK = octets;
4099
4100 stats->etherStatsUndersizePkts = al_reg_read32(®_rx_stats->etherStatsUndersizePkts);
4101 stats->etherStatsFragments = al_reg_read32(®_rx_stats->etherStatsFragments);
4102 stats->etherStatsJabbers = al_reg_read32(®_rx_stats->etherStatsJabbers);
4103 stats->etherStatsOversizePkts = al_reg_read32(®_rx_stats->etherStatsOversizePkts);
4104 stats->aFrameCheckSequenceErrors = al_reg_read32(®_rx_stats->CRCErrors);
4105 stats->aAlignmentErrors = al_reg_read32(®_rx_stats->aAlignmentErrors);
4106 stats->etherStatsDropEvents = al_reg_read32(®_rx_stats->etherStatsDropEvents);
4107 stats->aPAUSEMACCtrlFramesTransmitted = al_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames);
4108 stats->aPAUSEMACCtrlFramesReceived = al_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames);
4109 stats->aFrameTooLongErrors = al_reg_read32(®_rx_stats->aFrameTooLong);
4110 stats->aInRangeLengthErrors = al_reg_read32(®_rx_stats->aInRangeLengthErrors);
4111 stats->VLANTransmittedOK = al_reg_read32(®_tx_stats->VLANOK);
4112 stats->VLANReceivedOK = al_reg_read32(®_rx_stats->VLANOK);
4113 stats->etherStatsOctets = al_reg_read32(®_rx_stats->etherStatsOctets);
4114 stats->etherStatsPkts64Octets = al_reg_read32(®_rx_stats->etherStatsPkts64Octets);
4115 stats->etherStatsPkts65to127Octets = al_reg_read32(®_rx_stats->etherStatsPkts65to127Octets);
4116 stats->etherStatsPkts128to255Octets = al_reg_read32(®_rx_stats->etherStatsPkts128to255Octets);
4117 stats->etherStatsPkts256to511Octets = al_reg_read32(®_rx_stats->etherStatsPkts256to511Octets);
4118 stats->etherStatsPkts512to1023Octets = al_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets);
4119 stats->etherStatsPkts1024to1518Octets = al_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets);
4120 stats->etherStatsPkts1519toX = al_reg_read32(®_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(®_rx_stats->ifInUcastPkts);
4134 stats->ifInMulticastPkts = _40g_mac_reg_read32(®_rx_stats->ifInMulticastPkts);
4135 stats->ifInBroadcastPkts = _40g_mac_reg_read32(®_rx_stats->ifInBroadcastPkts);
4136 stats->etherStatsPkts = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts);
4137 stats->ifOutUcastPkts = _40g_mac_reg_read32(®_tx_stats->ifUcastPkts);
4138 stats->ifOutMulticastPkts = _40g_mac_reg_read32(®_tx_stats->ifMulticastPkts);
4139 stats->ifOutBroadcastPkts = _40g_mac_reg_read32(®_tx_stats->ifBroadcastPkts);
4140 stats->ifInErrors = _40g_mac_reg_read32(®_rx_stats->ifInErrors);
4141 stats->ifOutErrors = _40g_mac_reg_read32(®_tx_stats->ifOutErrors);
4142 stats->aFramesReceivedOK = _40g_mac_reg_read32(®_rx_stats->FramesOK);
4143 stats->aFramesTransmittedOK = _40g_mac_reg_read32(®_tx_stats->FramesOK);
4144
4145 /* aOctetsReceivedOK = ifInOctets - 18 * aFramesReceivedOK - 4 * VLANReceivedOK */
4146 octets = _40g_mac_reg_read32(®_rx_stats->ifOctetsL);
4147 octets |= (uint64_t)(_40g_mac_reg_read32(®_rx_stats->ifOctetsH)) << 32;
4148 octets -= 18 * stats->aFramesReceivedOK;
4149 octets -= 4 * _40g_mac_reg_read32(®_rx_stats->VLANOK);
4150 stats->aOctetsReceivedOK = octets;
4151
4152 /* aOctetsTransmittedOK = ifOutOctets - 18 * aFramesTransmittedOK - 4 * VLANTransmittedOK */
4153 octets = _40g_mac_reg_read32(®_tx_stats->ifOctetsL);
4154 octets |= (uint64_t)(_40g_mac_reg_read32(®_tx_stats->ifOctetsH)) << 32;
4155 octets -= 18 * stats->aFramesTransmittedOK;
4156 octets -= 4 * _40g_mac_reg_read32(®_tx_stats->VLANOK);
4157 stats->aOctetsTransmittedOK = octets;
4158
4159 stats->etherStatsUndersizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsUndersizePkts);
4160 stats->etherStatsFragments = _40g_mac_reg_read32(®_rx_stats->etherStatsFragments);
4161 stats->etherStatsJabbers = _40g_mac_reg_read32(®_rx_stats->etherStatsJabbers);
4162 stats->etherStatsOversizePkts = _40g_mac_reg_read32(®_rx_stats->etherStatsOversizePkts);
4163 stats->aFrameCheckSequenceErrors = _40g_mac_reg_read32(®_rx_stats->CRCErrors);
4164 stats->aAlignmentErrors = _40g_mac_reg_read32(®_rx_stats->aAlignmentErrors);
4165 stats->etherStatsDropEvents = _40g_mac_reg_read32(®_rx_stats->etherStatsDropEvents);
4166 stats->aPAUSEMACCtrlFramesTransmitted = _40g_mac_reg_read32(®_tx_stats->aPAUSEMACCtrlFrames);
4167 stats->aPAUSEMACCtrlFramesReceived = _40g_mac_reg_read32(®_rx_stats->aPAUSEMACCtrlFrames);
4168 stats->aFrameTooLongErrors = _40g_mac_reg_read32(®_rx_stats->aFrameTooLong);
4169 stats->aInRangeLengthErrors = _40g_mac_reg_read32(®_rx_stats->aInRangeLengthErrors);
4170 stats->VLANTransmittedOK = _40g_mac_reg_read32(®_tx_stats->VLANOK);
4171 stats->VLANReceivedOK = _40g_mac_reg_read32(®_rx_stats->VLANOK);
4172 stats->etherStatsOctets = _40g_mac_reg_read32(®_rx_stats->etherStatsOctets);
4173 stats->etherStatsPkts64Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts64Octets);
4174 stats->etherStatsPkts65to127Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts65to127Octets);
4175 stats->etherStatsPkts128to255Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts128to255Octets);
4176 stats->etherStatsPkts256to511Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts256to511Octets);
4177 stats->etherStatsPkts512to1023Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts512to1023Octets);
4178 stats->etherStatsPkts1024to1518Octets = _40g_mac_reg_read32(®_rx_stats->etherStatsPkts1024to1518Octets);
4179 stats->etherStatsPkts1519toX = _40g_mac_reg_read32(®_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 */
al_eth_ec_stats_get(struct al_hal_eth_adapter * adapter,struct al_eth_ec_stats * stats)4192 int 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 */
al_eth_ec_stat_udma_get(struct al_hal_eth_adapter * adapter,uint8_t idx,struct al_eth_ec_stat_udma * stats)4239 int 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
al_eth_flr_rmn(int (* pci_read_config_u32)(void * handle,int where,uint32_t * val),int (* pci_write_config_u32)(void * handle,int where,uint32_t val),void * handle,void __iomem * mac_base)4274 int 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, ®);
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
al_eth_flr_rmn_restore_params(int (* pci_read_config_u32)(void * handle,int where,uint32_t * val),int (* pci_write_config_u32)(void * handle,int where,uint32_t val),void * handle,void __iomem * mac_base,void __iomem * ec_base,int mac_addresses_num)4350 int 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, ¶ms);
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, ¶ms);
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
al_eth_board_params_set(void * __iomem mac_base,struct al_eth_board_params * params)4430 int 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
al_eth_board_params_get(void * __iomem mac_base,struct al_eth_board_params * params)4532 int 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) */
al_eth_byte_arr_to_reg(uint32_t * reg,uint8_t * arr,unsigned int num_bytes)4680 static 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
al_eth_wol_enable(struct al_hal_eth_adapter * adapter,struct al_eth_wol_params * wol)4696 int 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(®, &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(®, &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(®, &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(®, &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(®, &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(®, &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(®, &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
al_eth_wol_disable(struct al_hal_eth_adapter * adapter)4754 int 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
al_eth_tx_fwd_vid_table_set(struct al_hal_eth_adapter * adapter,uint32_t idx,uint8_t udma_mask,al_bool fwd_to_mac)4762 int 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
al_eth_tx_protocol_detect_table_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_tx_gpd_cam_entry * tx_gpd_entry)4775 int 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
al_eth_tx_generic_crc_table_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_tx_gcp_table_entry * tx_gcp_entry)4818 int 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
al_eth_tx_crc_chksum_replace_cmd_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry * tx_replace_entry)4891 int 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
al_eth_rx_protocol_detect_table_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_rx_gpd_cam_entry * rx_gpd_entry)4930 int 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
al_eth_rx_generic_crc_table_entry_set(struct al_hal_eth_adapter * adapter,uint32_t idx,struct al_eth_rx_gcp_table_entry * rx_gcp_entry)4985 int 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
5061 static struct al_eth_tx_gpd_cam_entry
5062 al_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
5093 static struct al_eth_tx_gcp_table_entry
5094 al_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
5161 static struct al_eth_tx_crc_chksum_replace_cmd_for_protocol_num_entry
5162 al_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
5184 static struct al_eth_rx_gpd_cam_entry
5185 al_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
5349 static struct al_eth_rx_gcp_table_entry
5350 al_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
al_eth_tx_protocol_detect_table_init(struct al_hal_eth_adapter * adapter)5578 int 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
al_eth_tx_generic_crc_table_init(struct al_hal_eth_adapter * adapter)5590 int 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
al_eth_tx_crc_chksum_replace_cmd_init(struct al_hal_eth_adapter * adapter)5605 int 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
al_eth_rx_protocol_detect_table_init(struct al_hal_eth_adapter * adapter)5617 int 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
al_eth_rx_generic_crc_table_init(struct al_hal_eth_adapter * adapter)5644 int 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