/*
 * ---------------------------------------------------------------------------
 * FILE:     netdev.c
 *
 * PURPOSE:
 *      This file provides the upper edge interface to the linux netdevice
 *      and wireless extensions.
 *      It is part of the porting exercise.
 *
 * Copyright (C) 2005-2010 by Cambridge Silicon Radio Ltd.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 * ---------------------------------------------------------------------------
 */

/*
 * Porting Notes:
 * This file implements the data plane of the UniFi linux driver.
 *
 * All the Tx packets are passed to the HIP core lib, using the
 * unifi_send_signal() API. For EAPOL packets use the MLME-EAPOL.req
 * signal, for all other use the MLME-UNITDATA.req. The unifi_send_signal()
 * expects the wire-formatted (packed) signal. For convenience, in the OS
 * layer we only use the native (unpacked) signal structures. The HIP core lib
 * provides the write_pack() helper function to convert to the packed signal.
 * The packet is stored in the bulk data of the signal. We do not need to
 * allocate new memory to store the packet, because unifi_net_data_malloc()
 * is implemented to return a skb, which is the format of packet in Linux.
 * The HIP core lib frees the bulk data buffers, so we do not need to do
 * this in the OS layer.
 *
 * All the Rx packets are MLME-UNITDATA.ind signals, passed by the HIP core lib
 * in unifi_receive_event(). We do not need to allocate an skb and copy the
 * received packet because the HIP core lib has stored in memory allocated by
 * unifi_net_data_malloc(). Also, we can perform the 802.11 to Ethernet
 * translation in-place because we allocate the extra memory allocated in
 * unifi_net_data_malloc().
 *
 * If possible, the porting exercise should appropriately implement
 * unifi_net_data_malloc() and unifi_net_data_free() to save copies between
 * network and driver buffers.
 */

#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/mutex.h>
#include <linux/semaphore.h>
#include <linux/vmalloc.h>
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "unifi_priv.h"
#include <net/pkt_sched.h>


/* Wext handler is supported only if CSR_SUPPORT_WEXT is defined */
#ifdef CSR_SUPPORT_WEXT
extern struct iw_handler_def unifi_iw_handler_def;
#endif /* CSR_SUPPORT_WEXT */
static void check_ba_frame_age_timeout( unifi_priv_t *priv,
                                            netInterface_priv_t *interfacePriv,
                                            ba_session_rx_struct *ba_session);
static void process_ba_frame(unifi_priv_t *priv,
                             netInterface_priv_t *interfacePriv,
                             ba_session_rx_struct *ba_session,
                             frame_desc_struct *frame_desc);
static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv);
static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
static void process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata);
static int uf_net_open(struct net_device *dev);
static int uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int uf_net_stop(struct net_device *dev);
static struct net_device_stats *uf_net_get_stats(struct net_device *dev);
static u16 uf_net_select_queue(struct net_device *dev, struct sk_buff *skb);
static netdev_tx_t uf_net_xmit(struct sk_buff *skb, struct net_device *dev);
static void uf_set_multicast_list(struct net_device *dev);


typedef int (*tx_signal_handler)(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority);

#ifdef CONFIG_NET_SCHED
/*
 * Queueing Discipline Interface
 * Only used if kernel is configured with CONFIG_NET_SCHED
 */

/*
 * The driver uses the qdisc interface to buffer and control all
 * outgoing traffic. We create a root qdisc, register our qdisc operations
 * and later we create two subsidiary pfifo queues for the uncontrolled
 * and controlled ports.
 *
 * The network stack delivers all outgoing packets in our enqueue handler.
 * There, we classify the packet and decide whether to store it or drop it
 * (if the controlled port state is set to "discard").
 * If the packet is enqueued, the network stack call our dequeue handler.
 * There, we decide whether we can send the packet, delay it or drop it
 * (the controlled port configuration might have changed meanwhile).
 * If a packet is dequeued, then the network stack calls our hard_start_xmit
 * handler where finally we send the packet.
 *
 * If the hard_start_xmit handler fails to send the packet, we return
 * NETDEV_TX_BUSY and the network stack call our requeue handler where
 * we put the packet back in the same queue in came from.
 *
 */

struct uf_sched_data
{
    /* Traffic Classifier TBD */
    struct tcf_proto *filter_list;
    /* Our two queues */
    struct Qdisc *queues[UNIFI_TRAFFIC_Q_MAX];
};

struct uf_tx_packet_data {
    /* Queue the packet is stored in */
    unifi_TrafficQueue queue;
    /* QoS Priority determined when enqueing packet */
    CSR_PRIORITY priority;
    /* Debug */
    unsigned long host_tag;
};

#endif /* CONFIG_NET_SCHED */

static const struct net_device_ops uf_netdev_ops =
{
    .ndo_open = uf_net_open,
    .ndo_stop = uf_net_stop,
    .ndo_start_xmit = uf_net_xmit,
    .ndo_do_ioctl = uf_net_ioctl,
    .ndo_get_stats = uf_net_get_stats, /* called by /proc/net/dev */
    .ndo_set_rx_mode = uf_set_multicast_list,
    .ndo_select_queue = uf_net_select_queue,
};

static u8 oui_rfc1042[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
static u8 oui_8021h[P80211_OUI_LEN]   = { 0x00, 0x00, 0xf8 };


/* Callback for event logging to blocking clients */
static void netdev_mlme_event_handler(ul_client_t  *client,
                                      const u8 *sig_packed, int sig_len,
                                      const bulk_data_param_t *bulkdata,
                                      int dir);

#ifdef CSR_SUPPORT_WEXT
/* Declare netdev_notifier block which will contain the state change
 * handler callback function
 */
static struct notifier_block uf_netdev_notifier;
#endif

/*
 * ---------------------------------------------------------------------------
 *  uf_alloc_netdevice
 *
 *      Allocate memory for the net_device and device private structs
 *      for this interface.
 *      Fill in the fields, but don't register the interface yet.
 *      We need to configure the UniFi first.
 *
 *  Arguments:
 *      sdio_dev        Pointer to SDIO context handle to use for all
 *                      SDIO ops.
 *      bus_id          A small number indicating the SDIO card position on the
 *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
 *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
 *
 *  Returns:
 *      Pointer to device private struct.
 *
 *  Notes:
 *      The net_device and device private structs are allocated together
 *      and should be freed by freeing the net_device pointer.
 * ---------------------------------------------------------------------------
 */
unifi_priv_t *
uf_alloc_netdevice(CsrSdioFunction *sdio_dev, int bus_id)
{
    struct net_device *dev;
    unifi_priv_t *priv;
    netInterface_priv_t *interfacePriv;
#ifdef CSR_SUPPORT_WEXT
    int rc;
#endif
    unsigned char i; /* loop index */

    /*
     * Allocate netdevice struct, assign name template and
     * setup as an ethernet device.
     * The net_device and private structs are zeroed. Ether_setup() then
     * sets up ethernet handlers and values.
     * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
     * so use "eth*" (like other wireless extns drivers).
     */
    dev = alloc_etherdev_mq(sizeof(unifi_priv_t) + sizeof(netInterface_priv_t), UNIFI_TRAFFIC_Q_MAX);

    if (dev == NULL) {
        return NULL;
    }

    /* Set up back pointer from priv to netdev */
    interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    priv = (unifi_priv_t *)(interfacePriv + 1);
    interfacePriv->privPtr = priv;
    interfacePriv->InterfaceTag = 0;


    /* Initialize all supported netdev interface to be NULL */
    for(i=0; i<CSR_WIFI_NUM_INTERFACES; i++) {
        priv->netdev[i] = NULL;
        priv->interfacePriv[i] = NULL;
    }
    priv->netdev[0] = dev;
    priv->interfacePriv[0] = interfacePriv;

    /* Setup / override net_device fields */
    dev->netdev_ops = &uf_netdev_ops;

#ifdef CSR_SUPPORT_WEXT
    dev->wireless_handlers = &unifi_iw_handler_def;
#if IW_HANDLER_VERSION < 6
    dev->get_wireless_stats = unifi_get_wireless_stats;
#endif /* IW_HANDLER_VERSION */
#endif /* CSR_SUPPORT_WEXT */

    /* This gives us enough headroom to add the 802.11 header */
    dev->needed_headroom = 32;

    /* Use bus_id as instance number */
    priv->instance = bus_id;
    /* Store SDIO pointer to pass in the core */
    priv->sdio = sdio_dev;

    sdio_dev->driverData = (void*)priv;
    /* Consider UniFi to be uninitialised */
    priv->init_progress = UNIFI_INIT_NONE;

    priv->prev_queue = 0;

    /*
     * Initialise the clients structure array.
     * We do not need protection around ul_init_clients() because
     * the character device can not be used until uf_alloc_netdevice()
     * returns and Unifi_instances[bus_id]=priv is set, since unifi_open()
     * will return -ENODEV.
     */
    ul_init_clients(priv);

    /*
     * Register a new ul client to send the multicast list signals.
     * Note: priv->instance must be set before calling this.
     */
    priv->netdev_client = ul_register_client(priv,
            0,
            netdev_mlme_event_handler);
    if (priv->netdev_client == NULL) {
        unifi_error(priv,
                "Failed to register a unifi client for background netdev processing\n");
        free_netdev(priv->netdev[0]);
        return NULL;
    }
    unifi_trace(priv, UDBG2, "Netdev %p client (id:%d s:0x%X) is registered\n",
            dev, priv->netdev_client->client_id, priv->netdev_client->sender_id);

    priv->sta_wmm_capabilities = 0;

#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_SUPPORT_SME))
    priv->wapi_multicast_filter = 0;
    priv->wapi_unicast_filter = 0;
    priv->wapi_unicast_queued_pkt_filter = 0;
#ifdef CSR_WIFI_SECURITY_WAPI_QOSCTRL_MIC_WORKAROUND
    priv->isWapiConnection = FALSE;
#endif
#endif

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

#ifdef CSR_SUPPORT_SME
    priv->allPeerDozing = 0;
#endif
    /*
     * Initialise the OS private struct.
     */
    /*
     * Instead of deciding in advance to use 11bg or 11a, we could do a more
     * clever scan on both radios.
     */
    if (use_5g) {
        priv->if_index = CSR_INDEX_5G;
        unifi_info(priv, "Using the 802.11a radio\n");
    } else {
        priv->if_index = CSR_INDEX_2G4;
    }

    /* Initialise bh thread structure */
    priv->bh_thread.thread_task = NULL;
    priv->bh_thread.block_thread = 1;
    init_waitqueue_head(&priv->bh_thread.wakeup_q);
    priv->bh_thread.wakeup_flag = 0;
    sprintf(priv->bh_thread.name, "uf_bh_thread");

    /* reset the connected state for the interface */
    interfacePriv->connected = UnifiConnectedUnknown;  /* -1 unknown, 0 no, 1 yes */

#ifdef USE_DRIVER_LOCK
    sema_init(&priv->lock, 1);
#endif /* USE_DRIVER_LOCK */

    spin_lock_init(&priv->send_signal_lock);

    spin_lock_init(&priv->m4_lock);
    sema_init(&priv->ba_mutex, 1);

#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
    spin_lock_init(&priv->wapi_lock);
#endif

#ifdef CSR_SUPPORT_SME
    spin_lock_init(&priv->staRecord_lock);
    spin_lock_init(&priv->tx_q_lock);
#endif

    /* Create the Traffic Analysis workqueue */
    priv->unifi_workqueue = create_singlethread_workqueue("unifi_workq");
    if (priv->unifi_workqueue == NULL) {
        /* Deregister priv->netdev_client */
        ul_deregister_client(priv->netdev_client);
        free_netdev(priv->netdev[0]);
        return NULL;
    }

#ifdef CSR_SUPPORT_SME
    /* Create the Multicast Addresses list work structure */
    INIT_WORK(&priv->multicast_list_task, uf_multicast_list_wq);

    /* Create m4 buffering work structure */
    INIT_WORK(&interfacePriv->send_m4_ready_task, uf_send_m4_ready_wq);

#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
    /* Create work structure to buffer the WAPI data packets to be sent to SME for encryption */
    INIT_WORK(&interfacePriv->send_pkt_to_encrypt, uf_send_pkt_to_encrypt);
#endif
#endif

    priv->ref_count = 1;

    priv->amp_client = NULL;
    priv->coredump_mode = 0;
    priv->ptest_mode = 0;
    priv->wol_suspend = FALSE;
    INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
    INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);
    sema_init(&priv->rx_q_sem, 1);

#ifdef CSR_SUPPORT_WEXT
    interfacePriv->netdev_callback_registered = FALSE;
    interfacePriv->wait_netdev_change = FALSE;
    /* Register callback for netdevice state changes */
    if ((rc = register_netdevice_notifier(&uf_netdev_notifier)) == 0) {
        interfacePriv->netdev_callback_registered = TRUE;
    }
    else {
        unifi_warning(priv, "Failed to register netdevice notifier : %d %p\n", rc, dev);
    }
#endif /* CSR_SUPPORT_WEXT */

#ifdef CSR_WIFI_SPLIT_PATCH
    /* set it to some invalid value */
    priv->pending_mode_set.common.destination = 0xaaaa;
#endif

    return priv;
} /* uf_alloc_netdevice() */

