2 * aQuantia Corporation Network Driver
3 * Copyright (C) 2014-2017 aQuantia Corporation. All rights reserved
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
10 /* File hw_atl_utils.c: Definition of common functions for Atlantic hardware
14 #include "../aq_nic.h"
15 #include "../aq_hw_utils.h"
16 #include "hw_atl_utils.h"
17 #include "hw_atl_llh.h"
18 #include "hw_atl_llh_internal.h"
20 #include <linux/random.h>
22 #define HW_ATL_UCP_0X370_REG 0x0370U
24 #define HW_ATL_MIF_CMD 0x0200U
25 #define HW_ATL_MIF_ADDR 0x0208U
26 #define HW_ATL_MIF_VAL 0x020CU
28 #define HW_ATL_FW_SM_RAM 0x2U
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 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
53 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
54 enum hal_atl_utils_fw_state_e state);
56 int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
60 err = hw_atl_utils_soft_reset(self);
64 hw_atl_utils_hw_chip_features_init(self,
65 &self->chip_features);
67 hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
69 if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
70 self->fw_ver_actual) == 0) {
71 *fw_ops = &aq_fw_1x_ops;
72 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
73 self->fw_ver_actual) == 0) {
74 *fw_ops = &aq_fw_2x_ops;
75 } else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
76 self->fw_ver_actual) == 0) {
77 *fw_ops = &aq_fw_2x_ops;
79 aq_pr_err("Bad FW version detected: %x\n",
83 self->aq_fw_ops = *fw_ops;
84 err = self->aq_fw_ops->init(self);
88 static int hw_atl_utils_soft_reset_flb(struct aq_hw_s *self)
93 aq_hw_write_reg(self, 0x404, 0x40e1);
97 val = aq_hw_read_reg(self, 0x53C);
98 aq_hw_write_reg(self, 0x53C, val | 0x10);
100 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
101 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
104 aq_hw_write_reg(self, 0x404, 0x80e0);
105 aq_hw_write_reg(self, 0x32a8, 0x0);
106 aq_hw_write_reg(self, 0x520, 0x1);
108 /* Reset SPI again because of possible interrupted SPI burst */
109 val = aq_hw_read_reg(self, 0x53C);
110 aq_hw_write_reg(self, 0x53C, val | 0x10);
112 /* Clear SPI reset state */
113 aq_hw_write_reg(self, 0x53C, val & ~0x10);
115 aq_hw_write_reg(self, 0x404, 0x180e0);
117 for (k = 0; k < 1000; k++) {
118 u32 flb_status = aq_hw_read_reg(self,
119 HW_ATL_MPI_DAISY_CHAIN_STATUS);
121 flb_status = flb_status & 0x10;
127 aq_pr_err("MAC kickstart failed\n");
132 aq_hw_write_reg(self, 0x404, 0x80e0);
134 aq_hw_write_reg(self, 0x3a0, 0x1);
136 /* Kickstart PHY - skipped */
138 /* Global software reset*/
139 hw_atl_rx_rx_reg_res_dis_set(self, 0U);
140 hw_atl_tx_tx_reg_res_dis_set(self, 0U);
141 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
142 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
143 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
144 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
145 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR, (gsr & 0xBFFF) | 0x8000);
147 for (k = 0; k < 1000; k++) {
148 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
155 aq_pr_err("FW kickstart failed\n");
158 /* Old FW requires fixed delay after init */
164 static int hw_atl_utils_soft_reset_rbl(struct aq_hw_s *self)
166 u32 gsr, val, rbl_status;
169 aq_hw_write_reg(self, 0x404, 0x40e1);
170 aq_hw_write_reg(self, 0x3a0, 0x1);
171 aq_hw_write_reg(self, 0x32a8, 0x0);
173 /* Alter RBL status */
174 aq_hw_write_reg(self, 0x388, 0xDEAD);
177 val = aq_hw_read_reg(self, 0x53C);
178 aq_hw_write_reg(self, 0x53C, val | 0x10);
180 /* Global software reset*/
181 hw_atl_rx_rx_reg_res_dis_set(self, 0U);
182 hw_atl_tx_tx_reg_res_dis_set(self, 0U);
183 aq_hw_write_reg_bit(self, HW_ATL_MAC_PHY_CONTROL,
184 BIT(HW_ATL_MAC_PHY_MPI_RESET_BIT),
185 HW_ATL_MAC_PHY_MPI_RESET_BIT, 0x0);
186 gsr = aq_hw_read_reg(self, HW_ATL_GLB_SOFT_RES_ADR);
187 aq_hw_write_reg(self, HW_ATL_GLB_SOFT_RES_ADR,
188 (gsr & 0xFFFFBFFF) | 0x8000);
191 aq_hw_write_reg(self, 0x534, 0x0);
193 aq_hw_write_reg(self, 0x404, 0x40e0);
195 /* Wait for RBL boot */
196 for (k = 0; k < 1000; k++) {
197 rbl_status = aq_hw_read_reg(self, 0x388) & 0xFFFF;
198 if (rbl_status && rbl_status != 0xDEAD)
202 if (!rbl_status || rbl_status == 0xDEAD) {
203 aq_pr_err("RBL Restart failed");
209 aq_hw_write_reg(self, 0x534, 0xA0);
211 if (rbl_status == 0xF1A7) {
212 aq_pr_err("No FW detected. Dynamic FW load not implemented\n");
216 for (k = 0; k < 1000; k++) {
217 u32 fw_state = aq_hw_read_reg(self, HW_ATL_MPI_FW_VERSION);
224 aq_pr_err("FW kickstart failed\n");
227 /* Old FW requires fixed delay after init */
233 int hw_atl_utils_soft_reset(struct aq_hw_s *self)
236 u32 boot_exit_code = 0;
238 for (k = 0; k < 1000; ++k) {
239 u32 flb_status = aq_hw_read_reg(self,
240 HW_ATL_MPI_DAISY_CHAIN_STATUS);
241 boot_exit_code = aq_hw_read_reg(self,
242 HW_ATL_MPI_BOOT_EXIT_CODE);
243 if (flb_status != 0x06000000 || boot_exit_code != 0)
248 aq_pr_err("Neither RBL nor FLB firmware started\n");
252 self->rbl_enabled = (boot_exit_code != 0);
254 /* FW 1.x may bootup in an invalid POWER state (WOL feature).
255 * We should work around this by forcing its state back to DEINIT
257 if (!hw_atl_utils_ver_match(HW_ATL_FW_VER_1X,
259 HW_ATL_MPI_FW_VERSION))) {
262 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
263 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
264 HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
268 if (self->rbl_enabled)
269 return hw_atl_utils_soft_reset_rbl(self);
271 return hw_atl_utils_soft_reset_flb(self);
274 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
279 AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
280 HW_ATL_FW_SM_RAM) == 1U,
286 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
287 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
294 aq_hw_write_reg(self, HW_ATL_MIF_ADDR, a);
296 for (++cnt; --cnt && !err;) {
297 aq_hw_write_reg(self, HW_ATL_MIF_CMD, 0x00008000U);
299 if (IS_CHIP_FEATURE(REVISION_B1))
300 AQ_HW_WAIT_FOR(a != aq_hw_read_reg(self,
304 AQ_HW_WAIT_FOR(!(0x100 & aq_hw_read_reg(self,
308 *(p++) = aq_hw_read_reg(self, HW_ATL_MIF_VAL);
312 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
318 static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
324 is_locked = hw_atl_reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
329 if (IS_CHIP_FEATURE(REVISION_B1)) {
332 for (; offset < cnt; ++offset) {
333 aq_hw_write_reg(self, 0x328, p[offset]);
334 aq_hw_write_reg(self, 0x32C,
335 (0x80000000 | (0xFFFF & (offset * 4))));
336 hw_atl_mcp_up_force_intr_set(self, 1);
337 /* 1000 times by 10us = 10ms */
338 AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
339 0x32C) & 0xF0000000) !=
346 aq_hw_write_reg(self, 0x208, a);
348 for (; offset < cnt; ++offset) {
349 aq_hw_write_reg(self, 0x20C, p[offset]);
350 aq_hw_write_reg(self, 0x200, 0xC000);
352 AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
353 0x100) == 0, 10, 1000);
357 hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
363 static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
366 const u32 dw_major_mask = 0xff000000U;
367 const u32 dw_minor_mask = 0x00ffffffU;
369 err = (dw_major_mask & (ver_expected ^ ver_actual)) ? -EOPNOTSUPP : 0;
372 err = ((dw_minor_mask & ver_expected) > (dw_minor_mask & ver_actual)) ?
378 static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
379 const struct aq_hw_caps_s *aq_hw_caps)
383 if (!aq_hw_read_reg(self, 0x370U)) {
384 unsigned int rnd = 0U;
385 unsigned int ucp_0x370 = 0U;
387 get_random_bytes(&rnd, sizeof(unsigned int));
389 ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
390 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
393 hw_atl_reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
395 /* check 10 times by 1ms */
396 AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
397 aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
402 #define HW_ATL_RPC_CONTROL_ADR 0x0338U
403 #define HW_ATL_RPC_STATE_ADR 0x033CU
405 struct aq_hw_atl_utils_fw_rpc_tid_s {
415 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
417 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
420 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
422 if (!IS_CHIP_FEATURE(MIPS)) {
426 err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
427 (u32 *)(void *)&self->rpc,
428 (rpc_size + sizeof(u32) -
429 sizeof(u8)) / sizeof(u32));
433 sw.tid = 0xFFFFU & (++self->rpc_tid);
434 sw.len = (u16)rpc_size;
435 aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
441 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
442 struct hw_atl_utils_fw_rpc **rpc)
445 struct aq_hw_atl_utils_fw_rpc_tid_s sw;
446 struct aq_hw_atl_utils_fw_rpc_tid_s fw;
449 sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
451 self->rpc_tid = sw.tid;
453 AQ_HW_WAIT_FOR(sw.tid ==
455 aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
456 fw.tid), 1000U, 100U);
460 if (fw.len == 0xFFFFU) {
461 err = hw_atl_utils_fw_rpc_call(self, sw.len);
465 } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
472 hw_atl_utils_fw_downld_dwords(self,
476 (fw.len + sizeof(u32) -
490 static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
494 err = hw_atl_utils_init_ucp(self, self->aq_nic_cfg->aq_hw_caps);
498 err = hw_atl_utils_fw_rpc_init(self);
506 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
507 struct hw_atl_utils_mbox_header *pmbox)
509 return hw_atl_utils_fw_downld_dwords(self,
511 (u32 *)(void *)pmbox,
512 sizeof(*pmbox) / sizeof(u32));
515 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
516 struct hw_atl_utils_mbox *pmbox)
520 err = hw_atl_utils_fw_downld_dwords(self,
522 (u32 *)(void *)pmbox,
523 sizeof(*pmbox) / sizeof(u32));
527 if (IS_CHIP_FEATURE(REVISION_A0)) {
528 unsigned int mtu = self->aq_nic_cfg ?
529 self->aq_nic_cfg->mtu : 1514U;
530 pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
531 pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
532 pmbox->stats.dpc = atomic_read(&self->dpc);
534 pmbox->stats.dpc = hw_atl_reg_rx_dma_stat_counter7get(self);
540 static int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
542 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
544 val = val & ~HW_ATL_MPI_SPEED_MSK;
545 val |= speed << HW_ATL_MPI_SPEED_SHIFT;
546 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
551 static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
552 enum hal_atl_utils_fw_state_e state)
555 u32 transaction_id = 0;
556 struct hw_atl_utils_mbox_header mbox;
557 u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
559 if (state == MPI_RESET) {
560 hw_atl_utils_mpi_read_mbox(self, &mbox);
562 transaction_id = mbox.transaction_id;
564 AQ_HW_WAIT_FOR(transaction_id !=
565 (hw_atl_utils_mpi_read_mbox(self, &mbox),
566 mbox.transaction_id),
571 /* On interface DEINIT we disable DW (raise bit)
572 * Otherwise enable DW (clear bit)
574 if (state == MPI_DEINIT || state == MPI_POWER)
575 val |= HW_ATL_MPI_DIRTY_WAKE_MSK;
577 val &= ~HW_ATL_MPI_DIRTY_WAKE_MSK;
579 /* Set new state bits */
580 val = val & ~HW_ATL_MPI_STATE_MSK;
581 val |= state & HW_ATL_MPI_STATE_MSK;
583 aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
588 int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
590 u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
591 u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
592 struct aq_hw_link_status_s *link_status = &self->aq_link_status;
594 if (!link_speed_mask) {
595 link_status->mbps = 0U;
597 switch (link_speed_mask) {
598 case HAL_ATLANTIC_RATE_10G:
599 link_status->mbps = 10000U;
602 case HAL_ATLANTIC_RATE_5G:
603 case HAL_ATLANTIC_RATE_5GSR:
604 link_status->mbps = 5000U;
607 case HAL_ATLANTIC_RATE_2GS:
608 link_status->mbps = 2500U;
611 case HAL_ATLANTIC_RATE_1G:
612 link_status->mbps = 1000U;
615 case HAL_ATLANTIC_RATE_100M:
616 link_status->mbps = 100U;
627 int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
635 if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
636 unsigned int rnd = 0;
637 unsigned int ucp_0x370 = 0;
639 get_random_bytes(&rnd, sizeof(unsigned int));
641 ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
642 aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
645 err = hw_atl_utils_fw_downld_dwords(self,
646 aq_hw_read_reg(self, 0x00000374U) +
649 ARRAY_SIZE(mac_addr));
655 mac_addr[0] = __swab32(mac_addr[0]);
656 mac_addr[1] = __swab32(mac_addr[1]);
659 ether_addr_copy(mac, (u8 *)mac_addr);
661 if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
664 (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
668 mac[5] = (u8)(0xFFU & l);
670 mac[4] = (u8)(0xFFU & l);
672 mac[3] = (u8)(0xFFU & l);
674 mac[2] = (u8)(0xFFU & l);
675 mac[1] = (u8)(0xFFU & h);
677 mac[0] = (u8)(0xFFU & h);
683 unsigned int hw_atl_utils_mbps_2_speed_index(unsigned int mbps)
685 unsigned int ret = 0U;
714 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
716 u32 chip_features = 0U;
717 u32 val = hw_atl_reg_glb_mif_id_get(self);
718 u32 mif_rev = val & 0xFFU;
720 if ((0xFU & mif_rev) == 1U) {
721 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
722 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
723 HAL_ATLANTIC_UTILS_CHIP_MIPS;
724 } else if ((0xFU & mif_rev) == 2U) {
725 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
726 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
727 HAL_ATLANTIC_UTILS_CHIP_MIPS |
728 HAL_ATLANTIC_UTILS_CHIP_TPO2 |
729 HAL_ATLANTIC_UTILS_CHIP_RPF2;
730 } else if ((0xFU & mif_rev) == 0xAU) {
731 chip_features |= HAL_ATLANTIC_UTILS_CHIP_REVISION_B1 |
732 HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
733 HAL_ATLANTIC_UTILS_CHIP_MIPS |
734 HAL_ATLANTIC_UTILS_CHIP_TPO2 |
735 HAL_ATLANTIC_UTILS_CHIP_RPF2;
741 static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
743 hw_atl_utils_mpi_set_speed(self, 0);
744 hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
748 int hw_atl_utils_update_stats(struct aq_hw_s *self)
750 struct hw_atl_utils_mbox mbox;
752 hw_atl_utils_mpi_read_stats(self, &mbox);
754 #define AQ_SDELTA(_N_) (self->curr_stats._N_ += \
755 mbox.stats._N_ - self->last_stats._N_)
757 if (self->aq_link_status.mbps) {
777 self->curr_stats.dma_pkt_rc = hw_atl_stats_rx_dma_good_pkt_counterlsw_get(self);
778 self->curr_stats.dma_pkt_tc = hw_atl_stats_tx_dma_good_pkt_counterlsw_get(self);
779 self->curr_stats.dma_oct_rc = hw_atl_stats_rx_dma_good_octet_counterlsw_get(self);
780 self->curr_stats.dma_oct_tc = hw_atl_stats_tx_dma_good_octet_counterlsw_get(self);
782 memcpy(&self->last_stats, &mbox.stats, sizeof(mbox.stats));
787 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
789 return &self->curr_stats;
792 static const u32 hw_atl_utils_hw_mac_regs[] = {
793 0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
794 0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
795 0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
796 0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
797 0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
798 0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
799 0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
800 0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
801 0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
802 0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
803 0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
804 0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
805 0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
806 0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
807 0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
808 0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
809 0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
810 0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
811 0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
812 0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
813 0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
814 0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
817 int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
818 const struct aq_hw_caps_s *aq_hw_caps,
823 for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
824 regs_buff[i] = aq_hw_read_reg(self,
825 hw_atl_utils_hw_mac_regs[i]);
829 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
831 *fw_version = aq_hw_read_reg(self, 0x18U);
835 static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
837 struct hw_atl_utils_fw_rpc *prpc = NULL;
838 unsigned int rpc_size = 0U;
841 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
845 memset(prpc, 0, sizeof(*prpc));
848 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
850 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
851 prpc->msg_wol.priority =
852 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
853 prpc->msg_wol.pattern_id =
854 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
855 prpc->msg_wol.wol_packet_type =
856 HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
858 ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
860 rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
862 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
863 prpc->msg_wol.pattern_id =
864 HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
867 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
873 static int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
876 struct hw_atl_utils_fw_rpc *prpc = NULL;
877 unsigned int rpc_size = 0U;
880 if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
881 err = aq_fw1x_set_wol(self, 1, mac);
886 rpc_size = sizeof(prpc->msg_id) +
887 sizeof(prpc->msg_enable_wakeup);
889 err = hw_atl_utils_fw_rpc_wait(self, &prpc);
894 memset(prpc, 0, rpc_size);
896 prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
897 prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
899 err = hw_atl_utils_fw_rpc_call(self, rpc_size);
903 hw_atl_utils_mpi_set_speed(self, 0);
904 hw_atl_utils_mpi_set_state(self, MPI_POWER);
910 const struct aq_fw_ops aq_fw_1x_ops = {
911 .init = hw_atl_utils_mpi_create,
912 .deinit = hw_atl_fw1x_deinit,
914 .get_mac_permanent = hw_atl_utils_get_mac_permanent,
915 .set_link_speed = hw_atl_utils_mpi_set_speed,
916 .set_state = hw_atl_utils_mpi_set_state,
917 .update_link_status = hw_atl_utils_mpi_get_link_status,
918 .update_stats = hw_atl_utils_update_stats,
919 .set_power = aq_fw1x_set_power,
920 .set_eee_rate = NULL,
921 .get_eee_rate = NULL,
922 .set_flow_control = NULL,