Commit 2a0efe6a authored by Dedy Lansky's avatar Dedy Lansky Committed by Kalle Valo

wil6210: support flashless device

Talyn device supports boot without flash.
Driver detects flashless device and in this case waits for ready indication
from HW machine (instead of bootloader ready indication). Also in this
case, MAC address is retrieved from OTP.
Signed-off-by: default avatarDedy Lansky <dlansky@codeaurora.org>
Signed-off-by: default avatarMaya Erez <merez@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 4276d771
/* /*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc. * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
...@@ -670,7 +671,7 @@ static void wil_set_oob_mode(struct wil6210_priv *wil, u8 mode) ...@@ -670,7 +671,7 @@ static void wil_set_oob_mode(struct wil6210_priv *wil, u8 mode)
} }
} }
static int wil_target_reset(struct wil6210_priv *wil) static int wil_target_reset(struct wil6210_priv *wil, int no_flash)
{ {
int delay = 0; int delay = 0;
u32 x, x1 = 0; u32 x, x1 = 0;
...@@ -684,9 +685,11 @@ static int wil_target_reset(struct wil6210_priv *wil) ...@@ -684,9 +685,11 @@ static int wil_target_reset(struct wil6210_priv *wil)
wil_halt_cpu(wil); wil_halt_cpu(wil);
/* clear all boot loader "ready" bits */ if (!no_flash)
wil_w(wil, RGF_USER_BL + /* clear all boot loader "ready" bits */
offsetof(struct bl_dedicated_registers_v0, boot_loader_ready), 0); wil_w(wil, RGF_USER_BL +
offsetof(struct bl_dedicated_registers_v0,
boot_loader_ready), 0);
/* Clear Fw Download notification */ /* Clear Fw Download notification */
wil_c(wil, RGF_USER_USAGE_6, BIT(0)); wil_c(wil, RGF_USER_USAGE_6, BIT(0));
...@@ -727,21 +730,33 @@ static int wil_target_reset(struct wil6210_priv *wil) ...@@ -727,21 +730,33 @@ static int wil_target_reset(struct wil6210_priv *wil)
wil_w(wil, RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); wil_w(wil, RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
/* wait until device ready. typical time is 20..80 msec */ /* wait until device ready. typical time is 20..80 msec */
do { if (no_flash)
msleep(RST_DELAY); do {
x = wil_r(wil, RGF_USER_BL + msleep(RST_DELAY);
offsetof(struct bl_dedicated_registers_v0, x = wil_r(wil, USER_EXT_USER_PMU_3);
boot_loader_ready)); if (delay++ > RST_COUNT) {
if (x1 != x) { wil_err(wil, "Reset not completed, PMU_3 0x%08x\n",
wil_dbg_misc(wil, "BL.ready 0x%08x => 0x%08x\n", x1, x); x);
x1 = x; return -ETIME;
} }
if (delay++ > RST_COUNT) { } while ((x & BIT_PMU_DEVICE_RDY) == 0);
wil_err(wil, "Reset not completed, bl.ready 0x%08x\n", else
x); do {
return -ETIME; msleep(RST_DELAY);
} x = wil_r(wil, RGF_USER_BL +
} while (x != BL_READY); offsetof(struct bl_dedicated_registers_v0,
boot_loader_ready));
if (x1 != x) {
wil_dbg_misc(wil, "BL.ready 0x%08x => 0x%08x\n",
x1, x);
x1 = x;
}
if (delay++ > RST_COUNT) {
wil_err(wil, "Reset not completed, bl.ready 0x%08x\n",
x);
return -ETIME;
}
} while (x != BL_READY);
wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
...@@ -906,6 +921,27 @@ static void wil_bl_crash_info(struct wil6210_priv *wil, bool is_err) ...@@ -906,6 +921,27 @@ static void wil_bl_crash_info(struct wil6210_priv *wil, bool is_err)
} }
} }
static int wil_get_otp_info(struct wil6210_priv *wil)
{
struct net_device *ndev = wil_to_ndev(wil);
struct wiphy *wiphy = wil_to_wiphy(wil);
u8 mac[8];
wil_memcpy_fromio_32(mac, wil->csr + HOSTADDR(RGF_OTP_MAC),
sizeof(mac));
if (!is_valid_ether_addr(mac)) {
wil_err(wil, "Invalid MAC %pM\n", mac);
return -EINVAL;
}
ether_addr_copy(ndev->perm_addr, mac);
ether_addr_copy(wiphy->perm_addr, mac);
if (!is_valid_ether_addr(ndev->dev_addr))
ether_addr_copy(ndev->dev_addr, mac);
return 0;
}
static int wil_wait_for_fw_ready(struct wil6210_priv *wil) static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
{ {
ulong to = msecs_to_jiffies(1000); ulong to = msecs_to_jiffies(1000);
...@@ -999,6 +1035,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) ...@@ -999,6 +1035,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
{ {
int rc; int rc;
unsigned long status_flags = BIT(wil_status_resetting); unsigned long status_flags = BIT(wil_status_resetting);
int no_flash;
wil_dbg_misc(wil, "reset\n"); wil_dbg_misc(wil, "reset\n");
...@@ -1074,20 +1111,28 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw) ...@@ -1074,20 +1111,28 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
flush_workqueue(wil->wq_service); flush_workqueue(wil->wq_service);
flush_workqueue(wil->wmi_wq); flush_workqueue(wil->wmi_wq);
wil_bl_crash_info(wil, false); no_flash = test_bit(hw_capa_no_flash, wil->hw_capa);
if (!no_flash)
wil_bl_crash_info(wil, false);
wil_disable_irq(wil); wil_disable_irq(wil);
rc = wil_target_reset(wil); rc = wil_target_reset(wil, no_flash);
wil6210_clear_irq(wil); wil6210_clear_irq(wil);
wil_enable_irq(wil); wil_enable_irq(wil);
wil_rx_fini(wil); wil_rx_fini(wil);
if (rc) { if (rc) {
wil_bl_crash_info(wil, true); if (!no_flash)
wil_bl_crash_info(wil, true);
goto out; goto out;
} }
rc = wil_get_bl_info(wil); if (no_flash) {
if (rc == -EAGAIN && !load_fw) /* ignore RF error if not going up */ rc = wil_get_otp_info(wil);
rc = 0; } else {
rc = wil_get_bl_info(wil);
if (rc == -EAGAIN && !load_fw)
/* ignore RF error if not going up */
rc = 0;
}
if (rc) if (rc)
goto out; goto out;
......
...@@ -44,7 +44,7 @@ int wil_set_capabilities(struct wil6210_priv *wil) ...@@ -44,7 +44,7 @@ int wil_set_capabilities(struct wil6210_priv *wil)
RGF_USER_REVISION_ID_MASK); RGF_USER_REVISION_ID_MASK);
int platform_capa; int platform_capa;
bitmap_zero(wil->hw_capabilities, hw_capability_last); bitmap_zero(wil->hw_capa, hw_capa_last);
bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX); bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
bitmap_zero(wil->platform_capa, WIL_PLATFORM_CAPA_MAX); bitmap_zero(wil->platform_capa, WIL_PLATFORM_CAPA_MAX);
wil->wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_DEFAULT : wil->wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_DEFAULT :
...@@ -83,6 +83,9 @@ int wil_set_capabilities(struct wil6210_priv *wil) ...@@ -83,6 +83,9 @@ int wil_set_capabilities(struct wil6210_priv *wil)
memcpy(fw_mapping, talyn_fw_mapping, sizeof(talyn_fw_mapping)); memcpy(fw_mapping, talyn_fw_mapping, sizeof(talyn_fw_mapping));
wil->rgf_fw_assert_code_addr = TALYN_RGF_FW_ASSERT_CODE; wil->rgf_fw_assert_code_addr = TALYN_RGF_FW_ASSERT_CODE;
wil->rgf_ucode_assert_code_addr = TALYN_RGF_UCODE_ASSERT_CODE; wil->rgf_ucode_assert_code_addr = TALYN_RGF_UCODE_ASSERT_CODE;
if (wil_r(wil, RGF_USER_OTP_HW_RD_MACHINE_1) &
BIT_NO_FLASH_INDICATION)
set_bit(hw_capa_no_flash, wil->hw_capa);
break; break;
default: default:
wil_err(wil, "Unknown board hardware, chip_id 0x%08x, chip_revision 0x%08x\n", wil_err(wil, "Unknown board hardware, chip_id 0x%08x, chip_revision 0x%08x\n",
...@@ -92,7 +95,8 @@ int wil_set_capabilities(struct wil6210_priv *wil) ...@@ -92,7 +95,8 @@ int wil_set_capabilities(struct wil6210_priv *wil)
return -EINVAL; return -EINVAL;
} }
wil_info(wil, "Board hardware is %s\n", wil->hw_name); wil_info(wil, "Board hardware is %s, flash %sexist\n", wil->hw_name,
test_bit(hw_capa_no_flash, wil->hw_capa) ? "doesn't " : "");
/* Get platform capabilities */ /* Get platform capabilities */
if (wil->platform_ops.get_capa) { if (wil->platform_ops.get_capa) {
......
...@@ -195,6 +195,8 @@ struct RGF_ICR { ...@@ -195,6 +195,8 @@ struct RGF_ICR {
#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c) #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c)
#define RGF_USER_SPARROW_M_4 (0x880c50) /* Sparrow */ #define RGF_USER_SPARROW_M_4 (0x880c50) /* Sparrow */
#define BIT_SPARROW_M_4_SEL_SLEEP_OR_REF BIT(2) #define BIT_SPARROW_M_4_SEL_SLEEP_OR_REF BIT(2)
#define RGF_USER_OTP_HW_RD_MACHINE_1 (0x880ce0)
#define BIT_NO_FLASH_INDICATION BIT(8)
#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ #define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
#define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
...@@ -285,6 +287,9 @@ struct RGF_ICR { ...@@ -285,6 +287,9 @@ struct RGF_ICR {
#define RGF_CAF_PLL_LOCK_STATUS (0x88afec) #define RGF_CAF_PLL_LOCK_STATUS (0x88afec)
#define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
#define USER_EXT_USER_PMU_3 (0x88d00c)
#define BIT_PMU_DEVICE_RDY BIT(0)
#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */ #define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
#define JTAG_DEV_ID_SPARROW (0x2632072f) #define JTAG_DEV_ID_SPARROW (0x2632072f)
#define JTAG_DEV_ID_TALYN (0x7e0e1) #define JTAG_DEV_ID_TALYN (0x7e0e1)
...@@ -294,6 +299,8 @@ struct RGF_ICR { ...@@ -294,6 +299,8 @@ struct RGF_ICR {
#define REVISION_ID_SPARROW_B0 (0x0) #define REVISION_ID_SPARROW_B0 (0x0)
#define REVISION_ID_SPARROW_D0 (0x3) #define REVISION_ID_SPARROW_D0 (0x3)
#define RGF_OTP_MAC (0x8a0620)
/* crash codes for FW/Ucode stored here */ /* crash codes for FW/Ucode stored here */
/* ASSERT RGFs */ /* ASSERT RGFs */
...@@ -583,7 +590,8 @@ enum { ...@@ -583,7 +590,8 @@ enum {
}; };
enum { enum {
hw_capability_last hw_capa_no_flash,
hw_capa_last
}; };
struct wil_probe_client_req { struct wil_probe_client_req {
...@@ -659,7 +667,8 @@ struct wil6210_priv { ...@@ -659,7 +667,8 @@ struct wil6210_priv {
u8 chip_revision; u8 chip_revision;
const char *hw_name; const char *hw_name;
const char *wil_fw_name; const char *wil_fw_name;
DECLARE_BITMAP(hw_capabilities, hw_capability_last); char *board_file;
DECLARE_BITMAP(hw_capa, hw_capa_last);
DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX); DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX); DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX);
u8 n_mids; /* number of additional MIDs as reported by FW */ u8 n_mids; /* number of additional MIDs as reported by FW */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment