diff options
Diffstat (limited to 'drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c')
-rwxr-xr-x | drivers/net/wireless/rda/rda_wlan/wlan_sdio_patch.c | 429 |
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; +} + |