net: atlantic: add fw configuration memory area
Device FW has a separate memory area where various config fields are stored and could be used by the driver. Here we modify download/upload infrastructure to allow accessing this area. Lateron this will be used to configure various behaviours Signed-off-by: Nikita Danilov <ndanilov@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d1287ce4ff
commit
dc12f75afc
|
@ -140,6 +140,7 @@ struct aq_hw_s {
|
|||
atomic_t dpc;
|
||||
u32 mbox_addr;
|
||||
u32 rpc_addr;
|
||||
u32 settings_addr;
|
||||
u32 rpc_tid;
|
||||
struct hw_atl_utils_fw_rpc rpc;
|
||||
s64 ptp_clk_offset;
|
||||
|
|
|
@ -47,6 +47,11 @@
|
|||
|
||||
#define FORCE_FLASHLESS 0
|
||||
|
||||
enum mcp_area {
|
||||
MCP_AREA_CONFIG = 0x80000000,
|
||||
MCP_AREA_SETTINGS = 0x20000000,
|
||||
};
|
||||
|
||||
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,
|
||||
|
@ -327,10 +332,75 @@ err_exit:
|
|||
return err;
|
||||
}
|
||||
|
||||
int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, u32 cnt)
|
||||
static int hw_atl_utils_write_b1_mbox(struct aq_hw_s *self, u32 addr,
|
||||
u32 *p, u32 cnt, enum mcp_area area)
|
||||
{
|
||||
u32 val;
|
||||
u32 data_offset = 0;
|
||||
u32 offset = addr;
|
||||
int err = 0;
|
||||
u32 val;
|
||||
|
||||
switch (area) {
|
||||
case MCP_AREA_CONFIG:
|
||||
offset -= self->rpc_addr;
|
||||
break;
|
||||
|
||||
case MCP_AREA_SETTINGS:
|
||||
offset -= self->settings_addr;
|
||||
break;
|
||||
}
|
||||
|
||||
offset = offset / sizeof(u32);
|
||||
|
||||
for (; data_offset < cnt; ++data_offset, ++offset) {
|
||||
aq_hw_write_reg(self, 0x328, p[data_offset]);
|
||||
aq_hw_write_reg(self, 0x32C,
|
||||
(area | (0xFFFF & (offset * 4))));
|
||||
hw_atl_mcp_up_force_intr_set(self, 1);
|
||||
/* 1000 times by 10us = 10ms */
|
||||
err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
|
||||
self, val,
|
||||
(val & 0xF0000000) !=
|
||||
area,
|
||||
10U, 10000U);
|
||||
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hw_atl_utils_write_b0_mbox(struct aq_hw_s *self, u32 addr,
|
||||
u32 *p, u32 cnt)
|
||||
{
|
||||
u32 offset = 0;
|
||||
int err = 0;
|
||||
u32 val;
|
||||
|
||||
aq_hw_write_reg(self, 0x208, addr);
|
||||
|
||||
for (; offset < cnt; ++offset) {
|
||||
aq_hw_write_reg(self, 0x20C, p[offset]);
|
||||
aq_hw_write_reg(self, 0x200, 0xC000);
|
||||
|
||||
err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
|
||||
self, val,
|
||||
(val & 0x100) == 0U,
|
||||
10U, 10000U);
|
||||
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 addr, u32 *p,
|
||||
u32 cnt, enum mcp_area area)
|
||||
{
|
||||
int err = 0;
|
||||
u32 val;
|
||||
|
||||
err = readx_poll_timeout_atomic(hw_atl_sem_ram_get, self,
|
||||
val, val == 1U,
|
||||
|
@ -338,43 +408,35 @@ int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, u32 cnt)
|
|||
if (err < 0)
|
||||
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 */
|
||||
err = readx_poll_timeout_atomic(hw_atl_scrpad12_get,
|
||||
self, val,
|
||||
(val & 0xF0000000) !=
|
||||
0x80000000,
|
||||
10U, 10000U);
|
||||
}
|
||||
} else {
|
||||
u32 offset = 0;
|
||||
|
||||
aq_hw_write_reg(self, 0x208, a);
|
||||
|
||||
for (; offset < cnt; ++offset) {
|
||||
aq_hw_write_reg(self, 0x20C, p[offset]);
|
||||
aq_hw_write_reg(self, 0x200, 0xC000);
|
||||
|
||||
err = readx_poll_timeout_atomic(hw_atl_utils_mif_cmd_get,
|
||||
self, val,
|
||||
(val & 0x100) == 0,
|
||||
1000U, 10000U);
|
||||
}
|
||||
}
|
||||
if (IS_CHIP_FEATURE(REVISION_B1))
|
||||
err = hw_atl_utils_write_b1_mbox(self, addr, p, cnt, area);
|
||||
else
|
||||
err = hw_atl_utils_write_b0_mbox(self, addr, p, cnt);
|
||||
|
||||
hw_atl_reg_glb_cpu_sem_set(self, 1U, HW_ATL_FW_SM_RAM);
|
||||
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
err = aq_hw_err_from_flags(self);
|
||||
|
||||
err_exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt)
|
||||
{
|
||||
return hw_atl_utils_fw_upload_dwords(self, self->rpc_addr, p,
|
||||
cnt, MCP_AREA_CONFIG);
|
||||
}
|
||||
|
||||
int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
|
||||
u32 cnt)
|
||||
{
|
||||
return hw_atl_utils_fw_upload_dwords(self, self->settings_addr + offset,
|
||||
p, cnt, MCP_AREA_SETTINGS);
|
||||
}
|
||||
|
||||
static int hw_atl_utils_ver_match(u32 ver_expected, u32 ver_actual)
|
||||
{
|
||||
int err = 0;
|
||||
|
@ -437,10 +499,9 @@ int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
|
|||
err = -1;
|
||||
goto err_exit;
|
||||
}
|
||||
err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
|
||||
(u32 *)(void *)&self->rpc,
|
||||
(rpc_size + sizeof(u32) -
|
||||
sizeof(u8)) / sizeof(u32));
|
||||
err = hw_atl_write_fwcfg_dwords(self, (u32 *)(void *)&self->rpc,
|
||||
(rpc_size + sizeof(u32) -
|
||||
sizeof(u8)) / sizeof(u32));
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
|
|
|
@ -277,6 +277,48 @@ struct __packed hw_fw_request_iface {
|
|||
};
|
||||
};
|
||||
|
||||
struct __packed hw_atl_utils_settings {
|
||||
u32 mtu;
|
||||
u32 downshift_retry_count;
|
||||
u32 link_pause_frame_quanta_100m;
|
||||
u32 link_pause_frame_threshold_100m;
|
||||
u32 link_pause_frame_quanta_1g;
|
||||
u32 link_pause_frame_threshold_1g;
|
||||
u32 link_pause_frame_quanta_2p5g;
|
||||
u32 link_pause_frame_threshold_2p5g;
|
||||
u32 link_pause_frame_quanta_5g;
|
||||
u32 link_pause_frame_threshold_5g;
|
||||
u32 link_pause_frame_quanta_10g;
|
||||
u32 link_pause_frame_threshold_10g;
|
||||
u32 pfc_quanta_class_0;
|
||||
u32 pfc_threshold_class_0;
|
||||
u32 pfc_quanta_class_1;
|
||||
u32 pfc_threshold_class_1;
|
||||
u32 pfc_quanta_class_2;
|
||||
u32 pfc_threshold_class_2;
|
||||
u32 pfc_quanta_class_3;
|
||||
u32 pfc_threshold_class_3;
|
||||
u32 pfc_quanta_class_4;
|
||||
u32 pfc_threshold_class_4;
|
||||
u32 pfc_quanta_class_5;
|
||||
u32 pfc_threshold_class_5;
|
||||
u32 pfc_quanta_class_6;
|
||||
u32 pfc_threshold_class_6;
|
||||
u32 pfc_quanta_class_7;
|
||||
u32 pfc_threshold_class_7;
|
||||
u32 eee_link_down_timeout;
|
||||
u32 eee_link_up_timeout;
|
||||
u32 eee_max_link_drops;
|
||||
u32 eee_rates_mask;
|
||||
u32 wake_timer;
|
||||
u32 thermal_shutdown_off_temp;
|
||||
u32 thermal_shutdown_warning_temp;
|
||||
u32 thermal_shutdown_cold_temp;
|
||||
u32 msm_options;
|
||||
u32 dac_cable_serdes_modes;
|
||||
u32 media_detect;
|
||||
};
|
||||
|
||||
enum hw_atl_rx_action_with_traffic {
|
||||
HW_ATL_RX_DISCARD,
|
||||
HW_ATL_RX_HOST,
|
||||
|
@ -554,7 +596,10 @@ struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
|
|||
int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
|
||||
u32 *p, u32 cnt);
|
||||
|
||||
int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p, u32 cnt);
|
||||
int hw_atl_write_fwcfg_dwords(struct aq_hw_s *self, u32 *p, u32 cnt);
|
||||
|
||||
int hw_atl_write_fwsettings_dwords(struct aq_hw_s *self, u32 offset, u32 *p,
|
||||
u32 cnt);
|
||||
|
||||
int hw_atl_utils_fw_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac);
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ static int aq_fw2x_set_state(struct aq_hw_s *self,
|
|||
|
||||
static u32 aq_fw2x_mbox_get(struct aq_hw_s *self);
|
||||
static u32 aq_fw2x_rpc_get(struct aq_hw_s *self);
|
||||
static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr);
|
||||
static u32 aq_fw2x_state2_get(struct aq_hw_s *self);
|
||||
|
||||
static int aq_fw2x_init(struct aq_hw_s *self)
|
||||
|
@ -95,6 +96,8 @@ static int aq_fw2x_init(struct aq_hw_s *self)
|
|||
self->rpc_addr != 0U,
|
||||
1000U, 100000U);
|
||||
|
||||
err = aq_fw2x_settings_get(self, &self->settings_addr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -418,8 +421,7 @@ static int aq_fw2x_send_fw_request(struct aq_hw_s *self,
|
|||
dword_cnt = size / sizeof(u32);
|
||||
if (size % sizeof(u32))
|
||||
dword_cnt++;
|
||||
err = hw_atl_utils_fw_upload_dwords(self, aq_fw2x_rpc_get(self),
|
||||
(void *)fw_req, dword_cnt);
|
||||
err = hw_atl_write_fwcfg_dwords(self, (void *)fw_req, dword_cnt);
|
||||
if (err < 0)
|
||||
goto err_exit;
|
||||
|
||||
|
@ -547,6 +549,19 @@ static u32 aq_fw2x_rpc_get(struct aq_hw_s *self)
|
|||
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR);
|
||||
}
|
||||
|
||||
static int aq_fw2x_settings_get(struct aq_hw_s *self, u32 *addr)
|
||||
{
|
||||
int err = 0;
|
||||
u32 offset;
|
||||
|
||||
offset = self->mbox_addr + offsetof(struct hw_atl_utils_mbox,
|
||||
info.setting_address);
|
||||
|
||||
err = hw_atl_utils_fw_downld_dwords(self, offset, addr, 1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32 aq_fw2x_state2_get(struct aq_hw_s *self)
|
||||
{
|
||||
return aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
|
||||
|
|
Loading…
Reference in New Issue