/*
 * ---------------------------------------------------------------------------
 * FILE:     sme_sys.c
 *
 * PURPOSE:
 *      Driver specific implementation of the SME SYS SAP.
 *      It is part of the porting exercise.
 *
 * Copyright (C) 2008-2011 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */

#include "csr_wifi_hip_unifiversion.h"
#include "unifi_priv.h"
#include "csr_wifi_hip_conversions.h"
#ifdef CSR_SUPPORT_WEXT_AP
#include "csr_wifi_sme_sef.h"
#endif

/*
 * This file implements the SME SYS API and contains the following functions:
 * CsrWifiRouterCtrlMediaStatusReqHandler()
 * CsrWifiRouterCtrlHipReqHandler()
 * CsrWifiRouterCtrlPortConfigureReqHandler()
 * CsrWifiRouterCtrlWifiOnReqHandler()
 * CsrWifiRouterCtrlWifiOffReqHandler()
 * CsrWifiRouterCtrlSuspendResHandler()
 * CsrWifiRouterCtrlResumeResHandler()
 * CsrWifiRouterCtrlQosControlReqHandler()
 * CsrWifiRouterCtrlConfigurePowerModeReqHandler()
 * CsrWifiRouterCtrlWifiOnResHandler()
 * CsrWifiRouterCtrlWifiOffRspHandler()
 * CsrWifiRouterCtrlMulticastAddressResHandler()
 * CsrWifiRouterCtrlTrafficConfigReqHandler()
 * CsrWifiRouterCtrlTrafficClassificationReqHandler()
 * CsrWifiRouterCtrlTclasAddReqHandler()
 * CsrWifiRouterCtrlTclasDelReqHandler()
 * CsrWifiRouterCtrlSetModeReqHandler()
 * CsrWifiRouterCtrlWapiMulticastFilterReqHandler()
 * CsrWifiRouterCtrlWapiUnicastFilterReqHandler()
 * CsrWifiRouterCtrlWapiUnicastTxPktReqHandler()
 * CsrWifiRouterCtrlWapiRxPktReqHandler()
 * CsrWifiRouterCtrlWapiFilterReqHandler()
 */

#ifdef CSR_SUPPORT_SME
static void check_inactivity_timer_expire_func(unsigned long data);
void uf_send_disconnected_ind_wq(struct work_struct *work);
#endif

void send_auto_ma_packet_confirm(unifi_priv_t *priv,
                                 netInterface_priv_t *interfacePriv,
                                 struct list_head *buffered_frames_list)
{
    tx_buffered_packets_t *buffered_frame_item = NULL;
    struct list_head *listHead;
    struct list_head *placeHolder;
    int client_id;

    CSR_SIGNAL unpacked_signal;
    u8 sigbuf[UNIFI_PACKED_SIGBUF_SIZE];
    u16 packed_siglen;


    list_for_each_safe(listHead, placeHolder, buffered_frames_list)
    {
        buffered_frame_item = list_entry(listHead, tx_buffered_packets_t, q);

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

        if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_NONE) &&
            (priv->wifi_on_state == wifi_on_done))
        {

            unifi_warning(priv, "Send MA_PACKET_CONFIRM to SenderProcessId = %x for (HostTag = %x TransmissionControl = %x)\n",
                                 (buffered_frame_item->leSenderProcessId),
                                 buffered_frame_item->hostTag,
                                 buffered_frame_item->transmissionControl);

            client_id = buffered_frame_item->leSenderProcessId & 0xFF00;

            if (client_id == priv->sme_cli->sender_id)
            {
                /* construct a MA-PACKET.confirm message for SME */
                memset(&unpacked_signal, 0, sizeof(unpacked_signal));
                unpacked_signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_CONFIRM_ID;
                unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId = buffered_frame_item->leSenderProcessId;
                unpacked_signal.SignalPrimitiveHeader.SenderProcessId = CSR_WIFI_ROUTER_IFACEQUEUE;

                unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,
                                                                                                     interfacePriv->InterfaceTag);
                unpacked_signal.u.MaPacketConfirm.TransmissionStatus = CSR_RESULT_FAILURE;
                unpacked_signal.u.MaPacketConfirm.RetryCount = 0;
                unpacked_signal.u.MaPacketConfirm.Rate = buffered_frame_item->rate;
                unpacked_signal.u.MaPacketConfirm.HostTag = buffered_frame_item->hostTag;

                write_pack(&unpacked_signal, sigbuf, &packed_siglen);
                unifi_warning(priv, "MA_PACKET_CONFIRM for SME (0x%x, 0x%x, 0x%x, 0x%x)\n",
                                         unpacked_signal.SignalPrimitiveHeader.ReceiverProcessId,
                                         unpacked_signal.SignalPrimitiveHeader.SenderProcessId,
                                         unpacked_signal.u.MaPacketConfirm.VirtualInterfaceIdentifier,
                                         unpacked_signal.u.MaPacketConfirm.HostTag);

                CsrWifiRouterCtrlHipIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
                                            packed_siglen,
                                            (u8 *)sigbuf,
                                            0, NULL,
                                            0, NULL);
            }
            else if((buffered_frame_item->hostTag & 0x80000000))
            {
                /* construct a MA-PACKET.confirm message for NME */
                unifi_warning(priv, "MA_PACKET_CONFIRM for NME (0x%x, 0x%x, 0x%x, 0x%x)\n",
                                    buffered_frame_item->leSenderProcessId,
                                    buffered_frame_item->interfaceTag,
                                    buffered_frame_item->transmissionControl,
                                    (buffered_frame_item->hostTag & 0x3FFFFFFF));

                CsrWifiRouterMaPacketCfmSend((buffered_frame_item->leSenderProcessId & 0xFF),
                                            buffered_frame_item->interfaceTag,
                                            CSR_RESULT_FAILURE,
                                            (buffered_frame_item->hostTag & 0x3FFFFFFF),
                                            buffered_frame_item->rate);

            }
            else
            {
                unifi_warning(priv, "Buffered packet dropped without sending a confirm\n");
            }

        }

        list_del(listHead);
        kfree(buffered_frame_item);
        buffered_frame_item = NULL;
    }
}

void CsrWifiRouterCtrlMediaStatusReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlMediaStatusReq* req = (CsrWifiRouterCtrlMediaStatusReq*)msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
    unsigned long flags;

    if (priv->smepriv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid smepriv\n");
        return;
    }
    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterCtrlMediaStatusReqHandler: invalid interfaceTag\n");
        return;
    }
    unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlMediaStatusReqHandler: Mode = %d req->mediaStatus = %d\n",interfacePriv->interfaceMode,req->mediaStatus);
    if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AMP) {
        bulk_data_desc_t bulk_data;

        bulk_data.data_length = 0;

        spin_lock_irqsave(&priv->m4_lock, flags);
        if (interfacePriv->m4_bulk_data.data_length > 0) {
            bulk_data = interfacePriv->m4_bulk_data;
            interfacePriv->m4_bulk_data.net_buf_length = 0;
            interfacePriv->m4_bulk_data.data_length = 0;
            interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
        }
        spin_unlock_irqrestore(&priv->m4_lock, flags);

        if (bulk_data.data_length != 0) {
            unifi_trace(priv, UDBG5, "CsrWifiRouterCtrlMediaStatusReqHandler: free M4\n");
            unifi_net_data_free(priv, &bulk_data);
        }

        if ((req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) &&
            (interfacePriv->connected != UnifiConnected)) {

            switch(interfacePriv->interfaceMode){
                case CSR_WIFI_ROUTER_CTRL_MODE_AP:
                case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
                    interfacePriv->connected = UnifiConnected;
                    netif_carrier_on(priv->netdev[req->interfaceTag]);
#ifdef CSR_SUPPORT_WEXT
                    wext_send_started_event(priv);
#endif
                    unifi_trace(priv, UDBG1,
                                "CsrWifiRouterCtrlMediaStatusReqHandler: AP/P2PGO setting netif_carrier_on\n");
                    netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
                    break;

                default:
#ifdef CSR_SUPPORT_WEXT
                /* In the WEXT builds (sme and native), the userspace is not ready
                 * to process any EAPOL or WAPI packets, until it has been informed
                 * of the NETDEV_CHANGE.
                 */
                if (interfacePriv->netdev_callback_registered && (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI)) {
                    interfacePriv->wait_netdev_change = TRUE;
                    unifi_trace(priv, UDBG1,
                                "CsrWifiRouterCtrlMediaStatusReqHandler: waiting for NETDEV_CHANGE\n");
                    /*
                     * Carrier can go to on, only after wait_netdev_change is set to TRUE.
                     * Otherwise there can be a race in uf_netdev_event().
                     */
                    netif_carrier_on(priv->netdev[req->interfaceTag]);
                    unifi_trace(priv, UDBG1,
                                "CsrWifiRouterCtrlMediaStatusReqHandler: STA/P2PCLI setting netif_carrier_on\n");
                }
                else
#endif
                {
                    /* In the NME build, the userspace does not wait for the NETDEV_CHANGE
                     * so it is ready to process all the EAPOL or WAPI packets.
                     * At this point, we enable all the Tx queues, and we indicate any packets
                     * that are queued (and the respective port is opened).
                     */
                    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
                    interfacePriv->connected = UnifiConnected;
                    unifi_trace(priv, UDBG1,
                                "CsrWifiRouterMediaStatusReqHandler: UnifiConnected && netif_carrier_on\n");
                    netif_carrier_on(priv->netdev[req->interfaceTag]);
                    netif_tx_wake_all_queues(priv->netdev[req->interfaceTag]);
                    uf_process_rx_pending_queue(priv, UF_UNCONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
                    uf_process_rx_pending_queue(priv, UF_CONTROLLED_PORT_Q, broadcast_address, 1, interfacePriv->InterfaceTag);
                }
                break;
            }
        }

        if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_DISCONNECTED) {
#ifdef CSR_SUPPORT_WEXT
            unifi_trace(priv, UDBG1,
                        "CsrWifiRouterMediaStatusReqHandler: cancel waiting for NETDEV_CHANGE\n");
            interfacePriv->wait_netdev_change = FALSE;
#endif
            unifi_trace(priv, UDBG1,
                        "CsrWifiRouterMediaStatusReqHandler: setting netif_carrier_off\n");
            netif_carrier_off(priv->netdev[req->interfaceTag]);
#ifdef CSR_SUPPORT_WEXT
            switch(interfacePriv->interfaceMode){
                case CSR_WIFI_ROUTER_CTRL_MODE_AP:
                case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
                     wext_send_started_event(priv);
                     break;
                default:
                     break;
            }
#endif
            interfacePriv->connected = UnifiNotConnected;
        }
    } else {
        /* For AMP, just update the L2 connected flag */
        if (req->mediaStatus == CSR_WIFI_SME_MEDIA_STATUS_CONNECTED) {
            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP connected\n");
            interfacePriv->connected = UnifiConnected;
        } else {
            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlMediaStatusReqHandler: AMP disconnected\n");
            interfacePriv->connected = UnifiNotConnected;
        }
    }
}


void CsrWifiRouterCtrlHipReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlHipReq* hipreq = (CsrWifiRouterCtrlHipReq*)msg;
    bulk_data_param_t bulkdata;
    u8 *signal_ptr;
    int signal_length;
    int r=0;
    void *dest;
    CsrResult csrResult;
    CSR_SIGNAL *signal;
    u16 interfaceTag = 0;
    CSR_MA_PACKET_REQUEST *req;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    if (priv == NULL) {
        return;
    }
    if (priv->smepriv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid smepriv\n");
        return;
    }
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid interfaceTag\n");
        return;
    }

    /* Initialize bulkdata to avoid os_net_buf is garbage */
    memset(&bulkdata, 0, sizeof(bulk_data_param_t));

    signal = (CSR_SIGNAL *)hipreq->mlmeCommand;

    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: 0x04%X ---->\n",
                *((u16*)hipreq->mlmeCommand));

    /* Construct the signal. */
    signal_ptr = (u8*)hipreq->mlmeCommand;
    signal_length = hipreq->mlmeCommandLength;

    /*
     * The MSB of the sender ID needs to be set to the client ID.
     * The LSB is controlled by the SME.
     */
    signal_ptr[5] = (priv->sme_cli->sender_id >> 8) & 0xff;

    /* Allocate buffers for the bulk data. */
    if (hipreq->dataRef1Length) {
        csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], hipreq->dataRef1Length);
        if (csrResult == CSR_RESULT_SUCCESS) {
            dest = (void*)bulkdata.d[0].os_data_ptr;
            memcpy(dest, hipreq->dataRef1, hipreq->dataRef1Length);
            bulkdata.d[0].data_length = hipreq->dataRef1Length;
        } else {
            unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
            return;
        }
    } else {
        bulkdata.d[0].os_data_ptr = NULL;
        bulkdata.d[0].data_length = 0;
    }
    if (hipreq->dataRef2Length) {
        csrResult = unifi_net_data_malloc(priv, &bulkdata.d[1], hipreq->dataRef2Length);
        if (csrResult == CSR_RESULT_SUCCESS) {
            dest = (void*)bulkdata.d[1].os_data_ptr;
            memcpy(dest, hipreq->dataRef2, hipreq->dataRef2Length);
            bulkdata.d[1].data_length = hipreq->dataRef2Length;
        } else {
            if (bulkdata.d[0].data_length)
            {
                unifi_net_data_free(priv, &bulkdata.d[0]);
            }
            unifi_warning(priv, "signal not sent down, allocation failed in CsrWifiRouterCtrlHipReqHandler\n");
            return;
        }
    } else {
        bulkdata.d[1].os_data_ptr = NULL;
        bulkdata.d[1].data_length = 0;
    }

    unifi_trace(priv, UDBG3, "SME SEND: Signal 0x%.4X \n",
                *((u16*)signal_ptr));
    if (signal->SignalPrimitiveHeader.SignalId == CSR_MA_PACKET_REQUEST_ID)
    {
        CSR_SIGNAL unpacked_signal;
        read_unpack_signal((u8 *) signal, &unpacked_signal);
        req = &unpacked_signal.u.MaPacketRequest;
        interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
        switch(interfacePriv->interfaceMode)
        {
            case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
                unifi_error(priv, "CsrWifiRouterCtrlHipReqHandler: invalid mode: NONE \n");
                break;
            default:
                unifi_trace(priv, UDBG5, "mode is %x\n", interfacePriv->interfaceMode);
        }
        /* While sending ensure that first 2 bits b31 and b30 are 00. These are used for local routing*/
        r = uf_process_ma_packet_req(priv, req->Ra.x, (req->HostTag & 0x3FFFFFFF), interfaceTag,
                                     req->TransmissionControl, req->TransmitRate,
                                     req->Priority, signal->SignalPrimitiveHeader.SenderProcessId,
                                     &bulkdata);
        if (r)
        {
            if (bulkdata.d[0].data_length)
            {
                unifi_net_data_free(priv, &bulkdata.d[0]);
            }
            if (bulkdata.d[1].data_length)
            {
                unifi_net_data_free(priv, &bulkdata.d[1]);
            }
        }
    } else {
        /* ul_send_signal_raw frees the bulk data if it fails */
        r = ul_send_signal_raw(priv, signal_ptr, signal_length, &bulkdata);
    }

    if (r) {
        unifi_error(priv,
                    "CsrWifiRouterCtrlHipReqHandler: Failed to send signal (0x%.4X - %u)\n",
                    *((u16*)signal_ptr), r);
        CsrWifiRouterCtrlWifiOffIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,CSR_WIFI_SME_CONTROL_INDICATION_ERROR);
    }

    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlHipReqHandler: <----\n");
}

