/*
 * ---------------------------------------------------------------------------
 * FILE:     unifi_pdu_processing.c
 *
 * PURPOSE:
 *      This file provides the PDU handling functionality before it gets sent to unfi and after
 *      receiving a PDU from unifi
 *
 * Copyright (C) 2010 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */

#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/vmalloc.h>

#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "csr_time.h"
#include "unifi_priv.h"
#include <net/pkt_sched.h>

#ifdef CSR_SUPPORT_SME
static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
                                                        tx_buffered_packets_t* buffered_pkt)
{
    struct sk_buff *skb ;
    u32 align_offset;

    if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){
        return;
    }

    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
    align_offset = (u32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
    if(align_offset){
        skb_pull(skb, align_offset);
    }

    buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
    buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length;
    buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
    buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
}
#endif

void
unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority,
                          CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag,
                          u16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl,
                          CSR_PROCESS_ID leSenderProcessId, u8 *peerMacAddress,
                          CSR_SIGNAL *signal)
{

    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
    netInterface_priv_t *interfacePriv;
    u8 ba_session_idx = 0;
    ba_session_tx_struct *ba_session = NULL;
    u8 *ba_addr = NULL;

    interfacePriv = priv->interfacePriv[interfaceTag];

	unifi_trace(priv, UDBG5,
		"In unifi_frame_ma_packet_req, Frame for Peer: %pMF\n",
		peerMacAddress);
    signal->SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
    signal->SignalPrimitiveHeader.ReceiverProcessId = 0;
    signal->SignalPrimitiveHeader.SenderProcessId = leSenderProcessId;

    /* Fill the MA-PACKET.req */
    req->Priority = priority;
    unifi_trace(priv, UDBG3, "Tx Frame with Priority: 0x%x\n", req->Priority);

    /* A value of 0 is used for auto selection of rates. But for P2P GO case
     * for action frames the rate is governed by SME. Hence instead of 0,
     * the rate is filled in with the value passed here
     */
    req->TransmitRate = TransmitRate;

    /* packets from netdev then no confirm required but packets from
     * Nme/Sme eapol data frames requires the confirmation
     */
    req->TransmissionControl = transmissionControl;
    req->VirtualInterfaceIdentifier =
           uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag);
    memcpy(req->Ra.x, peerMacAddress, ETH_ALEN);

    if (hostTag == 0xffffffff) {
        req->HostTag = interfacePriv->tag++;
        req->HostTag |= 0x40000000;
        unifi_trace(priv, UDBG3, "new host tag assigned = 0x%x\n", req->HostTag);
        interfacePriv->tag &= 0x0fffffff;
    } else {
        req->HostTag = hostTag;
        unifi_trace(priv, UDBG3, "host tag got from SME  = 0x%x\n", req->HostTag);
    }
    /* check if BA session exists for the peer MAC address on same tID */
    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
        ba_addr = peerMacAddress;
    }else{
        ba_addr = interfacePriv->bssid.a;
    }
    for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
        ba_session = interfacePriv->ba_session_tx[ba_session_idx];
        if (ba_session){
           if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == priority)){
                req->TransmissionControl |= CSR_ALLOW_BA;
                break;
            }
        }
    }

    unifi_trace(priv, UDBG5, "leaving unifi_frame_ma_packet_req\n");
}

#ifdef CSR_SUPPORT_SME

#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001
#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002

static
int frame_and_send_queued_pdu(unifi_priv_t* priv, tx_buffered_packets_t* buffered_pkt,
            CsrWifiRouterCtrlStaInfo_t *staRecord, u8 moreData , u8 eosp)
{

    CSR_SIGNAL signal;
    bulk_data_param_t bulkdata;
    int result;
    u8 toDs, fromDs, macHeaderLengthInBytes = MAC_HEADER_SIZE;
    u8 *qc;
    u16 *fc = (u16*)(buffered_pkt->bulkdata.os_data_ptr);
    unsigned long lock_flags;
    unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu with moreData: %d , EOSP: %d\n", moreData, eosp);
    unifi_frame_ma_packet_req(priv, buffered_pkt->priority, buffered_pkt->rate, buffered_pkt->hostTag,
               buffered_pkt->interfaceTag, buffered_pkt->transmissionControl,
               buffered_pkt->leSenderProcessId, buffered_pkt->peerMacAddress.a, &signal);
    bulkdata.d[0].os_data_ptr = buffered_pkt->bulkdata.os_data_ptr;
    bulkdata.d[0].data_length = buffered_pkt->bulkdata.data_length;
    bulkdata.d[0].os_net_buf_ptr = buffered_pkt->bulkdata.os_net_buf_ptr;
    bulkdata.d[0].net_buf_length = buffered_pkt->bulkdata.net_buf_length;
    bulkdata.d[1].os_data_ptr = NULL;
    bulkdata.d[1].data_length = 0;
    bulkdata.d[1].os_net_buf_ptr =0;
    bulkdata.d[1].net_buf_length =0;

    if(moreData) {
        *fc |= cpu_to_le16(IEEE802_11_FC_MOREDATA_MASK);
    } else {
        *fc &= cpu_to_le16(~IEEE802_11_FC_MOREDATA_MASK);
    }

    if((staRecord != NULL)&& (staRecord->wmmOrQosEnabled == TRUE))
    {
        unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu WMM Enabled: %d \n", staRecord->wmmOrQosEnabled);

        toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
        fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;

        switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
        {
            case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
            case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
                /* If both are set then the Address4 exists (only for AP) */
                if (fromDs && toDs) {
                    /* 6 is the size of Address4 field */
                    macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
                } else {
                    macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
                }

                /* If order bit set then HT control field is the part of MAC header */
                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
                    macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
                } else {
                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
                }
                *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
                break;
            default:
                if (fromDs && toDs)
                    macHeaderLengthInBytes += 6;
        }

    }
    result = ul_send_signal_unpacked(priv, &signal, &bulkdata);
    if(result){
        _update_buffered_pkt_params_after_alignment(priv, &bulkdata, buffered_pkt);
    }

 /* Decrement the packet counts queued in driver */
    if (result != -ENOSPC) {
        /* protect entire counter updation by disabling preemption */
        if (!priv->noOfPktQueuedInDriver) {
            unifi_error(priv, "packets queued in driver 0 still decrementing\n");
        } else {
            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
            priv->noOfPktQueuedInDriver--;
            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
        }
        /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
        if (staRecord) {
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            if (!staRecord->noOfPktQueued) {
                unifi_error(priv, "packets queued in driver per station is 0 still decrementing\n");
            } else {
                staRecord->noOfPktQueued--;
            }
            /* if the STA alive probe frame has failed then reset the saved host tag */
            if (result){
                if (staRecord->nullDataHostTag == buffered_pkt->hostTag){
                    staRecord->nullDataHostTag = INVALID_HOST_TAG;
                }
            }
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }

    }
    return result;
}
#ifdef CSR_SUPPORT_SME
static
void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList)
{
    /* dequeue the tx data packets from the appropriate queue */
    tx_buffered_packets_t *tx_q_item = NULL;
    struct list_head *listHead;
    struct list_head *placeHolder;
    unsigned long lock_flags;


    unifi_trace(priv, UDBG5, "entering set_eosp_transmit_ctrl\n");
    /* check for list empty */
    if (list_empty(txList)) {
        unifi_warning(priv, "In set_eosp_transmit_ctrl, the list is empty\n");
        return;
    }

    /* return the last node , and modify it. */

    spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
    list_for_each_prev_safe(listHead, placeHolder, txList) {
        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
        tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
        tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
        unifi_trace(priv, UDBG1,
                "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n", tx_q_item->transmissionControl, tx_q_item->hostTag);
        unifi_trace(priv, UDBG3, "in set_eosp_transmit_ctrl no.of buffered frames %d\n", priv->noOfPktQueuedInDriver);
        break;
    }
    spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
    unifi_trace(priv, UDBG1, "List Empty %d\n", list_empty(txList));
    unifi_trace(priv, UDBG5, "leaving set_eosp_transmit_ctrl\n");
    return;
}

static
void send_vif_availibility_rsp(unifi_priv_t *priv, CSR_VIF_IDENTIFIER vif, CSR_RESULT_CODE resultCode)
{
    CSR_SIGNAL signal;
    CSR_MA_VIF_AVAILABILITY_RESPONSE *rsp;
    bulk_data_param_t *bulkdata = NULL;
    int r;

    unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode);

    memset(&signal, 0, sizeof(CSR_SIGNAL));
    rsp = &signal.u.MaVifAvailabilityResponse;
    rsp->VirtualInterfaceIdentifier = vif;
    rsp->ResultCode = resultCode;
    signal.SignalPrimitiveHeader.SignalId = CSR_MA_VIF_AVAILABILITY_RESPONSE_ID;
    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
    signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;

    /* Send the signal to UniFi */
    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
    if(r) {
        unifi_error(priv, "Availibility response sending failed %x status %d\n", vif, r);
    }
    else {
        unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r);
    }
}
#endif

static
void verify_and_accomodate_tx_packet(unifi_priv_t *priv)
{
    tx_buffered_packets_t *tx_q_item;
    unsigned long lock_flags;
    struct list_head *listHead, *list;
    struct list_head *placeHolder;
    u8 i, j, eospFramedeleted=0;
    u8 thresholdExcedeDueToBroadcast = TRUE;
    /* it will be made it interface Specific in the future when multi interfaces are supported ,
    right now interface 0 is considered */
    netInterface_priv_t *interfacePriv = priv->interfacePriv[0];
    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;

    unifi_trace(priv, UDBG3, "entering verify_and_accomodate_tx_packet\n");

    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        staInfo = interfacePriv->staInfo[i];
            if (staInfo && (staInfo->noOfPktQueued >= CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER)) {
            /* remove the first(oldest) packet from the all the access catogory, since data
             * packets for station record crossed the threshold limit (64 for AP supporting
             * 8 peers)
             */
            unifi_trace(priv, UDBG3, "number of station pkts queued=  %d for sta id = %d\n", staInfo->noOfPktQueued, staInfo->aid);
            for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
                list = &staInfo->dataPdu[j];
                spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                list_for_each_safe(listHead, placeHolder, list) {
                    tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
                    list_del(listHead);
                    thresholdExcedeDueToBroadcast = FALSE;
                    unifi_net_data_free(priv, &tx_q_item->bulkdata);
                    kfree(tx_q_item);
                    tx_q_item = NULL;
                    if (!priv->noOfPktQueuedInDriver) {
                        unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
                    } else {
                        /* protection provided by spinlock */
                        priv->noOfPktQueuedInDriver--;

                    }
                    /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
                    if (!staInfo->noOfPktQueued) {
                        unifi_error(priv, "packets queued in driver per station is 0 still decrementing in %s\n", __FUNCTION__);
                    } else {
                        spin_lock(&priv->staRecord_lock);
                        staInfo->noOfPktQueued--;
                        spin_unlock(&priv->staRecord_lock);
                    }
                    break;
                }
                spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
            }
        }
    }
    if (thresholdExcedeDueToBroadcast &&  interfacePriv->noOfbroadcastPktQueued > CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD ) {
        /* Remove the packets from genericMulticastOrBroadCastFrames queue
         * (the max packets in driver is reached due to broadcast/multicast frames)
         */
        spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
            if(eospFramedeleted){
                tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
                tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
                unifi_trace(priv, UDBG1, "updating eosp for next packet hostTag:= 0x%x ", tx_q_item->hostTag);
                eospFramedeleted =0;
                break;
            }

            if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){
               eospFramedeleted = 1;
            }
            unifi_trace(priv, UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n", tx_q_item->transmissionControl, tx_q_item->hostTag);
            list_del(listHead);
            unifi_net_data_free(priv, &tx_q_item->bulkdata);
            kfree(tx_q_item);
            priv->noOfPktQueuedInDriver--;
            spin_lock(&priv->staRecord_lock);
            interfacePriv->noOfbroadcastPktQueued--;
            spin_unlock(&priv->staRecord_lock);
            if(!eospFramedeleted){
                break;
            }
        }
        spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
    }
    unifi_trace(priv, UDBG3, "leaving verify_and_accomodate_tx_packet\n");
}

static
CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
                            struct list_head *list, CSR_SIGNAL *signal,
                            u8 requeueOnSamePos)
{

    /* queue the tx data packets on to appropriate queue */
    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
    tx_buffered_packets_t *tx_q_item;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n");
    if(!list) {
       unifi_error(priv, "List is not specified\n");
       return CSR_RESULT_FAILURE;
    }

    /* Removes aged packets & adds the incoming packet */
    if (priv->noOfPktQueuedInDriver >= CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING) {
        unifi_trace(priv, UDBG3, "number of pkts queued=  %d \n", priv->noOfPktQueuedInDriver);
        verify_and_accomodate_tx_packet(priv);
    }



    tx_q_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
    if (tx_q_item == NULL) {
        unifi_error(priv,
                "Failed to allocate %d bytes for tx packet record\n",
                sizeof(tx_buffered_packets_t));
        return CSR_RESULT_FAILURE;
    }

    /* disable the preemption */
    spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
    INIT_LIST_HEAD(&tx_q_item->q);
    /* fill the tx_q structure members */
    tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
    tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length;
    tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
    tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
    tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
    tx_q_item->hostTag = req->HostTag;
    tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId;
    tx_q_item->transmissionControl = req->TransmissionControl;
    tx_q_item->priority = req->Priority;
    tx_q_item->rate = req->TransmitRate;
    memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN);



    if (requeueOnSamePos) {
        list_add(&tx_q_item->q, list);
    } else {
        list_add_tail(&tx_q_item->q, list);
    }

    /* Count of packet queued in driver */
    priv->noOfPktQueuedInDriver++;
    spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
    unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
    return CSR_RESULT_SUCCESS;
}

