|
@@ -49,6 +49,7 @@
|
|
#define FORCE_FLASHLESS 0
|
|
#define FORCE_FLASHLESS 0
|
|
|
|
|
|
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
|
|
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual);
|
|
|
|
+
|
|
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
|
|
static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
|
|
enum hal_atl_utils_fw_state_e state);
|
|
enum hal_atl_utils_fw_state_e state);
|
|
|
|
|
|
@@ -69,10 +70,10 @@ int hw_atl_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)
|
|
self->fw_ver_actual) == 0) {
|
|
self->fw_ver_actual) == 0) {
|
|
*fw_ops = &aq_fw_1x_ops;
|
|
*fw_ops = &aq_fw_1x_ops;
|
|
} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
|
|
} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_2X,
|
|
- self->fw_ver_actual) == 0) {
|
|
|
|
|
|
+ self->fw_ver_actual) == 0) {
|
|
*fw_ops = &aq_fw_2x_ops;
|
|
*fw_ops = &aq_fw_2x_ops;
|
|
} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
|
|
} else if (hw_atl_utils_ver_match(HW_ATL_FW_VER_3X,
|
|
- self->fw_ver_actual) == 0) {
|
|
|
|
|
|
+ self->fw_ver_actual) == 0) {
|
|
*fw_ops = &aq_fw_2x_ops;
|
|
*fw_ops = &aq_fw_2x_ops;
|
|
} else {
|
|
} else {
|
|
aq_pr_err("Bad FW version detected: %x\n",
|
|
aq_pr_err("Bad FW version detected: %x\n",
|
|
@@ -260,7 +261,7 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self)
|
|
|
|
|
|
hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
|
|
hw_atl_utils_mpi_set_state(self, MPI_DEINIT);
|
|
AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
|
|
AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_MPI_STATE_ADR) &
|
|
- HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
|
|
|
|
|
|
+ HW_ATL_MPI_STATE_MSK) == MPI_DEINIT,
|
|
10, 1000U);
|
|
10, 1000U);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -277,7 +278,7 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
|
|
|
|
|
|
AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
|
|
AQ_HW_WAIT_FOR(hw_atl_reg_glb_cpu_sem_get(self,
|
|
HW_ATL_FW_SM_RAM) == 1U,
|
|
HW_ATL_FW_SM_RAM) == 1U,
|
|
- 1U, 10000U);
|
|
|
|
|
|
+ 1U, 10000U);
|
|
|
|
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
bool is_locked;
|
|
bool is_locked;
|
|
@@ -325,17 +326,31 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
|
|
err = -ETIME;
|
|
err = -ETIME;
|
|
goto err_exit;
|
|
goto err_exit;
|
|
}
|
|
}
|
|
|
|
+ if (IS_CHIP_FEATURE(REVISION_B1)) {
|
|
|
|
+ u32 offset = 0;
|
|
|
|
+
|
|
|
|
+ for (; offset < cnt; ++offset) {
|
|
|
|
+ aq_hw_write_reg(self, 0x328, p[offset]);
|
|
|
|
+ aq_hw_write_reg(self, 0x32C,
|
|
|
|
+ (0x80000000 | (0xFFFF & (offset * 4))));
|
|
|
|
+ hw_atl_mcp_up_force_intr_set(self, 1);
|
|
|
|
+ /* 1000 times by 10us = 10ms */
|
|
|
|
+ AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
|
|
|
|
+ 0x32C) & 0xF0000000) !=
|
|
|
|
+ 0x80000000,
|
|
|
|
+ 10, 1000);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ u32 offset = 0;
|
|
|
|
|
|
- aq_hw_write_reg(self, 0x00000208U, a);
|
|
|
|
-
|
|
|
|
- for (++cnt; --cnt;) {
|
|
|
|
- u32 i = 0U;
|
|
|
|
|
|
+ aq_hw_write_reg(self, 0x208, a);
|
|
|
|
|
|
- aq_hw_write_reg(self, 0x0000020CU, *(p++));
|
|
|
|
- aq_hw_write_reg(self, 0x00000200U, 0xC000U);
|
|
|
|
|
|
+ for (; offset < cnt; ++offset) {
|
|
|
|
+ aq_hw_write_reg(self, 0x20C, p[offset]);
|
|
|
|
+ aq_hw_write_reg(self, 0x200, 0xC000);
|
|
|
|
|
|
- for (i = 1024U;
|
|
|
|
- (0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
|
|
|
|
|
|
+ AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
|
|
|
|
+ 0x100) == 0, 10, 1000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -379,7 +394,7 @@ static int hw_atl_utils_init_ucp(struct aq_hw_s *self,
|
|
|
|
|
|
/* check 10 times by 1ms */
|
|
/* check 10 times by 1ms */
|
|
AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
|
|
AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
|
|
- aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
|
|
|
|
|
|
+ aq_hw_read_reg(self, 0x360U)), 1000U, 10U);
|
|
|
|
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
@@ -399,7 +414,7 @@ struct aq_hw_atl_utils_fw_rpc_tid_s {
|
|
|
|
|
|
#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
|
|
#define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
|
|
|
|
|
|
-static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
|
|
|
|
|
|
+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
|
|
{
|
|
{
|
|
int err = 0;
|
|
int err = 0;
|
|
struct aq_hw_atl_utils_fw_rpc_tid_s sw;
|
|
struct aq_hw_atl_utils_fw_rpc_tid_s sw;
|
|
@@ -411,7 +426,7 @@ static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
|
|
err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
|
|
err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
|
|
(u32 *)(void *)&self->rpc,
|
|
(u32 *)(void *)&self->rpc,
|
|
(rpc_size + sizeof(u32) -
|
|
(rpc_size + sizeof(u32) -
|
|
- sizeof(u8)) / sizeof(u32));
|
|
|
|
|
|
+ sizeof(u8)) / sizeof(u32));
|
|
if (err < 0)
|
|
if (err < 0)
|
|
goto err_exit;
|
|
goto err_exit;
|
|
|
|
|
|
@@ -423,8 +438,8 @@ err_exit:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
|
|
|
- struct hw_aq_atl_utils_fw_rpc **rpc)
|
|
|
|
|
|
+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
|
|
|
+ struct hw_atl_utils_fw_rpc **rpc)
|
|
{
|
|
{
|
|
int err = 0;
|
|
int err = 0;
|
|
struct aq_hw_atl_utils_fw_rpc_tid_s sw;
|
|
struct aq_hw_atl_utils_fw_rpc_tid_s sw;
|
|
@@ -436,7 +451,7 @@ static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
|
self->rpc_tid = sw.tid;
|
|
self->rpc_tid = sw.tid;
|
|
|
|
|
|
AQ_HW_WAIT_FOR(sw.tid ==
|
|
AQ_HW_WAIT_FOR(sw.tid ==
|
|
- (fw.val =
|
|
|
|
|
|
+ (fw.val =
|
|
aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
|
|
aq_hw_read_reg(self, HW_ATL_RPC_STATE_ADR),
|
|
fw.tid), 1000U, 100U);
|
|
fw.tid), 1000U, 100U);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
@@ -459,7 +474,7 @@ static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
|
|
(u32 *)(void *)
|
|
(u32 *)(void *)
|
|
&self->rpc,
|
|
&self->rpc,
|
|
(fw.len + sizeof(u32) -
|
|
(fw.len + sizeof(u32) -
|
|
- sizeof(u8)) /
|
|
|
|
|
|
+ sizeof(u8)) /
|
|
sizeof(u32));
|
|
sizeof(u32));
|
|
if (err < 0)
|
|
if (err < 0)
|
|
goto err_exit;
|
|
goto err_exit;
|
|
@@ -489,16 +504,16 @@ err_exit:
|
|
}
|
|
}
|
|
|
|
|
|
int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
|
|
int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
|
|
- struct hw_aq_atl_utils_mbox_header *pmbox)
|
|
|
|
|
|
+ struct hw_atl_utils_mbox_header *pmbox)
|
|
{
|
|
{
|
|
return hw_atl_utils_fw_downld_dwords(self,
|
|
return hw_atl_utils_fw_downld_dwords(self,
|
|
- self->mbox_addr,
|
|
|
|
- (u32 *)(void *)pmbox,
|
|
|
|
- sizeof(*pmbox) / sizeof(u32));
|
|
|
|
|
|
+ self->mbox_addr,
|
|
|
|
+ (u32 *)(void *)pmbox,
|
|
|
|
+ sizeof(*pmbox) / sizeof(u32));
|
|
}
|
|
}
|
|
|
|
|
|
void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
|
|
void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
|
|
- struct hw_aq_atl_utils_mbox *pmbox)
|
|
|
|
|
|
+ struct hw_atl_utils_mbox *pmbox)
|
|
{
|
|
{
|
|
int err = 0;
|
|
int err = 0;
|
|
|
|
|
|
@@ -538,7 +553,7 @@ static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
|
|
{
|
|
{
|
|
int err = 0;
|
|
int err = 0;
|
|
u32 transaction_id = 0;
|
|
u32 transaction_id = 0;
|
|
- struct hw_aq_atl_utils_mbox_header mbox;
|
|
|
|
|
|
+ struct hw_atl_utils_mbox_header mbox;
|
|
u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
|
|
u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
|
|
|
|
|
|
if (state == MPI_RESET) {
|
|
if (state == MPI_RESET) {
|
|
@@ -547,8 +562,8 @@ static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
|
|
transaction_id = mbox.transaction_id;
|
|
transaction_id = mbox.transaction_id;
|
|
|
|
|
|
AQ_HW_WAIT_FOR(transaction_id !=
|
|
AQ_HW_WAIT_FOR(transaction_id !=
|
|
- (hw_atl_utils_mpi_read_mbox(self, &mbox),
|
|
|
|
- mbox.transaction_id),
|
|
|
|
|
|
+ (hw_atl_utils_mpi_read_mbox(self, &mbox),
|
|
|
|
+ mbox.transaction_id),
|
|
1000U, 100U);
|
|
1000U, 100U);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
goto err_exit;
|
|
goto err_exit;
|
|
@@ -645,9 +660,9 @@ int hw_atl_utils_get_mac_permanent(struct aq_hw_s *self,
|
|
|
|
|
|
if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
|
|
if ((mac[0] & 0x01U) || ((mac[0] | mac[1] | mac[2]) == 0x00U)) {
|
|
/* chip revision */
|
|
/* chip revision */
|
|
- l = 0xE3000000U
|
|
|
|
- | (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG))
|
|
|
|
- | (0x00 << 16);
|
|
|
|
|
|
+ l = 0xE3000000U |
|
|
|
|
+ (0xFFFFU & aq_hw_read_reg(self, HW_ATL_UCP_0X370_REG)) |
|
|
|
|
+ (0x00 << 16);
|
|
h = 0x8001300EU;
|
|
h = 0x8001300EU;
|
|
|
|
|
|
mac[5] = (u8)(0xFFU & l);
|
|
mac[5] = (u8)(0xFFU & l);
|
|
@@ -730,17 +745,9 @@ static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
|
|
|
|
- unsigned int power_state)
|
|
|
|
-{
|
|
|
|
- hw_atl_utils_mpi_set_speed(self, 0);
|
|
|
|
- hw_atl_utils_mpi_set_state(self, MPI_POWER);
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
int hw_atl_utils_update_stats(struct aq_hw_s *self)
|
|
int hw_atl_utils_update_stats(struct aq_hw_s *self)
|
|
{
|
|
{
|
|
- struct hw_aq_atl_utils_mbox mbox;
|
|
|
|
|
|
+ struct hw_atl_utils_mbox mbox;
|
|
|
|
|
|
hw_atl_utils_mpi_read_stats(self, &mbox);
|
|
hw_atl_utils_mpi_read_stats(self, &mbox);
|
|
|
|
|
|
@@ -825,6 +832,81 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
|
|
|
|
+{
|
|
|
|
+ struct hw_atl_utils_fw_rpc *prpc = NULL;
|
|
|
|
+ unsigned int rpc_size = 0U;
|
|
|
|
+ int err = 0;
|
|
|
|
+
|
|
|
|
+ err = hw_atl_utils_fw_rpc_wait(self, &prpc);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ goto err_exit;
|
|
|
|
+
|
|
|
|
+ memset(prpc, 0, sizeof(*prpc));
|
|
|
|
+
|
|
|
|
+ if (wol_enabled) {
|
|
|
|
+ rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
|
|
|
|
+
|
|
|
|
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
|
|
|
|
+ prpc->msg_wol.priority =
|
|
|
|
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PRIOR;
|
|
|
|
+ prpc->msg_wol.pattern_id =
|
|
|
|
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
|
|
|
|
+ prpc->msg_wol.wol_packet_type =
|
|
|
|
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_MAG_PKT;
|
|
|
|
+
|
|
|
|
+ ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
|
|
|
|
+ } else {
|
|
|
|
+ rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
|
|
|
|
+
|
|
|
|
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
|
|
|
|
+ prpc->msg_wol.pattern_id =
|
|
|
|
+ HAL_ATLANTIC_UTILS_FW_MSG_WOL_PATTERN;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ err = hw_atl_utils_fw_rpc_call(self, rpc_size);
|
|
|
|
+
|
|
|
|
+err_exit:
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
|
|
|
|
+ u8 *mac)
|
|
|
|
+{
|
|
|
|
+ struct hw_atl_utils_fw_rpc *prpc = NULL;
|
|
|
|
+ unsigned int rpc_size = 0U;
|
|
|
|
+ int err = 0;
|
|
|
|
+
|
|
|
|
+ if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
|
|
|
|
+ err = aq_fw1x_set_wol(self, 1, mac);
|
|
|
|
+
|
|
|
|
+ if (err < 0)
|
|
|
|
+ goto err_exit;
|
|
|
|
+
|
|
|
|
+ rpc_size = sizeof(prpc->msg_id) +
|
|
|
|
+ sizeof(prpc->msg_enable_wakeup);
|
|
|
|
+
|
|
|
|
+ err = hw_atl_utils_fw_rpc_wait(self, &prpc);
|
|
|
|
+
|
|
|
|
+ if (err < 0)
|
|
|
|
+ goto err_exit;
|
|
|
|
+
|
|
|
|
+ memset(prpc, 0, rpc_size);
|
|
|
|
+
|
|
|
|
+ prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
|
|
|
|
+ prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
|
|
|
|
+
|
|
|
|
+ err = hw_atl_utils_fw_rpc_call(self, rpc_size);
|
|
|
|
+ if (err < 0)
|
|
|
|
+ goto err_exit;
|
|
|
|
+ }
|
|
|
|
+ hw_atl_utils_mpi_set_speed(self, 0);
|
|
|
|
+ hw_atl_utils_mpi_set_state(self, MPI_POWER);
|
|
|
|
+
|
|
|
|
+err_exit:
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
const struct aq_fw_ops aq_fw_1x_ops = {
|
|
const struct aq_fw_ops aq_fw_1x_ops = {
|
|
.init = hw_atl_utils_mpi_create,
|
|
.init = hw_atl_utils_mpi_create,
|
|
.deinit = hw_atl_fw1x_deinit,
|
|
.deinit = hw_atl_fw1x_deinit,
|
|
@@ -834,5 +916,8 @@ const struct aq_fw_ops aq_fw_1x_ops = {
|
|
.set_state = hw_atl_utils_mpi_set_state,
|
|
.set_state = hw_atl_utils_mpi_set_state,
|
|
.update_link_status = hw_atl_utils_mpi_get_link_status,
|
|
.update_link_status = hw_atl_utils_mpi_get_link_status,
|
|
.update_stats = hw_atl_utils_update_stats,
|
|
.update_stats = hw_atl_utils_update_stats,
|
|
|
|
+ .set_power = aq_fw1x_set_power,
|
|
|
|
+ .set_eee_rate = NULL,
|
|
|
|
+ .get_eee_rate = NULL,
|
|
.set_flow_control = NULL,
|
|
.set_flow_control = NULL,
|
|
};
|
|
};
|