/*
 * ***************************************************************************
 *  FILE:     unifi_event.c
 *
 *  PURPOSE:
 *      Process the signals received by UniFi.
 *      It is part of the porting exercise.
 *
 * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ***************************************************************************
 */


/*
 * Porting notes:
 * The implementation of unifi_receive_event() in Linux is fairly complicated.
 * The linux driver support multiple userspace applications and several
 * build configurations, so the received signals are processed by different
 * processes and multiple times.
 * In a simple implementation, this function needs to deliver:
 * - The MLME-UNITDATA.ind signals to the Rx data plane and to the Traffic
 *   Analysis using unifi_ta_sample().
 * - The MLME-UNITDATA-STATUS.ind signals to the Tx data plane.
 * - All the other signals to the SME using unifi_sys_hip_ind().
 */

#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "unifi_priv.h"


/*
 * ---------------------------------------------------------------------------
 *  send_to_client
 *
 *      Helper for unifi_receive_event.
 *
 *      This function forwards a signal to one client.
 *
 *  Arguments:
 *      priv        Pointer to driver's private data.
 *      client      Pointer to the client structure.
 *      receiver_id The reciever id of the signal.
 *      sigdata     Pointer to the packed signal buffer.
 *      siglen      Length of the packed signal.
 *      bulkdata    Pointer to the signal's bulk data.
 *
 *  Returns:
 *      None.
 *
 * ---------------------------------------------------------------------------
 */
static void send_to_client(unifi_priv_t *priv, ul_client_t *client,
        int receiver_id,
        unsigned char *sigdata, int siglen,
        const bulk_data_param_t *bulkdata)
{
    if (client && client->event_hook) {
        /*unifi_trace(priv, UDBG3,
                "Receive: client %d, (s:0x%X, r:0x%X) - Signal 0x%.4X \n",
                client->client_id, client->sender_id, receiver_id,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));*/

        client->event_hook(client, sigdata, siglen, bulkdata, UDI_TO_HOST);
    }
}

/*
 * ---------------------------------------------------------------------------
 *  process_pkt_data_ind
 *
 *      Dispatcher for received signals.
 *
 *      This function receives the 'to host' signals and forwards
 *      them to the unifi linux clients.
 *
 *  Arguments:
 *      priv         Context
 *      sigdata      Pointer to the packed signal buffer(Its in form of MA-PACKET.ind).
 *      bulkdata     Pointer to signal's bulkdata
 *      freeBulkData Pointer to a flag which gets set if the bulkdata needs to
 *                   be freed after calling the logging handlers. If it is not
 *                   set the bulkdata must be freed by the MLME handler or
 *                   passed to the network stack.
 *  Returns:
 *      TRUE if the packet should be routed to the SME etc.
 *      FALSE if the packet is for the driver or network stack
 * ---------------------------------------------------------------------------
 */