/*
 *---------------------------------------------------------------------------
 *  uf_alloc_netdevice_for_other_interfaces
 *
 *      Allocate memory for the net_device and device private structs
 *      for this interface.
 *      Fill in the fields, but don't register the interface yet.
 *      We need to configure the UniFi first.
 *
 *  Arguments:
 *      interfaceTag   Interface number.
 *      sdio_dev        Pointer to SDIO context handle to use for all
 *                      SDIO ops.
 *      bus_id          A small number indicating the SDIO card position on the
 *                      bus. Typically this is the slot number, e.g. 0, 1 etc.
 *                      Valid values are 0 to MAX_UNIFI_DEVS-1.
 *
 *  Returns:
 *      Pointer to device private struct.
 *
 *  Notes:
 *      The device private structure contains the interfaceTag and pointer to the unifi_priv
 *      structure created allocated by net_device od interface0.
 *      The net_device and device private structs are allocated together
 *      and should be freed by freeing the net_device pointer.
 * ---------------------------------------------------------------------------
 */
u8
uf_alloc_netdevice_for_other_interfaces(unifi_priv_t *priv, u16 interfaceTag)
{
    struct net_device *dev;
    netInterface_priv_t *interfacePriv;

    /*
     * Allocate netdevice struct, assign name template and
     * setup as an ethernet device.
     * The net_device and private structs are zeroed. Ether_setup() then
     * sets up ethernet handlers and values.
     * The RedHat 9 redhat-config-network tool doesn't recognise wlan* devices,
     * so use "eth*" (like other wireless extns drivers).
     */
    dev = alloc_etherdev_mq(sizeof(netInterface_priv_t), 1);
    if (dev == NULL) {
        return FALSE;
    }

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

    /* Set up back pointer from priv to netdev */
    interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    interfacePriv->privPtr = priv;
    interfacePriv->InterfaceTag = interfaceTag;
    priv->netdev[interfaceTag] = dev;
    priv->interfacePriv[interfacePriv->InterfaceTag] = interfacePriv;

    /* reset the connected state for the interface */
    interfacePriv->connected = UnifiConnectedUnknown;  /* -1 unknown, 0 no, 1 yes */
    INIT_LIST_HEAD(&interfacePriv->rx_uncontrolled_list);
    INIT_LIST_HEAD(&interfacePriv->rx_controlled_list);

    /* Setup / override net_device fields */
    dev->netdev_ops = &uf_netdev_ops;

#ifdef CSR_SUPPORT_WEXT
    dev->wireless_handlers = &unifi_iw_handler_def;
#if IW_HANDLER_VERSION < 6
    dev->get_wireless_stats = unifi_get_wireless_stats;
#endif /* IW_HANDLER_VERSION */
#endif /* CSR_SUPPORT_WEXT */
    return TRUE;
} /* uf_alloc_netdevice() */



/*
 * ---------------------------------------------------------------------------
 *  uf_free_netdevice
 *
 *      Unregister the network device and free the memory allocated for it.
 *      NB This includes the memory for the priv struct.
 *
 *  Arguments:
 *      priv            Device private pointer.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
int
uf_free_netdevice(unifi_priv_t *priv)
{
    int i;
    unsigned long flags;

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

    if (!priv) {
        return -EINVAL;
    }

    /*
     * Free any buffers used for holding firmware
     */
    uf_release_firmware_files(priv);

#if (defined CSR_SUPPORT_SME) && (defined CSR_SUPPORT_WEXT)
    if (priv->connection_config.mlmeAssociateReqInformationElements) {
        kfree(priv->connection_config.mlmeAssociateReqInformationElements);
    }
    priv->connection_config.mlmeAssociateReqInformationElements = NULL;
    priv->connection_config.mlmeAssociateReqInformationElementsLength = 0;

    if (priv->mib_data.length) {
        vfree(priv->mib_data.data);
    }
    priv->mib_data.data = NULL;
    priv->mib_data.length = 0;

#endif /* CSR_SUPPORT_SME && CSR_SUPPORT_WEXT*/

    /* Free any bulkdata buffers allocated for M4 caching */
    spin_lock_irqsave(&priv->m4_lock, flags);
    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
        if (interfacePriv->m4_bulk_data.data_length > 0) {
            unifi_trace(priv, UDBG5, "uf_free_netdevice: free M4 bulkdata %d\n", i);
            unifi_net_data_free(priv, &interfacePriv->m4_bulk_data);
        }
    }
    spin_unlock_irqrestore(&priv->m4_lock, flags);

#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
    /* Free any bulkdata buffers allocated for M4 caching */
    spin_lock_irqsave(&priv->wapi_lock, flags);
    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
        netInterface_priv_t *interfacePriv = priv->interfacePriv[i];
        if (interfacePriv->wapi_unicast_bulk_data.data_length > 0) {
            unifi_trace(priv, UDBG5, "uf_free_netdevice: free WAPI PKT bulk data %d\n", i);
            unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data);
        }
    }
    spin_unlock_irqrestore(&priv->wapi_lock, flags);
#endif

#ifdef CSR_SUPPORT_WEXT
    /* Unregister callback for netdevice state changes */
    unregister_netdevice_notifier(&uf_netdev_notifier);
#endif /* CSR_SUPPORT_WEXT */

#ifdef CSR_SUPPORT_SME
    /* Cancel work items and destroy the workqueue */
    cancel_work_sync(&priv->multicast_list_task);
#endif
/* Destroy the workqueues. */
    flush_workqueue(priv->unifi_workqueue);
    destroy_workqueue(priv->unifi_workqueue);

    /* Free up netdev in reverse order: priv is allocated with netdev[0].
     * So, netdev[0] should be freed after all other netdevs are freed up
     */
    for (i=CSR_WIFI_NUM_INTERFACES-1; i>=0; i--) {
        /*Free the netdev struct and priv, which are all one lump*/
        if (priv->netdev[i]) {
            unifi_error(priv, "uf_free_netdevice: netdev %d %p\n", i, priv->netdev[i]);
            free_netdev(priv->netdev[i]);
        }
    }

    return 0;
} /* uf_free_netdevice() */


/*
 * ---------------------------------------------------------------------------
 *  uf_net_open
 *
 *      Called when userland does "ifconfig wlan0 up".
 *
 *  Arguments:
 *      dev             Device pointer.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static int
uf_net_open(struct net_device *dev)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    /* If we haven't finished UniFi initialisation, we can't start */
    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
        unifi_warning(priv, "%s: unifi not ready, failing net_open\n", __FUNCTION__);
        return -EINVAL;
    }

#if (defined CSR_NATIVE_LINUX) && (defined UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
    /*
     * To sniff, the user must do "iwconfig mode monitor", which sets
     * priv->wext_conf.mode to IW_MODE_MONITOR.
     * Then he/she must do "ifconfig ethn up", which calls this fn.
     * There is no point in starting the sniff with SNIFFJOIN until
     * this point.
     */
    if (priv->wext_conf.mode == IW_MODE_MONITOR) {
        int err;
        err = uf_start_sniff(priv);
        if (err) {
            return err;
        }
        netif_carrier_on(dev);
    }
#endif

#ifdef CSR_SUPPORT_WEXT
    if (interfacePriv->wait_netdev_change) {
        unifi_trace(priv, UDBG1, "%s: Waiting for NETDEV_CHANGE, assume connected\n",
                    __FUNCTION__);
        interfacePriv->connected = UnifiConnected;
        interfacePriv->wait_netdev_change = FALSE;
    }
#endif

    netif_tx_start_all_queues(dev);

    return 0;
} /* uf_net_open() */


static int
uf_net_stop(struct net_device *dev)
{
#if defined(CSR_NATIVE_LINUX) && defined(UNIFI_SNIFF_ARPHRD) && defined(CSR_SUPPORT_WEXT)
    netInterface_priv_t *interfacePriv = (netInterface_priv_t*)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

    /* Stop sniffing if in Monitor mode */
    if (priv->wext_conf.mode == IW_MODE_MONITOR) {
        if (priv->card) {
            int err;
            err = unifi_reset_state(priv, dev->dev_addr, 1);
            if (err) {
                return err;
            }
        }
    }
#endif

    netif_tx_stop_all_queues(dev);

    return 0;
} /* uf_net_stop() */


/* This is called after the WE handlers */
static int
uf_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
    int rc;

    rc = -EOPNOTSUPP;

    return rc;
} /* uf_net_ioctl() */



static struct net_device_stats *
uf_net_get_stats(struct net_device *dev)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);

    return &interfacePriv->stats;
} /* uf_net_get_stats() */

static CSR_PRIORITY uf_get_packet_priority(unifi_priv_t *priv, netInterface_priv_t *interfacePriv, struct sk_buff *skb, const int proto)
{
    CSR_PRIORITY priority = CSR_CONTENTION;

    priority = (CSR_PRIORITY) (skb->priority >> 5);

    if (priority == CSR_QOS_UP0) { /* 0 */

        unifi_trace(priv, UDBG5, "uf_get_packet_priority: proto = 0x%.4X\n", proto);

        switch (proto) {
            case 0x0800:        /* IPv4 */
            case 0x814C:        /* SNMP */
            case 0x880C:        /* GSMP */
                priority = (CSR_PRIORITY) (skb->data[1 + ETH_HLEN] >> 5);
                break;

            case 0x8100:        /* VLAN */
                priority = (CSR_PRIORITY) (skb->data[0 + ETH_HLEN] >> 5);
                break;

            case 0x86DD:        /* IPv6 */
                priority = (CSR_PRIORITY) ((skb->data[0 + ETH_HLEN] & 0x0E) >> 1);
                break;

            default:
                priority = CSR_QOS_UP0;
                break;
        }
    }

    /* Check if we are allowed to transmit on this AC. Because of ACM we may have to downgrade to a lower
     * priority */
    if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
        interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
        unifi_TrafficQueue queue;

        /* Keep trying lower priorities until we find a queue
         * Priority to queue mapping is 1,2 - BK, 0,3 - BE, 4,5 - VI, 6,7 - VO */
        queue = unifi_frame_priority_to_queue(priority);

        while (queue > UNIFI_TRAFFIC_Q_BK && !interfacePriv->queueEnabled[queue]) {
            queue--;
            priority = unifi_get_default_downgrade_priority(queue);
        }
    }

    unifi_trace(priv, UDBG5, "Packet priority = %d\n", priority);

    return priority;
}

/*
 */
/*
 * ---------------------------------------------------------------------------
 *  get_packet_priority
 *
 *  Arguments:
 *      priv             private data area of functional driver
 *      skb              socket buffer
 *      ehdr             ethernet header to fetch protocol
 *      interfacePriv    For accessing station record database
 *
 *
 *  Returns:
 *      CSR_PRIORITY.
 * ---------------------------------------------------------------------------
 */
CSR_PRIORITY
get_packet_priority(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, netInterface_priv_t *interfacePriv)
{
    CSR_PRIORITY priority = CSR_CONTENTION;
    const int proto = ntohs(ehdr->h_proto);

    u8 interfaceMode = interfacePriv->interfaceMode;

    /* Priority Mapping for all the Modes */
    switch(interfaceMode)
    {
        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
            unifi_trace(priv, UDBG4, "mode is STA \n");
            if ((priv->sta_wmm_capabilities & QOS_CAPABILITY_WMM_ENABLED) == 1) {
                priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
            } else {
                priority = CSR_CONTENTION;
            }
            break;
#ifdef CSR_SUPPORT_SME
        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            {
                CsrWifiRouterCtrlStaInfo_t * dstStaInfo =
                    CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,ehdr->h_dest, interfacePriv->InterfaceTag);
                unifi_trace(priv, UDBG4, "mode is AP \n");
                if (!(ehdr->h_dest[0] & 0x01) && dstStaInfo && dstStaInfo->wmmOrQosEnabled) {
                    /* If packet is not Broadcast/multicast */
                    priority = uf_get_packet_priority(priv, interfacePriv, skb, proto);
                } else {
                    /* Since packet destination is not QSTA, set priority to CSR_CONTENTION */
                    unifi_trace(priv, UDBG4, "Destination is not QSTA or BroadCast/Multicast\n");
                    priority = CSR_CONTENTION;
                }
            }
            break;
#endif
        default:
            unifi_trace(priv, UDBG3, " mode unknown in %s func, mode=%x\n", __FUNCTION__, interfaceMode);
    }
    unifi_trace(priv, UDBG5, "priority = %x\n", priority);

    return priority;
}

/*
 * ---------------------------------------------------------------------------
 *  uf_net_select_queue
 *
 *      Called by the kernel to select which queue to put the packet in
 *
 *  Arguments:
 *      dev             Device pointer
 *      skb             Packet
 *
 *  Returns:
 *      Queue index
 * ---------------------------------------------------------------------------
 */
static u16
uf_net_select_queue(struct net_device *dev, struct sk_buff *skb)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = (unifi_priv_t *)interfacePriv->privPtr;
    struct ethhdr ehdr;
    unifi_TrafficQueue queue;
    int proto;
    CSR_PRIORITY priority;

    memcpy(&ehdr, skb->data, ETH_HLEN);
    proto = ntohs(ehdr.h_proto);

    /* 802.1x - apply controlled/uncontrolled port rules */
    if ((proto != ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
            && (proto != ETH_P_WAI)
#endif
       ) {
        /* queues 0 - 3 */
        priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);
        queue = unifi_frame_priority_to_queue(priority);
    } else {
        /* queue 4 */
        queue = UNIFI_TRAFFIC_Q_EAPOL;
    }


    return (u16)queue;
} /* uf_net_select_queue() */

