Add common functions for Atlantic hardware abstraction layer.

Signed-off-by: Dmitrii Tarakanov <dmitrii.taraka...@aquantia.com>
Signed-off-by: Alexander Loktionov <alexander.loktio...@aquantia.com>
Signed-off-by: David M. VomLehn <voml...@texas.net>
---
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        | 545 +++++++++++++++++++++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        | 214 ++++++++
 2 files changed, 759 insertions(+)
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
 create mode 100644 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
new file mode 100644
index 0000000..42ca100
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -0,0 +1,545 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File hw_atl_utils.c: Definition of common functions for Atlantic hardware
+ * abstraction layer.
+ */
+
+#include "../aq_hw.h"
+#include "../aq_hw_utils.h"
+#include "../aq_pci_func.h"
+#include "../aq_ring.h"
+#include "../aq_vec.h"
+#include "hw_atl_utils.h"
+#include "hw_atl_llh.h"
+
+#include <linux/random.h>
+
+#define HW_ATL_UCP_0X370_REG    0x0370U
+
+#define HW_ATL_FW_SM_RAM        0x2U
+#define HW_ATL_MPI_CONTROL_ADR  0x0368U
+#define HW_ATL_MPI_STATE_ADR    0x036CU
+
+#define HW_ATL_MPI_STATE_MSK    0x00FFU
+#define HW_ATL_MPI_STATE_SHIFT  0U
+#define HW_ATL_MPI_SPEED_MSK    0xFFFFU
+#define HW_ATL_MPI_SPEED_SHIFT  16U
+
+int hw_atl_utils_fw_download_dwords(struct aq_hw_s *self, u32 a, u32 *p,
+                                   u32 cnt)
+{
+       int err = 0;
+
+       AQ_HW_WAIT_FOR(reg_glb_cpu_sem_get(self,
+                                          HW_ATL_FW_SM_RAM) == 1U, 1U, 1000U);
+
+       if (err < 0) {
+               bool is_locked;
+
+               reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+               is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+               if (!(is_locked)) {
+                       err = ETIME;
+                       goto err_exit;
+               }
+       }
+
+       aq_hw_write_reg(self, 0x00000208U, a);
+
+       for (++cnt; --cnt;) {
+               u32 i = 0U;
+
+               aq_hw_write_reg(self, 0x00000200U, 0x00008000U);
+
+               for (i = 1024U;
+                       (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
+               }
+
+               *(p++) = aq_hw_read_reg(self, 0x0000020CU);
+       }
+
+       reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+
+err_exit:
+       return err;
+}
+
+void hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
+                                  u32 cnt)
+{
+       int err = 0;
+       bool is_locked;
+
+       is_locked = reg_glb_cpu_sem_get(self, HW_ATL_FW_SM_RAM);
+       if (!(is_locked)) {
+               err = ETIME;
+               goto err_exit;
+       }
+
+       aq_hw_write_reg(self, 0x00000208U, a);
+
+       for (++cnt; --cnt;) {
+               u32 i = 0U;
+
+               aq_hw_write_reg(self, 0x0000020CU, *(p++));
+               aq_hw_write_reg(self, 0x00000200U, 0xC000U);
+
+               for (i = 1024U;
+                       (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
+               }
+       }
+
+       reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
+
+err_exit:;
+       (void)err;
+}
+
+int hw_atl_utils_init_ucp(struct aq_hw_s *self)
+{
+       int err = 0;
+
+       if (!aq_hw_read_reg(self, 0x370U)) {
+               unsigned int rnd = 0U;
+               unsigned int ucp_0x370 = 0U;
+
+               get_random_bytes(&rnd, sizeof(unsigned int));
+
+               ucp_0x370 = 0x02020202U | (0xFEFEFEFEU & rnd);
+               aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
+       }
+
+       reg_glb_cpu_scratch_scp_set(self, 0x00000000U, 25U);
+
+       /* check 10 times by 1ms */
+       AQ_HW_WAIT_FOR(0U != (PHAL_ATLANTIC_A0->mbox_addr =
+                       aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
+
+       return err;
+}
+
+#define HW_ATL_RPC_CONTROL_ADR 0x0338U
+#define HW_ATL_RPC_STATE_ADR   0x033CU
+
+struct aq_hw_atl_utils_fw_rpc_tid_s {
+       union {
+               u32 val;
+               struct {
+                       u16 tid;
+                       u16 len;
+               };
+       };
+};
+
+#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
+
+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
+{
+       int err = 0;
+       struct aq_hw_atl_utils_fw_rpc_tid_s sw;
+
+       if (!(IS_CHIP_FEATURE(MIPS))) {
+               err = -1;
+               goto err_exit;
+       }
+       hw_atl_utils_fw_upload_dwords(self, PHAL_ATLANTIC->rpc_addr,
+                                     (u32 *)(void *)&PHAL_ATLANTIC->rpc,
+                                     (rpc_size + sizeof(u32) -
+                                     sizeof(u8)) / sizeof(u32));
+
+       sw.tid = 0xFFFFU & (++PHAL_ATLANTIC->rpc_tid);
+       sw.len = (u16)rpc_size;
+       aq_hw_write_reg(self, HW_ATL_RPC_CONTROL_ADR, sw.val);
+
+err_exit:
+       return err;
+}
+
+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
+                            struct hw_aq_atl_utils_fw_rpc **rpc)
+{
+       int err = 0;
+       struct aq_hw_atl_utils_fw_rpc_tid_s sw;
+       struct aq_hw_atl_utils_fw_rpc_tid_s fw;
+
+       if (IS_CHIP_FEATURE(MIPS)) {
+               if (rpc) {
+                       PHAL_ATLANTIC->rpc.msg_id = 0U;
+                       *rpc = &PHAL_ATLANTIC->rpc;
+               }
+               goto err_exit;
+       }
+
+       do {
+               sw.val = aq_hw_read_reg(self, HW_ATL_RPC_CONTROL_ADR);
+
+               PHAL_ATLANTIC->rpc_tid = sw.tid;
+
+               AQ_HW_WAIT_FOR(sw.tid ==
+                               (fw.val =
+                               aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
+                               fw.tid), 10000U, 10U);
+               if (err < 0)
+                       goto err_exit;
+
+               if (fw.len == 0xFFFFU) {
+                       err = hw_atl_utils_fw_rpc_call(self, sw.len);
+                       if (err < 0)
+                               goto err_exit;
+               }
+       } while (sw.tid != fw.tid || 0xFFFFU == fw.len);
+       if (err < 0)
+               goto err_exit;
+
+       if (rpc) {
+               if (fw.len)
+                       hw_atl_utils_fw_download_dwords(self,
+                               PHAL_ATLANTIC->rpc_addr,
+                               (u32 *)(void *)&PHAL_ATLANTIC->rpc,
+                               (fw.len + sizeof(u32) - sizeof(u8)) /
+                                       sizeof(u32));
+
+               *rpc = &PHAL_ATLANTIC->rpc;
+       }
+
+err_exit:
+       return err;
+}
+
+int hw_atl_utils_mpi_create(struct aq_hw_s *self)
+{
+       int err = 0;
+
+       err = hw_atl_utils_init_ucp(self);
+       if (err < 0)
+               goto err_exit;
+
+       err = hw_atl_utils_fw_rpc_init(self);
+       if (err < 0)
+               goto err_exit;
+
+err_exit:
+       return err;
+}
+
+void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
+                                struct hw_aq_atl_utils_mbox *pmbox)
+{
+       int err = 0;
+
+       err = hw_atl_utils_fw_download_dwords(self,
+                                             PHAL_ATLANTIC->mbox_addr,
+                                             (u32 *)(void *)pmbox,
+                                             sizeof(*pmbox) / sizeof(u32));
+       if (err < 0)
+               goto err_exit;
+
+       if (pmbox != &PHAL_ATLANTIC->mbox)
+               memcpy(pmbox, &PHAL_ATLANTIC->mbox, sizeof(*pmbox));
+
+       if (IS_CHIP_FEATURE(REVISION_A0)) {
+               unsigned int mtu = self->aq_nic_cfg ?
+                                       self->aq_nic_cfg->mtu : 1514U;
+               pmbox->stats.ubrc = pmbox->stats.uprc * mtu;
+               pmbox->stats.ubtc = pmbox->stats.uptc * mtu;
+               pmbox->stats.dpc = atomic_read(&PHAL_ATLANTIC_A0->dpc);
+       } else {
+               pmbox->stats.dpc = reg_rx_dma_stat_counter7get(self);
+       }
+
+err_exit:;
+}
+
+int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
+                              enum hal_atl_utils_fw_state_e state)
+{
+       u32 ucp_0x368 = 0;
+
+       ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
+       aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
+
+       return 0;
+}
+
+void hw_atl_utils_mpi_set(struct aq_hw_s *self,
+                         enum hal_atl_utils_fw_state_e state, u32 speed)
+{
+       int err = 0;
+       u32 transaction_id = 0;
+
+       if (state == MPI_RESET) {
+               hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
+
+               transaction_id = PHAL_ATLANTIC->mbox.transaction_id;
+
+               AQ_HW_WAIT_FOR(transaction_id !=
+                               (hw_atl_utils_mpi_read_stats
+                                       (self, &PHAL_ATLANTIC->mbox),
+                                       PHAL_ATLANTIC->mbox.transaction_id),
+                                       1000, 10);
+               if (err < 0)
+                       goto err_exit;
+       }
+
+       err = hw_atl_utils_mpi_set_speed(self, speed, state);
+
+err_exit:;
+}
+
+int hw_atl_utils_mpi_get_link_state(struct aq_hw_s *self,
+                                   struct aq_hw_link_status_s *link_status)
+{
+       u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
+       u32 link_speed_mask = cp0x036C >> HW_ATL_MPI_SPEED_SHIFT;
+
+       if (!link_speed_mask) {
+               link_status->bps = 0U;
+       } else {
+               u64 link_speed;
+
+               switch (link_speed_mask) {
+               case HAL_ATLANTIC_RATE_10G:
+                       link_speed = 10 * GBIT;
+                       break;
+
+               case HAL_ATLANTIC_RATE_5G:
+               case HAL_ATLANTIC_RATE_5GSR:
+                       link_speed = 5 * GBIT;
+                       break;
+
+               case HAL_ATLANTIC_RATE_2GS:
+                       link_speed = 2500 * MBIT;
+                       break;
+
+               case HAL_ATLANTIC_RATE_1G:
+                       link_speed = 1 * GBIT;
+                       break;
+
+               case HAL_ATLANTIC_RATE_100M:
+                       link_speed = 100 * MBIT;
+                       break;
+
+               default:
+                       link_speed = 0U;
+                       break;
+               }
+
+               link_status->bps = link_speed;
+       }
+
+       return 0;
+}
+
+int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
+{
+       int err = 0;
+       u32 h = 0U;
+       u32 l = 0U;
+       u32 mac_addr[2];
+
+       self->mmio = aq_pci_func_get_mmio(self->aq_pci_func);
+
+       hw_atl_utils_hw_chip_features_init((struct aq_hw_s *)self,
+                                          &PHAL_ATLANTIC_A0->chip_features);
+
+       err = hw_atl_utils_mpi_create((struct aq_hw_s *)self);
+       if (err < 0)
+               goto err_exit;
+
+       if (!aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) {
+               unsigned int rnd = 0;
+               unsigned int ucp_0x370 = 0;
+
+               get_random_bytes(&rnd, sizeof(unsigned int));
+
+               ucp_0x370 = 0x02020202 | (0xFEFEFEFE & rnd);
+               aq_hw_write_reg(self, HW_ATL_UCP_0X370_REG, ucp_0x370);
+       }
+
+       hw_atl_utils_fw_download_dwords(self,
+                                       aq_hw_read_reg(self, 0x00000374U) +
+                                       (40U * 4U),
+                                       mac_addr,
+                                       AQ_DIMOF(mac_addr));
+       mac_addr[0] = cpu_to_be32(mac_addr[0]);
+       mac_addr[1] = cpu_to_be32(mac_addr[1]);
+
+       ether_addr_copy(mac, (u8 *)mac_addr);
+
+       if ((mac[0] != 0x00) || (mac[1] != 0x17) || (mac[2] != 0xB6)) {
+               /* chip revision */
+               l = 0xE3000000U
+                       | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
+                       | (0x00 << 16);
+               h = 0x8001300EU;
+
+               mac[5] = (u8)(0xFFU & l);
+               l >>= 8;
+               mac[4] = (u8)(0xFFU & l);
+               l >>= 8;
+               mac[3] = (u8)(0xFFU & l);
+               l >>= 8;
+               mac[2] = (u8)(0xFFU & l);
+               mac[1] = (u8)(0xFFU & h);
+               h >>= 8;
+               mac[0] = (u8)(0xFFU & h);
+       }
+
+err_exit:
+       return err;
+}
+
+int hw_atl_utils_bps_2_speed_index(u64 bps)
+{
+       unsigned int ret = 0U;
+
+       switch (bps) {
+       case 100 * MBIT:
+               ret = 5U;
+               break;
+
+       case 1 * GBIT:
+               ret = 4U;
+               break;
+
+       case 2500 * MBIT:
+               ret = 3U;
+               break;
+
+       case 5 * GBIT:
+               ret = 1U;
+               break;
+
+       case 10 * GBIT:
+               ret = 0U;
+               break;
+
+       default:
+               break;
+       }
+       return ret;
+}
+
+void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p)
+{
+       u32 chip_features = 0U;
+       u32 val = reg_glb_mif_id_get(self);
+       u32 mif_rev = val & 0xFFU;
+
+       if ((3U & mif_rev) == 1U) {
+               chip_features |=
+                       HAL_ATLANTIC_UTILS_CHIP_REVISION_A0 |
+                       HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
+                       HAL_ATLANTIC_UTILS_CHIP_MIPS;
+       } else if ((3U & mif_rev) == 2U)
+               chip_features |=
+                       HAL_ATLANTIC_UTILS_CHIP_REVISION_B0 |
+                       HAL_ATLANTIC_UTILS_CHIP_MPI_AQ |
+                       HAL_ATLANTIC_UTILS_CHIP_MIPS |
+                       HAL_ATLANTIC_UTILS_CHIP_TPO2 |
+                       HAL_ATLANTIC_UTILS_CHIP_RPF2;
+       *p = chip_features;
+}
+
+int hw_atl_utils_hw_deinit(struct aq_hw_s *self)
+{
+       hw_atl_utils_mpi_set(self, MPI_DEINIT, 0x0U);
+       return 0;
+}
+
+int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
+                             unsigned int power_state)
+{
+       hw_atl_utils_mpi_set(self, MPI_POWER, 0x0U);
+       return 0;
+}
+
+int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
+                             u64 *data, unsigned int *p_count)
+{
+       struct hw_atl_stats_s *stats = NULL;
+       int i = 0;
+
+       hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox);
+
+       stats = &PHAL_ATLANTIC->mbox.stats;
+
+       data[i] = stats->uprc + stats->mprc + stats->bprc;
+       data[++i] = stats->uprc;
+       data[++i] = stats->mprc;
+       data[++i] = stats->bprc;
+       data[++i] = stats->erpt;
+       data[++i] = stats->uptc + stats->mptc + stats->bptc;
+       data[++i] = stats->uptc;
+       data[++i] = stats->mptc;
+       data[++i] = stats->bptc;
+       data[++i] = stats->ubrc;
+       data[++i] = stats->ubtc;
+       data[++i] = stats->mbrc;
+       data[++i] = stats->mbtc;
+       data[++i] = stats->bbrc;
+       data[++i] = stats->bbtc;
+       data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
+       data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
+       data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self);
+       data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self);
+       data[++i] = stats_rx_dma_good_octet_counterlsw_get(self);
+       data[++i] = stats_tx_dma_good_octet_counterlsw_get(self);
+       data[++i] = stats->dpc;
+
+       if (p_count)
+               *p_count = ++i;
+
+       return 0;
+}
+
+static const u32 hw_atl_utils_hw_mac_regs[] = {
+       0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
+       0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
+       0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
+       0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
+       0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
+       0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
+       0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
+       0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
+       0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
+       0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
+       0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
+       0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
+       0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
+       0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
+       0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
+       0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
+       0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
+       0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
+       0x00007CE0U, 0x00000300U, 0x00000304U, 0x00000308U,
+       0x0000030cU, 0x00000310U, 0x00000314U, 0x00000318U,
+       0x0000031cU, 0x00000360U, 0x00000364U, 0x00000368U,
+       0x0000036cU, 0x00000370U, 0x00000374U, 0x00006900U,
+};
+
+int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
+                            struct aq_hw_caps_s *aq_hw_caps,
+                            u32 *regs_buff)
+{
+       unsigned int i = 0U;
+
+       for (i = 0; i < aq_hw_caps->mac_regs_count; i++)
+               regs_buff[i] = aq_hw_read_reg(self,
+                       hw_atl_utils_hw_mac_regs[i]);
+       return 0;
+}
+
+int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
+{
+       *fw_version = aq_hw_read_reg(self, 0x18U);
+       return 0;
+}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h 
b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
new file mode 100644
index 0000000..aa5550f
--- /dev/null
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -0,0 +1,214 @@
+/*
+ * Aquantia Corporation Network Driver
+ * Copyright (C) 2014-2016 Aquantia Corporation. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+/*
+ * File hw_atl_utils.h: Declaration of common functions for Atlantic hardware
+ * abstraction layer.
+ */
+
+#ifndef HW_ATL_UTILS_H
+#define HW_ATL_UTILS_H
+
+#include "../aq_common.h"
+
+#define HW_ATL_FLUSH() { (void)aq_hw_read_reg(self, 0x10); }
+
+struct __packed hw_atl_stats_s {
+       u32 uprc;
+       u32 mprc;
+       u32 bprc;
+       u32 erpt;
+       u32 uptc;
+       u32 mptc;
+       u32 bptc;
+       u32 erpr;
+       u32 mbtc;
+       u32 bbtc;
+       u32 mbrc;
+       u32 bbrc;
+       u32 ubrc;
+       u32 ubtc;
+       u32 dpc;
+};
+
+union __packed ip_addr {
+       struct {
+               u8 addr[16];
+       } v6;
+       struct {
+               u8 padding[12];
+               u8 addr[4];
+       } v4;
+};
+
+struct __packed hw_aq_atl_utils_fw_rpc {
+       u32 msg_id;
+
+       union {
+               struct {
+                       u32 pong;
+               } msg_ping;
+
+               struct {
+                       u8 mac_addr[6];
+                       u32 ip_addr_cnt;
+
+                       struct {
+                               union ip_addr addr;
+                               union ip_addr mask;
+                       } ip[1];
+               } msg_arp;
+
+               struct {
+                       u32 len;
+                       u8 packet[1514U];
+               } msg_inject;
+
+               struct {
+                       u32 priority;
+                       u32 wol_packet_type;
+                       u16 friendly_name_len;
+                       u16 friendly_name[65];
+                       u32 pattern_id;
+                       u32 next_wol_pattern_offset;
+
+                       union {
+                               struct {
+                                       u32 flags;
+                                       u8 ipv4_source_address[4];
+                                       u8 ipv4_dest_address[4];
+                                       u16 tcp_source_port_number;
+                                       u16 tcp_dest_port_number;
+                               } ipv4_tcp_syn_parameters;
+
+                               struct {
+                                       u32 flags;
+                                       u8 ipv6_source_address[16];
+                                       u8 ipv6_dest_address[16];
+                                       u16 tcp_source_port_number;
+                                       u16 tcp_dest_port_number;
+                               } ipv6_tcp_syn_parameters;
+
+                               struct {
+                                       u32 flags;
+                               } eapol_request_id_message_parameters;
+
+                               struct {
+                                       u32 flags;
+                                       u32 mask_offset;
+                                       u32 mask_size;
+                                       u32 pattern_offset;
+                                       u32 pattern_size;
+                               } wol_bit_map_pattern;
+                       } wol_pattern;
+               } msg_wol;
+
+               struct {
+                       u32 is_wake_on_link_down;
+                       u32 is_wake_on_link_up;
+               } msg_wolink;
+       };
+};
+
+struct __packed hw_aq_atl_utils_mbox {
+       u32 version;
+       u32 transaction_id;
+       int error;
+       struct hw_atl_stats_s stats;
+};
+
+struct __packed hw_atl_s {
+       struct aq_hw_s base;
+       struct hw_aq_atl_utils_mbox mbox;
+       u64 speed;
+       u32 itr_tx;
+       u32 itr_rx;
+       unsigned int chip_features;
+       u32 fw_ver_actual;
+       atomic_t dpc;
+       u32 mbox_addr;
+       u32 rpc_addr;
+       u32 rpc_tid;
+       struct hw_aq_atl_utils_fw_rpc rpc;
+};
+
+#define SELF ((struct hw_atl_s *)self)
+
+#define PHAL_ATLANTIC ((struct hw_atl_s *)((void *)(self)))
+#define PHAL_ATLANTIC_A0 ((struct hw_atl_s *)((void *)(self)))
+
+#define HAL_ATLANTIC_UTILS_CHIP_MIPS         0x00000001U
+#define HAL_ATLANTIC_UTILS_CHIP_TPO2         0x00000002U
+#define HAL_ATLANTIC_UTILS_CHIP_RPF2         0x00000004U
+#define HAL_ATLANTIC_UTILS_CHIP_MPI_AQ       0x00000010U
+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_A0  0x01000000U
+#define HAL_ATLANTIC_UTILS_CHIP_REVISION_B0  0x02000000U
+
+#define IS_CHIP_FEATURE(_F_) (HAL_ATLANTIC_UTILS_CHIP_##_F_ & \
+                               PHAL_ATLANTIC->chip_features)
+
+enum hal_atl_utils_fw_state_e {
+       MPI_DEINIT = 0,
+       MPI_RESET = 1,
+       MPI_INIT = 2,
+       MPI_POWER = 4,
+};
+
+#define HAL_ATLANTIC_RATE_10G        BIT(0)
+#define HAL_ATLANTIC_RATE_5G         BIT(1)
+#define HAL_ATLANTIC_RATE_5GSR       BIT(2)
+#define HAL_ATLANTIC_RATE_2GS        BIT(3)
+#define HAL_ATLANTIC_RATE_1G         BIT(4)
+#define HAL_ATLANTIC_RATE_100M       BIT(5)
+#define HAL_ATLANTIC_RATE_INVALID    BIT(6)
+
+int hw_atl_utils_mpi_create(struct aq_hw_s *self);
+
+void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);
+
+int hw_atl_fw_download_dwords(struct aq_hw_s *self, u32 a, u32 *p, u32 cnt);
+
+void hw_atl_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, u32 cnt);
+
+void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
+                                struct hw_aq_atl_utils_mbox *pmbox);
+
+void hw_atl_utils_mpi_set(struct aq_hw_s *self,
+                         enum hal_atl_utils_fw_state_e state,
+                         u32 speed);
+
+int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed,
+                              enum hal_atl_utils_fw_state_e state);
+
+int hw_atl_utils_mpi_get_link_state(struct aq_hw_s *self,
+                                   struct aq_hw_link_status_s *link_status);
+
+int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self, u8 *mac);
+
+int hw_atl_utils_bps_2_speed_index(u64 bps);
+
+int hw_atl_utils_hw_get_regs(struct aq_hw_s *self,
+                            struct aq_hw_caps_s *aq_hw_caps,
+                            u32 *regs_buff);
+
+int hw_atl_utils_hw_get_settings(struct aq_hw_s *self,
+                                struct ethtool_cmd *cmd);
+
+int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
+                             unsigned int power_state);
+
+int hw_atl_utils_hw_deinit(struct aq_hw_s *self);
+
+int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);
+
+int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
+                             u64 *data,
+                             unsigned int *p_count);
+
+#endif /* HW_ATL_UTILS_H */
-- 
2.7.4

Reply via email to