Ejemplo n.º 1
0
/*
 * ---------------------------------------------------------------------------
 *  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() */
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}