#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
CsrResult unifi_reque_ma_packet_request (void *ospriv, u32 host_tag,
                                         u16 txStatus, bulk_data_desc_t *bulkDataDesc)
{
    CsrResult status = CSR_RESULT_SUCCESS;
    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
    netInterface_priv_t *interfacePriv;
    struct list_head *list = NULL;
    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
    bulk_data_param_t bulkData;
    CSR_SIGNAL signal;
    CSR_PRIORITY priority = 0;
    u16 interfaceTag = 0;
    unifi_TrafficQueue priority_q;
    u16 frameControl = 0, frameType = 0;
    unsigned long lock_flags;

    interfacePriv = priv->interfacePriv[interfaceTag];

    /* If the current mode is not AP or P2PGO then just return failure
     * to clear the hip slot
     */
    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) {
        return CSR_RESULT_FAILURE;
    }

    unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag);

    staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,
                                                                    (((u8 *) bulkDataDesc->os_data_ptr) + 4),
                                                                    interfaceTag);
    if (NULL == staRecord) {
        unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n");
        return CSR_RESULT_FAILURE;
    }

    /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure
     * to clear the hip slot associated with the Packet
     */
    if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) {
        if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
        {
            unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n");
            if (!staRecord->timRequestPendingFlag) {
                update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
            }
            else {
                /* Cache the TimSet value so that it will processed immidiatly after
                 * completing the current setTim Request
                 */
                staRecord->updateTimReqQueued = 1;
                unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n",
                                         staRecord->updateTimReqQueued, staRecord->aid);
            }
        }
        return CSR_RESULT_FAILURE;
    }
    else if ((CSR_TX_LIFETIME == txStatus) ||  (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) ||
             (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) ||
             (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus)    ||
             (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) {
        /* Extract the Frame control and the frame type */
        frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr);
        frameType =  ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);

        /* Mgmt frames will not be re-queued for Tx
         * so just return failure to clear the hip slot
         */
        if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) {
            return CSR_RESULT_FAILURE;
        }
        else if (IEEE802_11_FRAMETYPE_DATA == frameType) {
            /* QOS NULL and DATA NULL frames will not be re-queued for Tx
             * so just return failure to clear the hip slot
             */
            if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) ||
                (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) {
                return CSR_RESULT_FAILURE;
            }
        }

        /* Extract the Packet priority */
        if (TRUE == staRecord->wmmOrQosEnabled) {
            u16 qosControl = 0;
            u8  dataFrameType = 0;

            dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4);

            if (dataFrameType == QOS_DATA) {
                /* QoS control field is offset from frame control by 2 (frame control)
                 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
                 */
                if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) {
                    qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30);
                }
                else {
                    qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24);
                }
            }

            priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);

            if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) {
                unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority);
                return CSR_RESULT_FAILURE;
            }
        }
        else {
            priority = CSR_CONTENTION;
        }

        /* Frame Bulk data to requeue it back to HAL Queues */
        bulkData.d[0].os_data_ptr    = bulkDataDesc->os_data_ptr;
        bulkData.d[0].data_length    = bulkDataDesc->data_length;
        bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr;
        bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length;

        bulkData.d[1].os_data_ptr    = NULL;
        bulkData.d[1].os_net_buf_ptr = NULL;
        bulkData.d[1].data_length    = bulkData.d[1].net_buf_length = 0;

        /* Initialize signal to zero */
        memset(&signal, 0, sizeof(CSR_SIGNAL));

        /* Frame MA Packet Req */
        unifi_frame_ma_packet_req(priv, priority, 0, host_tag,
                              interfaceTag, CSR_NO_CONFIRM_REQUIRED,
                              priv->netdev_client->sender_id,
                              staRecord->peerMacAddress.a, &signal);

        /* Find the Q-Priority */
        priority_q = unifi_frame_priority_to_queue(priority);
        list = &staRecord->dataPdu[priority_q];

        /* Place the Packet on to HAL Queue */
        status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE);

        /* Update the Per-station queued packet counter */
        if (!status) {
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staRecord->noOfPktQueued++;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }
    }
    else {
        /* Packet will not be re-queued for any of the other MA Packet Tx failure
         * reasons so just return failure to clear the hip slot
         */
        return CSR_RESULT_FAILURE;
    }

    return status;
}
#endif

static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, u8 *allDeliveryEnabled, u8 *dataAvailable)
{
    u8 i;
    *allDeliveryEnabled = TRUE;
    for (i = 0 ;i < MAX_ACCESS_CATOGORY; i++) {
        if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
            /* One is is not Delivery Enabled */
            *allDeliveryEnabled = FALSE;
            break;
        }
    }
    if (*allDeliveryEnabled) {
        *dataAvailable = (!list_empty(&staRecord->dataPdu[0]) || !list_empty(&staRecord->dataPdu[1])
                          ||!list_empty(&staRecord->dataPdu[2]) ||!list_empty(&staRecord->dataPdu[3])
                          ||!list_empty(&staRecord->mgtFrames));
    }
}

/*
 * ---------------------------------------------------------------------------
 *  uf_handle_tim_cfm
 *
 *
 *      This function updates tim status in host depending confirm status from firmware
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      cfm             CSR_MLME_SET_TIM_CONFIRM
 *      receiverProcessId SenderProcessID to fetch handle & timSet status
 *
 * ---------------------------------------------------------------------------
 */
void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, u16 receiverProcessId)
{
    u8 handle = CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId);
    u8 timSetStatus = CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId);
    u16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff);
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
    /* This variable holds what TIM value we wanted to set in firmware */
    u16 timSetValue = 0;
    /* Irrespective of interface the count maintained */
    static u8 retryCount = 0;
    unsigned long lock_flags;
    unifi_trace(priv, UDBG3, "entering %s, handle = %x, timSetStatus = %x\n", __FUNCTION__, handle, timSetStatus);

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_warning(priv, "bad interfaceTag = %x\n", interfaceTag);
        return;
    }

    if ((handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) && (handle >= UNIFI_MAX_CONNECTIONS)) {
        unifi_warning(priv, "bad station Handle = %x\n", handle);
        return;
    }

    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
        spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
            unifi_warning(priv, "uf_handle_tim_cfm: station record is NULL  handle = %x\n", handle);
            return;
        }
       spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
    }
    switch(timSetStatus)
    {
        case CSR_WIFI_TIM_SETTING:
            timSetValue = CSR_WIFI_TIM_SET;
            break;
        case CSR_WIFI_TIM_RESETTING:
            timSetValue = CSR_WIFI_TIM_RESET;
            break;
        default:
            unifi_warning(priv, "timSet state is %x: Debug\n", timSetStatus);
            return;
    }

    /* check TIM confirm for success/failures */
    switch(cfm->ResultCode)
    {
        case CSR_RC_SUCCESS:
            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
                /* Unicast frame & station record available */
                if (timSetStatus == staRecord->timSet) {
                    staRecord->timSet = timSetValue;
                    /* fh_cmd_q can also be full at some point of time!,
                     * resetting count as queue is cleaned by firmware at this point
                     */
                    retryCount = 0;
                    unifi_trace(priv, UDBG2, "tim (%s) successfully in firmware\n", (timSetValue)?"SET":"RESET");
                } else {
                    unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n",
                                 receiverProcessId, timSetStatus, staRecord->timSet, handle);
                }

                /* Reset TIM pending flag to send next TIM request */
                staRecord->timRequestPendingFlag = FALSE;

                /* Make sure that one more UpdateTim request is queued, if Queued its value
                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
                 */
                if (0xFF != staRecord->updateTimReqQueued)
                {
                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
                    if (staRecord->timSet != staRecord->updateTimReqQueued)
                    {
                       unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n");

                       update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle);

                       staRecord->updateTimReqQueued = 0xFF;
                    }
                }
            } else {

                interfacePriv->bcTimSet = timSetValue;
                /* fh_cmd_q can also be full at some point of time!,
                 * resetting count as queue is cleaned by firmware at this point
                 */
                retryCount = 0;
                unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET");

                /* Reset DTIM pending flag to send next DTIM request */
                interfacePriv->bcTimSetReqPendingFlag = FALSE;

                /* Make sure that one more UpdateDTim request is queued, if Queued its value
                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
                 */
                if (0xFF != interfacePriv->bcTimSetReqQueued)
                {
                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
                    if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued)
                    {
                        unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n");

                        update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF);

                        interfacePriv->bcTimSetReqQueued = 0xFF;
                    }
                }

            }
            break;
        case CSR_RC_INVALID_PARAMETERS:
        case CSR_RC_INSUFFICIENT_RESOURCE:
            /* check for max retry limit & send again
             * MAX_RETRY_LIMIT is not maintained for each set of transactions..Its generic
             * If failure crosses this Limit, we have to take a call to FIX
             */
            if (retryCount > UNIFI_MAX_RETRY_LIMIT) {
                u8 moreData = FALSE;
                retryCount = 0;
                /* Because of continuos traffic in fh_cmd_q the tim set request is failing (exceeding retry limit)
                 * but if we didn't synchronize our timSet varible state with firmware then it can cause below issues
                 * cond 1. We want to SET tim in firmware if its fails & max retry limit reached
                 *   -> If host set's the timSet to 1, we wont try to send(as max retry reached) update tim but
                 *   firmware is not updated with queue(TIM) status so it wont set TIM in beacon finally host start piling
                 *    up data & wont try to set tim in firmware (This can cause worser performance)
                 * cond 2. We want to reset tim in firmware it fails & reaches max retry limit
                 *   -> If host sets the timSet to Zero, it wont try to set a TIM request unless we wont have any packets
                 *   to be queued, so beacon unnecessarily advertizes the TIM
                 */

                if(staRecord) {
                    if(!staRecord->wmmOrQosEnabled) {
                        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
                                !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
                                !list_empty(&staRecord->mgtFrames));
                    } else {
                        /* Peer is QSTA */
                        u8 allDeliveryEnabled = 0, dataAvailable = 0;
                        /* Check if all AC's are Delivery Enabled */
                        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
                        /*check for more data in non-delivery enabled queues*/
                        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));

                    }
                    /* To avoid cond 1 & 2, check internal Queues status, if we have more Data then set RESET the timSet(0),
                     *  so we are trying to be in sync with firmware & next packets before queuing atleast try to
                     *  set TIM in firmware otherwise it SET timSet(1)
                     */
                    if (moreData) {
                        staRecord->timSet = CSR_WIFI_TIM_RESET;
                    } else {
                        staRecord->timSet = CSR_WIFI_TIM_SET;
                    }
                } else {
                    /* Its a broadcast frames */
                    moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
                               !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
                    if (moreData) {
                        update_tim(priv, 0, CSR_WIFI_TIM_SET, interfaceTag, 0xFFFFFFFF);
                    } else {
                        update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF);
                    }
                }

                unifi_error(priv, "no of error's for TIM setting crossed the Limit: verify\n");
                return;
            }
            retryCount++;

            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
                if (timSetStatus == staRecord->timSet) {
                    unifi_warning(priv, "tim request failed, retry for AID = %x\n", staRecord->aid);
                    update_tim(priv, staRecord->aid, timSetValue, interfaceTag, handle);
                } else {
                    unifi_trace(priv, UDBG1, "failure: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x\n",
                                  timSetStatus, staRecord->timSet);
                }
            } else {
                unifi_warning(priv, "tim request failed, retry for broadcast frames\n");
                update_tim(priv, 0, timSetValue, interfaceTag, 0xFFFFFFFF);
            }
            break;
        default:
            unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode);
    }

    unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__);
}

/*
 * ---------------------------------------------------------------------------
 *  update_tim
 *
 *
 *      This function updates tim status in firmware for AID[1 to UNIFI_MAX_CONNECTIONS] or
 *       AID[0] for broadcast/multicast packets.
 *
 *      NOTE: The LSB (least significant BYTE) of senderId while sending this MLME premitive
 *       has been modified(utilized) as below
 *
 *       SenderID in signal's SignalPrimitiveHeader is 2 byte the lowe byte bitmap is below
 *
 *       station handle(6 bits)      timSet Status (2 bits)
 *       ---------------------       ----------------------
 *       0  0  0  0  0  0        |       0  0
 *
 * timSet Status can be one of below:
 *
 * CSR_WIFI_TIM_RESET
 * CSR_WIFI_TIM_RESETTING
 * CSR_WIFI_TIM_SET
 * CSR_WIFI_TIM_SETTING
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      aid             can be 1 t0 UNIFI_MAX_CONNECTIONS & 0 means multicast/broadcast
 *      setTim          value SET(1) / RESET(0)
 *      interfaceTag    the interfaceID on which activity going on
 *      handle          from  (0 <= handle < UNIFI_MAX_CONNECTIONS)
 *
 * ---------------------------------------------------------------------------
 */
