/*
 * Copyright (c) 2007-2008 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/**
  *  The power saving manager is to save the power as much as possible.
  *  Generally speaking, it controls:
  *
  *         - when to sleep
  *         -
  *
  */
#include "cprecomp.h"

void zfPowerSavingMgrInit(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    wd->sta.powerSaveMode = ZM_STA_PS_NONE;
    wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
    wd->sta.psMgr.isSleepAllowed = 0;
    wd->sta.psMgr.maxSleepPeriods = 1;
    wd->sta.psMgr.ticks = 0;
    wd->sta.psMgr.sleepAllowedtick = 0;
}

static u16_t zfPowerSavingMgrHandlePsNone(zdev_t* dev, u8_t *isWakeUpRequired)
{
    u16_t ret = 0;
    zmw_get_wlan_dev(dev);

    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            *isWakeUpRequired = 0;
            break;

        case ZM_PS_MSG_STATE_T1:
        case ZM_PS_MSG_STATE_T2:
        case ZM_PS_MSG_STATE_SLEEP:
        default:
            *isWakeUpRequired = 1;
zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n");
            if ( zfStaIsConnected(dev) )
            {
                zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
                //zfSendNullData(dev, 0);
                ret = 1;
            }

            wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;
            break;
    }
    return ret;
}

static void zfPowerSavingMgrHandlePs(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            //zm_debug_msg0("zfPowerSavingMgrHandlePs: Prepare to sleep...\n");
            //wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
            break;

        case ZM_PS_MSG_STATE_T1:
        case ZM_PS_MSG_STATE_T2:
        case ZM_PS_MSG_STATE_SLEEP:
        default:
            break;
    }
}

void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode)
{
    u16_t sendNull = 0;
    u8_t isWakeUpRequired = 0;

    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    zm_debug_msg1("mode = ", mode);

    if (mode > ZM_STA_PS_LIGHT)
    {
        zm_debug_msg0("return - wrong power save mode");
        return;
    }

    zmw_enter_critical_section(dev);

    #if 1
    switch(mode)
    {
        case ZM_STA_PS_NONE:
            sendNull = zfPowerSavingMgrHandlePsNone(dev, &isWakeUpRequired);
            break;

        case ZM_STA_PS_FAST:
        case ZM_STA_PS_LIGHT:
            wd->sta.psMgr.maxSleepPeriods = 1;
            zfPowerSavingMgrHandlePs(dev);
            break;

        case ZM_STA_PS_MAX:
            wd->sta.psMgr.maxSleepPeriods = ZM_PS_MAX_SLEEP_PERIODS;
            zfPowerSavingMgrHandlePs(dev);
            break;
    }
    #else
    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            if ( mode != ZM_STA_PS_NONE )
            {
zm_debug_msg0("zfPowerSavingMgrSetMode: switch from ZM_PS_MSG_STATE_ACTIVE to ZM_PS_MSG_STATE_T1\n");
                // Stall the TX & start to wait the pending TX to be completed
                wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
            }
            break;

        case ZM_PS_MSG_STATE_SLEEP:
            break;
    }
    #endif

    wd->sta.powerSaveMode = mode;
    zmw_leave_critical_section(dev);

    if ( isWakeUpRequired )
    {
        zfHpPowerSaveSetState(dev, 0);
        wd->sta.psMgr.tempWakeUp = 0;
    }

    if ( zfStaIsConnected(dev)
         && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
    {
        switch(mode)
        {
            case ZM_STA_PS_NONE:
                zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
                break;

            case ZM_STA_PS_FAST:
            case ZM_STA_PS_MAX:
            case ZM_STA_PS_LIGHT:
                zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
                break;

            default:
                zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
                break;
        }
    }

    if (sendNull == 1)
    {
        zfSendNullData(dev, 0);
    }

    return;
}