#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
static void
uf_send_gratuitous_arp(unifi_priv_t *priv, u16 interfaceTag)
{
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    CSR_PRIORITY priority;
    CSR_SIGNAL signal;
    bulk_data_param_t bulkdata;
    CsrResult csrResult;
    struct sk_buff *skb, *newSkb = NULL;
    s8 protection;
    int r;
    static const u8 arp_req[36] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00,
                                         0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
                                         0x00, 0x02, 0x5f, 0x20, 0x2f, 0x02,
                                         0xc0, 0xa8, 0x00, 0x02,
                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                         0xc0, 0xa8, 0x00, 0x02};

    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], sizeof(arp_req));
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(priv, "Failed to allocate bulk data in CsrWifiSmeRoamCompleteIndHandler()\n");
        return;
    }
    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
    skb->len = bulkdata.d[0].data_length;

    memcpy(skb->data, arp_req, sizeof(arp_req));
    /* add MAC and IP address */
    memcpy(skb->data + 16, priv->netdev[interfaceTag]->dev_addr, ETH_ALEN);
    skb->data[22] = (priv->sta_ip_address      ) & 0xFF;
    skb->data[23] = (priv->sta_ip_address >>  8) & 0xFF;
    skb->data[24] = (priv->sta_ip_address >> 16) & 0xFF;
    skb->data[25] = (priv->sta_ip_address >> 24) & 0xFF;
    skb->data[32] = (priv->sta_ip_address      ) & 0xFF;
    skb->data[33] = (priv->sta_ip_address >>  8) & 0xFF;
    skb->data[34] = (priv->sta_ip_address >> 16) & 0xFF;
    skb->data[35] = (priv->sta_ip_address >> 24) & 0xFF;

    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;

    if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, &arp_req[26])) < 0)
    {
        unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: Failed to determine protection mode\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return;
    }

    if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1)
    {
        priority = CSR_QOS_UP0;
    }
    else
    {
        priority = CSR_CONTENTION;
    }

    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata,
                                  interfaceTag, &arp_req[26],
                                  priv->netdev[interfaceTag]->dev_addr, protection))
    {
        unifi_error(priv, "CsrWifiSmeRoamCompleteIndHandler: failed to create MAC header\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return;
    }
    bulkdata.d[0].os_data_ptr = skb->data;
    bulkdata.d[0].os_net_buf_ptr = skb;
    bulkdata.d[0].data_length = skb->len;

    unifi_frame_ma_packet_req(priv, priority, 0, 0xffffffff, interfaceTag,
                              CSR_NO_CONFIRM_REQUIRED, priv->netdev_client->sender_id,
                              interfacePriv->bssid.a, &signal);

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

}
#endif /* CSR_WIFI_SEND_GRATUITOUS_ARP */

/*
 * ---------------------------------------------------------------------------
 * configure_data_port
 *
 *      Store the new controlled port configuration.
 *
 * Arguments:
 *      priv            Pointer to device private context struct
 *      port_cfg        Pointer to the port configuration
 *
 * Returns:
 *      An unifi_ControlledPortAction value.
 * ---------------------------------------------------------------------------
 */
static int
configure_data_port(unifi_priv_t *priv,
        CsrWifiRouterCtrlPortAction port_action,
        const CsrWifiMacAddress *macAddress,
        const int queue,
        u16 interfaceTag)
{
    const u8 broadcast_mac_address[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    unifi_port_config_t *port;
    netInterface_priv_t *interfacePriv;
    int i;
    const char* controlled_string; /* cosmetic "controlled"/"uncontrolled" for trace */

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "configure_data_port: bad interfaceTag\n");
        return -EFAULT;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    if (queue == UF_CONTROLLED_PORT_Q) {
        port = &interfacePriv->controlled_data_port;
        controlled_string = "controlled";
    } else {
        port = &interfacePriv->uncontrolled_data_port;
        controlled_string = "uncontrolled";
    }

	unifi_trace(priv, UDBG2,
		"port config request %pM %s with port_action %d.\n",
		macAddress->a, controlled_string, port_action);

    /* If the new configuration has the broadcast MAC address or if we are in infrastructure mode then clear the list first and set port overide mode */
    if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode ||
        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) ||
        !memcmp(macAddress->a, broadcast_mac_address, ETH_ALEN)) {

        port->port_cfg[0].port_action = port_action;
        port->port_cfg[0].mac_address = *macAddress;
        port->port_cfg[0].in_use = TRUE;
        port->entries_in_use = 1;
        port->overide_action = UF_DATA_PORT_OVERIDE;

        unifi_trace(priv, UDBG2, "%s port override on\n",
                    (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");

        /* Discard the remaining entries in the port config table */
        for (i = 1; i < UNIFI_MAX_CONNECTIONS; i++) {
            port->port_cfg[i].in_use = FALSE;
        }

        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
            unifi_trace(priv, UDBG1, "%s port broadcast set to open.\n",
                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");

            /*
             * Ask stack to schedule for transmission any packets queued
             * while controlled port was not open.
             * Use netif_schedule() instead of netif_wake_queue() because
             * transmission should be already enabled at this point. If it
             * is not, probably the interface is down and should remain as is.
             */
            uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);

#ifdef CSR_WIFI_SEND_GRATUITOUS_ARP
            if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
                (queue == UF_CONTROLLED_PORT_Q) && (priv->sta_ip_address != 0xFFFFFFFF))
            {
                uf_send_gratuitous_arp(priv, interfaceTag);
            }
#endif
        } else {
            unifi_trace(priv, UDBG1, "%s port broadcast set to %s.\n",
                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled",
                        (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) ? "discard": "closed");

            /* If port is closed, discard all the pending Rx packets */
            if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
                uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
            }
        }
    } else {
        /* store the new configuration, either in the entry with matching mac address (if already present),
         * otherwise in a new entry
         */

        int found_entry_flag;
        int first_free_slot = -1;

        /* If leaving override mode, free the port entry used for override */
        if (port->overide_action == UF_DATA_PORT_OVERIDE) {
            port->port_cfg[0].in_use = FALSE;
            port->entries_in_use = 0;
            port->overide_action = UF_DATA_PORT_NOT_OVERIDE;

            unifi_trace(priv, UDBG2, "%s port override off\n",
                        (queue == UF_CONTROLLED_PORT_Q) ? "Controlled" : "Uncontrolled");
        }

        found_entry_flag = 0;
        for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
            if (port->port_cfg[i].in_use) {
                if (!memcmp(&port->port_cfg[i].mac_address.a, macAddress->a, ETH_ALEN)) {
                    /* We've seen this address before, reconfigure it */
                    port->port_cfg[i].port_action = port_action;
                    found_entry_flag = 1;
                    break;
                }
            } else if (first_free_slot == -1) {
                /* Remember the first free slot on the way past so it can be claimed
                 * if this turns out to be a new MAC address (to save walking the list again).
                 */
                first_free_slot = i;
            }
        }

        /* At this point we found an existing entry and have updated it, or need to
         * add a new entry. If all slots are allocated, give up and return an error.
         */
        if (!found_entry_flag) {
            if (first_free_slot == -1) {
                unifi_error(priv, "no free slot found in port config array (%d used)\n", port->entries_in_use);
                return -EFAULT;
            } else {
                port->entries_in_use++;
            }

            unifi_trace(priv, UDBG3, "port config index assigned in config_data_port = %d\n", first_free_slot);
            port->port_cfg[first_free_slot].in_use = TRUE;
            port->port_cfg[first_free_slot].port_action = port_action;
            port->port_cfg[first_free_slot].mac_address = *macAddress;
        }

        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
            /*
             * Ask stack to schedule for transmission any packets queued
             * while controlled port was not open.
             * Use netif_schedule() instead of netif_wake_queue() because
             * transmission should be already enabled at this point. If it
             * is not, probably the interface is down and should remain as is.
             */
            uf_resume_data_plane(priv, queue, *macAddress, interfaceTag);
        }

        /*
         * If port is closed, discard all the pending Rx packets
         * coming from the peer station.
         */
        if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
            uf_free_pending_rx_packets(priv, queue, *macAddress,interfaceTag);
        }

	unifi_trace(priv, UDBG2,
		"port config %pM with port_action %d.\n",
		macAddress->a, port_action);
    }
    return 0;
} /* configure_data_port() */


void CsrWifiRouterCtrlPortConfigureReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlPortConfigureReq* req = (CsrWifiRouterCtrlPortConfigureReq*)msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    unifi_trace(priv, UDBG3, "entering CsrWifiRouterCtrlPortConfigureReqHandler\n");
    if (priv->smepriv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlPortConfigureReqHandler: invalid smepriv\n");
        return;
    }

    /* To update the protection status of the peer/station */
    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
	    case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
            /* Since for Unifi as a station, the station record not maintained & interfaceID is
             * only needed to update the peer protection status
             */
            interfacePriv->protect = req->setProtection;
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            {
                u8 i;
                CsrWifiRouterCtrlStaInfo_t *staRecord;
                /* Ifscontrolled port is open means, The peer has been added to station record
                 * so that the protection corresponding to the peer is valid in this req
                 */
                if (req->controlledPortAction == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
                    for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
                        staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
                        if (staRecord) {
                                /* Find the matching station record & set the protection type */
                                if (!memcmp(req->macAddress.a, staRecord->peerMacAddress.a, ETH_ALEN)) {
                                        staRecord->protection = req->setProtection;
                                        break;
                                }
                        }
                    }
                }
            }
            break;
        default:
            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlPortConfigureReqHandler(0x%.4X) Uncaught mode %d\n",
                        msg->source, interfacePriv->interfaceMode);
    }

    configure_data_port(priv, req->uncontrolledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
                        UF_UNCONTROLLED_PORT_Q, req->interfaceTag);
    configure_data_port(priv, req->controlledPortAction, (const CsrWifiMacAddress *)&req->macAddress,
                        UF_CONTROLLED_PORT_Q, req->interfaceTag);

    CsrWifiRouterCtrlPortConfigureCfmSend(msg->source,req->clientData,req->interfaceTag,
                                      CSR_RESULT_SUCCESS, req->macAddress);
    unifi_trace(priv, UDBG3, "leaving CsrWifiRouterCtrlPortConfigureReqHandler\n");
}


void CsrWifiRouterCtrlWifiOnReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlVersions versions;
    CsrWifiRouterCtrlWifiOnReq* req = (CsrWifiRouterCtrlWifiOnReq*)msg;
    int r,i;
    CsrResult csrResult;

    if (priv == NULL) {
        return;
    }
    if( priv->wol_suspend ) {
        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Don't reset mode\n");
    } else {
#ifdef ANDROID_BUILD
        /* Take the wakelock while Wi-Fi On is in progress */
        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: take wake lock\n");
        wake_lock(&unifi_sdio_wake_lock);
#endif
        for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
            unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: Setting interface %d to NONE\n", i );

            priv->interfacePriv[i]->interfaceMode = 0;
        }
    }
    unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler(0x%.4X) req->dataLength=%d req->data=0x%x\n", msg->source, req->dataLength, req->data);

    if(req->dataLength==3 && req->data && req->data[0]==0 && req->data[1]==1 && req->data[2]==1)
    {
        priv->cmanrTestMode = TRUE;
        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOnReqHandler: cmanrTestMode=%d\n", priv->cmanrTestMode);
    }
    else
    {
        priv->cmanrTestMode = FALSE;
    }

    /*
     * The request to initialise UniFi might come while UniFi is running.
     * We need to block all I/O activity until the reset completes, otherwise
     * an SDIO error might occur resulting an indication to the SME which
     * makes it think that the initialisation has failed.
     */
    priv->bh_thread.block_thread = 1;

    /* Update the wifi_on state */
    priv->wifi_on_state = wifi_on_in_progress;

    /* If UniFi was unpowered, acquire the firmware for download to chip */
    if (!priv->wol_suspend) {
        r = uf_request_firmware_files(priv, UNIFI_FW_STA);
        if (r) {
            unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to get f/w\n");
            CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
            return;
        }
    } else {
        unifi_trace(priv, UDBG1, "Don't need firmware\n");
    }

    /* Power on UniFi (which may not necessarily have been off) */
    CsrSdioClaim(priv->sdio);
    csrResult = CsrSdioPowerOn(priv->sdio);
    CsrSdioRelease(priv->sdio);
    if (csrResult != CSR_RESULT_SUCCESS && csrResult != CSR_SDIO_RESULT_NOT_RESET) {
        unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to power on UniFi\n");
        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
        return;
    }

    /* If CsrSdioPowerOn() returns CSR_RESULT_SUCCESS, it means that we need to initialise UniFi */
    if (csrResult == CSR_RESULT_SUCCESS && !priv->wol_suspend) {
        /* Initialise UniFi hardware */
        r = uf_init_hw(priv);
        if (r) {
            unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
            CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
            return;
        }
    } else {
        unifi_trace(priv, UDBG1, "UniFi already initialised\n");
    }

    /* Completed handling of wake up from suspend with UniFi powered */
    priv->wol_suspend = FALSE;

    /* Re-enable the I/O thread */
    priv->bh_thread.block_thread = 0;

    /*
     * Start the I/O thread. The thread might be already running.
     * This fine, just carry on with the request.
     */
    r = uf_init_bh(priv);
    if (r) {
        CsrSdioClaim(priv->sdio);
        CsrSdioPowerOff(priv->sdio);
        CsrSdioRelease(priv->sdio);
        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, req->clientData, CSR_RESULT_FAILURE);
        return;
    }

    /* Get the version information from the core */
    unifi_card_info(priv->card, &priv->card_info);

    /* Set the sme queue id */
    priv->CSR_WIFI_SME_IFACEQUEUE = msg->source;
    CSR_WIFI_SME_IFACEQUEUE = msg->source;


    /* Copy to the unifiio_card_info structure. */
    versions.chipId = priv->card_info.chip_id;
    versions.chipVersion = priv->card_info.chip_version;
    versions.firmwareBuild = priv->card_info.fw_build;
    versions.firmwareHip = priv->card_info.fw_hip_version;
    versions.routerBuild = (char*)CSR_WIFI_VERSION;
    versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;

    CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);

    /* Update the wifi_on state */
    priv->wifi_on_state = wifi_on_done;
}


/*
 * wifi_off:
 *      Common code for CsrWifiRouterCtrlWifiOffReqHandler() and
 *      CsrWifiRouterCtrlWifiOffRspHandler().
 */
static void
wifi_off(unifi_priv_t *priv)
{
    int power_off;
    int priv_instance;
    int i;
    CsrResult csrResult;


    /* Already off? */
    if (priv->wifi_on_state == wifi_on_unspecified) {
        unifi_trace(priv, UDBG1, "wifi_off already\n");
        return;
    }

    unifi_trace(priv, UDBG1, "wifi_off\n");

    /* Destroy the Traffic Analysis Module */
    cancel_work_sync(&priv->ta_ind_work.task);
    cancel_work_sync(&priv->ta_sample_ind_work.task);
#ifdef CSR_SUPPORT_WEXT
    cancel_work_sync(&priv->sme_config_task);
    wext_send_disassoc_event(priv);
#endif

    /* Cancel pending M4 stuff */
    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
        if (priv->netdev[i]) {
            netInterface_priv_t *netpriv = (netInterface_priv_t *) netdev_priv(priv->netdev[i]);
            cancel_work_sync(&netpriv->send_m4_ready_task);
        }
    }
    flush_workqueue(priv->unifi_workqueue);

    /* fw_init parameter can prevent power off UniFi, for debugging */
    priv_instance = uf_find_priv(priv);
    if (priv_instance == -1) {
        unifi_warning(priv,
                "CsrWifiRouterCtrlStopReqHandler: Unknown priv instance, will power off card.\n");
        power_off = 1;
    } else {
        power_off = (fw_init[priv_instance] > 0) ? 0 : 1;
    }

    /* Production test mode requires power to the chip, too */
    if (priv->ptest_mode) {
        power_off = 0;
    }

    /* Stop the bh_thread */
    uf_stop_thread(priv, &priv->bh_thread);

    /* Read the f/w panic codes, if any. Protect against second wifi_off() call,
     * which may happen if SME requests a wifi_off and closes the char device */
    if (priv->init_progress != UNIFI_INIT_NONE) {
        CsrSdioClaim(priv->sdio);
        unifi_capture_panic(priv->card);
        CsrSdioRelease(priv->sdio);
    }

    /* Unregister the interrupt handler */
    if (csr_sdio_linux_remove_irq(priv->sdio)) {
        unifi_notice(priv,
                "csr_sdio_linux_remove_irq failed to talk to card.\n");
    }

    if (power_off) {
        unifi_trace(priv, UDBG2,
                    "Force low power and try to power off\n");
        /* Put UniFi to deep sleep, in case we can not power it off */
        CsrSdioClaim(priv->sdio);
        csrResult = unifi_force_low_power_mode(priv->card);
        CsrSdioRelease(priv->sdio);

        CsrSdioPowerOff(priv->sdio);
    }

    /* Consider UniFi to be uninitialised */
    priv->init_progress = UNIFI_INIT_NONE;
    priv->wifi_on_state = wifi_on_unspecified;


} /* wifi_off() */


void CsrWifiRouterCtrlWifiOffReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWifiOffReq* req = (CsrWifiRouterCtrlWifiOffReq*)msg;
    int i = 0;

    if (priv == NULL) {
        return;
    }

    unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWifiOffReqHandler(0x%.4X)\n", msg->source);

    /* Stop the network traffic on all interfaces before freeing the core. */
    for (i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
        if (interfacePriv->netdev_registered == 1) {
            netif_carrier_off(priv->netdev[i]);
            netif_tx_stop_all_queues(priv->netdev[i]);
            interfacePriv->connected = UnifiConnectedUnknown;
        }
        interfacePriv->interfaceMode = 0;

        /* Enable all queues by default */
        interfacePriv->queueEnabled[0] = 1;
        interfacePriv->queueEnabled[1] = 1;
        interfacePriv->queueEnabled[2] = 1;
        interfacePriv->queueEnabled[3] = 1;
    }
    wifi_off(priv);

    CsrWifiRouterCtrlWifiOffCfmSend(msg->source,req->clientData);

    /* If this is called in response to closing the character device, the
     * caller must use uf_sme_cancel_request() to terminate any pending SME
     * blocking request or there will be a delay while the operation times out.
     */
}


void CsrWifiRouterCtrlQosControlReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlQosControlReq* req = (CsrWifiRouterCtrlQosControlReq*)msg;
    netInterface_priv_t *interfacePriv;

    if (priv->smepriv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: invalid smepriv\n");
        return;
    }

    unifi_trace(priv, UDBG4, "CsrWifiRouterCtrlQosControlReqHandler:scontrol = %d", req->control);

    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterCtrlQosControlReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
        return;
    }
    interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (req->control == CSR_WIFI_ROUTER_CTRL_QOS_CONTROL_WMM_ON) {
        priv->sta_wmm_capabilities |= QOS_CAPABILITY_WMM_ENABLED;
        unifi_trace(priv, UDBG1, "WMM enabled\n");

        unifi_trace(priv, UDBG1, "Queue Config %x\n", req->queueConfig);

        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BK] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BK_ENABLE)?1:0;
        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_BE] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_BE_ENABLE)?1:0;
        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VI] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VI_ENABLE)?1:0;
        interfacePriv->queueEnabled[UNIFI_TRAFFIC_Q_VO] = (req->queueConfig & CSR_WIFI_ROUTER_CTRL_QUEUE_VO_ENABLE)?1:0;

    } else {
        priv->sta_wmm_capabilities = 0;
        unifi_trace(priv, UDBG1, "WMM disabled\n");
    }
}


void CsrWifiRouterCtrlTclasAddReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlTclasAddReq* req = (CsrWifiRouterCtrlTclasAddReq*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlTclasAddReqHandler: invalid smepriv\n");
        return;
    }

    CsrWifiRouterCtrlTclasAddCfmSend(msg->source, req->clientData, req->interfaceTag , CSR_RESULT_SUCCESS);
}

void CsrWifiRouterCtrlTclasDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlTclasDelReq* req = (CsrWifiRouterCtrlTclasDelReq*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlTclasDelReqHandler: invalid smepriv\n");
        return;
    }

    CsrWifiRouterCtrlTclasDelCfmSend(msg->source, req->clientData, req->interfaceTag, CSR_RESULT_SUCCESS);
}


void CsrWifiRouterCtrlConfigurePowerModeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlConfigurePowerModeReq* req = (CsrWifiRouterCtrlConfigurePowerModeReq*)msg;
    enum unifi_low_power_mode pm;
    CsrResult csrResult;

    if (priv->smepriv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlConfigurePowerModeReqHandler: invalid smepriv\n");
        return;
    }

    if (req->mode == CSR_WIFI_ROUTER_CTRL_LOW_POWER_MODE_DISABLED) {
        pm = UNIFI_LOW_POWER_DISABLED;
    } else {
        pm = UNIFI_LOW_POWER_ENABLED;
    }

    unifi_trace(priv, UDBG2,
                "CsrWifiRouterCtrlConfigurePowerModeReqHandler (mode=%d, wake=%d)\n",
                req->mode, req->wakeHost);
    csrResult = unifi_configure_low_power_mode(priv->card, pm,
                                               (req->wakeHost ? UNIFI_PERIODIC_WAKE_HOST_ENABLED : UNIFI_PERIODIC_WAKE_HOST_DISABLED));
}


void CsrWifiRouterCtrlWifiOnResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWifiOnRes* res = (CsrWifiRouterCtrlWifiOnRes*)msg;

    if (priv == NULL) {
        unifi_error(NULL, "CsrWifiRouterCtrlWifiOnResHandler: Invalid ospriv.\n");
        return;
    }

    unifi_trace(priv, UDBG1,
                "CsrWifiRouterCtrlWifiOnResHandler: status %d (patch %u)\n", res->status, res->smeVersions.firmwarePatch);

    if (res->smeVersions.firmwarePatch != 0) {
        unifi_info(priv, "Firmware patch %d\n", res->smeVersions.firmwarePatch);
    }

    if (res->numInterfaceAddress > CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "WifiOnResHandler bad numInterfaceAddress %d\n", res->numInterfaceAddress);
        return;
    }

    /* UniFi is now initialised, complete the init. */
    if (res->status == CSR_RESULT_SUCCESS)
    {
        int i; /* used as a loop counter */
        u32 intmode = CSR_WIFI_INTMODE_DEFAULT;
#ifdef CSR_WIFI_SPLIT_PATCH
        u8 switching_ap_fw = FALSE;
#endif
        /* Register the UniFi device with the OS network manager */
        unifi_trace(priv, UDBG3, "Card Init Completed Successfully\n");

        /* Store the MAC address in the netdev */
        for(i=0;i<res->numInterfaceAddress;i++)
        {
            memcpy(priv->netdev[i]->dev_addr, res->stationMacAddress[i].a, ETH_ALEN);
        }

        /* Copy version structure into the private versions field */
        priv->sme_versions = res->smeVersions;

        unifi_trace(priv, UDBG2, "network interfaces count = %d\n",
                    res->numInterfaceAddress);

        /* Register the netdevs for each interface. */
        for(i=0;i<res->numInterfaceAddress;i++)
        {
            netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
            if(!interfacePriv->netdev_registered)
            {
                int r;
                unifi_trace(priv, UDBG3, "registering net device %d\n", i);
                r = uf_register_netdev(priv, i);
                if (r)
                {
                    /* unregister the net_device that are registered in the previous iterations */
                    uf_unregister_netdev(priv);
                    unifi_error(priv, "Failed to register the network device.\n");
                    CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
                    return;
                }
            }
#ifdef CSR_WIFI_SPLIT_PATCH
            else
            {
                /* If a netdev is already registered, we have received this WifiOnRes
                 * in response to switching AP/STA firmware in a ModeSetReq.
                 * Rememeber this in order to send a ModeSetCfm once
                 */
                switching_ap_fw = TRUE;
            }
#endif
        }
        priv->totalInterfaceCount = res->numInterfaceAddress;

        /* If the MIB has selected f/w scheduled interrupt mode, apply it now
         * but let module param override.
         */
        if (run_bh_once != -1) {
            intmode = (u32)run_bh_once;
        } else if (res->scheduledInterrupt) {
            intmode = CSR_WIFI_INTMODE_RUN_BH_ONCE;
        }
        unifi_set_interrupt_mode(priv->card, intmode);

        priv->init_progress = UNIFI_INIT_COMPLETED;

        /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_SUCCESS);

#ifdef CSR_WIFI_SPLIT_PATCH
        if (switching_ap_fw && (priv->pending_mode_set.common.destination != 0xaaaa)) {
            unifi_info(priv, "Completed firmware reload with %s patch\n",
                CSR_WIFI_HIP_IS_AP_FW(priv->interfacePriv[0]->interfaceMode) ? "AP" : "STA");

            /* Confirm the ModeSetReq that requested the AP/STA patch switch */
            CsrWifiRouterCtrlModeSetCfmSend(priv->pending_mode_set.common.source,
                                            priv->pending_mode_set.clientData,
                                            priv->pending_mode_set.interfaceTag,
                                            priv->pending_mode_set.mode,
                                            CSR_RESULT_SUCCESS);
            priv->pending_mode_set.common.destination = 0xaaaa;
        }
