/*
 * ---------------------------------------------------------------------------
 * 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;

    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;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];

    /* 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;

    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;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];
    /* 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;

    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;
    }

    interfacePriv = priv->interfacePriv[req->interfaceTag];

    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;

    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;
    }

    interfacePriv = priv->interfacePriv[req->interfaceTag];

    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;

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

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

    interfacePriv = priv->interfacePriv[req->interfaceTag];

    if (CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) {

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


        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
}