static void zfPowerSavingMgrNotifyPSToAP(zdev_t *dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    if ( (wd->sta.psMgr.tempWakeUp != 1)&&
         (wd->sta.psMgr.lastTxUnicastFrm != wd->commTally.txUnicastFrm ||
          wd->sta.psMgr.lastTxBroadcastFrm != wd->commTally.txBroadcastFrm ||
          wd->sta.psMgr.lastTxMulticastFrm != wd->commTally.txMulticastFrm) )
    {
        zmw_enter_critical_section(dev);
        wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
        wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
        wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
        zmw_leave_critical_section(dev);

        zfSendNullData(dev, 1);
    }
}

static void zfPowerSavingMgrOnHandleT1(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    // If the tx Q is not empty...return
    if ( zfIsVtxqEmpty(dev) == FALSE )
    {
        return;
    }

zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n");

    // The the HAL TX Q is not empty...return
    if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
    {
        return;
    }

zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n");

    zmw_enter_critical_section(dev);

    if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
    {
        if (wd->sta.ReceivedPktRatePerSecond > 200)
        {
            zmw_leave_critical_section(dev);
            return;
        }

        if ( zfStaIsConnected(dev)
             && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
        {
            if (wd->sta.psMgr.sleepAllowedtick) {
                wd->sta.psMgr.sleepAllowedtick--;
                zmw_leave_critical_section(dev);
                return;
            }
        }
    }

    wd->sta.psMgr.state = ZM_PS_MSG_STATE_T2;

    zmw_leave_critical_section(dev);

    // Send the Null pkt to AP to notify that I'm going to sleep
    if ( zfStaIsConnected(dev) )
    {
zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n");
        zfPowerSavingMgrNotifyPSToAP(dev);
    }

    // Stall the TX now
    // zfTxEngineStop(dev);
}

static void zfPowerSavingMgrOnHandleT2(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    // Wait until the Null pkt is transmitted
    if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) )
    {
        return;
    }

    zmw_enter_critical_section(dev);
    wd->sta.psMgr.state = ZM_PS_MSG_STATE_SLEEP;
    wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm;
    wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm;
    wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm;
    zmw_leave_critical_section(dev);

    // Let CHIP sleep now
zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n");
    zfHpPowerSaveSetState(dev, 1);
    wd->sta.psMgr.tempWakeUp = 0;
}

u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev)
{
    u8_t isSleeping = FALSE;
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);
    if ( wd->sta.psMgr.state == ZM_PS_MSG_STATE_SLEEP ||
         wd->sta.psMgr.state == ZM_PS_MSG_STATE_T2)
    {
        isSleeping = TRUE;
    }
    zmw_leave_critical_section(dev);
    return isSleeping;
}

static u8_t zfPowerSavingMgrIsIdle(zdev_t *dev)
{
    u8_t isIdle = 0;

    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    zmw_enter_critical_section(dev);

    if ( zfStaIsConnected(dev) && wd->sta.psMgr.isSleepAllowed == 0 )
    {
        goto done;
    }

    if ( wd->sta.bChannelScan )
    {
        goto done;
    }

    if ( zfStaIsConnecting(dev) )
    {
        goto done;
    }

    if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT)
    {
        if (wd->sta.ReceivedPktRatePerSecond > 200)
        {
            goto done;
        }

        if ( zfStaIsConnected(dev)
             && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) )
        {
            if (wd->sta.psMgr.sleepAllowedtick) {
                wd->sta.psMgr.sleepAllowedtick--;
                goto done;
            }
        }
    }

    isIdle = 1;

done:
    zmw_leave_critical_section(dev);

    if ( zfIsVtxqEmpty(dev) == FALSE )
    {
        isIdle = 0;
    }

    return isIdle;
}

static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev)
{
    u8_t isIdle;

    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    isIdle = zfPowerSavingMgrIsIdle(dev);

    if ( isIdle == 0 )
    {
        return;
    }

    zmw_enter_critical_section(dev);

    switch(wd->sta.powerSaveMode)
    {
        case ZM_STA_PS_NONE:
            break;

        case ZM_STA_PS_MAX:
        case ZM_STA_PS_FAST:
        case ZM_STA_PS_LIGHT:
            zm_debug_msg0("zfPowerSavingMgrSleepIfIdle: IDLE so slep now...\n");
            wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1;
            break;
    }

    zmw_leave_critical_section(dev);
}