#endif
        unifi_info(priv, "UniFi ready\n");

#ifdef ANDROID_BUILD
        /* Release the wakelock */
        unifi_trace(priv, UDBG1, "ready: release wake lock\n");
        wake_unlock(&unifi_sdio_wake_lock);
#endif
        /* Firmware initialisation is complete, so let the SDIO bus
         * clock be raised when convienent to the core.
         */
        unifi_request_max_sdio_clock(priv->card);

#ifdef CSR_SUPPORT_WEXT
        /* Notify the Android wpa_supplicant that we are ready */
        wext_send_started_event(priv);

        queue_work(priv->unifi_workqueue, &priv->sme_config_task);
#endif

    } else {
        /* Acknowledge the CsrWifiRouterCtrlWifiOnReq now */
        CsrWifiRouterCtrlWifiOnCfmSend(msg->source, res->clientData, CSR_RESULT_FAILURE);
    }
}


void CsrWifiRouterCtrlWifiOffResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
}


void CsrWifiRouterCtrlMulticastAddressResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
}


void CsrWifiRouterMaPacketSubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterMaPacketSubscribeReq* req = (CsrWifiRouterMaPacketSubscribeReq*)msg;
    u8 i;
    CsrResult result;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterMaPacketSubscribeReqHandler: invalid priv\n");
        return;
    }

    /* Look for an unused filter */

    result = CSR_WIFI_RESULT_NO_ROOM;
    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {

        if (!priv->sme_unidata_ind_filters[i].in_use) {

            priv->sme_unidata_ind_filters[i].in_use = 1;
            priv->sme_unidata_ind_filters[i].appHandle = msg->source;
            priv->sme_unidata_ind_filters[i].encapsulation = req->encapsulation;
            priv->sme_unidata_ind_filters[i].protocol = req->protocol;

            priv->sme_unidata_ind_filters[i].oui[2] = (u8)  (req->oui        & 0xFF);
            priv->sme_unidata_ind_filters[i].oui[1] = (u8) ((req->oui >>  8) & 0xFF);
            priv->sme_unidata_ind_filters[i].oui[0] = (u8) ((req->oui >> 16) & 0xFF);

            result = CSR_RESULT_SUCCESS;
            break;
        }
    }

    unifi_trace(priv, UDBG1,
                "subscribe_req: encap=%d, handle=%d, result=%d\n",
                req->encapsulation, i, result);
    CsrWifiRouterMaPacketSubscribeCfmSend(msg->source,req->interfaceTag, i, result, 0);
}


void CsrWifiRouterMaPacketUnsubscribeReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterMaPacketUnsubscribeReq* req = (CsrWifiRouterMaPacketUnsubscribeReq*)msg;
    CsrResult result;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterMaPacketUnsubscribeReqHandler: invalid priv\n");
        return;
    }

    result = CSR_WIFI_RESULT_NOT_FOUND;

    if (req->subscriptionHandle < MAX_MA_UNIDATA_IND_FILTERS) {
        if (priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use) {
            priv->sme_unidata_ind_filters[req->subscriptionHandle].in_use = 0;
            result = CSR_RESULT_SUCCESS;
        } else {
            result = CSR_WIFI_RESULT_NOT_FOUND;
        }
    }

    unifi_trace(priv, UDBG1,
                "unsubscribe_req: handle=%d, result=%d\n",
                req->subscriptionHandle, result);
    CsrWifiRouterMaPacketUnsubscribeCfmSend(msg->source,req->interfaceTag, result);
}


void CsrWifiRouterCtrlCapabilitiesReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlCapabilitiesReq* req = (CsrWifiRouterCtrlCapabilitiesReq*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlCapabilitiesReqHandler: invalid priv\n");
        return;
    }

    CsrWifiRouterCtrlCapabilitiesCfmSend(msg->source,req->clientData,
            UNIFI_SOFT_COMMAND_Q_LENGTH - 1,
            UNIFI_SOFT_TRAFFIC_Q_LENGTH - 1);
}


void CsrWifiRouterCtrlSuspendResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlSuspendRes* res = (CsrWifiRouterCtrlSuspendRes*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlSuspendResHandler: invalid priv\n");
        return;
    }

    sme_complete_request(priv, res->status);
}


void CsrWifiRouterCtrlResumeResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlResumeRes* res = (CsrWifiRouterCtrlResumeRes*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlResumeResHandler: invalid priv\n");
        return;
    }

    sme_complete_request(priv, res->status);
}


void CsrWifiRouterCtrlTrafficConfigReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlTrafficConfigReq* req = (CsrWifiRouterCtrlTrafficConfigReq*)msg;
    CsrResult csrResult;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlTrafficConfigReqHandler: invalid smepriv\n");
        return;
    }
    if (req->trafficConfigType == CSR_WIFI_ROUTER_CTRL_TRAFFIC_CONFIG_TYPE_FILTER)
    {
        req->config.packetFilter |= CSR_WIFI_ROUTER_CTRL_TRAFFIC_PACKET_TYPE_CUSTOM;
    }
    csrResult = unifi_ta_configure(priv->card, req->trafficConfigType, (const CsrWifiRouterCtrlTrafficConfig *)&req->config);
}

void CsrWifiRouterCtrlTrafficClassificationReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlTrafficClassificationReq* req = (CsrWifiRouterCtrlTrafficClassificationReq*)msg;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlTrafficClassificationReqHandler: invalid smepriv\n");
        return;
    }

    unifi_ta_classification(priv->card, req->trafficType, req->period);
}

static int
_sys_packet_req(unifi_priv_t *priv, const CSR_SIGNAL *signal,
        u8 subscriptionHandle,
        u16 frameLength, u8 *frame,
        int proto)
{
    int r;
    const sme_ma_unidata_ind_filter_t *subs;
    bulk_data_param_t bulkdata;
    CSR_MA_PACKET_REQUEST req = signal->u.MaPacketRequest;
    struct sk_buff *skb, *newSkb = NULL;
    CsrWifiMacAddress peerMacAddress;
    CsrResult csrResult;
    u16 interfaceTag = req.VirtualInterfaceIdentifier & 0xff;
    u8 eapolStore = FALSE;
    s8 protection = 0;
    netInterface_priv_t *interfacePriv;
    unsigned long flags;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "_sys_packet_req: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
        return -EINVAL;
    }
    interfacePriv = priv->interfacePriv[interfaceTag];
    if (!priv->sme_unidata_ind_filters[subscriptionHandle].in_use) {
        unifi_error(priv, "_sys_packet_req: unknown subscription.\n");
        return -EINVAL;
    }

    subs = &priv->sme_unidata_ind_filters[subscriptionHandle];
    unifi_trace(priv, UDBG1,
                "_sys_packet_req: handle=%d, subs=%p, encap=%d\n",
                subscriptionHandle, subs, subs->encapsulation);

    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], frameLength);
    if (csrResult != CSR_RESULT_SUCCESS) {
        unifi_error(priv, "_sys_packet_req: failed to allocate bulkdata.\n");
        return (int)CsrHipResultToStatus(csrResult);
    }

    /* get the peer Mac address */
    memcpy(&peerMacAddress, frame, ETH_ALEN);

    /* Determine if we need to add encapsulation header */
    if (subs->encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
        memcpy((void*)bulkdata.d[0].os_data_ptr, frame, frameLength);

        /* The translation is performed on the skb */
        skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;

        unifi_trace(priv, UDBG1,
                    "_sys_packet_req: skb_add_llc_snap -->\n");
        r = skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto);
        unifi_trace(priv, UDBG1,
                    "_sys_packet_req: skb_add_llc_snap <--\n");
        if (r) {
            unifi_error(priv,
                        "_sys_packet_req: failed to translate eth frame.\n");
            unifi_net_data_free(priv,&bulkdata.d[0]);
            return r;
        }

        bulkdata.d[0].data_length = skb->len;
    } else {
        /* Crop the MAC addresses from the packet */
        memcpy((void*)bulkdata.d[0].os_data_ptr, frame + 2*ETH_ALEN, frameLength - 2*ETH_ALEN);
        bulkdata.d[0].data_length = frameLength - 2*ETH_ALEN;
        skb = (struct sk_buff*)bulkdata.d[0].os_net_buf_ptr;
        skb->len = bulkdata.d[0].data_length;

    }

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

    /* check for m4 detection */
    if (0 == uf_verify_m4(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length)) {
        eapolStore = TRUE;
    }

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    if (proto == ETH_P_WAI)
     {
        protection = 0; /*WAI packets always sent unencrypted*/
     }
   else
     {
#endif

#ifdef CSR_SUPPORT_SME
    if ((protection = uf_get_protection_bit_from_interfacemode(priv, interfaceTag, peerMacAddress.a)) < 0) {
        unifi_error(priv, "unicast address, but destination not in station record database\n");
        unifi_net_data_free(priv,&bulkdata.d[0]);
        return -1;
    }
#else
    protection = 0;
#endif

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    }
#endif

    /* add Mac header */
    if (prepare_and_add_macheader(priv, skb, newSkb, req.Priority, &bulkdata, interfaceTag, frame, frame + ETH_ALEN, protection)) {
        unifi_error(priv, "failed to create MAC header\n");
        unifi_net_data_free(priv,&bulkdata.d[0]);
        return -1;
    }

    if (eapolStore) {
        spin_lock_irqsave(&priv->m4_lock, flags);
        /* Store the EAPOL M4 packet for later */
        interfacePriv->m4_signal = *signal;
        interfacePriv->m4_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
        interfacePriv->m4_bulk_data.data_length = bulkdata.d[0].data_length;
        interfacePriv->m4_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
        interfacePriv->m4_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
        spin_unlock_irqrestore(&priv->m4_lock, flags);
        /* Send a signal to SME */
        unifi_trace(priv, UDBG1, "_sys_packet_req: Sending CsrWifiRouterCtrlM4ReadyToSendInd\n");
        CsrWifiRouterCtrlM4ReadyToSendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
        return 0;
    }

    /* Send the signal to UniFi */
      /* Set the B31 to 1 for local routing*/
    r= uf_process_ma_packet_req(priv,  peerMacAddress.a, (req.HostTag | 0x80000000), interfaceTag, 0,
                                (CSR_RATE)0, req.Priority, signal->SignalPrimitiveHeader.SenderProcessId, &bulkdata);
    if (r) {
        unifi_error(priv,
                    "_sys_packet_req: failed to send signal.\n");
        unifi_net_data_free(priv,&bulkdata.d[0]);
        return r;
    }
    /* The final CsrWifiRouterMaPacketCfmSend() will called when the actual MA-PACKET.cfm is received from the chip */

    return 0;
}

void CsrWifiRouterMaPacketReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    int r;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterMaPacketReq* mareq = (CsrWifiRouterMaPacketReq*)msg;
    llc_snap_hdr_t *snap;
    u16 snap_protocol;
    CSR_SIGNAL signal;
    CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
    CsrWifiRouterCtrlPortAction controlPortaction;
    u8 *daddr, *saddr;
    u16 interfaceTag = mareq->interfaceTag & 0x00ff;
    int queue;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

    if (!mareq->frame || !priv || !priv->smepriv)
    {
        unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: invalid frame/priv/priv->smepriv\n");
        return;
    }

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterMaPacketReqHandler: interfaceID >= CSR_WIFI_NUM_INTERFACES.\n");
        return;
    }
    /* get a pointer to dest & source Mac address */
    daddr = mareq->frame;
    saddr = (mareq->frame + ETH_ALEN);
    /* point to the proper position of frame, since frame has MAC header */
    snap = (llc_snap_hdr_t *) (mareq->frame + 2 * ETH_ALEN);
    snap_protocol = ntohs(snap->protocol);
    if((snap_protocol == ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
       || (snap_protocol == ETH_P_WAI)
#endif
    )
    {
        queue = UF_UNCONTROLLED_PORT_Q;
    }
    else
    {
        queue = UF_CONTROLLED_PORT_Q;
    }

    /* Controlled port restrictions apply to the packets */
    controlPortaction = uf_sme_port_state(priv, daddr, queue, interfaceTag);
    if (controlPortaction != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)
    {
        unifi_warning(priv, "CsrWifiRouterMaPacketReqHandler: (%s)controlled port is closed.\n", (queue == UF_CONTROLLED_PORT_Q)?"":"un");
        if(mareq->cfmRequested)
        {
            CsrWifiRouterMaPacketCfmSend(msg->source,
                                     interfaceTag,
                                     CSR_RESULT_FAILURE,
                                     mareq->hostTag, 0);
        }
        return;
    }

    signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
    /* Store the appHandle in the LSB of the SenderId. */
    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->sme_cli->sender_id & 0xff00) | (unsigned int)msg->source),
                                     (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;

    /* Fill in the MA-PACKET.req signal */
    memcpy(req->Ra.x, daddr, ETH_ALEN);
    req->Priority = mareq->priority;
    req->TransmitRate = 0; /* Let firmware select the rate*/
    req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
    req->HostTag = mareq->hostTag;

    if(mareq->cfmRequested)
        req->TransmissionControl = 0;
    else
        req->TransmissionControl = CSR_NO_CONFIRM_REQUIRED;

    r = _sys_packet_req(priv, &signal, mareq->subscriptionHandle,
            mareq->frameLength, mareq->frame, snap_protocol);

    if (r && mareq->cfmRequested)
    {
        CsrWifiRouterMaPacketCfmSend(msg->source,interfaceTag,
                                     CSR_RESULT_FAILURE,
                                     mareq->hostTag, 0);
    }
    return;
}

void CsrWifiRouterMaPacketCancelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
}