void update_tim(unifi_priv_t * priv, u16 aid, u8 setTim, u16 interfaceTag, u32 handle)
{
    CSR_SIGNAL signal;
    s32 r;
    CSR_MLME_SET_TIM_REQUEST *req = &signal.u.MlmeSetTimRequest;
    bulk_data_param_t *bulkdata = NULL;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    u8 senderIdLsb = 0;
    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
    u32 oldTimSetStatus = 0, timSetStatus = 0;

    unifi_trace(priv, UDBG5, "entering the update_tim routine\n");


    if (handle == 0xFFFFFFFF) {
        handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE;
        if (setTim == interfacePriv->bcTimSet)
        {
            unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet);
            return;
        }
    } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) {
        unifi_warning(priv, "bad station Handle = %x\n", handle);
        return;
    }

    if (setTim) {
        timSetStatus =  CSR_WIFI_TIM_SETTING;
    } else {
        timSetStatus =  CSR_WIFI_TIM_RESETTING;
    }

    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
            unifi_warning(priv, "station record is NULL in  update_tim: handle = %x :debug\n", handle);
            return;
        }
        /* In case of signal sending failed, revert back to old state */
        oldTimSetStatus = staRecord->timSet;
        staRecord->timSet = timSetStatus;
    }

    /* pack senderID LSB */
    senderIdLsb = CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle,  timSetStatus);

    /* initialize signal to zero */
    memset(&signal, 0, sizeof(CSR_SIGNAL));

    /* Frame the MLME-SET-TIM request */
    signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SET_TIM_REQUEST_ID;
    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->netdev_client->sender_id & 0xff00) | senderIdLsb),
                   (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);

    /* set The virtual interfaceIdentifier, aid, tim value */
    req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag);
    req->AssociationId = aid;
    req->TimValue = setTim;


    unifi_trace(priv, UDBG2, "update_tim:AID %x,senderIdLsb = 0x%x, handle = 0x%x, timSetStatus = %x, sender proceesID = %x \n",
                aid, senderIdLsb, handle, timSetStatus, signal.SignalPrimitiveHeader.SenderProcessId);

    /* Send the signal to UniFi */
    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
    if (r) {
        /* No need to free bulk data, as TIM request doesn't carries any data */
        unifi_error(priv, "Error queueing CSR_MLME_SET_TIM_REQUEST signal\n");
        if (staRecord) {
            staRecord->timSet = oldTimSetStatus ;
        }
        else
        {
            /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */
            interfacePriv->bcTimSet = !setTim;
        }
    }
    else {
        /* Update tim request pending flag and ensure no more TIM set requests are send
           for the same station until TIM confirm is received */
        if (staRecord) {
            staRecord->timRequestPendingFlag = TRUE;
        }
        else
        {
            /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send
             * for the same station until TIM confirm is received
             */
            interfacePriv->bcTimSetReqPendingFlag = TRUE;
        }
    }
    unifi_trace(priv, UDBG5, "leaving the update_tim routine\n");
}

static
void process_peer_active_transition(unifi_priv_t * priv,
                                    CsrWifiRouterCtrlStaInfo_t *staRecord,
                                    u16 interfaceTag)
{
    int r, i;
    u8 spaceAvail[4] = {TRUE, TRUE, TRUE, TRUE};
    tx_buffered_packets_t * buffered_pkt = NULL;
    unsigned long lock_flags;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    unifi_trace(priv, UDBG5, "entering process_peer_active_transition\n");

    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag)) {
        /* giving more priority to multicast packets so delaying unicast packets*/
        unifi_trace(priv, UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n");

        /* As station is active now, even though AP is not able to send frames to it
         * because of DTIM, it needs to reset the TIM here
         */
        if (!staRecord->timRequestPendingFlag){
            if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
            }
        }
        else
        {
            /* Cache the TimSet value so that it will processed immidiatly after
             * completing the current setTim Request
             */
            staRecord->updateTimReqQueued = 0;
            unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                        staRecord->aid);
        }
        return;
    }
    while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
        buffered_pkt->transmissionControl &=
                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
        if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, 0, FALSE)) == -ENOSPC) {
            unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n");
            /* Enqueue at the head of the queue */
            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
            list_add(&buffered_pkt->q, &staRecord->mgtFrames);
            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
            priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
            spaceAvail[3] = FALSE;
            break;
        } else {
            if(r){
                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                /* the PDU failed where we can't do any thing so free the storage */
                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
            }
            kfree(buffered_pkt);
        }
    }
    if (!staRecord->timRequestPendingFlag) {
        if (staRecord->txSuspend) {
            if(staRecord->timSet == CSR_WIFI_TIM_SET) {
                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
            }
            return;
        }
    }
    else
    {
        /* Cache the TimSet value so that it will processed immidiatly after
         * completing the current setTim Request
         */
        staRecord->updateTimReqQueued = 0;
        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                    staRecord->aid);
    }
    for(i=3;i>=0;i--) {
        if(!spaceAvail[i])
            continue;
        unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n", i);
        while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
           buffered_pkt->transmissionControl &=
                      ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
           if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, 0, FALSE)) == -ENOSPC) {
               /* Clear the trigger bit transmission control*/
               /* Enqueue at the head of the queue */
               spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
               list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
               spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
               priv->pausedStaHandle[i]=(u8)(staRecord->assignedHandle);
               break;
           } else {
              if(r){
                  unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                  /* the PDU failed where we can't do any thing so free the storage */
                  unifi_net_data_free(priv, &buffered_pkt->bulkdata);
               }
              kfree(buffered_pkt);
           }
        }
    }
    if (!staRecord->timRequestPendingFlag){
        if((staRecord->timSet  == CSR_WIFI_TIM_SET) || (staRecord->timSet  == CSR_WIFI_TIM_SETTING)) {
            unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
            update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
        }
    }
    else
    {
        /* Cache the TimSet value so that it will processed immidiatly after
         * completing the current setTim Request
         */
        staRecord->updateTimReqQueued = 0;
        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                    staRecord->aid);
    }
    unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n");
}



void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv, u16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm)
{
    netInterface_priv_t *interfacePriv;
    u8 i;
    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
    interfacePriv = priv->interfacePriv[interfaceTag];


    if(pkt_cfm->HostTag == interfacePriv->multicastPduHostTag) {
         unifi_trace(priv, UDBG2, "CFM for marked Multicast Tag = %x\n", interfacePriv->multicastPduHostTag);
         interfacePriv->multicastPduHostTag = 0xffffffff;
         resume_suspended_uapsd(priv, interfaceTag);
         resume_unicast_buffered_frames(priv, interfaceTag);
         if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) &&
              list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
            unifi_trace(priv, UDBG1, "Resetting multicastTIM");
            if (!interfacePriv->bcTimSetReqPendingFlag)
            {
                update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF);
            }
            else
            {
                /* Cache the DTimSet value so that it will processed immidiatly after
                 * completing the current setDTim Request
                 */
                 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
                 unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n",
                             interfacePriv->bcTimSetReqQueued);
            }

        }
        return;
    }

    /* Check if it is a Confirm for null data frame used
     * for probing station activity
     */
    for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
        staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
        if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {

            unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
                                    pkt_cfm->HostTag,
                                    pkt_cfm->TransmissionStatus
                                    );
            staRecord->nullDataHostTag = INVALID_HOST_TAG;

            if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
                u32 now;
                u32 inactive_time;

                unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
                /* Recheck if there is some activity after null data is sent.
                *
                * If still there is no activity then send a disconnected indication
                * to SME to delete the station record.
                */
                if (staRecord->activity_flag){
                    return;
                }
                now = CsrTimeGet(NULL);

                if (staRecord->lastActivity > now)
                {
                    /* simple timer wrap (for 1 wrap) */
                    inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
                                               now);
                }
                else
                {
                    inactive_time = (u32)CsrTimeSub(now, staRecord->lastActivity);
                }

                if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
                {
                    struct list_head send_cfm_list;
                    u8 j;

                    /* The SME/NME may be waiting for confirmation for requested frames to this station.
                     * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
                     * a defensive check, it loops through buffered frames for this station and if confirmation
                     * is requested, send auto confirmation with failure status. Also flush the frames so
                     * that these are not processed again in PEER_DEL_REQ handler.
                     */
                    INIT_LIST_HEAD(&send_cfm_list);

                    uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                                             &send_cfm_list,
                                                             &(staRecord->mgtFrames));

                    uf_flush_list(priv, &(staRecord->mgtFrames));

                    for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
                        uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                                                 &send_cfm_list,
                                                                 &(staRecord->dataPdu[j]));

                        uf_flush_list(priv, &(staRecord->dataPdu[j]));
                    }

                    send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);



                    unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
                                             staRecord->peerMacAddress.a[0],
                                             staRecord->peerMacAddress.a[1],
                                             staRecord->peerMacAddress.a[2],
                                             staRecord->peerMacAddress.a[3],
                                             staRecord->peerMacAddress.a[4],
                                             staRecord->peerMacAddress.a[5]);

                    CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
                                                      0,
                                                      staRecord->interfacePriv->InterfaceTag,
                                                      staRecord->peerMacAddress,
                                                      CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
                }

            }
            else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
            {
                 staRecord->activity_flag = TRUE;
            }
        }
    }
}

#endif
u16 uf_get_vif_identifier (CsrWifiRouterCtrlMode mode, u16 tag)
{
    switch(mode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
            return (0x02<<8|tag);

        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            return (0x03<<8|tag);

        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            return (0x01<<8|tag);

        case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
            return (0x04<<8|tag);
        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
            return (0x05<<8|tag);
        default:
            return tag;
    }
}

#ifdef CSR_SUPPORT_SME

/*
 * ---------------------------------------------------------------------------
 *  update_macheader
 *
 *
 *      These functions updates mac header for intra BSS packet
 *      routing.
 *      NOTE: This function always has to be called in rx context which
 *      is in bh thread context since GFP_KERNEL is used. In soft IRQ/ Interrupt
 *      context shouldn't be used
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      skb             Socket buffer containing data packet to transmit
 *      newSkb          Socket buffer containing data packet + Mac header if no sufficient headroom in skb
 *      priority        to append QOS control header in Mac header
 *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
 *      interfaceTag    the interfaceID on which activity going on
 *      macHeaderLengthInBytes no. of bytes of mac header in received frame
 *      qosDestination  used to append Qos control field
 *
 *  Returns:
 *      Zero on success or -1 on error.
 * ---------------------------------------------------------------------------
 */

static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb,
                            struct sk_buff *newSkb, CSR_PRIORITY *priority,
                            bulk_data_param_t *bulkdata, u16 interfaceTag,
                            u8 macHeaderLengthInBytes,
                            u8 qosDestination)
{

    u16 *fc = NULL;
    u8 direction = 0, toDs, fromDs;
    u8 *bufPtr = NULL;
    u8 sa[ETH_ALEN], da[ETH_ALEN];
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    int headroom;
    u8 macHeaderBuf[IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE] = {0};

    unifi_trace(priv, UDBG5, "entering the update_macheader function\n");

    /* temporary buffer for the Mac header storage */
    memcpy(macHeaderBuf, skb->data, macHeaderLengthInBytes);

    /* remove the Macheader from the skb */
    skb_pull(skb, macHeaderLengthInBytes);

    /* get the skb headroom for skb_push check */
    headroom = skb_headroom(skb);

    /*  pointer to frame control field */
    fc = (u16*) macHeaderBuf;

    toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
    fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;
    unifi_trace(priv, UDBG5, "In update_macheader function, fromDs = %x, toDs = %x\n", fromDs, toDs);
    direction = ((fromDs | (toDs << 1)) & 0x3);

    /* Address1 or 3 from the macheader */
    memcpy(da, macHeaderBuf+4+toDs*12, ETH_ALEN);
    /* Address2, 3 or 4 from the mac header */
    memcpy(sa, macHeaderBuf+10+fromDs*(6+toDs*8), ETH_ALEN);

    unifi_trace(priv, UDBG3, "update_macheader:direction = %x\n", direction);
    /* update the toDs, fromDs & address fields in Mac header */
    switch(direction)
    {
        case 2:
            /* toDs = 1 & fromDs = 0 , toAp when frames received from peer
             * while sending this packet to Destination the Mac header changed
             * as fromDs = 1 & toDs = 0, fromAp
             */
            *fc &= cpu_to_le16(~IEEE802_11_FC_TO_DS_MASK);
            *fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
            /* Address1: MAC address of the actual destination (4 = 2+2) */
            memcpy(macHeaderBuf + 4, da, ETH_ALEN);
            /* Address2: The MAC address of the AP (10 = 2+2+6) */
            memcpy(macHeaderBuf + 10, &interfacePriv->bssid, ETH_ALEN);
            /* Address3: MAC address of the actual source from mac header (16 = 2+2+6+6) */
            memcpy(macHeaderBuf + 16, sa, ETH_ALEN);
            break;
        case 3:
            unifi_trace(priv, UDBG3, "when both the toDs & fromDS set, NOT SUPPORTED\n");
            break;
        default:
            unifi_trace(priv, UDBG3, "problem in decoding packet in update_macheader \n");
            return -1;
    }

    /* frameType is Data always, Validation is done before calling this function */

    /* check for the souce station type */
    switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
    {
        case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
            /* No need to modify the qos control field */
            if (!qosDestination) {

                /* If source Sta is QOS enabled & if this bit set, then HTC is supported by
                 * peer station & htc field present in macHeader
                 */
                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
                    /* HT control field present in Mac header
                     * 6 = sizeof(qosControl) + sizeof(htc)
                     */
                    macHeaderLengthInBytes -= 6;
                } else {
                    macHeaderLengthInBytes -= 2;
                }
                /* Destination STA is non qos so change subtype to DATA */
                *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
                *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
                /* remove the qos control field & HTC(if present). new macHeaderLengthInBytes is less than old
                 * macHeaderLengthInBytes so no need to verify skb headroom
                 */
                if (headroom < macHeaderLengthInBytes) {
                    unifi_trace(priv, UDBG1, " sufficient headroom not there to push updated mac header \n");
                    return -1;
                }
                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);

                /*  update bulk data os_data_ptr */
                bulkdata->d[0].os_data_ptr = skb->data;
                bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
                bulkdata->d[0].data_length = skb->len;

            } else {
                /* pointing to QOS control field */
                u8 qc;
                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 4 - 2)));
                } else {
                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 2)));
                }

                if ((qc & IEEE802_11_QC_TID_MASK) > 7) {
                    *priority = 7;
                } else {
                    *priority = qc & IEEE802_11_QC_TID_MASK;
                }

                unifi_trace(priv, UDBG1, "Incoming packet priority from QSTA is %x\n", *priority);

                if (headroom < macHeaderLengthInBytes) {
                    unifi_trace(priv, UDBG3, " sufficient headroom not there to push updated mac header \n");
                    return -1;
                }
                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);
            }
            break;
        default:
            {
                bulk_data_param_t data_ptrs;
                CsrResult csrResult;
                unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n");

                if (qosDestination) {
                    u8 qc = 0;
                    unifi_trace(priv, UDBG3, "destination is QOS station \n");

                    /* Set Ma-Packet.req UP to UP0 */
                    *priority = CSR_QOS_UP0;

                    /* prepare the qos control field */
                    qc |= CSR_QOS_UP0;
                    /* no Amsdu is in ap buffer so eosp is left 0 */
                    if (da[0] & 0x1) {
                        /* multicast/broadcast frames, no acknowledgement needed */
                        qc |= 1 << 5;
                    }

                    /* update new Mac header Length with 2 = sizeof(qos control) */
                    macHeaderLengthInBytes += 2;

                    /* received DATA frame but destiantion is QOS station so update subtype to QOS*/
                    *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
                    *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);

                    /* appendQosControlOffset = macHeaderLengthInBytes - 2, since source sta is not QOS */
                    macHeaderBuf[macHeaderLengthInBytes - 2] = qc;
                    /* txopLimit is 0 */
                    macHeaderBuf[macHeaderLengthInBytes - 1] = 0;
                    if (headroom < macHeaderLengthInBytes) {
                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);

                        if (csrResult != CSR_RESULT_SUCCESS) {
                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
                            return -1;
                        }
                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
                        newSkb->len = skb->len + macHeaderLengthInBytes;

                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
                                skb->data, skb->len);

                        bulkdata->d[0].os_data_ptr = newSkb->data;
                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
                        bulkdata->d[0].data_length = newSkb->len;

                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;

                        /* The old skb will not be used again */
                        kfree_skb(skb);
                    } else {
                        /* skb headroom is sufficient to append Macheader */
                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
                        bulkdata->d[0].os_data_ptr = skb->data;
                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
                        bulkdata->d[0].data_length = skb->len;
                    }
                } else {
                    unifi_trace(priv, UDBG3, "destination is not a QSTA\n");
                    if (headroom < macHeaderLengthInBytes) {
                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);

                        if (csrResult != CSR_RESULT_SUCCESS) {
                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
                            return -1;
                        }
                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
                        newSkb->len = skb->len + macHeaderLengthInBytes;

                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
                                skb->data, skb->len);

                        bulkdata->d[0].os_data_ptr = newSkb->data;
                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
                        bulkdata->d[0].data_length = newSkb->len;

                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;

                        /* The old skb will not be used again */
                        kfree_skb(skb);
                    } else {
                        /* skb headroom is sufficient to append Macheader */
                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
                        bulkdata->d[0].os_data_ptr = skb->data;
                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
                        bulkdata->d[0].data_length = skb->len;
                    }
                }
            }
    }

    /* prepare the complete skb, by pushing the MAC header to the beginning of the skb->data */
    unifi_trace(priv, UDBG5, "updated Mac Header: %d \n", macHeaderLengthInBytes);
    memcpy(bufPtr, macHeaderBuf, macHeaderLengthInBytes);

    unifi_trace(priv, UDBG5, "leaving the update_macheader function\n");
    return 0;
}
/*
 * ---------------------------------------------------------------------------
 *  uf_ap_process_data_pdu
 *
 *
 *      Takes care of intra BSS admission control & routing packets within BSS
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      skb             Socket buffer containing data packet to transmit
 *      ehdr            ethernet header to fetch priority of packet
 *      srcStaInfo      source stations record for connection verification
 *      packed_signal
 *      signal_len
 *      signal          MA-PACKET.indication signal
 *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
 *      macHeaderLengthInBytes no. of bytes of mac header in received frame
 *
 *  Returns:
 *      Zero on success(ap processing complete) or -1 if packet also have to be sent to NETDEV.
 * ---------------------------------------------------------------------------
 */
