/*
 * ---------------------------------------------------------------------------
 * 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 = (tx_buffered_packets_t *)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 begining 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 staion 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 successfull, 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 successfull, 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 staion 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 catagory 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 = (tx_buffered_packets_t *) 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 untill 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
         * beacuse 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