void CsrWifiRouterCtrlM4TransmitReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlM4TransmitReq* req = (CsrWifiRouterCtrlM4TransmitReq*)msg;
    int r;
    bulk_data_param_t bulkdata;
    netInterface_priv_t *interfacePriv;
    CSR_SIGNAL m4_signal;
    unsigned long flags;

    if (priv == NULL) {
        unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid smepriv\n");
        return;
    }
    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "M4TransmitReqHandler: interfaceTag >= CSR_WIFI_NUM_INTERFACES\n");
        return;
    }

    interfacePriv = priv->interfacePriv[req->interfaceTag];
    spin_lock_irqsave(&priv->m4_lock, flags);
    if (interfacePriv->m4_bulk_data.data_length == 0) {
        spin_unlock_irqrestore(&priv->m4_lock, flags);
        unifi_error(priv, "CsrWifiRouterCtrlM4TransmitReqHandler: invalid buffer\n");
        return;
    }

    memcpy(&bulkdata.d[0], &interfacePriv->m4_bulk_data, sizeof(bulk_data_desc_t));

    interfacePriv->m4_bulk_data.net_buf_length = 0;
    interfacePriv->m4_bulk_data.data_length = 0;
    interfacePriv->m4_bulk_data.os_data_ptr = interfacePriv->m4_bulk_data.os_net_buf_ptr = NULL;
    m4_signal = interfacePriv->m4_signal;
    spin_unlock_irqrestore(&priv->m4_lock, flags);

    bulkdata.d[1].os_data_ptr = NULL;
    bulkdata.d[1].data_length = 0;

    interfacePriv->m4_sent = TRUE;
    m4_signal.u.MaPacketRequest.HostTag |= 0x80000000;
    /* Store the hostTag for later varification */
    interfacePriv->m4_hostTag = m4_signal.u.MaPacketRequest.HostTag;
    r = ul_send_signal_unpacked(priv, &m4_signal, &bulkdata);
    unifi_trace(priv, UDBG1,
                "CsrWifiRouterCtrlM4TransmitReqHandler: sent\n");
    if (r) {
        unifi_error(priv,
                    "CsrWifiRouterCtrlM4TransmitReqHandler: failed to send signal.\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
    }
}

/* reset the station records when the mode is set as CSR_WIFI_ROUTER_CTRL_MODE_NONE */
static void CsrWifiRouterCtrlResetStationRecordList(unifi_priv_t *priv, u16 interfaceTag)
{
    u8 i,j;
    CsrWifiRouterCtrlStaInfo_t *staInfo=NULL;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    unsigned long lock_flags;

    /* create a list for sending confirms of un-delivered packets */
    struct list_head send_cfm_list;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterCtrlResetStationRecordList: bad interfaceTag\n");
        return;
    }

    INIT_LIST_HEAD(&send_cfm_list);

    /* Reset the station record to NULL if mode is NONE */
    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        if ((staInfo=interfacePriv->staInfo[i]) != NULL) {
            uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                                 &send_cfm_list,
                                                 &(staInfo->mgtFrames));
            uf_flush_list(priv,&(staInfo->mgtFrames));
            for(j=0;j<MAX_ACCESS_CATOGORY;j++){
                uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                                     &send_cfm_list,
                                                     &(staInfo->dataPdu[j]));
                uf_flush_list(priv,&(staInfo->dataPdu[j]));
            }

            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
            /* Removing station record information from port config array */
            memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
            staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
            staInfo->peerControlledPort->in_use = FALSE;
            interfacePriv->controlled_data_port.entries_in_use--;

            memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
            staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
            staInfo->peerUnControlledPort->in_use = FALSE;
            interfacePriv->uncontrolled_data_port.entries_in_use--;

            kfree(interfacePriv->staInfo[i]);
            interfacePriv->staInfo[i] = NULL;
            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
        }
    }
    /* after the critical region process the list of frames that requested cfm
     * and send cfm to requestor one by one
     */
    send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);

#ifdef CSR_SUPPORT_SME
    /* Interface Independent, no of packet queued, incase of mode is None or AP set to 0 */
    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
        case CSR_WIFI_ROUTER_CTRL_MODE_NONE:
            if (priv->noOfPktQueuedInDriver) {
                unifi_warning(priv, "After reset the noOfPktQueuedInDriver = %x\n", priv->noOfPktQueuedInDriver);
                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
                priv->noOfPktQueuedInDriver = 0;
                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
            }
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            break;
        default:
            unifi_error(priv, "interfacemode is not correct in CsrWifiRouterCtrlResetStationRecordList: debug\n");
    }
#endif

    if (((interfacePriv->controlled_data_port.entries_in_use != 0) || (interfacePriv->uncontrolled_data_port.entries_in_use != 0))
            && (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE)) {
        /* Print in case if the value of entries goes to -ve/+ve (apart from 0)
         * we expect the entries should be zero here if mode is set as NONE
         */
        unifi_trace(priv, UDBG3, "In %s controlled port entries = %d, uncontrolled port entries = %d\n",
                   __FUNCTION__, interfacePriv->controlled_data_port.entries_in_use,
                   interfacePriv->uncontrolled_data_port.entries_in_use);
    }
}

void CsrWifiRouterCtrlInterfaceReset(unifi_priv_t *priv, u16 interfaceTag)
{
    netInterface_priv_t *interfacePriv;

    /* create a list for sending confirms of un-delivered packets */
    struct list_head send_cfm_list;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "CsrWifiRouterCtrlInterfaceReset: bad interfaceTag\n");
        return;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    INIT_LIST_HEAD(&send_cfm_list);

    /* Enable all queues by default */
    interfacePriv->queueEnabled[0] = 1;
    interfacePriv->queueEnabled[1] = 1;
    interfacePriv->queueEnabled[2] = 1;
    interfacePriv->queueEnabled[3] = 1;

    uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                             &send_cfm_list,
                                             &(interfacePriv->genericMgtFrames));
    uf_flush_list(priv,&(interfacePriv->genericMgtFrames));

    uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                             &send_cfm_list,
                                             &(interfacePriv->genericMulticastOrBroadCastMgtFrames));
    uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastMgtFrames));

    uf_prepare_send_cfm_list_for_queued_pkts(priv,
                                             &send_cfm_list,
                                             &(interfacePriv->genericMulticastOrBroadCastFrames));

    uf_flush_list(priv,&(interfacePriv->genericMulticastOrBroadCastFrames));

    /*  process the list of frames that requested cfm
    and send cfm to requestor one by one */
    send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);

    /* Reset the station record to NULL if mode is tried to set as NONE */
    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
        case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
            /* station records not available in these modes */
            break;
        default:
            CsrWifiRouterCtrlResetStationRecordList(priv,interfaceTag);
    }

    interfacePriv->num_stations_joined = 0;
    interfacePriv->sta_activity_check_enabled = FALSE;
}


void CsrWifiRouterCtrlModeSetReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlModeSetReq* req = (CsrWifiRouterCtrlModeSetReq*)msg;

    if (priv == NULL)
    {
        unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid smepriv\n");
        return;
    }

    if (req->interfaceTag < CSR_WIFI_NUM_INTERFACES)
    {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
#ifdef CSR_WIFI_SPLIT_PATCH
        u8 old_mode = interfacePriv->interfaceMode;
#endif
        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlModeSetReqHandler: interfacePriv->interfaceMode = %d\n",
                interfacePriv->interfaceMode);

        interfacePriv->interfaceMode = req->mode;

#ifdef CSR_WIFI_SPLIT_PATCH
        /* Detect a change in mode that requires a switch to/from the AP firmware patch.
         * This should only happen when transitioning in/out of AP modes.
         */
        if (CSR_WIFI_HIP_IS_AP_FW(req->mode) != CSR_WIFI_HIP_IS_AP_FW(old_mode))
        {
            CsrWifiRouterCtrlVersions versions;
            int r;

#ifdef ANDROID_BUILD
            /* Take the wakelock while switching patch */
            unifi_trace(priv, UDBG1, "patch switch: take wake lock\n");
            wake_lock(&unifi_sdio_wake_lock);
#endif
            unifi_info(priv, "Resetting UniFi with %s patch\n", CSR_WIFI_HIP_IS_AP_FW(req->mode) ? "AP" : "STA");

            r = uf_request_firmware_files(priv, UNIFI_FW_STA);
            if (r) {
                unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: Failed to get f/w\n");
                CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
                                                req->mode, CSR_RESULT_FAILURE);
                return;
            }

            /* Block the I/O thread */
            priv->bh_thread.block_thread = 1;

            /* Reset and download the new patch */
            r = uf_init_hw(priv);
            if (r) {
                unifi_error(priv, "CsrWifiRouterCtrlWifiOnReqHandler: Failed to initialise h/w, error %d\n", r);
                CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
                                                req->mode, CSR_RESULT_FAILURE);
                return;
            }

            /* Re-enable the I/O thread */
            priv->bh_thread.block_thread = 0;

            /* Get the version information from the core */
            unifi_card_info(priv->card, &priv->card_info);

            /* Copy to the unifiio_card_info structure. */
            versions.chipId = priv->card_info.chip_id;
            versions.chipVersion = priv->card_info.chip_version;
            versions.firmwareBuild = priv->card_info.fw_build;
            versions.firmwareHip = priv->card_info.fw_hip_version;
            versions.routerBuild = (char*)CSR_WIFI_VERSION;
            versions.routerHip = (UNIFI_HIP_MAJOR_VERSION << 8) | UNIFI_HIP_MINOR_VERSION;

            /* Now that new firmware is running, send a WifiOnInd to the NME. This will
             * cause it to retransfer the MIB.
             */
            CsrWifiRouterCtrlWifiOnIndSend(msg->source, 0, CSR_RESULT_SUCCESS, versions);

            /* Store the request so we know where to send the ModeSetCfm */
            priv->pending_mode_set = *req;
        }
        else
#endif
        {
            /* No patch switch, confirm straightaway */
            CsrWifiRouterCtrlModeSetCfmSend(msg->source, req->clientData, req->interfaceTag,
                                            req->mode, CSR_RESULT_SUCCESS);
        }

        interfacePriv->bssid = req->bssid;
        /* For modes other than AP/P2PGO, set below member FALSE */
        interfacePriv->intraBssEnabled = FALSE;
        /* Initialise the variable bcTimSet with a value
         * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
         */
        interfacePriv->bcTimSet = 0xFF;
        interfacePriv->bcTimSetReqPendingFlag = FALSE;
        /* Initialise the variable bcTimSetReqQueued with a value
         * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
         */
        interfacePriv->bcTimSetReqQueued =0xFF;
        CsrWifiRouterCtrlInterfaceReset(priv,req->interfaceTag);

        if(req->mode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
           req->mode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {
            interfacePriv->protect = req->protection;
            interfacePriv->dtimActive=FALSE;
            interfacePriv->multicastPduHostTag = 0xffffffff;
            /* For AP/P2PGO mode SME sending intraBssDistEnabled
             * i.e. for AP: intraBssDistEnabled = TRUE, for P2PGO
             * intraBssDistEnabled = TRUE/FALSE on requirement
             */
            interfacePriv->intraBssEnabled = req->intraBssDistEnabled;
            unifi_trace(priv, UDBG3, "CsrWifiRouterCtrlModeSetReqHandler: IntraBssDisEnabled = %d\n",
                        req->intraBssDistEnabled);
        } else if (req->mode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
              netif_carrier_off(priv->netdev[req->interfaceTag]);
              interfacePriv->connected = UnifiConnectedUnknown;
        }
    }
    else {
        unifi_error(priv, "CsrWifiRouterCtrlModeSetReqHandler: invalid interfaceTag :%d\n",req->interfaceTag);
    }
}

void CsrWifiRouterMaPacketResHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
}