int
skb_add_llc_snap(struct net_device *dev, struct sk_buff *skb, int proto)
{
    llc_snap_hdr_t *snap;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    int headroom;

    /* get the headroom available in skb */
    headroom = skb_headroom(skb);
    /* step 1: classify ether frame, DIX or 802.3? */

    if (proto < 0x600) {
        /* codes <= 1500 reserved for 802.3 lengths */
        /* it's 802.3, pass ether payload unchanged,  */
        unifi_trace(priv, UDBG3, "802.3 len: %d\n", skb->len);

        /*   leave off any PAD octets.  */
        skb_trim(skb, proto);
    } else if (proto == ETH_P_8021Q) {

        /* Store the VLAN SNAP (should be 87-65). */
        u16 vlan_snap = *(u16*)skb->data;
        /* check for headroom availability before skb_push 14 = (4 + 10) */
        if (headroom < 14) {
            unifi_trace(priv, UDBG3, "cant append vlan snap: debug\n");
            return -1;
        }
        /* Add AA-AA-03-00-00-00 */
        snap = (llc_snap_hdr_t *)skb_push(skb, 4);
        snap->dsap = snap->ssap = 0xAA;
        snap->ctrl = 0x03;
        memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);

        /* Add AA-AA-03-00-00-00 */
        snap = (llc_snap_hdr_t *)skb_push(skb, 10);
        snap->dsap = snap->ssap = 0xAA;
        snap->ctrl = 0x03;
        memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);

        /* Add the VLAN specific information */
        snap->protocol = htons(proto);
        *(u16*)(snap + 1) = vlan_snap;

    } else
    {
        /* it's DIXII, time for some conversion */
        unifi_trace(priv, UDBG3, "DIXII len: %d\n", skb->len);

        /* check for headroom availability before skb_push */
        if (headroom < sizeof(llc_snap_hdr_t)) {
            unifi_trace(priv, UDBG3, "cant append snap: debug\n");
            return -1;
        }
        /* tack on SNAP */
        snap = (llc_snap_hdr_t *)skb_push(skb, sizeof(llc_snap_hdr_t));
        snap->dsap = snap->ssap = 0xAA;
        snap->ctrl = 0x03;
        /* Use the appropriate OUI. */
        if ((proto == ETH_P_AARP) || (proto == ETH_P_IPX)) {
            memcpy(snap->oui, oui_8021h, P80211_OUI_LEN);
        } else {
            memcpy(snap->oui, oui_rfc1042, P80211_OUI_LEN);
        }
        snap->protocol = htons(proto);
    }

    return 0;
} /* skb_add_llc_snap() */

#ifdef CSR_SUPPORT_SME
static int
_identify_sme_ma_pkt_ind(unifi_priv_t *priv,
                         const s8 *oui, u16 protocol,
                         const CSR_SIGNAL *signal,
                         bulk_data_param_t *bulkdata,
                         const unsigned char *daddr,
                         const unsigned char *saddr)
{
    CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
    int r;
    u8 i;

    unifi_trace(priv, UDBG5,
            "_identify_sme_ma_pkt_ind -->\n");
    for (i = 0; i < MAX_MA_UNIDATA_IND_FILTERS; i++) {
        if (priv->sme_unidata_ind_filters[i].in_use) {
            if (!memcmp(oui, priv->sme_unidata_ind_filters[i].oui, 3) &&
                    (protocol == priv->sme_unidata_ind_filters[i].protocol)) {

                /* Send to client */
                if (priv->sme_cli) {
                    /*
                     * Pass the packet to the SME, using unifi_sys_ma_unitdata_ind().
                     * The frame needs to be converted according to the encapsulation.
                     */
                    unifi_trace(priv, UDBG1,
                            "_identify_sme_ma_pkt_ind: handle=%d, encap=%d, proto=%x\n",
                            i, priv->sme_unidata_ind_filters[i].encapsulation,
                            priv->sme_unidata_ind_filters[i].protocol);
                    if (priv->sme_unidata_ind_filters[i].encapsulation == CSR_WIFI_ROUTER_ENCAPSULATION_ETHERNET) {
                        struct sk_buff *skb;
                        /* The translation is performed on skb... */
                        skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
                        skb->len = bulkdata->d[0].data_length;

                        unifi_trace(priv, UDBG1,
                                "_identify_sme_ma_pkt_ind: skb_80211_to_ether -->\n");
                        r = skb_80211_to_ether(priv, skb, daddr, saddr,
                                signal, bulkdata);
                        unifi_trace(priv, UDBG1,
                                "_identify_sme_ma_pkt_ind: skb_80211_to_ether <--\n");
                        if (r) {
                            return -EINVAL;
                        }

                        /* ... but we indicate buffer and length */
                        bulkdata->d[0].os_data_ptr = skb->data;
                        bulkdata->d[0].data_length = skb->len;
                    } else {
                        /* Add the MAC addresses before the SNAP */
                        bulkdata->d[0].os_data_ptr -= 2*ETH_ALEN;
                        bulkdata->d[0].data_length += 2*ETH_ALEN;
                        memcpy((void*)bulkdata->d[0].os_data_ptr, daddr, ETH_ALEN);
                        memcpy((void*)bulkdata->d[0].os_data_ptr + ETH_ALEN, saddr, ETH_ALEN);
                    }

                    unifi_trace(priv, UDBG1,
                            "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind -->\n");
                    CsrWifiRouterMaPacketIndSend(priv->sme_unidata_ind_filters[i].appHandle,
                            (pkt_ind->VirtualInterfaceIdentifier & 0xff),
                            i,
                            pkt_ind->ReceptionStatus,
                            bulkdata->d[0].data_length,
                            (u8*)bulkdata->d[0].os_data_ptr,
                            NULL,
                            pkt_ind->Rssi,
                            pkt_ind->Snr,
                            pkt_ind->ReceivedRate);


                    unifi_trace(priv, UDBG1,
                            "_identify_sme_ma_pkt_ind: unifi_sys_ma_pkt_ind <--\n");
                }

                return 1;
            }
        }
    }

    return -1;
}
#endif /* CSR_SUPPORT_SME */

/*
 * ---------------------------------------------------------------------------
 *  skb_80211_to_ether
 *
 *      Make sure the received frame is in Ethernet (802.3) form.
 *      De-encapsulates SNAP if necessary, adds a ethernet header.
 *      The source buffer should not contain an 802.11 MAC header
 *
 *  Arguments:
 *      payload         Pointer to packet data received from UniFi.
 *      payload_length  Number of bytes of data received from UniFi.
 *      daddr           Destination MAC address.
 *      saddr           Source MAC address.
 *
 *  Returns:
 *      0 on success, -1 if the packet is bad and should be dropped,
 *      1 if the packet was forwarded to the SME or AMP client.
 * ---------------------------------------------------------------------------
 */
int
skb_80211_to_ether(unifi_priv_t *priv, struct sk_buff *skb,
                   const unsigned char *daddr, const unsigned char *saddr,
                   const CSR_SIGNAL *signal,
                   bulk_data_param_t *bulkdata)
{
    unsigned char *payload;
    int payload_length;
    struct ethhdr *eth;
    llc_snap_hdr_t *snap;
    int headroom;
#define UF_VLAN_LLC_HEADER_SIZE     18
    static const u8 vlan_inner_snap[] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };
#if defined(CSR_NATIVE_SOFTMAC) && defined(CSR_SUPPORT_SME)
    const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
#endif

    if(skb== NULL || daddr == NULL || saddr == NULL){
        unifi_error(priv,"skb_80211_to_ether: PBC fail\n");
        return 1;
    }

    payload = skb->data;
    payload_length = skb->len;

    snap = (llc_snap_hdr_t *)payload;
    eth  = (struct ethhdr *)payload;

    /* get the skb headroom size */
    headroom = skb_headroom(skb);

    /*
     * Test for the various encodings
     */
    if ((payload_length >= sizeof(llc_snap_hdr_t)) &&
            (snap->dsap == 0xAA) &&
            (snap->ssap == 0xAA) &&
            (snap->ctrl == 0x03) &&
            (snap->oui[0] == 0) &&
            (snap->oui[1] == 0) &&
            ((snap->oui[2] == 0) || (snap->oui[2] == 0xF8)))
    {
        /* AppleTalk AARP (2) or IPX SNAP */
        if ((snap->oui[2] == 0) &&
                ((ntohs(snap->protocol) == ETH_P_AARP) || (ntohs(snap->protocol) == ETH_P_IPX)))
        {
            u16 len;

            unifi_trace(priv, UDBG3, "%s len: %d\n",
                    (ntohs(snap->protocol) == ETH_P_AARP) ? "ETH_P_AARP" : "ETH_P_IPX",
                    payload_length);

            /* check for headroom availability before skb_push */
            if (headroom < (2 * ETH_ALEN + 2)) {
                unifi_warning(priv, "headroom not available to skb_push ether header\n");
                return -1;
            }

            /* Add 802.3 header and leave full payload */
            len = htons(skb->len);
            memcpy(skb_push(skb, 2), &len, 2);
            memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
            memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);

            return 0;
        }
        /* VLAN-tagged IP */
        if ((snap->oui[2] == 0) && (ntohs(snap->protocol) == ETH_P_8021Q))
        {
            /*
             * The translation doesn't change the packet length, so is done in-place.
             *
             * Example header (from Std 802.11-2007 Annex M):
             * AA-AA-03-00-00-00-81-00-87-65-AA-AA-03-00-00-00-08-06
             * -------SNAP-------p1-p1-ll-ll-------SNAP--------p2-p2
             * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-p1-p1-ll-ll-p2-p2
             * dd-dd-dd-dd-dd-dd-aa-aa-aa-aa-aa-aa-81-00-87-65-08-06
             */
            u16 vlan_snap;

            if (payload_length < UF_VLAN_LLC_HEADER_SIZE) {
                unifi_warning(priv, "VLAN SNAP header too short: %d bytes\n", payload_length);
                return -1;
            }

            if (memcmp(payload + 10, vlan_inner_snap, 6)) {
                unifi_warning(priv, "VLAN malformatted SNAP header.\n");
                return -1;
            }

            unifi_trace(priv, UDBG3, "VLAN SNAP: %02x-%02x\n", payload[8], payload[9]);
            unifi_trace(priv, UDBG3, "VLAN len: %d\n", payload_length);

            /* Create the 802.3 header */

            vlan_snap = *((u16*)(payload + 8));

            /* Create LLC header without byte-swapping */
            eth->h_proto = snap->protocol;

            memcpy(eth->h_dest, daddr, ETH_ALEN);
            memcpy(eth->h_source, saddr, ETH_ALEN);
            *(u16*)(eth + 1) = vlan_snap;
            return 0;
        }

        /* it's a SNAP + RFC1042 frame */
        unifi_trace(priv, UDBG3, "SNAP+RFC1042 len: %d\n", payload_length);

        /* chop SNAP+llc header from skb. */
        skb_pull(skb, sizeof(llc_snap_hdr_t));

        /* Since skb_pull called above to chop snap+llc, no need to check for headroom
         * availability before skb_push
         */
        /* create 802.3 header at beginning of skb. */
        eth = (struct ethhdr *)skb_push(skb, ETH_HLEN);
        memcpy(eth->h_dest, daddr, ETH_ALEN);
        memcpy(eth->h_source, saddr, ETH_ALEN);
        /* Copy protocol field without byte-swapping */
        eth->h_proto = snap->protocol;
    } else {
        u16 len;

        /* check for headroom availability before skb_push */
        if (headroom < (2 * ETH_ALEN + 2)) {
            unifi_warning(priv, "headroom not available to skb_push ether header\n");
            return -1;
        }
        /* Add 802.3 header and leave full payload */
        len = htons(skb->len);
        memcpy(skb_push(skb, 2), &len, 2);
        memcpy(skb_push(skb, ETH_ALEN), saddr, ETH_ALEN);
        memcpy(skb_push(skb, ETH_ALEN), daddr, ETH_ALEN);

        return 1;
    }

    return 0;
} /* skb_80211_to_ether() */


static CsrWifiRouterCtrlPortAction verify_port(unifi_priv_t *priv, unsigned char *address, int queue, u16 interfaceTag)
{
#ifdef CSR_NATIVE_LINUX
#ifdef CSR_SUPPORT_WEXT
    if (queue == UF_CONTROLLED_PORT_Q) {
        return priv->wext_conf.block_controlled_port;
    } else {
        return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN;
    }
#else
    return CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN; /* default to open for softmac dev */
#endif
#else
    return uf_sme_port_state(priv, address, queue, interfaceTag);
#endif
}

/*
 * ---------------------------------------------------------------------------
 *  prepare_and_add_macheader
 *
 *
 *      These functions adds mac header for packet from netdev
 *      to UniFi for transmission.
 *      EAP protocol packets are also appended with Mac header &
 *      sent using send_ma_pkt_request().
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      skb             Socket buffer containing data packet to transmit
 *      newSkb          Socket buffer containing data packet + Mac header if no sufficient headroom in skb
 *      serviceClass    to append QOS control header in Mac header
 *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
 *      interfaceTag    the interfaceID on which activity going on
 *      daddr           destination address
 *      saddr           source address
 *      protection      protection bit set in framce control of mac header
 *
 *  Returns:
 *      Zero on success or error code.
 * ---------------------------------------------------------------------------
 */

