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_compat.h"
13 : : #include "r8169_dash.h"
14 : : #include "r8169_hw.h"
15 : :
16 : : bool
17 : 0 : rtl_is_allow_access_dash_ocp(struct rtl_hw *hw)
18 : : {
19 : : bool allow_access = false;
20 : : u16 mac_ocp_data;
21 : :
22 [ # # ]: 0 : if (!HW_DASH_SUPPORT_DASH(hw))
23 : 0 : goto exit;
24 : :
25 : : allow_access = true;
26 [ # # # ]: 0 : switch (hw->mcfg) {
27 : 0 : case CFG_METHOD_48:
28 : : case CFG_METHOD_49:
29 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xd460);
30 [ # # # # ]: 0 : if (mac_ocp_data == 0xffff || !(mac_ocp_data & BIT_0))
31 : : allow_access = false;
32 : : break;
33 : 0 : case CFG_METHOD_54:
34 : : case CFG_METHOD_55:
35 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xd4c0);
36 [ # # # # ]: 0 : if (mac_ocp_data == 0xffff || (mac_ocp_data & BIT_3))
37 : : allow_access = false;
38 : : break;
39 : 0 : default:
40 : 0 : goto exit;
41 : : }
42 : 0 : exit:
43 : 0 : return allow_access;
44 : : }
45 : :
46 : : static u32
47 : : rtl_get_dash_fw_ver(struct rtl_hw *hw)
48 : : {
49 : : u32 ver = 0xffffffff;
50 : :
51 [ # # ]: 0 : if (HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(hw) == FALSE)
52 : 0 : goto exit;
53 : :
54 : 0 : ver = rtl_ocp_read(hw, OCP_REG_FIRMWARE_MAJOR_VERSION, 4);
55 : :
56 : 0 : exit:
57 : : return ver;
58 : : }
59 : :
60 : : static int
61 : 0 : _rtl_check_dash(struct rtl_hw *hw)
62 : : {
63 [ # # ]: 0 : if (!hw->AllowAccessDashOcp)
64 : : return 0;
65 : :
66 [ # # ]: 0 : if (HW_DASH_SUPPORT_TYPE_2(hw) || HW_DASH_SUPPORT_TYPE_4(hw)) {
67 [ # # ]: 0 : if (rtl_ocp_read(hw, 0x128, 1) & BIT_0)
68 : 0 : return 1;
69 : : }
70 : :
71 : : return 0;
72 : : }
73 : :
74 : : int
75 : 0 : rtl_check_dash(struct rtl_hw *hw)
76 : : {
77 : : u32 ver;
78 : :
79 [ # # ]: 0 : if (_rtl_check_dash(hw)) {
80 : : ver = rtl_get_dash_fw_ver(hw);
81 [ # # ]: 0 : if (!(ver == 0 || ver == 0xffffffff))
82 : 0 : return 1;
83 : : }
84 : :
85 : : return 0;
86 : : }
87 : :
88 : : static void
89 : 0 : rtl8125_dash2_disable_tx(struct rtl_hw *hw)
90 : : {
91 : : u16 wait_cnt = 0;
92 : : u8 tmp_uchar;
93 : :
94 [ # # ]: 0 : if (!HW_DASH_SUPPORT_CMAC(hw))
95 : : return;
96 : :
97 [ # # ]: 0 : if (!hw->DASH)
98 : : return;
99 : :
100 : : /* Disable oob Tx */
101 : 0 : RTL_CMAC_W8(hw, CMAC_IBCR2, RTL_CMAC_R8(hw, CMAC_IBCR2) & ~BIT_0);
102 : :
103 : : /* Wait oob Tx disable */
104 : : do {
105 : 0 : tmp_uchar = RTL_CMAC_R8(hw, CMAC_IBISR0);
106 [ # # ]: 0 : if (tmp_uchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE)
107 : : break;
108 : :
109 : 0 : rte_delay_us(50);
110 : 0 : wait_cnt++;
111 [ # # ]: 0 : } while (wait_cnt < 2000);
112 : :
113 : : /* Clear ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE */
114 : 0 : RTL_CMAC_W8(hw, CMAC_IBISR0, RTL_CMAC_R8(hw, CMAC_IBISR0) |
115 : : ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE);
116 : : }
117 : :
118 : : static void
119 : : rtl8125_dash2_disable_rx(struct rtl_hw *hw)
120 : : {
121 [ # # ]: 0 : if (!HW_DASH_SUPPORT_CMAC(hw))
122 : : return;
123 : :
124 [ # # ]: 0 : if (!hw->DASH)
125 : : return;
126 : :
127 : 0 : RTL_CMAC_W8(hw, CMAC_IBCR0, RTL_CMAC_R8(hw, CMAC_IBCR0) & ~BIT_0);
128 : : }
129 : :
130 : : void
131 : 0 : rtl8125_dash2_disable_txrx(struct rtl_hw *hw)
132 : : {
133 [ # # ]: 0 : if (!HW_DASH_SUPPORT_CMAC(hw))
134 : : return;
135 : :
136 : 0 : rtl8125_dash2_disable_tx(hw);
137 : : rtl8125_dash2_disable_rx(hw);
138 : : }
139 : :
140 : : static void
141 : 0 : rtl8125_notify_dash_oob_cmac(struct rtl_hw *hw, u32 cmd)
142 : : {
143 : : u32 tmp_value;
144 : :
145 [ # # ]: 0 : if (!HW_DASH_SUPPORT_CMAC(hw))
146 : : return;
147 : :
148 : 0 : rtl_ocp_write(hw, 0x180, 4, cmd);
149 : 0 : tmp_value = rtl_ocp_read(hw, 0x30, 4);
150 : 0 : tmp_value |= BIT_0;
151 : 0 : rtl_ocp_write(hw, 0x30, 4, tmp_value);
152 : : }
153 : :
154 : : static void
155 : 0 : rtl8125_notify_dash_oob_ipc2(struct rtl_hw *hw, u32 cmd)
156 : : {
157 [ # # ]: 0 : if (HW_DASH_SUPPORT_TYPE_4(hw) == FALSE)
158 : : return;
159 : :
160 : 0 : rtl_ocp_write(hw, IB2SOC_DATA, 4, cmd);
161 : 0 : rtl_ocp_write(hw, IB2SOC_CMD, 4, 0x00);
162 : 0 : rtl_ocp_write(hw, IB2SOC_SET, 4, 0x01);
163 : : }
164 : :
165 : : static void
166 : 0 : rtl8125_notify_dash_oob(struct rtl_hw *hw, u32 cmd)
167 : : {
168 [ # # # ]: 0 : switch (hw->HwSuppDashVer) {
169 : 0 : case 2:
170 : : case 3:
171 : 0 : rtl8125_notify_dash_oob_cmac(hw, cmd);
172 : 0 : break;
173 : 0 : case 4:
174 : 0 : rtl8125_notify_dash_oob_ipc2(hw, cmd);
175 : 0 : break;
176 : : default:
177 : : break;
178 : : }
179 : 0 : }
180 : :
181 : : static int
182 : 0 : rtl8125_wait_dash_fw_ready(struct rtl_hw *hw)
183 : : {
184 : : int rc = -1;
185 : : int timeout;
186 : :
187 [ # # ]: 0 : if (!hw->DASH)
188 : 0 : goto out;
189 : :
190 [ # # ]: 0 : for (timeout = 0; timeout < 10; timeout++) {
191 : : rte_delay_ms(10);
192 [ # # ]: 0 : if (rtl_ocp_read(hw, 0x124, 1) & BIT_0) {
193 : : rc = 1;
194 : 0 : goto out;
195 : : }
196 : : }
197 : :
198 : : rc = 0;
199 : :
200 : 0 : out:
201 : 0 : return rc;
202 : : }
203 : :
204 : : void
205 : 0 : rtl8125_driver_start(struct rtl_hw *hw)
206 : : {
207 [ # # ]: 0 : if (!hw->AllowAccessDashOcp)
208 : : return;
209 : :
210 : 0 : rtl8125_notify_dash_oob(hw, OOB_CMD_DRIVER_START);
211 : :
212 : 0 : rtl8125_wait_dash_fw_ready(hw);
213 : : }
214 : :
215 : : void
216 : 0 : rtl8125_driver_stop(struct rtl_hw *hw)
217 : : {
218 [ # # ]: 0 : if (!hw->AllowAccessDashOcp)
219 : : return;
220 : :
221 [ # # ]: 0 : if (HW_DASH_SUPPORT_CMAC(hw))
222 : 0 : rtl8125_dash2_disable_txrx(hw);
223 : :
224 : 0 : rtl8125_notify_dash_oob(hw, OOB_CMD_DRIVER_STOP);
225 : :
226 : 0 : rtl8125_wait_dash_fw_ready(hw);
227 : : }
|