summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c')
-rwxr-xr-xdrivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c429
1 files changed, 429 insertions, 0 deletions
diff --git a/drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c b/drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c
new file mode 100755
index 00000000..24842297
--- /dev/null
+++ b/drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c
@@ -0,0 +1,429 @@
+#include "wlan_includes.h"
+#include "wlan_sdio_patch_90.h"
+#include "wlan_sdio_patch_91.h"
+#include "wlan_sdio_patch_91e.h"
+#include "wlan_sdio_patch_91f.h"
+
+static u8 sdio_patch_complete = 0;
+static atomic_t sdio_init_complete = ATOMIC_INIT(0);
+
+int wlan_get_fw_version_polling(wlan_private *priv, u32* version)
+{
+ int ret = 0;
+
+ ENTER();
+
+ ret = wlan_generic_get_ulong(priv, WID_SYS_FW_VER, (u8*)version);
+ if (ret) {
+ WLAN_ERRP("get version failed \n");
+ goto out;
+ }
+
+ WLAN_ERRP("version %x \n", *version);
+
+out:
+ LEAVE();
+ return ret;
+}
+
+int wlan_write_sdio32_polling(wlan_private * priv, const u32(*data)[2],
+ u32 size)
+{
+ int count = size, index = 0;
+ int ret = 0;
+
+ ENTER();
+ //each time write five init data
+ for(index = 0; index < count/8; index ++){
+ ret = wlan_set_core_init_patch(priv, (const unsigned int (*)[2])&data[8*index][0], 8);
+ if(ret)
+ goto err;
+ WLAN_DBGLAP(WLAN_DA_PM, WLAN_DL_DEBUG, "index:%d\n", index);
+ }
+
+ if(count%8 > 0){
+ ret = wlan_set_core_init_patch(priv, (const unsigned int (*)[2])&data[8*index][0], count%8);
+ if(ret)
+ goto err;
+ }
+err:
+ LEAVE();
+ return ret;
+}
+
+int wlan_write_sdio8_polling(wlan_private *priv, const u8 (*data)[2], u32 size)
+{
+ int count = size, index = 0;
+ int ret = 0;
+
+ ENTER();
+ //each time write five init data
+ for(index = 0; index < count/8; index ++){
+ WLAN_DBGLAP(WLAN_DA_PM, WLAN_DL_DEBUG, "index:%d\n", index);
+ ret = wlan_set_core_patch(priv, (const unsigned char (*)[2])data[8*index], 8);
+ if(ret)
+ goto err;
+ }
+
+ if(count%8 > 0){
+ ret = wlan_set_core_patch(priv, (const unsigned char (*)[2])data[8*index], count%8);
+ if(ret)
+ goto err;
+ }
+
+err:
+ LEAVE();
+ return ret;
+}
+
+int wlan_sdio_patch_core_32(wlan_private *priv)
+{
+ int ret = 0;
+
+ ENTER();
+
+ if (priv->version == WLAN_VERSION_90_D) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_patch_data_32_90_D,
+ sizeof(wifi_core_patch_data_32_90_D) /
+ sizeof(wifi_core_patch_data_32_90_D[0]));
+ } else if (priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_patch_data_32_90_E,
+ sizeof(wifi_core_patch_data_32_90_E) /
+ sizeof(wifi_core_patch_data_32_90_E[0]));
+ } else if (priv->version == WLAN_VERSION_91) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_patch_data_32_91,
+ sizeof(wifi_core_patch_data_32_91)/
+ sizeof(wifi_core_patch_data_32_91[0]));
+
+ ret = wlan_write_sdio32_polling(priv, wifi_clock_switch_91,
+ sizeof(wifi_clock_switch_91) /
+ sizeof(wifi_clock_switch_91[0]));
+ }else if (priv->version == WLAN_VERSION_91_E) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_patch_data_32_91e,
+ sizeof(wifi_core_patch_data_32_91e)/
+ sizeof(wifi_core_patch_data_32_91e[0]));
+
+ ret = wlan_write_sdio32_polling(priv, wifi_clock_switch_91e,
+ sizeof(wifi_clock_switch_91e) /
+ sizeof(wifi_clock_switch_91e[0]));
+ }else if (priv->version == WLAN_VERSION_91_F) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_patch_data_32_91f,
+ sizeof(wifi_core_patch_data_32_91f)/
+ sizeof(wifi_core_patch_data_32_91f[0]));
+ ret = wlan_write_sdio32_polling(priv, wifi_clock_switch_91f,
+ sizeof(wifi_clock_switch_91f) /
+ sizeof(wifi_clock_switch_91f[0]));
+ }
+ LEAVE();
+ return ret;
+}
+
+int wlan_sdio_init_core_polling(wlan_private *priv)
+{
+ int ret = 0;
+
+ ENTER();
+ if(priv->version == WLAN_VERSION_90_D)
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_90_D,
+ sizeof(wifi_core_init_data_32_90_D) /
+ sizeof(wifi_core_init_data_32_90_D[0]));
+ else if(priv->version == WLAN_VERSION_90_E)
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_90_E,
+ sizeof(wifi_core_init_data_32_90_E) /
+ sizeof(wifi_core_init_data_32_90_E[0]));
+ else if(priv->version == WLAN_VERSION_91){
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91,
+ sizeof(wifi_core_init_data_32_91) /
+ sizeof(wifi_core_init_data_32_91[0]));
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91,
+ sizeof(wifi_core_AM_PM_data_32_91)/
+ sizeof(wifi_core_AM_PM_data_32_91[0]));
+ }else if (priv->version == WLAN_VERSION_91_E) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91e,
+ sizeof(wifi_core_init_data_32_91e) /
+ sizeof(wifi_core_init_data_32_91e[0]));
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91e,
+ sizeof(wifi_core_AM_PM_data_32_91e)/
+ sizeof(wifi_core_AM_PM_data_32_91e[0]));
+ }else if (priv->version == WLAN_VERSION_91_F) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91f,
+ sizeof(wifi_core_init_data_32_91f) /
+ sizeof(wifi_core_init_data_32_91f[0]));
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91f,
+ sizeof(wifi_core_AM_PM_data_32_91f)/
+ sizeof(wifi_core_AM_PM_data_32_91f[0]));
+ }
+ LEAVE();
+ return ret;
+}
+
+int wlan_sdio_core_wake_mode_polling(wlan_private *priv)
+{
+ int ret = 0;
+
+ if (priv->version == WLAN_VERSION_91 || priv->version == WLAN_VERSION_91_E || priv->version == WLAN_VERSION_91_F)
+ return 0;
+
+ ret = wlan_write_sdio32_polling(priv, wifi_core_data_wake,
+ sizeof(wifi_core_data_wake) /
+ sizeof(wifi_core_data_wake[0]));
+ return ret;
+}
+
+int wlan_sdio_patch_core_8_polling(wlan_private *priv)
+{
+ int ret = 0;
+ //for patch in byte mode
+
+ ENTER();
+
+ if (priv->version == WLAN_VERSION_90_D
+ || priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_90_8,
+ sizeof(wifi_core_patch_data_90_8) /
+ sizeof(wifi_core_patch_data_90_8[0]));
+ if(ret)
+ goto err;
+ }else if(priv->version == WLAN_VERSION_91){
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91_8,
+ sizeof(wifi_core_patch_data_91_8)/
+ sizeof(wifi_core_patch_data_91_8[0]));
+ if (ret)
+ goto err;
+ }else if (priv->version == WLAN_VERSION_91_E) {
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91e_8,
+ sizeof(wifi_core_patch_data_91e_8)/
+ sizeof(wifi_core_patch_data_91e_8[0]));
+ if(ret)
+ goto err;
+ }else if (priv->version == WLAN_VERSION_91_F) {
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91f_8,
+ sizeof(wifi_core_patch_data_91f_8)/
+ sizeof(wifi_core_patch_data_91f_8[0]));
+ if (ret)
+ goto err;
+ }
+
+ //for patch in wake continue clock mode
+ ret = wlan_sdio_core_wake_mode_polling(priv);
+ if(ret)
+ goto err;
+
+err:
+ LEAVE();
+ return ret;
+}
+
+int wlan_sdio_set_default_notch_polling(wlan_private *priv)
+{
+ int ret = 0;
+
+ ENTER();
+
+ if (priv->version == WLAN_VERSION_91 || priv->version == WLAN_VERSION_91_E || priv->version == WLAN_VERSION_91_F)
+ return 0;
+
+ if(priv->version == WLAN_VERSION_90_D)
+ ret = wlan_write_sdio32_polling(priv, wifi_notch_data_90_D,
+ sizeof(wifi_notch_data_90_D) /
+ sizeof(wifi_notch_data_90_D[0]));
+ else if(priv->version == WLAN_VERSION_90_E)
+ ret = wlan_write_sdio32_polling(priv, wifi_notch_data_90_E,
+ sizeof(wifi_notch_data_90_E) /
+ sizeof(wifi_notch_data_90_E[0]));
+ LEAVE();
+
+ return ret;
+}
+
+extern void rda_mci_enable_sdio_irq(struct mmc_host *mmc, int enable);
+int wlan_sdio_init(wlan_private *priv)
+{
+ int ret = 0;
+
+ atomic_set(&sdio_init_complete, 0);
+ sdio_patch_complete = 0;
+
+ ret = wlan_sdio_patch_core_32(priv);
+ if(ret < 0)
+ goto err;
+
+
+ sdio_patch_complete = 1;
+ wlan_sched_timeout(10); //10ms delay
+
+ ret = wlan_sdio_init_core_polling(priv);
+ if(ret)
+ goto err;
+
+ ret = wlan_sdio_patch_core_8_polling(priv);
+ if(ret < 0)
+ goto err;
+
+ ret = wlan_sdio_set_default_notch_polling(priv);
+ if(ret < 0)
+ goto err;
+
+ atomic_set(&sdio_init_complete, 1);
+ //wlan_register_host_wake_irq(priv);
+ rda_mci_enable_sdio_irq(priv->MmcCard->host, 1);
+ priv->sdio_irq_enable = TRUE;
+
+err:
+ return ret;
+}
+
+u8 is_sdio_init_complete(void)
+{
+ return atomic_read(&sdio_init_complete);
+}
+u8 is_sdio_patch_complete(void) //after patch complete need check write flow
+{
+ return sdio_patch_complete;
+
+
+
+}
+
+int wlan_set_test_mode(wlan_private *priv)
+{
+ int ret = 0;
+ ENTER();
+ atomic_set(&sdio_init_complete, 0);
+ sdio_patch_complete = 0;
+ ret = wlan_sdio_patch_core_32(priv);
+ if(ret)
+ goto err;
+
+ sdio_patch_complete = 1;
+
+ if (priv->version == WLAN_VERSION_90_D
+ || priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_90_8,
+ sizeof(wifi_core_patch_data_90_8)/
+ sizeof(wifi_core_patch_data_90_8[0]));
+ if(ret)
+ goto err;
+ }else if(priv->version == WLAN_VERSION_91){
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91,
+ sizeof(wifi_core_init_data_32_91) /
+ sizeof(wifi_core_init_data_32_91[0]));
+ if (ret)
+ goto err;
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91,
+ sizeof(wifi_core_AM_PM_data_32_91)/
+ sizeof(wifi_core_AM_PM_data_32_91[0]));
+ if (ret)
+ goto err;
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91_8,
+ sizeof(wifi_core_patch_data_91_8)/
+ sizeof(wifi_core_patch_data_91_8[0]));
+ if(ret)
+ goto err;
+
+ }else if (priv->version == WLAN_VERSION_91_E) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91e,
+ sizeof(wifi_core_init_data_32_91e) /
+ sizeof(wifi_core_init_data_32_91e[0]));
+ if(ret)
+ goto err;
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91e,
+ sizeof(wifi_core_AM_PM_data_32_91e)/
+ sizeof(wifi_core_AM_PM_data_32_91e[0]));
+ if(ret)
+ goto err;
+
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91e_8,
+ sizeof(wifi_core_patch_data_91e_8)/
+ sizeof(wifi_core_patch_data_91e_8[0]));
+ if(ret)
+ goto err;
+ }else if (priv->version == WLAN_VERSION_91_F) {
+ ret = wlan_write_sdio32_polling(priv, wifi_core_init_data_32_91f,
+ sizeof(wifi_core_init_data_32_91f) /
+ sizeof(wifi_core_init_data_32_91f[0]));
+ if (ret)
+ goto err;
+ ret = wlan_write_sdio32_polling(priv, wifi_core_AM_PM_data_32_91f,
+ sizeof(wifi_core_AM_PM_data_32_91f)/
+ sizeof(wifi_core_AM_PM_data_32_91f[0]));
+ if (ret)
+ goto err;
+ ret = wlan_write_sdio8_polling(priv, wifi_core_patch_data_91f_8,
+ sizeof(wifi_core_patch_data_91f_8)/
+ sizeof(wifi_core_patch_data_91f_8[0]));
+ if (ret)
+ goto err;
+ }
+ if (priv->version == WLAN_VERSION_90_D
+ || priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio32_polling(priv, wlan_test_mode_digital32_90,
+ sizeof(wlan_test_mode_digital32_90) /
+ sizeof(wlan_test_mode_digital32_90[0]));
+ if(ret)
+ goto err;
+ }
+ if (priv->version == WLAN_VERSION_90_D
+ || priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio32_polling(priv,
+ wifi_test_mode_agc_patch32_90,
+ sizeof(wifi_test_mode_agc_patch32_90) /
+ sizeof(wifi_test_mode_agc_patch32_90[0]));
+ if(ret)
+ goto err;
+ }
+
+ if (priv->version == WLAN_VERSION_90_D
+ || priv->version == WLAN_VERSION_90_E) {
+ ret = wlan_write_sdio32_polling(priv,
+ wifi_test_mode_rx_notch_32_90,
+ sizeof(wifi_test_mode_rx_notch_32_90) /
+ sizeof(wifi_test_mode_rx_notch_32_90[0]));
+ if(ret)
+ goto err;
+ }
+
+ ret = wlan_sdio_set_default_notch_polling(priv);
+ if(ret)
+ goto err;
+
+ atomic_set(&sdio_init_complete, 1);
+ rda_mci_enable_sdio_irq(priv->MmcCard->host, 1);
+ priv->sdio_irq_enable = TRUE;
+
+err:
+
+ LEAVE();
+ return ret;
+}
+int wlan_assoc_power_save(wlan_private * priv)
+{
+ int ret = 0;
+ ENTER();
+ if (priv->version == WLAN_VERSION_91){
+ ret = wlan_set_core_init_patch(priv, wifi_assoc_power_save_data_32_91,
+ sizeof(wifi_assoc_power_save_data_32_91) / sizeof(wifi_assoc_power_save_data_32_91[0]));
+ }
+
+ LEAVE();
+ return ret;
+}
+int wlan_set_phy_timeout(wlan_private * priv)
+{
+ int ret = 0;
+ if ((priv->version == WLAN_VERSION_90_D) ||
+ (priv->version == WLAN_VERSION_90_E)) {
+ ret = wlan_write_sdio32_polling(priv,
+ wifi_phy_timeout_cfg_90,
+ sizeof(wifi_phy_timeout_cfg_90) /
+ sizeof(wifi_phy_timeout_cfg_90[0]));
+ } else if ((priv->version == WLAN_VERSION_91) ||
+ (priv->version == WLAN_VERSION_91_E) || priv->version == WLAN_VERSION_91_F) {
+ ret = wlan_write_sdio32_polling(priv,
+ wifi_phy_timeout_cfg_91e,
+ sizeof(wifi_phy_timeout_cfg_91e) /
+ sizeof(wifi_phy_timeout_cfg_91e[0]));
+ }
+ return ret;
+}
+