int prepare_and_add_macheader(unifi_priv_t *priv, struct sk_buff *skb, struct sk_buff *newSkb,
                              CSR_PRIORITY priority,
                              bulk_data_param_t *bulkdata,
                              u16 interfaceTag,
                              const u8 *daddr,
                              const u8 *saddr,
                              u8 protection)
{
    u16 fc = 0;
    u8 qc = 0;
    u8 macHeaderLengthInBytes = MAC_HEADER_SIZE, *bufPtr = NULL;
    bulk_data_param_t data_ptrs;
    CsrResult csrResult;
    int headroom =0;
    u8 direction = 0;
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
    u8 *addressOne;
    u8 bQosNull = false;

    if (skb == NULL) {
        unifi_error(priv,"prepare_and_add_macheader: Invalid SKB reference\n");
        return -1;
    }

    /* add a MAC header refer: 7.1.3.1 Frame Control field in P802.11REVmb.book */
    if (priority != CSR_CONTENTION) {
        /* EAPOL packets don't go as QOS_DATA */
        if (priority == CSR_MANAGEMENT) {
            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
        } else {
            /* Qos Control Field */
            macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;

            if (skb->len) {

                fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
            } else {
                fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_NULL);
                bQosNull = true;
            }
        }
    } else {
        if(skb->len == 0) {
            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_NULL);
        } else {
            fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
        }
    }

    switch (interfacePriv->interfaceMode)
    {
        case  CSR_WIFI_ROUTER_CTRL_MODE_STA:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
            direction = 2;
            fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
            break;
        case  CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
            direction = 0;
            break;
        case  CSR_WIFI_ROUTER_CTRL_MODE_AP:
        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
            direction = 1;
            fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
            break;
        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
            if (priority == CSR_MANAGEMENT ) {

                direction = 2;
                fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK);
            } else {
                /* Data frames have to use WDS 4 address frames */
                direction = 3;
                fc |= cpu_to_le16(IEEE802_11_FC_TO_DS_MASK | IEEE802_11_FC_FROM_DS_MASK);
                macHeaderLengthInBytes += 6;
            }
            break;
        default:
            unifi_warning(priv, "prepare_and_add_macheader: Unknown mode %d\n",
                          interfacePriv->interfaceMode);
    }


    /* If Sta is QOS & HTC is supported then need to set 'order' bit */
    /* We don't support HT Control for now */

    if(protection) {
        fc |= cpu_to_le16(IEEE802_11_FC_PROTECTED_MASK);
    }

    /* check the skb headroom before pushing mac header */
    headroom = skb_headroom(skb);

    if (headroom < macHeaderLengthInBytes) {
        unifi_trace(priv, UDBG5,
                    "prepare_and_add_macheader: Allocate headroom extra %d bytes\n",
                    macHeaderLengthInBytes);

        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);

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

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

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

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

        /* The old skb will not be used again */
            kfree_skb(skb);
    } else {

        /* headroom has sufficient size, so will get proper pointer */
        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
        bulkdata->d[0].os_data_ptr = skb->data;
        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
        bulkdata->d[0].data_length = skb->len;
    }

    /* Frame the actual MAC header */

    memset(bufPtr, 0, macHeaderLengthInBytes);

    /* copy frameControl field */
    memcpy(bufPtr, &fc, sizeof(fc));
    bufPtr += sizeof(fc);
    macHeaderLengthInBytes -= sizeof(fc);

    /* Duration/ID field which is 2 bytes */
    bufPtr += 2;
    macHeaderLengthInBytes -= 2;

    switch(direction)
    {
        case 0:
            /* Its an Ad-Hoc no need to route it through AP */
            /* Address1: MAC address of the destination from eth header */
            memcpy(bufPtr, daddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address2: MAC address of the source */
            memcpy(bufPtr, saddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address3: the BSSID (locally generated in AdHoc (creators Bssid)) */
            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;
            break;
        case 1:
           /* Address1: MAC address of the actual destination */
            memcpy(bufPtr, daddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;
            /* Address2: The MAC address of the AP */
            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address3: MAC address of the source from eth header */
            memcpy(bufPtr, saddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;
            break;
        case  2:
            /* Address1: To AP is the MAC address of the AP to which its associated */
            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address2: MAC address of the source from eth header */
            memcpy(bufPtr, saddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address3: MAC address of the actual destination on the distribution system */
            memcpy(bufPtr, daddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;
            break;
        case 3:
            memcpy(bufPtr, &interfacePriv->bssid, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address2: MAC address of the source from eth header */
            memcpy(bufPtr, saddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;

            /* Address3: MAC address of the actual destination on the distribution system */
            memcpy(bufPtr, daddr, ETH_ALEN);
            bufPtr += ETH_ALEN;
            macHeaderLengthInBytes -= ETH_ALEN;
            break;
        default:
            unifi_error(priv,"Unknown direction =%d : Not handled now\n",direction);
            return -1;
    }
    /* 2 bytes of frame control field, appended by firmware */
    bufPtr += 2;
    macHeaderLengthInBytes -= 2;

    if (3 == direction) {
        /* Address4: MAC address of the source */
        memcpy(bufPtr, saddr, ETH_ALEN);
        bufPtr += ETH_ALEN;
        macHeaderLengthInBytes -= ETH_ALEN;
    }

    /* IF Qos Data or Qos Null Data then set QosControl field */
    if ((priority != CSR_CONTENTION) && (macHeaderLengthInBytes >= QOS_CONTROL_HEADER_SIZE)) {

        if (priority > 7) {
            unifi_trace(priv, UDBG1, "data packets priority is more than 7, priority = %x\n", priority);
            qc |= 7;
        } else {
            qc |= priority;
        }
        /*assigning address1
        * Address1 offset taken fromm bufPtr(currently bufPtr pointing to Qos contorl) variable in reverse direction
        * Address4 don't exit
        */

        addressOne = bufPtr- ADDRESS_ONE_OFFSET;

        if (addressOne[0] & 0x1) {
            /* multicast/broadcast frames, no acknowledgement needed */
            qc |= 1 << 5;
        }
        /* non-AP mode only for now */
        if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA ||
           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_IBSS ||
           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI) {
           /* In case of STA and IBSS case eosp and txop limit is 0. */
        } else {
            if(bQosNull) {
                qc |= 1 << 4;
            }
        }

        /* append Qos control field to mac header */
        bufPtr[0] = qc;
        /* txop limit is 0 */
        bufPtr[1] = 0;
        macHeaderLengthInBytes -= QOS_CONTROL_HEADER_SIZE;
    }
    if (macHeaderLengthInBytes) {
        unifi_warning(priv, " Mac header not appended properly\n");
        return -1;
    }
    return 0;
}

/*
 * ---------------------------------------------------------------------------
 *  send_ma_pkt_request
 *
 *      These functions send a data packet to UniFi for transmission.
 *      EAP protocol packets are also sent as send_ma_pkt_request().
 *
 *  Arguments:
 *      priv            Pointer to device private context struct
 *      skb             Socket buffer containing data packet to transmit
 *      ehdr            Pointer to Ethernet header within skb.
 *
 *  Returns:
 *      Zero on success or error code.
 * ---------------------------------------------------------------------------
 */

static int
send_ma_pkt_request(unifi_priv_t *priv, struct sk_buff *skb, const struct ethhdr *ehdr, CSR_PRIORITY priority)
{
    int r;
    u16 i;
    u8 eapolStore = FALSE;
    struct sk_buff *newSkb = NULL;
    bulk_data_param_t bulkdata;
    const int proto = ntohs(ehdr->h_proto);
    u16 interfaceTag;
    CsrWifiMacAddress peerAddress;
    CSR_TRANSMISSION_CONTROL transmissionControl = CSR_NO_CONFIRM_REQUIRED;
    s8 protection;
    netInterface_priv_t *interfacePriv = NULL;
    CSR_RATE TransmitRate = (CSR_RATE)0;

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

    /* Get the interface Tag by means of source Mac address */
    for (i = 0; i < CSR_WIFI_NUM_INTERFACES; i++) {
        if (!memcmp(priv->netdev[i]->dev_addr, ehdr->h_source, ETH_ALEN)) {
            interfaceTag = i;
            interfacePriv = priv->interfacePriv[interfaceTag];
            break;
        }
    }

    if (interfacePriv == NULL) {
        /* No match found - error */
        interfaceTag = 0;
        interfacePriv = priv->interfacePriv[interfaceTag];
        unifi_warning(priv, "Mac address not matching ... debugging needed\n");
        interfacePriv->stats.tx_dropped++;
        kfree_skb(skb);
        return -1;
    }

    /* Add a SNAP header if necessary */
    if (skb_add_llc_snap(priv->netdev[interfaceTag], skb, proto) != 0) {
        /* convert failed */
        unifi_error(priv, "skb_add_llc_snap failed.\n");
        kfree_skb(skb);
        return -1;
    }

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

#ifdef CSR_SUPPORT_SME
    /* Notify the TA module for the Tx frame  for non AP/P2PGO mode*/
    if ((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
        (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)) {
        unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_TX,
                        &bulkdata.d[0], ehdr->h_source,
                        priv->netdev[interfaceTag]->dev_addr,
                        jiffies_to_msecs(jiffies),
                        0);     /* rate is unknown on tx */
    }
#endif /* CSR_SUPPORT_SME */

    if ((proto == ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
            || (proto == ETH_P_WAI)
#endif
       )
    {
        /* 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, ehdr->h_dest)) < 0) {
        unifi_warning(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

    /* append Mac header for Eapol as well as data packet */
    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, ehdr->h_dest, ehdr->h_source, protection)) {
        unifi_error(priv, "failed to create MAC header\n");
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return -1;
    }

    /* RA address must contain the immediate destination MAC address that is similar to
     * the Address 1 field of 802.11 Mac header here 4 is: (sizeof(framecontrol) + sizeof (durationID))
     * which is address 1 field
     */
    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);

    unifi_trace(priv, UDBG5, "RA[0]=%x, RA[1]=%x, RA[2]=%x, RA[3]=%x, RA[4]=%x, RA[5]=%x\n",
                peerAddress.a[0],peerAddress.a[1], peerAddress.a[2], peerAddress.a[3],
                peerAddress.a[4],peerAddress.a[5]);


    if ((proto == ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
            || (proto == ETH_P_WAI)
#endif
       )
    {
        CSR_SIGNAL signal;
        CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;

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

        /* Frame MA_PACKET request */
        signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
        signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
        signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;

        transmissionControl = req->TransmissionControl = 0;
#ifdef CSR_SUPPORT_SME
        if (eapolStore)
        {
            netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);

            /* Fill the MA-PACKET.req */

            req->Priority = priority;
            unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);

            /* rate selected by firmware */
            req->TransmitRate = 0;
            req->HostTag = CSR_WIFI_EAPOL_M4_HOST_TAG;
            /* RA address matching with address 1 of Mac header */
            memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);

            spin_lock(&priv->m4_lock);
            /* Store the M4-PACKET.req 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(&priv->m4_lock);

            /* Signal the workqueue to call CsrWifiRouterCtrlM4ReadyToSendIndSend().
             * It cannot be called directly from the tx path because it
             * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
             */
            queue_work(priv->unifi_workqueue, &netpriv->send_m4_ready_task);

            return 0;
        }
#endif
    }/*EAPOL or WAI packet*/

#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
    if ((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) && \
        (priv->wapi_unicast_filter) && \
        (proto != ETH_P_PAE) && \
        (proto != ETH_P_WAI) && \
        (skb->len > 0))
    {
        CSR_SIGNAL signal;
        CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
        netInterface_priv_t *netpriv = (netInterface_priv_t *)netdev_priv(priv->netdev[interfaceTag]);

        unifi_trace(priv, UDBG4, "send_ma_pkt_request() - WAPI unicast data packet when USKID = 1 \n");

        /* initialize signal to zero */
        memset(&signal, 0, sizeof(CSR_SIGNAL));
        /* Frame MA_PACKET request */
        signal.SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
        signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
        signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;

        /* Fill the MA-PACKET.req */
        req->TransmissionControl = 0;
        req->Priority = priority;
        unifi_trace(priv, UDBG3, "Tx Frame with Priority: %x\n", req->Priority);
        req->TransmitRate = (CSR_RATE) 0; /* rate selected by firmware */
        req->HostTag = 0xffffffff;        /* Ask for a new HostTag */
        /* RA address matching with address 1 of Mac header */
        memcpy(req->Ra.x, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);

        /* Store the M4-PACKET.req for later */
        spin_lock(&priv->wapi_lock);
        interfacePriv->wapi_unicast_ma_pkt_sig = signal;
        interfacePriv->wapi_unicast_bulk_data.net_buf_length = bulkdata.d[0].net_buf_length;
        interfacePriv->wapi_unicast_bulk_data.data_length = bulkdata.d[0].data_length;
        interfacePriv->wapi_unicast_bulk_data.os_data_ptr = bulkdata.d[0].os_data_ptr;
        interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = bulkdata.d[0].os_net_buf_ptr;
        spin_unlock(&priv->wapi_lock);

        /* Signal the workqueue to call CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend().
         * It cannot be called directly from the tx path because it
         * does a non-atomic kmalloc via the framework's CsrPmemAlloc().
         */
        queue_work(priv->unifi_workqueue, &netpriv->send_pkt_to_encrypt);

        return 0;
    }
#endif

    if(priv->cmanrTestMode)
    {
        TransmitRate = priv->cmanrTestModeTransmitRate;
        unifi_trace(priv, UDBG2, "send_ma_pkt_request: cmanrTestModeTransmitRate = %d TransmitRate=%d\n",
                    priv->cmanrTestModeTransmitRate,
                    TransmitRate
                   );
    }

    /* Send UniFi msg */
    /* Here hostTag is been sent as 0xffffffff, its been appended properly while framing MA-Packet request in pdu_processing.c file */
    r = uf_process_ma_packet_req(priv,
                                 peerAddress.a,
                                 0xffffffff,  /* Ask for a new HostTag */
                                 interfaceTag,
                                 transmissionControl,
                                 TransmitRate,
                                 priority,
                                 priv->netdev_client->sender_id,
                                 &bulkdata);

    if (r) {
        unifi_trace(priv, UDBG1, "(HIP validation failure) r = %x\n", r);
        unifi_net_data_free(priv, &bulkdata.d[0]);
        return -1;
    }

    unifi_trace(priv, UDBG3, "leaving send_ma_pkt_request, UNITDATA result code = %d\n", r);

    return r;
} /* send_ma_pkt_request() */

/*
 * ---------------------------------------------------------------------------
 *  uf_net_xmit
 *
 *      This function is called by the higher level stack to transmit an
 *      ethernet packet.
 *
 *  Arguments:
 *      skb     Ethernet packet to send.
 *      dev     Pointer to the linux net device.
 *
 *  Returns:
 *      0   on success (packet was consumed, not necessarily transmitted)
 *      1   if packet was requeued
 *     -1   on error
 *
 *
 *  Notes:
 *      The controlled port is handled in the qdisc dequeue handler.
 * ---------------------------------------------------------------------------
 */
static netdev_tx_t
uf_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;
    struct ethhdr ehdr;
    int proto, port;
    int result;
    static tx_signal_handler tx_handler;
    CSR_PRIORITY priority;
    CsrWifiRouterCtrlPortAction port_action;

    unifi_trace(priv, UDBG5, "unifi_net_xmit: skb = %x\n", skb);

    memcpy(&ehdr, skb->data, ETH_HLEN);
    proto = ntohs(ehdr.h_proto);
    priority = get_packet_priority(priv, skb, &ehdr, interfacePriv);

    /* All frames are sent as MA-PACKET.req (EAPOL also) */
    tx_handler = send_ma_pkt_request;

    /* 802.1x - apply controlled/uncontrolled port rules */
    if ((proto != ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
            && (proto != ETH_P_WAI)
#endif
       ) {
        port = UF_CONTROLLED_PORT_Q;
    } else {
        /* queue 4 */
        port = UF_UNCONTROLLED_PORT_Q;
    }

    /* Uncontrolled port rules apply */
    port_action = verify_port(priv
        , (((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode)||(CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI== interfacePriv->interfaceMode))? interfacePriv->bssid.a: ehdr.h_dest)
        , port
        , interfacePriv->InterfaceTag);

    if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
        unifi_trace(priv, UDBG5,
                    "uf_net_xmit: %s controlled port open\n",
                    port ? "" : "un");
        /* Remove the ethernet header */
        skb_pull(skb, ETH_HLEN);
        result = tx_handler(priv, skb, &ehdr, priority);
    } else {

        /* Discard the packet if necessary */
        unifi_trace(priv, UDBG2,
                "uf_net_xmit: %s controlled port %s\n",
                port ? "" : "un", port_action==CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK ? "blocked" : "closed");
        interfacePriv->stats.tx_dropped++;
        kfree_skb(skb);

        return NETDEV_TX_OK;
    }

    if (result == NETDEV_TX_OK) {
#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION))
    	/* Don't update the tx stats when the pkt is to be sent for sw encryption*/
    	if (!((CSR_WIFI_ROUTER_CTRL_MODE_STA == interfacePriv->interfaceMode) &&
              (priv->wapi_unicast_filter == 1)))
        {
            dev->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 += skb->len;

        }
#else
    	dev->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 += skb->len;
#endif
    } else if (result < 0) {

        /* Failed to send: fh queue was full, and the skb was discarded.
         * Return OK to indicate that the buffer was consumed, to stop the
         * kernel re-transmitting the freed buffer.
         */
        interfacePriv->stats.tx_dropped++;
        unifi_trace(priv, UDBG1, "unifi_net_xmit: (Packet Drop), dropped count = %x\n", interfacePriv->stats.tx_dropped);
        result = NETDEV_TX_OK;
    }

    /* The skb will have been freed by send_XXX_request() */

    return result;
} /* uf_net_xmit() */

/*
 * ---------------------------------------------------------------------------
 *  unifi_pause_xmit
 *  unifi_restart_xmit
 *
 *      These functions are called from the UniFi core to control the flow
 *      of packets from the upper layers.
 *      unifi_pause_xmit() is called when the internal queue is full and
 *      should take action to stop unifi_ma_unitdata() being called.
 *      When the queue has drained, unifi_restart_xmit() will be called to
 *      re-enable the flow of packets for transmission.
 *
 *  Arguments:
 *      ospriv          OS private context pointer.
 *
 *  Returns:
 *      unifi_pause_xmit() is called from interrupt context.
 * ---------------------------------------------------------------------------
 */
void
unifi_pause_xmit(void *ospriv, unifi_TrafficQueue queue)
{
    unifi_priv_t *priv = ospriv;
    int i; /* used as a loop counter */

    unifi_trace(priv, UDBG2, "Stopping queue %d\n", queue);

    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
    {
        if (netif_running(priv->netdev[i]))
        {
            netif_stop_subqueue(priv->netdev[i], (u16)queue);
        }
    }

#ifdef CSR_SUPPORT_SME
    if(queue<=3) {
        routerStartBuffering(priv,queue);
        unifi_trace(priv,UDBG2,"Start buffering %d\n", queue);
     } else {
        routerStartBuffering(priv,0);
        unifi_error(priv, "Start buffering %d defaulting to 0\n", queue);
     }
#endif

} /* unifi_pause_xmit() */

void
unifi_restart_xmit(void *ospriv, unifi_TrafficQueue queue)
{
    unifi_priv_t *priv = ospriv;
    int i=0; /* used as a loop counter */

    unifi_trace(priv, UDBG2, "Waking queue %d\n", queue);

    for(i=0;i<CSR_WIFI_NUM_INTERFACES;i++)
    {
        if (netif_running(priv->netdev[i]))
        {
            netif_wake_subqueue(priv->netdev[i], (u16)queue);
        }
    }

#ifdef CSR_SUPPORT_SME
    if(queue <=3) {
        routerStopBuffering(priv,queue);
        uf_send_buffered_frames(priv,queue);
    } else {
        routerStopBuffering(priv,0);
        uf_send_buffered_frames(priv,0);
    }
#endif
} /* unifi_restart_xmit() */


static void
indicate_rx_skb(unifi_priv_t *priv, u16 ifTag, u8* dst_a, u8* src_a, struct sk_buff *skb, CSR_SIGNAL *signal,
                bulk_data_param_t *bulkdata)
{
    int r, sr = 0;
    struct net_device *dev;

#ifdef CSR_SUPPORT_SME
    llc_snap_hdr_t *snap;

    snap = (llc_snap_hdr_t *)skb->data;

    sr = _identify_sme_ma_pkt_ind(priv,
                                  snap->oui, ntohs(snap->protocol),
                                  signal,
                                  bulkdata,
                                  dst_a, src_a );
#endif

    /*
     * Decapsulate any SNAP header and
     * prepend an ethernet header so that the skb manipulation and ARP
     * stuff works.
     */
    r = skb_80211_to_ether(priv, skb, dst_a, src_a,
                           signal, bulkdata);
    if (r == -1) {
        /* Drop the packet and return */
        priv->interfacePriv[ifTag]->stats.rx_errors++;
        priv->interfacePriv[ifTag]->stats.rx_frame_errors++;
        unifi_net_data_free(priv, &bulkdata->d[0]);
        unifi_notice(priv, "indicate_rx_skb: Discard unknown frame.\n");
        return;
    }

    /* Handle the case where packet is sent up through the subscription
     * API but should not be given to the network stack (AMP PAL case)
     * LLC header is different from WiFi and the packet has been subscribed for
     */
    if (r == 1 && sr == 1) {
        unifi_net_data_free(priv, &bulkdata->d[0]);
        unifi_trace(priv, UDBG5, "indicate_rx_skb: Data given to subscription"
                "API, not being given to kernel\n");
        return;
    }

    dev = priv->netdev[ifTag];
    /* Now we look like a regular ethernet frame */
    /* Fill in SKB meta data */
    skb->dev = dev;
    skb->protocol = eth_type_trans(skb, dev);
    skb->ip_summed = CHECKSUM_UNNECESSARY;

    /* Test for an overlength frame */
    if (skb->len > (dev->mtu + ETH_HLEN)) {
        /* A bogus length ethfrm has been encap'd. */
        /* Is someone trying an oflow attack? */
        unifi_error(priv, "%s: oversize frame (%d > %d)\n",
                    dev->name,
                    skb->len, dev->mtu + ETH_HLEN);

        /* Drop the packet and return */
        priv->interfacePriv[ifTag]->stats.rx_errors++;
        priv->interfacePriv[ifTag]->stats.rx_length_errors++;
        unifi_net_data_free(priv, &bulkdata->d[0]);
        return;
    }


    if(priv->cmanrTestMode)
    {
        const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
        priv->cmanrTestModeTransmitRate = pkt_ind->ReceivedRate;
        unifi_trace(priv, UDBG2, "indicate_rx_skb: cmanrTestModeTransmitRate=%d\n", priv->cmanrTestModeTransmitRate);
    }

    /* Pass SKB up the stack */
#ifdef CSR_WIFI_USE_NETIF_RX
        netif_rx(skb);
#else
        netif_rx_ni(skb);
#endif

    if (dev != NULL) {
        dev->last_rx = jiffies;
    }

    /* Bump rx stats */
    priv->interfacePriv[ifTag]->stats.rx_packets++;
    priv->interfacePriv[ifTag]->stats.rx_bytes += bulkdata->d[0].data_length;

    return;
}

void
uf_process_rx_pending_queue(unifi_priv_t *priv, int queue,
                            CsrWifiMacAddress source_address,
                            int indicate, u16 interfaceTag)
{
    rx_buffered_packets_t *rx_q_item;
    struct list_head *rx_list;
    struct list_head *n;
    struct list_head *l_h;
    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];

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

    if (queue == UF_CONTROLLED_PORT_Q) {
        rx_list = &interfacePriv->rx_controlled_list;
    } else {
        rx_list = &interfacePriv->rx_uncontrolled_list;
    }

    down(&priv->rx_q_sem);
    list_for_each_safe(l_h, n, rx_list) {
        rx_q_item = list_entry(l_h, rx_buffered_packets_t, q);

        /* Validate against the source address */
        if (memcmp(broadcast_address.a, source_address.a, ETH_ALEN) &&
                memcmp(rx_q_item->sa.a, source_address.a, ETH_ALEN)) {

            unifi_trace(priv, UDBG2,
                        "uf_process_rx_pending_queue: Skipping sa=%02X%02X%02X%02X%02X%02X skb=%p, bulkdata=%p\n",
                        rx_q_item->sa.a[0], rx_q_item->sa.a[1],
                        rx_q_item->sa.a[2], rx_q_item->sa.a[3],
                        rx_q_item->sa.a[4], rx_q_item->sa.a[5],
                        rx_q_item->skb, &rx_q_item->bulkdata.d[0]);
            continue;
        }

        list_del(l_h);


        unifi_trace(priv, UDBG2,
                    "uf_process_rx_pending_queue: Was Blocked skb=%p, bulkdata=%p\n",
                    rx_q_item->skb, &rx_q_item->bulkdata);

        if (indicate) {
            indicate_rx_skb(priv, interfaceTag, rx_q_item->da.a, rx_q_item->sa.a, rx_q_item->skb, &rx_q_item->signal, &rx_q_item->bulkdata);
        } else {
            interfacePriv->stats.rx_dropped++;
            unifi_net_data_free(priv, &rx_q_item->bulkdata.d[0]);
        }

        /* It is our resposibility to free the Rx structure object. */
        kfree(rx_q_item);
    }
    up(&priv->rx_q_sem);
}

/*
 * ---------------------------------------------------------------------------
 *  uf_resume_data_plane
 *
 *      Is called when the (un)controlled port is set to open,
 *      to notify the network stack to schedule for transmission
 *      any packets queued in the qdisk while port was closed and
 *      indicated to the stack any packets buffered in the Rx queues.
 *
 *  Arguments:
 *      priv        Pointer to device private struct
 *
 *  Returns:
 * ---------------------------------------------------------------------------
 */
void
uf_resume_data_plane(unifi_priv_t *priv, int queue,
                     CsrWifiMacAddress peer_address,
                     u16 interfaceTag)
{
#ifdef CSR_SUPPORT_WEXT
    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
#endif

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

    unifi_trace(priv, UDBG2, "Resuming netif\n");

    /*
     * If we are waiting for the net device to enter the up state, don't
     * process the rx queue yet as it will be done by the callback when
     * the device is ready.
     */
#ifdef CSR_SUPPORT_WEXT
    if (!interfacePriv->wait_netdev_change)
#endif
    {
#ifdef CONFIG_NET_SCHED
        if (netif_running(priv->netdev[interfaceTag])) {
            netif_tx_schedule_all(priv->netdev[interfaceTag]);
        }
#endif
        uf_process_rx_pending_queue(priv, queue, peer_address, 1,interfaceTag);
    }
} /* uf_resume_data_plane() */


void uf_free_pending_rx_packets(unifi_priv_t *priv, int queue, CsrWifiMacAddress peer_address,u16 interfaceTag)
{
    uf_process_rx_pending_queue(priv, queue, peer_address, 0,interfaceTag);

} /* uf_free_pending_rx_packets() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_rx
 *
 *      Reformat a UniFi data received packet into a p80211 packet and
 *      pass it up the protocol stack.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
unifi_rx(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
    u16 interfaceTag;
    bulk_data_desc_t *pData;
    const CSR_MA_PACKET_INDICATION *pkt_ind = &signal->u.MaPacketIndication;
    struct sk_buff *skb;
    CsrWifiRouterCtrlPortAction port_action;
    u8 dataFrameType;
    int proto;
    int queue;

    u8 da[ETH_ALEN], sa[ETH_ALEN];
    u8 toDs, fromDs, frameType, macHeaderLengthInBytes = MAC_HEADER_SIZE;
    u16 frameControl;
    netInterface_priv_t *interfacePriv;
    struct ethhdr ehdr;

    interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
    interfacePriv = priv->interfacePriv[interfaceTag];

    /* Sanity check that the VIF refers to a sensible interface */
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }

    /* Sanity check that the VIF refers to an allocated netdev */
    if (!interfacePriv->netdev_registered)
    {
        unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
        unifi_net_data_free(priv, &bulkdata->d[0]);
        return;
    }

    if (bulkdata->d[0].data_length == 0) {
        unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }


    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
    skb->len = bulkdata->d[0].data_length;

    /* Point to the addresses */
    toDs = (skb->data[1] & 0x01) ? 1 : 0;
    fromDs = (skb->data[1] & 0x02) ? 1 : 0;

    memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
    memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */


    pData = &bulkdata->d[0];
    frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
    frameType = ((frameControl & 0x000C) >> 2);

    dataFrameType =((frameControl & 0x00f0) >> 4);
    unifi_trace(priv, UDBG6,
                "%s: Receive Data Frame Type %d \n", __FUNCTION__,dataFrameType);

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

            /* If order bit set then HT control field is the part of MAC header */
            if (frameControl & FRAME_CONTROL_ORDER_BIT)
                macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
            break;
        default:
            if (fromDs && toDs)
                macHeaderLengthInBytes += 6;
    }

    /* Prepare the ethernet header from snap header of skb data */
    switch(dataFrameType)
    {
        case DATA_NULL:
        case QOS_DATA_NULL:
            /* This is for only queue info fetching, EAPOL wont come as
             * null data so the proto is initialized as zero
             */
            proto = 0x0;
            break;
        default:
            {
                llc_snap_hdr_t *snap;
                /* Fetch a snap header to find protocol (for IPV4/IPV6 packets
                 * the snap header fetching offset is same)
                 */
                snap = (llc_snap_hdr_t *) (skb->data + macHeaderLengthInBytes);

                /* prepare the ethernet header from the snap header & addresses */
                ehdr.h_proto = snap->protocol;
                memcpy(ehdr.h_dest, da, ETH_ALEN);
                memcpy(ehdr.h_source, sa, ETH_ALEN);
            }
            proto = ntohs(ehdr.h_proto);
    }
    unifi_trace(priv, UDBG3, "in unifi_rx protocol from snap header = 0x%x\n", proto);

    if ((proto != ETH_P_PAE)
#ifdef CSR_WIFI_SECURITY_WAPI_ENABLE
            && (proto != ETH_P_WAI)
#endif
       ) {
        queue = UF_CONTROLLED_PORT_Q;
    } else {
        queue = UF_UNCONTROLLED_PORT_Q;
    }

    port_action = verify_port(priv, (unsigned char*)sa, queue, interfaceTag);
    unifi_trace(priv, UDBG3, "in unifi_rx port action is = 0x%x & queue = %x\n", port_action, queue);