/* delete the station record from the station record data base */
static int peer_delete_record(unifi_priv_t *priv, CsrWifiRouterCtrlPeerDelReq *req)
{
    u8 j;
    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
    unifi_port_config_t *controlledPort;
    unifi_port_config_t *unControlledPort;
    netInterface_priv_t *interfacePriv;

    u8 ba_session_idx = 0;
    ba_session_rx_struct *ba_session_rx = NULL;
    ba_session_tx_struct *ba_session_tx = NULL;

    /* create a list for sending confirms of un-delivered packets */
    struct list_head send_cfm_list;

    unsigned long lock_flags;

    if ((req->peerRecordHandle >= UNIFI_MAX_CONNECTIONS) || (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
        unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", req->peerRecordHandle, req->interfaceTag);
        return CSR_RESULT_FAILURE;
    }

    INIT_LIST_HEAD(&send_cfm_list);

    interfacePriv = priv->interfacePriv[req->interfaceTag];
    /* remove the station record & make it NULL */
    if ((staInfo=interfacePriv->staInfo[req->peerRecordHandle])!=NULL) {

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

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

        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
        /* clear the port configure array info, for the corresponding peer entry */
        controlledPort = &interfacePriv->controlled_data_port;
        unControlledPort = &interfacePriv->uncontrolled_data_port;

        unifi_trace(priv, UDBG1, "peer_delete_record: Peer found handle = %d, port in use: cont(%d), unCont(%d)\n",
                    req->peerRecordHandle, controlledPort->entries_in_use, unControlledPort->entries_in_use);

        memset(staInfo->peerControlledPort, 0, sizeof(unifi_port_cfg_t));
        staInfo->peerControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
        staInfo->peerControlledPort->in_use = FALSE;
        if (controlledPort->entries_in_use) {
            controlledPort->entries_in_use--;
        } else {
            unifi_warning(priv, "number of controlled port entries is zero, trying to decrement: debug\n");
        }

        memset(staInfo->peerUnControlledPort, 0, sizeof(unifi_port_cfg_t));
        staInfo->peerUnControlledPort->port_action = CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD;
        staInfo->peerUnControlledPort->in_use = FALSE;
        if (unControlledPort->entries_in_use) {
            unControlledPort->entries_in_use--;
        } else {
            unifi_warning(priv, "number of uncontrolled port entries is zero, trying to decrement: debug\n");
        }

        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
        /* update the TIM with zero */
        if (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS &&
                staInfo->timSet == CSR_WIFI_TIM_SET) {
            unifi_trace(priv, UDBG3, "peer is deleted so TIM updated to 0, in firmware\n");
            update_tim(priv,staInfo->aid,0,req->interfaceTag, req->peerRecordHandle);
        }


        /* Stop BA session if it is active, for this peer address all BA sessions
        (per tID per role) are closed */

        down(&priv->ba_mutex);
        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
            ba_session_rx = priv->interfacePriv[req->interfaceTag]->ba_session_rx[ba_session_idx];
            if(ba_session_rx) {
                if(!memcmp(ba_session_rx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
                    blockack_session_stop(priv,
                                        req->interfaceTag,
                                        CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT,
                                        ba_session_rx->tID,
                                        ba_session_rx->macAddress);
                }
            }
        }

        for(ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
            ba_session_tx = priv->interfacePriv[req->interfaceTag]->ba_session_tx[ba_session_idx];
            if(ba_session_tx) {
                if(!memcmp(ba_session_tx->macAddress.a, staInfo->peerMacAddress.a, ETH_ALEN)){
                    blockack_session_stop(priv,
                                        req->interfaceTag,
                                        CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR,
                                        ba_session_tx->tID,
                                        ba_session_tx->macAddress);
                }
            }
        }

        up(&priv->ba_mutex);

#ifdef CSR_SUPPORT_SME
        unifi_trace(priv, UDBG1, "Canceling work queue for STA with AID: %d\n", staInfo->aid);
        cancel_work_sync(&staInfo->send_disconnected_ind_task);
#endif

        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
#ifdef CSR_SUPPORT_SME
        interfacePriv->num_stations_joined--;

        staInfo->nullDataHostTag = INVALID_HOST_TAG;

        if ((interfacePriv->sta_activity_check_enabled) &&
            (interfacePriv->num_stations_joined < STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD))
        {
            unifi_trace(priv, UDBG1, "STOPPING the Inactivity Timer (num of stations = %d)\n", interfacePriv->num_stations_joined);
            interfacePriv->sta_activity_check_enabled = FALSE;
            del_timer_sync(&interfacePriv->sta_activity_check_timer);
        }
#endif

        /* Free the station record for corresponding peer */
        kfree(interfacePriv->staInfo[req->peerRecordHandle]);
        interfacePriv->staInfo[req->peerRecordHandle] = NULL;
        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);

        /* after the critical region process the list of frames that requested cfm
        and send cfm to requestor one by one */
        send_auto_ma_packet_confirm(priv, interfacePriv, &send_cfm_list);


    }
    else
    {
        unifi_trace(priv, UDBG3, " peer not found: Delete request Peer handle[%d]\n", req->peerRecordHandle);
    }

    return CSR_RESULT_SUCCESS;
}

void CsrWifiRouterCtrlPeerDelReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    CsrWifiRouterCtrlPeerDelReq* req = (CsrWifiRouterCtrlPeerDelReq*)msg;
    CsrResult status = CSR_RESULT_SUCCESS;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerDelReqHandler \n");
    if (priv == NULL)
    {
        unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: invalid smepriv\n");
        return;
    }

    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "CsrWifiRouterCtrlPeerDelReqHandler: bad interfaceTag\n");
        return;
    }

    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            /* remove the station from station record data base */
            status = peer_delete_record(priv, req);
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
        default:
            /* No station record to maintain in these modes */
            break;
    }

    CsrWifiRouterCtrlPeerDelCfmSend(msg->source,req->clientData,req->interfaceTag,status);
    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerDelReqHandler \n");
}

/* Add the new station to the station record data base */
static int peer_add_new_record(unifi_priv_t *priv,CsrWifiRouterCtrlPeerAddReq *req,u32 *handle)
{
    u8 i, powerModeTemp = 0;
    u8 freeSlotFound = FALSE;
    CsrWifiRouterCtrlStaInfo_t *newRecord = NULL;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
    u32 currentTime, currentTimeHi;
    unsigned long lock_flags;

    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "peer_add_new_record: bad interfaceTag\n");
        return CSR_RESULT_FAILURE;
    }

    currentTime = CsrTimeGet(&currentTimeHi);

    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        if(interfacePriv->staInfo[i] == NULL) {
            /* Slot is empty, so can be used for station record */
            freeSlotFound = TRUE;
            *handle = i;

            /* Allocate for the new station record , to avoid race condition would happen between ADD_PEER &
             * DEL_PEER the allocation made atomic memory rather than kernel memory
             */
            newRecord = kmalloc(sizeof(CsrWifiRouterCtrlStaInfo_t), GFP_ATOMIC);
            if (!newRecord) {
                unifi_error(priv, "failed to allocate the %d bytes of mem for station record\n",
                            sizeof(CsrWifiRouterCtrlStaInfo_t));
                return CSR_RESULT_FAILURE;
            }

            unifi_trace(priv, UDBG1, "peer_add_new_record: handle = %d AID = %d addr = %x:%x:%x:%x:%x:%x LI=%u\n",
                        *handle, req->associationId, req->peerMacAddress.a[0], req->peerMacAddress.a[1], req->peerMacAddress.a[2],
                        req->peerMacAddress.a[3], req->peerMacAddress.a[4], req->peerMacAddress.a[5],
                        req->staInfo.listenIntervalInTus);

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

            interfacePriv->staInfo[i] = newRecord;
            /* Initialize the record*/
            memset(newRecord,0,sizeof(CsrWifiRouterCtrlStaInfo_t));
            /* update the station record */
            memcpy(newRecord->peerMacAddress.a, req->peerMacAddress.a, ETH_ALEN);
            newRecord->wmmOrQosEnabled = req->staInfo.wmmOrQosEnabled;

            /* maxSpLength is bit map in qosInfo field, so converting accordingly */
            newRecord->maxSpLength = req->staInfo.maxSpLength * 2;

            /*Max SP 0 mean any number of packets. since we buffer only 512
            packets we are hard coding this to zero for the moment */

            if(newRecord->maxSpLength == 0)
                newRecord->maxSpLength=512;

            newRecord->assignedHandle = i;

             /* copy power save mode of all access catagory (Trigger/Delivery/both enabled/disabled) */
            powerModeTemp = (u8) ((req->staInfo.powersaveMode >> 4) & 0xff);

            if(!(req->staInfo.powersaveMode & 0x0001))
                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
            else
               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BK]= powerModeTemp & 0x03;

            if(!(req->staInfo.powersaveMode & 0x0002))
                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
            else
               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_BE]= ((powerModeTemp & 0x0C)>> 2);

            if(!(req->staInfo.powersaveMode & 0x0004))
                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
            else
               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VI]= ((powerModeTemp & 0x30)>> 4);

            if(!(req->staInfo.powersaveMode & 0x0008))
                newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= CSR_WIFI_AC_LEGACY_POWER_SAVE;
            else
               newRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]= ((powerModeTemp & 0xC0)>> 6);

            {
                u8 k;
                for(k=0; k< MAX_ACCESS_CATOGORY ;k++)
                    unifi_trace(priv, UDBG2, "peer_add_new_record: WMM : %d ,AC %d, powersaveMode %x \n",
                            req->staInfo.wmmOrQosEnabled,k,newRecord->powersaveMode[k]);
            }

            unifi_trace(priv, UDBG3, "newRecord->wmmOrQosEnabled : %d , MAX SP : %d\n",
                    newRecord->wmmOrQosEnabled,newRecord->maxSpLength);

            /* Initialize the mgtFrames & data Pdu list */
            {
                u8 j;
                INIT_LIST_HEAD(&newRecord->mgtFrames);
                for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
                    INIT_LIST_HEAD(&newRecord->dataPdu[j]);
                }
            }

            newRecord->lastActivity = currentTime;
            newRecord->activity_flag = TRUE;

            /* enable the preemption as station record updated */
            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);

            /* First time port actions are set for the peer with below information */
            configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
                                UF_UNCONTROLLED_PORT_Q, req->interfaceTag);

            if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS) {
                configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN, &newRecord->peerMacAddress,
                                    UF_CONTROLLED_PORT_Q, req->interfaceTag);
            } else {
                configure_data_port(priv, CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD, &newRecord->peerMacAddress,
                                    UF_CONTROLLED_PORT_Q, req->interfaceTag);
            }


            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
            /* Port status must be already set before calling the Add Peer request */
            newRecord->peerControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
                                                                      UF_CONTROLLED_PORT_Q, req->interfaceTag);
            newRecord->peerUnControlledPort = uf_sme_port_config_handle(priv, newRecord->peerMacAddress.a,
                                                                        UF_UNCONTROLLED_PORT_Q, req->interfaceTag);

            if (!newRecord->peerControlledPort || !newRecord->peerUnControlledPort) {
                /* enable the preemption as station record failed to update */
                unifi_warning(priv, "Un/ControlledPort record not found in port configuration array index = %d\n", i);
                kfree(interfacePriv->staInfo[i]);
                interfacePriv->staInfo[i] = NULL;
                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
                return CSR_RESULT_FAILURE;
            }

            newRecord->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;

            /* changes done during block ack handling */
            newRecord->txSuspend = FALSE;

            /*U-APSD related data structure*/
            newRecord->timRequestPendingFlag = FALSE;

            /* Initialise the variable updateTimReqQueued with a value
             * other then CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET value
             */
            newRecord->updateTimReqQueued = 0xFF;
            newRecord->timSet = CSR_WIFI_TIM_RESET;
            newRecord->uapsdActive = FALSE;
            newRecord->noOfSpFramesSent =0;
            newRecord->triggerFramePriority = CSR_QOS_UP0;

            /* The protection bit is updated once the port opens for corresponding peer in
             * routerPortConfigure request */

            /* update the association ID */
            newRecord->aid = req->associationId;

#ifdef CSR_SUPPORT_SME
            interfacePriv->num_stations_joined++;
            newRecord->interfacePriv = interfacePriv;
            newRecord->listenIntervalInTus = req->staInfo.listenIntervalInTus;
            newRecord->nullDataHostTag = INVALID_HOST_TAG;

            INIT_WORK(&newRecord->send_disconnected_ind_task, uf_send_disconnected_ind_wq);

            if(!(interfacePriv->sta_activity_check_enabled) &&
               (interfacePriv->num_stations_joined >= STA_INACTIVE_DETECTION_TRIGGER_THRESHOLD)){
                unifi_trace(priv, UDBG1,
                            "peer_add_new_record: STARTING the Inactivity Timer (num of stations = %d)",
                            interfacePriv->num_stations_joined);

                interfacePriv->sta_activity_check_enabled = TRUE;
                interfacePriv->sta_activity_check_timer.function = check_inactivity_timer_expire_func;
                interfacePriv->sta_activity_check_timer.data = (unsigned long)interfacePriv;

                init_timer(&interfacePriv->sta_activity_check_timer);
                mod_timer(&interfacePriv->sta_activity_check_timer,
                          (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));

            }
#endif
            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
            break;
        }
    }

    if(!freeSlotFound) {
        unifi_error(priv, "Limited connectivity, Free slot not found for station record addition\n");
        return CSR_RESULT_FAILURE;
    }
    return CSR_RESULT_SUCCESS;
}

#ifdef CSR_SUPPORT_SME
static void check_inactivity_timer_expire_func(unsigned long data)
{
    struct unifi_priv *priv;
    CsrWifiRouterCtrlStaInfo_t *sta_record = NULL;
    u8 i = 0;
    u32 now;
    u32 inactive_time;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *) data;

    if (!interfacePriv)
    {
        return;
    }

    priv = interfacePriv->privPtr;

    if (interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "check_inactivity_timer_expire_func: Invalid interfaceTag\n");
        return;
    }

    /* RUN Algorithm to check inactivity for each connected station */
    now = CsrTimeGet(NULL);

    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
        if(interfacePriv->staInfo[i] != NULL) {
            sta_record = interfacePriv->staInfo[i];

            if (sta_record->activity_flag == TRUE){
                sta_record->activity_flag = FALSE;
                sta_record->lastActivity = now;
                continue;
            }

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

            if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
            {
                unifi_trace(priv, UDBG1, "STA is Inactive - AID = %d inactive_time = %d\n",
                                        sta_record->aid,
                                        inactive_time);

                /* station is in-active, if it is in active mode send a null frame
                 * and the station should acknowledge the null frame, if acknowledgement
                 * is not received throw out the station.
                 * If the station is in Power Save, update TIM for the station so
                 * that it wakes up and register some activity through PS-Poll or
                 * trigger frame.
                 */
                 if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
                 {
                    unifi_trace(priv, UDBG1, "STA power save state - Active, send a NULL frame to check if it is ALIVE\n");
                    uf_send_nulldata ( priv,
                                       sta_record->interfacePriv->InterfaceTag,
                                       sta_record->peerMacAddress.a,
                                       CSR_CONTENTION,
                                       sta_record);
                 }
                 else if (sta_record->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
                 {
                    if((sta_record->timSet == CSR_WIFI_TIM_SET) ||
                       (sta_record->timSet == CSR_WIFI_TIM_SETTING))
                    {
                        unifi_trace(priv, UDBG1, "STA power save state - PS, TIM is already SET\n");

                        /* If TIM is set and we do not have any activity for
                         * more than 3 listen intervals then send a disconnected
                         * indication to SME, to delete the station from station
                         * record list.
                         * The inactivity is already more than STA_INACTIVE_TIMEOUT_VAL
                         * and this check ensures if the listen interval is a larger
                         * value than STA_INACTIVE_TIMEOUT_VAL.
                         */
                         if (inactive_time > (3 * (sta_record->listenIntervalInTus * 1024)))
                         {
                            unifi_trace(priv, UDBG1, "STA is inactive for more than 3 listen intervals\n");
                            queue_work( priv->unifi_workqueue,
                                        &sta_record->send_disconnected_ind_task);
                         }

                    }
                    else
                    {
                        unifi_trace(priv, UDBG1, "STA power save state - PS, update TIM to see if it is ALIVE\n");
                        update_tim(priv,
                                   sta_record->aid,
                                   CSR_WIFI_TIM_SET,
                                   interfacePriv->InterfaceTag,
                                   sta_record->assignedHandle);
                    }
                 }
            }
        }
    }

    /* re-run the timer interrupt */
    mod_timer(&interfacePriv->sta_activity_check_timer,
              (jiffies + usecs_to_jiffies(STA_INACTIVE_DETECTION_TIMER_INTERVAL * 1000 * 1000)));

}


