/* * --------------------------------------------------------------------------- * unifi_suspend * * Handles a suspend request from the SDIO driver. * * Arguments: * ospriv Pointer to OS driver context. * * --------------------------------------------------------------------------- */ void unifi_suspend(void *ospriv) { unifi_priv_t *priv = ospriv; int interfaceTag=0; /* For powered suspend, tell the resume's wifi_on() not to reinit UniFi */ priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; unifi_trace(priv, UDBG1, "unifi_suspend: wol_suspend %d, enable_wol %d", priv->wol_suspend, enable_wol ); /* Stop network traffic. */ /* need to stop all the netdevices*/ for( interfaceTag=0;interfaceTag<CSR_WIFI_NUM_INTERFACES;interfaceTag++) { netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; if (interfacePriv->netdev_registered == 1) { if( priv->wol_suspend ) { unifi_trace(priv, UDBG1, "unifi_suspend: Don't netif_carrier_off"); } else { unifi_trace(priv, UDBG1, "unifi_suspend: netif_carrier_off"); netif_carrier_off(priv->netdev[interfaceTag]); } UF_NETIF_TX_STOP_ALL_QUEUES(priv->netdev[interfaceTag]); } } unifi_trace(priv, UDBG1, "unifi_suspend: suspend SME"); sme_sys_suspend(priv); } /* unifi_suspend() */
int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_power_t cfg_power; int rc; if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } switch (cfg_power) { case UNIFI_CFG_POWER_OFF: rc = sme_sys_suspend(priv); if (rc) { return rc; } break; case UNIFI_CFG_POWER_ON: rc = sme_sys_resume(priv); if (rc) { return rc; } break; default: unifi_error(priv, "WIFI POWER: Unknown value.\n"); return -EINVAL; } return 0; }
int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg) { int r; CsrInt32 csr_r; int already_in_test = priv->ptest_mode; /* Ensure that sme_sys_suspend() doesn't power down the chip because: * 1) Power is needed anyway for ptest. * 2) The app code uses the START ioctl as a reset, so it gets called * multiple times. If the app stops the XAPs, but the power_down/up * sequence doesn't actually power down the chip, there can be problems * resetting, because part of the power_up sequence disables function 1 */ priv->ptest_mode = 1; /* Suspend the SME and UniFi */ r = sme_sys_suspend(priv); if (r) { unifi_error(priv, "unifi_putest_start: failed to suspend UniFi\n"); return r; } /* Application may have stopped the XAPs, but they are needed for reset */ if (already_in_test) { csr_r = unifi_start_processors(priv->card); if (csr_r) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } } else { /* Ensure chip is powered for the case where there's no unifi_helper */ csr_r = CsrSdioPowerOn(priv->sdio); if (csr_r) { unifi_error(priv, "CsrSdioPowerOn status %d\n", csr_r); } } csr_r = unifi_init(priv->card); if (csr_r && (csr_r != 1)) { unifi_error(priv, "unifi_putest_start: failed to init UniFi\n"); return convert_csr_error(csr_r); } return 0; }
int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_power_t cfg_power; int rc; int wol; if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } switch (cfg_power) { case UNIFI_CFG_POWER_OFF: priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; rc = sme_sys_suspend(priv); if (rc) { return rc; } break; case UNIFI_CFG_POWER_ON: wol = priv->wol_suspend; rc = sme_sys_resume(priv); if (rc) { return rc; } if (wol) { /* Kick the BH to ensure pending transfers are handled when * a suspend happened with card powered. */ unifi_send_signal(priv->card, NULL, 0, NULL); } break; default: unifi_error(priv, "WIFI POWER: Unknown value.\n"); return -EINVAL; } return 0; }