static u8 check_routing_pkt_data_ind(unifi_priv_t *priv,
        u8 *sigdata,
        const bulk_data_param_t* bulkdata,
        u8 *freeBulkData,
        netInterface_priv_t *interfacePriv)
{
    u16  frmCtrl, receptionStatus, frmCtrlSubType;
    u8 *macHdrLocation;
    u8 interfaceTag;
    u8 isDataFrame;
    u8 isProtocolVerInvalid = FALSE;
    u8 isDataFrameSubTypeNoData = FALSE;

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    static const u8 wapiProtocolIdSNAPHeader[] = {0x88,0xb4};
    static const u8 wapiProtocolIdSNAPHeaderOffset = 6;
    u8 *destAddr;
    u8 *srcAddr;
    u8 isWapiUnicastPkt = FALSE;

#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
    u16 qosControl;
#endif

    u8 llcSnapHeaderOffset = 0;

    destAddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
    srcAddr  = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;

    /*Individual/Group bit - Bit 0 of first byte*/
    isWapiUnicastPkt = (!(destAddr[0] & 0x01)) ? TRUE : FALSE;
#endif

#define CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET    sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22

    *freeBulkData = FALSE;

    /* Fetch the MAC header location from  MA_PKT_IND packet */
    macHdrLocation = (u8 *) bulkdata->d[0].os_data_ptr;
    /* Fetch the Frame Control value from  MAC header */
    frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);

    /* Pull out interface tag from virtual interface identifier */
    interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + 14)) & 0xff;

    /* check for MIC failure before processing the signal */
    receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET);

    /* To discard any spurious MIC failures that could be reported by the firmware */
    isDataFrame = ((frmCtrl & IEEE80211_FC_TYPE_MASK) == (IEEE802_11_FC_TYPE_DATA & IEEE80211_FC_TYPE_MASK)) ? TRUE : FALSE;
    /* 0x00 is the only valid protocol version*/
    isProtocolVerInvalid = (frmCtrl & IEEE80211_FC_PROTO_VERSION_MASK) ? TRUE : FALSE;
    frmCtrlSubType = (frmCtrl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET;
    /*Exclude the no data & reserved sub-types from MIC failure processing*/
    isDataFrameSubTypeNoData = (((frmCtrlSubType>0x03)&&(frmCtrlSubType<0x08)) || (frmCtrlSubType>0x0B)) ? TRUE : FALSE;
    if ((receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
        ((!isDataFrame) || isProtocolVerInvalid || (isDataFrame && isDataFrameSubTypeNoData))) {
        /* Currently MIC errors are discarded for frames other than data frames. This might need changing when we start
         * supporting 802.11w (Protected Management frames)
         */
        *freeBulkData = TRUE;
        unifi_trace(priv, UDBG4, "Discarding this frame and ignoring the MIC failure as this is a garbage/non-data/no data frame\n");
        return FALSE;
     }

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE

    if (receptionStatus == CSR_MICHAEL_MIC_ERROR) {

        if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) {

#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
            if ((isDataFrame) &&
                ((IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK) == (frmCtrl & IEEE80211_FC_SUBTYPE_MASK)) &&
                (priv->isWapiConnection))
            {
            	qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation + (((frmCtrl & IEEE802_11_FC_TO_DS_MASK) && (frmCtrl & IEEE802_11_FC_FROM_DS_MASK)) ? 30 : 24) );

            	unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind() :: Value of the QoS control field - 0x%04x \n", qosControl);

                if (qosControl & IEEE802_11_QC_NON_TID_BITS_MASK)
                {
                	unifi_trace(priv, UDBG4, "Ignore the MIC failure and pass the MPDU to the stack when any of bits [4-15] is set in the QoS control field\n");

            		/*Exclude the MIC [16] and the PN [16] that are appended by the firmware*/
            		((bulk_data_param_t*)bulkdata)->d[0].data_length = bulkdata->d[0].data_length - 32;

            		/*Clear the reception status of the signal (CSR_RX_SUCCESS)*/
            		*(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET)     = 0x00;
            		*(sigdata + CSR_WIFI_MA_PKT_IND_RECEPTION_STATUS_OFFSET+1)   = 0x00;

            		*freeBulkData = FALSE;

            		return FALSE;
                }
            }
#endif
            /* If this MIC ERROR reported by the firmware is either for
             *    [1] a WAPI Multicast MPDU and the Multicast filter has NOT been set (It is set only when group key index (MSKID) = 1 in Group Rekeying)   OR
             *    [2] a WAPI Unicast MPDU and either the CONTROL PORT is open or the WAPI Unicast filter or filter(s) is NOT set
             * then report a MIC FAILURE indication to the SME.
             */
#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
    	if ((priv->wapi_multicast_filter == 0) || isWapiUnicastPkt) {
#else
        /*When SW encryption is enabled and USKID=1 (wapi_unicast_filter = 1), we are expected
		 *to receive MIC failure INDs for unicast MPDUs*/
    	if ( ((priv->wapi_multicast_filter == 0) && !isWapiUnicastPkt) ||
             ((priv->wapi_unicast_filter   == 0) &&  isWapiUnicastPkt) ) {
#endif
                /*Discard the frame*/
                *freeBulkData = TRUE;
                unifi_trace(priv, UDBG4, "Discarding the contents of the frame with MIC failure \n");

                if (isWapiUnicastPkt &&
                    ((uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag) != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN)||
#ifndef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
                    (priv->wapi_unicast_filter) ||
#endif
                    (priv->wapi_unicast_queued_pkt_filter))) {

                    /* Workaround to handle MIC failures reported by the firmware for encrypted packets from the AP
                     * while we are in the process of re-association induced by unsupported WAPI Unicast key index
                     *             - Discard the packets with MIC failures "until" we have
                     *               a. negotiated a key,
                     *               b. opened the CONTROL PORT and
                     *               c. the AP has started using the new key
                     */
                    unifi_trace(priv, UDBG4, "Ignoring the MIC failure as either a. CONTROL PORT isn't OPEN or b. Unicast filter is set or c. WAPI AP using old key for buffered pkts\n");

                    /*Ignore this MIC failure*/
                    return FALSE;

                }/*WAPI re-key specific workaround*/

                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
                            interfaceTag, srcAddr[0], srcAddr[1], srcAddr[2], srcAddr[3], srcAddr[4], srcAddr[5]);
                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Dest Addr %x:%x:%x:%x:%x:%x\n",
                            destAddr[0], destAddr[1], destAddr[2], destAddr[3], destAddr[4], destAddr[5]);
                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind - MIC FAILURE : Control Port State - 0x%.4X \n",
                            uf_sme_port_state(priv,srcAddr,UF_CONTROLLED_PORT_Q,interfaceTag));

                unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);

                /*Report the MIC failure to the SME*/
                return TRUE;
            }
        }/* STA mode */
        else {
            /* Its AP Mode . Just Return */
            *freeBulkData = TRUE;
            unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);
            return TRUE;
         } /* AP mode */
    }/* MIC error */