int
uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb,
                       struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
                       const CSR_SIGNAL *signal,
                       bulk_data_param_t *bulkdata,
                       u8 macHeaderLengthInBytes)
{
    const CSR_MA_PACKET_INDICATION *ind = &(signal->u.MaPacketIndication);
    u16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0x00ff);
    struct sk_buff *newSkb = NULL;
    /* pointer to skb or private skb created using skb_copy() */
    struct sk_buff *skbPtr = skb;
    u8 sendToNetdev = FALSE;
    u8 qosDestination = FALSE;
    CSR_PRIORITY priority = CSR_CONTENTION;
    CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
    netInterface_priv_t *interfacePriv;

    unifi_trace(priv, UDBG5, "entering  uf_ap_process_data_pdu %d\n", macHeaderLengthInBytes);
    /* InterfaceTag validation from MA_PACKET.indication */
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_trace(priv, UDBG1, "Interface Tag is Invalid in uf_ap_process_data_pdu\n");
        unifi_net_data_free(priv, &bulkdata->d[0]);
        return 0;
    }
    interfacePriv = priv->interfacePriv[interfaceTag];

    if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) &&
       (interfacePriv->intraBssEnabled == FALSE)) {
        unifi_trace(priv, UDBG2, "uf_ap_process_data_pdu:P2P GO intrabssEnabled?= %d\n", interfacePriv->intraBssEnabled);

        /*In P2P GO case, if intraBSS distribution Disabled then don't do IntraBSS routing */
        /* If destination in our BSS then drop otherwise give packet to netdev */
        dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);
        if (dstStaInfo) {
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return 0;
        }
        /* May be associated P2PCLI trying to send the packets on backbone (Netdev) */
        return -1;
    }

    if(!memcmp(ehdr->h_dest, interfacePriv->bssid.a, ETH_ALEN)) {
        /* This packet will be given to the TCP/IP stack since this packet is for us(AP)
         * No routing needed */
        unifi_trace(priv, UDBG4, "destination address is csr_ap\n");
        return -1;
    }

    /* fetch the destination record from station record database */
    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);

    /* AP mode processing, & if packet is unicast */
    if(!dstStaInfo) {
        if (!(ehdr->h_dest[0] & 0x1)) {
            /* destination not in station record & its a unicast packet, so pass the packet to network stack */
            unifi_trace(priv, UDBG3, "unicast frame & destination record not exist, send to netdev proto = %x\n", htons(skb->protocol));
            return -1;
        } else {
            /* packet is multicast/broadcast */
            /* copy the skb to skbPtr, send skb to netdev & skbPtr to multicast/broad cast list */
            unifi_trace(priv, UDBG5, "skb_copy, in  uf_ap_process_data_pdu, protocol = %x\n", htons(skb->protocol));
            skbPtr = skb_copy(skb, GFP_KERNEL);
            if(skbPtr == NULL) {
                /* We don't have memory to don't send the frame in BSS*/
                unifi_notice(priv, "broacast/multicast frame can't be sent in BSS No memeory: proto = %x\n", htons(skb->protocol));
                return -1;
            }
            sendToNetdev = TRUE;
        }
    } else {

        /* validate the Peer & Destination Station record */
        if (uf_process_station_records_for_sending_data(priv, interfaceTag, srcStaInfo, dstStaInfo)) {
            unifi_notice(priv, "uf_ap_process_data_pdu: station record validation failed \n");
            interfacePriv->stats.rx_errors++;
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return 0;
        }
    }

    /* BroadCast packet received and it's been sent as non QOS packets.
     * Since WMM spec not mandates broadcast/multicast to be sent as QOS data only,
     * if all Peers are QSTA
     */
    if(sendToNetdev) {
       /* BroadCast packet and it's been sent as non QOS packets */
        qosDestination = FALSE;
    } else if(dstStaInfo && (dstStaInfo->wmmOrQosEnabled == TRUE)) {
          qosDestination = TRUE;
    }

    unifi_trace(priv, UDBG3, "uf_ap_process_data_pdu QoS destination  = %s\n", (qosDestination)? "TRUE": "FALSE");

    /* packet is allowed to send to unifi, update the Mac header */
    if (update_macheader(priv, skbPtr, newSkb, &priority, bulkdata, interfaceTag, macHeaderLengthInBytes, qosDestination)) {
        interfacePriv->stats.rx_errors++;
        unifi_notice(priv, "(Packet Drop) failed to update the Mac header in uf_ap_process_data_pdu\n");
        if (sendToNetdev) {
            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
            bulkdata->d[0].os_data_ptr = skbPtr->data;
            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
            bulkdata->d[0].data_length = skbPtr->len;
            unifi_net_data_free(priv, &bulkdata->d[0]);
        }
        return -1;
    }

    unifi_trace(priv, UDBG3, "Mac Header updated...calling uf_process_ma_packet_req \n");

    /* Packet is ready to send to unifi ,transmissionControl = 0x0004, confirmation is not needed for data packets */
    if (uf_process_ma_packet_req(priv, ehdr->h_dest, 0xffffffff, interfaceTag, CSR_NO_CONFIRM_REQUIRED, (CSR_RATE)0, priority, priv->netdev_client->sender_id, bulkdata)) {
        if (sendToNetdev) {
            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop) uf_process_ma_packet_req failed. freeing skb_copy data (original data sent to Netdev)\n");
            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
            bulkdata->d[0].os_data_ptr = skbPtr->data;
            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
            bulkdata->d[0].data_length = skbPtr->len;
            unifi_net_data_free(priv, &bulkdata->d[0]);
        } else {
            /* This free's the skb data */
            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop). Unicast data so freeing original skb \n");
            unifi_net_data_free(priv, &bulkdata->d[0]);
        }
    }
    unifi_trace(priv, UDBG5, "leaving  uf_ap_process_data_pdu\n");

    if (sendToNetdev) {
        /* The packet is multicast/broadcast, so after AP processing packet has to
         * be sent to netdev, if peer port state is open
        */
        unifi_trace(priv, UDBG4, "Packet will be routed to NetDev\n");
        return -1;
    }
    /* Ap handled the packet & its a unicast packet, no need to send to netdev */
    return 0;
}

#endif

CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
                                   u8 *peerMacAddress,
                                   CSR_CLIENT_TAG hostTag,
                                   u16 interfaceTag,
                                   CSR_TRANSMISSION_CONTROL transmissionControl,
                                   CSR_RATE TransmitRate,
                                   CSR_PRIORITY priority,
                                   CSR_PROCESS_ID leSenderProcessId,
                                   bulk_data_param_t *bulkdata)
{
    CsrResult status = CSR_RESULT_SUCCESS;
    CSR_SIGNAL signal;
    int result;
#ifdef CSR_SUPPORT_SME
   CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
    const u8 *macHdrLocation =  bulkdata->d[0].os_data_ptr;
    CsrWifiPacketType pktType;
    int frameType = 0;
    u8 queuePacketDozing = FALSE;
    u32 priority_q;
    u16 frmCtrl;
    struct list_head * list = NULL; /* List to which buffered PDUs are to be enqueued*/
    u8 setBcTim=FALSE;
    netInterface_priv_t *interfacePriv;
    u8 requeueOnSamePos = FALSE;
    u32 handle = 0xFFFFFFFF;
    unsigned long lock_flags;

	unifi_trace(priv, UDBG5,
		"entering uf_process_ma_packet_req, peer: %pMF\n",
		peerMacAddress);

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
        return CSR_RESULT_FAILURE;
    }
    interfacePriv = priv->interfacePriv[interfaceTag];


    /* fetch the station record for corresponding peer mac address */
    if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag))) {
        handle = staRecord->assignedHandle;
    }

    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag,
                              interfaceTag, transmissionControl, leSenderProcessId,
                              peerMacAddress, &signal);

   /* Since it's common path between STA & AP mode, in case of STA packet
     * need not to be queued but in AP case we have to queue PDU's in
     * different scenarios
     */
    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            /* For this mode processing done below */
            break;
        default:
            /* In case of STA/IBSS/P2PCLI/AMP, no checks needed send the packet down & return */
            unifi_trace(priv, UDBG5, "In %s, interface mode is %x \n", __FUNCTION__, interfacePriv->interfaceMode);
            if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
                unifi_warning(priv, "In %s, interface mode NONE \n", __FUNCTION__);
            }
            if ((result = ul_send_signal_unpacked(priv, &signal, bulkdata))) {
                status = CSR_RESULT_FAILURE;
            }
            return status;
    }

    /* -----Only AP/P2pGO mode handling falls below----- */

    /* convert priority to queue */
    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);

    /* check the powersave status of the peer */
    if (staRecord && (staRecord->currentPeerState ==
                     CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)) {
        /* Peer is dozing & packet have to be delivered, so buffer the packet &
         * update the TIM
         */
        queuePacketDozing = TRUE;
    }

    /* find the type of frame unicast or mulicast/broadcast */
    if (*peerMacAddress & 0x1) {
        /* Multicast/broadCast data are always triggered by vif_availability.ind
         * at the DTIM
         */
        pktType = CSR_WIFI_MULTICAST_PDU;
    } else {
        pktType = CSR_WIFI_UNICAST_PDU;
    }

    /* Fetch the frame control field from mac header & check for frame type */
    frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);

    /* Processing done according to Frame/Packet type */
    frameType =  ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
    switch(frameType)
    {
        case IEEE802_11_FRAMETYPE_MANAGEMENT:

            switch(pktType)
            {
                case CSR_WIFI_UNICAST_PDU:
                    unifi_trace(priv, UDBG5, "management unicast PDU in uf_process_ma_packet_req \n");
                    /* push the packet in to the queue with appropriate mgt list */
                    if (!staRecord) {
                        /* push the packet to the unifi if list is empty (if packet lost how to re-enque) */
                        if (list_empty(&interfacePriv->genericMgtFrames)) {
#ifdef CSR_SUPPORT_SME
                            if(!(IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag))) {
#endif

                            unifi_trace(priv, UDBG3, "genericMgtFrames list is empty uf_process_ma_packet_req \n");
                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
                            /*  reque only on ENOSPC */
                            if(result == -ENOSPC) {
                                /* requeue the failed packet to genericMgtFrame with same position */
                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending genericMgtFrames Failed so buffering\n");
                                list = &interfacePriv->genericMgtFrames;
                                requeueOnSamePos = TRUE;
                            }
#ifdef CSR_SUPPORT_SME
                            }else{
                                list = &interfacePriv->genericMgtFrames;
                                unifi_trace(priv, UDBG3, "genericMgtFrames queue empty and dtim started\n hosttag is 0x%x,\n", signal.u.MaPacketRequest.HostTag);
                                update_eosp_to_head_of_broadcast_list_head(priv, interfaceTag);
                           }
#endif
                        } else {
                            /* Queue the packet to genericMgtFrame of unifi_priv_t data structure */
                            list = &interfacePriv->genericMgtFrames;
                            unifi_trace(priv, UDBG2, "genericMgtFrames queue not empty\n");
                        }
                    } else {
                        /* check peer power state */
                        if (queuePacketDozing || !list_empty(&staRecord->mgtFrames) || IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag)) {
                            /* peer is in dozing mode, so queue packet in mgt frame list of station record */
                           /*if multicast traffic is going on, buffer the unicast packets*/
                            list = &staRecord->mgtFrames;

                            unifi_trace(priv, UDBG1, "staRecord->MgtFrames list empty? = %s, handle = %d, queuePacketDozing = %d\n",
                                        (list_empty(&staRecord->mgtFrames))? "YES": "NO", staRecord->assignedHandle, queuePacketDozing);
                            if(IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag)){
                                update_eosp_to_head_of_broadcast_list_head(priv, interfaceTag);
                            }

                        } else {
                            unifi_trace(priv, UDBG5, "staRecord->mgtFrames list is empty uf_process_ma_packet_req \n");
                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
                            if(result == -ENOSPC) {
                                /* requeue the failed packet to staRecord->mgtFrames with same position */
                                list = &staRecord->mgtFrames;
                                requeueOnSamePos = TRUE;
                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending MgtFrames Failed handle = %d so buffering\n", staRecord->assignedHandle);
                                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
                            } else if (result) {
                                status = CSR_RESULT_FAILURE;
                            }
                        }
                    }
                    break;
                case CSR_WIFI_MULTICAST_PDU:
                    unifi_trace(priv, UDBG5, "management multicast/broadcast PDU in uf_process_ma_packet_req 'QUEUE it' \n");
                    /* Queue the packet to genericMulticastOrBroadCastMgtFrames of unifi_priv_t data structure
                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
                     */

                    list = &interfacePriv->genericMulticastOrBroadCastMgtFrames;
                    if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) &&
                            (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
                        setBcTim=TRUE;
                    }
                    break;
                default:
                    unifi_error(priv, "condition never meets: packet type unrecognized\n");
            }
            break;
        case IEEE802_11_FRAMETYPE_DATA:
            switch(pktType)
            {
                case CSR_WIFI_UNICAST_PDU:
                    unifi_trace(priv, UDBG5, "data unicast PDU in uf_process_ma_packet_req \n");
                    /* check peer power state, list status & peer port status */
                    if(!staRecord) {
                        unifi_error(priv, "In %s unicast but staRecord = NULL\n", __FUNCTION__);
                        return CSR_RESULT_FAILURE;
                    } else if (queuePacketDozing || isRouterBufferEnabled(priv, priority_q)|| !list_empty(&staRecord->dataPdu[priority_q]) || IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag)) {
                        /* peer is in dozing mode, so queue packet in mgt frame list of station record */
                        /* if multicast traffic is going on, buffet the unicast packets */
                        unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\
                                Buffering enabled = %d \n", priority_q, queuePacketDozing, isRouterBufferEnabled(priv, priority_q));
                        list = &staRecord->dataPdu[priority_q];
                    } else {
                        unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q);
                        /* Pdu allowed to send to unifi */
                        result = ul_send_signal_unpacked(priv, &signal, bulkdata);
                        if(result == -ENOSPC) {
                            /* requeue the failed packet to staRecord->dataPdu[priority_q] with same position */
                            unifi_trace(priv, UDBG1, "(ENOSPC) Sending Unicast DataPDU to queue %d Failed so buffering\n", priority_q);
                            requeueOnSamePos = TRUE;
                            list = &staRecord->dataPdu[priority_q];
                            priv->pausedStaHandle[priority_q]=(u8)(staRecord->assignedHandle);
                            if(!isRouterBufferEnabled(priv, priority_q)) {
                                unifi_error(priv, "Buffering Not enabled for queue %d \n", priority_q);
                            }
                        } else if (result) {
                            status = CSR_RESULT_FAILURE;
                        }
                    }
                    break;
                case CSR_WIFI_MULTICAST_PDU:
                    unifi_trace(priv, UDBG5, "data multicast/broadcast PDU in uf_process_ma_packet_req \n");
                    /* Queue the packet to genericMulticastOrBroadCastFrames list of unifi_priv_t data structure
                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
                     */
                    list = &interfacePriv->genericMulticastOrBroadCastFrames;
                    if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
                        setBcTim = TRUE;
                    }
                    break;
                default:
                    unifi_error(priv, "condition never meets: packet type un recognized\n");
            }
            break;
        default:
            unifi_error(priv, "unrecognized frame type\n");
    }
    if(list) {
        status = enque_tx_data_pdu(priv, bulkdata, list, &signal, requeueOnSamePos);
        /* Record no. of packet queued for each peer */
        if (staRecord && (pktType == CSR_WIFI_UNICAST_PDU) && (!status)) {
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staRecord->noOfPktQueued++;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }
        else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status))
        {
            /* If broadcast Tim is set && queuing is successful, then only update TIM */
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            interfacePriv->noOfbroadcastPktQueued++;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }
    }
    /* If broadcast Tim is set && queuing is successful, then only update TIM */
    if(setBcTim && !status) {
        unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n");
        if (!interfacePriv->bcTimSetReqPendingFlag)
        {
            update_tim(priv, 0, CSR_WIFI_TIM_SET, interfaceTag, handle);
        }
        else
        {
            /* Cache the TimSet value so that it will processed immidiatly after
            * completing the current setTim Request
            */
            interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET;
            unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n",
                        interfacePriv->bcTimSetReqQueued);
        }
    } else if(staRecord && staRecord->currentPeerState ==
                            CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
        if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
            if(!staRecord->wmmOrQosEnabled) {
                if(!list_empty(&staRecord->mgtFrames) ||
                   !list_empty(&staRecord->dataPdu[3]) ||
                   !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) {
                    unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n");
                    if (!staRecord->timRequestPendingFlag){
                        update_tim(priv, staRecord->aid, 1, interfaceTag, handle);
                    }
                    else
                    {
                        /* Cache the TimSet value so that it will processed immidiatly after
                         * completing the current setTim Request
                         */
                        staRecord->updateTimReqQueued = 1;
                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                                    staRecord->aid);
                    }
                }
            } else {
                /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
                u8 allDeliveryEnabled = 0, dataAvailable = 0;
                /* Check if all AC's are Delivery Enabled */
                is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
                if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)
                    || (!list_empty(&staRecord->mgtFrames))) {
                    if (!staRecord->timRequestPendingFlag) {
                        update_tim(priv, staRecord->aid, 1, interfaceTag, handle);
                    }
                    else
                    {
                        /* Cache the TimSet value so that it will processed immidiatly after
                         * completing the current setTim Request
                         */
                        staRecord->updateTimReqQueued = 1;
                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                                    staRecord->aid);
                    }
                }
            }
        }
    }

    if((list) && (pktType == CSR_WIFI_UNICAST_PDU && !queuePacketDozing) && !(isRouterBufferEnabled(priv, priority_q)) && !(IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag))) {
        unifi_trace(priv, UDBG2, "buffering cleared for queue = %d So resending buffered frames\n", priority_q);
        uf_send_buffered_frames(priv, priority_q);
    }
    unifi_trace(priv, UDBG5, "leaving uf_process_ma_packet_req \n");
    return status;
#else
#ifdef CSR_NATIVE_LINUX
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
        return CSR_RESULT_FAILURE;
    }
    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag, interfaceTag,
            transmissionControl, leSenderProcessId,
            peerMacAddress, &signal);
    result = ul_send_signal_unpacked(priv, &signal, bulkdata);
    if (result) {
        return CSR_RESULT_FAILURE;
    }
#endif
    return status;
#endif
}

#ifdef CSR_SUPPORT_SME
s8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, u16 interfaceTag, const u8 *daddr)
{
    s8 protection = 0;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            protection = interfacePriv->protect;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            {
                CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
                if (daddr[0] & 0x1) {
                    unifi_trace(priv, UDBG3, "broadcast/multicast packet in send_ma_pkt_request\n");
                    /* In this mode, the protect member of priv structure has an information of how
                     * AP/P2PGO has started, & the member updated in set mode request for AP/P2PGO
                     */
                    protection = interfacePriv->protect;
                } else {
                    /* fetch the destination record from station record database */
                    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, daddr, interfaceTag);
                    if (!dstStaInfo) {
                        unifi_trace(priv, UDBG3, "peer not found in station record in send_ma_pkt_request\n");
                        return -1;
                    }
                    protection = dstStaInfo->protection;
                }
            }
            break;
        default:
            unifi_trace(priv, UDBG2, "mode unknown in send_ma_pkt_request\n");
    }
    return protection;
}
#endif
#ifdef CSR_SUPPORT_SME
u8 send_multicast_frames(unifi_priv_t *priv, u16 interfaceTag)
{
    int r;
    tx_buffered_packets_t * buffered_pkt = NULL;
    u8 moreData = FALSE;
    u8 pduSent =0;
    unsigned long lock_flags;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    u32 hostTag = 0xffffffff;

    if(!isRouterBufferEnabled(priv, UNIFI_TRAFFIC_Q_VO)) {
        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv, &interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;


            unifi_trace(priv, UDBG2, "DTIM Occurred for interface:sending Mgt packet %d\n", interfaceTag);

            if((r=frame_and_send_queued_pdu(priv, buffered_pkt, NULL, moreData, FALSE)) == -ENOSPC) {
               unifi_trace(priv, UDBG1, "frame_and_send_queued_pdu failed with ENOSPC for host tag = %x\n", buffered_pkt->hostTag);
               /* Enqueue at the head of the queue */
               spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
               list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastMgtFrames);
               spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
               break;
            } else {
                unifi_trace(priv, UDBG1, "send_multicast_frames: Send genericMulticastOrBroadCastMgtFrames (%x, %x)\n",
                                        buffered_pkt->hostTag,
                                        r);
                if(r) {
                   unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                }
                if(!moreData) {

                    interfacePriv->dtimActive = FALSE;
                    if(!r) {
                        hostTag = buffered_pkt->hostTag;
                        pduSent++;
                    } else {
                        send_vif_availibility_rsp(priv, uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag), CSR_RC_UNSPECIFIED_FAILURE);
                    }
                }
                /* Buffered frame sent successfully */
                spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
                interfacePriv->noOfbroadcastPktQueued--;
                spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
                kfree(buffered_pkt);
           }

        }
    }
    if(!isRouterBufferEnabled(priv, UNIFI_TRAFFIC_Q_CONTENTION)) {
        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv, &interfacePriv->genericMulticastOrBroadCastFrames))) {
            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;


            if((r=frame_and_send_queued_pdu(priv, buffered_pkt, NULL, moreData, FALSE)) == -ENOSPC) {
                /* Clear the trigger bit transmission control*/
                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK);
                /* Enqueue at the head of the queue */
                spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastFrames);
                spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                break;
            } else {
                if(r) {
                    unifi_trace(priv, UDBG1, "send_multicast_frames: Send genericMulticastOrBroadCastFrame failed (%x, %x)\n",
                                            buffered_pkt->hostTag,
                                            r);
                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                }
                if(!moreData) {
                    interfacePriv->dtimActive = FALSE;
                    if(!r) {
                        pduSent ++;
                        hostTag = buffered_pkt->hostTag;
                    } else {
                        send_vif_availibility_rsp(priv, uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag), CSR_RC_UNSPECIFIED_FAILURE);
                    }
                }
                /* Buffered frame sent successfully */
                spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
                interfacePriv->noOfbroadcastPktQueued--;
                spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
                kfree(buffered_pkt);
            }
        }
    }
    if((interfacePriv->dtimActive == FALSE)) {
        /* Record the host Tag*/
        unifi_trace(priv, UDBG2, "send_multicast_frames: Recorded hostTag of EOSP packet: = 0x%x\n", hostTag);
        interfacePriv->multicastPduHostTag = hostTag;
    }
    return pduSent;
}
#endif
void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv, u8 *sigdata,
                                        u32 siglen)
{
#ifdef CSR_SUPPORT_SME
    CSR_SIGNAL signal;
    CSR_MA_VIF_AVAILABILITY_INDICATION *ind;
    int r;
    u16 interfaceTag;
    u8 pduSent =0;
    CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS;
    netInterface_priv_t *interfacePriv;

    unifi_trace(priv, UDBG3,
            "uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n",
            *((u16*)sigdata));

    r = read_unpack_signal(sigdata, &signal);
    if (r) {
        unifi_error(priv,
                    "uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n",
                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
        return;
    }
    ind = &signal.u.MaVifAvailabilityIndication;
    interfaceTag=ind->VirtualInterfaceIdentifier & 0xff;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "in vif_availability_ind interfaceTag is wrong\n");
        return;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    if(ind->Multicast) {
        if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames) &&
            list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames)) {
            /* This condition can occur because of a potential race where the
               TIM is not yet reset as host is waiting for confirm but it is sent
               by firmware and DTIM occurs*/
            unifi_notice(priv, "ma_vif_availibility_ind recevied for multicast but queues are empty%d\n", interfaceTag);
            send_vif_availibility_rsp(priv, ind->VirtualInterfaceIdentifier, CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
            interfacePriv->dtimActive = FALSE;
            if(interfacePriv->multicastPduHostTag == 0xffffffff) {
                unifi_notice(priv, "ma_vif_availibility_ind recevied for multicast but queues are empty%d\n", interfaceTag);
                /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */
                if (!interfacePriv->bcTimSetReqPendingFlag)
                {
                    update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF);
                }
                else
                {
                    /* Cache the TimSet value so that it will processed immidiatly after
                     * completing the current setTim Request
                     */
                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
                    unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n",
                                interfacePriv->bcTimSetReqQueued);
                }
            }
            return;
        }
        if(interfacePriv->dtimActive) {
            unifi_trace(priv, UDBG2, "DTIM Occurred for already active DTIM interface %d\n", interfaceTag);
            return;
        } else {
            unifi_trace(priv, UDBG2, "DTIM Occurred for interface %d\n", interfaceTag);
            if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
                set_eosp_transmit_ctrl(priv, &interfacePriv->genericMulticastOrBroadCastMgtFrames);
            } else {
                set_eosp_transmit_ctrl(priv, &interfacePriv->genericMulticastOrBroadCastFrames);
            }
        }
        interfacePriv->dtimActive = TRUE;
        pduSent = send_multicast_frames(priv, interfaceTag);
    }
    else {
        unifi_error(priv, "Interface switching is not supported %d\n", interfaceTag);
        resultCode = CSR_RC_NOT_SUPPORTED;
        send_vif_availibility_rsp(priv, ind->VirtualInterfaceIdentifier, CSR_RC_NOT_SUPPORTED);
    }