#ifdef CSR_SUPPORT_SME
    /* Notify the TA module for the Rx frame for non P2PGO and AP cases*/
    if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_AP) &&
            (interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))
    {
        /* Remove MAC header of length(macHeaderLengthInBytes) before sampling */
        skb_pull(skb, macHeaderLengthInBytes);
        pData->os_data_ptr = skb->data;
        pData->data_length -= macHeaderLengthInBytes;

        if (pData->data_length) {
            unifi_ta_sample(priv->card, CSR_WIFI_ROUTER_CTRL_PROTOCOL_DIRECTION_RX,
                            &bulkdata->d[0],
                            sa, priv->netdev[interfaceTag]->dev_addr,
                            jiffies_to_msecs(jiffies),
                            pkt_ind->ReceivedRate);
        }
    } else {

        /* AP/P2PGO specific handling here */
        CsrWifiRouterCtrlStaInfo_t * srcStaInfo =
            CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);

        /* Defensive check only; Source address is already checked in
        process_ma_packet_ind and we should have a valid source address here */

         if(srcStaInfo == NULL) {
            CsrWifiMacAddress peerMacAddress;
            /* Unknown data PDU */
            memcpy(peerMacAddress.a,sa,ETH_ALEN);
            unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
            sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return;
        }

       /* For AP GO mode, don't store the PDUs */
        if (port_action != CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_OPEN) {
            /* Drop the packet and return */
            CsrWifiMacAddress peerMacAddress;
            memcpy(peerMacAddress.a,sa,ETH_ALEN);
            unifi_trace(priv, UDBG3, "%s: Port is not open: unexpected frame from peer = %x:%x:%x:%x:%x:%x\n",
                        __FUNCTION__, sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);

            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
            interfacePriv->stats.rx_dropped++;
            unifi_net_data_free(priv, &bulkdata->d[0]);
            unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n", __FUNCTION__,
                         proto, queue ? "Controlled" : "Un-controlled");
            return;
        }

         /* Qos NULL/Data NULL  are freed here and not processed further */
        if((dataFrameType == QOS_DATA_NULL) || (dataFrameType == DATA_NULL)){
            unifi_trace(priv, UDBG5, "%s: Null Frame Received and Freed\n", __FUNCTION__);
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return;
        }

        /* Now we have done with MAC header so proceed with the real data part*/
        /* This function takes care of appropriate routing for AP/P2PGO case*/
        /* the function hadnles following things
           2. Routing the PDU to appropriate location
           3. Error case handling
           */
        if(!(uf_ap_process_data_pdu(priv, skb, &ehdr, srcStaInfo,
             signal,
             bulkdata,
             macHeaderLengthInBytes)))
        {
            return;
        }
        unifi_trace(priv, UDBG5, "unifi_rx: no specific AP handling process as normal frame, MAC Header len %d\n",macHeaderLengthInBytes);
        /* Remove the MAC header for subsequent conversion */
        skb_pull(skb, macHeaderLengthInBytes);
        pData->os_data_ptr = skb->data;
        pData->data_length -= macHeaderLengthInBytes;
        pData->os_net_buf_ptr = (unsigned char*)skb;
        pData->net_buf_length = skb->len;
    }
