summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/aquantia/atlantic/hw_atl
diff options
context:
space:
mode:
authorIgor Russkikh <igor.russkikh@aquantia.com>2018-01-19 17:03:24 +0300
committerDavid S. Miller <davem@davemloft.net>2018-01-21 18:19:03 -0500
commit0c58c35f02c2e99bb10137b32e8ec96dcbdcc705 (patch)
tree4bd8efa8d6b9a52a297bdce7d2fa0edeeff3678a /drivers/net/ethernet/aquantia/atlantic/hw_atl
parent76c19c6cfa8f7e4f8c7d5407f77237b80095e5d9 (diff)
net: aquantia: Introduce firmware ops callbacks
New AQC cards will have an updated firmware with new binary interface. This patch extracts firmware specific operations into a separate table and prepares for the introduction of new fw 2.x and 3.x Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/aquantia/atlantic/hw_atl')
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c23
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c23
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c81
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h10
4 files changed, 71 insertions, 66 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 52f2eb543ee4..67e2f9fb9402 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -105,7 +105,7 @@ static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
if (err < 0)
goto err_exit;
- hw_atl_utils_mpi_set(self, MPI_RESET, 0x0U);
+ self->aq_fw_ops->set_state(self, MPI_RESET);
err = aq_hw_err_from_flags(self);
@@ -354,7 +354,8 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
hw_atl_a0_hw_mac_addr_set(self, mac_addr);
- hw_atl_utils_mpi_set(self, MPI_INIT, aq_nic_cfg->link_speed_msk);
+ self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
+ self->aq_fw_ops->set_state(self, MPI_INIT);
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x800000b8U);
hw_atl_reg_tx_dma_debug_ctl_set(self, 0x000000b8U);
@@ -365,7 +366,7 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
/* Reset link status and read out initial hardware counters */
self->aq_link_status.mbps = 0;
- hw_atl_utils_update_stats(self);
+ self->aq_fw_ops->update_stats(self);
err = aq_hw_err_from_flags(self);
if (err < 0)
@@ -871,23 +872,8 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
return aq_hw_err_from_flags(self);
}
-static int hw_atl_a0_hw_set_speed(struct aq_hw_s *self, u32 speed)
-{
- int err = 0;
-
- err = hw_atl_utils_mpi_set_speed(self, speed, MPI_INIT);
- if (err < 0)
- goto err_exit;
-
-err_exit:
- return err;
-}
-
const struct aq_hw_ops hw_atl_ops_a0 = {
- .hw_get_mac_permanent = hw_atl_utils_get_mac_permanent,
.hw_set_mac_address = hw_atl_a0_hw_mac_addr_set,
- .hw_get_link_status = hw_atl_utils_mpi_get_link_status,
- .hw_set_link_speed = hw_atl_a0_hw_set_speed,
.hw_init = hw_atl_a0_hw_init,
.hw_deinit = hw_atl_utils_hw_deinit,
.hw_set_power = hw_atl_utils_hw_set_power,
@@ -917,7 +903,6 @@ const struct aq_hw_ops hw_atl_ops_a0 = {
.hw_rss_set = hw_atl_a0_hw_rss_set,
.hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set,
.hw_get_regs = hw_atl_utils_hw_get_regs,
- .hw_update_stats = hw_atl_utils_update_stats,
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
.hw_get_fw_version = hw_atl_utils_get_fw_version,
};
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index f601230166ee..29abbc2588c6 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -108,7 +108,7 @@ static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
if (err < 0)
goto err_exit;
- hw_atl_utils_mpi_set(self, MPI_RESET, 0x0U);
+ self->aq_fw_ops->set_state(self, MPI_RESET);
err = aq_hw_err_from_flags(self);
@@ -403,7 +403,8 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
hw_atl_b0_hw_mac_addr_set(self, mac_addr);
- hw_atl_utils_mpi_set(self, MPI_INIT, aq_nic_cfg->link_speed_msk);
+ self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
+ self->aq_fw_ops->set_state(self, MPI_INIT);
hw_atl_b0_hw_qos_set(self);
hw_atl_b0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
@@ -422,7 +423,7 @@ static int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr)
/* Reset link status and read out initial hardware counters */
self->aq_link_status.mbps = 0;
- hw_atl_utils_update_stats(self);
+ self->aq_fw_ops->update_stats(self);
err = aq_hw_err_from_flags(self);
if (err < 0)
@@ -947,23 +948,8 @@ static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
return aq_hw_err_from_flags(self);
}
-static int hw_atl_b0_hw_set_speed(struct aq_hw_s *self, u32 speed)
-{
- int err = 0;
-
- err = hw_atl_utils_mpi_set_speed(self, speed, MPI_INIT);
- if (err < 0)
- goto err_exit;
-
-err_exit:
- return err;
-}
-
const struct aq_hw_ops hw_atl_ops_b0 = {
- .hw_get_mac_permanent = hw_atl_utils_get_mac_permanent,
.hw_set_mac_address = hw_atl_b0_hw_mac_addr_set,
- .hw_get_link_status = hw_atl_utils_mpi_get_link_status,
- .hw_set_link_speed = hw_atl_b0_hw_set_speed,
.hw_init = hw_atl_b0_hw_init,
.hw_deinit = hw_atl_utils_hw_deinit,
.hw_set_power = hw_atl_utils_hw_set_power,
@@ -993,7 +979,6 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
.hw_rss_set = hw_atl_b0_hw_rss_set,
.hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set,
.hw_get_regs = hw_atl_utils_hw_get_regs,
- .hw_update_stats = hw_atl_utils_update_stats,
.hw_get_hw_stats = hw_atl_utils_get_hw_stats,
.hw_get_fw_version = hw_atl_utils_get_fw_version,
};
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
index f4418c7da9dc..616475ea5b2f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -13,23 +13,49 @@
#include "../aq_nic.h"
#include "../aq_hw_utils.h"
-#include "../aq_pci_func.h"
#include "hw_atl_utils.h"
#include "hw_atl_llh.h"
+#include "hw_atl_llh_internal.h"
#include <linux/random.h>
#define HW_ATL_UCP_0X370_REG 0x0370U
#define HW_ATL_FW_SM_RAM 0x2U
+#define HW_ATL_MPI_FW_VERSION 0x18
#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_MSK 0xFFFF0000U
#define HW_ATL_MPI_SPEED_SHIFT 16U
+#define HW_ATL_FW_VER_1X 0x01050006U
+
+static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
+
+int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
+{
+ int err = 0;
+
+ hw_atl_utils_hw_chip_features_init(self,
+ &self->chip_features);
+
+ hw_atl_utils_get_fw_version(self, &self->fw_ver_actual);
+
+ if (hw_atl_utils_ver_match(HW_ATL_FW_VER_1X, self->fw_ver_actual) == 0)
+ *fw_ops = &aq_fw_1x_ops;
+ else {
+ aq_pr_err("Bad FW version detected: %x\n",
+ self->fw_ver_actual);
+ return -EOPNOTSUPP;
+ }
+ self->aq_fw_ops = *fw_ops;
+ err = self->aq_fw_ops->init(self);
+ return err;
+}
+
static int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
u32 *p, u32 cnt)
{
@@ -137,14 +163,6 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
- err = hw_atl_utils_ver_match(aq_hw_caps->fw_ver_expected,
- aq_hw_read_reg(self, 0x18U));
-
- if (err < 0)
- pr_err("%s: Bad FW version detected: expected=%x, actual=%x\n",
- AQ_CFG_DRV_NAME,
- aq_hw_caps->fw_ver_expected,
- aq_hw_read_reg(self, 0x18U));
return err;
}
@@ -286,19 +304,19 @@ void hw_atl_utils_mpi_read_stats(struct aq_hw_s *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)
+int hw_atl_utils_mpi_set_speed(struct aq_hw_s *self, u32 speed)
{
- u32 ucp_0x368 = 0;
+ u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
- ucp_0x368 = (speed << HW_ATL_MPI_SPEED_SHIFT) | state;
- aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, ucp_0x368);
+ val = (val & HW_ATL_MPI_STATE_MSK) | (speed << HW_ATL_MPI_SPEED_SHIFT);
+ aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
return 0;
}
void hw_atl_utils_mpi_set(struct aq_hw_s *self,
- enum hal_atl_utils_fw_state_e state, u32 speed)
+ enum hal_atl_utils_fw_state_e state,
+ u32 speed)
{
int err = 0;
u32 transaction_id = 0;
@@ -317,11 +335,22 @@ void hw_atl_utils_mpi_set(struct aq_hw_s *self,
goto err_exit;
}
- err = hw_atl_utils_mpi_set_speed(self, speed, state);
+ aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR,
+ (speed << HW_ATL_MPI_SPEED_SHIFT) | state);
err_exit:;
}
+static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
+ enum hal_atl_utils_fw_state_e state)
+{
+ u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
+
+ val = state | (val & HW_ATL_MPI_SPEED_MSK);
+ aq_hw_write_reg(self, HW_ATL_MPI_CONTROL_ADR, val);
+ return 0;
+}
+
int hw_atl_utils_mpi_get_link_status(struct aq_hw_s *self)
{
u32 cp0x036C = aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR);
@@ -369,13 +398,6 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
u32 l = 0U;
u32 mac_addr[2];
- hw_atl_utils_hw_chip_features_init(self,
- &self->chip_features);
-
- err = hw_atl_utils_mpi_create(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;
@@ -421,7 +443,6 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
mac[0] = (u8)(0xFFU & h);
}
-err_exit:
return err;
}
@@ -578,3 +599,13 @@ 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;
}
+
+const struct aq_fw_ops aq_fw_1x_ops = {
+ .init = hw_atl_utils_mpi_create,
+ .reset = NULL,
+ .get_mac_permanent = hw_atl_utils_get_mac_permanent,
+ .set_link_speed = hw_atl_utils_mpi_set_speed,
+ .set_state = hw_atl_utils_mpi_set_state,
+ .update_link_status = hw_atl_utils_mpi_get_link_status,
+ .update_stats = hw_atl_utils_update_stats,
+};
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
index 40e2319c65d5..d6d05e5eb939 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -181,9 +181,14 @@ enum hal_atl_utils_fw_state_e {
#define HAL_ATLANTIC_RATE_INVALID BIT(6)
struct aq_hw_s;
+struct aq_fw_ops;
struct aq_hw_caps_s;
struct aq_hw_link_status_s;
+int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops);
+
+int hw_atl_utils_soft_reset(struct aq_hw_s *self);
+
void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);
int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
@@ -196,9 +201,6 @@ 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_status(struct aq_hw_s *self);
int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
@@ -221,4 +223,6 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self);
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
+extern const struct aq_fw_ops aq_fw_1x_ops;
+
#endif /* HW_ATL_UTILS_H */