From d4a1bd480003f3e1a0590bc46fbcb24f05652ca7 Mon Sep 17 00:00:00 2001 From: tzh <tanzhtanzh@gmail.com> Date: Thu, 15 Aug 2024 06:56:47 +0000 Subject: [PATCH] feat(wfit/bt): update aic8800 wifi/bt drive and hal --- longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c | 131 +++++++++++++++++++++++++++++-------------- 1 files changed, 88 insertions(+), 43 deletions(-) diff --git a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c old mode 100644 new mode 100755 index 141e59e..babf6dc --- a/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c +++ b/longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aicsdio.c @@ -80,37 +80,70 @@ int aicbsp_set_subsys(int subsys, int state) { - static int cur_state; - static int aic_power_state; + static int pre_power_map; + int cur_power_map; + int pre_power_state; + int cur_power_state; mutex_lock(&aicbsp_power_lock); + cur_power_map = pre_power_map; if (state) - aic_power_state |= (1 << subsys); + cur_power_map |= (1 << subsys); else - aic_power_state &= ~(1 << subsys); + cur_power_map &= ~(1 << subsys); + + pre_power_state = pre_power_map > 0; + cur_power_state = cur_power_map > 0; sdio_dbg("%s, subsys: %s, state to: %d\n", __func__, aicbsp_subsys_name(subsys), state); - if (cur_state != (aic_power_state > 0)) { - cur_state = (aic_power_state > 0); - sdio_dbg("%s, power state change to %d dure to %s\n", __func__, cur_state, aicbsp_subsys_name(subsys)); - if (cur_state) { - aicbsp_platform_power_on(); - aicbsp_sdio_init(); - aicbsp_driver_fw_init(aicbsp_sdiodev); + if (cur_power_state != pre_power_state) { + sdio_dbg("%s, power state change to %d dure to %s\n", __func__, cur_power_state, aicbsp_subsys_name(subsys)); + if (cur_power_state) { + if (aicbsp_platform_power_on() < 0) + goto err0; + if (aicbsp_sdio_init()) + goto err1; + if (!aicbsp_sdiodev) + goto err2; + if (aicbsp_driver_fw_init(aicbsp_sdiodev)) + goto err3; aicbsp_sdio_release(aicbsp_sdiodev); } else { aicbsp_sdio_exit(); aicbsp_platform_power_off(); } } else { - sdio_dbg("%s, power state no need to change\n", __func__); + sdio_dbg("%s, power state no need to change, current: %d\n", __func__, cur_power_state); } + pre_power_map = cur_power_map; mutex_unlock(&aicbsp_power_lock); - return cur_state > 0; + return cur_power_state; + +err3: + aicbsp_sdio_release(aicbsp_sdiodev); + +err2: + aicbsp_sdio_exit(); + +err1: + aicbsp_platform_power_off(); + +err0: + sdio_dbg("%s, fail to set %s power state to %d\n", __func__, aicbsp_subsys_name(subsys), state); + mutex_unlock(&aicbsp_power_lock); + return -1; } EXPORT_SYMBOL_GPL(aicbsp_set_subsys); + +void *aicbsp_get_drvdata(void *args) +{ + (void)args; + if (aicbsp_sdiodev) + return aicbsp_sdiodev->bus_if; + return dev_get_drvdata((const struct device *)args); +} static int aicbsp_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) @@ -121,12 +154,12 @@ int err = -ENODEV; sdio_dbg("%s:%d\n", __func__, func->num); - host = func->card->host; if (func->num != 2) { return err; } func = func->card->sdio_func[1 - 1]; //replace 2 with 1 + host = func->card->host; sdio_dbg("%s after replace:%d\n", __func__, func->num); bus_if = kzalloc(sizeof(struct aicwf_bus), GFP_KERNEL); @@ -155,6 +188,7 @@ if (aicwf_sdio_bus_init(sdiodev) == NULL) { sdio_err("sdio bus init err\r\n"); + err = -1; goto fail; } host->caps |= MMC_CAP_NONREMOVABLE; @@ -177,17 +211,20 @@ struct aic_sdio_dev *sdiodev = NULL; sdio_dbg("%s\n", __func__); - host = func->card->host; - host->caps &= ~MMC_CAP_NONREMOVABLE; - bus_if = dev_get_drvdata(&func->dev); + bus_if = aicbsp_get_drvdata(&func->dev); if (!bus_if) { - return; + sdio_dbg("%s: allready unregister\n", __func__); + goto done; } sdiodev = bus_if->bus_priv.sdio; if (!sdiodev) { - return; + goto done; } + + func = sdiodev->func; + host = func->card->host; + host->caps &= ~MMC_CAP_NONREMOVABLE; aicwf_sdio_release(sdiodev); aicwf_sdio_func_deinit(sdiodev); @@ -195,6 +232,9 @@ dev_set_drvdata(&sdiodev->func->dev, NULL); kfree(sdiodev); kfree(bus_if); + +done: + aicbsp_sdiodev = NULL; sdio_dbg("%s done\n", __func__); } @@ -276,6 +316,7 @@ return 0; } + aicbsp_unreg_sdio_notify(); sunxi_wlan_set_power(0); return -1; } @@ -296,12 +337,12 @@ } #endif -void aicbsp_sdio_init(void) +int aicbsp_sdio_init(void) { - if (sdio_register_driver(&aicbsp_sdio_driver)) { - } else { - //may add mmc_rescan here - } + if (sdio_register_driver(&aicbsp_sdio_driver)) + return -1; + + return 0; } void aicbsp_sdio_exit(void) @@ -541,9 +582,9 @@ static void aicwf_sdio_bus_stop(struct device *dev) { - struct aicwf_bus *bus_if = dev_get_drvdata(dev); + struct aicwf_bus *bus_if = aicbsp_get_drvdata(dev); struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - int ret; + int ret = 0; aicwf_sdio_pwrctl_timer(sdiodev, 0); sdio_dbg("%s\n", __func__); @@ -553,18 +594,19 @@ sdiodev->pwrctl_tsk = NULL; } - sdio_dbg("%s:pwrctl stopped\n", __func__); - bus_if->state = BUS_DOWN_ST; - ret = down_interruptible(&sdiodev->tx_priv->txctl_sema); - if (ret) - sdio_err("down txctl_sema fail\n"); + if (sdiodev->tx_priv) { + ret = down_interruptible(&sdiodev->tx_priv->txctl_sema); + if (ret) + sdio_err("down txctl_sema fail\n"); + } aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST); - if (!ret) - up(&sdiodev->tx_priv->txctl_sema); - aicwf_frame_queue_flush(&sdiodev->tx_priv->txq); - sdio_dbg("exit %s\n", __func__); + if (sdiodev->tx_priv) { + if (!ret) + up(&sdiodev->tx_priv->txctl_sema); + aicwf_frame_queue_flush(&sdiodev->tx_priv->txq); + } } struct sk_buff *aicwf_sdio_readframes(struct aic_sdio_dev *sdiodev) @@ -755,7 +797,7 @@ if (sdiodev->tx_priv->cmd_txstate) { int timeout = msecs_to_jiffies(CMD_TX_TIMEOUT); - ret = wait_event_interruptible_timeout(sdiodev->tx_priv->cmd_txdone_wait, \ + ret = wait_event_timeout(sdiodev->tx_priv->cmd_txdone_wait, \ !(sdiodev->tx_priv->cmd_txstate), timeout); } @@ -1080,12 +1122,11 @@ void aicwf_sdio_release(struct aic_sdio_dev *sdiodev) { struct aicwf_bus *bus_if; - struct aicwf_rx_priv *rx_priv = NULL; int ret = 0; sdio_dbg("%s\n", __func__); - bus_if = dev_get_drvdata(sdiodev->dev); + bus_if = sdiodev->bus_if; bus_if->state = BUS_DOWN_ST; sdio_claim_host(sdiodev->func); @@ -1097,13 +1138,17 @@ sdio_release_irq(sdiodev->func); sdio_release_host(sdiodev->func); - aicwf_tx_deinit(sdiodev->tx_priv); if (sdiodev->dev) aicwf_bus_deinit(sdiodev->dev); - rx_priv = sdiodev->rx_priv; - if (rx_priv != NULL) - aicwf_rx_deinit(rx_priv); - sdio_dbg("exit cfg80211 deinit\n"); + + if (sdiodev->tx_priv) + aicwf_tx_deinit(sdiodev->tx_priv); + + if (sdiodev->rx_priv) + aicwf_rx_deinit(sdiodev->rx_priv); + + if (sdiodev->cmd_mgr.state == RWNX_CMD_MGR_STATE_INITED) + rwnx_cmd_mgr_deinit(&sdiodev->cmd_mgr); } int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev) -- Gitblit v1.6.2