static void zfPowerSavingMgrDisconnectMain(zdev_t* dev)
{
#ifdef ZM_ENABLE_DISCONNECT_PS
    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            zfPowerSavingMgrSleepIfIdle(dev);
            break;

        case ZM_PS_MSG_STATE_SLEEP:
            break;

        case ZM_PS_MSG_STATE_T1:
            zfPowerSavingMgrOnHandleT1(dev);
            break;

        case ZM_PS_MSG_STATE_T2:
            zfPowerSavingMgrOnHandleT2(dev);
            break;
    }
#else
    zfPowerSavingMgrWakeup(dev);
#endif
}

static void zfPowerSavingMgrInfraMain(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            zfPowerSavingMgrSleepIfIdle(dev);
            break;

        case ZM_PS_MSG_STATE_SLEEP:
            break;

        case ZM_PS_MSG_STATE_T1:
            zfPowerSavingMgrOnHandleT1(dev);
            break;

        case ZM_PS_MSG_STATE_T2:
            zfPowerSavingMgrOnHandleT2(dev);
            break;
    }
}

void zfPowerSavingMgrAtimWinExpired(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

//printk("zfPowerSavingMgrAtimWinExpired #1\n");
    if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE )
    {
        return;
    }

//printk("zfPowerSavingMgrAtimWinExpired #2\n");
    // if we received any ATIM window from the others to indicate we have buffered data
    // at the other station, we can't go to sleep
    if ( wd->sta.recvAtim )
    {
        wd->sta.recvAtim = 0;
        zm_debug_msg0("Can't sleep due to receving ATIM window!");
        return;
    }

    // if we are the one to tx beacon during last beacon interval. we can't go to sleep
    // since we need to be alive to respond the probe request!
    if ( wd->sta.txBeaconInd )
    {
        zm_debug_msg0("Can't sleep due to just transmit a beacon!");
        return;
    }

    // If we buffer any data for the other stations. we could not go to sleep
    if ( wd->sta.ibssPrevPSDataCount != 0 )
    {
        zm_debug_msg0("Can't sleep due to buffering data for the others!");
        return;
    }

    // before sleeping, we still need to notify the others by transmitting null
    // pkt with power mgmt bit turned on.
    zfPowerSavingMgrOnHandleT1(dev);
}

static void zfPowerSavingMgrIBSSMain(zdev_t* dev)
{
    // wait for the end of
    // if need to wait to know if we are the one to transmit the beacon
    // during the beacon interval. If it's me, we can't go to sleep.

    zmw_get_wlan_dev(dev);

    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
        case ZM_PS_MSG_STATE_SLEEP:
        case ZM_PS_MSG_STATE_T1:
            break;

        case ZM_PS_MSG_STATE_T2:
            zfPowerSavingMgrOnHandleT2(dev);
            break;
    }

    return;
}

#if 1
void zfPowerSavingMgrMain(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    switch (wd->sta.adapterState)
    {
    case ZM_STA_STATE_DISCONNECT:
        zfPowerSavingMgrDisconnectMain(dev);
        break;
    case ZM_STA_STATE_CONNECTED:
        {
            if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) {
                zfPowerSavingMgrInfraMain(dev);
            } else if (wd->wlanMode == ZM_MODE_IBSS) {
                zfPowerSavingMgrIBSSMain(dev);
            }
        }
        break;
    case ZM_STA_STATE_CONNECTING:
    default:
        break;
    }
}
#else
void zfPowerSavingMgrMain(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);

    if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE )
    {
        return;
    }

    switch(wd->sta.psMgr.state)
    {
        case ZM_PS_MSG_STATE_ACTIVE:
            goto check_sleep;
            break;

        case ZM_PS_MSG_STATE_SLEEP:
            goto sleeping;
            break;

        case ZM_PS_MSG_STATE_T1:
            zfPowerSavingMgrOnHandleT1(dev);
            break;

        case ZM_PS_MSG_STATE_T2:
            zfPowerSavingMgrOnHandleT2(dev);
            break;
    }

    return;

sleeping:
    return;