#else
    if (receptionStatus == CSR_MICHAEL_MIC_ERROR) {
        *freeBulkData = TRUE;
        unifi_error(priv, "MIC failure in %s\n", __FUNCTION__);
        return TRUE;
    }
#endif /*CSR_WIFI_SECURITY_WAPI_ENABLE*/

    unifi_trace(priv, UDBG4, "frmCtrl = 0x%04x %s\n",
                frmCtrl,
                (((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) == IEEE802_11_FRAMETYPE_MANAGEMENT) ?
                    "Mgt" : "Ctrl/Data");

#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
    /* To ignore MIC failures reported due to the WAPI AP using the old key for queued packets before
     * starting to use the new key negotiated as part of unicast re-keying
     */
    if ((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA)&&
        isWapiUnicastPkt &&
        (receptionStatus == CSR_RX_SUCCESS) &&
        (priv->wapi_unicast_queued_pkt_filter==1)) {

        unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI unicast pkt received when the (wapi_unicast_queued_pkt_filter) is set\n");

        if (isDataFrame) {
            switch(frmCtrl & IEEE80211_FC_SUBTYPE_MASK) {
                case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
                    llcSnapHeaderOffset = MAC_HEADER_SIZE + 2;
                    break;
                case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
                case IEEE802_11_FC_TYPE_NULL & IEEE80211_FC_SUBTYPE_MASK:
                    break;
                default:
                    llcSnapHeaderOffset = MAC_HEADER_SIZE;
            }
        }

        if (llcSnapHeaderOffset > 0) {
        	/* QoS data or Data */
            unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): SNAP header found & its offset %d\n",llcSnapHeaderOffset);
            if (memcmp((u8 *)(bulkdata->d[0].os_data_ptr+llcSnapHeaderOffset+wapiProtocolIdSNAPHeaderOffset),
                       wapiProtocolIdSNAPHeader,sizeof(wapiProtocolIdSNAPHeader))) {

            	unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): This is a data & NOT a WAI protocol packet\n");
                /* On the first unicast data pkt that is decrypted successfully after re-keying, reset the filter */
                priv->wapi_unicast_queued_pkt_filter = 0;
                unifi_trace(priv, UDBG4, "check_routing_pkt_data_ind(): WAPI AP has started using the new unicast key, no more MIC failures expected (reset filter)\n");
            }
            else {
                unifi_trace(priv, UDBG6, "check_routing_pkt_data_ind(): WAPI - This is a WAI protocol packet\n");
            }
        }
	}