void uf_send_disconnected_ind_wq(struct work_struct *work)
{

    CsrWifiRouterCtrlStaInfo_t *staInfo = container_of(work, CsrWifiRouterCtrlStaInfo_t, send_disconnected_ind_task);
    unifi_priv_t *priv;
    u16 interfaceTag;
    struct list_head send_cfm_list;
    u8 j;

    if(!staInfo) {
        return;
    }

    if(!staInfo->interfacePriv) {
        return;
    }

    priv = staInfo->interfacePriv->privPtr;
    interfaceTag =  staInfo->interfacePriv->InterfaceTag;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "uf_send_disconnected_ind_wq: invalid interfaceTag\n");
        return;
    }

    /* The SME/NME may be waiting for confirmation for requested frames to this station.
     * So loop 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,
                                             &(staInfo->mgtFrames));

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

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

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

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

    unifi_warning(priv, "uf_send_disconnected_ind_wq: Router Disconnected IND Peer (%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]);

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


    return;
}


#endif
void CsrWifiRouterCtrlPeerAddReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
{
    CsrWifiRouterCtrlPeerAddReq* req = (CsrWifiRouterCtrlPeerAddReq*)msg;
    CsrResult status = CSR_RESULT_SUCCESS;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    u32 handle = 0;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerAddReqHandler \n");
    if (priv == NULL)
    {
        unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: invalid smepriv\n");
        return;
    }

    if (req->interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "CsrWifiRouterCtrlPeerAddReqHandler: bad interfaceTag\n");
        return;
    }

    switch(interfacePriv->interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            /* Add station record */
            status = peer_add_new_record(priv,req,&handle);
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
        default:
            /* No station record to maintain in these modes */
            break;
    }

    CsrWifiRouterCtrlPeerAddCfmSend(msg->source,req->clientData,req->interfaceTag,req->peerMacAddress,handle,status);
    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerAddReqHandler \n");
}

void CsrWifiRouterCtrlPeerUpdateReqHandler(void* drvpriv,CsrWifiFsmEvent* msg)
{
    CsrWifiRouterCtrlPeerUpdateReq* req = (CsrWifiRouterCtrlPeerUpdateReq*)msg;
    CsrResult status = CSR_RESULT_SUCCESS;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;

    unifi_trace(priv, UDBG2, "entering CsrWifiRouterCtrlPeerUpdateReqHandler \n");
    if (priv == NULL)
    {
        unifi_error(priv, "CsrWifiRouterCtrlPeerUpdateReqHandler: invalid smepriv\n");
        return;
    }

    CsrWifiRouterCtrlPeerUpdateCfmSend(msg->source,req->clientData,req->interfaceTag,status);
    unifi_trace(priv, UDBG2, "leaving CsrWifiRouterCtrlPeerUpdateReqHandler \n");
}


 void CsrWifiRouterCtrlRawSdioDeinitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    /* This will never be called as it is intercepted in the Userspace */
}

void CsrWifiRouterCtrlRawSdioInitialiseReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    /* This will never be called as it is intercepted in the Userspace */
}

void
uf_send_ba_err_wq(struct work_struct *work)
{
    ba_session_rx_struct *ba_session = container_of(work, ba_session_rx_struct, send_ba_err_task);
    unifi_priv_t *priv;

    if(!ba_session) {
        return;
    }

    if(!ba_session->interfacePriv) {
        return;
    }

    priv = ba_session->interfacePriv->privPtr;

    if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
        return;
    }

    unifi_warning(priv, "%s: Calling CsrWifiRouterCtrlBlockAckErrorIndSend(%d, %d, %d, %d, %x:%x:%x:%x:%x:%x, %d)\n",
                    __FUNCTION__,
                    priv->CSR_WIFI_SME_IFACEQUEUE,
                    0,
                    ba_session->interfacePriv->InterfaceTag,
                    ba_session->tID,
                    ba_session->macAddress.a[0],
                    ba_session->macAddress.a[1],
                    ba_session->macAddress.a[2],
                    ba_session->macAddress.a[3],
                    ba_session->macAddress.a[4],
                    ba_session->macAddress.a[5],
                    CSR_RESULT_SUCCESS
                 );
    CsrWifiRouterCtrlBlockAckErrorIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
                    0,
                    ba_session->interfacePriv->InterfaceTag,
                    ba_session->tID,
                    ba_session->macAddress,
                    CSR_RESULT_SUCCESS);
}


static void ba_session_terminate_timer_func(unsigned long data)
{
    ba_session_rx_struct *ba_session = (ba_session_rx_struct*)data;
    struct unifi_priv *priv;

    if(!ba_session) {
        return;
    }

    if(!ba_session->interfacePriv) {
        return;
    }

    priv = ba_session->interfacePriv->privPtr;

    if (ba_session->interfacePriv->InterfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "%s: invalid interfaceTag\n", __FUNCTION__);
        return;
    }

    queue_work(priv->unifi_workqueue, &ba_session->send_ba_err_task);
}


u8 blockack_session_stop(unifi_priv_t *priv,
                                     u16 interfaceTag,
                                     CsrWifiRouterCtrlBlockAckRole role,
                                     u16 tID,
                                     CsrWifiMacAddress macAddress)
{
    netInterface_priv_t *interfacePriv;
    ba_session_rx_struct *ba_session_rx = NULL;
    ba_session_tx_struct *ba_session_tx = NULL;
    u8 ba_session_idx = 0;
    int i;

    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
        return FALSE;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    if(!interfacePriv) {
        unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
        return FALSE;
    }

    if(tID > 15) {
        unifi_error(priv, "%s: bad tID = %d\n", __FUNCTION__, tID);
        return FALSE;
    }

    if((role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR) &&
        (role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT)) {
        unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
        return FALSE;
        }

	unifi_warning(priv,
		"%s: stopping ba_session for peer = %pM role = %d tID = %d\n",
		__func__, macAddress.a, role, tID);

    /* find out the appropriate ba session (/station /tid /role) for which stop is requested */
    if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){
        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){

            ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];

            if(ba_session_rx){
                if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
                    break;
                }
            }
        }

        if (!ba_session_rx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX)) {
            unifi_error(priv, "%s: bad ba_session for Rx [tID=%d]\n", __FUNCTION__, tID);
            return FALSE;
        }


        if(ba_session_rx->timeout) {
            del_timer_sync(&ba_session_rx->timer);
        }
        cancel_work_sync(&ba_session_rx->send_ba_err_task);
        for (i = 0; i < ba_session_rx->wind_size; i++) {
            if(ba_session_rx->buffer[i].active) {
                frame_desc_struct *frame_desc = &ba_session_rx->buffer[i];
                unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
            }
        }
        kfree(ba_session_rx->buffer);

        interfacePriv->ba_session_rx[ba_session_idx] = NULL;
        kfree(ba_session_rx);
    }else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
        ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
            if(ba_session_tx){
                if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
                    break;
                }
            }
        }

        if (!ba_session_tx || (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX)) {
            unifi_error(priv, "%s: bad ba_session for Tx [tID=%d]\n", __FUNCTION__, tID);
            return FALSE;
        }
        interfacePriv->ba_session_tx[ba_session_idx] = NULL;
        kfree(ba_session_tx);

    }

    return TRUE;
}


void CsrWifiRouterCtrlBlockAckDisableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    CsrWifiRouterCtrlBlockAckDisableReq* req = (CsrWifiRouterCtrlBlockAckDisableReq*)msg;
    u8 r;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;

    unifi_trace(priv, UDBG6, "%s: in ok\n", __FUNCTION__);

    down(&priv->ba_mutex);
    r = blockack_session_stop(priv,
                              req->interfaceTag,
                              req->role,
                              req->trafficStreamID,
                              req->macAddress);
    up(&priv->ba_mutex);

    CsrWifiRouterCtrlBlockAckDisableCfmSend(msg->source,
                                            req->clientData,
                                            req->interfaceTag,
                                            r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);

    unifi_trace(priv, UDBG6, "%s: out ok\n", __FUNCTION__);
}


u8 blockack_session_start(unifi_priv_t *priv,
                               u16 interfaceTag,
                               u16 tID,
                               u16 timeout,
                               CsrWifiRouterCtrlBlockAckRole role,
                               u16 wind_size,
                               u16 start_sn,
                               CsrWifiMacAddress macAddress
                              )
{
    netInterface_priv_t *interfacePriv;
    ba_session_rx_struct *ba_session_rx = NULL;
    ba_session_tx_struct *ba_session_tx = NULL;
    u8 ba_session_idx = 0;


    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
        unifi_error(priv, "%s: bad interfaceTag = %d\n", __FUNCTION__, interfaceTag);
        return FALSE;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    if(!interfacePriv) {
        unifi_error(priv, "%s: bad interfacePriv\n", __FUNCTION__);
        return FALSE;
    }

    if(tID > 15)
    {
        unifi_error(priv, "%s: bad tID=%d\n", __FUNCTION__, tID);
        return FALSE;
    }

    if(wind_size > MAX_BA_WIND_SIZE) {
        unifi_error(priv, "%s: bad wind_size = %d\n", __FUNCTION__, wind_size);
        return FALSE;
    }

    if(role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR &&
       role != CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT) {
        unifi_error(priv, "%s: bad role = %d\n", __FUNCTION__, role);
        return FALSE;
    }

	unifi_warning(priv,
		"%s: ba session with peer= (%pM)\n", __func__,
		macAddress.a);

    unifi_warning(priv, "%s: ba session for tID=%d timeout=%d role=%d wind_size=%d start_sn=%d\n", __FUNCTION__,
                  tID,
                  timeout,
                  role,
                  wind_size,
                  start_sn);

    /* Check if BA session exists for per station, per TID, per role or not.
    if BA session exists update parameters and if it does not exist
    create a new BA session */
    if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_ORIGINATOR){
        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
            ba_session_tx = interfacePriv->ba_session_tx[ba_session_idx];
            if (ba_session_tx) {
                if ((!memcmp(ba_session_tx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_tx->tID == tID)){
                    unifi_warning(priv, "%s: ba_session for Tx already exists\n", __FUNCTION__);
                    return TRUE;
                }
            }
        }

        /* we have to create new ba_session_tx struct */
         ba_session_tx = NULL;

        /* loop through until an empty BA session slot is there and save the session there */
        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX ; ba_session_idx++){
            if (!(interfacePriv->ba_session_tx[ba_session_idx])){
                break;
            }
        }
        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_TX){
            unifi_error(priv, "%s: All ba_session used for Tx, NO free session available\n", __FUNCTION__);
            return FALSE;
        }

        /* create and populate the new BA session structure */
        ba_session_tx = kzalloc(sizeof(ba_session_tx_struct), GFP_KERNEL);
        if (!ba_session_tx) {
            unifi_error(priv, "%s: kmalloc failed for ba_session_tx\n", __FUNCTION__);
            return FALSE;
        }

        ba_session_tx->interfacePriv = interfacePriv;
        ba_session_tx->tID = tID;
        ba_session_tx->macAddress = macAddress;

        interfacePriv->ba_session_tx[ba_session_idx] = ba_session_tx;

    } else if (role == CSR_WIFI_ROUTER_CTRL_BLOCK_ACK_RECIPIENT){

        for (ba_session_idx =0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
            ba_session_rx = interfacePriv->ba_session_rx[ba_session_idx];
            if (ba_session_rx) {
                if ((!memcmp(ba_session_rx->macAddress.a, macAddress.a, ETH_ALEN)) && (ba_session_rx->tID == tID)){
                    unifi_warning(priv, "%s: ba_session for Rx[tID = %d] already exists\n", __FUNCTION__, tID);

                    if(ba_session_rx->wind_size == wind_size &&
                        ba_session_rx->timeout == timeout &&
                        ba_session_rx->expected_sn == start_sn) {
                        return TRUE;
                    }

                    if(ba_session_rx->timeout) {
                        del_timer_sync(&ba_session_rx->timer);
                        ba_session_rx->timeout = 0;
                    }

                    if(ba_session_rx->wind_size != wind_size) {
                        blockack_session_stop(priv, interfaceTag, role, tID, macAddress);
                    } else {
                        if (timeout) {
                            ba_session_rx->timeout = timeout;
                            ba_session_rx->timer.function = ba_session_terminate_timer_func;
                            ba_session_rx->timer.data = (unsigned long)ba_session_rx;
                            init_timer(&ba_session_rx->timer);
                            mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
                        }
                        /*
                         * The starting sequence number shall remain same if the BA
                         * enable request is issued to update BA parameters only. If
                         * it is not same, then we scroll our window to the new starting
                         * sequence number. This could happen if the DELBA frame from
                         * originator is lost and then we receive ADDBA frame with new SSN.
                        */
                        if(ba_session_rx->start_sn != start_sn) {
                            scroll_ba_window(priv, interfacePriv, ba_session_rx, start_sn);
                        }
                        return TRUE;
                    }
                }
            }
        }

        /* we could have a valid BA session pointer here or un-initialized
        ba session pointer. but in any case we have to create a new session.
        so re-initialize the ba_session pointer */
        ba_session_rx = NULL;

        /* loop through until an empty BA session slot is there and save the session there */
        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX ; ba_session_idx++){
            if (!(interfacePriv->ba_session_rx[ba_session_idx])){
                break;
            }
        }
        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
            unifi_error(priv, "%s: All ba_session used for Rx, NO free session available\n", __FUNCTION__);
            return FALSE;
        }

        /* It is observed that with some devices there is a race between
         * EAPOL exchanges and BA session establishment. This results in
         * some EAPOL authentication packets getting stuck in BA reorder
         * buffer and hence the conection cannot be established. To avoid
         * this we check here if the EAPOL authentication is complete and
         * if so then only allow the BA session to establish.
         *
         * It is verified that the peers normally re-establish
         * the BA session after the initial rejection.
         */
        if (CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN != uf_sme_port_state(priv, macAddress.a, UF_CONTROLLED_PORT_Q, interfacePriv->InterfaceTag))
        {
            unifi_warning(priv, "blockack_session_start: Controlled port not opened, Reject BA request\n");
            return FALSE;
        }

        ba_session_rx = kzalloc(sizeof(ba_session_rx_struct), GFP_KERNEL);
        if (!ba_session_rx) {
            unifi_error(priv, "%s: kmalloc failed for ba_session_rx\n", __FUNCTION__);
            return FALSE;
        }

        ba_session_rx->wind_size = wind_size;
        ba_session_rx->start_sn = ba_session_rx->expected_sn = start_sn;
        ba_session_rx->trigger_ba_after_ssn = FALSE;

        ba_session_rx->buffer = kzalloc(ba_session_rx->wind_size*sizeof(frame_desc_struct), GFP_KERNEL);
        if (!ba_session_rx->buffer) {
            kfree(ba_session_rx);
            unifi_error(priv, "%s: kmalloc failed for buffer\n", __FUNCTION__);
            return FALSE;
        }

        INIT_WORK(&ba_session_rx->send_ba_err_task, uf_send_ba_err_wq);
        if (timeout) {
            ba_session_rx->timeout = timeout;
            ba_session_rx->timer.function = ba_session_terminate_timer_func;
            ba_session_rx->timer.data = (unsigned long)ba_session_rx;
            init_timer(&ba_session_rx->timer);
            mod_timer(&ba_session_rx->timer, (jiffies + usecs_to_jiffies((ba_session_rx->timeout) * 1024)));
        }

        ba_session_rx->interfacePriv = interfacePriv;
        ba_session_rx->tID = tID;
        ba_session_rx->macAddress = macAddress;

        interfacePriv->ba_session_rx[ba_session_idx] = ba_session_rx;
    }
    return TRUE;
}