#endif
}
#ifdef CSR_SUPPORT_SME

#define  GET_ACTIVE_INTERFACE_TAG(priv) 0

static u8 uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord)
{
    s8 i;

    for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--)
    {
        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
             &&(!list_empty(&staRecord->dataPdu[i]))) {
            unifi_trace(priv, UDBG2, "uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i);
            return TRUE;
        }
    }

    unifi_trace(priv, UDBG2, "uf_is_more_data_for_delivery_ac: Data NOT Available \n");
    return FALSE;
}

static u8 uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue)
{
    s8 i;

    for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--)
    {
        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
             &&(!list_empty(&staRecord->dataPdu[i]))) {
            unifi_trace(priv, UDBG2, "uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i);
            return TRUE;
        }
    }

    unifi_trace(priv, UDBG2, "uf_is_more_data_for_usp_delivery: Data NOT Available \n");
    return FALSE;
}

/*
 * ---------------------------------------------------------------------------
 *  uf_send_buffered_data_from_delivery_ac
 *
 *      This function takes care of
 *      -> Parsing the delivery enabled queue & sending frame down to HIP
 *      -> Setting EOSP=1 when USP to be terminated
 *      -> Depending on MAX SP length services the USP
 *
 * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont
 *      call this function from any other location in code
 *
 *  Arguments:
 *      priv        Pointer to device private context struct
 *      vif         interface specific HIP vif instance
 *      staInfo     peer for which UAPSD to be scheduled
 *      queue       AC from which Data to be sent in USP
 *      txList      access category for processing list
 * ---------------------------------------------------------------------------
 */
void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
                                            CsrWifiRouterCtrlStaInfo_t * staInfo,
                                            u8 queue,
                                            struct list_head *txList)
{

    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
    tx_buffered_packets_t * buffered_pkt = NULL;
    unsigned long lock_flags;
    u8 eosp=FALSE;
    s8 r =0;
    u8 moreData = FALSE;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);

    if (queue > UNIFI_TRAFFIC_Q_VO)
    {
        return;
    }
    while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) {
        if((IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag))) {
            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n",
                        staInfo->aid);

            /* Once resume called, the U-APSD delivery operation will resume */
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staInfo->uspSuspend = TRUE;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
            /* re-queueing the packet as DTIM started */
            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
            list_add(&buffered_pkt->q, txList);
            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
            break;
        }

        buffered_pkt->transmissionControl &=
                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);


        if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) {

             buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK;

             /* Check All delivery enables Ac for more data, because caller of this
              * function not aware about last packet
              * (First check in moreData fetching helps in draining out Mgt frames Q)
              */
              moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue));

              if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) {
                  moreData = FALSE;
              }

              if(moreData == FALSE) {
                  eosp = TRUE;
                  buffered_pkt->transmissionControl =
                      (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
              }
        } else {
            /* Non QoS and non U-APSD */
            unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n");
        }

        unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n", moreData, eosp);

        if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staInfo, moreData, eosp)) == -ENOSPC) {

            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue);

            /* Once resume called, the U-APSD delivery operation will resume */
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staInfo->uspSuspend = TRUE;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);

            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
            list_add(&buffered_pkt->q, txList);
            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
            priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
            break;
        } else {
            if(r){
                /* the PDU failed where we can't do any thing so free the storage */
                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
            }
            kfree(buffered_pkt);
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staInfo->noOfSpFramesSent++;
            if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) {
                unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n");
                staInfo->uapsdActive = FALSE;
                staInfo->uspSuspend = FALSE;
                staInfo->noOfSpFramesSent = 0;
                spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
                break;
            }
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }
    }
    unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
}

void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
                                   CsrWifiRouterCtrlStaInfo_t * staInfo,
                                   u8 queue,
                                   struct list_head *txList)
{
    tx_buffered_packets_t * buffered_pkt = NULL;
    unsigned long lock_flags;
    u8 eosp=FALSE;
    u8 moreData = FALSE;
    s8 r =0;

    unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_ac :\n");

    while(!isRouterBufferEnabled(priv, queue) &&
                    ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){

        buffered_pkt->transmissionControl &=
                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);

        unifi_trace(priv, UDBG3, "uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n", moreData, eosp);

        if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staInfo, moreData, eosp)) == -ENOSPC) {
           /* Enqueue at the head of the queue */
           spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
           list_add(&buffered_pkt->q, txList);
           spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
           if(staInfo != NULL){
              priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
           }
           unifi_trace(priv, UDBG3, " uf_send_buffered_data_from_ac: PDU sending failed .. no space for queue %d \n", queue);
           } else {
            if(r){
                /* the PDU failed where we can't do any thing so free the storage */
                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
            }
            kfree(buffered_pkt);
      }
  }

}

void uf_send_buffered_frames(unifi_priv_t *priv, unifi_TrafficQueue q)
{
    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
    u32 startIndex=0, endIndex=0;
    CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
    u8 queue;
    u8 moreData = FALSE;

    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)))
        return;

    queue = (q<=3)?q:0;

    if(interfacePriv->dtimActive) {
        /* this function updates dtimActive*/
        send_multicast_frames(priv, interfaceTag);
        if(!interfacePriv->dtimActive) {
            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
             !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
            if(!moreData) {
                if (!interfacePriv->bcTimSetReqPendingFlag)
                {
                    update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0XFFFFFFFF);
                }
                else
                {
                    /* Cache the TimSet value so that it will processed immidiatly after
                     * completing the current setTim Request
                     */
                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
                    unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n",
                                interfacePriv->bcTimSetReqQueued);
                }
            }
        } else {
            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
                        !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
           if(!moreData) {
               /* This should never happen but if it happens, we need a way out */
               unifi_error(priv, "ERROR: No More Data but DTIM is active sending Response\n");
               send_vif_availibility_rsp(priv, uf_get_vif_identifier(interfacePriv->interfaceMode, interfaceTag), CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
               interfacePriv->dtimActive = FALSE;
           }
        }
        return;
    }
    if(priv->pausedStaHandle[queue] > 7) {
        priv->pausedStaHandle[queue] = 0;
    }

    if(queue == UNIFI_TRAFFIC_Q_VO) {


        unifi_trace(priv, UDBG2, "uf_send_buffered_frames : trying mgt from queue=%d\n", queue);
        for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
            staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, startIndex, interfaceTag);
            if(!staInfo ) {
                continue;
            } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
                       &&(staInfo->uapsdActive == FALSE) ) {
                continue;
            }

            if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
                               &&(staInfo->uapsdActive == FALSE)){
                            /*Non-UAPSD case push the management frames out*/
               if(!list_empty(&staInfo->mgtFrames)){
                    uf_send_buffered_data_from_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
                }
            }

            if(isRouterBufferEnabled(priv, queue)) {
                unifi_notice(priv, "uf_send_buffered_frames : No space Left for queue = %d\n", queue);
                break;
            }
        }
        /*push generic management frames out*/
        if(!list_empty(&interfacePriv->genericMgtFrames)) {
            unifi_trace(priv, UDBG2, "uf_send_buffered_frames : trying generic mgt from queue=%d\n", queue);
            uf_send_buffered_data_from_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
        }
    }


    unifi_trace(priv, UDBG2, "uf_send_buffered_frames : Resume called for Queue=%d\n", queue);
    unifi_trace(priv, UDBG2, "uf_send_buffered_frames : start=%d end=%d\n", startIndex, endIndex);

    startIndex = priv->pausedStaHandle[queue];
    endIndex = (startIndex + UNIFI_MAX_CONNECTIONS -1) % UNIFI_MAX_CONNECTIONS;

    while(startIndex != endIndex) {
        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, startIndex, interfaceTag);
        if(!staInfo) {
            startIndex ++;
            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
                startIndex = 0;
            }
            continue;
        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
                   &&(staInfo->uapsdActive == FALSE)) {
            startIndex ++;
            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
                startIndex = 0;
            }
            continue;
        }
        /* Peer is active or U-APSD is active so send PDUs to the peer */
        unifi_trace(priv, UDBG2, "uf_send_buffered_frames : trying data from queue=%d\n", queue);


        if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
                           &&(staInfo->uapsdActive == FALSE)) {
           if(!list_empty(&staInfo->dataPdu[queue])) {

               /*Non-UAPSD case push the AC frames out*/
               uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
           }
        }
        startIndex ++;
        if(startIndex >= UNIFI_MAX_CONNECTIONS) {
           startIndex = 0;
        }
    }
    if(isRouterBufferEnabled(priv, queue)) {
        priv->pausedStaHandle[queue] = endIndex;
    } else {
        priv->pausedStaHandle[queue] = 0;
    }

    /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity).
     * So restart it if U-APSD was active with any of the station
     */
    unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
    resume_suspended_uapsd(priv, interfaceTag);
}


u8 uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord)
{
    u8 i;

    for(i=0;i<=3;i++)
    {
        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
                ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
                &&(!list_empty(&staRecord->dataPdu[i]))){

         return TRUE;
        }
    }

    if(((staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
            ||(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
            &&(!list_empty(&staRecord->mgtFrames))){

     return TRUE;
    }



    return FALSE;
}


int uf_process_station_records_for_sending_data(unifi_priv_t *priv, u16 interfaceTag,
                                                 CsrWifiRouterCtrlStaInfo_t *srcStaInfo,
                                                 CsrWifiRouterCtrlStaInfo_t *dstStaInfo)
{
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    unifi_trace(priv, UDBG5, "entering uf_process_station_records_for_sending_data\n");

    if (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED) {
        unifi_error(priv, "Peer State not connected AID = %x, handle = %x, control port state = %x\n",
                    srcStaInfo->aid, srcStaInfo->assignedHandle, srcStaInfo->peerControlledPort->port_action);
        return -1;
    }
    switch (interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
            unifi_trace(priv, UDBG5, "mode is AP/P2PGO\n");
            break;
        default:
            unifi_warning(priv, "mode is nor AP neither P2PGO, packet cant be xmit\n");
            return -1;
    }

    switch(dstStaInfo->peerControlledPort->port_action)
    {
        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD:
        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK:
            unifi_trace(priv, UDBG5, "destination port is closed/blocked, discarding the packet\n");
            return -1;
        default:
            unifi_trace(priv, UDBG5, "destination port state is open\n");
    }

    /* port state is open, destination station record is valid, Power save state is
     * validated in uf_process_ma_packet_req function
     */
    unifi_trace(priv, UDBG5, "leaving uf_process_station_records_for_sending_data\n");
    return 0;
}


/*
 * ---------------------------------------------------------------------------
 *  uf_handle_uspframes_delivery
 *
 *      This function takes care of handling USP session for peer, when
 *      -> trigger frame from peer
 *      -> suspended USP to be processed (resumed)
 *
 *      NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont
 *      make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of
 *      code
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      staInfo         peer for which UAPSD to be scheduled
 *      interfaceTag    virtual interface tag
 * ---------------------------------------------------------------------------
 */
static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, u16 interfaceTag)
{

    s8 i;
    u8 allDeliveryEnabled = 0, dataAvailable = 0;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    unsigned long lock_flags;

    unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n",
                staInfo->uapsdActive, staInfo->uspSuspend);

    /* Check for Buffered frames according to priority order & deliver it
     *  1. AC_VO delivery enable & Mgt frames available
     *  2. Process remaining Ac's from order AC_VO to AC_BK
     */

    /* USP initiated by WMMPS enabled peer  & SET the status flag to TRUE */
    if (!staInfo->uspSuspend && staInfo->uapsdActive)
    {
        unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n",
                staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1],
                staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3],
                staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]);
        return;
    }

    spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
    staInfo->uapsdActive = TRUE;
    staInfo->uspSuspend = FALSE;
    spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);

    if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
        (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
        && (!list_empty(&staInfo->mgtFrames))) {

         /* Management queue has data &&  UNIFI_TRAFFIC_Q_VO is delivery enable */
        unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n");
        uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
    }

    if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) {
        /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP
         * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP
         */
        if (!staInfo->uspSuspend) {
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            staInfo->uapsdActive = FALSE;
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);

            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n");
            uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo);
            staInfo->triggerFramePriority = CSR_QOS_UP0;
        } else {
            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n");
        }
    } else {
        for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) {
            if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
                ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
                && (!list_empty(&staInfo->dataPdu[i]))) {
                /* Deliver Data according to AC priority (from VO to BK) as part of USP */
                unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i);
                uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
            }

            if ((!staInfo->uapsdActive) ||
                    (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag))) {
                /* If DTIM active found on one AC, No need to parse the remaining AC's
                 * as USP suspended. Break out of loop
                 */
                unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x,  DTIM=%x, USP terminated=%s\n",
                           staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag),
                           staInfo->uapsdActive?"NO":"YES");
                break;
            }
        }
    }

    /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only
     * (since we are not manipulating any Non-delivery list(AC))
     */
    is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
    if ((allDeliveryEnabled && !dataAvailable)) {
        if ((staInfo->timSet != CSR_WIFI_TIM_RESET) && (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) {
            staInfo->updateTimReqQueued = (u8) CSR_WIFI_TIM_RESET;
            unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n");
            if (!staInfo->timRequestPendingFlag) {
                update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle);
            }
        }
    }
    unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n",
                staInfo->uapsdActive, staInfo->uspSuspend);
}