#endif


    switch ((frmCtrl & 0x000c)>>FRAME_CONTROL_TYPE_FIELD_OFFSET) {
        case IEEE802_11_FRAMETYPE_MANAGEMENT:
            *freeBulkData = TRUE;       /* Free (after SME handler copies it) */

            /* In P2P device mode, filter the legacy AP beacons here */
            if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2P)&&\
               ((CSR_WIFI_80211_GET_FRAME_SUBTYPE(macHdrLocation)) == CSR_WIFI_80211_FRAME_SUBTYPE_BEACON)){

                u8 *pSsid, *pSsidLen;
                static u8 P2PWildCardSsid[CSR_WIFI_P2P_WILDCARD_SSID_LENGTH] = {'D', 'I', 'R', 'E', 'C', 'T', '-'};

                pSsidLen = macHdrLocation + MAC_HEADER_SIZE + CSR_WIFI_BEACON_FIXED_LENGTH;
                pSsid = pSsidLen + 2;

                if(*(pSsidLen + 1) >= CSR_WIFI_P2P_WILDCARD_SSID_LENGTH){
                    if(memcmp(pSsid, P2PWildCardSsid, CSR_WIFI_P2P_WILDCARD_SSID_LENGTH) == 0){
                        unifi_trace(priv, UDBG6, "Received a P2P Beacon, pass it to SME\n");
                        return TRUE;
                    }
                }
                unifi_trace(priv, UDBG6, "Received a Legacy AP beacon in P2P mode, drop it\n");
                return FALSE;
            }
            return TRUE;                /* Route to SME */
        case IEEE802_11_FRAMETYPE_DATA:
        case IEEE802_11_FRAMETYPE_CONTROL:
            *freeBulkData = FALSE;      /* Network stack or MLME handler frees */
            return FALSE;
        default:
            unifi_error(priv, "Unhandled frame type %04x\n", frmCtrl);
            *freeBulkData = TRUE;       /* Not interested, but must free it */
            return FALSE;
    }
}

/*
 * ---------------------------------------------------------------------------
 *  unifi_process_receive_event
 *
 *      Dispatcher for received signals.
 *
 *      This function receives the 'to host' signals and forwards
 *      them to the unifi linux clients.
 *
 *  Arguments:
 *      ospriv      Pointer to driver's private data.
 *      sigdata     Pointer to the packed signal buffer.
 *      siglen      Length of the packed signal.
 *      bulkdata    Pointer to the signal's bulk data.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 *  The signals are received in the format described in the host interface
 *  specification, i.e wire formatted. Certain clients use the same format
 *  to interpret them and other clients use the host formatted structures.
 *  Each client has to call read_unpack_signal() to transform the wire
 *  formatted signal into the host formatted signal, if necessary.
 *  The code is in the core, since the signals are defined therefore
 *  binded to the host interface specification.
 * ---------------------------------------------------------------------------
 */