void CsrWifiRouterCtrlBlockAckEnableReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
    CsrWifiRouterCtrlBlockAckEnableReq* req = (CsrWifiRouterCtrlBlockAckEnableReq*)msg;
    u8 r;
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;

    unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);
    down(&priv->ba_mutex);
    r = blockack_session_start(priv,
                               req->interfaceTag,
                               req->trafficStreamID,
                               req->timeout,
                               req->role,
                               req->bufferSize,
                               req->ssn,
                               req->macAddress
                              );
    up(&priv->ba_mutex);

    CsrWifiRouterCtrlBlockAckEnableCfmSend(msg->source,
                                           req->clientData,
                                           req->interfaceTag,
                                           r?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE);
    unifi_trace(priv, UDBG6, "<<%s: r=%d\n", __FUNCTION__, r);

}

void CsrWifiRouterCtrlWapiMulticastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE

    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWapiMulticastFilterReq* req = (CsrWifiRouterCtrlWapiMulticastFilterReq*)msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);

        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiMulticastFilterReq: req->status = %d\n", req->status);

        /* status 1 - Filter on
        * status 0 - Filter off */
        priv->wapi_multicast_filter = req->status;

        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
    } else {

    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);

    }
#elif defined(UNIFI_DEBUG)
    /*WAPI Disabled*/
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    unifi_error(priv,"CsrWifiRouterCtrlWapiMulticastFilterReqHandler: called when WAPI isn't enabled\n");
#endif
}

void CsrWifiRouterCtrlWapiUnicastFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE

    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWapiUnicastFilterReq* req = (CsrWifiRouterCtrlWapiUnicastFilterReq*)msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);

        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastFilterReq: req->status= %d\n", req->status);

        if ((priv->wapi_unicast_filter == 1) && (req->status == 0)) {
            /* When we have successfully re-associated and obtained a new unicast key with keyid = 0 */
            priv->wapi_unicast_queued_pkt_filter = 1;
        }

        /* status 1 - Filter ON
         * status 0 - Filter OFF */
        priv->wapi_unicast_filter = req->status;

        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
    } else {

    	 unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);

    }
#elif defined(UNIFI_DEBUG)
    /*WAPI Disabled*/
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastFilterReqHandler: called when WAPI isn't enabled\n");
#endif
}

void CsrWifiRouterCtrlWapiRxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE

    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWapiRxPktReq* req =  (CsrWifiRouterCtrlWapiRxPktReq*)msg;
    int client_id, receiver_id;
    bulk_data_param_t bulkdata;
    CsrResult res;
    ul_client_t *client;
    CSR_SIGNAL signal;
    CSR_MA_PACKET_INDICATION *pkt_ind;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

    	unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);

        if (priv == NULL) {
            unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid priv\n",__FUNCTION__);
            return;
        }

        if (priv->smepriv == NULL) {
             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq : invalid sme priv\n",__FUNCTION__);
             return;
        }

        if (req->dataLength == 0 || req->data == NULL) {
             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: invalid request\n",__FUNCTION__);
             return;
        }

        res = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
        if (res != CSR_RESULT_SUCCESS) {
             unifi_error(priv, "CsrWifiRouterCtrlWapiRxPktReq: Could not allocate net data\n",__FUNCTION__);
             return;
        }

        /* This function is expected to be called only when the MIC has been verified by SME to be correct
         * So reset the reception status to rx_success */
        res = read_unpack_signal(req->signal, &signal);
        if (res) {
	          unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Received unknown or corrupted signal.\n");
	          return;
        }
        pkt_ind = (CSR_MA_PACKET_INDICATION*) (&((&signal)->u).MaPacketIndication);
        if (pkt_ind->ReceptionStatus != CSR_MICHAEL_MIC_ERROR) {
	          unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: Unknown signal with reception status = %d\n",pkt_ind->ReceptionStatus);
	          return;
        } else {
	          unifi_trace(priv, UDBG4,"CsrWifiRouterCtrlWapiRxPktReqHandler: MIC verified , RX_SUCCESS \n",__FUNCTION__);
	          pkt_ind->ReceptionStatus = CSR_RX_SUCCESS;
	          write_pack(&signal, req->signal, &(req->signalLength));
        }

        memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);

        receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((req->signal) + sizeof(s16)) & 0xFFF0;
        client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;

        client = &priv->ul_clients[client_id];

        if (client && client->event_hook) {
              unifi_trace(priv, UDBG3,
                          "CsrWifiRouterCtrlWapiRxPktReq: "
                          "Sending signal to client %d, (s:0x%X, r:0x%X) - Signal 0x%X \n",
                          client->client_id, client->sender_id, receiver_id,
                          CSR_GET_UINT16_FROM_LITTLE_ENDIAN(req->signal));

              client->event_hook(client, req->signal, req->signalLength, &bulkdata, UDI_TO_HOST);
        } else {
              unifi_trace(priv, UDBG4, "No client to give the packet to\n");
              unifi_net_data_free(priv, &bulkdata.d[0]);
        }

        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
    } else {
    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);
    }
#elif defined(UNIFI_DEBUG)
    /*WAPI Disabled*/
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    unifi_error(priv,"CsrWifiRouterCtrlWapiRxPktReqHandler: called when WAPI isn't enabled\n");
#endif
}

void CsrWifiRouterCtrlWapiUnicastTxPktReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))

	unifi_priv_t *priv = (unifi_priv_t*) drvpriv;
    CsrWifiRouterCtrlWapiUnicastTxPktReq *req 	= (CsrWifiRouterCtrlWapiUnicastTxPktReq*) msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];
    bulk_data_param_t bulkdata;
    u8 macHeaderLengthInBytes = MAC_HEADER_SIZE;
    /*KeyID, Reserved, PN, MIC*/
    u8 appendedCryptoFields = 1 + 1 + 16 + 16;
    CsrResult result;
    /* Retrieve the MA PACKET REQ fields from the Signal retained from send_ma_pkt_request() */
    CSR_MA_PACKET_REQUEST *storedSignalMAPktReq = &interfacePriv->wapi_unicast_ma_pkt_sig.u.MaPacketRequest;

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);

        if (priv == NULL) {
            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid priv\n",__FUNCTION__);
            return;
        }
        if (priv->smepriv == NULL) {
            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler : invalid sme priv\n",__FUNCTION__);
            return;
        }
        if (req->data == NULL) {
            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid request\n",__FUNCTION__);
            return;
        } else {
            /* If it is QoS data (type = data subtype = QoS), frame header contains QoS control field */
            if ((req->data[0] & 0x88) == 0x88) {
      	        macHeaderLengthInBytes  = macHeaderLengthInBytes + QOS_CONTROL_HEADER_SIZE;
            }
        }
        if ( !(req->dataLength>(macHeaderLengthInBytes+appendedCryptoFields)) ) {
            unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: invalid dataLength\n",__FUNCTION__);
            return;
        }

	    /* Encrypted DATA Packet contained in (req->data)
         * -------------------------------------------------------------------
         * |MAC Header|  KeyId   | Reserved |    PN    | xxDataxx | xxMICxxx |
         * -------------------------------------------------------------------
         *                                             (<-----Encrypted----->)
         * -------------------------------------------------------------------
         * |24/26(QoS)|    1     |    1     |    16    |    x     |    16    |
         * -------------------------------------------------------------------
         */
        result = unifi_net_data_malloc(priv, &bulkdata.d[0], req->dataLength);
        if (result != CSR_RESULT_SUCCESS) {
             unifi_error(priv, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: Could not allocate net data\n",__FUNCTION__);
             return;
        }
        memcpy((void*)bulkdata.d[0].os_data_ptr, req->data, req->dataLength);
        bulkdata.d[0].data_length = req->dataLength;
        bulkdata.d[1].os_data_ptr = NULL;
        bulkdata.d[1].data_length = 0;

        /* Send UniFi msg */
        /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
        result = uf_process_ma_packet_req(priv,
    	                                  storedSignalMAPktReq->Ra.x,
                                          storedSignalMAPktReq->HostTag,/* Ask for a new HostTag */
                                          req->interfaceTag,
                                          storedSignalMAPktReq->TransmissionControl,
                                          storedSignalMAPktReq->TransmitRate,
                                          storedSignalMAPktReq->Priority, /* Retained value */
                                          interfacePriv->wapi_unicast_ma_pkt_sig.SignalPrimitiveHeader.SenderProcessId, /*FIXME AP: VALIDATE ???*/
                                          &bulkdata);

        if (result == NETDEV_TX_OK) {
             (priv->netdev[req->interfaceTag])->trans_start = jiffies;
             /* Should really count tx stats in the UNITDATA.status signal but
              * that doesn't have the length.
              */
             interfacePriv->stats.tx_packets++;

             /* count only the packet payload */
             interfacePriv->stats.tx_bytes += req->dataLength - macHeaderLengthInBytes - appendedCryptoFields;
             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Sent), sent count = %x\n", interfacePriv->stats.tx_packets);
        } else {
             /* Failed to send: fh queue was full, and the skb was discarded*/
             unifi_trace(priv, UDBG1, "(HIP validation failure) Result = %d\n", result);
             unifi_net_data_free(priv, &bulkdata.d[0]);

             interfacePriv->stats.tx_dropped++;
             unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
        }

        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);

    } else {

    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);

    }
#elif defined(UNIFI_DEBUG)
    /*WAPI Disabled*/
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    unifi_error(priv,"CsrWifiRouterCtrlWapiUnicastTxPktReqHandler: called when WAPI SW ENCRYPTION isn't enabled\n");
#endif
}

void CsrWifiRouterCtrlWapiFilterReqHandler(void* drvpriv, CsrWifiFsmEvent* msg)
{
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE

#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    CsrWifiRouterCtrlWapiFilterReq* req = (CsrWifiRouterCtrlWapiFilterReq*)msg;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

        unifi_trace(priv, UDBG6, ">>%s\n", __FUNCTION__);

        unifi_trace(priv, UDBG1, "CsrWifiRouterCtrlWapiFilterReq: req->isWapiConnected [0/1] = %d \n",req->isWapiConnected);

        priv->isWapiConnection = req->isWapiConnected;

        unifi_trace(priv, UDBG6, "<<%s\n", __FUNCTION__);
    } else {

    	unifi_warning(priv, "%s is NOT applicable for interface mode - %d\n", __FUNCTION__,interfacePriv->interfaceMode);

    }
#endif

#elif defined(UNIFI_DEBUG)
    /*WAPI Disabled*/
    unifi_priv_t *priv = (unifi_priv_t*)drvpriv;
    unifi_error(priv,"CsrWifiRouterCtrlWapiFilterReq: called when WAPI isn't enabled\n");
#endif
}