void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
                                     CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
                                     u16 qosControl,
                                     u16 interfaceTag)
{
    CSR_PRIORITY priority;
    unifi_TrafficQueue priority_q;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
    /* If recceived Frames trigger Frame and Devlivery enabled AC has data
     * then transmit from High priorty delivery enabled AC
     */
    priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);

    if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
        ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) {
        spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
        srcStaInfo->triggerFramePriority = priority;
        spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q);
        uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag);
    }
    unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
}


void uf_send_qos_null(unifi_priv_t * priv, u16 interfaceTag, const u8 *da, CSR_PRIORITY priority, CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
{
    bulk_data_param_t bulkdata;
    CsrResult csrResult;
    struct sk_buff *skb, *newSkb = NULL;
    CsrWifiMacAddress peerAddress;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
    int r;
    CSR_SIGNAL signal;
    u32 priority_q;
    CSR_RATE transmitRate = 0;


    /* Send a Null Frame to Peer,
     * 32= size of mac header  */
    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE);

    if (csrResult != CSR_RESULT_SUCCESS) {
        unifi_error(priv, " failed to allocate request_data. in uf_send_qos_null func\n");
        return ;
    }
    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
    skb->len = 0;
    bulkdata.d[0].os_data_ptr = skb->data;
    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
    bulkdata.d[1].os_data_ptr = NULL;
    bulkdata.d[1].os_net_buf_ptr = NULL;
    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;

    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */

    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
        unifi_error(priv, "failed to create MAC header\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return;
    }
    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
    /* convert priority to queue */
    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);

    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
     */
    switch (interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
            transmitRate = 2;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            transmitRate = 12;
            break;
        default:
            transmitRate = 0;
    }
    unifi_frame_ma_packet_req(priv, priority, transmitRate, 0xffffffff, interfaceTag,
                              transmissionControl, priv->netdev_client->sender_id,
                              peerAddress.a, &signal);

    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
    if(r) {
        unifi_error(priv, "failed to send QOS data null packet result: %d\n", r);
        unifi_net_data_free(priv, &bulkdata.d[0]);
    }

    return;

}
void uf_send_nulldata(unifi_priv_t * priv, u16 interfaceTag, const u8 *da, CSR_PRIORITY priority, CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
{
    bulk_data_param_t bulkdata;
    CsrResult csrResult;
    struct sk_buff *skb, *newSkb = NULL;
    CsrWifiMacAddress peerAddress;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    CSR_TRANSMISSION_CONTROL transmissionControl = 0;
    int r;
    CSR_SIGNAL signal;
    u32 priority_q;
    CSR_RATE transmitRate = 0;
    CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
    unsigned long lock_flags;

    /* Send a Null Frame to Peer, size = 24 for MAC header */
    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE);

    if (csrResult != CSR_RESULT_SUCCESS) {
        unifi_error(priv, "uf_send_nulldata: Failed to allocate memory for NULL frame\n");
        return ;
    }
    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
    skb->len = 0;
    bulkdata.d[0].os_data_ptr = skb->data;
    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
    bulkdata.d[1].os_data_ptr = NULL;
    bulkdata.d[1].os_net_buf_ptr = NULL;
    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;

    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */
    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
        unifi_error(priv, "uf_send_nulldata: Failed to create MAC header\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return;
    }
    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
    /* convert priority to queue */
    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
    transmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);

    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
     */
    switch (interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
            transmitRate = 2;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            transmitRate = 12;
            break;
        default:
            transmitRate = 0;
    }
    unifi_frame_ma_packet_req(priv, priority, transmitRate, INVALID_HOST_TAG, interfaceTag,
                              transmissionControl, priv->netdev_client->sender_id,
                              peerAddress.a, &signal);

    /* Save host tag to check the status on reception of MA packet confirm */
    srcStaInfo->nullDataHostTag = req->HostTag;
    unifi_trace(priv, UDBG1, "uf_send_nulldata: STA AID = %d hostTag = %x\n", srcStaInfo->aid, req->HostTag);

    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);

    if(r == -ENOSPC) {
        unifi_trace(priv, UDBG1, "uf_send_nulldata: ENOSPC Requeue the Null frame\n");
        enque_tx_data_pdu(priv, &bulkdata, &srcStaInfo->dataPdu[priority_q], &signal, 1);
        spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
        srcStaInfo->noOfPktQueued++;
        spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);


    }
    if(r && r != -ENOSPC){
        unifi_error(priv, "uf_send_nulldata: Failed to send Null frame Error = %d\n", r);
        unifi_net_data_free(priv, &bulkdata.d[0]);
        srcStaInfo->nullDataHostTag = INVALID_HOST_TAG;
    }

    return;
}

u8 uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata)
{
    u8 *bssid = NULL;
    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
    u8 toDs, fromDs;

    toDs = (((bulkdata->d[0].os_data_ptr)[1]) & 0x01) ? 1 : 0;
    fromDs =(((bulkdata->d[0].os_data_ptr)[1]) & 0x02) ? 1 : 0;

     if (toDs && fromDs)
    {
        unifi_trace(priv, UDBG6, "Address 4 present, Don't try to find BSSID\n");
        bssid = NULL;
    }
    else if((toDs == 0) && (fromDs ==0))
    {
        /* BSSID is Address 3 */
        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + (2 * ETH_ALEN));
    }
    else if(toDs)
    {
        /* BSSID is Address 1 */
        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4);
    }
    else if(fromDs)
    {
        /* BSSID is Address 2 */
        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + ETH_ALEN);
    }

    if (memcmp(broadcast_address.a, bssid, ETH_ALEN)== 0)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}


u8 uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
                                u8 pmBit, u16 interfaceTag)
{
    u8 moreData = FALSE;
    u8 powerSaveChanged = FALSE;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG3, "entering uf_process_pm_bit_for_peer\n");
    if (pmBit) {
        priv->allPeerDozing |= (0x01 << (srcStaInfo->assignedHandle));
    } else {
        priv->allPeerDozing &= ~(0x01 << (srcStaInfo->assignedHandle));
    }
    if(pmBit) {
        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {

            /* disable the preemption */
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            srcStaInfo->currentPeerState =CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE;
            powerSaveChanged = TRUE;
            /* enable the preemption */
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        } else {
            return powerSaveChanged;
        }
    } else {
        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
            /* disable the preemption */
            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
            srcStaInfo->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
            powerSaveChanged = TRUE;
            /* enable the preemption */
            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
        }else {
            return powerSaveChanged;
        }
    }


    if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {
        unifi_trace(priv, UDBG3, "Peer with AID = %d is active now\n", srcStaInfo->aid);
        process_peer_active_transition(priv, srcStaInfo, interfaceTag);
    } else {
        unifi_trace(priv, UDBG3, "Peer with AID = %d is in PS Now\n", srcStaInfo->aid);
        /* Set TIM if needed */
        if(!srcStaInfo->wmmOrQosEnabled) {
            moreData = (!list_empty(&srcStaInfo->mgtFrames) ||
                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_VO])||
                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]));
            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
                unifi_trace(priv, UDBG3, "This condition should not occur\n");
                if (!srcStaInfo->timRequestPendingFlag){
                    update_tim(priv, srcStaInfo->aid, 1, interfaceTag, srcStaInfo->assignedHandle);
                }
                else
                {
                    /* Cache the TimSet value so that it will processed immidiatly after
                     * completing the current setTim Request
                     */
                    srcStaInfo->updateTimReqQueued = 1;
                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
                                srcStaInfo->aid);
                }

            }
        } else {
            u8 allDeliveryEnabled = 0, dataAvailable = 0;
            unifi_trace(priv, UDBG5, "Qos in AP Mode\n");
            /* Check if all AC's are Delivery Enabled */
            is_all_ac_deliver_enabled_and_moredata(srcStaInfo, &allDeliveryEnabled, &dataAvailable);
            /*check for more data in non-delivery enabled queues*/
            moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable));

            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
                if (!srcStaInfo->timRequestPendingFlag){
                    update_tim(priv, srcStaInfo->aid, 1, interfaceTag, srcStaInfo->assignedHandle);
                }
                else
                {
                    /* Cache the TimSet value so that it will processed immidiatly after
                     * completing the current setTim Request
                     */
                    srcStaInfo->updateTimReqQueued = 1;
                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
                                srcStaInfo->aid);
                }
            }
        }
    }
    unifi_trace(priv, UDBG3, "leaving uf_process_pm_bit_for_peer\n");
    return powerSaveChanged;
}



void uf_process_ps_poll(unifi_priv_t *priv, u8* sa, u8* da, u8 pmBit, u16 interfaceTag)
{
    CsrWifiRouterCtrlStaInfo_t *staRecord =
    CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, sa, interfaceTag);
    tx_buffered_packets_t * buffered_pkt = NULL;
    CsrWifiMacAddress peerMacAddress;
    unsigned long lock_flags;
    s8 r =0;
    u8 moreData = FALSE;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    unifi_trace(priv, UDBG3, "entering uf_process_ps_poll\n");
    if(!staRecord) {
        memcpy(peerMacAddress.a, sa, ETH_ALEN);
        unifi_trace(priv, UDBG3, "In uf_process_ps_poll, sta record not found:unexpected frame addr = %x:%x:%x:%x:%x:%x\n",
                sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
        CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
        return;
    }

    uf_process_pm_bit_for_peer(priv, staRecord, pmBit, interfaceTag);

    /* Update station last activity time */
    staRecord->activity_flag = TRUE;

    /* This should not change the PM bit as PS-POLL has PM bit always set */
    if(!pmBit) {
        unifi_notice (priv, " PM bit reset in PS-POLL\n");
        return;
    }

    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive, interfacePriv->multicastPduHostTag)) {
        /* giving more priority to multicast packets so dropping ps-poll*/
        unifi_notice (priv, " multicast transmission is going on so don't take action on PS-POLL\n");
        return;
    }

    if(!staRecord->wmmOrQosEnabled) {
        if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
                        !list_empty(&staRecord->mgtFrames));

            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
            if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, moreData, FALSE)) == -ENOSPC) {
                /* Clear the trigger bit transmission control*/
                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
                /* Enqueue at the head of the queue */
                spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                list_add(&buffered_pkt->q, &staRecord->mgtFrames);
                spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
            } else {
                if(r){
                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                    /* the PDU failed where we can't do any thing so free the storage */
                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                }
                kfree(buffered_pkt);
            }
        } else if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) {
            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]));

            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
            if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, moreData, FALSE)) == -ENOSPC) {
                /* Clear the trigger bit transmission control*/
                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
                /* Enqueue at the head of the queue */
                spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
                spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
            } else {
                if(r){
                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                    /* the PDU failed where we can't do any thing so free the storage */
                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                }
                kfree(buffered_pkt);
            }
        } else  if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]))) {
            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
            moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);

            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
            if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, moreData, FALSE)) == -ENOSPC) {
                /* Clear the trigger bit transmission control*/
                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
                /* Enqueue at the head of the queue */
                spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
                spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
            } else {
                if(r){
                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                    /* the PDU failed where we can't do any thing so free the storage */
                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                }
                kfree(buffered_pkt);
            }
        } else {
         /* Actually since we have sent an ACK, there
         * there is no need to send a NULL frame*/
        }
        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
           !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
            !list_empty(&staRecord->mgtFrames));
        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
            if (!staRecord->timRequestPendingFlag){
                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
            }
            else
            {
                /* Cache the TimSet value so that it will processed immidiatly after
                 * completing the current setTim Request
                 */
                staRecord->updateTimReqQueued = 0;
                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                            staRecord->aid);
            }
        }
    } else {

        u8 allDeliveryEnabled = 0, dataAvailable = 0;
        unifi_trace(priv, UDBG3, "Qos Support station.Processing PS-Poll\n");

        /*Send Data From Management Frames*/
        /* Priority orders for delivering the buffered packets are
         * 1. Deliver the Management frames if there
         * 2. Other access category frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO
         * priority is from VO->BK
         */

        /* Check if all AC's are Delivery Enabled */
        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);

        if (allDeliveryEnabled) {
            unifi_trace(priv, UDBG3, "uf_process_ps_poll: All ACs are delivery enable so Sending QOS Null in response of Ps-poll\n");
            uf_send_qos_null(priv, interfaceTag, sa, CSR_QOS_UP0, staRecord);
            return;
        }

        if (!list_empty(&staRecord->mgtFrames)) {
             if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
                    /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management
                     * queue of the station record
                     */
                    moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
                    buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);

                    /* Last parameter is EOSP & its false always for PS-POLL processing */
                    if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, moreData, FALSE)) == -ENOSPC) {
                        /* Clear the trigger bit transmission control*/
                        buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
                        /* Enqueue at the head of the queue */
                        spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                        list_add(&buffered_pkt->q, &staRecord->mgtFrames);
                        spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                        priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
                        unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
                    } else {
                        if(r){
                            unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                            /* the PDU failed where we can't do any thing so free the storage */
                            unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                        }
                        kfree(buffered_pkt);
                    }
                } else {
                    unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n");
                }

        } else {
            s8 i;
            /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2
             * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK
             */
            for(i= 3; i>=0; i--) {
                if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
                    /* Send One packet, if queue is NULL then continue */
                    if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
                        moreData = uf_is_more_data_for_non_delivery_ac(staRecord);

                        buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);

                        /* Last parameter is EOSP & its false always for PS-POLL processing */
                        if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staRecord, moreData, FALSE)) == -ENOSPC) {
                            /* Clear the trigger bit transmission control*/
                            buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
                            /* Enqueue at the head of the queue */
                            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                            list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
                            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                            priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
                            unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
                        } else {
                            if(r) {
                                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                                /* the PDU failed where we can't do any thing so free the storage */
                                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                            }
                            kfree(buffered_pkt);
                        }
                        break;
                    }
                }
            }
        }
        /* Check if all AC's are Delivery Enabled */
        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
        /*check for more data in non-delivery enabled queues*/
        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
            if (!staRecord->timRequestPendingFlag){
                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
            }
            else
            {
                /* Cache the TimSet value so that it will processed immidiatly after
                 * completing the current setTim Request
                 */
                staRecord->updateTimReqQueued = 0;
                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
                            staRecord->aid);
            }

        }
    }

        unifi_trace(priv, UDBG3, "leaving uf_process_ps_poll\n");
}