static void
unifi_process_receive_event(void *ospriv,
                            u8 *sigdata, u32 siglen,
                            const bulk_data_param_t *bulkdata)
{
    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
    int i, receiver_id;
    int client_id;
    s16 signal_id;
    u8 pktIndToSme = FALSE, freeBulkData = FALSE;

    unifi_trace(priv, UDBG5, "unifi_process_receive_event: "
                "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*1) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*2) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*3) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*4) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*5) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*6) & 0xFFFF,
                CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*7) & 0xFFFF,
                siglen);

    receiver_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)) & 0xFF00;
    client_id = (receiver_id & 0x0F00) >> UDI_SENDER_ID_SHIFT;
    signal_id = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata);



    /* check for the type of frame received (checks for 802.11 management frames) */
    if (signal_id == CSR_MA_PACKET_INDICATION_ID)
    {
#define CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET    14
        u8 interfaceTag;
        netInterface_priv_t *interfacePriv;

        /* Pull out interface tag from virtual interface identifier */
        interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
        interfacePriv = priv->interfacePriv[interfaceTag];

        /* Update activity for this station in case of IBSS */
#ifdef CSR_SUPPORT_SME
        if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS)
        {
            u8 *saddr;
            /* Fetch the source address from  mac header */
            saddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR2_OFFSET;
            unifi_trace(priv, UDBG5,
                                    "Updating sta activity in IBSS interfaceTag %x Src Addr %x:%x:%x:%x:%x:%x\n",
                                    interfaceTag, saddr[0], saddr[1], saddr[2], saddr[3], saddr[4], saddr[5]);

            uf_update_sta_activity(priv, interfaceTag, saddr);
        }
#endif

        pktIndToSme = check_routing_pkt_data_ind(priv, sigdata, bulkdata, &freeBulkData, interfacePriv);

        unifi_trace(priv, UDBG6, "RX: packet entry point to driver from HIP,pkt to SME ?(%s) \n", (pktIndToSme)? "YES":"NO");

    }

    if (pktIndToSme)
    {
        /* Management MA_PACKET_IND for SME */
        if(sigdata != NULL && bulkdata != NULL){
            send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
        }
        else{
            unifi_error(priv, "unifi_receive_event2: sigdata or Bulkdata is NULL \n");
        }
#ifdef CSR_NATIVE_LINUX
        send_to_client(priv, priv->wext_client,
                receiver_id,
                sigdata, siglen, bulkdata);
#endif
    }
    else
    {
        /* Signals with ReceiverId==0 are also reported to SME / WEXT,
         * unless they are data/control MA_PACKET_INDs or VIF_AVAILABILITY_INDs
         */
        if (!receiver_id) {
               if(signal_id == CSR_MA_VIF_AVAILABILITY_INDICATION_ID) {
                      uf_process_ma_vif_availibility_ind(priv, sigdata, siglen);
               }
               else if (signal_id != CSR_MA_PACKET_INDICATION_ID) {
                      send_to_client(priv, priv->sme_cli, receiver_id, sigdata, siglen, bulkdata);
#ifdef CSR_NATIVE_LINUX
                      send_to_client(priv, priv->wext_client,
                                     receiver_id,
                                     sigdata, siglen, bulkdata);
#endif
               }
               else
               {

#if (defined(CSR_SUPPORT_SME) && defined(CSR_WIFI_SECURITY_WAPI_ENABLE))
                   #define CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET    sizeof(CSR_SIGNAL_PRIMITIVE_HEADER) + 22
                   netInterface_priv_t *interfacePriv;
                   u8 interfaceTag;
                   u16 receptionStatus = CSR_RX_SUCCESS;

                   /* Pull out interface tag from virtual interface identifier */
                   interfaceTag = (CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_INTERFACETAG_OFFSET)) & 0xff;
                   interfacePriv = priv->interfacePriv[interfaceTag];

                   /* check for MIC failure */
                   receptionStatus = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata + CSR_MA_PACKET_INDICATION_RECEPTION_STATUS_OFFSET);

                   /* Send a WAPI MPDU to SME for re-check MIC if the respective filter has been set*/
                   if ((!freeBulkData) &&
                       (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) &&
                       (receptionStatus == CSR_MICHAEL_MIC_ERROR) &&
                       ((priv->wapi_multicast_filter == 1)
#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
                         || (priv->wapi_unicast_filter == 1)
#endif
                       ))
                   {
                       CSR_SIGNAL signal;
                       u8 *destAddr;
                       CsrResult res;
                       u16 interfaceTag = 0;
                       u8 isMcastPkt = TRUE;

                       unifi_trace(priv, UDBG6, "Received a WAPI data packet when the Unicast/Multicast filter is set\n");
                       res = read_unpack_signal(sigdata, &signal);
                       if (res) {
                           unifi_error(priv, "Received unknown or corrupted signal (0x%x).\n",
                                       CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
                           return;
                       }

                       /* Check if the type of MPDU and the respective filter status*/
                       destAddr = (u8 *) bulkdata->d[0].os_data_ptr + MAC_HEADER_ADDR1_OFFSET;
                       isMcastPkt = (destAddr[0] & 0x01) ? TRUE : FALSE;
                       unifi_trace(priv, UDBG6,
                                   "1.MPDU type: (%s), 2.Multicast filter: (%s), 3. Unicast filter: (%s)\n",
                                   ((isMcastPkt) ? "Multiast":"Unicast"),
                                   ((priv->wapi_multicast_filter) ? "Enabled":"Disabled"),
                                   ((priv->wapi_unicast_filter)  ? "Enabled":"Disabled"));

                       if (((isMcastPkt) && (priv->wapi_multicast_filter == 1))
#ifdef CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION
                           || ((!isMcastPkt) && (priv->wapi_unicast_filter == 1))
#endif
                          )
                        {
                            unifi_trace(priv, UDBG4, "Sending the WAPI MPDU for MIC check\n");
                            CsrWifiRouterCtrlWapiRxMicCheckIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, siglen, sigdata, bulkdata->d[0].data_length, (u8*)bulkdata->d[0].os_data_ptr);

                            for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
                                if (bulkdata->d[i].data_length != 0) {
                                    unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
                                }
                           }
                           return;
                       }
                   } /* CSR_MA_PACKET_INDICATION_ID */