#endif /* CSR_SUPPORT_SME */


    /* Now that the MAC header is removed, null-data frames have zero length
     * and can be dropped
     */
    if (pData->data_length == 0) {
        if (((frameControl & 0x00f0) >> 4) != QOS_DATA_NULL &&
            ((frameControl & 0x00f0) >> 4) != DATA_NULL) {
            unifi_trace(priv, UDBG1, "Zero length frame, but not null-data %04x\n", frameControl);
        }
        unifi_net_data_free(priv, &bulkdata->d[0]);
        return;
    }

    if (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD) {
        /* Drop the packet and return */
        interfacePriv->stats.rx_dropped++;
        unifi_net_data_free(priv, &bulkdata->d[0]);
        unifi_notice(priv, "%s: Dropping packet, proto=0x%04x, %s port\n",
                     __FUNCTION__, proto, queue ? "controlled" : "uncontrolled");
        return;
    } else if ( (port_action == CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK) ||
                   (interfacePriv->connected != UnifiConnected) ) {

        /* Buffer the packet into the Rx queues */
        rx_buffered_packets_t *rx_q_item;
        struct list_head *rx_list;

        rx_q_item = (rx_buffered_packets_t *)kmalloc(sizeof(rx_buffered_packets_t),
                GFP_KERNEL);
        if (rx_q_item == NULL) {
            unifi_error(priv, "%s: Failed to allocate %d bytes for rx packet record\n",
                        __FUNCTION__, sizeof(rx_buffered_packets_t));
            interfacePriv->stats.rx_dropped++;
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return;
        }

        INIT_LIST_HEAD(&rx_q_item->q);
        rx_q_item->bulkdata = *bulkdata;
        rx_q_item->skb = skb;
        rx_q_item->signal = *signal;
        memcpy(rx_q_item->sa.a, sa, ETH_ALEN);
        memcpy(rx_q_item->da.a, da, ETH_ALEN);
        unifi_trace(priv, UDBG2, "%s: Blocked skb=%p, bulkdata=%p\n",
                    __FUNCTION__, rx_q_item->skb, &rx_q_item->bulkdata);

        if (queue == UF_CONTROLLED_PORT_Q) {
            rx_list = &interfacePriv->rx_controlled_list;
        } else {
            rx_list = &interfacePriv->rx_uncontrolled_list;
        }

        /* Add to tail of packets queue */
        down(&priv->rx_q_sem);
        list_add_tail(&rx_q_item->q, rx_list);
        up(&priv->rx_q_sem);

        return;

    }

    indicate_rx_skb(priv, interfaceTag, da, sa, skb, signal, bulkdata);

} /* unifi_rx() */

static void process_ma_packet_cfm(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
    u16 interfaceTag;
    const CSR_MA_PACKET_CONFIRM *pkt_cfm = &signal->u.MaPacketConfirm;
    netInterface_priv_t *interfacePriv;

    interfaceTag = (pkt_cfm->VirtualInterfaceIdentifier & 0xff);
    interfacePriv = priv->interfacePriv[interfaceTag];

    /* Sanity check that the VIF refers to a sensible interface */
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "%s: MA-PACKET confirm with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
        return;
    }
#ifdef CSR_SUPPORT_SME
    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) {

        uf_process_ma_pkt_cfm_for_ap(priv,interfaceTag,pkt_cfm);
    } else if (interfacePriv->m4_sent && (pkt_cfm->HostTag == interfacePriv->m4_hostTag)) {
        /* Check if this is a confirm for EAPOL M4 frame and we need to send transmistted ind*/
        CsrResult result = pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL?CSR_RESULT_SUCCESS:CSR_RESULT_FAILURE;
        CsrWifiMacAddress peerMacAddress;
        memcpy(peerMacAddress.a, interfacePriv->m4_signal.u.MaPacketRequest.Ra.x, ETH_ALEN);

        unifi_trace(priv, UDBG1, "%s: Sending M4 Transmit CFM\n", __FUNCTION__);
        CsrWifiRouterCtrlM4TransmittedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0,
                                              interfaceTag,
                                              peerMacAddress,
                                              result);
        interfacePriv->m4_sent = FALSE;
        interfacePriv->m4_hostTag = 0xffffffff;
    }
#endif
    return;
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_rx
 *
 *      Reformat a UniFi data received packet into a p80211 packet and
 *      pass it up the protocol stack.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void process_ma_packet_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
    u16 interfaceTag;
    bulk_data_desc_t *pData;
    CSR_MA_PACKET_INDICATION *pkt_ind = (CSR_MA_PACKET_INDICATION*)&signal->u.MaPacketIndication;
    struct sk_buff *skb;
    u16 frameControl;
    netInterface_priv_t *interfacePriv;
    u8 da[ETH_ALEN], sa[ETH_ALEN];
    u8 *bssid = NULL, *ba_addr = NULL;
    u8 toDs, fromDs, frameType;
    u8 i =0;

#ifdef CSR_SUPPORT_SME
    u8 dataFrameType = 0;
    u8 powerSaveChanged = FALSE;
    u8 pmBit = 0;
    CsrWifiRouterCtrlStaInfo_t *srcStaInfo = NULL;
    u16 qosControl;

#endif

    interfaceTag = (pkt_ind->VirtualInterfaceIdentifier & 0xff);
    interfacePriv = priv->interfacePriv[interfaceTag];


    /* Sanity check that the VIF refers to a sensible interface */
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "%s: MA-PACKET indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }

    /* Sanity check that the VIF refers to an allocated netdev */
    if (!interfacePriv->netdev_registered)
    {
        unifi_error(priv, "%s: MA-PACKET indication with unallocated interfaceTag %d\n", __FUNCTION__, interfaceTag);
        unifi_net_data_free(priv, &bulkdata->d[0]);
        return;
    }

    if (bulkdata->d[0].data_length == 0) {
        unifi_warning(priv, "%s: MA-PACKET indication with zero bulk data\n", __FUNCTION__);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }
    /* For monitor mode we need to pass this indication to the registered application
    handle this separately*/
    /* MIC failure is already taken care of so no need to send the PDUs which are not successfully received in non-monitor mode*/
    if(pkt_ind->ReceptionStatus != CSR_RX_SUCCESS)
    {
        unifi_warning(priv, "%s: MA-PACKET indication with status = %d\n",__FUNCTION__, pkt_ind->ReceptionStatus);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }


    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
    skb->len = bulkdata->d[0].data_length;

    /* Point to the addresses */
    toDs = (skb->data[1] & 0x01) ? 1 : 0;
    fromDs = (skb->data[1] & 0x02) ? 1 : 0;

    memcpy(da,(skb->data+4+toDs*12),ETH_ALEN);/* Address1 or 3 */
    memcpy(sa,(skb->data+10+fromDs*(6+toDs*8)),ETH_ALEN); /* Address2, 3 or 4 */

    /* Find the BSSID, which will be used to match the BA session */
    if (toDs && fromDs)
    {
        unifi_trace(priv, UDBG6, "4 address frame - don't try to find BSSID\n");
        bssid = NULL;
    }
    else
    {
        bssid = (u8 *) (skb->data + 4 + 12 - (fromDs * 6) - (toDs * 12));
    }

    pData = &bulkdata->d[0];
    frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr);
    frameType = ((frameControl & 0x000C) >> 2);

    unifi_trace(priv, UDBG3, "Rx Frame Type: %d sn: %d\n",frameType,
         (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff);
    if(frameType == IEEE802_11_FRAMETYPE_CONTROL){
#ifdef CSR_SUPPORT_SME
        unifi_trace(priv, UDBG6, "%s: Received Control Frame\n", __FUNCTION__);

        if((frameControl & 0x00f0) == 0x00A0){
            /* This is a PS-POLL request */
            u8 pmBit = (frameControl & 0x1000)?0x01:0x00;
            unifi_trace(priv, UDBG6, "%s: Received PS-POLL Frame\n", __FUNCTION__);

            uf_process_ps_poll(priv,sa,da,pmBit,interfaceTag);
        }
        else {
            unifi_warning(priv, "%s: Non PS-POLL control frame is received\n", __FUNCTION__);
        }
#endif
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }
    if(frameType != IEEE802_11_FRAMETYPE_DATA) {
        unifi_warning(priv, "%s: Non control Non Data frame is received\n",__FUNCTION__);
        unifi_net_data_free(priv,&bulkdata->d[0]);
        return;
    }

#ifdef CSR_SUPPORT_SME
    if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
       (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)){

        srcStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,sa,interfaceTag);

        if(srcStaInfo == NULL) {
            CsrWifiMacAddress peerMacAddress;
            /* Unknown data PDU */
            memcpy(peerMacAddress.a,sa,ETH_ALEN);
            unifi_trace(priv, UDBG1, "%s: Unexpected frame from peer = %x:%x:%x:%x:%x:%x\n", __FUNCTION__,
            sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
            CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
            unifi_net_data_free(priv, &bulkdata->d[0]);
            return;
        }

        /*
        verify power management bit here so as to ensure host and unifi are always
        in sync with power management status of peer.

        If we do it later, it may so happen we have stored the frame in BA re-ordering
        buffer and hence host and unifi are out of sync for power management status
        */

        pmBit = (frameControl & 0x1000)?0x01:0x00;
        powerSaveChanged = uf_process_pm_bit_for_peer(priv,srcStaInfo,pmBit,interfaceTag);

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

        /* For Qos Frame if PM bit is toggled to indicate the change in power save state then it shall not be
        considered as Trigger Frame. Enter only if WMM STA and peer is in Power save */

        dataFrameType = ((frameControl & 0x00f0) >> 4);

        if((powerSaveChanged == FALSE)&&(srcStaInfo->wmmOrQosEnabled == TRUE)&&
        (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)){

            if((dataFrameType == QOS_DATA) || (dataFrameType == QOS_DATA_NULL)){

                /*
                 * QoS control field is offset from frame control by 2 (frame control)
                 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
                 */
                if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
                    qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 30);
                }
                else{
                    qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(pData->os_data_ptr + 24);
                }
                unifi_trace(priv, UDBG5, "%s: Check if U-APSD operations are triggered for qosControl: 0x%x\n",__FUNCTION__,qosControl);
                uf_process_wmm_deliver_ac_uapsd(priv,srcStaInfo,qosControl,interfaceTag);
            }
        }
    }