void add_to_send_cfm_list(unifi_priv_t * priv,
                          tx_buffered_packets_t *tx_q_item,
                          struct list_head *frames_need_cfm_list)
{
    tx_buffered_packets_t *send_cfm_list_item = NULL;

    send_cfm_list_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);

    if(send_cfm_list_item == NULL){
        unifi_warning(priv, "%s: Failed to allocate memory for new list item \n");
        return;
    }

    INIT_LIST_HEAD(&send_cfm_list_item->q);

    send_cfm_list_item->hostTag = tx_q_item->hostTag;
    send_cfm_list_item->interfaceTag = tx_q_item->interfaceTag;
    send_cfm_list_item->transmissionControl = tx_q_item->transmissionControl;
    send_cfm_list_item->leSenderProcessId = tx_q_item->leSenderProcessId;
    send_cfm_list_item->rate = tx_q_item->rate;
    memcpy(send_cfm_list_item->peerMacAddress.a, tx_q_item->peerMacAddress.a, ETH_ALEN);
    send_cfm_list_item->priority = tx_q_item->priority;

    list_add_tail(&send_cfm_list_item->q, frames_need_cfm_list);
}

void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
                                                 struct list_head *frames_need_cfm_list,
                                                 struct list_head * list)
{
    tx_buffered_packets_t *tx_q_item = NULL;
    struct list_head *listHead;
    struct list_head *placeHolder;
    unsigned long lock_flags;

    spin_lock_irqsave(&priv->tx_q_lock, lock_flags);

    /* Search through the list and if confirmation required for any frames,
    add it to the send_cfm list */
    list_for_each_safe(listHead, placeHolder, list) {
        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);

        if(!tx_q_item) {
            unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
            continue;
        }

        /* check if confirmation is requested and if the sender ID
        is not netdevice client then save the entry in the list for need cfms */
        if (!(tx_q_item->transmissionControl & CSR_NO_CONFIRM_REQUIRED) &&
            (tx_q_item->leSenderProcessId != priv->netdev_client->sender_id)){
             unifi_trace(priv, UDBG1, "%s: SenderProcessID=%x host tag=%x transmission control=%x\n",
                __FUNCTION__,
                tx_q_item->leSenderProcessId,
                tx_q_item->hostTag,
                tx_q_item->transmissionControl);

             add_to_send_cfm_list(priv, tx_q_item, frames_need_cfm_list);
        }
    }

    spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);

}



void uf_flush_list(unifi_priv_t * priv, struct list_head * list)
{
    tx_buffered_packets_t *tx_q_item;
    struct list_head *listHead;
    struct list_head *placeHolder;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG5, "entering the uf_flush_list \n");

    spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
    /* go through list, delete & free memory */
    list_for_each_safe(listHead, placeHolder, list) {
        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);

        if(!tx_q_item) {
            unifi_error(priv, "entry should exists, otherwise crashes (bug)\n");
        }
        unifi_trace(priv, UDBG5,
                "proccess_tx:  in uf_flush_list peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
                tx_q_item->leSenderProcessId);

        list_del(listHead);
        /* free the allocated memory */
        unifi_net_data_free(priv, &tx_q_item->bulkdata);
        kfree(tx_q_item);
        tx_q_item = NULL;
        if (!priv->noOfPktQueuedInDriver) {
            unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
        } else {
            priv->noOfPktQueuedInDriver--;
        }
    }
    spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
}

tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList)
{
    /* dequeue the tx data packets from the appropriate queue */
    tx_buffered_packets_t *tx_q_item = NULL;
    struct list_head *listHead;
    struct list_head *placeHolder;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG5, "entering dequeue_tx_data_pdu\n");
    /* check for list empty */
    if (list_empty(txList)) {
        unifi_trace(priv, UDBG5, "In dequeue_tx_data_pdu, the list is empty\n");
        return NULL;
    }

    /* Verification, if packet count is negetive */
    if (priv->noOfPktQueuedInDriver == 0xFFFF) {
        unifi_warning(priv, "no packet available in queue: debug");
        return NULL;
    }

    /* return first node after header, & delete from the list  && atleast one item exist */
    spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
    list_for_each_safe(listHead, placeHolder, txList) {
        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
        list_del(listHead);
        break;
    }
    spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);

    if (tx_q_item) {
        unifi_trace(priv, UDBG5,
                "proccess_tx:  In dequeue_tx_data_pdu peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
                tx_q_item->leSenderProcessId);
    }

    unifi_trace(priv, UDBG5, "leaving dequeue_tx_data_pdu\n");
    return tx_q_item;
}
/* generic function to get the station record handler */
CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv,
        const u8 *peerMacAddress,
        u16 interfaceTag)
{
    u8 i;
    netInterface_priv_t *interfacePriv;
    unsigned long lock_flags;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "interfaceTag is not proper, interfaceTag = %d\n", interfaceTag);
        return NULL;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    /* disable the preemption until station record is fetched */
    spin_lock_irqsave(&priv->staRecord_lock, lock_flags);

    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        if (interfacePriv->staInfo[i]!= NULL) {
            if (!memcmp(((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]))->peerMacAddress.a, peerMacAddress, ETH_ALEN)) {
                /* enable the preemption as station record is fetched */
                spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
                unifi_trace(priv, UDBG5, "peer entry found in station record\n");
                return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]));
            }
        }
    }
    /* enable the preemption as station record is fetched */
    spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
    unifi_trace(priv, UDBG5, "peer entry not found in station record\n");
    return NULL;
}
/* generic function to get the station record handler from the handle */
CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv,
                                                                 u32 handle,
                                                                 u16 interfaceTag)
{
    netInterface_priv_t *interfacePriv;

    if ((handle >= UNIFI_MAX_CONNECTIONS) || (interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
        unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", handle, interfaceTag);
        return NULL;
    }
    interfacePriv = priv->interfacePriv[interfaceTag];
    return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]));
}

/* Function to do inactivity */
void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, u32 currentTime)
{
    u32 i;
    CsrWifiRouterCtrlStaInfo_t *staInfo;
    u32 elapsedTime;    /* Time in microseconds */
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    CsrWifiMacAddress peerMacAddress;
    unsigned long lock_flags;

    if (interfacePriv == NULL) {
        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
        return;
    }

    spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
    /* Go through the list of stations to check for inactivity */
    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, i, interfaceTag);
        if(!staInfo ) {
            continue;
        }

        unifi_trace(priv, UDBG3, "Running Inactivity handler Time %xus station's last activity %xus\n",
                currentTime, staInfo->lastActivity);


        elapsedTime = (currentTime >= staInfo->lastActivity)?
                (currentTime - staInfo->lastActivity):
                (~((u32)0) - staInfo->lastActivity + currentTime);
        spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);

        if (elapsedTime > MAX_INACTIVITY_INTERVAL) {
            memcpy((u8*)&peerMacAddress, (u8*)&staInfo->peerMacAddress, sizeof(CsrWifiMacAddress));

            /* Indicate inactivity for the station */
            unifi_trace(priv, UDBG3, "Station %x:%x:%x:%x:%x:%x inactive since %xus\n sending Inactive Ind\n",
                        peerMacAddress.a[0], peerMacAddress.a[1],
                        peerMacAddress.a[2], peerMacAddress.a[3],
                        peerMacAddress.a[4], peerMacAddress.a[5],
                        elapsedTime);

            CsrWifiRouterCtrlStaInactiveIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
        }
    }

    interfacePriv->last_inactivity_check = currentTime;
}

/* Function to update activity of a station */
void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress)
{
    u32 elapsedTime, currentTime;    /* Time in microseconds */
    u32 timeHi;         /* Not used - Time in microseconds */
    CsrWifiRouterCtrlStaInfo_t *staInfo;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    unsigned long lock_flags;

    if (interfacePriv == NULL) {
        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
        return;
    }

    currentTime = CsrTimeGet(&timeHi);


    staInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag);

    if (staInfo == NULL) {
        unifi_trace(priv, UDBG4, "Sta does not exist yet");
        return;
    }

    spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
    /* Update activity */
    staInfo->lastActivity = currentTime;

    /* See if inactivity handler needs to be run
     * Here it is theoretically possible that the counter may have wrapped around. But
     * since we just want to know when to run the inactivity handler it does not really matter.
     * Especially since this is data path it makes sense in keeping it simple and avoiding
     * 64 bit handling */
    elapsedTime = (currentTime >= interfacePriv->last_inactivity_check)?
                    (currentTime - interfacePriv->last_inactivity_check):
                    (~((u32)0) - interfacePriv->last_inactivity_check + currentTime);

    spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);

    /* Check if it is time to run the inactivity handler */
    if (elapsedTime > INACTIVITY_CHECK_INTERVAL) {
        uf_check_inactivity(priv, interfaceTag, currentTime);
    }
}
void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag)
{

   netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
   u8 i;
   int j;
   tx_buffered_packets_t * buffered_pkt = NULL;
   u8 hipslotFree[4] = {TRUE, TRUE, TRUE, TRUE};
   int r;
   unsigned long lock_flags;

   while(!isRouterBufferEnabled(priv, 3) &&
                            ((buffered_pkt=dequeue_tx_data_pdu(priv, &interfacePriv->genericMgtFrames))!=NULL)) {
        buffered_pkt->transmissionControl &=
                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
        if((r=frame_and_send_queued_pdu(priv, buffered_pkt, NULL, 0, FALSE)) == -ENOSPC) {
            /* Enqueue at the head of the queue */
            spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
            list_add(&buffered_pkt->q, &interfacePriv->genericMgtFrames);
            spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
            hipslotFree[3]=FALSE;
            break;
        }else {
            if(r){
                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                /* the PDU failed where we can't do any thing so free the storage */
                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
            }
            kfree(buffered_pkt);
        }
   }
   for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        CsrWifiRouterCtrlStaInfo_t *staInfo = interfacePriv->staInfo[i];
        if(!hipslotFree[0] && !hipslotFree[1] && !hipslotFree[2] && !hipslotFree[3]) {
            unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full \n");
            break;
        }
        if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) {
          while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) {
              buffered_pkt->transmissionControl &=
                           ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
              if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staInfo, 0, FALSE)) == -ENOSPC) {
                  unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n");
                  /* Enqueue at the head of the queue */
                  spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                  list_add(&buffered_pkt->q, &staInfo->mgtFrames);
                  spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                  priv->pausedStaHandle[3]=(u8)(staInfo->assignedHandle);
                  hipslotFree[3] = FALSE;
                  break;
              } else {
                  if(r){
                      unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                      /* the PDU failed where we can't do any thing so free the storage */
                      unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                  }
                  kfree(buffered_pkt);
              }
          }

          for(j=3;j>=0;j--) {
              if(!hipslotFree[j])
                  continue;

              while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) {
                 buffered_pkt->transmissionControl &=
                            ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
                 if((r=frame_and_send_queued_pdu(priv, buffered_pkt, staInfo, 0, FALSE)) == -ENOSPC) {
                     /* Enqueue at the head of the queue */
                     spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
                     list_add(&buffered_pkt->q, &staInfo->dataPdu[j]);
                     spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
                     priv->pausedStaHandle[j]=(u8)(staInfo->assignedHandle);
                     hipslotFree[j]=FALSE;
                     break;
                 } else {
                    if(r){
                        unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
                        /* the PDU failed where we can't do any thing so free the storage */
                        unifi_net_data_free(priv, &buffered_pkt->bulkdata);
                     }
                    kfree(buffered_pkt);
                 }
              }
          }
       }
    }
}
void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv, u16 interfaceTag)
{

    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    unsigned long lock_flags;
    struct list_head *listHead;
    struct list_head *placeHolder;
    tx_buffered_packets_t *tx_q_item;

    if (interfacePriv->noOfbroadcastPktQueued) {

        /* Update the EOSP to the HEAD of b/c list
         * because we have received any mgmt packet so it should not hold for long time
         * peer may time out.
         */
        spin_lock_irqsave(&priv->tx_q_lock, lock_flags);
        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
            tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
            tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
            unifi_trace(priv, UDBG1, "updating eosp for list Head hostTag:= 0x%x ", tx_q_item->hostTag);
            break;
        }
        spin_unlock_irqrestore(&priv->tx_q_lock, lock_flags);
    }
}

/*
 * ---------------------------------------------------------------------------
 *  resume_suspended_uapsd
 *
 *      This function takes care processing packets of Unscheduled Service Period,
 *      which been suspended earlier due to DTIM/HIP ENOSPC scenarios
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      interfaceTag    For which resume should happen
 * ---------------------------------------------------------------------------
 */
void resume_suspended_uapsd(unifi_priv_t* priv, u16 interfaceTag)
{

   u8 startIndex;
   CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
    unsigned long lock_flags;

    unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n");
    for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, startIndex, interfaceTag);

        if(!staInfo || !staInfo->wmmOrQosEnabled) {
            continue;
        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
                   &&staInfo->uapsdActive && staInfo->uspSuspend) {
            /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR
             * due to DTIM activity
             */
            uf_handle_uspframes_delivery(priv, staInfo, interfaceTag);
        } else {
            unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n",
                        staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend);
            if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
            {
                spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
                staInfo->uapsdActive = FALSE;
                staInfo->uspSuspend = FALSE;
                spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
            }
        }
    }
    unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n");
}

#endif