#endif /*CSR_SUPPORT_SME && CSR_WIFI_SECURITY_WAPI_ENABLE*/
               }
        }

        /* calls the registered clients handler callback func.
         * netdev_mlme_event_handler is one of the registered handler used to route
         * data packet to network stack or AMP/EAPOL related data to SME
         *
         * The freeBulkData check ensures that, it has received a management frame and
         * the frame needs to be freed here. So not to be passed to netdev handler
         */
        if(!freeBulkData){
            if ((client_id < MAX_UDI_CLIENTS) &&
                    (&priv->ul_clients[client_id] != priv->logging_client)) {
            	unifi_trace(priv, UDBG6, "Call the registered clients handler callback func\n");
                send_to_client(priv, &priv->ul_clients[client_id],
                        receiver_id,
                        sigdata, siglen, bulkdata);
            }
        }
    }

    /*
     * Free bulk data buffers here unless it is a CSR_MA_PACKET_INDICATION
     */
    switch (signal_id)
    {
#ifdef UNIFI_SNIFF_ARPHRD
        case CSR_MA_SNIFFDATA_INDICATION_ID:
#endif
            break;

        case CSR_MA_PACKET_INDICATION_ID:
            if (!freeBulkData)
            {
                break;
            }
            /* FALLS THROUGH... */
        default:
            for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
                if (bulkdata->d[i].data_length != 0) {
                    unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
                }
            }
    }

} /* unifi_process_receive_event() */


#ifdef CSR_WIFI_RX_PATH_SPLIT
static u8 signal_buffer_is_full(unifi_priv_t* priv)
{
    return (((priv->rxSignalBuffer.writePointer + 1)% priv->rxSignalBuffer.size) == (priv->rxSignalBuffer.readPointer));
}