#endif

    if( ((frameControl & 0x00f0) >> 4) == QOS_DATA) {
        u8 *qos_control_ptr = (u8*)bulkdata->d[0].os_data_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
        int tID = *qos_control_ptr & IEEE802_11_QC_TID_MASK; /* using ls octet of qos control */
        ba_session_rx_struct *ba_session;
        u8 ba_session_idx = 0;
        /* Get the BA originator address */
        if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
           interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
            ba_addr = sa;
        }else{
            ba_addr = bssid;
        }

        down(&priv->ba_mutex);
        for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
            ba_session = interfacePriv->ba_session_rx[ba_session_idx];
            if (ba_session){
                unifi_trace(priv, UDBG6, "found ba_session=0x%x ba_session_idx=%d", ba_session, ba_session_idx);
                if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == tID)){
                        frame_desc_struct frame_desc;
                        frame_desc.bulkdata = *bulkdata;
                        frame_desc.signal = *signal;
                        frame_desc.sn = (le16_to_cpu(*((u16*)(bulkdata->d[0].os_data_ptr + IEEE802_11_SEQUENCE_CONTROL_OFFSET))) >> 4) & 0xfff;
                        frame_desc.active = TRUE;
                        unifi_trace(priv, UDBG6, "%s: calling process_ba_frame (session=%d)\n", __FUNCTION__, ba_session_idx);
                        process_ba_frame(priv, interfacePriv, ba_session, &frame_desc);
                        up(&priv->ba_mutex);
                        process_ba_complete(priv, interfacePriv);
                        break;
                }
            }
        }
        if (ba_session_idx == MAX_SUPPORTED_BA_SESSIONS_RX){
            up(&priv->ba_mutex);
            unifi_trace(priv, UDBG6, "%s: calling process_amsdu()", __FUNCTION__);
            process_amsdu(priv, signal, bulkdata);
        }
    } else {
        unifi_trace(priv, UDBG6, "calling unifi_rx()");
        unifi_rx(priv, signal, bulkdata);
    }

    /* check if the frames in reorder buffer has aged, the check
     * is done after receive processing so that if the missing frame
     * has arrived in this receive process, then it is handled cleanly.
     *
     * And also this code here takes care that timeout check is made for all
     * the receive indications
     */
    down(&priv->ba_mutex);
    for (i=0; i < MAX_SUPPORTED_BA_SESSIONS_RX; i++){
        ba_session_rx_struct *ba_session;
        ba_session = interfacePriv->ba_session_rx[i];
            if (ba_session){
                check_ba_frame_age_timeout(priv, interfacePriv, ba_session);
            }
    }
    up(&priv->ba_mutex);
    process_ba_complete(priv, interfacePriv);

}
/*
 * ---------------------------------------------------------------------------
 *  uf_set_multicast_list
 *
 *      This function is called by the higher level stack to set
 *      a list of multicast rx addresses.
 *
 *  Arguments:
 *      dev             Network Device pointer.
 *
 *  Returns:
 *      None.
 *
 *  Notes:
 * ---------------------------------------------------------------------------
 */

static void
uf_set_multicast_list(struct net_device *dev)
{
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(dev);
    unifi_priv_t *priv = interfacePriv->privPtr;

#ifdef CSR_NATIVE_LINUX
    unifi_trace(priv, UDBG3, "uf_set_multicast_list unsupported\n");
    return;
#else

    u8 *mc_list = interfacePriv->mc_list;
    struct netdev_hw_addr *mc_addr;
    int mc_addr_count;

    if (priv->init_progress != UNIFI_INIT_COMPLETED) {
        return;
    }

    mc_addr_count = netdev_mc_count(dev);

    unifi_trace(priv, UDBG3,
            "uf_set_multicast_list (count=%d)\n", mc_addr_count);


    /* Not enough space? */
    if (mc_addr_count > UNIFI_MAX_MULTICAST_ADDRESSES) {
        return;
    }

    /* Store the list to be processed by the work item. */
    interfacePriv->mc_list_count = mc_addr_count;
    netdev_hw_addr_list_for_each(mc_addr, &dev->mc) {
        memcpy(mc_list, mc_addr->addr, ETH_ALEN);
        mc_list += ETH_ALEN;
    }

    /* Send a message to the workqueue */
    queue_work(priv->unifi_workqueue, &priv->multicast_list_task);
#endif

} /* uf_set_multicast_list() */

/*
 * ---------------------------------------------------------------------------
 *  netdev_mlme_event_handler
 *
 *      Callback function to be used as the udi_event_callback when registering
 *      as a netdev client.
 *      To use it, a client specifies this function as the udi_event_callback
 *      to ul_register_client(). The signal dispatcher in
 *      unifi_receive_event() will call this function to deliver a signal.
 *
 *  Arguments:
 *      pcli            Pointer to the client instance.
 *      signal          Pointer to the received signal.
 *      signal_len      Size of the signal structure in bytes.
 *      bulkdata        Pointer to structure containing any associated bulk data.
 *      dir             Direction of the signal. Zero means from host,
 *                      non-zero means to host.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void
netdev_mlme_event_handler(ul_client_t *pcli, const u8 *sig_packed, int sig_len,
                          const bulk_data_param_t *bulkdata_o, int dir)
{
    CSR_SIGNAL signal;
    unifi_priv_t *priv = uf_find_instance(pcli->instance);
    int id, r;
    bulk_data_param_t bulkdata;

    /* Just a sanity check */
    if (sig_packed == NULL) {
        return;
    }

    /*
     * This copy is to silence a compiler warning about discarding the
     * const qualifier.
     */
    bulkdata = *bulkdata_o;

    /* Get the unpacked signal */
    r = read_unpack_signal(sig_packed, &signal);
    if (r) {
        /*
         * The CSR_MLME_CONNECTED_INDICATION_ID has a receiverID=0 so will
         * fall through this case. It is safe to ignore this signal.
         */
        unifi_trace(priv, UDBG1,
                    "Netdev - Received unknown signal 0x%.4X.\n",
                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sig_packed));
        return;
    }

    id = signal.SignalPrimitiveHeader.SignalId;
    unifi_trace(priv, UDBG3, "Netdev - Process signal 0x%.4X\n", id);

    /*
     * Take the appropriate action for the signal.
     */
    switch (id) {
        case CSR_MA_PACKET_ERROR_INDICATION_ID:
            process_ma_packet_error_ind(priv, &signal, &bulkdata);
            break;
        case CSR_MA_PACKET_INDICATION_ID:
            process_ma_packet_ind(priv, &signal, &bulkdata);
            break;
        case  CSR_MA_PACKET_CONFIRM_ID:
            process_ma_packet_cfm(priv, &signal, &bulkdata);
            break;
#ifdef CSR_SUPPORT_SME
        case CSR_MLME_SET_TIM_CONFIRM_ID:
            /* Handle TIM confirms from FW & set the station record's TIM state appropriately,
             * In case of failures, tries with max_retransmit limit
             */
            uf_handle_tim_cfm(priv, &signal.u.MlmeSetTimConfirm, signal.SignalPrimitiveHeader.ReceiverProcessId);
            break;
#endif
        case CSR_DEBUG_STRING_INDICATION_ID:
            debug_string_indication(priv, bulkdata.d[0].os_data_ptr, bulkdata.d[0].data_length);
            break;

        case CSR_DEBUG_WORD16_INDICATION_ID:
            debug_word16_indication(priv, &signal);
            break;

        case CSR_DEBUG_GENERIC_CONFIRM_ID:
        case CSR_DEBUG_GENERIC_INDICATION_ID:
            debug_generic_indication(priv, &signal);
            break;
        default:
            break;
    }

} /* netdev_mlme_event_handler() */


/*
 * ---------------------------------------------------------------------------
 *  uf_net_get_name
 *
 *      Retrieve the name (e.g. eth1) associated with this network device
 *
 *  Arguments:
 *      dev             Pointer to the network device.
 *      name            Buffer to write name
 *      len             Size of buffer in bytes
 *
 *  Returns:
 *      None
 *
 *  Notes:
 * ---------------------------------------------------------------------------
 */
void uf_net_get_name(struct net_device *dev, char *name, int len)
{
    *name = '\0';
    if (dev) {
        strlcpy(name, dev->name, (len > IFNAMSIZ) ? IFNAMSIZ : len);
    }

} /* uf_net_get_name */

#ifdef CSR_SUPPORT_WEXT

/*
 * ---------------------------------------------------------------------------
 *  uf_netdev_event
 *
 *     Callback function to handle netdev state changes
 *
 *  Arguments:
 *      notif           Pointer to a notifier_block.
 *      event           Event prompting notification
 *      ptr             net_device pointer
 *
 *  Returns:
 *      None
 *
 *  Notes:
 *   The event handler is global, and may occur on non-UniFi netdevs.
 * ---------------------------------------------------------------------------
 */
static int
uf_netdev_event(struct notifier_block *notif, unsigned long event, void* ptr) {
    struct net_device *netdev = ptr;
    netInterface_priv_t *interfacePriv = (netInterface_priv_t *)netdev_priv(netdev);
    unifi_priv_t *priv = NULL;
    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};

    /* Check that the event is for a UniFi netdev. If it's not, the netdev_priv
     * structure is not safe to use.
     */
    if (uf_find_netdev_priv(interfacePriv) == -1) {
        unifi_trace(NULL, UDBG1, "uf_netdev_event: ignore e=%d, ptr=%p, priv=%p %s\n",
                    event, ptr, interfacePriv, netdev->name);
        return 0;
    }

    switch(event) {
    case NETDEV_CHANGE:
        priv = interfacePriv->privPtr;
        unifi_trace(priv, UDBG1, "NETDEV_CHANGE: %p %s %s waiting for it\n",
                    ptr,
                    netdev->name,
                    interfacePriv->wait_netdev_change ? "" : "not");

        if (interfacePriv->wait_netdev_change) {
            netif_tx_wake_all_queues(priv->netdev[interfacePriv->InterfaceTag]);
            interfacePriv->connected = UnifiConnected;
            interfacePriv->wait_netdev_change = FALSE;
            /* Note: passing the broadcast address here will allow anyone to attempt to join our adhoc network */
            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;

    default:
        break;
    }
    return 0;
}

static struct notifier_block uf_netdev_notifier = {
    .notifier_call = uf_netdev_event,
};
#endif /* CSR_SUPPORT_WEXT */


