gpio: rcar: Fix runtime PM imbalance on error
[linux/fpc-iii.git] / drivers / net / ethernet / aquantia / atlantic / hw_atl / hw_atl_utils.c
blob354705f9bc493afcbe9c63f28cc36f779eea4be5
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * aQuantia Corporation Network Driver
4 * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
5 */
7 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware
8 * abstraction layer.
9 */
11 #include "../aq_nic.h"
12 #include "../aq_hw_utils.h"
13 #include "hw_atl_utils.h"
14 #include "hw_atl_llh.h"
15 #include "hw_atl_llh_internal.h"
17 #include <linux/random.h>
19 #define HW_ATL_UCP_0X370_REG 0x0370U
21 #define HW_ATL_MIF_CMD 0x0200U
22 #define HW_ATL_MIF_ADDR 0x0208U
23 #define HW_ATL_MIF_VAL 0x020CU
25 #define HW_ATL_MPI_RPC_ADDR 0x0334U
26 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
27 #define HW_ATL_RPC_STATE_ADR 0x033CU
29 #define HW_ATL_MPI_FW_VERSION 0x18
30 #define HW_ATL_MPI_CONTROL_ADR 0x0368U
31 #define HW_ATL_MPI_STATE_ADR 0x036CU
33 #define HW_ATL_MPI_STATE_MSK 0x00FFU
34 #define HW_ATL_MPI_STATE_SHIFT 0U
35 #define HW_ATL_MPI_SPEED_MSK 0x00FF0000U
36 #define HW_ATL_MPI_SPEED_SHIFT 16U
37 #define HW_ATL_MPI_DIRTY_WAKE_MSK 0x02000000U
39 #define HW_ATL_MPI_DAISY_CHAIN_STATUS 0x704
40 #define HW_ATL_MPI_BOOT_EXIT_CODE 0x388
42 #define HW_ATL_MAC_PHY_CONTROL 0x4000
43 #define HW_ATL_MAC_PHY_MPI_RESET_BIT 0x1D
45 #define HW_ATL_FW_VER_1X 0x01050006U
46 #define HW_ATL_FW_VER_2X 0x02000000U
47 #define HW_ATL_FW_VER_3X 0x03000000U
49 #define FORCE_FLASHLESS 0
51 enum mcp_area {
52 MCP_AREA_CONFIG = 0x80000000,
53 MCP_AREA_SETTINGS = 0x20000000,
56 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
57 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
58 enum hal_atl_utils_fw_state_e state);
59 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self);
60 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self);
61 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self);
62 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self);
63 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self);
64 static u32 aq_fw1x_rpc_get(struct aq_hw_s *self);
66 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
68 int err = 0;
70 err = hw_atl_utils_soft_reset(self);
71 if (err)
72 return err;
74 hw_atl_utils_hw_chip_features_init(self,
75 &self->chip_features);
77 hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
79 if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
80 self->fw_ver_actual) == 0) {
81 *fw_ops = &aq_fw_1x_ops;
82 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
83 self->fw_ver_actual) == 0) {
84 *fw_ops = &aq_fw_2x_ops;
85 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
86 self->fw_ver_actual) == 0) {
87 *fw_ops = &aq_fw_2x_ops;
88 } else {
89 aq_pr_err("Bad FW version detected: %x\n",
90 self->fw_ver_actual);
91 return -EOPNOTSUPP;
93 self->aq_fw_ops = *fw_ops;
94 err = self->aq_fw_ops->init(self);
96 return err;
99 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
101 u32 gsr, val;
102 int k = 0;
104 aq_hw_write_reg(self, 0x404, 0x40e1);
105 AQ_HW_SLEEP(50);
107 /* Cleanup SPI */
108 val = aq_hw_read_reg(self, 0x53C);
109 aq_hw_write_reg(self, 0x53C, val | 0x10);
111 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
112 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
114 /* Kickstart MAC */
115 aq_hw_write_reg(self, 0x404, 0x80e0);
116 aq_hw_write_reg(self, 0x32a8, 0x0);
117 aq_hw_write_reg(self, 0x520, 0x1);
119 /* Reset SPI again because of possible interrupted SPI burst */
120 val = aq_hw_read_reg(self, 0x53C);
121 aq_hw_write_reg(self, 0x53C, val | 0x10);
122 AQ_HW_SLEEP(10);
123 /* Clear SPI reset state */
124 aq_hw_write_reg(self, 0x53C, val & ~0x10);
126 aq_hw_write_reg(self, 0x404, 0x180e0);
128 for (k = 0; k < 1000; k++) {
129 u32 flb_status = aq_hw_read_reg(self,
130 HW_ATL_MPI_DAISY_CHAIN_STATUS);
132 flb_status = flb_status & 0x10;
133 if (flb_status)
134 break;
135 AQ_HW_SLEEP(10);
137 if (k == 1000) {
138 aq_pr_err("MAC kickstart failed\n");
139 return -EIO;
142 /* FW reset */
143 aq_hw_write_reg(self, 0x404, 0x80e0);
144 AQ_HW_SLEEP(50);
145 aq_hw_write_reg(self, 0x3a0, 0x1);
147 /* Kickstart PHY - skipped */
149 /* Global software reset*/
150 hw_atl_rx_rx_reg_res_dis_set(self, 0U);
151 hw_atl_tx_tx_reg_res_dis_set(self, 0U);
152 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
153 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
154 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
155 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
156 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
158 for (k = 0; k < 1000; k++) {
159 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
161 if (fw_state)
162 break;
163 AQ_HW_SLEEP(10);
165 if (k == 1000) {
166 aq_pr_err("FW kickstart failed\n");
167 return -EIO;
169 /* Old FW requires fixed delay after init */
170 AQ_HW_SLEEP(15);
172 return 0;
175 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
177 u32 gsr, val, rbl_status;
178 int k;
180 aq_hw_write_reg(self, 0x404, 0x40e1);
181 aq_hw_write_reg(self, 0x3a0, 0x1);
182 aq_hw_write_reg(self, 0x32a8, 0x0);
184 /* Alter RBL status */
185 aq_hw_write_reg(self, 0x388, 0xDEAD);
187 /* Cleanup SPI */
188 val = aq_hw_read_reg(self, 0x53C);
189 aq_hw_write_reg(self, 0x53C, val | 0x10);
191 /* Global software reset*/
192 hw_atl_rx_rx_reg_res_dis_set(self, 0U);
193 hw_atl_tx_tx_reg_res_dis_set(self, 0U);
194 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
195 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
196 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
197 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
198 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR,
199 (gsr & 0xFFFFBFFF) | 0x8000);
201 if (FORCE_FLASHLESS)
202 aq_hw_write_reg(self, 0x534, 0x0);
204 aq_hw_write_reg(self, 0x404, 0x40e0);
206 /* Wait for RBL boot */
207 for (k = 0; k < 1000; k++) {
208 rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF;
209 if (rbl_status && rbl_status != 0xDEAD)
210 break;
211 AQ_HW_SLEEP(10);
213 if (!rbl_status || rbl_status == 0xDEAD) {
214 aq_pr_err("RBL Restart failed");
215 return -EIO;
218 /* Restore NVR */
219 if (FORCE_FLASHLESS)
220 aq_hw_write_reg(self, 0x534, 0xA0);
222 if (rbl_status == 0xF1A7) {
223 aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
224 return -ENOTSUPP;
227 for (k = 0; k < 1000; k++) {
228 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
230 if (fw_state)
231 break;
232 AQ_HW_SLEEP(10);
234 if (k == 1000) {
235 aq_pr_err("FW kickstart failed\n");
236 return -EIO;
238 /* Old FW requires fixed delay after init */
239 AQ_HW_SLEEP(15);
241 return 0;
244 int hw_atl_utils_soft_reset(struct aq_hw_s *self)
246 u32 boot_exit_code = 0;
247 u32 val;
248 int k;
250 for (k = 0; k < 1000; ++k) {
251 u32 flb_status = aq_hw_read_reg(self,
252 HW_ATL_MPI_DAISY_CHAIN_STATUS);
253 boot_exit_code = aq_hw_read_reg(self,
254 HW_ATL_MPI_BOOT_EXIT_CODE);
255 if (flb_status != 0x06000000 || boot_exit_code != 0)
256 break;
259 if (k == 1000) {
260 aq_pr_err("Neither RBL nor FLB firmware started\n");
261 return -EOPNOTSUPP;
264 self->rbl_enabled = (boot_exit_code != 0);
266 /* FW 1.x may bootup in an invalid POWER state (WOL feature).
267 * We should work around this by forcing its state back to DEINIT
269 if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
270 aq_hw_read_reg(self,
271 HW_ATL_MPI_FW_VERSION))) {
272 int err = 0;
274 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
275 err = readx_poll_timeout_atomic(hw_atl_utils_mpi_get_state,
276 self, val,
277 (val & HW_ATL_MPI_STATE_MSK) ==
278 MPI_DEINIT,
279 10, 10000U);
280 if (err)
281 return err;
284 if (self->rbl_enabled)
285 return hw_atl_utils_soft_reset_rbl(self);
286 else
287 return hw_atl_utils_soft_reset_flb(self);
290 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
291 u32 *p, u32 cnt)
293 int err = 0;
294 u32 val;
296 err = readx_poll_timeout_atomic(hw_atl_sem_ram_get,
297 self, val, val == 1U,
298 1U, 10000U);
300 if (err < 0) {
301 bool is_locked;
303 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
304 is_locked = hw_atl_sem_ram_get(self);
305 if (!is_locked) {
306 err = -ETIME;
307 goto err_exit;
311 aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
313 for (++cnt; --cnt && !err;) {
314 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
316 if (IS_CHIP_FEATURE(REVISION_B1))
317 err = readx_poll_timeout_atomic(hw_atl_utils_mif_addr_get,
318 self, val, val != a,
319 1U, 1000U);
320 else
321 err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
322 self, val,
323 !(val & 0x100),
324 1U, 1000U);
326 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
327 a += 4;
330 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
332 err_exit:
333 return err;
336 static int hw_atl_utils_write_b1_mbox(struct aq_hw_s *self, u32 addr,
337 u32 *p, u32 cnt, enum mcp_area area)
339 u32 data_offset = 0;
340 u32 offset = addr;
341 int err = 0;
342 u32 val;
344 switch (area) {
345 case MCP_AREA_CONFIG:
346 offset -= self->rpc_addr;
347 break;
349 case MCP_AREA_SETTINGS:
350 offset -= self->settings_addr;
351 break;
354 offset = offset / sizeof(u32);
356 for (; data_offset < cnt; ++data_offset, ++offset) {
357 aq_hw_write_reg(self, 0x328, p[data_offset]);
358 aq_hw_write_reg(self, 0x32C,
359 (area | (0xFFFF & (offset * 4))));
360 hw_atl_mcp_up_force_intr_set(self, 1);
361 /* 1000 times by 10us = 10ms */
362 err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
363 self, val,
364 (val & 0xF0000000) !=
365 area,
366 10U, 10000U);
368 if (err < 0)
369 break;
372 return err;
375 static int hw_atl_utils_write_b0_mbox(struct aq_hw_s *self, u32 addr,
376 u32 *p, u32 cnt)
378 u32 offset = 0;
379 int err = 0;
380 u32 val;
382 aq_hw_write_reg(self, 0x208, addr);
384 for (; offset < cnt; ++offset) {
385 aq_hw_write_reg(self, 0x20C, p[offset]);
386 aq_hw_write_reg(self, 0x200, 0xC000);
388 err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
389 self, val,
390 (val & 0x100) == 0U,
391 10U, 10000U);
393 if (err < 0)
394 break;
397 return err;
400 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 addr, u32 *p,
401 u32 cnt, enum mcp_area area)
403 int err = 0;
404 u32 val;
406 err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self,
407 val, val == 1U,
408 10U, 100000U);
409 if (err < 0)
410 goto err_exit;
412 if (IS_CHIP_FEATURE(REVISION_B1))
413 err = hw_atl_utils_write_b1_mbox(self, addr, p, cnt, area);
414 else
415 err = hw_atl_utils_write_b0_mbox(self, addr, p, cnt);
417 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
419 if (err < 0)
420 goto err_exit;
422 err = aq_hw_err_from_flags(self);
424 err_exit:
425 return err;
428 int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt)
430 return hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, p,
431 cnt, MCP_AREA_CONFIG);
434 int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
435 u32 cnt)
437 return hw_atl_utils_fw_upload_dwords(self, self->settings_addr + offset,
438 p, cnt, MCP_AREA_SETTINGS);
441 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
443 const u32 dw_major_mask = 0xff000000U;
444 const u32 dw_minor_mask = 0x00ffffffU;
445 int err = 0;
447 err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
448 if (err < 0)
449 goto err_exit;
450 err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
451 -EOPNOTSUPP : 0;
453 err_exit:
454 return err;
457 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
458 const struct aq_hw_caps_s *aq_hw_caps)
460 int err = 0;
462 if (!aq_hw_read_reg(self, 0x370U)) {
463 unsigned int rnd = 0U;
464 unsigned int ucp_0x370 = 0U;
466 get_random_bytes(&rnd, sizeof(unsigned int));
468 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
469 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
472 hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
474 /* check 10 times by 1ms */
475 err = readx_poll_timeout_atomic(hw_atl_scrpad25_get,
476 self, self->mbox_addr,
477 self->mbox_addr != 0U,
478 1000U, 10000U);
479 err = readx_poll_timeout_atomic(aq_fw1x_rpc_get, self,
480 self->rpc_addr,
481 self->rpc_addr != 0U,
482 1000U, 100000U);
484 return err;
487 struct aq_hw_atl_utils_fw_rpc_tid_s {
488 union {
489 u32 val;
490 struct {
491 u16 tid;
492 u16 len;
497 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
499 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
501 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
502 int err = 0;
504 if (!IS_CHIP_FEATURE(MIPS)) {
505 err = -1;
506 goto err_exit;
508 err = hw_atl_write_fwcfg_dwords(self, (u32 *)(void *)&self->rpc,
509 (rpc_size + sizeof(u32) -
510 sizeof(u8)) / sizeof(u32));
511 if (err < 0)
512 goto err_exit;
514 sw.tid = 0xFFFFU & (++self->rpc_tid);
515 sw.len = (u16)rpc_size;
516 aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
518 err_exit:
519 return err;
522 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
523 struct hw_atl_utils_fw_rpc **rpc)
525 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
526 struct aq_hw_atl_utils_fw_rpc_tid_s fw;
527 int err = 0;
529 do {
530 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
532 self->rpc_tid = sw.tid;
534 err = readx_poll_timeout_atomic(hw_atl_utils_rpc_state_get,
535 self, fw.val,
536 sw.tid == fw.tid,
537 1000U, 100000U);
538 if (err < 0)
539 goto err_exit;
541 err = aq_hw_err_from_flags(self);
542 if (err < 0)
543 goto err_exit;
545 if (fw.len == 0xFFFFU) {
546 err = hw_atl_utils_fw_rpc_call(self, sw.len);
547 if (err < 0)
548 goto err_exit;
550 } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
552 if (rpc) {
553 if (fw.len) {
554 err =
555 hw_atl_utils_fw_downld_dwords(self,
556 self->rpc_addr,
557 (u32 *)(void *)
558 &self->rpc,
559 (fw.len + sizeof(u32) -
560 sizeof(u8)) /
561 sizeof(u32));
562 if (err < 0)
563 goto err_exit;
566 *rpc = &self->rpc;
569 err_exit:
570 return err;
573 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
575 int err = 0;
577 err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
578 if (err < 0)
579 goto err_exit;
581 err = hw_atl_utils_fw_rpc_init(self);
582 if (err < 0)
583 goto err_exit;
585 err_exit:
586 return err;
589 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
590 struct hw_atl_utils_mbox_header *pmbox)
592 return hw_atl_utils_fw_downld_dwords(self,
593 self->mbox_addr,
594 (u32 *)(void *)pmbox,
595 sizeof(*pmbox) / sizeof(u32));
598 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
599 struct hw_atl_utils_mbox *pmbox)
601 int err = 0;
603 err = hw_atl_utils_fw_downld_dwords(self,
604 self->mbox_addr,
605 (u32 *)(void *)pmbox,
606 sizeof(*pmbox) / sizeof(u32));
607 if (err < 0)
608 goto err_exit;
610 if (IS_CHIP_FEATURE(REVISION_A0)) {
611 unsigned int mtu = self->aq_nic_cfg ?
612 self->aq_nic_cfg->mtu : 1514U;
613 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
614 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
615 pmbox->stats.dpc = atomic_read(&self->dpc);
616 } else {
617 pmbox->stats.dpc = hw_atl_rpb_rx_dma_drop_pkt_cnt_get(self);
620 err_exit:;
623 static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
625 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
627 val = val & ~HW_ATL_MPI_SPEED_MSK;
628 val |= speed << HW_ATL_MPI_SPEED_SHIFT;
629 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
631 return 0;
634 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
635 enum hal_atl_utils_fw_state_e state)
637 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
638 struct hw_atl_utils_mbox_header mbox;
639 u32 transaction_id = 0;
640 int err = 0;
642 if (state == MPI_RESET) {
643 hw_atl_utils_mpi_read_mbox(self, &mbox);
645 transaction_id = mbox.transaction_id;
647 err = readx_poll_timeout_atomic(hw_atl_utils_get_mpi_mbox_tid,
648 self, mbox.transaction_id,
649 transaction_id !=
650 mbox.transaction_id,
651 1000U, 100000U);
652 if (err < 0)
653 goto err_exit;
655 /* On interface DEINIT we disable DW (raise bit)
656 * Otherwise enable DW (clear bit)
658 if (state == MPI_DEINIT || state == MPI_POWER)
659 val |= HW_ATL_MPI_DIRTY_WAKE_MSK;
660 else
661 val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;
663 /* Set new state bits */
664 val = val & ~HW_ATL_MPI_STATE_MSK;
665 val |= state & HW_ATL_MPI_STATE_MSK;
667 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
669 err_exit:
670 return err;
673 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
675 struct aq_hw_link_status_s *link_status = &self->aq_link_status;
676 u32 mpi_state;
677 u32 speed;
679 mpi_state = hw_atl_utils_mpi_get_state(self);
680 speed = mpi_state >> HW_ATL_MPI_SPEED_SHIFT;
682 if (!speed) {
683 link_status->mbps = 0U;
684 } else {
685 switch (speed) {
686 case HAL_ATLANTIC_RATE_10G:
687 link_status->mbps = 10000U;
688 break;
690 case HAL_ATLANTIC_RATE_5G:
691 case HAL_ATLANTIC_RATE_5GSR:
692 link_status->mbps = 5000U;
693 break;
695 case HAL_ATLANTIC_RATE_2GS:
696 link_status->mbps = 2500U;
697 break;
699 case HAL_ATLANTIC_RATE_1G:
700 link_status->mbps = 1000U;
701 break;
703 case HAL_ATLANTIC_RATE_100M:
704 link_status->mbps = 100U;
705 break;
707 default:
708 return -EBUSY;
712 return 0;
715 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
716 u8 *mac)
718 u32 mac_addr[2];
719 u32 efuse_addr;
720 int err = 0;
721 u32 h = 0U;
722 u32 l = 0U;
724 if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
725 unsigned int ucp_0x370 = 0;
726 unsigned int rnd = 0;
728 get_random_bytes(&rnd, sizeof(unsigned int));
730 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
731 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
734 efuse_addr = aq_hw_read_reg(self, 0x00000374U);
736 err = hw_atl_utils_fw_downld_dwords(self, efuse_addr + (40U * 4U),
737 mac_addr, ARRAY_SIZE(mac_addr));
738 if (err < 0) {
739 mac_addr[0] = 0U;
740 mac_addr[1] = 0U;
741 err = 0;
742 } else {
743 mac_addr[0] = __swab32(mac_addr[0]);
744 mac_addr[1] = __swab32(mac_addr[1]);
747 ether_addr_copy(mac, (u8 *)mac_addr);
749 if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
750 /* chip revision */
751 l = 0xE3000000U |
752 (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
753 (0x00 << 16);
754 h = 0x8001300EU;
756 mac[5] = (u8)(0xFFU & l);
757 l >>= 8;
758 mac[4] = (u8)(0xFFU & l);
759 l >>= 8;
760 mac[3] = (u8)(0xFFU & l);
761 l >>= 8;
762 mac[2] = (u8)(0xFFU & l);
763 mac[1] = (u8)(0xFFU & h);
764 h >>= 8;
765 mac[0] = (u8)(0xFFU & h);
768 return err;
771 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
773 unsigned int ret = 0U;
775 switch (mbps) {
776 case 100U:
777 ret = 5U;
778 break;
780 case 1000U:
781 ret = 4U;
782 break;
784 case 2500U:
785 ret = 3U;
786 break;
788 case 5000U:
789 ret = 1U;
790 break;
792 case 10000U:
793 ret = 0U;
794 break;
796 default:
797 break;
800 return ret;
803 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
805 u32 val = hw_atl_reg_glb_mif_id_get(self);
806 u32 mif_rev = val & 0xFFU;
807 u32 chip_features = 0U;
809 if ((0xFU & mif_rev) == 1U) {
810 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
811 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
812 HAL_ATLANTIC_UTILS_CHIP_MIPS;
813 } else if ((0xFU & mif_rev) == 2U) {
814 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
815 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
816 HAL_ATLANTIC_UTILS_CHIP_MIPS |
817 HAL_ATLANTIC_UTILS_CHIP_TPO2 |
818 HAL_ATLANTIC_UTILS_CHIP_RPF2;
819 } else if ((0xFU & mif_rev) == 0xAU) {
820 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
821 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
822 HAL_ATLANTIC_UTILS_CHIP_MIPS |
823 HAL_ATLANTIC_UTILS_CHIP_TPO2 |
824 HAL_ATLANTIC_UTILS_CHIP_RPF2;
827 *p = chip_features;
830 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
832 hw_atl_utils_mpi_set_speed(self, 0);
833 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
835 return 0;
838 int hw_atl_utils_update_stats(struct aq_hw_s *self)
840 struct aq_stats_s *cs = &self->curr_stats;
841 struct hw_atl_utils_mbox mbox;
843 hw_atl_utils_mpi_read_stats(self, &mbox);
845 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
846 mbox.stats._N_ - self->last_stats._N_)
848 if (self->aq_link_status.mbps) {
849 AQ_SDELTA(uprc);
850 AQ_SDELTA(mprc);
851 AQ_SDELTA(bprc);
852 AQ_SDELTA(erpt);
854 AQ_SDELTA(uptc);
855 AQ_SDELTA(mptc);
856 AQ_SDELTA(bptc);
857 AQ_SDELTA(erpr);
859 AQ_SDELTA(ubrc);
860 AQ_SDELTA(ubtc);
861 AQ_SDELTA(mbrc);
862 AQ_SDELTA(mbtc);
863 AQ_SDELTA(bbrc);
864 AQ_SDELTA(bbtc);
865 AQ_SDELTA(dpc);
867 #undef AQ_SDELTA
869 cs->dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counter_get(self);
870 cs->dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counter_get(self);
871 cs->dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counter_get(self);
872 cs->dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counter_get(self);
874 memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
876 return 0;
879 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
881 return &self->curr_stats;
884 static const u32 hw_atl_utils_hw_mac_regs[] = {
885 0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
886 0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
887 0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
888 0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
889 0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
890 0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
891 0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
892 0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
893 0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
894 0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
895 0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
896 0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
897 0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
898 0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
899 0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
900 0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
901 0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
902 0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
903 0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
904 0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
905 0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
906 0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
909 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
910 const struct aq_hw_caps_s *aq_hw_caps,
911 u32 *regs_buff)
913 unsigned int i = 0U;
915 for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
916 regs_buff[i] = aq_hw_read_reg(self,
917 hw_atl_utils_hw_mac_regs[i]);
919 return 0;
922 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
924 *fw_version = aq_hw_read_reg(self, 0x18U);
926 return 0;
929 static int aq_fw1x_set_wake_magic(struct aq_hw_s *self, bool wol_enabled,
930 u8 *mac)
932 struct hw_atl_utils_fw_rpc *prpc = NULL;
933 unsigned int rpc_size = 0U;
934 int err = 0;
936 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
937 if (err < 0)
938 goto err_exit;
940 memset(prpc, 0, sizeof(*prpc));
942 if (wol_enabled) {
943 rpc_size = offsetof(struct hw_atl_utils_fw_rpc, msg_wol_add) +
944 sizeof(prpc->msg_wol_add);
947 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
948 prpc->msg_wol_add.priority =
949 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
950 prpc->msg_wol_add.pattern_id =
951 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
952 prpc->msg_wol_add.packet_type =
953 HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
955 ether_addr_copy((u8 *)&prpc->msg_wol_add.magic_packet_pattern,
956 mac);
957 } else {
958 rpc_size = sizeof(prpc->msg_wol_remove) +
959 offsetof(struct hw_atl_utils_fw_rpc, msg_wol_remove);
961 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
962 prpc->msg_wol_add.pattern_id =
963 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
966 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
968 err_exit:
969 return err;
972 static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
973 u8 *mac)
975 struct hw_atl_utils_fw_rpc *prpc = NULL;
976 unsigned int rpc_size = 0U;
977 int err = 0;
979 if (self->aq_nic_cfg->wol & WAKE_MAGIC) {
980 err = aq_fw1x_set_wake_magic(self, 1, mac);
982 if (err < 0)
983 goto err_exit;
985 rpc_size = sizeof(prpc->msg_id) +
986 sizeof(prpc->msg_enable_wakeup);
988 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
990 if (err < 0)
991 goto err_exit;
993 memset(prpc, 0, rpc_size);
995 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
996 prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
998 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
999 if (err < 0)
1000 goto err_exit;
1002 hw_atl_utils_mpi_set_speed(self, 0);
1003 hw_atl_utils_mpi_set_state(self, MPI_POWER);
1005 err_exit:
1006 return err;
1009 static u32 hw_atl_utils_get_mpi_mbox_tid(struct aq_hw_s *self)
1011 struct hw_atl_utils_mbox_header mbox;
1013 hw_atl_utils_mpi_read_mbox(self, &mbox);
1015 return mbox.transaction_id;
1018 static u32 hw_atl_utils_mpi_get_state(struct aq_hw_s *self)
1020 return aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
1023 static u32 hw_atl_utils_mif_cmd_get(struct aq_hw_s *self)
1025 return aq_hw_read_reg(self, HW_ATL_MIF_CMD);
1028 static u32 hw_atl_utils_mif_addr_get(struct aq_hw_s *self)
1030 return aq_hw_read_reg(self, HW_ATL_MIF_ADDR);
1033 static u32 hw_atl_utils_rpc_state_get(struct aq_hw_s *self)
1035 return aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR);
1038 static u32 aq_fw1x_rpc_get(struct aq_hw_s *self)
1040 return aq_hw_read_reg(self, HW_ATL_MPI_RPC_ADDR);
1043 const struct aq_fw_ops aq_fw_1x_ops = {
1044 .init = hw_atl_utils_mpi_create,
1045 .deinit = hw_atl_fw1x_deinit,
1046 .reset = NULL,
1047 .get_mac_permanent = hw_atl_utils_get_mac_permanent,
1048 .set_link_speed = hw_atl_utils_mpi_set_speed,
1049 .set_state = hw_atl_utils_mpi_set_state,
1050 .update_link_status = hw_atl_utils_mpi_get_link_status,
1051 .update_stats = hw_atl_utils_update_stats,
1052 .get_phy_temp = NULL,
1053 .set_power = aq_fw1x_set_power,
1054 .set_eee_rate = NULL,
1055 .get_eee_rate = NULL,
1056 .set_flow_control = NULL,
1057 .send_fw_request = NULL,
1058 .enable_ptp = NULL,
1059 .led_control = NULL,