1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) 2014-2015 Hisilicon Limited. |
4 | */ |
5 | |
6 | #include <linux/delay.h> |
7 | #include <linux/of_mdio.h> |
8 | #include "hns_dsaf_main.h" |
9 | #include "hns_dsaf_mac.h" |
10 | #include "hns_dsaf_gmac.h" |
11 | |
12 | static const struct mac_stats_string g_gmac_stats_string[] = { |
13 | {"gmac_rx_octets_total_ok" , MAC_STATS_FIELD_OFF(rx_good_bytes)}, |
14 | {"gmac_rx_octets_bad" , MAC_STATS_FIELD_OFF(rx_bad_bytes)}, |
15 | {"gmac_rx_uc_pkts" , MAC_STATS_FIELD_OFF(rx_uc_pkts)}, |
16 | {"gmac_rx_mc_pkts" , MAC_STATS_FIELD_OFF(rx_mc_pkts)}, |
17 | {"gmac_rx_bc_pkts" , MAC_STATS_FIELD_OFF(rx_bc_pkts)}, |
18 | {"gmac_rx_pkts_64octets" , MAC_STATS_FIELD_OFF(rx_64bytes)}, |
19 | {"gmac_rx_pkts_65to127" , MAC_STATS_FIELD_OFF(rx_65to127)}, |
20 | {"gmac_rx_pkts_128to255" , MAC_STATS_FIELD_OFF(rx_128to255)}, |
21 | {"gmac_rx_pkts_256to511" , MAC_STATS_FIELD_OFF(rx_256to511)}, |
22 | {"gmac_rx_pkts_512to1023" , MAC_STATS_FIELD_OFF(rx_512to1023)}, |
23 | {"gmac_rx_pkts_1024to1518" , MAC_STATS_FIELD_OFF(rx_1024to1518)}, |
24 | {"gmac_rx_pkts_1519tomax" , MAC_STATS_FIELD_OFF(rx_1519tomax)}, |
25 | {"gmac_rx_fcs_errors" , MAC_STATS_FIELD_OFF(rx_fcs_err)}, |
26 | {"gmac_rx_tagged" , MAC_STATS_FIELD_OFF(rx_vlan_pkts)}, |
27 | {"gmac_rx_data_err" , MAC_STATS_FIELD_OFF(rx_data_err)}, |
28 | {"gmac_rx_align_errors" , MAC_STATS_FIELD_OFF(rx_align_err)}, |
29 | {"gmac_rx_long_errors" , MAC_STATS_FIELD_OFF(rx_oversize)}, |
30 | {"gmac_rx_jabber_errors" , MAC_STATS_FIELD_OFF(rx_jabber_err)}, |
31 | {"gmac_rx_pause_maccontrol" , MAC_STATS_FIELD_OFF(rx_pfc_tc0)}, |
32 | {"gmac_rx_unknown_maccontrol" , MAC_STATS_FIELD_OFF(rx_unknown_ctrl)}, |
33 | {"gmac_rx_very_long_err" , MAC_STATS_FIELD_OFF(rx_long_err)}, |
34 | {"gmac_rx_runt_err" , MAC_STATS_FIELD_OFF(rx_minto64)}, |
35 | {"gmac_rx_short_err" , MAC_STATS_FIELD_OFF(rx_under_min)}, |
36 | {"gmac_rx_filt_pkt" , MAC_STATS_FIELD_OFF(rx_filter_pkts)}, |
37 | {"gmac_rx_octets_total_filt" , MAC_STATS_FIELD_OFF(rx_filter_bytes)}, |
38 | {"gmac_rx_overrun_cnt" , MAC_STATS_FIELD_OFF(rx_fifo_overrun_err)}, |
39 | {"gmac_rx_length_err" , MAC_STATS_FIELD_OFF(rx_len_err)}, |
40 | {"gmac_rx_fail_comma" , MAC_STATS_FIELD_OFF(rx_comma_err)}, |
41 | |
42 | {"gmac_tx_octets_ok" , MAC_STATS_FIELD_OFF(tx_good_bytes)}, |
43 | {"gmac_tx_octets_bad" , MAC_STATS_FIELD_OFF(tx_bad_bytes)}, |
44 | {"gmac_tx_uc_pkts" , MAC_STATS_FIELD_OFF(tx_uc_pkts)}, |
45 | {"gmac_tx_mc_pkts" , MAC_STATS_FIELD_OFF(tx_mc_pkts)}, |
46 | {"gmac_tx_bc_pkts" , MAC_STATS_FIELD_OFF(tx_bc_pkts)}, |
47 | {"gmac_tx_pkts_64octets" , MAC_STATS_FIELD_OFF(tx_64bytes)}, |
48 | {"gmac_tx_pkts_65to127" , MAC_STATS_FIELD_OFF(tx_65to127)}, |
49 | {"gmac_tx_pkts_128to255" , MAC_STATS_FIELD_OFF(tx_128to255)}, |
50 | {"gmac_tx_pkts_256to511" , MAC_STATS_FIELD_OFF(tx_256to511)}, |
51 | {"gmac_tx_pkts_512to1023" , MAC_STATS_FIELD_OFF(tx_512to1023)}, |
52 | {"gmac_tx_pkts_1024to1518" , MAC_STATS_FIELD_OFF(tx_1024to1518)}, |
53 | {"gmac_tx_pkts_1519tomax" , MAC_STATS_FIELD_OFF(tx_1519tomax)}, |
54 | {"gmac_tx_excessive_length_drop" , MAC_STATS_FIELD_OFF(tx_jabber_err)}, |
55 | {"gmac_tx_underrun" , MAC_STATS_FIELD_OFF(tx_underrun_err)}, |
56 | {"gmac_tx_tagged" , MAC_STATS_FIELD_OFF(tx_vlan)}, |
57 | {"gmac_tx_crc_error" , MAC_STATS_FIELD_OFF(tx_crc_err)}, |
58 | {"gmac_tx_pause_frames" , MAC_STATS_FIELD_OFF(tx_pfc_tc0)} |
59 | }; |
60 | |
61 | static void hns_gmac_enable(void *mac_drv, enum mac_commom_mode mode) |
62 | { |
63 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
64 | |
65 | /*enable GE rX/tX */ |
66 | if (mode == MAC_COMM_MODE_TX || mode == MAC_COMM_MODE_RX_AND_TX) |
67 | dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_TX_EN_B, 1); |
68 | |
69 | if (mode == MAC_COMM_MODE_RX || mode == MAC_COMM_MODE_RX_AND_TX) { |
70 | /* enable rx pcs */ |
71 | dsaf_set_dev_bit(drv, GMAC_PCS_RX_EN_REG, 0, 0); |
72 | dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 1); |
73 | } |
74 | } |
75 | |
76 | static void hns_gmac_disable(void *mac_drv, enum mac_commom_mode mode) |
77 | { |
78 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
79 | |
80 | /*disable GE rX/tX */ |
81 | if (mode == MAC_COMM_MODE_TX || mode == MAC_COMM_MODE_RX_AND_TX) |
82 | dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_TX_EN_B, 0); |
83 | |
84 | if (mode == MAC_COMM_MODE_RX || mode == MAC_COMM_MODE_RX_AND_TX) { |
85 | /* disable rx pcs */ |
86 | dsaf_set_dev_bit(drv, GMAC_PCS_RX_EN_REG, 0, 1); |
87 | dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0); |
88 | } |
89 | } |
90 | |
91 | /* hns_gmac_get_en - get port enable |
92 | * @mac_drv:mac device |
93 | * @rx:rx enable |
94 | * @tx:tx enable |
95 | */ |
96 | static void hns_gmac_get_en(void *mac_drv, u32 *rx, u32 *tx) |
97 | { |
98 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
99 | u32 porten; |
100 | |
101 | porten = dsaf_read_dev(drv, GMAC_PORT_EN_REG); |
102 | *tx = dsaf_get_bit(porten, GMAC_PORT_TX_EN_B); |
103 | *rx = dsaf_get_bit(porten, GMAC_PORT_RX_EN_B); |
104 | } |
105 | |
106 | static void hns_gmac_free(void *mac_drv) |
107 | { |
108 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
109 | struct dsaf_device *dsaf_dev |
110 | = (struct dsaf_device *)dev_get_drvdata(dev: drv->dev); |
111 | |
112 | u32 mac_id = drv->mac_id; |
113 | |
114 | dsaf_dev->misc_op->ge_srst(dsaf_dev, mac_id, 0); |
115 | } |
116 | |
117 | static void hns_gmac_set_tx_auto_pause_frames(void *mac_drv, u16 newval) |
118 | { |
119 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
120 | |
121 | dsaf_set_dev_field(drv, GMAC_FC_TX_TIMER_REG, GMAC_FC_TX_TIMER_M, |
122 | GMAC_FC_TX_TIMER_S, newval); |
123 | } |
124 | |
125 | static void hns_gmac_get_tx_auto_pause_frames(void *mac_drv, u16 *newval) |
126 | { |
127 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
128 | |
129 | *newval = dsaf_get_dev_field(drv, GMAC_FC_TX_TIMER_REG, |
130 | GMAC_FC_TX_TIMER_M, GMAC_FC_TX_TIMER_S); |
131 | } |
132 | |
133 | static void hns_gmac_config_max_frame_length(void *mac_drv, u16 newval) |
134 | { |
135 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
136 | |
137 | dsaf_set_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, GMAC_MAX_FRM_SIZE_M, |
138 | GMAC_MAX_FRM_SIZE_S, newval); |
139 | |
140 | dsaf_set_dev_field(drv, GAMC_RX_MAX_FRAME, GMAC_MAX_FRM_SIZE_M, |
141 | GMAC_MAX_FRM_SIZE_S, newval); |
142 | } |
143 | |
144 | static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval) |
145 | { |
146 | u32 tx_ctrl; |
147 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
148 | |
149 | tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); |
150 | dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval); |
151 | dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval); |
152 | dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl); |
153 | } |
154 | |
155 | static void hns_gmac_config_an_mode(void *mac_drv, u8 newval) |
156 | { |
157 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
158 | |
159 | dsaf_set_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, |
160 | GMAC_TX_AN_EN_B, !!newval); |
161 | } |
162 | |
163 | static void hns_gmac_tx_loop_pkt_dis(void *mac_drv) |
164 | { |
165 | u32 tx_loop_pkt_pri; |
166 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
167 | |
168 | tx_loop_pkt_pri = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); |
169 | dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_EN_B, 1); |
170 | dsaf_set_bit(tx_loop_pkt_pri, GMAC_TX_LOOP_PKT_HIG_PRI_B, 0); |
171 | dsaf_write_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG, tx_loop_pkt_pri); |
172 | } |
173 | |
174 | static void hns_gmac_get_duplex_type(void *mac_drv, |
175 | enum hns_gmac_duplex_mdoe *duplex_mode) |
176 | { |
177 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
178 | |
179 | *duplex_mode = (enum hns_gmac_duplex_mdoe)dsaf_get_dev_bit( |
180 | drv, GMAC_DUPLEX_TYPE_REG, GMAC_DUPLEX_TYPE_B); |
181 | } |
182 | |
183 | static void hns_gmac_get_port_mode(void *mac_drv, enum hns_port_mode *port_mode) |
184 | { |
185 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
186 | |
187 | *port_mode = (enum hns_port_mode)dsaf_get_dev_field( |
188 | drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); |
189 | } |
190 | |
191 | static void hns_gmac_port_mode_get(void *mac_drv, |
192 | struct hns_gmac_port_mode_cfg *port_mode) |
193 | { |
194 | u32 tx_ctrl; |
195 | u32 recv_ctrl; |
196 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
197 | |
198 | port_mode->port_mode = (enum hns_port_mode)dsaf_get_dev_field( |
199 | drv, GMAC_PORT_MODE_REG, GMAC_PORT_MODE_M, GMAC_PORT_MODE_S); |
200 | |
201 | tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); |
202 | recv_ctrl = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); |
203 | |
204 | port_mode->max_frm_size = |
205 | dsaf_get_dev_field(drv, GMAC_MAX_FRM_SIZE_REG, |
206 | GMAC_MAX_FRM_SIZE_M, GMAC_MAX_FRM_SIZE_S); |
207 | port_mode->short_runts_thr = |
208 | dsaf_get_dev_field(drv, GMAC_SHORT_RUNTS_THR_REG, |
209 | GMAC_SHORT_RUNTS_THR_M, |
210 | GMAC_SHORT_RUNTS_THR_S); |
211 | |
212 | port_mode->pad_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_PAD_EN_B); |
213 | port_mode->crc_add = dsaf_get_bit(tx_ctrl, GMAC_TX_CRC_ADD_B); |
214 | port_mode->an_enable = dsaf_get_bit(tx_ctrl, GMAC_TX_AN_EN_B); |
215 | |
216 | port_mode->runt_pkt_en = |
217 | dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_RUNT_PKT_EN_B); |
218 | port_mode->strip_pad_en = |
219 | dsaf_get_bit(recv_ctrl, GMAC_RECV_CTRL_STRIP_PAD_EN_B); |
220 | } |
221 | |
222 | static void hns_gmac_pause_frm_cfg(void *mac_drv, u32 rx_pause_en, |
223 | u32 tx_pause_en) |
224 | { |
225 | u32 pause_en; |
226 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
227 | |
228 | pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); |
229 | dsaf_set_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B, !!rx_pause_en); |
230 | dsaf_set_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B, !!tx_pause_en); |
231 | dsaf_write_dev(drv, GMAC_PAUSE_EN_REG, pause_en); |
232 | } |
233 | |
234 | static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 *rx_pause_en, |
235 | u32 *tx_pause_en) |
236 | { |
237 | u32 pause_en; |
238 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
239 | |
240 | pause_en = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); |
241 | |
242 | *rx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_RX_FDFC_B); |
243 | *tx_pause_en = dsaf_get_bit(pause_en, GMAC_PAUSE_EN_TX_FDFC_B); |
244 | } |
245 | |
246 | static bool hns_gmac_need_adjust_link(void *mac_drv, enum mac_speed speed, |
247 | int duplex) |
248 | { |
249 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
250 | struct hns_mac_cb *mac_cb = drv->mac_cb; |
251 | |
252 | return (mac_cb->speed != speed) || |
253 | (mac_cb->half_duplex == duplex); |
254 | } |
255 | |
256 | static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed, |
257 | u32 full_duplex) |
258 | { |
259 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
260 | |
261 | dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG, |
262 | GMAC_DUPLEX_TYPE_B, !!full_duplex); |
263 | |
264 | switch (speed) { |
265 | case MAC_SPEED_10: |
266 | dsaf_set_dev_field( |
267 | drv, GMAC_PORT_MODE_REG, |
268 | GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x6); |
269 | break; |
270 | case MAC_SPEED_100: |
271 | dsaf_set_dev_field( |
272 | drv, GMAC_PORT_MODE_REG, |
273 | GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x7); |
274 | break; |
275 | case MAC_SPEED_1000: |
276 | dsaf_set_dev_field( |
277 | drv, GMAC_PORT_MODE_REG, |
278 | GMAC_PORT_MODE_M, GMAC_PORT_MODE_S, 0x8); |
279 | break; |
280 | default: |
281 | dev_err(drv->dev, |
282 | "hns_gmac_adjust_link fail, speed%d mac%d\n" , |
283 | speed, drv->mac_id); |
284 | return -EINVAL; |
285 | } |
286 | |
287 | return 0; |
288 | } |
289 | |
290 | static void hns_gmac_set_uc_match(void *mac_drv, u16 en) |
291 | { |
292 | struct mac_driver *drv = mac_drv; |
293 | |
294 | dsaf_set_dev_bit(drv, GMAC_REC_FILT_CONTROL_REG, |
295 | GMAC_UC_MATCH_EN_B, !en); |
296 | dsaf_set_dev_bit(drv, GMAC_STATION_ADDR_HIGH_2_REG, |
297 | GMAC_ADDR_EN_B, !en); |
298 | } |
299 | |
300 | static void hns_gmac_set_promisc(void *mac_drv, u8 en) |
301 | { |
302 | struct mac_driver *drv = mac_drv; |
303 | |
304 | if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) |
305 | hns_gmac_set_uc_match(mac_drv, en); |
306 | } |
307 | |
308 | static int hns_gmac_wait_fifo_clean(void *mac_drv) |
309 | { |
310 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
311 | int wait_cnt; |
312 | u32 val; |
313 | |
314 | wait_cnt = 0; |
315 | while (wait_cnt++ < HNS_MAX_WAIT_CNT) { |
316 | val = dsaf_read_dev(drv, GMAC_FIFO_STATE_REG); |
317 | /* bit5~bit0 is not send complete pkts */ |
318 | if ((val & 0x3f) == 0) |
319 | break; |
320 | usleep_range(min: 100, max: 200); |
321 | } |
322 | |
323 | if (wait_cnt >= HNS_MAX_WAIT_CNT) { |
324 | dev_err(drv->dev, |
325 | "hns ge %d fifo was not idle.\n" , drv->mac_id); |
326 | return -EBUSY; |
327 | } |
328 | |
329 | return 0; |
330 | } |
331 | |
332 | static void hns_gmac_init(void *mac_drv) |
333 | { |
334 | u32 port; |
335 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
336 | struct dsaf_device *dsaf_dev |
337 | = (struct dsaf_device *)dev_get_drvdata(dev: drv->dev); |
338 | |
339 | port = drv->mac_id; |
340 | |
341 | dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 0); |
342 | mdelay(10); |
343 | dsaf_dev->misc_op->ge_srst(dsaf_dev, port, 1); |
344 | mdelay(10); |
345 | hns_gmac_disable(mac_drv, mode: MAC_COMM_MODE_RX_AND_TX); |
346 | hns_gmac_tx_loop_pkt_dis(mac_drv); |
347 | if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG) |
348 | hns_gmac_set_uc_match(mac_drv, en: 0); |
349 | |
350 | hns_gmac_config_pad_and_crc(mac_drv, newval: 1); |
351 | |
352 | dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG, |
353 | GMAC_MODE_CHANGE_EB_B, 1); |
354 | |
355 | /* reduce gmac tx water line to avoid gmac hang-up |
356 | * in speed 100M and duplex half. |
357 | */ |
358 | dsaf_set_dev_field(drv, GMAC_TX_WATER_LINE_REG, GMAC_TX_WATER_LINE_MASK, |
359 | GMAC_TX_WATER_LINE_SHIFT, 8); |
360 | } |
361 | |
362 | static void hns_gmac_update_stats(void *mac_drv) |
363 | { |
364 | struct mac_hw_stats *hw_stats = NULL; |
365 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
366 | |
367 | hw_stats = &drv->mac_cb->hw_stats; |
368 | |
369 | /* RX */ |
370 | hw_stats->rx_good_bytes |
371 | += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); |
372 | hw_stats->rx_bad_bytes |
373 | += dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); |
374 | hw_stats->rx_uc_pkts += dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); |
375 | hw_stats->rx_mc_pkts += dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); |
376 | hw_stats->rx_bc_pkts += dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); |
377 | hw_stats->rx_64bytes |
378 | += dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); |
379 | hw_stats->rx_65to127 |
380 | += dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); |
381 | hw_stats->rx_128to255 |
382 | += dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); |
383 | hw_stats->rx_256to511 |
384 | += dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); |
385 | hw_stats->rx_512to1023 |
386 | += dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); |
387 | hw_stats->rx_1024to1518 |
388 | += dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); |
389 | hw_stats->rx_1519tomax |
390 | += dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); |
391 | hw_stats->rx_fcs_err += dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); |
392 | hw_stats->rx_vlan_pkts += dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); |
393 | hw_stats->rx_data_err += dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); |
394 | hw_stats->rx_align_err |
395 | += dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); |
396 | hw_stats->rx_oversize |
397 | += dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); |
398 | hw_stats->rx_jabber_err |
399 | += dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); |
400 | hw_stats->rx_pfc_tc0 |
401 | += dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); |
402 | hw_stats->rx_unknown_ctrl |
403 | += dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); |
404 | hw_stats->rx_long_err |
405 | += dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); |
406 | hw_stats->rx_minto64 |
407 | += dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); |
408 | hw_stats->rx_under_min |
409 | += dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); |
410 | hw_stats->rx_filter_pkts |
411 | += dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); |
412 | hw_stats->rx_filter_bytes |
413 | += dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); |
414 | hw_stats->rx_fifo_overrun_err |
415 | += dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); |
416 | hw_stats->rx_len_err |
417 | += dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); |
418 | hw_stats->rx_comma_err |
419 | += dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); |
420 | |
421 | /* TX */ |
422 | hw_stats->tx_good_bytes |
423 | += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); |
424 | hw_stats->tx_bad_bytes |
425 | += dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); |
426 | hw_stats->tx_uc_pkts += dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); |
427 | hw_stats->tx_mc_pkts += dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); |
428 | hw_stats->tx_bc_pkts += dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); |
429 | hw_stats->tx_64bytes |
430 | += dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); |
431 | hw_stats->tx_65to127 |
432 | += dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); |
433 | hw_stats->tx_128to255 |
434 | += dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); |
435 | hw_stats->tx_256to511 |
436 | += dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); |
437 | hw_stats->tx_512to1023 |
438 | += dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); |
439 | hw_stats->tx_1024to1518 |
440 | += dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); |
441 | hw_stats->tx_1519tomax |
442 | += dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); |
443 | hw_stats->tx_jabber_err |
444 | += dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); |
445 | hw_stats->tx_underrun_err |
446 | += dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); |
447 | hw_stats->tx_vlan += dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); |
448 | hw_stats->tx_crc_err += dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); |
449 | hw_stats->tx_pfc_tc0 |
450 | += dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); |
451 | } |
452 | |
453 | static void hns_gmac_set_mac_addr(void *mac_drv, const char *mac_addr) |
454 | { |
455 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
456 | |
457 | u32 high_val = mac_addr[1] | (mac_addr[0] << 8); |
458 | |
459 | u32 low_val = mac_addr[5] | (mac_addr[4] << 8) |
460 | | (mac_addr[3] << 16) | (mac_addr[2] << 24); |
461 | |
462 | u32 val = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); |
463 | u32 sta_addr_en = dsaf_get_bit(val, GMAC_ADDR_EN_B); |
464 | |
465 | dsaf_write_dev(drv, GMAC_STATION_ADDR_LOW_2_REG, low_val); |
466 | dsaf_write_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG, |
467 | high_val | (sta_addr_en << GMAC_ADDR_EN_B)); |
468 | } |
469 | |
470 | static int hns_gmac_config_loopback(void *mac_drv, enum hnae_loop loop_mode, |
471 | u8 enable) |
472 | { |
473 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
474 | |
475 | switch (loop_mode) { |
476 | case MAC_INTERNALLOOP_MAC: |
477 | dsaf_set_dev_bit(drv, GMAC_LOOP_REG, GMAC_LP_REG_CF2MI_LP_EN_B, |
478 | !!enable); |
479 | break; |
480 | default: |
481 | dev_err(drv->dev, "loop_mode error\n" ); |
482 | return -EINVAL; |
483 | } |
484 | |
485 | return 0; |
486 | } |
487 | |
488 | static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info) |
489 | { |
490 | enum hns_gmac_duplex_mdoe duplex; |
491 | enum hns_port_mode speed; |
492 | u32 rx_pause; |
493 | u32 tx_pause; |
494 | u32 rx; |
495 | u32 tx; |
496 | u16 fc_tx_timer; |
497 | struct hns_gmac_port_mode_cfg port_mode = { GMAC_10M_MII, 0 }; |
498 | |
499 | hns_gmac_port_mode_get(mac_drv, port_mode: &port_mode); |
500 | mac_info->pad_and_crc_en = port_mode.crc_add && port_mode.pad_enable; |
501 | mac_info->auto_neg = port_mode.an_enable; |
502 | |
503 | hns_gmac_get_tx_auto_pause_frames(mac_drv, newval: &fc_tx_timer); |
504 | mac_info->tx_pause_time = fc_tx_timer; |
505 | |
506 | hns_gmac_get_en(mac_drv, rx: &rx, tx: &tx); |
507 | mac_info->port_en = rx && tx; |
508 | |
509 | hns_gmac_get_duplex_type(mac_drv, duplex_mode: &duplex); |
510 | mac_info->duplex = duplex; |
511 | |
512 | hns_gmac_get_port_mode(mac_drv, port_mode: &speed); |
513 | switch (speed) { |
514 | case GMAC_10M_SGMII: |
515 | mac_info->speed = MAC_SPEED_10; |
516 | break; |
517 | case GMAC_100M_SGMII: |
518 | mac_info->speed = MAC_SPEED_100; |
519 | break; |
520 | case GMAC_1000M_SGMII: |
521 | mac_info->speed = MAC_SPEED_1000; |
522 | break; |
523 | default: |
524 | mac_info->speed = 0; |
525 | break; |
526 | } |
527 | |
528 | hns_gmac_get_pausefrm_cfg(mac_drv, rx_pause_en: &rx_pause, tx_pause_en: &tx_pause); |
529 | mac_info->rx_pause_en = rx_pause; |
530 | mac_info->tx_pause_en = tx_pause; |
531 | } |
532 | |
533 | static void hns_gmac_autoneg_stat(void *mac_drv, u32 *enable) |
534 | { |
535 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
536 | |
537 | *enable = dsaf_get_dev_bit(drv, GMAC_TRANSMIT_CONTROL_REG, |
538 | GMAC_TX_AN_EN_B); |
539 | } |
540 | |
541 | static void hns_gmac_get_link_status(void *mac_drv, u32 *link_stat) |
542 | { |
543 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
544 | |
545 | *link_stat = dsaf_get_dev_bit(drv, GMAC_AN_NEG_STATE_REG, |
546 | GMAC_AN_NEG_STAT_RX_SYNC_OK_B); |
547 | } |
548 | |
549 | static void hns_gmac_get_regs(void *mac_drv, void *data) |
550 | { |
551 | u32 *regs = data; |
552 | int i; |
553 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
554 | |
555 | /* base config registers */ |
556 | regs[0] = dsaf_read_dev(drv, GMAC_DUPLEX_TYPE_REG); |
557 | regs[1] = dsaf_read_dev(drv, GMAC_FD_FC_TYPE_REG); |
558 | regs[2] = dsaf_read_dev(drv, GMAC_FC_TX_TIMER_REG); |
559 | regs[3] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_LOW_REG); |
560 | regs[4] = dsaf_read_dev(drv, GMAC_FD_FC_ADDR_HIGH_REG); |
561 | regs[5] = dsaf_read_dev(drv, GMAC_IPG_TX_TIMER_REG); |
562 | regs[6] = dsaf_read_dev(drv, GMAC_PAUSE_THR_REG); |
563 | regs[7] = dsaf_read_dev(drv, GMAC_MAX_FRM_SIZE_REG); |
564 | regs[8] = dsaf_read_dev(drv, GMAC_PORT_MODE_REG); |
565 | regs[9] = dsaf_read_dev(drv, GMAC_PORT_EN_REG); |
566 | regs[10] = dsaf_read_dev(drv, GMAC_PAUSE_EN_REG); |
567 | regs[11] = dsaf_read_dev(drv, GMAC_SHORT_RUNTS_THR_REG); |
568 | regs[12] = dsaf_read_dev(drv, GMAC_AN_NEG_STATE_REG); |
569 | regs[13] = dsaf_read_dev(drv, GMAC_TX_LOCAL_PAGE_REG); |
570 | regs[14] = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG); |
571 | regs[15] = dsaf_read_dev(drv, GMAC_REC_FILT_CONTROL_REG); |
572 | regs[16] = dsaf_read_dev(drv, GMAC_PTP_CONFIG_REG); |
573 | |
574 | /* rx static registers */ |
575 | regs[17] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_OK_REG); |
576 | regs[18] = dsaf_read_dev(drv, GMAC_RX_OCTETS_BAD_REG); |
577 | regs[19] = dsaf_read_dev(drv, GMAC_RX_UC_PKTS_REG); |
578 | regs[20] = dsaf_read_dev(drv, GMAC_RX_MC_PKTS_REG); |
579 | regs[21] = dsaf_read_dev(drv, GMAC_RX_BC_PKTS_REG); |
580 | regs[22] = dsaf_read_dev(drv, GMAC_RX_PKTS_64OCTETS_REG); |
581 | regs[23] = dsaf_read_dev(drv, GMAC_RX_PKTS_65TO127OCTETS_REG); |
582 | regs[24] = dsaf_read_dev(drv, GMAC_RX_PKTS_128TO255OCTETS_REG); |
583 | regs[25] = dsaf_read_dev(drv, GMAC_RX_PKTS_255TO511OCTETS_REG); |
584 | regs[26] = dsaf_read_dev(drv, GMAC_RX_PKTS_512TO1023OCTETS_REG); |
585 | regs[27] = dsaf_read_dev(drv, GMAC_RX_PKTS_1024TO1518OCTETS_REG); |
586 | regs[28] = dsaf_read_dev(drv, GMAC_RX_PKTS_1519TOMAXOCTETS_REG); |
587 | regs[29] = dsaf_read_dev(drv, GMAC_RX_FCS_ERRORS_REG); |
588 | regs[30] = dsaf_read_dev(drv, GMAC_RX_TAGGED_REG); |
589 | regs[31] = dsaf_read_dev(drv, GMAC_RX_DATA_ERR_REG); |
590 | regs[32] = dsaf_read_dev(drv, GMAC_RX_ALIGN_ERRORS_REG); |
591 | regs[33] = dsaf_read_dev(drv, GMAC_RX_LONG_ERRORS_REG); |
592 | regs[34] = dsaf_read_dev(drv, GMAC_RX_JABBER_ERRORS_REG); |
593 | regs[35] = dsaf_read_dev(drv, GMAC_RX_PAUSE_MACCTRL_FRAM_REG); |
594 | regs[36] = dsaf_read_dev(drv, GMAC_RX_UNKNOWN_MACCTRL_FRAM_REG); |
595 | regs[37] = dsaf_read_dev(drv, GMAC_RX_VERY_LONG_ERR_CNT_REG); |
596 | regs[38] = dsaf_read_dev(drv, GMAC_RX_RUNT_ERR_CNT_REG); |
597 | regs[39] = dsaf_read_dev(drv, GMAC_RX_SHORT_ERR_CNT_REG); |
598 | regs[40] = dsaf_read_dev(drv, GMAC_RX_FILT_PKT_CNT_REG); |
599 | regs[41] = dsaf_read_dev(drv, GMAC_RX_OCTETS_TOTAL_FILT_REG); |
600 | |
601 | /* tx static registers */ |
602 | regs[42] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_OK_REG); |
603 | regs[43] = dsaf_read_dev(drv, GMAC_OCTETS_TRANSMITTED_BAD_REG); |
604 | regs[44] = dsaf_read_dev(drv, GMAC_TX_UC_PKTS_REG); |
605 | regs[45] = dsaf_read_dev(drv, GMAC_TX_MC_PKTS_REG); |
606 | regs[46] = dsaf_read_dev(drv, GMAC_TX_BC_PKTS_REG); |
607 | regs[47] = dsaf_read_dev(drv, GMAC_TX_PKTS_64OCTETS_REG); |
608 | regs[48] = dsaf_read_dev(drv, GMAC_TX_PKTS_65TO127OCTETS_REG); |
609 | regs[49] = dsaf_read_dev(drv, GMAC_TX_PKTS_128TO255OCTETS_REG); |
610 | regs[50] = dsaf_read_dev(drv, GMAC_TX_PKTS_255TO511OCTETS_REG); |
611 | regs[51] = dsaf_read_dev(drv, GMAC_TX_PKTS_512TO1023OCTETS_REG); |
612 | regs[52] = dsaf_read_dev(drv, GMAC_TX_PKTS_1024TO1518OCTETS_REG); |
613 | regs[53] = dsaf_read_dev(drv, GMAC_TX_PKTS_1519TOMAXOCTETS_REG); |
614 | regs[54] = dsaf_read_dev(drv, GMAC_TX_EXCESSIVE_LENGTH_DROP_REG); |
615 | regs[55] = dsaf_read_dev(drv, GMAC_TX_UNDERRUN_REG); |
616 | regs[56] = dsaf_read_dev(drv, GMAC_TX_TAGGED_REG); |
617 | regs[57] = dsaf_read_dev(drv, GMAC_TX_CRC_ERROR_REG); |
618 | regs[58] = dsaf_read_dev(drv, GMAC_TX_PAUSE_FRAMES_REG); |
619 | |
620 | regs[59] = dsaf_read_dev(drv, GAMC_RX_MAX_FRAME); |
621 | regs[60] = dsaf_read_dev(drv, GMAC_LINE_LOOP_BACK_REG); |
622 | regs[61] = dsaf_read_dev(drv, GMAC_CF_CRC_STRIP_REG); |
623 | regs[62] = dsaf_read_dev(drv, GMAC_MODE_CHANGE_EN_REG); |
624 | regs[63] = dsaf_read_dev(drv, GMAC_SIXTEEN_BIT_CNTR_REG); |
625 | regs[64] = dsaf_read_dev(drv, GMAC_LD_LINK_COUNTER_REG); |
626 | regs[65] = dsaf_read_dev(drv, GMAC_LOOP_REG); |
627 | regs[66] = dsaf_read_dev(drv, GMAC_RECV_CONTROL_REG); |
628 | regs[67] = dsaf_read_dev(drv, GMAC_VLAN_CODE_REG); |
629 | regs[68] = dsaf_read_dev(drv, GMAC_RX_OVERRUN_CNT_REG); |
630 | regs[69] = dsaf_read_dev(drv, GMAC_RX_LENGTHFIELD_ERR_CNT_REG); |
631 | regs[70] = dsaf_read_dev(drv, GMAC_RX_FAIL_COMMA_CNT_REG); |
632 | |
633 | regs[71] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_0_REG); |
634 | regs[72] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_0_REG); |
635 | regs[73] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_1_REG); |
636 | regs[74] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_1_REG); |
637 | regs[75] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_2_REG); |
638 | regs[76] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_2_REG); |
639 | regs[77] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_3_REG); |
640 | regs[78] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_3_REG); |
641 | regs[79] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_4_REG); |
642 | regs[80] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_4_REG); |
643 | regs[81] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_5_REG); |
644 | regs[82] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_5_REG); |
645 | regs[83] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_0_REG); |
646 | regs[84] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_0_REG); |
647 | regs[85] = dsaf_read_dev(drv, GMAC_STATION_ADDR_LOW_MSK_1_REG); |
648 | regs[86] = dsaf_read_dev(drv, GMAC_STATION_ADDR_HIGH_MSK_1_REG); |
649 | regs[87] = dsaf_read_dev(drv, GMAC_MAC_SKIP_LEN_REG); |
650 | regs[88] = dsaf_read_dev(drv, GMAC_TX_LOOP_PKT_PRI_REG); |
651 | |
652 | /* mark end of mac regs */ |
653 | for (i = 89; i < 96; i++) |
654 | regs[i] = 0xaaaaaaaa; |
655 | } |
656 | |
657 | static void hns_gmac_get_stats(void *mac_drv, u64 *data) |
658 | { |
659 | u32 i; |
660 | u64 *buf = data; |
661 | struct mac_driver *drv = (struct mac_driver *)mac_drv; |
662 | struct mac_hw_stats *hw_stats = NULL; |
663 | |
664 | hw_stats = &drv->mac_cb->hw_stats; |
665 | |
666 | for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) { |
667 | buf[i] = DSAF_STATS_READ(hw_stats, |
668 | g_gmac_stats_string[i].offset); |
669 | } |
670 | } |
671 | |
672 | static void hns_gmac_get_strings(u32 stringset, u8 *data) |
673 | { |
674 | u8 *buff = data; |
675 | u32 i; |
676 | |
677 | if (stringset != ETH_SS_STATS) |
678 | return; |
679 | |
680 | for (i = 0; i < ARRAY_SIZE(g_gmac_stats_string); i++) |
681 | ethtool_sprintf(data: &buff, fmt: g_gmac_stats_string[i].desc); |
682 | } |
683 | |
684 | static int hns_gmac_get_sset_count(int stringset) |
685 | { |
686 | if (stringset == ETH_SS_STATS) |
687 | return ARRAY_SIZE(g_gmac_stats_string); |
688 | |
689 | return 0; |
690 | } |
691 | |
692 | static int hns_gmac_get_regs_count(void) |
693 | { |
694 | return ETH_GMAC_DUMP_NUM; |
695 | } |
696 | |
697 | void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param) |
698 | { |
699 | struct mac_driver *mac_drv; |
700 | |
701 | mac_drv = devm_kzalloc(dev: mac_cb->dev, size: sizeof(*mac_drv), GFP_KERNEL); |
702 | if (!mac_drv) |
703 | return NULL; |
704 | |
705 | mac_drv->mac_init = hns_gmac_init; |
706 | mac_drv->mac_enable = hns_gmac_enable; |
707 | mac_drv->mac_disable = hns_gmac_disable; |
708 | mac_drv->mac_free = hns_gmac_free; |
709 | mac_drv->adjust_link = hns_gmac_adjust_link; |
710 | mac_drv->need_adjust_link = hns_gmac_need_adjust_link; |
711 | mac_drv->set_tx_auto_pause_frames = hns_gmac_set_tx_auto_pause_frames; |
712 | mac_drv->config_max_frame_length = hns_gmac_config_max_frame_length; |
713 | mac_drv->mac_pausefrm_cfg = hns_gmac_pause_frm_cfg; |
714 | |
715 | mac_drv->mac_id = mac_param->mac_id; |
716 | mac_drv->mac_mode = mac_param->mac_mode; |
717 | mac_drv->io_base = mac_param->vaddr; |
718 | mac_drv->dev = mac_param->dev; |
719 | mac_drv->mac_cb = mac_cb; |
720 | |
721 | mac_drv->set_mac_addr = hns_gmac_set_mac_addr; |
722 | mac_drv->set_an_mode = hns_gmac_config_an_mode; |
723 | mac_drv->config_loopback = hns_gmac_config_loopback; |
724 | mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc; |
725 | mac_drv->get_info = hns_gmac_get_info; |
726 | mac_drv->autoneg_stat = hns_gmac_autoneg_stat; |
727 | mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg; |
728 | mac_drv->get_link_status = hns_gmac_get_link_status; |
729 | mac_drv->get_regs = hns_gmac_get_regs; |
730 | mac_drv->get_regs_count = hns_gmac_get_regs_count; |
731 | mac_drv->get_ethtool_stats = hns_gmac_get_stats; |
732 | mac_drv->get_sset_count = hns_gmac_get_sset_count; |
733 | mac_drv->get_strings = hns_gmac_get_strings; |
734 | mac_drv->update_stats = hns_gmac_update_stats; |
735 | mac_drv->set_promiscuous = hns_gmac_set_promisc; |
736 | mac_drv->wait_fifo_clean = hns_gmac_wait_fifo_clean; |
737 | |
738 | return (void *)mac_drv; |
739 | } |
740 | |