static void
        process_amsdu(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
    u32 offset;
    u32 length = bulkdata->d[0].data_length;
    u32 subframe_length, subframe_body_length, dot11_hdr_size;
    u8 *ptr;
    bulk_data_param_t subframe_bulkdata;
    u8 *dot11_hdr_ptr = (u8*)bulkdata->d[0].os_data_ptr;
    CsrResult csrResult;
    u16 frameControl;
    u8 *qos_control_ptr;

    frameControl = le16_to_cpu(*((u16*)dot11_hdr_ptr));
    qos_control_ptr = dot11_hdr_ptr + (((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK))?30: 24);
    if(!(*qos_control_ptr & IEEE802_11_QC_A_MSDU_PRESENT)) {
        unifi_trace(priv, UDBG6, "%s: calling unifi_rx()", __FUNCTION__);
        unifi_rx(priv, signal, bulkdata);
        return;
    }
    *qos_control_ptr &= ~(IEEE802_11_QC_A_MSDU_PRESENT);

    ptr = qos_control_ptr + 2;
    offset = dot11_hdr_size = ptr - dot11_hdr_ptr;

    while(length > (offset + sizeof(struct ethhdr) + sizeof(llc_snap_hdr_t))) {
        subframe_body_length = ntohs(((struct ethhdr*)ptr)->h_proto);
        if(subframe_body_length > IEEE802_11_MAX_DATA_LEN) {
            unifi_error(priv, "%s: bad subframe_body_length = %d\n", __FUNCTION__, subframe_body_length);
            break;
        }
        subframe_length = sizeof(struct ethhdr) + subframe_body_length;
        memset(&subframe_bulkdata, 0, sizeof(bulk_data_param_t));

        csrResult = unifi_net_data_malloc(priv, &subframe_bulkdata.d[0], dot11_hdr_size + subframe_body_length);

        if (csrResult != CSR_RESULT_SUCCESS) {
            unifi_error(priv, "%s: unifi_net_data_malloc failed\n", __FUNCTION__);
            break;
        }

        memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr, dot11_hdr_ptr, dot11_hdr_size);


        /* When to DS=0 and from DS=0, address 3 will already have BSSID so no need to re-program */
        if ((frameControl & IEEE802_11_FC_TO_DS_MASK) && !(frameControl & IEEE802_11_FC_FROM_DS_MASK)){
                memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET, ((struct ethhdr*)ptr)->h_dest, ETH_ALEN);
        }
        else if (!(frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)){
                memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + IEEE802_11_ADDR3_OFFSET,
                         ((struct ethhdr*)ptr)->h_source,
                           ETH_ALEN);
        }

        memcpy((u8*)subframe_bulkdata.d[0].os_data_ptr + dot11_hdr_size,
                ptr + sizeof(struct ethhdr),
                             subframe_body_length);
        unifi_trace(priv, UDBG6, "%s: calling unifi_rx. length = %d subframe_length = %d\n", __FUNCTION__, length, subframe_length);
        unifi_rx(priv, signal, &subframe_bulkdata);

        subframe_length = (subframe_length + 3)&(~0x3);
        ptr += subframe_length;
        offset += subframe_length;
    }
    unifi_net_data_free(priv, &bulkdata->d[0]);
}


#define SN_TO_INDEX(__ba_session, __sn) (((__sn - __ba_session->start_sn) & 0xFFF) % __ba_session->wind_size)


#define ADVANCE_EXPECTED_SN(__ba_session) \
{ \
    __ba_session->expected_sn++; \
    __ba_session->expected_sn &= 0xFFF; \
}

#define FREE_BUFFER_SLOT(__ba_session, __index) \
{ \
    __ba_session->occupied_slots--; \
    __ba_session->buffer[__index].active = FALSE; \
    ADVANCE_EXPECTED_SN(__ba_session); \
}

static void add_frame_to_ba_complete(unifi_priv_t *priv,
                          netInterface_priv_t *interfacePriv,
                          frame_desc_struct *frame_desc)
{
    interfacePriv->ba_complete[interfacePriv->ba_complete_index] = *frame_desc;
    interfacePriv->ba_complete_index++;
}


static void update_expected_sn(unifi_priv_t *priv,
                          netInterface_priv_t *interfacePriv,
                          ba_session_rx_struct *ba_session,
                          u16 sn)
{
    int i, j;
    u16 gap;

    gap = (sn - ba_session->expected_sn) & 0xFFF;
    unifi_trace(priv, UDBG6, "%s: process the frames up to new_expected_sn = %d gap = %d\n", __FUNCTION__, sn, gap);
    for(j = 0; j < gap && j < ba_session->wind_size; j++) {
        i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
        unifi_trace(priv, UDBG6, "%s: process the slot index = %d\n", __FUNCTION__, i);
        if(ba_session->buffer[i].active) {
            add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
            unifi_trace(priv, UDBG6, "%s: process the frame at index = %d expected_sn = %d\n", __FUNCTION__, i, ba_session->expected_sn);
            FREE_BUFFER_SLOT(ba_session, i);
        } else {
            unifi_trace(priv, UDBG6, "%s: empty slot at index = %d\n", __FUNCTION__, i);
            ADVANCE_EXPECTED_SN(ba_session);
        }
    }
    ba_session->expected_sn = sn;
}


static void complete_ready_sequence(unifi_priv_t *priv,
                               netInterface_priv_t *interfacePriv,
                               ba_session_rx_struct *ba_session)
{
    int i;

    i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
    while (ba_session->buffer[i].active) {
        add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
        unifi_trace(priv, UDBG6, "%s: completed stored frame(expected_sn=%d) at i = %d\n", __FUNCTION__, ba_session->expected_sn, i);
        FREE_BUFFER_SLOT(ba_session, i);
        i = SN_TO_INDEX(ba_session, ba_session->expected_sn);
    }
}


void scroll_ba_window(unifi_priv_t *priv,
                                netInterface_priv_t *interfacePriv,
                                ba_session_rx_struct *ba_session,
                                u16 sn)
{
    if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {
        update_expected_sn(priv, interfacePriv, ba_session, sn);
        complete_ready_sequence(priv, interfacePriv, ba_session);
    }
}


static int consume_frame_or_get_buffer_index(unifi_priv_t *priv,
                                            netInterface_priv_t *interfacePriv,
                                            ba_session_rx_struct *ba_session,
                                            u16 sn,
                                            frame_desc_struct *frame_desc) {
    int i;
    u16 sn_temp;

    if(((sn - ba_session->expected_sn) & 0xFFF) <= 2048) {

        /* once we are in BA window, set the flag for BA trigger */
        if(!ba_session->trigger_ba_after_ssn){
            ba_session->trigger_ba_after_ssn = TRUE;
        }

        sn_temp = ba_session->expected_sn + ba_session->wind_size;
        unifi_trace(priv, UDBG6, "%s: new frame: sn=%d\n", __FUNCTION__, sn);
        if(!(((sn - sn_temp) & 0xFFF) > 2048)) {
            u16 new_expected_sn;
            unifi_trace(priv, UDBG6, "%s: frame is out of window\n", __FUNCTION__);
            sn_temp = (sn - ba_session->wind_size) & 0xFFF;
            new_expected_sn = (sn_temp + 1) & 0xFFF;
            update_expected_sn(priv, interfacePriv, ba_session, new_expected_sn);
        }
        i = -1;
        if (sn == ba_session->expected_sn) {
            unifi_trace(priv, UDBG6, "%s: sn = ba_session->expected_sn = %d\n", __FUNCTION__, sn);
            ADVANCE_EXPECTED_SN(ba_session);
            add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
        } else {
            i = SN_TO_INDEX(ba_session, sn);
            unifi_trace(priv, UDBG6, "%s: sn(%d) != ba_session->expected_sn(%d), i = %d\n", __FUNCTION__, sn, ba_session->expected_sn, i);
            if (ba_session->buffer[i].active) {
                unifi_trace(priv, UDBG6, "%s: free frame at i = %d\n", __FUNCTION__, i);
                i = -1;
                unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
            }
        }
    } else {
        i = -1;
        if(!ba_session->trigger_ba_after_ssn){
            unifi_trace(priv, UDBG6, "%s: frame before ssn, pass it up: sn=%d\n", __FUNCTION__, sn);
            add_frame_to_ba_complete(priv, interfacePriv, frame_desc);
        }else{
            unifi_trace(priv, UDBG6, "%s: old frame, drop: sn=%d, expected_sn=%d\n", __FUNCTION__, sn, ba_session->expected_sn);
            unifi_net_data_free(priv, &frame_desc->bulkdata.d[0]);
        }
    }
    return i;
}



static void process_ba_frame(unifi_priv_t *priv,
                                             netInterface_priv_t *interfacePriv,
                                             ba_session_rx_struct *ba_session,
                                             frame_desc_struct *frame_desc)
{
    int i;
    u16 sn = frame_desc->sn;

    if (ba_session->timeout) {
        mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
    }
    unifi_trace(priv, UDBG6, "%s: got frame(sn=%d)\n", __FUNCTION__, sn);

    i = consume_frame_or_get_buffer_index(priv, interfacePriv, ba_session, sn, frame_desc);
    if(i >= 0) {
        unifi_trace(priv, UDBG6, "%s: store frame(sn=%d) at i = %d\n", __FUNCTION__, sn, i);
        ba_session->buffer[i] = *frame_desc;
        ba_session->buffer[i].recv_time = CsrTimeGet(NULL);
        ba_session->occupied_slots++;
    } else {
        unifi_trace(priv, UDBG6, "%s: frame consumed - sn = %d\n", __FUNCTION__, sn);
    }
    complete_ready_sequence(priv, interfacePriv, ba_session);
}


static void process_ba_complete(unifi_priv_t *priv, netInterface_priv_t *interfacePriv)
{
    frame_desc_struct *frame_desc;
    u8 i;

    for(i = 0; i < interfacePriv->ba_complete_index; i++) {
        frame_desc = &interfacePriv->ba_complete[i];
        unifi_trace(priv, UDBG6, "%s: calling process_amsdu()\n", __FUNCTION__);
        process_amsdu(priv, &frame_desc->signal, &frame_desc->bulkdata);
    }
    interfacePriv->ba_complete_index = 0;

}


/* Check if the frames in BA reoder buffer has aged and
 * if so release the frames to upper processes and move
 * the window
 */
static void check_ba_frame_age_timeout( unifi_priv_t *priv,
                                        netInterface_priv_t *interfacePriv,
                                        ba_session_rx_struct *ba_session)
{
    u32 now;
    u32 age;
    u8 i, j;
    u16 sn_temp;

    /* gap is started at 1 because we have buffered frames and
     * hence a minimum gap of 1 exists
     */
    u8 gap=1;

    now = CsrTimeGet(NULL);

    if (ba_session->occupied_slots)
    {
        /* expected sequence has not arrived so start searching from next
         * sequence number until a frame is available and determine the gap.
         * Check if the frame available has timedout, if so advance the
         * expected sequence number and release the frames
         */
        sn_temp = (ba_session->expected_sn + 1) & 0xFFF;

        for(j = 0; j < ba_session->wind_size; j++)
        {
            i = SN_TO_INDEX(ba_session, sn_temp);

            if(ba_session->buffer[i].active)
            {
                unifi_trace(priv, UDBG6, "check age at slot index = %d sn = %d recv_time = %u now = %u\n",
                                        i,
                                        ba_session->buffer[i].sn,
                                        ba_session->buffer[i].recv_time,
                                        now);

                if (ba_session->buffer[i].recv_time > now)
                {
                    /* timer wrap */
                    age = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, ba_session->buffer[i].recv_time), now);
                }
                else
                {
                    age = (u32)CsrTimeSub(now, ba_session->buffer[i].recv_time);
                }

                if (age >= CSR_WIFI_BA_MPDU_FRAME_AGE_TIMEOUT)
                {
                    unifi_trace(priv, UDBG2, "release the frame at index = %d gap = %d expected_sn = %d sn = %d\n",
                                            i,
                                            gap,
                                            ba_session->expected_sn,
                                            ba_session->buffer[i].sn);

                    /* if it has timedout don't wait for missing frames, move the window */
                    while (gap--)
                    {
                        ADVANCE_EXPECTED_SN(ba_session);
                    }
                    add_frame_to_ba_complete(priv, interfacePriv, &ba_session->buffer[i]);
                    FREE_BUFFER_SLOT(ba_session, i);
                    complete_ready_sequence(priv, interfacePriv, ba_session);
                }
                break;

            }
            else
            {
                /* advance temp sequence number and frame gap */
                sn_temp = (sn_temp + 1) & 0xFFF;
                gap++;
            }
        }
    }
}


static void process_ma_packet_error_ind(unifi_priv_t *priv, CSR_SIGNAL *signal, bulk_data_param_t *bulkdata)
{
    u16 interfaceTag;
    const CSR_MA_PACKET_ERROR_INDICATION *pkt_err_ind = &signal->u.MaPacketErrorIndication;
    netInterface_priv_t *interfacePriv;
    ba_session_rx_struct *ba_session;
    u8 ba_session_idx = 0;
    CSR_PRIORITY        UserPriority;
    CSR_SEQUENCE_NUMBER sn;

    interfaceTag = (pkt_err_ind->VirtualInterfaceIdentifier & 0xff);


    /* Sanity check that the VIF refers to a sensible interface */
    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES)
    {
        unifi_error(priv, "%s: MaPacketErrorIndication indication with bad interfaceTag %d\n", __FUNCTION__, interfaceTag);
        return;
    }

    interfacePriv = priv->interfacePriv[interfaceTag];
    UserPriority = pkt_err_ind->UserPriority;
    if(UserPriority > 15) {
        unifi_error(priv, "%s: MaPacketErrorIndication indication with bad UserPriority=%d\n", __FUNCTION__, UserPriority);
    }
    sn = pkt_err_ind->SequenceNumber;

    down(&priv->ba_mutex);
    /* To find the right ba_session loop through the BA sessions, compare MAC address and tID */
    for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_RX; ba_session_idx++){
        ba_session = interfacePriv->ba_session_rx[ba_session_idx];
        if (ba_session){
            if ((!memcmp(ba_session->macAddress.a, pkt_err_ind->PeerQstaAddress.x, ETH_ALEN)) && (ba_session->tID == UserPriority)){
                if (ba_session->timeout) {
                    mod_timer(&ba_session->timer, (jiffies + usecs_to_jiffies((ba_session->timeout) * 1024)));
                }
                scroll_ba_window(priv, interfacePriv, ba_session, sn);
                break;
            }
        }
    }

    up(&priv->ba_mutex);
    process_ba_complete(priv, interfacePriv);
}