void unifi_rx_queue_flush(void *ospriv)
{
    unifi_priv_t *priv = (unifi_priv_t*)ospriv;

    unifi_trace(priv, UDBG4, "rx_wq_handler: RdPtr = %d WritePtr =  %d\n",
                priv->rxSignalBuffer.readPointer,priv->rxSignalBuffer.writePointer);
    if(priv != NULL) {
        u8 readPointer = priv->rxSignalBuffer.readPointer;
        while (readPointer != priv->rxSignalBuffer.writePointer)
        {
             rx_buff_struct_t *buf = &priv->rxSignalBuffer.rx_buff[readPointer];
             unifi_trace(priv, UDBG6, "rx_wq_handler: RdPtr = %d WritePtr =  %d\n",
                         readPointer,priv->rxSignalBuffer.writePointer);
             unifi_process_receive_event(priv, buf->bufptr, buf->sig_len, &buf->data_ptrs);
             readPointer ++;
             if(readPointer >= priv->rxSignalBuffer.size) {
                    readPointer = 0;
             }
        }
        priv->rxSignalBuffer.readPointer = readPointer;
    }
}

void rx_wq_handler(struct work_struct *work)
{
    unifi_priv_t *priv = container_of(work, unifi_priv_t, rx_work_struct);
    unifi_rx_queue_flush(priv);
}
#endif



/*
 * ---------------------------------------------------------------------------
 *  unifi_receive_event
 *
 *      Dispatcher for received signals.
 *
 *      This function receives the 'to host' signals and forwards
 *      them to the unifi linux clients.
 *
 *  Arguments:
 *      ospriv      Pointer to driver's private data.
 *      sigdata     Pointer to the packed signal buffer.
 *      siglen      Length of the packed signal.
 *      bulkdata    Pointer to the signal's bulk data.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 *  The signals are received in the format described in the host interface
 *  specification, i.e wire formatted. Certain clients use the same format
 *  to interpret them and other clients use the host formatted structures.
 *  Each client has to call read_unpack_signal() to transform the wire
 *  formatted signal into the host formatted signal, if necessary.
 *  The code is in the core, since the signals are defined therefore
 *  binded to the host interface specification.
 * ---------------------------------------------------------------------------
 */
void
unifi_receive_event(void *ospriv,
                    u8 *sigdata, u32 siglen,
                    const bulk_data_param_t *bulkdata)
{
#ifdef CSR_WIFI_RX_PATH_SPLIT
    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
    u8 writePointer;
    int i;
    rx_buff_struct_t * rx_buff;

    unifi_trace(priv, UDBG5, "unifi_receive_event: "
            "%04x %04x %04x %04x %04x %04x %04x %04x (%d)\n",
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*0) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*1) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*2) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*3) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*4) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*5) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*6) & 0xFFFF,
            CSR_GET_UINT16_FROM_LITTLE_ENDIAN((sigdata) + sizeof(s16)*7) & 0xFFFF, siglen);
    if(signal_buffer_is_full(priv)) {
        unifi_error(priv,"TO HOST signal queue FULL dropping the PDU\n");
        for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++) {
            if (bulkdata->d[i].data_length != 0) {
                unifi_net_data_free(priv, (void *)&bulkdata->d[i]);
            }
        }
        return;
    }
    writePointer = priv->rxSignalBuffer.writePointer;
    rx_buff = &priv->rxSignalBuffer.rx_buff[writePointer];
    memcpy(rx_buff->bufptr,sigdata,siglen);
    rx_buff->sig_len = siglen;
    rx_buff->data_ptrs = *bulkdata;
    writePointer++;
    if(writePointer >= priv->rxSignalBuffer.size) {
        writePointer =0;
    }
    unifi_trace(priv, UDBG4, "unifi_receive_event:writePtr = %d\n",priv->rxSignalBuffer.writePointer);
    priv->rxSignalBuffer.writePointer = writePointer;

#ifndef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
    queue_work(priv->rx_workqueue, &priv->rx_work_struct);
#endif

#else
    unifi_process_receive_event(ospriv, sigdata, siglen, bulkdata);
#endif
} /* unifi_receive_event() */

