Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Realtek Corporation. All rights reserved
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <errno.h>
7 : : #include <stdint.h>
8 : :
9 : : #include <rte_ether.h>
10 : : #include <ethdev_driver.h>
11 : :
12 : : #include "r8169_hw.h"
13 : : #include "r8169_logs.h"
14 : : #include "r8169_dash.h"
15 : :
16 : : static u32
17 : 0 : rtl_eri_read_with_oob_base_address(struct rtl_hw *hw, int addr, int len,
18 : : int type, const u32 base_address)
19 : : {
20 : : int i, val_shift, shift = 0;
21 : : u32 value1 = 0;
22 : : u32 value2 = 0;
23 : : u32 eri_cmd, tmp, mask;
24 : 0 : const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) |
25 : 0 : (base_address & 0x000FFF);
26 : :
27 [ # # ]: 0 : if (len > 4 || len <= 0)
28 : : return -1;
29 : :
30 [ # # ]: 0 : while (len > 0) {
31 : 0 : val_shift = addr % ERIAR_Addr_Align;
32 : 0 : addr = addr & ~0x3;
33 : :
34 : 0 : eri_cmd = ERIAR_Read | transformed_base_address |
35 : 0 : type << ERIAR_Type_shift |
36 : 0 : ERIAR_ByteEn << ERIAR_ByteEn_shift |
37 : 0 : (addr & 0x0FFF);
38 [ # # ]: 0 : if (addr & 0xF000) {
39 : : tmp = addr & 0xF000;
40 : : tmp >>= 12;
41 : 0 : eri_cmd |= (tmp << 20) & 0x00F00000;
42 : : }
43 : :
44 : 0 : RTL_W32(hw, ERIAR, eri_cmd);
45 : :
46 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
47 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
48 : :
49 : : /* Check if the NIC has completed ERI read */
50 [ # # ]: 0 : if (RTL_R32(hw, ERIAR) & ERIAR_Flag)
51 : : break;
52 : : }
53 : :
54 [ # # ]: 0 : if (len == 1)
55 : 0 : mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF;
56 [ # # ]: 0 : else if (len == 2)
57 : 0 : mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF;
58 [ # # ]: 0 : else if (len == 3)
59 : 0 : mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF;
60 : : else
61 : 0 : mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF;
62 : :
63 : 0 : value1 = RTL_R32(hw, ERIDR) & mask;
64 : 0 : value2 |= (value1 >> val_shift * 8) << shift * 8;
65 : :
66 [ # # ]: 0 : if (len <= 4 - val_shift) {
67 : : len = 0;
68 : : } else {
69 : 0 : len -= (4 - val_shift);
70 : : shift = 4 - val_shift;
71 : 0 : addr += 4;
72 : : }
73 : : }
74 : :
75 : 0 : rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME);
76 : :
77 : 0 : return value2;
78 : : }
79 : :
80 : : static int
81 : 0 : rtl_eri_write_with_oob_base_address(struct rtl_hw *hw, int addr,
82 : : int len, u32 value, int type,
83 : : const u32 base_address)
84 : : {
85 : : int i, val_shift, shift = 0;
86 : : u32 value1 = 0;
87 : : u32 eri_cmd, mask, tmp;
88 : 0 : const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) |
89 : 0 : (base_address & 0x000FFF);
90 : :
91 [ # # ]: 0 : if (len > 4 || len <= 0)
92 : : return -1;
93 : :
94 [ # # ]: 0 : while (len > 0) {
95 : 0 : val_shift = addr % ERIAR_Addr_Align;
96 : 0 : addr = addr & ~0x3;
97 : :
98 [ # # ]: 0 : if (len == 1)
99 : 0 : mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF;
100 [ # # ]: 0 : else if (len == 2)
101 : 0 : mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF;
102 [ # # ]: 0 : else if (len == 3)
103 : 0 : mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF;
104 : : else
105 : 0 : mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF;
106 : :
107 : 0 : value1 = rtl_eri_read_with_oob_base_address(hw, addr, 4, type,
108 : 0 : base_address) & ~mask;
109 : 0 : value1 |= ((value << val_shift * 8) >> shift * 8);
110 : :
111 : 0 : RTL_W32(hw, ERIDR, value1);
112 : :
113 : 0 : eri_cmd = ERIAR_Write | transformed_base_address |
114 : 0 : type << ERIAR_Type_shift |
115 : 0 : ERIAR_ByteEn << ERIAR_ByteEn_shift |
116 : 0 : (addr & 0x0FFF);
117 [ # # ]: 0 : if (addr & 0xF000) {
118 : : tmp = addr & 0xF000;
119 : : tmp >>= 12;
120 : 0 : eri_cmd |= (tmp << 20) & 0x00F00000;
121 : : }
122 : :
123 : 0 : RTL_W32(hw, ERIAR, eri_cmd);
124 : :
125 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
126 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
127 : :
128 : : /* Check if the NIC has completed ERI write */
129 [ # # ]: 0 : if (!(RTL_R32(hw, ERIAR) & ERIAR_Flag))
130 : : break;
131 : : }
132 : :
133 [ # # ]: 0 : if (len <= 4 - val_shift) {
134 : : len = 0;
135 : : } else {
136 : 0 : len -= (4 - val_shift);
137 : : shift = 4 - val_shift;
138 : 0 : addr += 4;
139 : : }
140 : : }
141 : :
142 : 0 : rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME);
143 : :
144 : 0 : return 0;
145 : : }
146 : :
147 : : static u32
148 : : rtl_ocp_read_with_oob_base_address(struct rtl_hw *hw, u16 addr, u8 len,
149 : : const u32 base_address)
150 : : {
151 : 0 : return rtl_eri_read_with_oob_base_address(hw, addr, len, ERIAR_OOB,
152 : : base_address);
153 : : }
154 : :
155 : : u32
156 : 0 : rtl_ocp_read(struct rtl_hw *hw, u16 addr, u8 len)
157 : : {
158 : : u32 value = 0;
159 : :
160 [ # # ]: 0 : if (!hw->AllowAccessDashOcp)
161 : : return 0xffffffff;
162 : :
163 [ # # ]: 0 : if (hw->HwSuppOcpChannelVer == 2)
164 : 0 : value = rtl_ocp_read_with_oob_base_address(hw, addr, len,
165 : : NO_BASE_ADDRESS);
166 : :
167 : : return value;
168 : : }
169 : :
170 : : static u32
171 : : rtl_ocp_write_with_oob_base_address(struct rtl_hw *hw, u16 addr, u8 len,
172 : : u32 value, const u32 base_address)
173 : : {
174 : 0 : return rtl_eri_write_with_oob_base_address(hw, addr, len, value, ERIAR_OOB,
175 : : base_address);
176 : : }
177 : :
178 : : void
179 : 0 : rtl_ocp_write(struct rtl_hw *hw, u16 addr, u8 len, u32 value)
180 : : {
181 [ # # ]: 0 : if (!hw->AllowAccessDashOcp)
182 : : return;
183 : :
184 [ # # ]: 0 : if (hw->HwSuppOcpChannelVer == 2)
185 : 0 : rtl_ocp_write_with_oob_base_address(hw, addr, len, value,
186 : : NO_BASE_ADDRESS);
187 : : }
188 : :
189 : : void
190 : 0 : rtl8125_oob_mutex_lock(struct rtl_hw *hw)
191 : : {
192 : : u8 reg_16, reg_a0;
193 : : u16 ocp_reg_mutex_ib;
194 : : u16 ocp_reg_mutex_oob;
195 : : u16 ocp_reg_mutex_prio;
196 : : u32 wait_cnt_0, wait_cnt_1;
197 : :
198 [ # # ]: 0 : if (!hw->DASH)
199 : : return;
200 : :
201 [ # # ]: 0 : switch (hw->mcfg) {
202 : 0 : case CFG_METHOD_48:
203 : : case CFG_METHOD_49:
204 : : case CFG_METHOD_52:
205 : : case CFG_METHOD_54:
206 : : case CFG_METHOD_55:
207 : : ocp_reg_mutex_oob = 0x110;
208 : : ocp_reg_mutex_ib = 0x114;
209 : : ocp_reg_mutex_prio = 0x11C;
210 : : break;
211 : : default:
212 : : return;
213 : : }
214 : :
215 : 0 : rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, BIT_0);
216 : 0 : reg_16 = rtl_ocp_read(hw, ocp_reg_mutex_oob, 1);
217 : : wait_cnt_0 = 0;
218 [ # # ]: 0 : while (reg_16) {
219 : 0 : reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1);
220 [ # # ]: 0 : if (reg_a0) {
221 : 0 : rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, 0x00);
222 : 0 : reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1);
223 : : wait_cnt_1 = 0;
224 [ # # ]: 0 : while (reg_a0) {
225 : 0 : reg_a0 = rtl_ocp_read(hw, ocp_reg_mutex_prio, 1);
226 : :
227 : 0 : wait_cnt_1++;
228 : :
229 [ # # ]: 0 : if (wait_cnt_1 > 2000)
230 : : break;
231 : : };
232 : 0 : rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, BIT_0);
233 : : }
234 : 0 : reg_16 = rtl_ocp_read(hw, ocp_reg_mutex_oob, 1);
235 : :
236 : 0 : wait_cnt_0++;
237 : :
238 [ # # ]: 0 : if (wait_cnt_0 > 2000)
239 : : break;
240 : : };
241 : : }
242 : :
243 : : void
244 : 0 : rtl8125_oob_mutex_unlock(struct rtl_hw *hw)
245 : : {
246 : : u16 ocp_reg_mutex_ib;
247 : : u16 ocp_reg_mutex_prio;
248 : :
249 [ # # ]: 0 : if (!hw->DASH)
250 : : return;
251 : :
252 [ # # ]: 0 : switch (hw->mcfg) {
253 : 0 : case CFG_METHOD_48:
254 : : case CFG_METHOD_49:
255 : : case CFG_METHOD_52:
256 : : case CFG_METHOD_54:
257 : : case CFG_METHOD_55:
258 : : ocp_reg_mutex_ib = 0x114;
259 : : ocp_reg_mutex_prio = 0x11C;
260 : : break;
261 : : default:
262 : : return;
263 : : }
264 : :
265 : 0 : rtl_ocp_write(hw, ocp_reg_mutex_prio, 1, BIT_0);
266 : 0 : rtl_ocp_write(hw, ocp_reg_mutex_ib, 1, 0x00);
267 : : }
268 : :
269 : : void
270 : 0 : rtl_mac_ocp_write(struct rtl_hw *hw, u16 addr, u16 value)
271 : : {
272 : : u32 data32;
273 : :
274 : 0 : data32 = addr / 2;
275 : 0 : data32 <<= OCPR_Addr_Reg_shift;
276 : 0 : data32 += value;
277 : 0 : data32 |= OCPR_Write;
278 : :
279 : 0 : RTL_W32(hw, MACOCP, data32);
280 : 0 : }
281 : :
282 : : u16
283 : 0 : rtl_mac_ocp_read(struct rtl_hw *hw, u16 addr)
284 : : {
285 : : u32 data32;
286 : : u16 data16 = 0;
287 : :
288 : 0 : data32 = addr / 2;
289 : 0 : data32 <<= OCPR_Addr_Reg_shift;
290 : :
291 : 0 : RTL_W32(hw, MACOCP, data32);
292 : 0 : data16 = (u16)RTL_R32(hw, MACOCP);
293 : :
294 : 0 : return data16;
295 : : }
296 : :
297 : : u32
298 : 0 : rtl_csi_read(struct rtl_hw *hw, u32 addr)
299 : : {
300 : : u32 cmd;
301 : : int i;
302 : : u32 value = 0;
303 : :
304 : 0 : cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift |
305 : : (addr & CSIAR_Addr_Mask);
306 : :
307 : 0 : RTL_W32(hw, CSIAR, cmd);
308 : :
309 [ # # ]: 0 : for (i = 0; i < 10; i++) {
310 : 0 : rte_delay_us(100);
311 : :
312 : : /* Check if the NIC has completed CSI read */
313 [ # # ]: 0 : if (RTL_R32(hw, CSIAR) & CSIAR_Flag) {
314 : 0 : value = RTL_R32(hw, CSIDR);
315 : 0 : break;
316 : : }
317 : : }
318 : :
319 : 0 : rte_delay_us(20);
320 : :
321 : 0 : return value;
322 : : }
323 : :
324 : : void
325 : 0 : rtl_csi_write(struct rtl_hw *hw, u32 addr, u32 value)
326 : : {
327 : : u32 cmd;
328 : : int i;
329 : :
330 : 0 : RTL_W32(hw, CSIDR, value);
331 : 0 : cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift |
332 : : (addr & CSIAR_Addr_Mask);
333 : :
334 : 0 : RTL_W32(hw, CSIAR, cmd);
335 : :
336 [ # # ]: 0 : for (i = 0; i < RTL_CHANNEL_WAIT_COUNT; i++) {
337 : 0 : rte_delay_us(RTL_CHANNEL_WAIT_TIME);
338 : :
339 : : /* Check if the NIC has completed CSI write */
340 [ # # ]: 0 : if (!(RTL_R32(hw, CSIAR) & CSIAR_Flag))
341 : : break;
342 : : }
343 : :
344 : 0 : rte_delay_us(RTL_CHANNEL_EXIT_DELAY_TIME);
345 : 0 : }
346 : :
347 : : static void
348 : 0 : rtl_enable_rxdvgate(struct rtl_hw *hw)
349 : : {
350 [ # # ]: 0 : switch (hw->mcfg) {
351 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
352 : : case CFG_METHOD_69 ... CFG_METHOD_71:
353 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) | BIT_3);
354 : : rte_delay_ms(2);
355 : : }
356 : 0 : }
357 : :
358 : : void
359 : 0 : rtl_disable_rxdvgate(struct rtl_hw *hw)
360 : : {
361 [ # # ]: 0 : switch (hw->mcfg) {
362 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
363 : : case CFG_METHOD_69 ... CFG_METHOD_71:
364 : 0 : RTL_W8(hw, 0xF2, RTL_R8(hw, 0xF2) & ~BIT_3);
365 : : rte_delay_ms(2);
366 : : }
367 : 0 : }
368 : :
369 : : static void
370 : 0 : rtl_stop_all_request(struct rtl_hw *hw)
371 : : {
372 : : int i;
373 : :
374 : 0 : RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) | StopReq);
375 : :
376 [ # # ]: 0 : switch (hw->mcfg) {
377 : : case CFG_METHOD_48:
378 : : case CFG_METHOD_49:
379 : : case CFG_METHOD_52:
380 [ # # ]: 0 : for (i = 0; i < 20; i++) {
381 : 0 : rte_delay_us(10);
382 [ # # ]: 0 : if (!(RTL_R8(hw, ChipCmd) & StopReq))
383 : : break;
384 : : }
385 : :
386 : : break;
387 : 0 : default:
388 : 0 : rte_delay_us(200);
389 : 0 : break;
390 : : }
391 : :
392 : 0 : RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) & (CmdTxEnb | CmdRxEnb));
393 : 0 : }
394 : :
395 : : static void
396 : 0 : rtl_wait_txrx_fifo_empty(struct rtl_hw *hw)
397 : : {
398 : : int i;
399 : :
400 [ # # ]: 0 : switch (hw->mcfg) {
401 : : case CFG_METHOD_48 ... CFG_METHOD_57:
402 : : case CFG_METHOD_69 ... CFG_METHOD_71:
403 [ # # ]: 0 : for (i = 0; i < 3000; i++) {
404 : 0 : rte_delay_us(50);
405 [ # # ]: 0 : if ((RTL_R8(hw, MCUCmd_reg) & (Txfifo_empty | Rxfifo_empty)) ==
406 : : (Txfifo_empty | Rxfifo_empty))
407 : : break;
408 : : }
409 : : break;
410 : : }
411 : :
412 [ # # ]: 0 : switch (hw->mcfg) {
413 : : case CFG_METHOD_50:
414 : : case CFG_METHOD_51:
415 : : case CFG_METHOD_53 ... CFG_METHOD_57:
416 : : case CFG_METHOD_69 ... CFG_METHOD_71:
417 [ # # ]: 0 : for (i = 0; i < 3000; i++) {
418 : 0 : rte_delay_us(50);
419 [ # # ]: 0 : if ((RTL_R16(hw, IntrMitigate) & (BIT_0 | BIT_1 | BIT_8)) ==
420 : : (BIT_0 | BIT_1 | BIT_8))
421 : : break;
422 : : }
423 : : break;
424 : : }
425 : 0 : }
426 : :
427 : : static void
428 : : rtl_disable_rx_packet_filter(struct rtl_hw *hw)
429 : : {
430 : 0 : RTL_W32(hw, RxConfig, RTL_R32(hw, RxConfig) &
431 : : ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast |
432 : : AcceptMyPhys | AcceptAllPhys));
433 : : }
434 : :
435 : : void
436 : 0 : rtl_nic_reset(struct rtl_hw *hw)
437 : : {
438 : : int i;
439 : :
440 : : rtl_disable_rx_packet_filter(hw);
441 : :
442 : 0 : rtl_enable_rxdvgate(hw);
443 : :
444 : 0 : rtl_stop_all_request(hw);
445 : :
446 : 0 : rtl_wait_txrx_fifo_empty(hw);
447 : :
448 : : rte_delay_ms(2);
449 : :
450 : : /* Soft reset the chip. */
451 : 0 : RTL_W8(hw, ChipCmd, CmdReset);
452 : :
453 : : /* Check that the chip has finished the reset. */
454 [ # # ]: 0 : for (i = 100; i > 0; i--) {
455 : 0 : rte_delay_us(100);
456 [ # # ]: 0 : if ((RTL_R8(hw, ChipCmd) & CmdReset) == 0)
457 : : break;
458 : : }
459 : 0 : }
460 : :
461 : : void
462 : 0 : rtl_enable_cfg9346_write(struct rtl_hw *hw)
463 : : {
464 : 0 : RTL_W8(hw, Cfg9346, RTL_R8(hw, Cfg9346) | Cfg9346_Unlock);
465 : 0 : }
466 : :
467 : : void
468 : 0 : rtl_disable_cfg9346_write(struct rtl_hw *hw)
469 : : {
470 : 0 : RTL_W8(hw, Cfg9346, RTL_R8(hw, Cfg9346) & ~Cfg9346_Unlock);
471 : 0 : }
472 : :
473 : : static void
474 : : rtl_enable_force_clkreq(struct rtl_hw *hw, bool enable)
475 : : {
476 : : if (enable)
477 : : RTL_W8(hw, 0xF1, RTL_R8(hw, 0xF1) | BIT_7);
478 : : else
479 : 0 : RTL_W8(hw, 0xF1, RTL_R8(hw, 0xF1) & ~BIT_7);
480 : : }
481 : :
482 : : static void
483 : 0 : rtl_enable_aspm_clkreq_lock(struct rtl_hw *hw, bool enable)
484 : : {
485 [ # # # ]: 0 : switch (hw->mcfg) {
486 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
487 : : case CFG_METHOD_69:
488 : 0 : rtl_enable_cfg9346_write(hw);
489 [ # # ]: 0 : if (enable) {
490 : 0 : RTL_W8(hw, Config2, RTL_R8(hw, Config2) | BIT_7);
491 : 0 : RTL_W8(hw, Config5, RTL_R8(hw, Config5) | BIT_0);
492 : : } else {
493 : 0 : RTL_W8(hw, Config2, RTL_R8(hw, Config2) & ~BIT_7);
494 : 0 : RTL_W8(hw, Config5, RTL_R8(hw, Config5) & ~BIT_0);
495 : : }
496 : 0 : rtl_disable_cfg9346_write(hw);
497 : 0 : break;
498 : 0 : case CFG_METHOD_70:
499 : : case CFG_METHOD_71:
500 : 0 : rtl_enable_cfg9346_write(hw);
501 [ # # ]: 0 : if (enable) {
502 : 0 : RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) | BIT_3);
503 : 0 : RTL_W8(hw, Config5, RTL_R8(hw, Config5) | BIT_0);
504 : : } else {
505 : 0 : RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) & ~BIT_3);
506 : 0 : RTL_W8(hw, Config5, RTL_R8(hw, Config5) & ~BIT_0);
507 : : }
508 : 0 : rtl_disable_cfg9346_write(hw);
509 : 0 : break;
510 : : }
511 : 0 : }
512 : :
513 : : static void
514 : 0 : rtl_disable_l1_timeout(struct rtl_hw *hw)
515 : : {
516 : 0 : rtl_csi_write(hw, 0x890, rtl_csi_read(hw, 0x890) & ~BIT_0);
517 : 0 : }
518 : :
519 : : static void
520 : 0 : rtl_disable_eee_plus(struct rtl_hw *hw)
521 : : {
522 [ # # ]: 0 : switch (hw->mcfg) {
523 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
524 : : case CFG_METHOD_69 ... CFG_METHOD_71:
525 : 0 : rtl_mac_ocp_write(hw, 0xE080, rtl_mac_ocp_read(hw, 0xE080) & ~BIT_1);
526 : 0 : break;
527 : :
528 : : default:
529 : : /* Not support EEEPlus */
530 : : break;
531 : : }
532 : 0 : }
533 : :
534 : : static void
535 : 0 : rtl_hw_clear_timer_int(struct rtl_hw *hw)
536 : : {
537 [ # # ]: 0 : switch (hw->mcfg) {
538 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
539 : : case CFG_METHOD_69 ... CFG_METHOD_71:
540 : 0 : RTL_W32(hw, TIMER_INT0_8125, 0x0000);
541 : 0 : RTL_W32(hw, TIMER_INT1_8125, 0x0000);
542 : 0 : RTL_W32(hw, TIMER_INT2_8125, 0x0000);
543 : 0 : RTL_W32(hw, TIMER_INT3_8125, 0x0000);
544 : : break;
545 : : }
546 : 0 : }
547 : :
548 : : static void
549 : 0 : rtl_hw_clear_int_miti(struct rtl_hw *hw)
550 : : {
551 : : int i;
552 : :
553 [ # # # ]: 0 : switch (hw->HwSuppIntMitiVer) {
554 : : case 3:
555 : : case 6:
556 : : /* IntMITI_0-IntMITI_31 */
557 [ # # ]: 0 : for (i = 0xA00; i < 0xB00; i += 4)
558 : 0 : RTL_W32(hw, i, 0x0000);
559 : : break;
560 : : case 4:
561 : : case 5:
562 : : /* IntMITI_0-IntMITI_15 */
563 [ # # ]: 0 : for (i = 0xA00; i < 0xA80; i += 4)
564 : 0 : RTL_W32(hw, i, 0x0000);
565 : :
566 [ # # ]: 0 : if (hw->HwSuppIntMitiVer == 5)
567 : 0 : RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) &
568 : : ~(INT_CFG0_TIMEOUT0_BYPASS_8125 |
569 : : INT_CFG0_MITIGATION_BYPASS_8125 |
570 : : INT_CFG0_RDU_BYPASS_8126));
571 : : else
572 : 0 : RTL_W8(hw, INT_CFG0_8125, RTL_R8(hw, INT_CFG0_8125) &
573 : : ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | INT_CFG0_MITIGATION_BYPASS_8125));
574 : :
575 : 0 : RTL_W16(hw, INT_CFG1_8125, 0x0000);
576 : : break;
577 : : }
578 : 0 : }
579 : :
580 : : void
581 : 0 : rtl_hw_config(struct rtl_hw *hw)
582 : : {
583 : : u32 mac_ocp_data;
584 : :
585 : : /* Set RxConfig to default */
586 : 0 : RTL_W32(hw, RxConfig, (RX_DMA_BURST_unlimited << RxCfgDMAShift));
587 : :
588 : 0 : rtl_nic_reset(hw);
589 : :
590 : 0 : rtl_enable_cfg9346_write(hw);
591 : :
592 : : /* Disable aspm clkreq internal */
593 [ # # ]: 0 : switch (hw->mcfg) {
594 : : case CFG_METHOD_48 ... CFG_METHOD_57:
595 : : case CFG_METHOD_69 ... CFG_METHOD_71:
596 : : rtl_enable_force_clkreq(hw, 0);
597 : 0 : rtl_enable_aspm_clkreq_lock(hw, 0);
598 : 0 : break;
599 : : }
600 : :
601 : : /* Disable magic packet */
602 [ # # ]: 0 : switch (hw->mcfg) {
603 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
604 : : case CFG_METHOD_69 ... CFG_METHOD_71:
605 : : mac_ocp_data = 0;
606 : 0 : rtl_mac_ocp_write(hw, 0xC0B6, mac_ocp_data);
607 : 0 : break;
608 : : }
609 : :
610 : : /* Set DMA burst size and interframe gap time */
611 : 0 : RTL_W32(hw, TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) |
612 : : (InterFrameGap << TxInterFrameGapShift));
613 : :
614 [ # # ]: 0 : if (hw->EnableTxNoClose)
615 : 0 : RTL_W32(hw, TxConfig, (RTL_R32(hw, TxConfig) | BIT_6));
616 : :
617 : : /* TCAM */
618 [ # # ]: 0 : switch (hw->mcfg) {
619 : 0 : case CFG_METHOD_48 ... CFG_METHOD_53:
620 : 0 : RTL_W16(hw, 0x382, 0x221B);
621 : : break;
622 : : }
623 : :
624 [ # # ]: 0 : switch (hw->mcfg) {
625 : 0 : case CFG_METHOD_69 ... CFG_METHOD_71:
626 : 0 : rtl_disable_l1_timeout(hw);
627 : 0 : break;
628 : : }
629 : :
630 [ # # ]: 0 : switch (hw->mcfg) {
631 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
632 : : case CFG_METHOD_69 ... CFG_METHOD_71:
633 : :
634 : : /* RSS_control_0 */
635 : 0 : RTL_W32(hw, RSS_CTRL_8125, 0x00);
636 : :
637 : : /* VMQ_control */
638 : 0 : RTL_W16(hw, Q_NUM_CTRL_8125, 0x0000);
639 : :
640 : : /* Disable speed down */
641 : 0 : RTL_W8(hw, Config1, RTL_R8(hw, Config1) & ~0x10);
642 : :
643 : : /* CRC disable set */
644 : 0 : rtl_mac_ocp_write(hw, 0xC140, 0xFFFF);
645 : 0 : rtl_mac_ocp_write(hw, 0xC142, 0xFFFF);
646 : :
647 : : /* New TX desc format */
648 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB58);
649 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71)
650 : 0 : mac_ocp_data &= ~(BIT_0 | BIT_1);
651 : 0 : mac_ocp_data |= BIT_0;
652 : 0 : rtl_mac_ocp_write(hw, 0xEB58, mac_ocp_data);
653 : :
654 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71)
655 : 0 : RTL_W8(hw, 0xD8, RTL_R8(hw, 0xD8) & ~BIT_1);
656 : :
657 : : /*
658 : : * MTPS
659 : : * 15-8 maximum tx use credit number
660 : : * 7-0 reserved for pcie product line
661 : : */
662 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xE614);
663 : 0 : mac_ocp_data &= ~(BIT_10 | BIT_9 | BIT_8);
664 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_50 || hw->mcfg == CFG_METHOD_51 ||
665 : : hw->mcfg == CFG_METHOD_53)
666 : 0 : mac_ocp_data |= ((2 & 0x07) << 8);
667 [ # # ]: 0 : else if (hw->mcfg == CFG_METHOD_69 || hw->mcfg == CFG_METHOD_70 ||
668 : : hw->mcfg == CFG_METHOD_71)
669 : 0 : mac_ocp_data |= ((4 & 0x07) << 8);
670 : : else
671 : 0 : mac_ocp_data |= ((3 & 0x07) << 8);
672 : 0 : rtl_mac_ocp_write(hw, 0xE614, mac_ocp_data);
673 : :
674 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xE63E);
675 : 0 : mac_ocp_data &= ~(BIT_5 | BIT_4);
676 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 ||
677 [ # # # # ]: 0 : hw->mcfg == CFG_METHOD_52 || hw->mcfg == CFG_METHOD_69 ||
678 [ # # ]: 0 : hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71)
679 : 0 : mac_ocp_data |= ((0x02 & 0x03) << 4);
680 : 0 : rtl_mac_ocp_write(hw, 0xE63E, mac_ocp_data);
681 : :
682 : : /*
683 : : * FTR_MCU_CTRL
684 : : * 3-2 txpla packet valid start
685 : : */
686 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xC0B4);
687 : 0 : mac_ocp_data &= ~BIT_0;
688 : 0 : rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data);
689 : 0 : mac_ocp_data |= BIT_0;
690 : 0 : rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data);
691 : :
692 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xC0B4);
693 : : mac_ocp_data |= (BIT_3 | BIT_2);
694 : 0 : rtl_mac_ocp_write(hw, 0xC0B4, mac_ocp_data);
695 : :
696 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB6A);
697 : 0 : mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 |
698 : : BIT_0);
699 : 0 : mac_ocp_data |= (BIT_5 | BIT_4 | BIT_1 | BIT_0);
700 : 0 : rtl_mac_ocp_write(hw, 0xEB6A, mac_ocp_data);
701 : :
702 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xEB50);
703 : 0 : mac_ocp_data &= ~(BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5);
704 : 0 : mac_ocp_data |= BIT_6;
705 : 0 : rtl_mac_ocp_write(hw, 0xEB50, mac_ocp_data);
706 : :
707 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xE056);
708 : 0 : mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4);
709 : 0 : rtl_mac_ocp_write(hw, 0xE056, mac_ocp_data);
710 : :
711 : : /* EEE_CR */
712 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xE040);
713 : 0 : mac_ocp_data &= ~BIT_12;
714 : 0 : rtl_mac_ocp_write(hw, 0xE040, mac_ocp_data);
715 : :
716 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xEA1C);
717 : 0 : mac_ocp_data &= ~(BIT_1 | BIT_0);
718 : 0 : mac_ocp_data |= BIT_0;
719 : 0 : rtl_mac_ocp_write(hw, 0xEA1C, mac_ocp_data);
720 : :
721 [ # # ]: 0 : switch (hw->mcfg) {
722 : 0 : case CFG_METHOD_48:
723 : : case CFG_METHOD_49:
724 : : case CFG_METHOD_52:
725 : : case CFG_METHOD_54:
726 : : case CFG_METHOD_55:
727 : 0 : rtl8125_oob_mutex_lock(hw);
728 : 0 : break;
729 : : }
730 : :
731 : : /* MAC_PWRDWN_CR0 */
732 : 0 : rtl_mac_ocp_write(hw, 0xE0C0, 0x4000);
733 : :
734 : 0 : rtl_set_mac_ocp_bit(hw, 0xE052, (BIT_6 | BIT_5));
735 : 0 : rtl_clear_mac_ocp_bit(hw, 0xE052, (BIT_3 | BIT_7));
736 : :
737 [ # # ]: 0 : switch (hw->mcfg) {
738 : 0 : case CFG_METHOD_48:
739 : : case CFG_METHOD_49:
740 : : case CFG_METHOD_52:
741 : : case CFG_METHOD_54:
742 : : case CFG_METHOD_55:
743 : 0 : rtl8125_oob_mutex_unlock(hw);
744 : 0 : break;
745 : : }
746 : :
747 : : /*
748 : : * DMY_PWR_REG_0
749 : : * (1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b111111, L1 Mask
750 : : */
751 : 0 : rtl_set_mac_ocp_bit(hw, 0xC0AC,
752 : : (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12));
753 : :
754 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xD430);
755 : 0 : mac_ocp_data &= ~(BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 |
756 : : BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0);
757 : 0 : mac_ocp_data |= 0x45F;
758 : 0 : rtl_mac_ocp_write(hw, 0xD430, mac_ocp_data);
759 : :
760 [ # # ]: 0 : if (!hw->DASH)
761 : 0 : RTL_W8(hw, 0xD0, RTL_R8(hw, 0xD0) | BIT_6 | BIT_7);
762 : : else
763 : 0 : RTL_W8(hw, 0xD0, RTL_R8(hw, 0xD0) & ~(BIT_6 | BIT_7));
764 : :
765 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 ||
766 : : hw->mcfg == CFG_METHOD_52)
767 : 0 : RTL_W8(hw, MCUCmd_reg, RTL_R8(hw, MCUCmd_reg) | BIT_0);
768 : :
769 : 0 : rtl_disable_eee_plus(hw);
770 : :
771 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xEA1C);
772 : 0 : mac_ocp_data &= ~BIT_2;
773 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_70 || hw->mcfg == CFG_METHOD_71)
774 : 0 : mac_ocp_data &= ~(BIT_9 | BIT_8);
775 : 0 : rtl_mac_ocp_write(hw, 0xEA1C, mac_ocp_data);
776 : :
777 : : /* Clear TCAM entries */
778 : 0 : rtl_set_mac_ocp_bit(hw, 0xEB54, BIT_0);
779 : 0 : rte_delay_us(1);
780 : 0 : rtl_clear_mac_ocp_bit(hw, 0xEB54, BIT_0);
781 : :
782 : 0 : RTL_W16(hw, 0x1880, RTL_R16(hw, 0x1880) & ~(BIT_4 | BIT_5));
783 : :
784 [ # # ]: 0 : switch (hw->mcfg) {
785 : 0 : case CFG_METHOD_54 ... CFG_METHOD_57:
786 : 0 : RTL_W8(hw, 0xd8, RTL_R8(hw, 0xd8) & ~EnableRxDescV4_0);
787 : : break;
788 : : }
789 : : }
790 : :
791 : : /* Other hw parameters */
792 : 0 : rtl_hw_clear_timer_int(hw);
793 : :
794 : 0 : rtl_hw_clear_int_miti(hw);
795 : :
796 [ # # ]: 0 : switch (hw->mcfg) {
797 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
798 : : case CFG_METHOD_69 ... CFG_METHOD_71:
799 : 0 : rtl_mac_ocp_write(hw, 0xE098, 0xC302);
800 : 0 : break;
801 : : }
802 : :
803 : 0 : rtl_disable_cfg9346_write(hw);
804 : :
805 : 0 : rte_delay_us(10);
806 : 0 : }
807 : :
808 : : int
809 : 0 : rtl_set_hw_ops(struct rtl_hw *hw)
810 : : {
811 [ # # # # : 0 : switch (hw->mcfg) {
# # # ]
812 : : /* 8125A */
813 : 0 : case CFG_METHOD_48:
814 : : case CFG_METHOD_49:
815 : 0 : hw->hw_ops = rtl8125a_ops;
816 : 0 : return 0;
817 : : /* 8125B */
818 : 0 : case CFG_METHOD_50:
819 : : case CFG_METHOD_51:
820 : 0 : hw->hw_ops = rtl8125b_ops;
821 : 0 : return 0;
822 : : /* 8168KB */
823 : 0 : case CFG_METHOD_52:
824 : : case CFG_METHOD_53:
825 : 0 : hw->hw_ops = rtl8168kb_ops;
826 : 0 : return 0;
827 : : /* 8125BP */
828 : 0 : case CFG_METHOD_54:
829 : : case CFG_METHOD_55:
830 : 0 : hw->hw_ops = rtl8125bp_ops;
831 : 0 : return 0;
832 : : /* 8125D */
833 : 0 : case CFG_METHOD_56:
834 : : case CFG_METHOD_57:
835 : 0 : hw->hw_ops = rtl8125d_ops;
836 : 0 : return 0;
837 : : /* 8126A */
838 : 0 : case CFG_METHOD_69 ... CFG_METHOD_71:
839 : 0 : hw->hw_ops = rtl8126a_ops;
840 : 0 : return 0;
841 : : default:
842 : : return -ENOTSUP;
843 : : }
844 : : }
845 : :
846 : : void
847 : 0 : rtl_hw_disable_mac_mcu_bps(struct rtl_hw *hw)
848 : : {
849 : : u16 reg_addr;
850 : :
851 : 0 : rtl_enable_aspm_clkreq_lock(hw, 0);
852 : :
853 [ # # ]: 0 : switch (hw->mcfg) {
854 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
855 : : case CFG_METHOD_69 ... CFG_METHOD_71:
856 : 0 : rtl_mac_ocp_write(hw, 0xFC48, 0x0000);
857 : 0 : break;
858 : : }
859 : :
860 [ # # ]: 0 : switch (hw->mcfg) {
861 : : case CFG_METHOD_48 ... CFG_METHOD_57:
862 : : case CFG_METHOD_69 ... CFG_METHOD_71:
863 [ # # ]: 0 : for (reg_addr = 0xFC28; reg_addr < 0xFC48; reg_addr += 2)
864 : 0 : rtl_mac_ocp_write(hw, reg_addr, 0x0000);
865 : :
866 : : rte_delay_ms(3);
867 : :
868 : 0 : rtl_mac_ocp_write(hw, 0xFC26, 0x0000);
869 : 0 : break;
870 : : }
871 : 0 : }
872 : :
873 : : static void
874 : 0 : rtl_switch_mac_mcu_ram_code_page(struct rtl_hw *hw, u16 page)
875 : : {
876 : : u16 tmp_ushort;
877 : :
878 : 0 : page &= (BIT_1 | BIT_0);
879 : 0 : tmp_ushort = rtl_mac_ocp_read(hw, 0xE446);
880 : 0 : tmp_ushort &= ~(BIT_1 | BIT_0);
881 : 0 : tmp_ushort |= page;
882 : 0 : rtl_mac_ocp_write(hw, 0xE446, tmp_ushort);
883 : 0 : }
884 : :
885 : : static void
886 : 0 : _rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt)
887 : : {
888 : : u16 i;
889 : :
890 [ # # ]: 0 : for (i = 0; i < entry_cnt; i++)
891 : 0 : rtl_mac_ocp_write(hw, 0xF800 + i * 2, entry[i]);
892 : 0 : }
893 : :
894 : : static void
895 : 0 : _rtl_write_mac_mcu_ram_code_with_page(struct rtl_hw *hw, const u16 *entry,
896 : : u16 entry_cnt, u16 page_size)
897 : : {
898 : : u16 i;
899 : : u16 offset;
900 : : u16 page;
901 : :
902 [ # # ]: 0 : if (page_size == 0)
903 : : return;
904 : :
905 [ # # ]: 0 : for (i = 0; i < entry_cnt; i++) {
906 : 0 : offset = i % page_size;
907 [ # # ]: 0 : if (offset == 0) {
908 : 0 : page = (i / page_size);
909 : 0 : rtl_switch_mac_mcu_ram_code_page(hw, page);
910 : : }
911 : 0 : rtl_mac_ocp_write(hw, 0xF800 + offset * 2, entry[i]);
912 : : }
913 : : }
914 : :
915 : : void
916 : 0 : rtl_write_mac_mcu_ram_code(struct rtl_hw *hw, const u16 *entry, u16 entry_cnt)
917 : : {
918 [ # # ]: 0 : if (HW_SUPPORT_MAC_MCU(hw) == FALSE)
919 : : return;
920 [ # # ]: 0 : if (entry == NULL || entry_cnt == 0)
921 : : return;
922 : :
923 [ # # ]: 0 : if (hw->MacMcuPageSize > 0)
924 : 0 : _rtl_write_mac_mcu_ram_code_with_page(hw, entry, entry_cnt,
925 : : hw->MacMcuPageSize);
926 : : else
927 : 0 : _rtl_write_mac_mcu_ram_code(hw, entry, entry_cnt);
928 : : }
929 : :
930 : : bool
931 : 0 : rtl_is_speed_mode_valid(u32 speed)
932 : : {
933 [ # # ]: 0 : switch (speed) {
934 : : case SPEED_5000:
935 : : case SPEED_2500:
936 : : case SPEED_1000:
937 : : case SPEED_100:
938 : : case SPEED_10:
939 : : return true;
940 : 0 : default:
941 : 0 : return false;
942 : : }
943 : : }
944 : :
945 : : static bool
946 : : rtl_is_duplex_mode_valid(u8 duplex)
947 : : {
948 [ # # ]: 0 : switch (duplex) {
949 : : case DUPLEX_FULL:
950 : : case DUPLEX_HALF:
951 : : return true;
952 : : default:
953 : : return false;
954 : : }
955 : : }
956 : :
957 : : static bool
958 : : rtl_is_autoneg_mode_valid(u32 autoneg)
959 : : {
960 : : switch (autoneg) {
961 : : case AUTONEG_ENABLE:
962 : : case AUTONEG_DISABLE:
963 : : return true;
964 : : default:
965 : : return false;
966 : : }
967 : : }
968 : :
969 : : void
970 : 0 : rtl_set_link_option(struct rtl_hw *hw, u8 autoneg, u32 speed, u8 duplex,
971 : : enum rtl_fc_mode fc)
972 : : {
973 : : u64 adv;
974 : :
975 [ # # ]: 0 : if (!rtl_is_speed_mode_valid(speed))
976 : : speed = SPEED_5000;
977 : :
978 : : if (!rtl_is_duplex_mode_valid(duplex))
979 : : duplex = DUPLEX_FULL;
980 : :
981 : : if (!rtl_is_autoneg_mode_valid(autoneg))
982 : : autoneg = AUTONEG_ENABLE;
983 : :
984 : 0 : speed = RTE_MIN(speed, hw->HwSuppMaxPhyLinkSpeed);
985 : :
986 : : adv = 0;
987 [ # # # ]: 0 : switch (speed) {
988 : 0 : case SPEED_5000:
989 : : adv |= ADVERTISE_5000_FULL;
990 : : /* Fall through */
991 : 0 : case SPEED_2500:
992 : 0 : adv |= ADVERTISE_2500_FULL;
993 : : /* Fall through */
994 : 0 : default:
995 : 0 : adv |= (ADVERTISE_10_HALF | ADVERTISE_10_FULL |
996 : : ADVERTISE_100_HALF | ADVERTISE_100_FULL |
997 : : ADVERTISE_1000_HALF | ADVERTISE_1000_FULL);
998 : : break;
999 : : }
1000 : :
1001 : 0 : hw->autoneg = autoneg;
1002 : 0 : hw->speed = speed;
1003 : 0 : hw->duplex = duplex;
1004 : 0 : hw->advertising = adv;
1005 : 0 : hw->fcpause = fc;
1006 : 0 : }
1007 : :
1008 : : static void
1009 : 0 : rtl_init_software_variable(struct rtl_hw *hw)
1010 : : {
1011 : : int tx_no_close_enable = 1;
1012 : : unsigned int speed_mode = SPEED_5000;
1013 : : unsigned int duplex_mode = DUPLEX_FULL;
1014 : : unsigned int autoneg_mode = AUTONEG_ENABLE;
1015 : : u8 tmp;
1016 : :
1017 [ # # # ]: 0 : switch (hw->mcfg) {
1018 : 0 : case CFG_METHOD_48:
1019 : : case CFG_METHOD_49:
1020 : 0 : tmp = (u8)rtl_mac_ocp_read(hw, 0xD006);
1021 [ # # ]: 0 : if (tmp == 0x02 || tmp == 0x04)
1022 : 0 : hw->HwSuppDashVer = 2;
1023 : : break;
1024 : 0 : case CFG_METHOD_54:
1025 : : case CFG_METHOD_55:
1026 : 0 : hw->HwSuppDashVer = 4;
1027 : 0 : break;
1028 : 0 : default:
1029 : 0 : hw->HwSuppDashVer = 0;
1030 : 0 : break;
1031 : : }
1032 : :
1033 [ # # # ]: 0 : switch (hw->mcfg) {
1034 : 0 : case CFG_METHOD_48:
1035 : : case CFG_METHOD_49:
1036 [ # # ]: 0 : if (HW_DASH_SUPPORT_DASH(hw))
1037 : 0 : hw->HwSuppOcpChannelVer = 2;
1038 : : break;
1039 : 0 : case CFG_METHOD_54:
1040 : : case CFG_METHOD_55:
1041 : 0 : hw->HwSuppOcpChannelVer = 2;
1042 : 0 : break;
1043 : : }
1044 : :
1045 : 0 : hw->AllowAccessDashOcp = rtl_is_allow_access_dash_ocp(hw);
1046 : :
1047 [ # # # # ]: 0 : if (HW_DASH_SUPPORT_DASH(hw) && rtl_check_dash(hw))
1048 : 0 : hw->DASH = 1;
1049 : : else
1050 : 0 : hw->DASH = 0;
1051 : :
1052 [ # # ]: 0 : if (HW_DASH_SUPPORT_TYPE_2(hw))
1053 : 0 : hw->cmac_ioaddr = hw->mmio_addr;
1054 : :
1055 [ # # # # : 0 : switch (hw->mcfg) {
# # # ]
1056 : 0 : case CFG_METHOD_48:
1057 : : case CFG_METHOD_49:
1058 : 0 : hw->chipset_name = RTL8125A;
1059 : 0 : break;
1060 : 0 : case CFG_METHOD_50:
1061 : : case CFG_METHOD_51:
1062 : 0 : hw->chipset_name = RTL8125B;
1063 : 0 : break;
1064 : 0 : case CFG_METHOD_52:
1065 : : case CFG_METHOD_53:
1066 : 0 : hw->chipset_name = RTL8168KB;
1067 : 0 : break;
1068 : 0 : case CFG_METHOD_54:
1069 : : case CFG_METHOD_55:
1070 : 0 : hw->chipset_name = RTL8125BP;
1071 : 0 : break;
1072 : 0 : case CFG_METHOD_56:
1073 : : case CFG_METHOD_57:
1074 : 0 : hw->chipset_name = RTL8125D;
1075 : 0 : break;
1076 : 0 : case CFG_METHOD_69 ... CFG_METHOD_71:
1077 : 0 : hw->chipset_name = RTL8126A;
1078 : 0 : break;
1079 : 0 : default:
1080 : 0 : hw->chipset_name = UNKNOWN;
1081 : 0 : break;
1082 : : }
1083 : :
1084 [ # # ]: 0 : switch (hw->mcfg) {
1085 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1086 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1087 : 0 : hw->HwSuppNowIsOobVer = 1;
1088 : : }
1089 : :
1090 [ # # ]: 0 : switch (hw->mcfg) {
1091 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1092 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1093 : 0 : hw->HwSuppCheckPhyDisableModeVer = 3;
1094 : : }
1095 : :
1096 [ # # # ]: 0 : switch (hw->mcfg) {
1097 : 0 : case CFG_METHOD_48 ... CFG_METHOD_51:
1098 : : case CFG_METHOD_54 ... CFG_METHOD_57:
1099 : 0 : hw->HwSuppMaxPhyLinkSpeed = SPEED_2500;
1100 : 0 : break;
1101 : 0 : case CFG_METHOD_69 ... CFG_METHOD_71:
1102 : 0 : hw->HwSuppMaxPhyLinkSpeed = SPEED_5000;
1103 : 0 : break;
1104 : 0 : default:
1105 : 0 : hw->HwSuppMaxPhyLinkSpeed = SPEED_1000;
1106 : 0 : break;
1107 : : }
1108 : :
1109 [ # # # # : 0 : switch (hw->mcfg) {
# ]
1110 : 0 : case CFG_METHOD_48 ... CFG_METHOD_53:
1111 : 0 : hw->HwSuppTxNoCloseVer = 3;
1112 : 0 : break;
1113 : 0 : case CFG_METHOD_54 ... CFG_METHOD_57:
1114 : 0 : hw->HwSuppTxNoCloseVer = 6;
1115 : 0 : break;
1116 : 0 : case CFG_METHOD_69:
1117 : 0 : hw->HwSuppTxNoCloseVer = 4;
1118 : 0 : break;
1119 : 0 : case CFG_METHOD_70:
1120 : : case CFG_METHOD_71:
1121 : 0 : hw->HwSuppTxNoCloseVer = 5;
1122 : 0 : break;
1123 : : }
1124 : :
1125 [ # # # # ]: 0 : switch (hw->HwSuppTxNoCloseVer) {
1126 : 0 : case 5:
1127 : : case 6:
1128 : 0 : hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V4;
1129 : 0 : break;
1130 : 0 : case 4:
1131 : 0 : hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V3;
1132 : 0 : break;
1133 : 0 : case 3:
1134 : 0 : hw->MaxTxDescPtrMask = MAX_TX_NO_CLOSE_DESC_PTR_MASK_V2;
1135 : 0 : break;
1136 : : default:
1137 : : tx_no_close_enable = 0;
1138 : : break;
1139 : : }
1140 : :
1141 [ # # # # ]: 0 : if (hw->HwSuppTxNoCloseVer > 0 && tx_no_close_enable == 1)
1142 : 0 : hw->EnableTxNoClose = TRUE;
1143 : :
1144 [ # # # ]: 0 : switch (hw->HwSuppTxNoCloseVer) {
1145 : 0 : case 4:
1146 : : case 5:
1147 : 0 : hw->hw_clo_ptr_reg = HW_CLO_PTR0_8126;
1148 : 0 : hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8126;
1149 : 0 : break;
1150 : 0 : case 6:
1151 : 0 : hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125BP;
1152 : 0 : hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125BP;
1153 : 0 : break;
1154 : 0 : default:
1155 : 0 : hw->hw_clo_ptr_reg = HW_CLO_PTR0_8125;
1156 : 0 : hw->sw_tail_ptr_reg = SW_TAIL_PTR0_8125;
1157 : 0 : break;
1158 : : }
1159 : :
1160 [ # # # # : 0 : switch (hw->mcfg) {
# # # # #
# # # ]
1161 : 0 : case CFG_METHOD_48:
1162 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_48;
1163 : 0 : break;
1164 : 0 : case CFG_METHOD_49:
1165 : : case CFG_METHOD_52:
1166 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_49;
1167 : 0 : break;
1168 : 0 : case CFG_METHOD_50:
1169 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_50;
1170 : 0 : break;
1171 : 0 : case CFG_METHOD_51:
1172 : : case CFG_METHOD_53:
1173 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_51;
1174 : 0 : break;
1175 : 0 : case CFG_METHOD_54:
1176 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_54;
1177 : 0 : break;
1178 : 0 : case CFG_METHOD_55:
1179 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_55;
1180 : 0 : break;
1181 : 0 : case CFG_METHOD_56:
1182 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_56;
1183 : 0 : break;
1184 : 0 : case CFG_METHOD_57:
1185 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_57;
1186 : 0 : break;
1187 : 0 : case CFG_METHOD_69:
1188 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_69;
1189 : 0 : break;
1190 : 0 : case CFG_METHOD_70:
1191 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_70;
1192 : 0 : break;
1193 : 0 : case CFG_METHOD_71:
1194 : 0 : hw->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_71;
1195 : 0 : break;
1196 : : }
1197 : :
1198 [ # # ]: 0 : if (hw->HwIcVerUnknown) {
1199 : 0 : hw->NotWrRamCodeToMicroP = TRUE;
1200 : 0 : hw->NotWrMcuPatchCode = TRUE;
1201 : : }
1202 : :
1203 [ # # ]: 0 : switch (hw->mcfg) {
1204 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1205 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1206 : 0 : hw->HwSuppMacMcuVer = 2;
1207 : 0 : break;
1208 : : }
1209 : :
1210 [ # # ]: 0 : switch (hw->mcfg) {
1211 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1212 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1213 : 0 : hw->MacMcuPageSize = RTL_MAC_MCU_PAGE_SIZE;
1214 : 0 : break;
1215 : : }
1216 : :
1217 [ # # ]: 0 : switch (hw->mcfg) {
1218 : 0 : case CFG_METHOD_49:
1219 : : case CFG_METHOD_52:
1220 [ # # ]: 0 : if ((rtl_mac_ocp_read(hw, 0xD442) & BIT_5) &&
1221 [ # # ]: 0 : (rtl_mdio_direct_read_phy_ocp(hw, 0xD068) & BIT_1))
1222 : 0 : hw->RequirePhyMdiSwapPatch = TRUE;
1223 : : break;
1224 : : }
1225 : :
1226 [ # # # # : 0 : switch (hw->mcfg) {
# ]
1227 : 0 : case CFG_METHOD_48:
1228 : : case CFG_METHOD_49:
1229 : : case CFG_METHOD_52:
1230 : 0 : hw->HwSuppIntMitiVer = 3;
1231 : 0 : break;
1232 : 0 : case CFG_METHOD_50:
1233 : : case CFG_METHOD_51:
1234 : : case CFG_METHOD_53:
1235 : : case CFG_METHOD_69:
1236 : 0 : hw->HwSuppIntMitiVer = 4;
1237 : 0 : break;
1238 : 0 : case CFG_METHOD_54 ... CFG_METHOD_57:
1239 : 0 : hw->HwSuppIntMitiVer = 6;
1240 : 0 : break;
1241 : 0 : case CFG_METHOD_70:
1242 : : case CFG_METHOD_71:
1243 : 0 : hw->HwSuppIntMitiVer = 5;
1244 : 0 : break;
1245 : : }
1246 : :
1247 : 0 : rtl_set_link_option(hw, autoneg_mode, speed_mode, duplex_mode, rtl_fc_full);
1248 : :
1249 [ # # ]: 0 : switch (hw->mcfg) {
1250 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1251 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1252 : 0 : hw->mcu_pme_setting = rtl_mac_ocp_read(hw, 0xE00A);
1253 : 0 : break;
1254 : : }
1255 : :
1256 : 0 : hw->mtu = RTL_DEFAULT_MTU;
1257 : 0 : }
1258 : :
1259 : : static void
1260 : 0 : rtl_exit_realwow(struct rtl_hw *hw)
1261 : : {
1262 : : /* Disable realwow function */
1263 [ # # ]: 0 : switch (hw->mcfg) {
1264 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1265 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1266 : 0 : rtl_mac_ocp_write(hw, 0xC0BC, 0x00FF);
1267 : 0 : break;
1268 : : }
1269 : 0 : }
1270 : :
1271 : : static void
1272 : : rtl_disable_now_is_oob(struct rtl_hw *hw)
1273 : : {
1274 [ # # ]: 0 : if (hw->HwSuppNowIsOobVer == 1)
1275 : 0 : RTL_W8(hw, MCUCmd_reg, RTL_R8(hw, MCUCmd_reg) & ~Now_is_oob);
1276 : : }
1277 : :
1278 : : static void
1279 : : rtl_wait_ll_share_fifo_ready(struct rtl_hw *hw)
1280 : : {
1281 : : int i;
1282 : :
1283 [ # # # # ]: 0 : for (i = 0; i < 10; i++) {
1284 : 0 : rte_delay_us(100);
1285 [ # # # # ]: 0 : if (RTL_R16(hw, 0xD2) & BIT_9)
1286 : : break;
1287 : : }
1288 : : }
1289 : :
1290 : : static void
1291 : 0 : rtl_exit_oob(struct rtl_hw *hw)
1292 : : {
1293 : : u16 data16;
1294 : :
1295 : : rtl_disable_rx_packet_filter(hw);
1296 : :
1297 [ # # ]: 0 : if (HW_DASH_SUPPORT_DASH(hw)) {
1298 : 0 : rtl8125_driver_start(hw);
1299 : 0 : rtl8125_dash2_disable_txrx(hw);
1300 : : }
1301 : :
1302 : 0 : rtl_exit_realwow(hw);
1303 : :
1304 : 0 : rtl_nic_reset(hw);
1305 : :
1306 [ # # ]: 0 : switch (hw->mcfg) {
1307 : : case CFG_METHOD_48 ... CFG_METHOD_57:
1308 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1309 : : rtl_disable_now_is_oob(hw);
1310 : :
1311 : 0 : data16 = rtl_mac_ocp_read(hw, 0xE8DE) & ~BIT_14;
1312 : 0 : rtl_mac_ocp_write(hw, 0xE8DE, data16);
1313 : : rtl_wait_ll_share_fifo_ready(hw);
1314 : :
1315 : 0 : rtl_mac_ocp_write(hw, 0xC0AA, 0x07D0);
1316 : :
1317 : 0 : rtl_mac_ocp_write(hw, 0xC0A6, 0x01B5);
1318 : :
1319 : 0 : rtl_mac_ocp_write(hw, 0xC01E, 0x5555);
1320 : :
1321 : : rtl_wait_ll_share_fifo_ready(hw);
1322 : : break;
1323 : : }
1324 : 0 : }
1325 : :
1326 : : static void
1327 : 0 : rtl_disable_ups(struct rtl_hw *hw)
1328 : : {
1329 [ # # ]: 0 : switch (hw->mcfg) {
1330 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1331 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1332 : 0 : rtl_mac_ocp_write(hw, 0xD40A, rtl_mac_ocp_read(hw, 0xD40A) & ~BIT_4);
1333 : 0 : break;
1334 : : }
1335 : 0 : }
1336 : :
1337 : : static void
1338 : 0 : rtl8125_disable_ocp_phy_power_saving(struct rtl_hw *hw)
1339 : : {
1340 : : u16 val;
1341 : :
1342 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_48 || hw->mcfg == CFG_METHOD_49 ||
1343 : : hw->mcfg == CFG_METHOD_52) {
1344 : 0 : val = rtl_mdio_direct_read_phy_ocp(hw, 0xC416);
1345 [ # # ]: 0 : if (val != 0x0050) {
1346 : 0 : rtl_set_phy_mcu_patch_request(hw);
1347 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0000);
1348 : 0 : rtl_mdio_direct_write_phy_ocp(hw, 0xC416, 0x0500);
1349 : 0 : rtl_clear_phy_mcu_patch_request(hw);
1350 : : }
1351 : : }
1352 : 0 : }
1353 : :
1354 : : static void
1355 : 0 : rtl_hw_init(struct rtl_hw *hw)
1356 : : {
1357 [ # # ]: 0 : switch (hw->mcfg) {
1358 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1359 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1360 : 0 : rtl_enable_aspm_clkreq_lock(hw, 0);
1361 : : rtl_enable_force_clkreq(hw, 0);
1362 : : break;
1363 : : }
1364 : :
1365 : 0 : rtl_disable_ups(hw);
1366 : :
1367 : 0 : hw->hw_ops.hw_mac_mcu_config(hw);
1368 : :
1369 : : /* Disable ocp phy power saving */
1370 : 0 : rtl8125_disable_ocp_phy_power_saving(hw);
1371 : 0 : }
1372 : :
1373 : : void
1374 : 0 : rtl_hw_initialize(struct rtl_hw *hw)
1375 : : {
1376 : 0 : rtl_init_software_variable(hw);
1377 : :
1378 : 0 : rtl_exit_oob(hw);
1379 : :
1380 : 0 : rtl_hw_init(hw);
1381 : :
1382 : 0 : rtl_nic_reset(hw);
1383 : 0 : }
1384 : :
1385 : : void
1386 : 0 : rtl_get_mac_version(struct rtl_hw *hw, struct rte_pci_device *pci_dev)
1387 : : {
1388 : : u32 reg, val32;
1389 : : u32 ic_version_id;
1390 : :
1391 : 0 : val32 = RTL_R32(hw, TxConfig);
1392 : 0 : reg = val32 & 0x7c800000;
1393 : 0 : ic_version_id = val32 & 0x00700000;
1394 : :
1395 [ # # # # : 0 : switch (reg) {
# # ]
1396 : 0 : case 0x60800000:
1397 [ # # ]: 0 : if (ic_version_id == 0x00000000) {
1398 : 0 : hw->mcfg = CFG_METHOD_48;
1399 : :
1400 [ # # ]: 0 : } else if (ic_version_id == 0x100000) {
1401 : 0 : hw->mcfg = CFG_METHOD_49;
1402 : :
1403 : : } else {
1404 : 0 : hw->mcfg = CFG_METHOD_49;
1405 : 0 : hw->HwIcVerUnknown = TRUE;
1406 : : }
1407 : :
1408 : 0 : hw->efuse_ver = EFUSE_SUPPORT_V4;
1409 : 0 : break;
1410 : 0 : case 0x64000000:
1411 [ # # ]: 0 : if (ic_version_id == 0x00000000) {
1412 : 0 : hw->mcfg = CFG_METHOD_50;
1413 : :
1414 [ # # ]: 0 : } else if (ic_version_id == 0x100000) {
1415 : 0 : hw->mcfg = CFG_METHOD_51;
1416 : :
1417 : : } else {
1418 : 0 : hw->mcfg = CFG_METHOD_51;
1419 : 0 : hw->HwIcVerUnknown = TRUE;
1420 : : }
1421 : :
1422 : 0 : hw->efuse_ver = EFUSE_SUPPORT_V4;
1423 : 0 : break;
1424 : 0 : case 0x68000000:
1425 [ # # ]: 0 : if (ic_version_id == 0x00000000) {
1426 : 0 : hw->mcfg = CFG_METHOD_54;
1427 [ # # ]: 0 : } else if (ic_version_id == 0x100000) {
1428 : 0 : hw->mcfg = CFG_METHOD_55;
1429 : : } else {
1430 : 0 : hw->mcfg = CFG_METHOD_55;
1431 : 0 : hw->HwIcVerUnknown = TRUE;
1432 : : }
1433 : :
1434 : 0 : hw->efuse_ver = EFUSE_SUPPORT_V4;
1435 : 0 : break;
1436 : 0 : case 0x68800000:
1437 [ # # ]: 0 : if (ic_version_id == 0x00000000) {
1438 : 0 : hw->mcfg = CFG_METHOD_56;
1439 [ # # ]: 0 : } else if (ic_version_id == 0x100000) {
1440 : 0 : hw->mcfg = CFG_METHOD_57;
1441 : : } else {
1442 : 0 : hw->mcfg = CFG_METHOD_57;
1443 : 0 : hw->HwIcVerUnknown = TRUE;
1444 : : }
1445 : :
1446 : 0 : hw->efuse_ver = EFUSE_SUPPORT_V4;
1447 : 0 : break;
1448 : 0 : case 0x64800000:
1449 [ # # ]: 0 : if (ic_version_id == 0x00000000) {
1450 : 0 : hw->mcfg = CFG_METHOD_69;
1451 [ # # ]: 0 : } else if (ic_version_id == 0x100000) {
1452 : 0 : hw->mcfg = CFG_METHOD_70;
1453 [ # # ]: 0 : } else if (ic_version_id == 0x200000) {
1454 : 0 : hw->mcfg = CFG_METHOD_71;
1455 : : } else {
1456 : 0 : hw->mcfg = CFG_METHOD_71;
1457 : 0 : hw->HwIcVerUnknown = TRUE;
1458 : : }
1459 : :
1460 : 0 : hw->efuse_ver = EFUSE_SUPPORT_V4;
1461 : 0 : break;
1462 : 0 : default:
1463 : 0 : PMD_INIT_LOG(NOTICE, "unknown chip version (%x)", reg);
1464 : 0 : hw->mcfg = CFG_METHOD_DEFAULT;
1465 : 0 : hw->HwIcVerUnknown = TRUE;
1466 : 0 : hw->efuse_ver = EFUSE_NOT_SUPPORT;
1467 : 0 : break;
1468 : : }
1469 : :
1470 [ # # ]: 0 : if (pci_dev->id.device_id == 0x8162) {
1471 [ # # ]: 0 : if (hw->mcfg == CFG_METHOD_49)
1472 : 0 : hw->mcfg = CFG_METHOD_52;
1473 [ # # ]: 0 : else if (hw->mcfg == CFG_METHOD_51)
1474 : 0 : hw->mcfg = CFG_METHOD_53;
1475 : : }
1476 : 0 : }
1477 : :
1478 : : int
1479 : 0 : rtl_get_mac_address(struct rtl_hw *hw, struct rte_ether_addr *ea)
1480 : : {
1481 : : u8 mac_addr[MAC_ADDR_LEN] = {0};
1482 : :
1483 [ # # ]: 0 : switch (hw->mcfg) {
1484 : 0 : case CFG_METHOD_48 ... CFG_METHOD_57:
1485 : : case CFG_METHOD_69 ... CFG_METHOD_71:
1486 : 0 : *(u32 *)&mac_addr[0] = RTL_R32(hw, BACKUP_ADDR0_8125);
1487 : 0 : *(u16 *)&mac_addr[4] = RTL_R16(hw, BACKUP_ADDR1_8125);
1488 : 0 : break;
1489 : : default:
1490 : : break;
1491 : : }
1492 : :
1493 : : rte_ether_addr_copy((struct rte_ether_addr *)mac_addr, ea);
1494 : :
1495 : 0 : return 0;
1496 : : }
1497 : :
1498 : : void
1499 : 0 : rtl_rar_set(struct rtl_hw *hw, uint8_t *addr)
1500 : : {
1501 : : uint32_t rar_low = 0;
1502 : : uint32_t rar_high = 0;
1503 : :
1504 : 0 : rar_low = ((uint32_t)addr[0] | ((uint32_t)addr[1] << 8) |
1505 : 0 : ((uint32_t)addr[2] << 16) | ((uint32_t)addr[3] << 24));
1506 : :
1507 : 0 : rar_high = ((uint32_t)addr[4] | ((uint32_t)addr[5] << 8));
1508 : :
1509 : 0 : rtl_enable_cfg9346_write(hw);
1510 : :
1511 : 0 : RTL_W32(hw, MAC0, rar_low);
1512 : 0 : RTL_W32(hw, MAC4, rar_high);
1513 : :
1514 : 0 : rtl_disable_cfg9346_write(hw);
1515 : 0 : }
1516 : :
1517 : : void
1518 : 0 : rtl_get_tally_stats(struct rtl_hw *hw, struct rte_eth_stats *rte_stats)
1519 : : {
1520 : : struct rtl_counters *counters;
1521 : : uint64_t paddr;
1522 : : u32 cmd;
1523 : : u32 wait_cnt;
1524 : :
1525 : 0 : counters = hw->tally_vaddr;
1526 : 0 : paddr = hw->tally_paddr;
1527 [ # # ]: 0 : if (!counters)
1528 : : return;
1529 : :
1530 : 0 : RTL_W32(hw, CounterAddrHigh, (u64)paddr >> 32);
1531 : 0 : cmd = (u64)paddr & DMA_BIT_MASK(32);
1532 : 0 : RTL_W32(hw, CounterAddrLow, cmd);
1533 : 0 : RTL_W32(hw, CounterAddrLow, cmd | CounterDump);
1534 : :
1535 : : wait_cnt = 0;
1536 [ # # ]: 0 : while (RTL_R32(hw, CounterAddrLow) & CounterDump) {
1537 : 0 : rte_delay_us(10);
1538 : :
1539 : 0 : wait_cnt++;
1540 [ # # ]: 0 : if (wait_cnt > 20)
1541 : : break;
1542 : : }
1543 : :
1544 : : /* RX errors */
1545 : 0 : rte_stats->imissed = rte_le_to_cpu_64(counters->rx_missed);
1546 : 0 : rte_stats->ierrors = rte_le_to_cpu_64(counters->rx_errors);
1547 : :
1548 : : /* TX errors */
1549 : 0 : rte_stats->oerrors = rte_le_to_cpu_64(counters->tx_errors);
1550 : :
1551 : 0 : rte_stats->ipackets = rte_le_to_cpu_64(counters->rx_packets);
1552 : 0 : rte_stats->opackets = rte_le_to_cpu_64(counters->tx_packets);
1553 : : }
1554 : :
1555 : : void
1556 : 0 : rtl_clear_tally_stats(struct rtl_hw *hw)
1557 : : {
1558 [ # # ]: 0 : if (!hw->tally_paddr)
1559 : : return;
1560 : :
1561 : 0 : RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32);
1562 : 0 : RTL_W32(hw, CounterAddrLow,
1563 : : ((u64)hw->tally_paddr & (DMA_BIT_MASK(32))) | CounterReset);
1564 : : }
1565 : :
1566 : : int
1567 : 0 : rtl_tally_init(struct rte_eth_dev *dev)
1568 : : {
1569 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
1570 : 0 : struct rtl_hw *hw = &adapter->hw;
1571 : : const struct rte_memzone *mz;
1572 : :
1573 : 0 : mz = rte_eth_dma_zone_reserve(dev, "tally_counters", 0,
1574 : 0 : sizeof(struct rtl_counters), 64, rte_socket_id());
1575 [ # # ]: 0 : if (mz == NULL)
1576 : : return -ENOMEM;
1577 : :
1578 : 0 : hw->tally_vaddr = mz->addr;
1579 : 0 : hw->tally_paddr = mz->iova;
1580 : :
1581 : : /* Fill tally addrs */
1582 : 0 : RTL_W32(hw, CounterAddrHigh, (u64)hw->tally_paddr >> 32);
1583 : 0 : RTL_W32(hw, CounterAddrLow, (u64)hw->tally_paddr & (DMA_BIT_MASK(32)));
1584 : :
1585 : : /* Reset the hw statistics */
1586 : 0 : rtl_clear_tally_stats(hw);
1587 : :
1588 : 0 : return 0;
1589 : : }
1590 : :
1591 : : void
1592 : 0 : rtl_tally_free(struct rte_eth_dev *dev)
1593 : : {
1594 : 0 : rte_eth_dma_zone_free(dev, "tally_counters", 0);
1595 : 0 : }
|