check_sleep:
    zfPowerSavingMgrSleepIfIdle(dev);
    return;
}
#endif

#ifdef ZM_ENABLE_POWER_SAVE
void zfPowerSavingMgrWakeup(zdev_t* dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

//zm_debug_msg0("zfPowerSavingMgrWakeup");

    //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 ))
    if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE )
    {
        zmw_enter_critical_section(dev);

        wd->sta.psMgr.isSleepAllowed = 0;
        wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE;

        if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE )
            wd->sta.psMgr.tempWakeUp = 1;

        zmw_leave_critical_section(dev);

        // Wake up the CHIP now!!
        zfHpPowerSaveSetState(dev, 0);
    }
}
#else
void zfPowerSavingMgrWakeup(zdev_t* dev)
{
}
#endif

void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf)
{
    u8_t   length, bitmap;
    u16_t  offset, n1, n2, q, r;
    zbuf_t* psBuf;

    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE  )
    //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP )
    {
        return;
    }

    wd->sta.psMgr.isSleepAllowed = 1;

    offset = zfFindElement(dev, buf, ZM_WLAN_EID_TIM);
    if (offset != 0xffff)
    {
        length = zmw_rx_buf_readb(dev, buf, offset+1);

        if ( length > 3 )
        {
            n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0);
            n2 = length + n1 - 4;
            q = wd->sta.aid >> 3;
            r = wd->sta.aid & 7;

            if ((q >= n1) && (q <= n2))
            {
                bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1);

                if ( (bitmap >> r) &  ZM_BIT_0 )
                {
                    //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST )
                    if ( 0 )
                    {
                        wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1;
                        //zfSendPSPoll(dev);
                        zfSendNullData(dev, 0);
                    }
                    else
                    {
                        if ((wd->sta.qosInfo&0xf) != 0xf)
                        {
                            /* send ps-poll */
                            //printk("zfSendPSPoll #1\n");

                            wd->sta.psMgr.isSleepAllowed = 0;

                            switch (wd->sta.powerSaveMode)
                            {
                            case ZM_STA_PS_MAX:
                            case ZM_STA_PS_FAST:
                                //zm_debug_msg0("wake up and send PS-Poll\n");
                                zfSendPSPoll(dev);
                                break;
                            case ZM_STA_PS_LIGHT:
                                zm_debug_msg0("wake up and send null data\n");

                                zmw_enter_critical_section(dev);
                                wd->sta.psMgr.sleepAllowedtick = 400;
                                zmw_leave_critical_section(dev);

                                zfSendNullData(dev, 0);
                                break;
                            }

                            wd->sta.psMgr.tempWakeUp = 0;
                        }
                    }
                }
            }
        }
    }

    while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL)
    {
        zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0);
    }

    //printk("zfPowerSavingMgrProcessBeacon #1\n");
    zfPowerSavingMgrMain(dev);
}

void zfPowerSavingMgrConnectNotify(zdev_t *dev)
{
    zmw_get_wlan_dev(dev);

    if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE )
    {
        switch(wd->sta.powerSaveMode)
        {
            case ZM_STA_PS_NONE:
                zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
                break;

            case ZM_STA_PS_FAST:
            case ZM_STA_PS_MAX:
            case ZM_STA_PS_LIGHT:
                zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval);
                break;

            default:
                zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval);
                break;
        }
    }
}

void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev)
{
    zmw_get_wlan_dev(dev);
    zmw_declare_for_critical_section();

    /* disable TBTT interrupt when change from connection to disconnect */
    if (zfStaIsDisconnect(dev)) {
        zfHpPowerSaveSetMode(dev, 0, 0, 0);
        zfPowerSavingMgrWakeup(dev);
        return;
    }

    zmw_enter_critical_section(dev);
    wd->sta.psMgr.ticks++;

    if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods )
    {
        zmw_leave_critical_section(dev);
        return;
    }
    else
    {
        wd->sta.psMgr.ticks = 0;
    }

    zmw_leave_critical_section(dev);

    zfPowerSavingMgrWakeup(dev);
}

/* Leave an empty line below to remove warning message on some compiler */

