linux/drivers/staging/csr/unifi_pdu_processing.c
<<
>>
Prefs
   1/*
   2 * ---------------------------------------------------------------------------
   3 * FILE:     unifi_pdu_processing.c
   4 *
   5 * PURPOSE:
   6 *      This file provides the PDU handling functionality before it gets sent to unfi and after
   7 *      receiving a PDU from unifi
   8 *
   9 * Copyright (C) 2010 by Cambridge Silicon Radio Ltd.
  10 *
  11 * Refer to LICENSE.txt included with this source code for details on
  12 * the license terms.
  13 *
  14 * ---------------------------------------------------------------------------
  15 */
  16
  17#include <linux/types.h>
  18#include <linux/etherdevice.h>
  19#include <linux/vmalloc.h>
  20
  21#include "csr_wifi_hip_unifi.h"
  22#include "csr_wifi_hip_conversions.h"
  23#include "csr_time.h"
  24#include "unifi_priv.h"
  25#include <net/pkt_sched.h>
  26
  27#ifdef CSR_SUPPORT_SME
  28static void _update_buffered_pkt_params_after_alignment(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
  29                                                        tx_buffered_packets_t* buffered_pkt)
  30{
  31    struct sk_buff *skb ;
  32    u32 align_offset;
  33
  34    if (priv == NULL || bulkdata == NULL || buffered_pkt == NULL){
  35        return;
  36    }
  37
  38    skb = (struct sk_buff*)bulkdata->d[0].os_net_buf_ptr;
  39    align_offset = (u32)(long)(bulkdata->d[0].os_data_ptr) & (CSR_WIFI_ALIGN_BYTES-1);
  40    if(align_offset){
  41        skb_pull(skb,align_offset);
  42    }
  43
  44    buffered_pkt->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
  45    buffered_pkt->bulkdata.data_length = bulkdata->d[0].data_length;
  46    buffered_pkt->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
  47    buffered_pkt->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
  48}
  49#endif
  50
  51void
  52unifi_frame_ma_packet_req(unifi_priv_t *priv, CSR_PRIORITY priority,
  53                          CSR_RATE TransmitRate, CSR_CLIENT_TAG hostTag,
  54                          u16 interfaceTag, CSR_TRANSMISSION_CONTROL transmissionControl,
  55                          CSR_PROCESS_ID leSenderProcessId, u8 *peerMacAddress,
  56                          CSR_SIGNAL *signal)
  57{
  58
  59    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
  60    netInterface_priv_t *interfacePriv;
  61    u8 ba_session_idx = 0;
  62    ba_session_tx_struct *ba_session = NULL;
  63    u8 *ba_addr = NULL;
  64
  65    interfacePriv = priv->interfacePriv[interfaceTag];
  66
  67        unifi_trace(priv, UDBG5,
  68                "In unifi_frame_ma_packet_req, Frame for Peer: %pMF\n",
  69                peerMacAddress);
  70    signal->SignalPrimitiveHeader.SignalId = CSR_MA_PACKET_REQUEST_ID;
  71    signal->SignalPrimitiveHeader.ReceiverProcessId = 0;
  72    signal->SignalPrimitiveHeader.SenderProcessId = leSenderProcessId;
  73
  74    /* Fill the MA-PACKET.req */
  75    req->Priority = priority;
  76    unifi_trace(priv, UDBG3, "Tx Frame with Priority: 0x%x\n", req->Priority);
  77
  78    /* A value of 0 is used for auto selection of rates. But for P2P GO case
  79     * for action frames the rate is governed by SME. Hence instead of 0,
  80     * the rate is filled in with the value passed here
  81     */
  82    req->TransmitRate = TransmitRate;
  83
  84    /* packets from netdev then no confirm required but packets from
  85     * Nme/Sme eapol data frames requires the confirmation
  86     */
  87    req->TransmissionControl = transmissionControl;
  88    req->VirtualInterfaceIdentifier =
  89           uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
  90    memcpy(req->Ra.x, peerMacAddress, ETH_ALEN);
  91
  92    if (hostTag == 0xffffffff) {
  93        req->HostTag = interfacePriv->tag++;
  94        req->HostTag |= 0x40000000;
  95        unifi_trace(priv, UDBG3, "new host tag assigned = 0x%x\n", req->HostTag);
  96        interfacePriv->tag &= 0x0fffffff;
  97    } else {
  98        req->HostTag = hostTag;
  99        unifi_trace(priv, UDBG3, "host tag got from SME  = 0x%x\n", req->HostTag);
 100    }
 101    /* check if BA session exists for the peer MAC address on same tID */
 102    if(interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP ||
 103       interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO){
 104        ba_addr = peerMacAddress;
 105    }else{
 106        ba_addr = interfacePriv->bssid.a;
 107    }
 108    for (ba_session_idx=0; ba_session_idx < MAX_SUPPORTED_BA_SESSIONS_TX; ba_session_idx++){
 109        ba_session = interfacePriv->ba_session_tx[ba_session_idx];
 110        if (ba_session){
 111           if ((!memcmp(ba_session->macAddress.a, ba_addr, ETH_ALEN)) && (ba_session->tID == priority)){
 112                req->TransmissionControl |= CSR_ALLOW_BA;
 113                break;
 114            }
 115        }
 116    }
 117
 118    unifi_trace(priv, UDBG5, "leaving unifi_frame_ma_packet_req\n");
 119}
 120
 121#ifdef CSR_SUPPORT_SME
 122
 123#define TRANSMISSION_CONTROL_TRIGGER_MASK 0x0001
 124#define TRANSMISSION_CONTROL_EOSP_MASK 0x0002
 125
 126static
 127int frame_and_send_queued_pdu(unifi_priv_t* priv,tx_buffered_packets_t* buffered_pkt,
 128            CsrWifiRouterCtrlStaInfo_t *staRecord,u8 moreData , u8 eosp)
 129{
 130
 131    CSR_SIGNAL signal;
 132    bulk_data_param_t bulkdata;
 133    int result;
 134    u8 toDs, fromDs, macHeaderLengthInBytes = MAC_HEADER_SIZE;
 135    u8 *qc;
 136    u16 *fc = (u16*)(buffered_pkt->bulkdata.os_data_ptr);
 137    unsigned long lock_flags;
 138    unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu with moreData: %d , EOSP: %d\n",moreData,eosp);
 139    unifi_frame_ma_packet_req(priv, buffered_pkt->priority, buffered_pkt->rate, buffered_pkt->hostTag,
 140               buffered_pkt->interfaceTag, buffered_pkt->transmissionControl,
 141               buffered_pkt->leSenderProcessId, buffered_pkt->peerMacAddress.a, &signal);
 142    bulkdata.d[0].os_data_ptr = buffered_pkt->bulkdata.os_data_ptr;
 143    bulkdata.d[0].data_length = buffered_pkt->bulkdata.data_length;
 144    bulkdata.d[0].os_net_buf_ptr = buffered_pkt->bulkdata.os_net_buf_ptr;
 145    bulkdata.d[0].net_buf_length = buffered_pkt->bulkdata.net_buf_length;
 146    bulkdata.d[1].os_data_ptr = NULL;
 147    bulkdata.d[1].data_length = 0;
 148    bulkdata.d[1].os_net_buf_ptr =0;
 149    bulkdata.d[1].net_buf_length =0;
 150
 151    if(moreData) {
 152        *fc |= cpu_to_le16(IEEE802_11_FC_MOREDATA_MASK);
 153    } else {
 154        *fc &= cpu_to_le16(~IEEE802_11_FC_MOREDATA_MASK);
 155    }
 156
 157    if((staRecord != NULL)&& (staRecord->wmmOrQosEnabled == TRUE))
 158    {
 159        unifi_trace(priv, UDBG3, "frame_and_send_queued_pdu WMM Enabled: %d \n",staRecord->wmmOrQosEnabled);
 160
 161        toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
 162        fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;
 163
 164        switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
 165        {
 166            case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
 167            case IEEE802_11_FC_TYPE_QOS_NULL & IEEE80211_FC_SUBTYPE_MASK:
 168                /* If both are set then the Address4 exists (only for AP) */
 169                if (fromDs && toDs) {
 170                    /* 6 is the size of Address4 field */
 171                    macHeaderLengthInBytes += (QOS_CONTROL_HEADER_SIZE + 6);
 172                } else {
 173                    macHeaderLengthInBytes += QOS_CONTROL_HEADER_SIZE;
 174                }
 175
 176                /* If order bit set then HT control field is the part of MAC header */
 177                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
 178                    macHeaderLengthInBytes += HT_CONTROL_HEADER_SIZE;
 179                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-6));
 180                } else {
 181                    qc = (u8*)(buffered_pkt->bulkdata.os_data_ptr + (macHeaderLengthInBytes-2));
 182                }
 183                *qc = eosp ? *qc | (1 << 4) : *qc & (~(1 << 4));
 184                break;
 185            default:
 186                if (fromDs && toDs)
 187                    macHeaderLengthInBytes += 6;
 188        }
 189
 190    }
 191    result = ul_send_signal_unpacked(priv, &signal, &bulkdata);
 192    if(result){
 193        _update_buffered_pkt_params_after_alignment(priv, &bulkdata,buffered_pkt);
 194    }
 195
 196 /* Decrement the packet counts queued in driver */
 197    if (result != -ENOSPC) {
 198        /* protect entire counter updation by disabling preemption */
 199        if (!priv->noOfPktQueuedInDriver) {
 200            unifi_error(priv, "packets queued in driver 0 still decrementing\n");
 201        } else {
 202            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 203            priv->noOfPktQueuedInDriver--;
 204            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 205        }
 206        /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
 207        if (staRecord) {
 208            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
 209            if (!staRecord->noOfPktQueued) {
 210                unifi_error(priv, "packets queued in driver per station is 0 still decrementing\n");
 211            } else {
 212                staRecord->noOfPktQueued--;
 213            }
 214            /* if the STA alive probe frame has failed then reset the saved host tag */
 215            if (result){
 216                if (staRecord->nullDataHostTag == buffered_pkt->hostTag){
 217                    staRecord->nullDataHostTag = INVALID_HOST_TAG;
 218                }
 219            }
 220            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
 221        }
 222
 223    }
 224    return result;
 225}
 226#ifdef CSR_SUPPORT_SME
 227static
 228void set_eosp_transmit_ctrl(unifi_priv_t *priv, struct list_head *txList)
 229{
 230    /* dequeue the tx data packets from the appropriate queue */
 231    tx_buffered_packets_t *tx_q_item = NULL;
 232    struct list_head *listHead;
 233    struct list_head *placeHolder;
 234    unsigned long lock_flags;
 235
 236
 237    unifi_trace(priv, UDBG5, "entering set_eosp_transmit_ctrl\n");
 238    /* check for list empty */
 239    if (list_empty(txList)) {
 240        unifi_warning(priv, "In set_eosp_transmit_ctrl, the list is empty\n");
 241        return;
 242    }
 243
 244    /* return the last node , and modify it. */
 245
 246    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 247    list_for_each_prev_safe(listHead, placeHolder, txList) {
 248        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
 249        tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
 250        tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
 251        unifi_trace(priv, UDBG1,
 252                "set_eosp_transmit_ctrl Transmission Control = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
 253        unifi_trace(priv,UDBG3,"in set_eosp_transmit_ctrl no.of buffered frames %d\n",priv->noOfPktQueuedInDriver);
 254        break;
 255    }
 256    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 257    unifi_trace(priv, UDBG1,"List Empty %d\n",list_empty(txList));
 258    unifi_trace(priv, UDBG5, "leaving set_eosp_transmit_ctrl\n");
 259    return;
 260}
 261
 262static
 263void send_vif_availibility_rsp(unifi_priv_t *priv,CSR_VIF_IDENTIFIER vif,CSR_RESULT_CODE resultCode)
 264{
 265    CSR_SIGNAL signal;
 266    CSR_MA_VIF_AVAILABILITY_RESPONSE *rsp;
 267    bulk_data_param_t *bulkdata = NULL;
 268    int r;
 269
 270    unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : invoked with resultCode = %d \n", resultCode);
 271
 272    memset(&signal,0,sizeof(CSR_SIGNAL));
 273    rsp = &signal.u.MaVifAvailabilityResponse;
 274    rsp->VirtualInterfaceIdentifier = vif;
 275    rsp->ResultCode = resultCode;
 276    signal.SignalPrimitiveHeader.SignalId = CSR_MA_VIF_AVAILABILITY_RESPONSE_ID;
 277    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
 278    signal.SignalPrimitiveHeader.SenderProcessId = priv->netdev_client->sender_id;
 279
 280    /* Send the signal to UniFi */
 281    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
 282    if(r) {
 283        unifi_error(priv,"Availibility response sending failed %x status %d\n",vif,r);
 284    }
 285    else {
 286        unifi_trace(priv, UDBG3, "send_vif_availibility_rsp : status = %d \n", r);
 287    }
 288}
 289#endif
 290
 291static
 292void verify_and_accomodate_tx_packet(unifi_priv_t *priv)
 293{
 294    tx_buffered_packets_t *tx_q_item;
 295    unsigned long lock_flags;
 296    struct list_head *listHead, *list;
 297    struct list_head *placeHolder;
 298    u8 i, j,eospFramedeleted=0;
 299    u8 thresholdExcedeDueToBroadcast = TRUE;
 300    /* it will be made it interface Specific in the future when multi interfaces are supported ,
 301    right now interface 0 is considered */
 302    netInterface_priv_t *interfacePriv = priv->interfacePriv[0];
 303    CsrWifiRouterCtrlStaInfo_t *staInfo = NULL;
 304
 305    unifi_trace(priv, UDBG3, "entering verify_and_accomodate_tx_packet\n");
 306
 307    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
 308        staInfo = interfacePriv->staInfo[i];
 309            if (staInfo && (staInfo->noOfPktQueued >= CSR_WIFI_DRIVER_MAX_PKT_QUEUING_THRESHOLD_PER_PEER)) {
 310            /* remove the first(oldest) packet from the all the access catogory, since data
 311             * packets for station record crossed the threshold limit (64 for AP supporting
 312             * 8 peers)
 313             */
 314            unifi_trace(priv,UDBG3,"number of station pkts queued=  %d for sta id = %d\n", staInfo->noOfPktQueued, staInfo->aid);
 315            for(j = 0; j < MAX_ACCESS_CATOGORY; j++) {
 316                list = &staInfo->dataPdu[j];
 317                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 318                list_for_each_safe(listHead, placeHolder, list) {
 319                    tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
 320                    list_del(listHead);
 321                    thresholdExcedeDueToBroadcast = FALSE;
 322                    unifi_net_data_free(priv, &tx_q_item->bulkdata);
 323                    kfree(tx_q_item);
 324                    tx_q_item = NULL;
 325                    if (!priv->noOfPktQueuedInDriver) {
 326                        unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
 327                    } else {
 328                        /* protection provided by spinlock */
 329                        priv->noOfPktQueuedInDriver--;
 330
 331                    }
 332                    /* Sta Record is available for all unicast (except genericMgt Frames) & in other case its NULL */
 333                    if (!staInfo->noOfPktQueued) {
 334                        unifi_error(priv, "packets queued in driver per station is 0 still decrementing in %s\n", __FUNCTION__);
 335                    } else {
 336                        spin_lock(&priv->staRecord_lock);
 337                        staInfo->noOfPktQueued--;
 338                        spin_unlock(&priv->staRecord_lock);
 339                    }
 340                    break;
 341                }
 342                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 343            }
 344        }
 345    }
 346    if (thresholdExcedeDueToBroadcast &&  interfacePriv->noOfbroadcastPktQueued > CSR_WIFI_DRIVER_MINIMUM_BROADCAST_PKT_THRESHOLD ) {
 347        /* Remove the packets from genericMulticastOrBroadCastFrames queue
 348         * (the max packets in driver is reached due to broadcast/multicast frames)
 349         */
 350        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 351        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
 352            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
 353            if(eospFramedeleted){
 354                tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
 355                tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
 356                unifi_trace(priv, UDBG1,"updating eosp for next packet hostTag:= 0x%x ",tx_q_item->hostTag);
 357                eospFramedeleted =0;
 358                break;
 359            }
 360
 361            if(tx_q_item->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK ){
 362               eospFramedeleted = 1;
 363            }
 364            unifi_trace(priv,UDBG1, "freeing of multicast packets ToC = 0x%x hostTag = 0x%x \n",tx_q_item->transmissionControl,tx_q_item->hostTag);
 365            list_del(listHead);
 366            unifi_net_data_free(priv, &tx_q_item->bulkdata);
 367            kfree(tx_q_item);
 368            priv->noOfPktQueuedInDriver--;
 369            spin_lock(&priv->staRecord_lock);
 370            interfacePriv->noOfbroadcastPktQueued--;
 371            spin_unlock(&priv->staRecord_lock);
 372            if(!eospFramedeleted){
 373                break;
 374            }
 375        }
 376        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 377    }
 378    unifi_trace(priv, UDBG3, "leaving verify_and_accomodate_tx_packet\n");
 379}
 380
 381static
 382CsrResult enque_tx_data_pdu(unifi_priv_t *priv, bulk_data_param_t *bulkdata,
 383                            struct list_head *list, CSR_SIGNAL *signal,
 384                            u8 requeueOnSamePos)
 385{
 386
 387    /* queue the tx data packets on to appropriate queue */
 388    CSR_MA_PACKET_REQUEST *req = &signal->u.MaPacketRequest;
 389    tx_buffered_packets_t *tx_q_item;
 390    unsigned long lock_flags;
 391
 392    unifi_trace(priv, UDBG5, "entering enque_tx_data_pdu\n");
 393    if(!list) {
 394       unifi_error(priv,"List is not specified\n");
 395       return CSR_RESULT_FAILURE;
 396    }
 397
 398    /* Removes aged packets & adds the incoming packet */
 399    if (priv->noOfPktQueuedInDriver >= CSR_WIFI_DRIVER_SUPPORT_FOR_MAX_PKT_QUEUEING) {
 400        unifi_trace(priv,UDBG3,"number of pkts queued=  %d \n", priv->noOfPktQueuedInDriver);
 401        verify_and_accomodate_tx_packet(priv);
 402    }
 403
 404
 405
 406    tx_q_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
 407    if (tx_q_item == NULL) {
 408        unifi_error(priv,
 409                "Failed to allocate %d bytes for tx packet record\n",
 410                sizeof(tx_buffered_packets_t));
 411        return CSR_RESULT_FAILURE;
 412    }
 413
 414    /* disable the preemption */
 415    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 416    INIT_LIST_HEAD(&tx_q_item->q);
 417    /* fill the tx_q structure members */
 418    tx_q_item->bulkdata.os_data_ptr = bulkdata->d[0].os_data_ptr;
 419    tx_q_item->bulkdata.data_length = bulkdata->d[0].data_length;
 420    tx_q_item->bulkdata.os_net_buf_ptr = bulkdata->d[0].os_net_buf_ptr;
 421    tx_q_item->bulkdata.net_buf_length = bulkdata->d[0].net_buf_length;
 422    tx_q_item->interfaceTag = req->VirtualInterfaceIdentifier & 0xff;
 423    tx_q_item->hostTag = req->HostTag;
 424    tx_q_item->leSenderProcessId = signal->SignalPrimitiveHeader.SenderProcessId;
 425    tx_q_item->transmissionControl = req->TransmissionControl;
 426    tx_q_item->priority = req->Priority;
 427    tx_q_item->rate = req->TransmitRate;
 428    memcpy(tx_q_item->peerMacAddress.a, req->Ra.x, ETH_ALEN);
 429
 430
 431
 432    if (requeueOnSamePos) {
 433        list_add(&tx_q_item->q, list);
 434    } else {
 435        list_add_tail(&tx_q_item->q, list);
 436    }
 437
 438    /* Count of packet queued in driver */
 439    priv->noOfPktQueuedInDriver++;
 440    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 441    unifi_trace(priv, UDBG5, "leaving enque_tx_data_pdu\n");
 442    return CSR_RESULT_SUCCESS;
 443}
 444
 445#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
 446CsrResult unifi_reque_ma_packet_request (void *ospriv, u32 host_tag,
 447                                         u16 txStatus, bulk_data_desc_t *bulkDataDesc)
 448{
 449    CsrResult status = CSR_RESULT_SUCCESS;
 450    unifi_priv_t *priv = (unifi_priv_t*)ospriv;
 451    netInterface_priv_t *interfacePriv;
 452    struct list_head *list = NULL;
 453    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
 454    bulk_data_param_t bulkData;
 455    CSR_SIGNAL signal;
 456    CSR_PRIORITY priority = 0;
 457    u16 interfaceTag = 0;
 458    unifi_TrafficQueue priority_q;
 459    u16 frameControl = 0, frameType = 0;
 460    unsigned long lock_flags;
 461
 462    interfacePriv = priv->interfacePriv[interfaceTag];
 463
 464    /* If the current mode is not AP or P2PGO then just return failure
 465     * to clear the hip slot
 466     */
 467    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
 468        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO))) {
 469        return CSR_RESULT_FAILURE;
 470    }
 471
 472    unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: host_tag = 0x%x\n", host_tag);
 473
 474    staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv,
 475                                                                    (((u8 *) bulkDataDesc->os_data_ptr) + 4),
 476                                                                    interfaceTag);
 477    if (NULL == staRecord) {
 478        unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid STA record \n");
 479        return CSR_RESULT_FAILURE;
 480    }
 481
 482    /* Update TIM if MA-PACKET.cfm fails with status as Tx-retry-limit or No-BSS and then just return failure
 483     * to clear the hip slot associated with the Packet
 484     */
 485    if (CSR_TX_RETRY_LIMIT == txStatus || CSR_TX_NO_BSS == txStatus) {
 486        if (staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING)
 487        {
 488            unifi_trace(priv, UDBG2, "unifi_reque_ma_packet_request: CFM failed with Retry Limit or No BSS-->update TIM\n");
 489            if (!staRecord->timRequestPendingFlag) {
 490                update_tim(priv, staRecord->aid, 1, interfaceTag, staRecord->assignedHandle);
 491            }
 492            else {
 493                /* Cache the TimSet value so that it will processed immidiatly after
 494                 * completing the current setTim Request
 495                 */
 496                staRecord->updateTimReqQueued = 1;
 497                unifi_trace(priv, UDBG6, "unifi_reque_ma_packet_request: One more UpdateTim Request(:%d)Queued for AID %x\n",
 498                                         staRecord->updateTimReqQueued, staRecord->aid);
 499            }
 500        }
 501        return CSR_RESULT_FAILURE;
 502    }
 503    else if ((CSR_TX_LIFETIME == txStatus) ||  (CSR_TX_BLOCK_ACK_TIMEOUT == txStatus) ||
 504             (CSR_TX_FAIL_TRANSMISSION_VIF_INTERRUPTED == txStatus) ||
 505             (CSR_TX_REJECTED_PEER_STATION_SLEEPING == txStatus)    ||
 506             (CSR_TX_REJECTED_DTIM_STARTED == txStatus)) {
 507        /* Extract the Frame control and the frame type */
 508        frameControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr);
 509        frameType =  ((frameControl & IEEE80211_FC_TYPE_MASK) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
 510
 511        /* Mgmt frames will not be re-queued for Tx
 512         * so just return failure to clear the hip slot
 513         */
 514        if (IEEE802_11_FRAMETYPE_MANAGEMENT == frameType) {
 515            return CSR_RESULT_FAILURE;
 516        }
 517        else if (IEEE802_11_FRAMETYPE_DATA == frameType) {
 518            /* QOS NULL and DATA NULL frames will not be re-queued for Tx
 519             * so just return failure to clear the hip slot
 520             */
 521            if ((((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET) == QOS_DATA_NULL) ||
 522                (((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> FRAME_CONTROL_SUBTYPE_FIELD_OFFSET)== DATA_NULL )) {
 523                return CSR_RESULT_FAILURE;
 524            }
 525        }
 526
 527        /* Extract the Packet priority */
 528        if (TRUE == staRecord->wmmOrQosEnabled) {
 529            u16 qosControl = 0;
 530            u8  dataFrameType = 0;
 531
 532            dataFrameType =((frameControl & IEEE80211_FC_SUBTYPE_MASK) >> 4);
 533
 534            if (dataFrameType == QOS_DATA) {
 535                /* QoS control field is offset from frame control by 2 (frame control)
 536                 * + 2 (duration/ID) + 2 (sequence control) + 3*ETH_ALEN or 4*ETH_ALEN
 537                 */
 538                if((frameControl & IEEE802_11_FC_TO_DS_MASK) && (frameControl & IEEE802_11_FC_FROM_DS_MASK)) {
 539                    qosControl= CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 30);
 540                }
 541                else {
 542                    qosControl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(bulkDataDesc->os_data_ptr + 24);
 543                }
 544            }
 545
 546            priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
 547
 548            if (priority < CSR_QOS_UP0 || priority > CSR_QOS_UP7) {
 549                unifi_trace(priv, UDBG5, "unifi_reque_ma_packet_request: Invalid priority:%x \n", priority);
 550                return CSR_RESULT_FAILURE;
 551            }
 552        }
 553        else {
 554            priority = CSR_CONTENTION;
 555        }
 556
 557        /* Frame Bulk data to requeue it back to HAL Queues */
 558        bulkData.d[0].os_data_ptr    = bulkDataDesc->os_data_ptr;
 559        bulkData.d[0].data_length    = bulkDataDesc->data_length;
 560        bulkData.d[0].os_net_buf_ptr = bulkDataDesc->os_net_buf_ptr;
 561        bulkData.d[0].net_buf_length = bulkDataDesc->net_buf_length;
 562
 563        bulkData.d[1].os_data_ptr    = NULL;
 564        bulkData.d[1].os_net_buf_ptr = NULL;
 565        bulkData.d[1].data_length    = bulkData.d[1].net_buf_length = 0;
 566
 567        /* Initialize signal to zero */
 568        memset(&signal, 0, sizeof(CSR_SIGNAL));
 569
 570        /* Frame MA Packet Req */
 571        unifi_frame_ma_packet_req(priv, priority, 0, host_tag,
 572                              interfaceTag, CSR_NO_CONFIRM_REQUIRED,
 573                              priv->netdev_client->sender_id,
 574                              staRecord->peerMacAddress.a, &signal);
 575
 576        /* Find the Q-Priority */
 577        priority_q = unifi_frame_priority_to_queue(priority);
 578        list = &staRecord->dataPdu[priority_q];
 579
 580        /* Place the Packet on to HAL Queue */
 581        status = enque_tx_data_pdu(priv, &bulkData, list, &signal, TRUE);
 582
 583        /* Update the Per-station queued packet counter */
 584        if (!status) {
 585            spin_lock_irqsave(&priv->staRecord_lock, lock_flags);
 586            staRecord->noOfPktQueued++;
 587            spin_unlock_irqrestore(&priv->staRecord_lock, lock_flags);
 588        }
 589    }
 590    else {
 591        /* Packet will not be re-queued for any of the other MA Packet Tx failure
 592         * reasons so just return failure to clear the hip slot
 593         */
 594        return CSR_RESULT_FAILURE;
 595    }
 596
 597    return status;
 598}
 599#endif
 600
 601static void is_all_ac_deliver_enabled_and_moredata(CsrWifiRouterCtrlStaInfo_t *staRecord, u8 *allDeliveryEnabled, u8 *dataAvailable)
 602{
 603    u8 i;
 604    *allDeliveryEnabled = TRUE;
 605    for (i = 0 ;i < MAX_ACCESS_CATOGORY; i++) {
 606        if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
 607            /* One is is not Delivery Enabled */
 608            *allDeliveryEnabled = FALSE;
 609            break;
 610        }
 611    }
 612    if (*allDeliveryEnabled) {
 613        *dataAvailable = (!list_empty(&staRecord->dataPdu[0]) || !list_empty(&staRecord->dataPdu[1])
 614                          ||!list_empty(&staRecord->dataPdu[2]) ||!list_empty(&staRecord->dataPdu[3])
 615                          ||!list_empty(&staRecord->mgtFrames));
 616    }
 617}
 618
 619/*
 620 * ---------------------------------------------------------------------------
 621 *  uf_handle_tim_cfm
 622 *
 623 *
 624 *      This function updates tim status in host depending confirm status from firmware
 625 *
 626 *  Arguments:
 627 *      priv            Pointer to device private context struct
 628 *      cfm             CSR_MLME_SET_TIM_CONFIRM
 629 *      receiverProcessId SenderProcessID to fetch handle & timSet status
 630 *
 631 * ---------------------------------------------------------------------------
 632 */
 633void uf_handle_tim_cfm(unifi_priv_t *priv, CSR_MLME_SET_TIM_CONFIRM *cfm, u16 receiverProcessId)
 634{
 635    u8 handle = CSR_WIFI_GET_STATION_HANDLE_FROM_RECEIVER_ID(receiverProcessId);
 636    u8 timSetStatus = CSR_WIFI_GET_TIMSET_STATE_FROM_RECEIVER_ID(receiverProcessId);
 637    u16 interfaceTag = (cfm->VirtualInterfaceIdentifier & 0xff);
 638    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
 639    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
 640    /* This variable holds what TIM value we wanted to set in firmware */
 641    u16 timSetValue = 0;
 642    /* Irrespective of interface the count maintained */
 643    static u8 retryCount = 0;
 644    unsigned long lock_flags;
 645    unifi_trace(priv, UDBG3, "entering %s, handle = %x, timSetStatus = %x\n", __FUNCTION__, handle, timSetStatus);
 646
 647    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
 648        unifi_warning(priv, "bad interfaceTag = %x\n", interfaceTag);
 649        return;
 650    }
 651
 652    if ((handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) && (handle >= UNIFI_MAX_CONNECTIONS)) {
 653        unifi_warning(priv, "bad station Handle = %x\n", handle);
 654        return;
 655    }
 656
 657    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
 658        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
 659        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
 660            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
 661            unifi_warning(priv, "uf_handle_tim_cfm: station record is NULL  handle = %x\n", handle);
 662            return;
 663        }
 664       spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
 665    }
 666    switch(timSetStatus)
 667    {
 668        case CSR_WIFI_TIM_SETTING:
 669            timSetValue = CSR_WIFI_TIM_SET;
 670            break;
 671        case CSR_WIFI_TIM_RESETTING:
 672            timSetValue = CSR_WIFI_TIM_RESET;
 673            break;
 674        default:
 675            unifi_warning(priv, "timSet state is %x: Debug\n", timSetStatus);
 676            return;
 677    }
 678
 679    /* check TIM confirm for success/failures */
 680    switch(cfm->ResultCode)
 681    {
 682        case CSR_RC_SUCCESS:
 683            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
 684                /* Unicast frame & station record available */
 685                if (timSetStatus == staRecord->timSet) {
 686                    staRecord->timSet = timSetValue;
 687                    /* fh_cmd_q can also be full at some point of time!,
 688                     * resetting count as queue is cleaned by firmware at this point
 689                     */
 690                    retryCount = 0;
 691                    unifi_trace(priv, UDBG2, "tim (%s) successfully in firmware\n", (timSetValue)?"SET":"RESET");
 692                } else {
 693                    unifi_trace(priv, UDBG3, "receiver processID = %x, success: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x, handle = %x\n",
 694                                 receiverProcessId, timSetStatus, staRecord->timSet, handle);
 695                }
 696
 697                /* Reset TIM pending flag to send next TIM request */
 698                staRecord->timRequestPendingFlag = FALSE;
 699
 700                /* Make sure that one more UpdateTim request is queued, if Queued its value
 701                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
 702                 */
 703                if (0xFF != staRecord->updateTimReqQueued)
 704                {
 705                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
 706                    if (staRecord->timSet != staRecord->updateTimReqQueued)
 707                    {
 708                       unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateTimReq \n");
 709
 710                       update_tim(priv, staRecord->aid, staRecord->updateTimReqQueued, interfaceTag, handle);
 711
 712                       staRecord->updateTimReqQueued = 0xFF;
 713                    }
 714                }
 715            } else {
 716
 717                interfacePriv->bcTimSet = timSetValue;
 718                /* fh_cmd_q can also be full at some point of time!,
 719                 * resetting count as queue is cleaned by firmware at this point
 720                 */
 721                retryCount = 0;
 722                unifi_trace(priv, UDBG3, "tim (%s) successfully for broadcast frame in firmware\n", (timSetValue)?"SET":"RESET");
 723
 724                /* Reset DTIM pending flag to send next DTIM request */
 725                interfacePriv->bcTimSetReqPendingFlag = FALSE;
 726
 727                /* Make sure that one more UpdateDTim request is queued, if Queued its value
 728                 * should be CSR_WIFI_TIM_SET or CSR_WIFI_TIM_RESET
 729                 */
 730                if (0xFF != interfacePriv->bcTimSetReqQueued)
 731                {
 732                    /* Process the UpdateTim Request which is queued while previous UpdateTim was in progress */
 733                    if (interfacePriv->bcTimSet != interfacePriv->bcTimSetReqQueued)
 734                    {
 735                        unifi_trace(priv, UDBG2, "uf_handle_tim_cfm : Processing Queued UpdateDTimReq \n");
 736
 737                        update_tim(priv, 0, interfacePriv->bcTimSetReqQueued, interfaceTag, 0xFFFFFFFF);
 738
 739                        interfacePriv->bcTimSetReqQueued = 0xFF;
 740                    }
 741                }
 742
 743            }
 744            break;
 745        case CSR_RC_INVALID_PARAMETERS:
 746        case CSR_RC_INSUFFICIENT_RESOURCE:
 747            /* check for max retry limit & send again
 748             * MAX_RETRY_LIMIT is not maintained for each set of transactions..Its generic
 749             * If failure crosses this Limit, we have to take a call to FIX
 750             */
 751            if (retryCount > UNIFI_MAX_RETRY_LIMIT) {
 752                u8 moreData = FALSE;
 753                retryCount = 0;
 754                /* Because of continuos traffic in fh_cmd_q the tim set request is failing (exceeding retry limit)
 755                 * but if we didn't synchronize our timSet varible state with firmware then it can cause below issues
 756                 * cond 1. We want to SET tim in firmware if its fails & max retry limit reached
 757                 *   -> If host set's the timSet to 1, we wont try to send(as max retry reached) update tim but
 758                 *   firmware is not updated with queue(TIM) status so it wont set TIM in beacon finally host start piling
 759                 *    up data & wont try to set tim in firmware (This can cause worser performance)
 760                 * cond 2. We want to reset tim in firmware it fails & reaches max retry limit
 761                 *   -> If host sets the timSet to Zero, it wont try to set a TIM request unless we wont have any packets
 762                 *   to be queued, so beacon unnecessarily advertizes the TIM
 763                 */
 764
 765                if(staRecord) {
 766                    if(!staRecord->wmmOrQosEnabled) {
 767                        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
 768                                !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
 769                                !list_empty(&staRecord->mgtFrames));
 770                    } else {
 771                        /* Peer is QSTA */
 772                        u8 allDeliveryEnabled = 0, dataAvailable = 0;
 773                        /* Check if all AC's are Delivery Enabled */
 774                        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
 775                        /*check for more data in non-delivery enabled queues*/
 776                        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
 777
 778                    }
 779                    /* To avoid cond 1 & 2, check internal Queues status, if we have more Data then set RESET the timSet(0),
 780                     *  so we are trying to be in sync with firmware & next packets before queuing atleast try to
 781                     *  set TIM in firmware otherwise it SET timSet(1)
 782                     */
 783                    if (moreData) {
 784                        staRecord->timSet = CSR_WIFI_TIM_RESET;
 785                    } else {
 786                        staRecord->timSet = CSR_WIFI_TIM_SET;
 787                    }
 788                } else {
 789                    /* Its a broadcast frames */
 790                    moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
 791                               !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
 792                    if (moreData) {
 793                        update_tim(priv, 0, CSR_WIFI_TIM_SET, interfaceTag, 0xFFFFFFFF);
 794                    } else {
 795                        update_tim(priv, 0, CSR_WIFI_TIM_RESET, interfaceTag, 0xFFFFFFFF);
 796                    }
 797                }
 798
 799                unifi_error(priv, "no of error's for TIM setting crossed the Limit: verify\n");
 800                return;
 801            }
 802            retryCount++;
 803
 804            if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
 805                if (timSetStatus == staRecord->timSet) {
 806                    unifi_warning(priv, "tim request failed, retry for AID = %x\n", staRecord->aid);
 807                    update_tim(priv, staRecord->aid, timSetValue, interfaceTag, handle);
 808                } else {
 809                    unifi_trace(priv, UDBG1, "failure: request & confirm states are not matching in TIM cfm: Debug status = %x, staRecord->timSet = %x\n",
 810                                  timSetStatus, staRecord->timSet);
 811                }
 812            } else {
 813                unifi_warning(priv, "tim request failed, retry for broadcast frames\n");
 814                update_tim(priv, 0, timSetValue, interfaceTag, 0xFFFFFFFF);
 815            }
 816            break;
 817        default:
 818            unifi_warning(priv, "tim update request failed resultcode = %x\n", cfm->ResultCode);
 819    }
 820
 821    unifi_trace(priv, UDBG2, "leaving %s\n", __FUNCTION__);
 822}
 823
 824/*
 825 * ---------------------------------------------------------------------------
 826 *  update_tim
 827 *
 828 *
 829 *      This function updates tim status in firmware for AID[1 to UNIFI_MAX_CONNECTIONS] or
 830 *       AID[0] for broadcast/multicast packets.
 831 *
 832 *      NOTE: The LSB (least significant BYTE) of senderId while sending this MLME premitive
 833 *       has been modified(utilized) as below
 834 *
 835 *       SenderID in signal's SignalPrimitiveHeader is 2 byte the lowe byte bitmap is below
 836 *
 837 *       station handle(6 bits)      timSet Status (2 bits)
 838 *       ---------------------       ----------------------
 839 *       0  0  0  0  0  0        |       0  0
 840 *
 841 * timSet Status can be one of below:
 842 *
 843 * CSR_WIFI_TIM_RESET
 844 * CSR_WIFI_TIM_RESETTING
 845 * CSR_WIFI_TIM_SET
 846 * CSR_WIFI_TIM_SETTING
 847 *
 848 *  Arguments:
 849 *      priv            Pointer to device private context struct
 850 *      aid             can be 1 t0 UNIFI_MAX_CONNECTIONS & 0 means multicast/broadcast
 851 *      setTim          value SET(1) / RESET(0)
 852 *      interfaceTag    the interfaceID on which activity going on
 853 *      handle          from  (0 <= handle < UNIFI_MAX_CONNECTIONS)
 854 *
 855 * ---------------------------------------------------------------------------
 856 */
 857void update_tim(unifi_priv_t * priv, u16 aid, u8 setTim, u16 interfaceTag, u32 handle)
 858{
 859    CSR_SIGNAL signal;
 860    s32 r;
 861    CSR_MLME_SET_TIM_REQUEST *req = &signal.u.MlmeSetTimRequest;
 862    bulk_data_param_t *bulkdata = NULL;
 863    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
 864    u8 senderIdLsb = 0;
 865    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
 866    u32 oldTimSetStatus = 0, timSetStatus = 0;
 867
 868    unifi_trace(priv, UDBG5, "entering the update_tim routine\n");
 869
 870
 871    if (handle == 0xFFFFFFFF) {
 872        handle &= CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE;
 873        if (setTim == interfacePriv->bcTimSet)
 874        {
 875            unifi_trace(priv, UDBG3, "update_tim, Drop:Hdl=%x, timval=%d, globalTim=%d\n", handle, setTim, interfacePriv->bcTimSet);
 876            return;
 877        }
 878    } else if ((handle != 0xFFFFFFFF) && (handle >= UNIFI_MAX_CONNECTIONS)) {
 879        unifi_warning(priv, "bad station Handle = %x\n", handle);
 880        return;
 881    }
 882
 883    if (setTim) {
 884        timSetStatus =  CSR_WIFI_TIM_SETTING;
 885    } else {
 886        timSetStatus =  CSR_WIFI_TIM_RESETTING;
 887    }
 888
 889    if (handle != CSR_WIFI_BROADCAST_OR_MULTICAST_HANDLE) {
 890        if ((staRecord = ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]))) == NULL) {
 891            unifi_warning(priv, "station record is NULL in  update_tim: handle = %x :debug\n", handle);
 892            return;
 893        }
 894        /* In case of signal sending failed, revert back to old state */
 895        oldTimSetStatus = staRecord->timSet;
 896        staRecord->timSet = timSetStatus;
 897    }
 898
 899    /* pack senderID LSB */
 900    senderIdLsb = CSR_WIFI_PACK_SENDER_ID_LSB_FOR_TIM_REQ(handle,  timSetStatus);
 901
 902    /* initialize signal to zero */
 903    memset(&signal, 0, sizeof(CSR_SIGNAL));
 904
 905    /* Frame the MLME-SET-TIM request */
 906    signal.SignalPrimitiveHeader.SignalId = CSR_MLME_SET_TIM_REQUEST_ID;
 907    signal.SignalPrimitiveHeader.ReceiverProcessId = 0;
 908    CSR_COPY_UINT16_TO_LITTLE_ENDIAN(((priv->netdev_client->sender_id & 0xff00) | senderIdLsb),
 909                   (u8*)&signal.SignalPrimitiveHeader.SenderProcessId);
 910
 911    /* set The virtual interfaceIdentifier, aid, tim value */
 912    req->VirtualInterfaceIdentifier = uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag);
 913    req->AssociationId = aid;
 914    req->TimValue = setTim;
 915
 916
 917    unifi_trace(priv, UDBG2, "update_tim:AID %x,senderIdLsb = 0x%x, handle = 0x%x, timSetStatus = %x, sender proceesID = %x \n",
 918                aid,senderIdLsb, handle, timSetStatus, signal.SignalPrimitiveHeader.SenderProcessId);
 919
 920    /* Send the signal to UniFi */
 921    r = ul_send_signal_unpacked(priv, &signal, bulkdata);
 922    if (r) {
 923        /* No need to free bulk data, as TIM request doesn't carries any data */
 924        unifi_error(priv, "Error queueing CSR_MLME_SET_TIM_REQUEST signal\n");
 925        if (staRecord) {
 926            staRecord->timSet = oldTimSetStatus ;
 927        }
 928        else
 929        {
 930            /* MLME_SET_TIM.req sending failed here for AID0, so revert back our bcTimSet status */
 931            interfacePriv->bcTimSet = !setTim;
 932        }
 933    }
 934    else {
 935        /* Update tim request pending flag and ensure no more TIM set requests are send
 936           for the same station until TIM confirm is received */
 937        if (staRecord) {
 938            staRecord->timRequestPendingFlag = TRUE;
 939        }
 940        else
 941        {
 942            /* Update tim request (for AID 0) pending flag and ensure no more DTIM set requests are send
 943             * for the same station until TIM confirm is received
 944             */
 945            interfacePriv->bcTimSetReqPendingFlag = TRUE;
 946        }
 947    }
 948    unifi_trace(priv, UDBG5, "leaving the update_tim routine\n");
 949}
 950
 951static
 952void process_peer_active_transition(unifi_priv_t * priv,
 953                                    CsrWifiRouterCtrlStaInfo_t *staRecord,
 954                                    u16 interfaceTag)
 955{
 956    int r,i;
 957    u8 spaceAvail[4] = {TRUE,TRUE,TRUE,TRUE};
 958    tx_buffered_packets_t * buffered_pkt = NULL;
 959    unsigned long lock_flags;
 960    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
 961
 962    unifi_trace(priv, UDBG5, "entering process_peer_active_transition\n");
 963
 964    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
 965        /* giving more priority to multicast packets so delaying unicast packets*/
 966        unifi_trace(priv,UDBG2, "Multicast transmission is going on so resume unicast transmission after DTIM over\n");
 967
 968        /* As station is active now, even though AP is not able to send frames to it
 969         * because of DTIM, it needs to reset the TIM here
 970         */
 971        if (!staRecord->timRequestPendingFlag){
 972            if((staRecord->timSet == CSR_WIFI_TIM_SET) || (staRecord->timSet == CSR_WIFI_TIM_SETTING)){
 973                update_tim(priv, staRecord->aid, 0, interfaceTag, staRecord->assignedHandle);
 974            }
 975        }
 976        else
 977        {
 978            /* Cache the TimSet value so that it will processed immidiatly after
 979             * completing the current setTim Request
 980             */
 981            staRecord->updateTimReqQueued = 0;
 982            unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
 983                        staRecord->aid);
 984        }
 985        return;
 986    }
 987    while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
 988        buffered_pkt->transmissionControl &=
 989                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
 990        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
 991            unifi_trace(priv, UDBG2, "p_p_a_t:(ENOSPC) Mgt Frame queueing \n");
 992            /* Enqueue at the head of the queue */
 993            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
 994            list_add(&buffered_pkt->q, &staRecord->mgtFrames);
 995            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
 996            priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
 997            spaceAvail[3] = FALSE;
 998            break;
 999        } else {
1000            if(r){
1001                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
1002                /* the PDU failed where we can't do any thing so free the storage */
1003                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
1004            }
1005            kfree(buffered_pkt);
1006        }
1007    }
1008    if (!staRecord->timRequestPendingFlag) {
1009        if (staRecord->txSuspend) {
1010            if(staRecord->timSet == CSR_WIFI_TIM_SET) {
1011                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
1012            }
1013            return;
1014        }
1015    }
1016    else
1017    {
1018        /* Cache the TimSet value so that it will processed immidiatly after
1019         * completing the current setTim Request
1020         */
1021        staRecord->updateTimReqQueued = 0;
1022        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1023                    staRecord->aid);
1024    }
1025    for(i=3;i>=0;i--) {
1026        if(!spaceAvail[i])
1027            continue;
1028        unifi_trace(priv, UDBG6, "p_p_a_t:data pkt sending for AC %d \n",i);
1029        while((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
1030           buffered_pkt->transmissionControl &=
1031                      ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
1032           if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,0,FALSE)) == -ENOSPC) {
1033               /* Clear the trigger bit transmission control*/
1034               /* Enqueue at the head of the queue */
1035               spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
1036               list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
1037               spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
1038               priv->pausedStaHandle[i]=(u8)(staRecord->assignedHandle);
1039               break;
1040           } else {
1041              if(r){
1042                  unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
1043                  /* the PDU failed where we can't do any thing so free the storage */
1044                  unifi_net_data_free(priv, &buffered_pkt->bulkdata);
1045               }
1046              kfree(buffered_pkt);
1047           }
1048        }
1049    }
1050    if (!staRecord->timRequestPendingFlag){
1051        if((staRecord->timSet  == CSR_WIFI_TIM_SET) || (staRecord->timSet  == CSR_WIFI_TIM_SETTING)) {
1052            unifi_trace(priv, UDBG3, "p_p_a_t:resetting tim .....\n");
1053            update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
1054        }
1055    }
1056    else
1057    {
1058        /* Cache the TimSet value so that it will processed immidiatly after
1059         * completing the current setTim Request
1060         */
1061        staRecord->updateTimReqQueued = 0;
1062        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1063                    staRecord->aid);
1064    }
1065    unifi_trace(priv, UDBG5, "leaving process_peer_active_transition\n");
1066}
1067
1068
1069
1070void uf_process_ma_pkt_cfm_for_ap(unifi_priv_t *priv,u16 interfaceTag, const CSR_MA_PACKET_CONFIRM *pkt_cfm)
1071{
1072    netInterface_priv_t *interfacePriv;
1073    u8 i;
1074    CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
1075    interfacePriv = priv->interfacePriv[interfaceTag];
1076
1077
1078    if(pkt_cfm->HostTag == interfacePriv->multicastPduHostTag) {
1079         unifi_trace(priv,UDBG2,"CFM for marked Multicast Tag = %x\n",interfacePriv->multicastPduHostTag);
1080         interfacePriv->multicastPduHostTag = 0xffffffff;
1081         resume_suspended_uapsd(priv,interfaceTag);
1082         resume_unicast_buffered_frames(priv,interfaceTag);
1083         if(list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) &&
1084              list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
1085            unifi_trace(priv,UDBG1,"Resetting multicastTIM");
1086            if (!interfacePriv->bcTimSetReqPendingFlag)
1087            {
1088                update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
1089            }
1090            else
1091            {
1092                /* Cache the DTimSet value so that it will processed immidiatly after
1093                 * completing the current setDTim Request
1094                 */
1095                 interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
1096                 unifi_trace(priv, UDBG2, "uf_process_ma_pkt_cfm_for_ap : One more UpdateDTim Request(%d) Queued \n",
1097                             interfacePriv->bcTimSetReqQueued);
1098            }
1099
1100        }
1101        return;
1102    }
1103
1104    /* Check if it is a Confirm for null data frame used
1105     * for probing station activity
1106     */
1107    for(i =0; i < UNIFI_MAX_CONNECTIONS; i++) {
1108        staRecord = (CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]);
1109        if (staRecord && (staRecord->nullDataHostTag == pkt_cfm->HostTag)) {
1110
1111            unifi_trace(priv, UDBG1, "CFM for Inactive probe Null frame (tag = %x, status = %d)\n",
1112                                    pkt_cfm->HostTag,
1113                                    pkt_cfm->TransmissionStatus
1114                                    );
1115            staRecord->nullDataHostTag = INVALID_HOST_TAG;
1116
1117            if(pkt_cfm->TransmissionStatus == CSR_TX_RETRY_LIMIT){
1118                u32 now;
1119                u32 inactive_time;
1120
1121                unifi_trace(priv, UDBG1, "Nulldata to probe STA ALIVE Failed with retry limit\n");
1122                /* Recheck if there is some activity after null data is sent.
1123                *
1124                * If still there is no activity then send a disconnected indication
1125                * to SME to delete the station record.
1126                */
1127                if (staRecord->activity_flag){
1128                    return;
1129                }
1130                now = CsrTimeGet(NULL);
1131
1132                if (staRecord->lastActivity > now)
1133                {
1134                    /* simple timer wrap (for 1 wrap) */
1135                    inactive_time = CsrTimeAdd((u32)CsrTimeSub(CSR_SCHED_TIME_MAX, staRecord->lastActivity),
1136                                               now);
1137                }
1138                else
1139                {
1140                    inactive_time = (u32)CsrTimeSub(now, staRecord->lastActivity);
1141                }
1142
1143                if (inactive_time >= STA_INACTIVE_TIMEOUT_VAL)
1144                {
1145                    struct list_head send_cfm_list;
1146                    u8 j;
1147
1148                    /* The SME/NME may be waiting for confirmation for requested frames to this station.
1149                     * Though this is --VERY UNLIKELY-- in case of station in active mode. But still as a
1150                     * a defensive check, it loops through buffered frames for this station and if confirmation
1151                     * is requested, send auto confirmation with failure status. Also flush the frames so
1152                     * that these are not processed again in PEER_DEL_REQ handler.
1153                     */
1154                    INIT_LIST_HEAD(&send_cfm_list);
1155
1156                    uf_prepare_send_cfm_list_for_queued_pkts(priv,
1157                                                             &send_cfm_list,
1158                                                             &(staRecord->mgtFrames));
1159
1160                    uf_flush_list(priv, &(staRecord->mgtFrames));
1161
1162                    for(j = 0; j < MAX_ACCESS_CATOGORY; j++){
1163                        uf_prepare_send_cfm_list_for_queued_pkts(priv,
1164                                                                 &send_cfm_list,
1165                                                                 &(staRecord->dataPdu[j]));
1166
1167                        uf_flush_list(priv,&(staRecord->dataPdu[j]));
1168                    }
1169
1170                    send_auto_ma_packet_confirm(priv, staRecord->interfacePriv, &send_cfm_list);
1171
1172
1173
1174                    unifi_warning(priv, "uf_process_ma_pkt_cfm_for_ap: Router Disconnected IND Peer (%x-%x-%x-%x-%x-%x)\n",
1175                                             staRecord->peerMacAddress.a[0],
1176                                             staRecord->peerMacAddress.a[1],
1177                                             staRecord->peerMacAddress.a[2],
1178                                             staRecord->peerMacAddress.a[3],
1179                                             staRecord->peerMacAddress.a[4],
1180                                             staRecord->peerMacAddress.a[5]);
1181
1182                    CsrWifiRouterCtrlConnectedIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,
1183                                                      0,
1184                                                      staRecord->interfacePriv->InterfaceTag,
1185                                                      staRecord->peerMacAddress,
1186                                                      CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED);
1187                }
1188
1189            }
1190            else if (pkt_cfm->TransmissionStatus == CSR_TX_SUCCESSFUL)
1191            {
1192                 staRecord->activity_flag = TRUE;
1193            }
1194        }
1195    }
1196}
1197
1198#endif
1199u16 uf_get_vif_identifier (CsrWifiRouterCtrlMode mode, u16 tag)
1200{
1201    switch(mode)
1202    {
1203        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1204        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1205            return (0x02<<8|tag);
1206
1207        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1208        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1209            return (0x03<<8|tag);
1210
1211        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1212            return (0x01<<8|tag);
1213
1214        case CSR_WIFI_ROUTER_CTRL_MODE_MONITOR:
1215            return (0x04<<8|tag);
1216        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1217            return (0x05<<8|tag);
1218        default:
1219            return tag;
1220    }
1221}
1222
1223#ifdef CSR_SUPPORT_SME
1224
1225/*
1226 * ---------------------------------------------------------------------------
1227 *  update_macheader
1228 *
1229 *
1230 *      These functions updates mac header for intra BSS packet
1231 *      routing.
1232 *      NOTE: This function always has to be called in rx context which
1233 *      is in bh thread context since GFP_KERNEL is used. In soft IRQ/ Interrupt
1234 *      context shouldn't be used
1235 *
1236 *  Arguments:
1237 *      priv            Pointer to device private context struct
1238 *      skb             Socket buffer containing data packet to transmit
1239 *      newSkb          Socket buffer containing data packet + Mac header if no sufficient headroom in skb
1240 *      priority        to append QOS control header in Mac header
1241 *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
1242 *      interfaceTag    the interfaceID on which activity going on
1243 *      macHeaderLengthInBytes no. of bytes of mac header in received frame
1244 *      qosDestination  used to append Qos control field
1245 *
1246 *  Returns:
1247 *      Zero on success or -1 on error.
1248 * ---------------------------------------------------------------------------
1249 */
1250
1251static int update_macheader(unifi_priv_t *priv, struct sk_buff *skb,
1252                            struct sk_buff *newSkb, CSR_PRIORITY *priority,
1253                            bulk_data_param_t *bulkdata, u16 interfaceTag,
1254                            u8 macHeaderLengthInBytes,
1255                            u8 qosDestination)
1256{
1257
1258    u16 *fc = NULL;
1259    u8 direction = 0, toDs, fromDs;
1260    u8 *bufPtr = NULL;
1261    u8 sa[ETH_ALEN], da[ETH_ALEN];
1262    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1263    int headroom;
1264    u8 macHeaderBuf[IEEE802_11_DATA_FRAME_MAC_HEADER_SIZE] = {0};
1265
1266    unifi_trace(priv, UDBG5, "entering the update_macheader function\n");
1267
1268    /* temporary buffer for the Mac header storage */
1269    memcpy(macHeaderBuf, skb->data, macHeaderLengthInBytes);
1270
1271    /* remove the Macheader from the skb */
1272    skb_pull(skb, macHeaderLengthInBytes);
1273
1274    /* get the skb headroom for skb_push check */
1275    headroom = skb_headroom(skb);
1276
1277    /*  pointer to frame control field */
1278    fc = (u16*) macHeaderBuf;
1279
1280    toDs = (*fc & cpu_to_le16(IEEE802_11_FC_TO_DS_MASK))?1 : 0;
1281    fromDs = (*fc & cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK))? 1: 0;
1282    unifi_trace(priv, UDBG5, "In update_macheader function, fromDs = %x, toDs = %x\n", fromDs, toDs);
1283    direction = ((fromDs | (toDs << 1)) & 0x3);
1284
1285    /* Address1 or 3 from the macheader */
1286    memcpy(da, macHeaderBuf+4+toDs*12, ETH_ALEN);
1287    /* Address2, 3 or 4 from the mac header */
1288    memcpy(sa, macHeaderBuf+10+fromDs*(6+toDs*8), ETH_ALEN);
1289
1290    unifi_trace(priv, UDBG3, "update_macheader:direction = %x\n", direction);
1291    /* update the toDs, fromDs & address fields in Mac header */
1292    switch(direction)
1293    {
1294        case 2:
1295            /* toDs = 1 & fromDs = 0 , toAp when frames received from peer
1296             * while sending this packet to Destination the Mac header changed
1297             * as fromDs = 1 & toDs = 0, fromAp
1298             */
1299            *fc &= cpu_to_le16(~IEEE802_11_FC_TO_DS_MASK);
1300            *fc |= cpu_to_le16(IEEE802_11_FC_FROM_DS_MASK);
1301            /* Address1: MAC address of the actual destination (4 = 2+2) */
1302            memcpy(macHeaderBuf + 4, da, ETH_ALEN);
1303            /* Address2: The MAC address of the AP (10 = 2+2+6) */
1304            memcpy(macHeaderBuf + 10, &interfacePriv->bssid, ETH_ALEN);
1305            /* Address3: MAC address of the actual source from mac header (16 = 2+2+6+6) */
1306            memcpy(macHeaderBuf + 16, sa, ETH_ALEN);
1307            break;
1308        case 3:
1309            unifi_trace(priv, UDBG3, "when both the toDs & fromDS set, NOT SUPPORTED\n");
1310            break;
1311        default:
1312            unifi_trace(priv, UDBG3, "problem in decoding packet in update_macheader \n");
1313            return -1;
1314    }
1315
1316    /* frameType is Data always, Validation is done before calling this function */
1317
1318    /* check for the souce station type */
1319    switch(le16_to_cpu(*fc) & IEEE80211_FC_SUBTYPE_MASK)
1320    {
1321        case IEEE802_11_FC_TYPE_QOS_DATA & IEEE80211_FC_SUBTYPE_MASK:
1322            /* No need to modify the qos control field */
1323            if (!qosDestination) {
1324
1325                /* If source Sta is QOS enabled & if this bit set, then HTC is supported by
1326                 * peer station & htc field present in macHeader
1327                 */
1328                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
1329                    /* HT control field present in Mac header
1330                     * 6 = sizeof(qosControl) + sizeof(htc)
1331                     */
1332                    macHeaderLengthInBytes -= 6;
1333                } else {
1334                    macHeaderLengthInBytes -= 2;
1335                }
1336                /* Destination STA is non qos so change subtype to DATA */
1337                *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
1338                *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_DATA);
1339                /* remove the qos control field & HTC(if present). new macHeaderLengthInBytes is less than old
1340                 * macHeaderLengthInBytes so no need to verify skb headroom
1341                 */
1342                if (headroom < macHeaderLengthInBytes) {
1343                    unifi_trace(priv, UDBG1, " sufficient headroom not there to push updated mac header \n");
1344                    return -1;
1345                }
1346                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);
1347
1348                /*  update bulk data os_data_ptr */
1349                bulkdata->d[0].os_data_ptr = skb->data;
1350                bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
1351                bulkdata->d[0].data_length = skb->len;
1352
1353            } else {
1354                /* pointing to QOS control field */
1355                u8 qc;
1356                if (*fc & cpu_to_le16(IEEE80211_FC_ORDER_MASK)) {
1357                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 4 - 2)));
1358                } else {
1359                    qc = *((u8*)(macHeaderBuf + (macHeaderLengthInBytes - 2)));
1360                }
1361
1362                if ((qc & IEEE802_11_QC_TID_MASK) > 7) {
1363                    *priority = 7;
1364                } else {
1365                    *priority = qc & IEEE802_11_QC_TID_MASK;
1366                }
1367
1368                unifi_trace(priv, UDBG1, "Incoming packet priority from QSTA is %x\n", *priority);
1369
1370                if (headroom < macHeaderLengthInBytes) {
1371                    unifi_trace(priv, UDBG3, " sufficient headroom not there to push updated mac header \n");
1372                    return -1;
1373                }
1374                bufPtr = (u8 *) skb_push(skb, macHeaderLengthInBytes);
1375            }
1376            break;
1377        default:
1378            {
1379                bulk_data_param_t data_ptrs;
1380                CsrResult csrResult;
1381                unifi_trace(priv, UDBG5, "normal Data packet, NO QOS \n");
1382
1383                if (qosDestination) {
1384                    u8 qc = 0;
1385                    unifi_trace(priv, UDBG3, "destination is QOS station \n");
1386
1387                    /* Set Ma-Packet.req UP to UP0 */
1388                    *priority = CSR_QOS_UP0;
1389
1390                    /* prepare the qos control field */
1391                    qc |= CSR_QOS_UP0;
1392                    /* no Amsdu is in ap buffer so eosp is left 0 */
1393                    if (da[0] & 0x1) {
1394                        /* multicast/broadcast frames, no acknowledgement needed */
1395                        qc |= 1 << 5;
1396                    }
1397
1398                    /* update new Mac header Length with 2 = sizeof(qos control) */
1399                    macHeaderLengthInBytes += 2;
1400
1401                    /* received DATA frame but destiantion is QOS station so update subtype to QOS*/
1402                    *fc &= cpu_to_le16(~IEEE80211_FC_SUBTYPE_MASK);
1403                    *fc |= cpu_to_le16(IEEE802_11_FC_TYPE_QOS_DATA);
1404
1405                    /* appendQosControlOffset = macHeaderLengthInBytes - 2, since source sta is not QOS */
1406                    macHeaderBuf[macHeaderLengthInBytes - 2] = qc;
1407                    /* txopLimit is 0 */
1408                    macHeaderBuf[macHeaderLengthInBytes - 1] = 0;
1409                    if (headroom < macHeaderLengthInBytes) {
1410                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
1411
1412                        if (csrResult != CSR_RESULT_SUCCESS) {
1413                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
1414                            return -1;
1415                        }
1416                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
1417                        newSkb->len = skb->len + macHeaderLengthInBytes;
1418
1419                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
1420                                skb->data, skb->len);
1421
1422                        bulkdata->d[0].os_data_ptr = newSkb->data;
1423                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
1424                        bulkdata->d[0].data_length = newSkb->len;
1425
1426                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
1427
1428                        /* The old skb will not be used again */
1429                        kfree_skb(skb);
1430                    } else {
1431                        /* skb headroom is sufficient to append Macheader */
1432                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
1433                        bulkdata->d[0].os_data_ptr = skb->data;
1434                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
1435                        bulkdata->d[0].data_length = skb->len;
1436                    }
1437                } else {
1438                    unifi_trace(priv, UDBG3, "destination is not a QSTA\n");
1439                    if (headroom < macHeaderLengthInBytes) {
1440                        csrResult = unifi_net_data_malloc(priv, &data_ptrs.d[0], skb->len + macHeaderLengthInBytes);
1441
1442                        if (csrResult != CSR_RESULT_SUCCESS) {
1443                            unifi_error(priv, " failed to allocate request_data. in update_macheader func\n");
1444                            return -1;
1445                        }
1446                        newSkb = (struct sk_buff *)(data_ptrs.d[0].os_net_buf_ptr);
1447                        newSkb->len = skb->len + macHeaderLengthInBytes;
1448
1449                        memcpy((void*)data_ptrs.d[0].os_data_ptr + macHeaderLengthInBytes,
1450                                skb->data, skb->len);
1451
1452                        bulkdata->d[0].os_data_ptr = newSkb->data;
1453                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)newSkb;
1454                        bulkdata->d[0].data_length = newSkb->len;
1455
1456                        bufPtr = (u8*)data_ptrs.d[0].os_data_ptr;
1457
1458                        /* The old skb will not be used again */
1459                        kfree_skb(skb);
1460                    } else {
1461                        /* skb headroom is sufficient to append Macheader */
1462                        bufPtr = (u8*)skb_push(skb, macHeaderLengthInBytes);
1463                        bulkdata->d[0].os_data_ptr = skb->data;
1464                        bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skb;
1465                        bulkdata->d[0].data_length = skb->len;
1466                    }
1467                }
1468            }
1469    }
1470
1471    /* prepare the complete skb, by pushing the MAC header to the beginning of the skb->data */
1472    unifi_trace(priv, UDBG5, "updated Mac Header: %d \n",macHeaderLengthInBytes);
1473    memcpy(bufPtr, macHeaderBuf, macHeaderLengthInBytes);
1474
1475    unifi_trace(priv, UDBG5, "leaving the update_macheader function\n");
1476    return 0;
1477}
1478/*
1479 * ---------------------------------------------------------------------------
1480 *  uf_ap_process_data_pdu
1481 *
1482 *
1483 *      Takes care of intra BSS admission control & routing packets within BSS
1484 *
1485 *  Arguments:
1486 *      priv            Pointer to device private context struct
1487 *      skb             Socket buffer containing data packet to transmit
1488 *      ehdr            ethernet header to fetch priority of packet
1489 *      srcStaInfo      source stations record for connection verification
1490 *      packed_signal
1491 *      signal_len
1492 *      signal          MA-PACKET.indication signal
1493 *      bulkdata        if newSkb allocated then bulkdata updated to send to unifi
1494 *      macHeaderLengthInBytes no. of bytes of mac header in received frame
1495 *
1496 *  Returns:
1497 *      Zero on success(ap processing complete) or -1 if packet also have to be sent to NETDEV.
1498 * ---------------------------------------------------------------------------
1499 */
1500int
1501uf_ap_process_data_pdu(unifi_priv_t *priv, struct sk_buff *skb,
1502                       struct ethhdr *ehdr, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
1503                       const CSR_SIGNAL *signal,
1504                       bulk_data_param_t *bulkdata,
1505                       u8 macHeaderLengthInBytes)
1506{
1507    const CSR_MA_PACKET_INDICATION *ind = &(signal->u.MaPacketIndication);
1508    u16 interfaceTag = (ind->VirtualInterfaceIdentifier & 0x00ff);
1509    struct sk_buff *newSkb = NULL;
1510    /* pointer to skb or private skb created using skb_copy() */
1511    struct sk_buff *skbPtr = skb;
1512    u8 sendToNetdev = FALSE;
1513    u8 qosDestination = FALSE;
1514    CSR_PRIORITY priority = CSR_CONTENTION;
1515    CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
1516    netInterface_priv_t *interfacePriv;
1517
1518    unifi_trace(priv, UDBG5, "entering  uf_ap_process_data_pdu %d\n",macHeaderLengthInBytes);
1519    /* InterfaceTag validation from MA_PACKET.indication */
1520    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1521        unifi_trace(priv, UDBG1, "Interface Tag is Invalid in uf_ap_process_data_pdu\n");
1522        unifi_net_data_free(priv, &bulkdata->d[0]);
1523        return 0;
1524    }
1525    interfacePriv = priv->interfacePriv[interfaceTag];
1526
1527    if((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO) &&
1528       (interfacePriv->intraBssEnabled == FALSE)) {
1529        unifi_trace(priv, UDBG2, "uf_ap_process_data_pdu:P2P GO intrabssEnabled?= %d\n", interfacePriv->intraBssEnabled);
1530
1531        /*In P2P GO case, if intraBSS distribution Disabled then don't do IntraBSS routing */
1532        /* If destination in our BSS then drop otherwise give packet to netdev */
1533        dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);
1534        if (dstStaInfo) {
1535            unifi_net_data_free(priv, &bulkdata->d[0]);
1536            return 0;
1537        }
1538        /* May be associated P2PCLI trying to send the packets on backbone (Netdev) */
1539        return -1;
1540    }
1541
1542    if(!memcmp(ehdr->h_dest, interfacePriv->bssid.a, ETH_ALEN)) {
1543        /* This packet will be given to the TCP/IP stack since this packet is for us(AP)
1544         * No routing needed */
1545        unifi_trace(priv, UDBG4, "destination address is csr_ap\n");
1546        return -1;
1547    }
1548
1549    /* fetch the destination record from station record database */
1550    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, ehdr->h_dest, interfaceTag);
1551
1552    /* AP mode processing, & if packet is unicast */
1553    if(!dstStaInfo) {
1554        if (!(ehdr->h_dest[0] & 0x1)) {
1555            /* destination not in station record & its a unicast packet, so pass the packet to network stack */
1556            unifi_trace(priv, UDBG3, "unicast frame & destination record not exist, send to netdev proto = %x\n", htons(skb->protocol));
1557            return -1;
1558        } else {
1559            /* packet is multicast/broadcast */
1560            /* copy the skb to skbPtr, send skb to netdev & skbPtr to multicast/broad cast list */
1561            unifi_trace(priv, UDBG5, "skb_copy, in  uf_ap_process_data_pdu, protocol = %x\n", htons(skb->protocol));
1562            skbPtr = skb_copy(skb, GFP_KERNEL);
1563            if(skbPtr == NULL) {
1564                /* We don't have memory to don't send the frame in BSS*/
1565                unifi_notice(priv, "broacast/multicast frame can't be sent in BSS No memeory: proto = %x\n", htons(skb->protocol));
1566                return -1;
1567            }
1568            sendToNetdev = TRUE;
1569        }
1570    } else {
1571
1572        /* validate the Peer & Destination Station record */
1573        if (uf_process_station_records_for_sending_data(priv, interfaceTag, srcStaInfo, dstStaInfo)) {
1574            unifi_notice(priv, "uf_ap_process_data_pdu: station record validation failed \n");
1575            interfacePriv->stats.rx_errors++;
1576            unifi_net_data_free(priv, &bulkdata->d[0]);
1577            return 0;
1578        }
1579    }
1580
1581    /* BroadCast packet received and it's been sent as non QOS packets.
1582     * Since WMM spec not mandates broadcast/multicast to be sent as QOS data only,
1583     * if all Peers are QSTA
1584     */
1585    if(sendToNetdev) {
1586       /* BroadCast packet and it's been sent as non QOS packets */
1587        qosDestination = FALSE;
1588    } else if(dstStaInfo && (dstStaInfo->wmmOrQosEnabled == TRUE)) {
1589          qosDestination = TRUE;
1590    }
1591
1592    unifi_trace(priv, UDBG3, "uf_ap_process_data_pdu QoS destination  = %s\n", (qosDestination)? "TRUE": "FALSE");
1593
1594    /* packet is allowed to send to unifi, update the Mac header */
1595    if (update_macheader(priv, skbPtr, newSkb, &priority, bulkdata, interfaceTag, macHeaderLengthInBytes, qosDestination)) {
1596        interfacePriv->stats.rx_errors++;
1597        unifi_notice(priv, "(Packet Drop) failed to update the Mac header in uf_ap_process_data_pdu\n");
1598        if (sendToNetdev) {
1599            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
1600            bulkdata->d[0].os_data_ptr = skbPtr->data;
1601            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
1602            bulkdata->d[0].data_length = skbPtr->len;
1603            unifi_net_data_free(priv, &bulkdata->d[0]);
1604        }
1605        return -1;
1606    }
1607
1608    unifi_trace(priv, UDBG3, "Mac Header updated...calling uf_process_ma_packet_req \n");
1609
1610    /* Packet is ready to send to unifi ,transmissionControl = 0x0004, confirmation is not needed for data packets */
1611    if (uf_process_ma_packet_req(priv,  ehdr->h_dest, 0xffffffff, interfaceTag, CSR_NO_CONFIRM_REQUIRED, (CSR_RATE)0,priority, priv->netdev_client->sender_id, bulkdata)) {
1612        if (sendToNetdev) {
1613            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop) uf_process_ma_packet_req failed. freeing skb_copy data (original data sent to Netdev)\n");
1614            /*  Free's the skb_copy(skbPtr) data since packet processing failed */
1615            bulkdata->d[0].os_data_ptr = skbPtr->data;
1616            bulkdata->d[0].os_net_buf_ptr = (unsigned char*)skbPtr;
1617            bulkdata->d[0].data_length = skbPtr->len;
1618            unifi_net_data_free(priv, &bulkdata->d[0]);
1619        } else {
1620            /* This free's the skb data */
1621            unifi_trace(priv, UDBG1, "In uf_ap_process_data_pdu, (Packet Drop). Unicast data so freeing original skb \n");
1622            unifi_net_data_free(priv, &bulkdata->d[0]);
1623        }
1624    }
1625    unifi_trace(priv, UDBG5, "leaving  uf_ap_process_data_pdu\n");
1626
1627    if (sendToNetdev) {
1628        /* The packet is multicast/broadcast, so after AP processing packet has to
1629         * be sent to netdev, if peer port state is open
1630        */
1631        unifi_trace(priv, UDBG4, "Packet will be routed to NetDev\n");
1632        return -1;
1633    }
1634    /* Ap handled the packet & its a unicast packet, no need to send to netdev */
1635    return 0;
1636}
1637
1638#endif
1639
1640CsrResult uf_process_ma_packet_req(unifi_priv_t *priv,
1641                                   u8 *peerMacAddress,
1642                                   CSR_CLIENT_TAG hostTag,
1643                                   u16 interfaceTag,
1644                                   CSR_TRANSMISSION_CONTROL transmissionControl,
1645                                   CSR_RATE TransmitRate,
1646                                   CSR_PRIORITY priority,
1647                                   CSR_PROCESS_ID leSenderProcessId,
1648                                   bulk_data_param_t *bulkdata)
1649{
1650    CsrResult status = CSR_RESULT_SUCCESS;
1651    CSR_SIGNAL signal;
1652    int result;
1653#ifdef CSR_SUPPORT_SME
1654   CsrWifiRouterCtrlStaInfo_t *staRecord = NULL;
1655    const u8 *macHdrLocation =  bulkdata->d[0].os_data_ptr;
1656    CsrWifiPacketType pktType;
1657    int frameType = 0;
1658    u8 queuePacketDozing = FALSE;
1659    u32 priority_q;
1660    u16 frmCtrl;
1661    struct list_head * list = NULL; /* List to which buffered PDUs are to be enqueued*/
1662    u8 setBcTim=FALSE;
1663    netInterface_priv_t *interfacePriv;
1664    u8 requeueOnSamePos = FALSE;
1665    u32 handle = 0xFFFFFFFF;
1666    unsigned long lock_flags;
1667
1668        unifi_trace(priv, UDBG5,
1669                "entering uf_process_ma_packet_req, peer: %pMF\n",
1670                peerMacAddress);
1671
1672    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1673        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
1674        return CSR_RESULT_FAILURE;
1675    }
1676    interfacePriv = priv->interfacePriv[interfaceTag];
1677
1678
1679    /* fetch the station record for corresponding peer mac address */
1680    if ((staRecord = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag))) {
1681        handle = staRecord->assignedHandle;
1682    }
1683
1684    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
1685    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag,
1686                              interfaceTag, transmissionControl, leSenderProcessId,
1687                              peerMacAddress, &signal);
1688
1689   /* Since it's common path between STA & AP mode, in case of STA packet
1690     * need not to be queued but in AP case we have to queue PDU's in
1691     * different scenarios
1692     */
1693    switch(interfacePriv->interfaceMode)
1694    {
1695        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1696        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1697            /* For this mode processing done below */
1698            break;
1699        default:
1700            /* In case of STA/IBSS/P2PCLI/AMP, no checks needed send the packet down & return */
1701            unifi_trace(priv, UDBG5, "In %s, interface mode is %x \n", __FUNCTION__, interfacePriv->interfaceMode);
1702            if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_NONE) {
1703                unifi_warning(priv, "In %s, interface mode NONE \n", __FUNCTION__);
1704            }
1705            if ((result = ul_send_signal_unpacked(priv, &signal, bulkdata))) {
1706                status = CSR_RESULT_FAILURE;
1707            }
1708            return status;
1709    }
1710
1711    /* -----Only AP/P2pGO mode handling falls below----- */
1712
1713    /* convert priority to queue */
1714    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
1715
1716    /* check the powersave status of the peer */
1717    if (staRecord && (staRecord->currentPeerState ==
1718                     CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)) {
1719        /* Peer is dozing & packet have to be delivered, so buffer the packet &
1720         * update the TIM
1721         */
1722        queuePacketDozing = TRUE;
1723    }
1724
1725    /* find the type of frame unicast or mulicast/broadcast */
1726    if (*peerMacAddress & 0x1) {
1727        /* Multicast/broadCast data are always triggered by vif_availability.ind
1728         * at the DTIM
1729         */
1730        pktType = CSR_WIFI_MULTICAST_PDU;
1731    } else {
1732        pktType = CSR_WIFI_UNICAST_PDU;
1733    }
1734
1735    /* Fetch the frame control field from mac header & check for frame type */
1736    frmCtrl = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(macHdrLocation);
1737
1738    /* Processing done according to Frame/Packet type */
1739    frameType =  ((frmCtrl & 0x000c) >> FRAME_CONTROL_TYPE_FIELD_OFFSET);
1740    switch(frameType)
1741    {
1742        case IEEE802_11_FRAMETYPE_MANAGEMENT:
1743
1744            switch(pktType)
1745            {
1746                case CSR_WIFI_UNICAST_PDU:
1747                    unifi_trace(priv, UDBG5, "management unicast PDU in uf_process_ma_packet_req \n");
1748                    /* push the packet in to the queue with appropriate mgt list */
1749                    if (!staRecord) {
1750                        /* push the packet to the unifi if list is empty (if packet lost how to re-enque) */
1751                        if (list_empty(&interfacePriv->genericMgtFrames)) {
1752#ifdef CSR_SUPPORT_SME
1753                            if(!(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
1754#endif
1755
1756                            unifi_trace(priv, UDBG3, "genericMgtFrames list is empty uf_process_ma_packet_req \n");
1757                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
1758                            /*  reque only on ENOSPC */
1759                            if(result == -ENOSPC) {
1760                                /* requeue the failed packet to genericMgtFrame with same position */
1761                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending genericMgtFrames Failed so buffering\n");
1762                                list = &interfacePriv->genericMgtFrames;
1763                                requeueOnSamePos = TRUE;
1764                            }
1765#ifdef CSR_SUPPORT_SME
1766                            }else{
1767                                list = &interfacePriv->genericMgtFrames;
1768                                unifi_trace(priv, UDBG3, "genericMgtFrames queue empty and dtim started\n hosttag is 0x%x,\n",signal.u.MaPacketRequest.HostTag);
1769                                update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag);
1770                           }
1771#endif
1772                        } else {
1773                            /* Queue the packet to genericMgtFrame of unifi_priv_t data structure */
1774                            list = &interfacePriv->genericMgtFrames;
1775                            unifi_trace(priv, UDBG2, "genericMgtFrames queue not empty\n");
1776                        }
1777                    } else {
1778                        /* check peer power state */
1779                        if (queuePacketDozing || !list_empty(&staRecord->mgtFrames) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
1780                            /* peer is in dozing mode, so queue packet in mgt frame list of station record */
1781                           /*if multicast traffic is going on, buffer the unicast packets*/
1782                            list = &staRecord->mgtFrames;
1783
1784                            unifi_trace(priv, UDBG1, "staRecord->MgtFrames list empty? = %s, handle = %d, queuePacketDozing = %d\n",
1785                                        (list_empty(&staRecord->mgtFrames))? "YES": "NO", staRecord->assignedHandle, queuePacketDozing);
1786                            if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)){
1787                                update_eosp_to_head_of_broadcast_list_head(priv,interfaceTag);
1788                            }
1789
1790                        } else {
1791                            unifi_trace(priv, UDBG5, "staRecord->mgtFrames list is empty uf_process_ma_packet_req \n");
1792                            result = ul_send_signal_unpacked(priv, &signal, bulkdata);
1793                            if(result == -ENOSPC) {
1794                                /* requeue the failed packet to staRecord->mgtFrames with same position */
1795                                list = &staRecord->mgtFrames;
1796                                requeueOnSamePos = TRUE;
1797                                unifi_trace(priv, UDBG1, "(ENOSPC) Sending MgtFrames Failed handle = %d so buffering\n",staRecord->assignedHandle);
1798                                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
1799                            } else if (result) {
1800                                status = CSR_RESULT_FAILURE;
1801                            }
1802                        }
1803                    }
1804                    break;
1805                case CSR_WIFI_MULTICAST_PDU:
1806                    unifi_trace(priv, UDBG5, "management multicast/broadcast PDU in uf_process_ma_packet_req 'QUEUE it' \n");
1807                    /* Queue the packet to genericMulticastOrBroadCastMgtFrames of unifi_priv_t data structure
1808                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
1809                     */
1810
1811                    list = &interfacePriv->genericMulticastOrBroadCastMgtFrames;
1812                    if((interfacePriv->interfaceMode != CSR_WIFI_ROUTER_CTRL_MODE_IBSS) &&
1813                            (list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
1814                        setBcTim=TRUE;
1815                    }
1816                    break;
1817                default:
1818                    unifi_error(priv, "condition never meets: packet type unrecognized\n");
1819            }
1820            break;
1821        case IEEE802_11_FRAMETYPE_DATA:
1822            switch(pktType)
1823            {
1824                case CSR_WIFI_UNICAST_PDU:
1825                    unifi_trace(priv, UDBG5, "data unicast PDU in uf_process_ma_packet_req \n");
1826                    /* check peer power state, list status & peer port status */
1827                    if(!staRecord) {
1828                        unifi_error(priv, "In %s unicast but staRecord = NULL\n", __FUNCTION__);
1829                        return CSR_RESULT_FAILURE;
1830                    } else if (queuePacketDozing || isRouterBufferEnabled(priv,priority_q)|| !list_empty(&staRecord->dataPdu[priority_q]) || IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
1831                        /* peer is in dozing mode, so queue packet in mgt frame list of station record */
1832                        /* if multicast traffic is going on, buffet the unicast packets */
1833                        unifi_trace(priv, UDBG2, "Enqueued to staRecord->dataPdu[%d] queuePacketDozing=%d,\
1834                                Buffering enabled = %d \n", priority_q,queuePacketDozing,isRouterBufferEnabled(priv,priority_q));
1835                        list = &staRecord->dataPdu[priority_q];
1836                    } else {
1837                        unifi_trace(priv, UDBG5, "staRecord->dataPdu[%d] list is empty uf_process_ma_packet_req \n", priority_q);
1838                        /* Pdu allowed to send to unifi */
1839                        result = ul_send_signal_unpacked(priv, &signal, bulkdata);
1840                        if(result == -ENOSPC) {
1841                            /* requeue the failed packet to staRecord->dataPdu[priority_q] with same position */
1842                            unifi_trace(priv, UDBG1, "(ENOSPC) Sending Unicast DataPDU to queue %d Failed so buffering\n",priority_q);
1843                            requeueOnSamePos = TRUE;
1844                            list = &staRecord->dataPdu[priority_q];
1845                            priv->pausedStaHandle[priority_q]=(u8)(staRecord->assignedHandle);
1846                            if(!isRouterBufferEnabled(priv,priority_q)) {
1847                                unifi_error(priv,"Buffering Not enabled for queue %d \n",priority_q);
1848                            }
1849                        } else if (result) {
1850                            status = CSR_RESULT_FAILURE;
1851                        }
1852                    }
1853                    break;
1854                case CSR_WIFI_MULTICAST_PDU:
1855                    unifi_trace(priv, UDBG5, "data multicast/broadcast PDU in uf_process_ma_packet_req \n");
1856                    /* Queue the packet to genericMulticastOrBroadCastFrames list of unifi_priv_t data structure
1857                     * will be sent when we receive VIF AVAILABILITY from firmware as part of DTIM
1858                     */
1859                    list = &interfacePriv->genericMulticastOrBroadCastFrames;
1860                    if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
1861                        setBcTim = TRUE;
1862                    }
1863                    break;
1864                default:
1865                    unifi_error(priv, "condition never meets: packet type un recognized\n");
1866            }
1867            break;
1868        default:
1869            unifi_error(priv, "unrecognized frame type\n");
1870    }
1871    if(list) {
1872        status = enque_tx_data_pdu(priv, bulkdata,list, &signal,requeueOnSamePos);
1873        /* Record no. of packet queued for each peer */
1874        if (staRecord && (pktType == CSR_WIFI_UNICAST_PDU) && (!status)) {
1875            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1876            staRecord->noOfPktQueued++;
1877            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1878        }
1879        else if ((pktType == CSR_WIFI_MULTICAST_PDU) && (!status))
1880        {
1881            /* If broadcast Tim is set && queuing is successful, then only update TIM */
1882            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
1883            interfacePriv->noOfbroadcastPktQueued++;
1884            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
1885        }
1886    }
1887    /* If broadcast Tim is set && queuing is successful, then only update TIM */
1888    if(setBcTim && !status) {
1889        unifi_trace(priv, UDBG3, "tim set due to broadcast pkt\n");
1890        if (!interfacePriv->bcTimSetReqPendingFlag)
1891        {
1892            update_tim(priv,0,CSR_WIFI_TIM_SET,interfaceTag, handle);
1893        }
1894        else
1895        {
1896            /* Cache the TimSet value so that it will processed immidiatly after
1897            * completing the current setTim Request
1898            */
1899            interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_SET;
1900            unifi_trace(priv, UDBG2, "uf_process_ma_packet_req : One more UpdateDTim Request(:%d) Queued \n",
1901                        interfacePriv->bcTimSetReqQueued);
1902        }
1903    } else if(staRecord && staRecord->currentPeerState ==
1904                            CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
1905        if(staRecord->timSet == CSR_WIFI_TIM_RESET || staRecord->timSet == CSR_WIFI_TIM_RESETTING) {
1906            if(!staRecord->wmmOrQosEnabled) {
1907                if(!list_empty(&staRecord->mgtFrames) ||
1908                   !list_empty(&staRecord->dataPdu[3]) ||
1909                   !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION])) {
1910                    unifi_trace(priv, UDBG3, "tim set due to unicast pkt & peer in powersave\n");
1911                    if (!staRecord->timRequestPendingFlag){
1912                        update_tim(priv,staRecord->aid,1,interfaceTag, handle);
1913                    }
1914                    else
1915                    {
1916                        /* Cache the TimSet value so that it will processed immidiatly after
1917                         * completing the current setTim Request
1918                         */
1919                        staRecord->updateTimReqQueued = 1;
1920                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1921                                    staRecord->aid);
1922                    }
1923                }
1924            } else {
1925                /* Check for non delivery enable(i.e trigger enable), all delivery enable & legacy AC for TIM update in firmware */
1926                u8 allDeliveryEnabled = 0, dataAvailable = 0;
1927                /* Check if all AC's are Delivery Enabled */
1928                is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
1929                if (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable)
1930                    || (!list_empty(&staRecord->mgtFrames))) {
1931                    if (!staRecord->timRequestPendingFlag) {
1932                        update_tim(priv,staRecord->aid,1,interfaceTag, handle);
1933                    }
1934                    else
1935                    {
1936                        /* Cache the TimSet value so that it will processed immidiatly after
1937                         * completing the current setTim Request
1938                         */
1939                        staRecord->updateTimReqQueued = 1;
1940                        unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
1941                                    staRecord->aid);
1942                    }
1943                }
1944            }
1945        }
1946    }
1947
1948    if((list) && (pktType == CSR_WIFI_UNICAST_PDU && !queuePacketDozing) && !(isRouterBufferEnabled(priv,priority_q)) && !(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
1949        unifi_trace(priv, UDBG2, "buffering cleared for queue = %d So resending buffered frames\n",priority_q);
1950        uf_send_buffered_frames(priv, priority_q);
1951    }
1952    unifi_trace(priv, UDBG5, "leaving uf_process_ma_packet_req \n");
1953    return status;
1954#else
1955#ifdef CSR_NATIVE_LINUX
1956    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
1957        unifi_error(priv, "interfaceTag >= CSR_WIFI_NUM_INTERFACES, interfacetag = %d\n", interfaceTag);
1958        return CSR_RESULT_FAILURE;
1959    }
1960    /* Frame ma-packet.req, this is saved/transmitted depend on queue state */
1961    unifi_frame_ma_packet_req(priv, priority, TransmitRate, hostTag, interfaceTag,
1962            transmissionControl, leSenderProcessId,
1963            peerMacAddress, &signal);
1964    result = ul_send_signal_unpacked(priv, &signal, bulkdata);
1965    if (result) {
1966        return CSR_RESULT_FAILURE;
1967    }
1968#endif
1969    return status;
1970#endif
1971}
1972
1973#ifdef CSR_SUPPORT_SME
1974s8 uf_get_protection_bit_from_interfacemode(unifi_priv_t *priv, u16 interfaceTag, const u8 *daddr)
1975{
1976    s8 protection = 0;
1977    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
1978
1979    switch(interfacePriv->interfaceMode)
1980    {
1981        case CSR_WIFI_ROUTER_CTRL_MODE_STA:
1982        case CSR_WIFI_ROUTER_CTRL_MODE_P2PCLI:
1983        case CSR_WIFI_ROUTER_CTRL_MODE_AMP:
1984        case CSR_WIFI_ROUTER_CTRL_MODE_IBSS:
1985            protection = interfacePriv->protect;
1986            break;
1987        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
1988        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
1989            {
1990                CsrWifiRouterCtrlStaInfo_t *dstStaInfo = NULL;
1991                if (daddr[0] & 0x1) {
1992                    unifi_trace(priv, UDBG3, "broadcast/multicast packet in send_ma_pkt_request\n");
1993                    /* In this mode, the protect member of priv structure has an information of how
1994                     * AP/P2PGO has started, & the member updated in set mode request for AP/P2PGO
1995                     */
1996                    protection = interfacePriv->protect;
1997                } else {
1998                    /* fetch the destination record from station record database */
1999                    dstStaInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, daddr, interfaceTag);
2000                    if (!dstStaInfo) {
2001                        unifi_trace(priv, UDBG3, "peer not found in station record in send_ma_pkt_request\n");
2002                        return -1;
2003                    }
2004                    protection = dstStaInfo->protection;
2005                }
2006            }
2007            break;
2008        default:
2009            unifi_trace(priv, UDBG2, "mode unknown in send_ma_pkt_request\n");
2010    }
2011    return protection;
2012}
2013#endif
2014#ifdef CSR_SUPPORT_SME
2015u8 send_multicast_frames(unifi_priv_t *priv, u16 interfaceTag)
2016{
2017    int r;
2018    tx_buffered_packets_t * buffered_pkt = NULL;
2019    u8 moreData = FALSE;
2020    u8 pduSent =0;
2021    unsigned long lock_flags;
2022    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2023    u32 hostTag = 0xffffffff;
2024
2025    if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_VO)) {
2026        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames))) {
2027            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK);
2028            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
2029
2030
2031            unifi_trace(priv,UDBG2,"DTIM Occurred for interface:sending Mgt packet %d\n",interfaceTag);
2032
2033            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
2034               unifi_trace(priv,UDBG1,"frame_and_send_queued_pdu failed with ENOSPC for host tag = %x\n", buffered_pkt->hostTag);
2035               /* Enqueue at the head of the queue */
2036               spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2037               list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastMgtFrames);
2038               spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2039               break;
2040            } else {
2041                unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastMgtFrames (%x, %x)\n",
2042                                        buffered_pkt->hostTag,
2043                                        r);
2044                if(r) {
2045                   unifi_net_data_free(priv, &buffered_pkt->bulkdata);
2046                }
2047                if(!moreData) {
2048
2049                    interfacePriv->dtimActive = FALSE;
2050                    if(!r) {
2051                        hostTag = buffered_pkt->hostTag;
2052                        pduSent++;
2053                    } else {
2054                        send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE);
2055                    }
2056                }
2057                /* Buffered frame sent successfully */
2058                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2059                interfacePriv->noOfbroadcastPktQueued--;
2060                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2061                kfree(buffered_pkt);
2062           }
2063
2064        }
2065    }
2066    if(!isRouterBufferEnabled(priv,UNIFI_TRAFFIC_Q_CONTENTION)) {
2067        while((interfacePriv->dtimActive)&& (buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMulticastOrBroadCastFrames))) {
2068            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
2069            moreData = (buffered_pkt->transmissionControl & TRANSMISSION_CONTROL_EOSP_MASK)?FALSE:TRUE;
2070
2071
2072            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,moreData,FALSE)) == -ENOSPC) {
2073                /* Clear the trigger bit transmission control*/
2074                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK);
2075                /* Enqueue at the head of the queue */
2076                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2077                list_add(&buffered_pkt->q, &interfacePriv->genericMulticastOrBroadCastFrames);
2078                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2079                break;
2080            } else {
2081                if(r) {
2082                    unifi_trace(priv,UDBG1,"send_multicast_frames: Send genericMulticastOrBroadCastFrame failed (%x, %x)\n",
2083                                            buffered_pkt->hostTag,
2084                                            r);
2085                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
2086                }
2087                if(!moreData) {
2088                    interfacePriv->dtimActive = FALSE;
2089                    if(!r) {
2090                        pduSent ++;
2091                        hostTag = buffered_pkt->hostTag;
2092                    } else {
2093                        send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_UNSPECIFIED_FAILURE);
2094                    }
2095                }
2096                /* Buffered frame sent successfully */
2097                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2098                interfacePriv->noOfbroadcastPktQueued--;
2099                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2100                kfree(buffered_pkt);
2101            }
2102        }
2103    }
2104    if((interfacePriv->dtimActive == FALSE)) {
2105        /* Record the host Tag*/
2106        unifi_trace(priv,UDBG2,"send_multicast_frames: Recorded hostTag of EOSP packet: = 0x%x\n",hostTag);
2107        interfacePriv->multicastPduHostTag = hostTag;
2108    }
2109    return pduSent;
2110}
2111#endif
2112void uf_process_ma_vif_availibility_ind(unifi_priv_t *priv,u8 *sigdata,
2113                                        u32 siglen)
2114{
2115#ifdef CSR_SUPPORT_SME
2116    CSR_SIGNAL signal;
2117    CSR_MA_VIF_AVAILABILITY_INDICATION *ind;
2118    int r;
2119    u16 interfaceTag;
2120    u8 pduSent =0;
2121    CSR_RESULT_CODE resultCode = CSR_RC_SUCCESS;
2122    netInterface_priv_t *interfacePriv;
2123
2124    unifi_trace(priv, UDBG3,
2125            "uf_process_ma_vif_availibility_ind: Process signal 0x%.4X\n",
2126            *((u16*)sigdata));
2127
2128    r = read_unpack_signal(sigdata, &signal);
2129    if (r) {
2130        unifi_error(priv,
2131                    "uf_process_ma_vif_availibility_ind: Received unknown signal 0x%.4X.\n",
2132                    CSR_GET_UINT16_FROM_LITTLE_ENDIAN(sigdata));
2133        return;
2134    }
2135    ind = &signal.u.MaVifAvailabilityIndication;
2136    interfaceTag=ind->VirtualInterfaceIdentifier & 0xff;
2137
2138    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
2139        unifi_error(priv, "in vif_availability_ind interfaceTag is wrong\n");
2140        return;
2141    }
2142
2143    interfacePriv = priv->interfacePriv[interfaceTag];
2144
2145    if(ind->Multicast) {
2146        if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames) &&
2147            list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames)) {
2148            /* This condition can occur because of a potential race where the
2149               TIM is not yet reset as host is waiting for confirm but it is sent
2150               by firmware and DTIM occurs*/
2151            unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
2152            send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
2153            interfacePriv->dtimActive = FALSE;
2154            if(interfacePriv->multicastPduHostTag == 0xffffffff) {
2155                unifi_notice(priv,"ma_vif_availibility_ind recevied for multicast but queues are empty%d\n",interfaceTag);
2156                /* This may be an extra request in very rare race conditions but it is fine as it would atleast remove the potential lock up */
2157                if (!interfacePriv->bcTimSetReqPendingFlag)
2158                {
2159                    update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0xFFFFFFFF);
2160                }
2161                else
2162                {
2163                    /* Cache the TimSet value so that it will processed immidiatly after
2164                     * completing the current setTim Request
2165                     */
2166                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
2167                    unifi_trace(priv, UDBG2, "uf_process_ma_vif_availibility_ind : One more UpdateDTim Request(%d) Queued \n",
2168                                interfacePriv->bcTimSetReqQueued);
2169                }
2170            }
2171            return;
2172        }
2173        if(interfacePriv->dtimActive) {
2174            unifi_trace(priv,UDBG2,"DTIM Occurred for already active DTIM interface %d\n",interfaceTag);
2175            return;
2176        } else {
2177            unifi_trace(priv,UDBG2,"DTIM Occurred for interface %d\n",interfaceTag);
2178            if(list_empty(&interfacePriv->genericMulticastOrBroadCastFrames)) {
2179                set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastMgtFrames);
2180            } else {
2181                set_eosp_transmit_ctrl(priv,&interfacePriv->genericMulticastOrBroadCastFrames);
2182            }
2183        }
2184        interfacePriv->dtimActive = TRUE;
2185        pduSent = send_multicast_frames(priv,interfaceTag);
2186    }
2187    else {
2188        unifi_error(priv,"Interface switching is not supported %d\n",interfaceTag);
2189        resultCode = CSR_RC_NOT_SUPPORTED;
2190        send_vif_availibility_rsp(priv,ind->VirtualInterfaceIdentifier,CSR_RC_NOT_SUPPORTED);
2191    }
2192#endif
2193}
2194#ifdef CSR_SUPPORT_SME
2195
2196#define  GET_ACTIVE_INTERFACE_TAG(priv) 0
2197
2198static u8 uf_is_more_data_for_delivery_ac(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord)
2199{
2200    s8 i;
2201
2202    for(i=UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--)
2203    {
2204        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2205             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2206             &&(!list_empty(&staRecord->dataPdu[i]))) {
2207            unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data Available AC = %d\n", i);
2208            return TRUE;
2209        }
2210    }
2211
2212    unifi_trace(priv,UDBG2,"uf_is_more_data_for_delivery_ac: Data NOT Available \n");
2213    return FALSE;
2214}
2215
2216static u8 uf_is_more_data_for_usp_delivery(unifi_priv_t *priv, CsrWifiRouterCtrlStaInfo_t *staRecord, unifi_TrafficQueue queue)
2217{
2218    s8 i;
2219
2220    for(i = queue; i >= UNIFI_TRAFFIC_Q_BK; i--)
2221    {
2222        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2223             ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2224             &&(!list_empty(&staRecord->dataPdu[i]))) {
2225            unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data Available AC = %d\n", i);
2226            return TRUE;
2227        }
2228    }
2229
2230    unifi_trace(priv,UDBG2,"uf_is_more_data_for_usp_delivery: Data NOT Available \n");
2231    return FALSE;
2232}
2233
2234/*
2235 * ---------------------------------------------------------------------------
2236 *  uf_send_buffered_data_from_delivery_ac
2237 *
2238 *      This function takes care of
2239 *      -> Parsing the delivery enabled queue & sending frame down to HIP
2240 *      -> Setting EOSP=1 when USP to be terminated
2241 *      -> Depending on MAX SP length services the USP
2242 *
2243 * NOTE:This function always called from uf_handle_uspframes_delivery(), Dont
2244 *      call this function from any other location in code
2245 *
2246 *  Arguments:
2247 *      priv        Pointer to device private context struct
2248 *      vif         interface specific HIP vif instance
2249 *      staInfo     peer for which UAPSD to be scheduled
2250 *      queue       AC from which Data to be sent in USP
2251 *      txList      access category for processing list
2252 * ---------------------------------------------------------------------------
2253 */
2254void uf_send_buffered_data_from_delivery_ac(unifi_priv_t *priv,
2255                                            CsrWifiRouterCtrlStaInfo_t * staInfo,
2256                                            u8 queue,
2257                                            struct list_head *txList)
2258{
2259
2260    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
2261    tx_buffered_packets_t * buffered_pkt = NULL;
2262    unsigned long lock_flags;
2263    u8 eosp=FALSE;
2264    s8 r =0;
2265    u8 moreData = FALSE;
2266    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2267
2268    unifi_trace(priv, UDBG2, "++uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
2269
2270    if (queue > UNIFI_TRAFFIC_Q_VO)
2271    {
2272        return;
2273    }
2274    while((buffered_pkt=dequeue_tx_data_pdu(priv, txList))) {
2275        if((IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
2276            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: DTIM Active, suspend UAPSD, staId: 0x%x\n",
2277                        staInfo->aid);
2278
2279            /* Once resume called, the U-APSD delivery operation will resume */
2280            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2281            staInfo->uspSuspend = TRUE;
2282            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2283            /* re-queueing the packet as DTIM started */
2284            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2285            list_add(&buffered_pkt->q,txList);
2286            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2287            break;
2288        }
2289
2290        buffered_pkt->transmissionControl &=
2291                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
2292
2293
2294        if((staInfo->wmmOrQosEnabled == TRUE)&&(staInfo->uapsdActive == TRUE)) {
2295
2296             buffered_pkt->transmissionControl = TRANSMISSION_CONTROL_TRIGGER_MASK;
2297
2298             /* Check All delivery enables Ac for more data, because caller of this
2299              * function not aware about last packet
2300              * (First check in moreData fetching helps in draining out Mgt frames Q)
2301              */
2302              moreData = (!list_empty(txList) || uf_is_more_data_for_usp_delivery(priv, staInfo, queue));
2303
2304              if(staInfo->noOfSpFramesSent == (staInfo->maxSpLength - 1)) {
2305                  moreData = FALSE;
2306              }
2307
2308              if(moreData == FALSE) {
2309                  eosp = TRUE;
2310                  buffered_pkt->transmissionControl =
2311                      (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
2312              }
2313        } else {
2314            /* Non QoS and non U-APSD */
2315            unifi_warning(priv, "uf_send_buffered_data_from_delivery_ac: non U-APSD !!! \n");
2316        }
2317
2318        unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_delivery_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
2319
2320        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
2321
2322            unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: UASPD suspended, ENOSPC in hipQ=%x\n", queue);
2323
2324            /* Once resume called, the U-APSD delivery operation will resume */
2325            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2326            staInfo->uspSuspend = TRUE;
2327            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2328
2329            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2330            list_add(&buffered_pkt->q,txList);
2331            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2332            priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
2333            break;
2334        } else {
2335            if(r){
2336                /* the PDU failed where we can't do any thing so free the storage */
2337                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
2338            }
2339            kfree(buffered_pkt);
2340            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2341            staInfo->noOfSpFramesSent++;
2342            if((!moreData) || (staInfo->noOfSpFramesSent == staInfo->maxSpLength)) {
2343                unifi_trace(priv, UDBG2, "uf_send_buffered_data_from_delivery_ac: Terminating USP\n");
2344                staInfo->uapsdActive = FALSE;
2345                staInfo->uspSuspend = FALSE;
2346                staInfo->noOfSpFramesSent = 0;
2347                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2348                break;
2349            }
2350            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2351        }
2352    }
2353    unifi_trace(priv, UDBG2, "--uf_send_buffered_data_from_delivery_ac, active=%x\n", staInfo->uapsdActive);
2354}
2355
2356void uf_send_buffered_data_from_ac(unifi_priv_t *priv,
2357                                   CsrWifiRouterCtrlStaInfo_t * staInfo,
2358                                   u8 queue,
2359                                   struct list_head *txList)
2360{
2361    tx_buffered_packets_t * buffered_pkt = NULL;
2362    unsigned long lock_flags;
2363    u8 eosp=FALSE;
2364    u8 moreData = FALSE;
2365    s8 r =0;
2366
2367    unifi_trace(priv,UDBG2,"uf_send_buffered_data_from_ac :\n");
2368
2369    while(!isRouterBufferEnabled(priv,queue) &&
2370                    ((buffered_pkt=dequeue_tx_data_pdu(priv, txList))!=NULL)){
2371
2372        buffered_pkt->transmissionControl &=
2373                 ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
2374
2375        unifi_trace(priv,UDBG3,"uf_send_buffered_data_from_ac : MoreData:%d, EOSP:%d\n",moreData,eosp);
2376
2377        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,moreData,eosp)) == -ENOSPC) {
2378           /* Enqueue at the head of the queue */
2379           spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
2380           list_add(&buffered_pkt->q,txList);
2381           spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
2382           if(staInfo != NULL){
2383              priv->pausedStaHandle[queue]=(u8)(staInfo->assignedHandle);
2384           }
2385           unifi_trace(priv,UDBG3," uf_send_buffered_data_from_ac: PDU sending failed .. no space for queue %d \n",queue);
2386           } else {
2387            if(r){
2388                /* the PDU failed where we can't do any thing so free the storage */
2389                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
2390            }
2391            kfree(buffered_pkt);
2392      }
2393  }
2394
2395}
2396
2397void uf_send_buffered_frames(unifi_priv_t *priv,unifi_TrafficQueue q)
2398{
2399    u16 interfaceTag = GET_ACTIVE_INTERFACE_TAG(priv);
2400    u32 startIndex=0,endIndex=0;
2401    CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
2402    u8 queue;
2403    u8 moreData = FALSE;
2404
2405    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2406
2407    if(!((interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_AP) ||
2408        (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_P2PGO)))
2409        return;
2410
2411    queue = (q<=3)?q:0;
2412
2413    if(interfacePriv->dtimActive) {
2414        /* this function updates dtimActive*/
2415        send_multicast_frames(priv,interfaceTag);
2416        if(!interfacePriv->dtimActive) {
2417            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
2418             !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
2419            if(!moreData) {
2420                if (!interfacePriv->bcTimSetReqPendingFlag)
2421                {
2422                    update_tim(priv,0,CSR_WIFI_TIM_RESET,interfaceTag, 0XFFFFFFFF);
2423                }
2424                else
2425                {
2426                    /* Cache the TimSet value so that it will processed immidiatly after
2427                     * completing the current setTim Request
2428                     */
2429                    interfacePriv->bcTimSetReqQueued = CSR_WIFI_TIM_RESET;
2430                    unifi_trace(priv, UDBG2, "uf_send_buffered_frames : One more UpdateDTim Request(%d) Queued \n",
2431                                interfacePriv->bcTimSetReqQueued);
2432                }
2433            }
2434        } else {
2435            moreData = (!list_empty(&interfacePriv->genericMulticastOrBroadCastMgtFrames) ||
2436                        !list_empty(&interfacePriv->genericMulticastOrBroadCastFrames));
2437           if(!moreData) {
2438               /* This should never happen but if it happens, we need a way out */
2439               unifi_error(priv,"ERROR: No More Data but DTIM is active sending Response\n");
2440               send_vif_availibility_rsp(priv,uf_get_vif_identifier(interfacePriv->interfaceMode,interfaceTag),CSR_RC_NO_BUFFERED_BROADCAST_MULTICAST_FRAMES);
2441               interfacePriv->dtimActive = FALSE;
2442           }
2443        }
2444        return;
2445    }
2446    if(priv->pausedStaHandle[queue] > 7) {
2447        priv->pausedStaHandle[queue] = 0;
2448    }
2449
2450    if(queue == UNIFI_TRAFFIC_Q_VO) {
2451
2452
2453        unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying mgt from queue=%d\n",queue);
2454        for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
2455            staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
2456            if(!staInfo ) {
2457                continue;
2458            } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2459                       &&(staInfo->uapsdActive == FALSE) ) {
2460                continue;
2461            }
2462
2463            if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2464                               &&(staInfo->uapsdActive == FALSE)){
2465                            /*Non-UAPSD case push the management frames out*/
2466               if(!list_empty(&staInfo->mgtFrames)){
2467                    uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2468                }
2469            }
2470
2471            if(isRouterBufferEnabled(priv,queue)) {
2472                unifi_notice(priv,"uf_send_buffered_frames : No space Left for queue = %d\n",queue);
2473                break;
2474            }
2475        }
2476        /*push generic management frames out*/
2477        if(!list_empty(&interfacePriv->genericMgtFrames)) {
2478            unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying generic mgt from queue=%d\n",queue);
2479            uf_send_buffered_data_from_ac(priv,staInfo, UNIFI_TRAFFIC_Q_VO, &interfacePriv->genericMgtFrames);
2480        }
2481    }
2482
2483
2484    unifi_trace(priv,UDBG2,"uf_send_buffered_frames : Resume called for Queue=%d\n",queue);
2485    unifi_trace(priv,UDBG2,"uf_send_buffered_frames : start=%d end=%d\n",startIndex,endIndex);
2486
2487    startIndex = priv->pausedStaHandle[queue];
2488    endIndex = (startIndex + UNIFI_MAX_CONNECTIONS -1) % UNIFI_MAX_CONNECTIONS;
2489
2490    while(startIndex != endIndex) {
2491        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
2492        if(!staInfo) {
2493            startIndex ++;
2494            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2495                startIndex = 0;
2496            }
2497            continue;
2498        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
2499                   &&(staInfo->uapsdActive == FALSE)) {
2500            startIndex ++;
2501            if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2502                startIndex = 0;
2503            }
2504            continue;
2505        }
2506        /* Peer is active or U-APSD is active so send PDUs to the peer */
2507        unifi_trace(priv,UDBG2,"uf_send_buffered_frames : trying data from queue=%d\n",queue);
2508
2509
2510        if((staInfo != NULL)&&(staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
2511                           &&(staInfo->uapsdActive == FALSE)) {
2512           if(!list_empty(&staInfo->dataPdu[queue])) {
2513
2514               /*Non-UAPSD case push the AC frames out*/
2515               uf_send_buffered_data_from_ac(priv, staInfo, queue, (&staInfo->dataPdu[queue]));
2516           }
2517        }
2518        startIndex ++;
2519        if(startIndex >= UNIFI_MAX_CONNECTIONS) {
2520           startIndex = 0;
2521        }
2522    }
2523    if(isRouterBufferEnabled(priv,queue)) {
2524        priv->pausedStaHandle[queue] = endIndex;
2525    } else {
2526        priv->pausedStaHandle[queue] = 0;
2527    }
2528
2529    /* U-APSD might have stopped because of ENOSPC in lib_hip (pause activity).
2530     * So restart it if U-APSD was active with any of the station
2531     */
2532    unifi_trace(priv, UDBG4, "csrWifiHipSendBufferedFrames: UAPSD Resume Q=%x\n", queue);
2533    resume_suspended_uapsd(priv, interfaceTag);
2534}
2535
2536
2537u8 uf_is_more_data_for_non_delivery_ac(CsrWifiRouterCtrlStaInfo_t *staRecord)
2538{
2539    u8 i;
2540
2541    for(i=0;i<=3;i++)
2542    {
2543        if(((staRecord->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
2544                ||(staRecord->powersaveMode[i]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
2545                &&(!list_empty(&staRecord->dataPdu[i]))){
2546
2547         return TRUE;
2548        }
2549    }
2550
2551    if(((staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
2552            ||(staRecord->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_LEGACY_POWER_SAVE))
2553            &&(!list_empty(&staRecord->mgtFrames))){
2554
2555     return TRUE;
2556    }
2557
2558
2559
2560    return FALSE;
2561}
2562
2563
2564int uf_process_station_records_for_sending_data(unifi_priv_t *priv,u16 interfaceTag,
2565                                                 CsrWifiRouterCtrlStaInfo_t *srcStaInfo,
2566                                                 CsrWifiRouterCtrlStaInfo_t *dstStaInfo)
2567{
2568    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2569
2570    unifi_trace(priv, UDBG5, "entering uf_process_station_records_for_sending_data\n");
2571
2572    if (srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_DISCONNECTED) {
2573        unifi_error(priv, "Peer State not connected AID = %x, handle = %x, control port state = %x\n",
2574                    srcStaInfo->aid, srcStaInfo->assignedHandle, srcStaInfo->peerControlledPort->port_action);
2575        return -1;
2576    }
2577    switch (interfacePriv->interfaceMode)
2578    {
2579        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2580        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2581            unifi_trace(priv, UDBG5, "mode is AP/P2PGO\n");
2582            break;
2583        default:
2584            unifi_warning(priv, "mode is nor AP neither P2PGO, packet cant be xmit\n");
2585            return -1;
2586    }
2587
2588    switch(dstStaInfo->peerControlledPort->port_action)
2589    {
2590        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_DISCARD:
2591        case CSR_WIFI_ROUTER_CTRL_PORT_ACTION_8021X_PORT_CLOSED_BLOCK:
2592            unifi_trace(priv, UDBG5, "destination port is closed/blocked, discarding the packet\n");
2593            return -1;
2594        default:
2595            unifi_trace(priv, UDBG5, "destination port state is open\n");
2596    }
2597
2598    /* port state is open, destination station record is valid, Power save state is
2599     * validated in uf_process_ma_packet_req function
2600     */
2601    unifi_trace(priv, UDBG5, "leaving uf_process_station_records_for_sending_data\n");
2602    return 0;
2603}
2604
2605
2606/*
2607 * ---------------------------------------------------------------------------
2608 *  uf_handle_uspframes_delivery
2609 *
2610 *      This function takes care of handling USP session for peer, when
2611 *      -> trigger frame from peer
2612 *      -> suspended USP to be processed (resumed)
2613 *
2614 *      NOTE: uf_send_buffered_data_from_delivery_ac() always called from this function, Dont
2615 *      make a direct call to uf_send_buffered_data_from_delivery_ac() from any other part of
2616 *      code
2617 *
2618 *  Arguments:
2619 *      priv            Pointer to device private context struct
2620 *      staInfo         peer for which UAPSD to be scheduled
2621 *      interfaceTag    virtual interface tag
2622 * ---------------------------------------------------------------------------
2623 */
2624static void uf_handle_uspframes_delivery(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t *staInfo, u16 interfaceTag)
2625{
2626
2627    s8 i;
2628    u8 allDeliveryEnabled = 0, dataAvailable = 0;
2629    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2630    unsigned long lock_flags;
2631
2632    unifi_trace(priv, UDBG2, " ++ uf_handle_uspframes_delivery, uapsd active=%x, suspended?=%x\n",
2633                staInfo->uapsdActive, staInfo->uspSuspend);
2634
2635    /* Check for Buffered frames according to priority order & deliver it
2636     *  1. AC_VO delivery enable & Mgt frames available
2637     *  2. Process remaining Ac's from order AC_VO to AC_BK
2638     */
2639
2640    /* USP initiated by WMMPS enabled peer  & SET the status flag to TRUE */
2641    if (!staInfo->uspSuspend && staInfo->uapsdActive)
2642    {
2643        unifi_notice(priv, "uf_handle_uspframes_delivery: U-APSD already active! STA=%x:%x:%x:%x:%x:%x\n",
2644                staInfo->peerMacAddress.a[0], staInfo->peerMacAddress.a[1],
2645                staInfo->peerMacAddress.a[2], staInfo->peerMacAddress.a[3],
2646                staInfo->peerMacAddress.a[4], staInfo->peerMacAddress.a[5]);
2647        return;
2648    }
2649
2650    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2651    staInfo->uapsdActive = TRUE;
2652    staInfo->uspSuspend = FALSE;
2653    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2654
2655    if(((staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)||
2656        (staInfo->powersaveMode[UNIFI_TRAFFIC_Q_VO]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE))
2657        && (!list_empty(&staInfo->mgtFrames))) {
2658
2659         /* Management queue has data &&  UNIFI_TRAFFIC_Q_VO is delivery enable */
2660        unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Sending buffered management frames\n");
2661        uf_send_buffered_data_from_delivery_ac(priv, staInfo, UNIFI_TRAFFIC_Q_VO, &staInfo->mgtFrames);
2662    }
2663
2664    if (!uf_is_more_data_for_delivery_ac(priv, staInfo)) {
2665        /* All delivery enable AC's are empty, so QNULL to be sent to terminate the USP
2666         * NOTE: If we have sent Mgt frame also, we must send QNULL followed to terminate USP
2667         */
2668        if (!staInfo->uspSuspend) {
2669            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2670            staInfo->uapsdActive = FALSE;
2671            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2672
2673            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: sending QNull for trigger\n");
2674            uf_send_qos_null(priv, interfaceTag, staInfo->peerMacAddress.a, (CSR_PRIORITY) staInfo->triggerFramePriority, staInfo);
2675            staInfo->triggerFramePriority = CSR_QOS_UP0;
2676        } else {
2677            unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: MgtQ xfer suspended\n");
2678        }
2679    } else {
2680        for(i = UNIFI_TRAFFIC_Q_VO; i >= UNIFI_TRAFFIC_Q_BK; i--) {
2681            if(((staInfo->powersaveMode[i]==CSR_WIFI_AC_DELIVERY_ONLY_ENABLE)
2682                ||(staInfo->powersaveMode[i]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED))
2683                && (!list_empty(&staInfo->dataPdu[i]))) {
2684                /* Deliver Data according to AC priority (from VO to BK) as part of USP */
2685                unifi_trace(priv, UDBG4, "uf_handle_uspframes_delivery: Buffered data frames from Queue (%d) for USP\n", i);
2686                uf_send_buffered_data_from_delivery_ac(priv, staInfo, i, &staInfo->dataPdu[i]);
2687            }
2688
2689            if ((!staInfo->uapsdActive) ||
2690                    (staInfo->uspSuspend && IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag))) {
2691                /* If DTIM active found on one AC, No need to parse the remaining AC's
2692                 * as USP suspended. Break out of loop
2693                 */
2694                unifi_trace(priv, UDBG2, "uf_handle_uspframes_delivery: suspend=%x,  DTIM=%x, USP terminated=%s\n",
2695                           staInfo->uspSuspend, IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag),
2696                           staInfo->uapsdActive?"NO":"YES");
2697                break;
2698            }
2699        }
2700    }
2701
2702    /* Depending on the USP status, update the TIM accordingly for delivery enabled AC only
2703     * (since we are not manipulating any Non-delivery list(AC))
2704     */
2705    is_all_ac_deliver_enabled_and_moredata(staInfo, &allDeliveryEnabled, &dataAvailable);
2706    if ((allDeliveryEnabled && !dataAvailable)) {
2707        if ((staInfo->timSet != CSR_WIFI_TIM_RESET) || (staInfo->timSet != CSR_WIFI_TIM_RESETTING)) {
2708            staInfo->updateTimReqQueued = (u8) CSR_WIFI_TIM_RESET;
2709            unifi_trace(priv, UDBG4, " --uf_handle_uspframes_delivery, UAPSD timset\n");
2710            if (!staInfo->timRequestPendingFlag) {
2711                update_tim(priv, staInfo->aid, 0, interfaceTag, staInfo->assignedHandle);
2712            }
2713        }
2714    }
2715    unifi_trace(priv, UDBG2, " --uf_handle_uspframes_delivery, uapsd active=%x, suspend?=%x\n",
2716                staInfo->uapsdActive, staInfo->uspSuspend);
2717}
2718
2719void uf_process_wmm_deliver_ac_uapsd(unifi_priv_t * priv,
2720                                     CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
2721                                     u16 qosControl,
2722                                     u16 interfaceTag)
2723{
2724    CSR_PRIORITY priority;
2725    unifi_TrafficQueue priority_q;
2726    unsigned long lock_flags;
2727
2728    unifi_trace(priv, UDBG2, "++uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
2729    /* If recceived Frames trigger Frame and Devlivery enabled AC has data
2730     * then transmit from High priorty delivery enabled AC
2731     */
2732    priority = (CSR_PRIORITY)(qosControl & IEEE802_11_QC_TID_MASK);
2733    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
2734
2735    if((srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_ONLY_ENABLED)
2736        ||(srcStaInfo->powersaveMode[priority_q]==CSR_WIFI_AC_TRIGGER_AND_DELIVERY_ENABLED)) {
2737        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2738        srcStaInfo->triggerFramePriority = priority;
2739        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2740        unifi_trace(priv, UDBG2, "uf_process_wmm_deliver_ac_uapsd: trigger frame, Begin U-APSD, triggerQ=%x\n", priority_q);
2741        uf_handle_uspframes_delivery(priv, srcStaInfo, interfaceTag);
2742    }
2743    unifi_trace(priv, UDBG2, "--uf_process_wmm_deliver_ac_uapsd: uapsdactive?=%x\n", srcStaInfo->uapsdActive);
2744}
2745
2746
2747void uf_send_qos_null(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
2748{
2749    bulk_data_param_t bulkdata;
2750    CsrResult csrResult;
2751    struct sk_buff *skb, *newSkb = NULL;
2752    CsrWifiMacAddress peerAddress;
2753    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2754    CSR_TRANSMISSION_CONTROL transmissionControl = (TRANSMISSION_CONTROL_EOSP_MASK | TRANSMISSION_CONTROL_TRIGGER_MASK);
2755    int r;
2756    CSR_SIGNAL signal;
2757    u32 priority_q;
2758    CSR_RATE transmitRate = 0;
2759
2760
2761    /* Send a Null Frame to Peer,
2762     * 32= size of mac header  */
2763    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE + QOS_CONTROL_HEADER_SIZE);
2764
2765    if (csrResult != CSR_RESULT_SUCCESS) {
2766        unifi_error(priv, " failed to allocate request_data. in uf_send_qos_null func\n");
2767        return ;
2768    }
2769    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
2770    skb->len = 0;
2771    bulkdata.d[0].os_data_ptr = skb->data;
2772    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
2773    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
2774    bulkdata.d[1].os_data_ptr = NULL;
2775    bulkdata.d[1].os_net_buf_ptr = NULL;
2776    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
2777
2778    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */
2779
2780    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
2781        unifi_error(priv, "failed to create MAC header\n");
2782        unifi_net_data_free(priv, &bulkdata.d[0]);
2783        return;
2784    }
2785    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
2786    /* convert priority to queue */
2787    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
2788
2789    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
2790     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
2791     */
2792    switch (interfacePriv->interfaceMode)
2793    {
2794        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2795            transmitRate = 2;
2796            break;
2797        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2798            transmitRate = 12;
2799            break;
2800        default:
2801            transmitRate = 0;
2802    }
2803    unifi_frame_ma_packet_req(priv, priority, transmitRate, 0xffffffff, interfaceTag,
2804                              transmissionControl, priv->netdev_client->sender_id,
2805                              peerAddress.a, &signal);
2806
2807    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
2808    if(r) {
2809        unifi_error(priv, "failed to send QOS data null packet result: %d\n",r);
2810        unifi_net_data_free(priv, &bulkdata.d[0]);
2811    }
2812
2813    return;
2814
2815}
2816void uf_send_nulldata(unifi_priv_t * priv,u16 interfaceTag, const u8 *da,CSR_PRIORITY priority,CsrWifiRouterCtrlStaInfo_t * srcStaInfo)
2817{
2818    bulk_data_param_t bulkdata;
2819    CsrResult csrResult;
2820    struct sk_buff *skb, *newSkb = NULL;
2821    CsrWifiMacAddress peerAddress;
2822    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
2823    CSR_TRANSMISSION_CONTROL transmissionControl = 0;
2824    int r;
2825    CSR_SIGNAL signal;
2826    u32 priority_q;
2827    CSR_RATE transmitRate = 0;
2828    CSR_MA_PACKET_REQUEST *req = &signal.u.MaPacketRequest;
2829    unsigned long lock_flags;
2830
2831    /* Send a Null Frame to Peer, size = 24 for MAC header */
2832    csrResult = unifi_net_data_malloc(priv, &bulkdata.d[0], MAC_HEADER_SIZE);
2833
2834    if (csrResult != CSR_RESULT_SUCCESS) {
2835        unifi_error(priv, "uf_send_nulldata: Failed to allocate memory for NULL frame\n");
2836        return ;
2837    }
2838    skb = (struct sk_buff *)(bulkdata.d[0].os_net_buf_ptr);
2839    skb->len = 0;
2840    bulkdata.d[0].os_data_ptr = skb->data;
2841    bulkdata.d[0].os_net_buf_ptr = (unsigned char*)skb;
2842    bulkdata.d[0].net_buf_length = bulkdata.d[0].data_length = skb->len;
2843    bulkdata.d[1].os_data_ptr = NULL;
2844    bulkdata.d[1].os_net_buf_ptr = NULL;
2845    bulkdata.d[1].net_buf_length = bulkdata.d[1].data_length = 0;
2846
2847    /* For null frames protection bit should not be set in MAC header, so passing value 0 below for protection field */
2848    if (prepare_and_add_macheader(priv, skb, newSkb, priority, &bulkdata, interfaceTag, da, interfacePriv->bssid.a, 0)) {
2849        unifi_error(priv, "uf_send_nulldata: Failed to create MAC header\n");
2850        unifi_net_data_free(priv, &bulkdata.d[0]);
2851        return;
2852    }
2853    memcpy(peerAddress.a, ((u8 *) bulkdata.d[0].os_data_ptr) + 4, ETH_ALEN);
2854    /* convert priority to queue */
2855    priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY) priority);
2856    transmissionControl &= ~(CSR_NO_CONFIRM_REQUIRED);
2857
2858    /* Frame ma-packet.req, this is saved/transmitted depend on queue state
2859     * send the null frame at data rate of 1 Mb/s for AP or 6 Mb/s for P2PGO
2860     */
2861    switch (interfacePriv->interfaceMode)
2862    {
2863        case CSR_WIFI_ROUTER_CTRL_MODE_AP:
2864            transmitRate = 2;
2865            break;
2866        case CSR_WIFI_ROUTER_CTRL_MODE_P2PGO:
2867            transmitRate = 12;
2868            break;
2869        default:
2870            transmitRate = 0;
2871    }
2872    unifi_frame_ma_packet_req(priv, priority, transmitRate, INVALID_HOST_TAG, interfaceTag,
2873                              transmissionControl, priv->netdev_client->sender_id,
2874                              peerAddress.a, &signal);
2875
2876    /* Save host tag to check the status on reception of MA packet confirm */
2877    srcStaInfo->nullDataHostTag = req->HostTag;
2878    unifi_trace(priv, UDBG1, "uf_send_nulldata: STA AID = %d hostTag = %x\n", srcStaInfo->aid, req->HostTag);
2879
2880    r = ul_send_signal_unpacked(priv, &signal, &bulkdata);
2881
2882    if(r == -ENOSPC) {
2883        unifi_trace(priv, UDBG1, "uf_send_nulldata: ENOSPC Requeue the Null frame\n");
2884        enque_tx_data_pdu(priv, &bulkdata, &srcStaInfo->dataPdu[priority_q], &signal, 1);
2885        spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2886        srcStaInfo->noOfPktQueued++;
2887        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2888
2889
2890    }
2891    if(r && r != -ENOSPC){
2892        unifi_error(priv, "uf_send_nulldata: Failed to send Null frame Error = %d\n",r);
2893        unifi_net_data_free(priv, &bulkdata.d[0]);
2894        srcStaInfo->nullDataHostTag = INVALID_HOST_TAG;
2895    }
2896
2897    return;
2898}
2899
2900u8 uf_check_broadcast_bssid(unifi_priv_t *priv, const bulk_data_param_t *bulkdata)
2901{
2902    u8 *bssid = NULL;
2903    static const CsrWifiMacAddress broadcast_address = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
2904    u8 toDs, fromDs;
2905
2906    toDs = (((bulkdata->d[0].os_data_ptr)[1]) & 0x01) ? 1 : 0;
2907    fromDs =(((bulkdata->d[0].os_data_ptr)[1]) & 0x02) ? 1 : 0;
2908
2909     if (toDs && fromDs)
2910    {
2911        unifi_trace(priv, UDBG6, "Address 4 present, Don't try to find BSSID\n");
2912        bssid = NULL;
2913    }
2914    else if((toDs == 0) && (fromDs ==0))
2915    {
2916        /* BSSID is Address 3 */
2917        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + (2 * ETH_ALEN));
2918    }
2919    else if(toDs)
2920    {
2921        /* BSSID is Address 1 */
2922        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4);
2923    }
2924    else if(fromDs)
2925    {
2926        /* BSSID is Address 2 */
2927        bssid = (u8 *) (bulkdata->d[0].os_data_ptr + 4 + ETH_ALEN);
2928    }
2929
2930    if (memcmp(broadcast_address.a, bssid, ETH_ALEN)== 0)
2931    {
2932        return TRUE;
2933    }
2934    else
2935    {
2936        return FALSE;
2937    }
2938}
2939
2940
2941u8 uf_process_pm_bit_for_peer(unifi_priv_t * priv, CsrWifiRouterCtrlStaInfo_t * srcStaInfo,
2942                                u8 pmBit,u16 interfaceTag)
2943{
2944    u8 moreData = FALSE;
2945    u8 powerSaveChanged = FALSE;
2946    unsigned long lock_flags;
2947
2948    unifi_trace(priv, UDBG3, "entering uf_process_pm_bit_for_peer\n");
2949    if (pmBit) {
2950        priv->allPeerDozing |= (0x01 << (srcStaInfo->assignedHandle));
2951    } else {
2952        priv->allPeerDozing &= ~(0x01 << (srcStaInfo->assignedHandle));
2953    }
2954    if(pmBit) {
2955        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {
2956
2957            /* disable the preemption */
2958            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2959            srcStaInfo->currentPeerState =CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE;
2960            powerSaveChanged = TRUE;
2961            /* enable the preemption */
2962            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2963        } else {
2964            return powerSaveChanged;
2965        }
2966    } else {
2967        if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE) {
2968            /* disable the preemption */
2969            spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
2970            srcStaInfo->currentPeerState = CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE;
2971            powerSaveChanged = TRUE;
2972            /* enable the preemption */
2973            spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
2974        }else {
2975            return powerSaveChanged;
2976        }
2977    }
2978
2979
2980    if(srcStaInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE) {
2981        unifi_trace(priv,UDBG3, "Peer with AID = %d is active now\n",srcStaInfo->aid);
2982        process_peer_active_transition(priv,srcStaInfo,interfaceTag);
2983    } else {
2984        unifi_trace(priv,UDBG3, "Peer with AID = %d is in PS Now\n",srcStaInfo->aid);
2985        /* Set TIM if needed */
2986        if(!srcStaInfo->wmmOrQosEnabled) {
2987            moreData = (!list_empty(&srcStaInfo->mgtFrames) ||
2988                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_VO])||
2989                        !list_empty(&srcStaInfo->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]));
2990            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
2991                unifi_trace(priv, UDBG3, "This condition should not occur\n");
2992                if (!srcStaInfo->timRequestPendingFlag){
2993                    update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
2994                }
2995                else
2996                {
2997                    /* Cache the TimSet value so that it will processed immidiatly after
2998                     * completing the current setTim Request
2999                     */
3000                    srcStaInfo->updateTimReqQueued = 1;
3001                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
3002                                srcStaInfo->aid);
3003                }
3004
3005            }
3006        } else {
3007            u8 allDeliveryEnabled = 0, dataAvailable = 0;
3008            unifi_trace(priv, UDBG5, "Qos in AP Mode\n");
3009            /* Check if all AC's are Delivery Enabled */
3010            is_all_ac_deliver_enabled_and_moredata(srcStaInfo, &allDeliveryEnabled, &dataAvailable);
3011            /*check for more data in non-delivery enabled queues*/
3012            moreData = (uf_is_more_data_for_non_delivery_ac(srcStaInfo) || (allDeliveryEnabled && dataAvailable));
3013
3014            if(moreData && (srcStaInfo->timSet == CSR_WIFI_TIM_RESET)) {
3015                if (!srcStaInfo->timRequestPendingFlag){
3016                    update_tim(priv,srcStaInfo->aid,1,interfaceTag, srcStaInfo->assignedHandle);
3017                }
3018                else
3019                {
3020                    /* Cache the TimSet value so that it will processed immidiatly after
3021                     * completing the current setTim Request
3022                     */
3023                    srcStaInfo->updateTimReqQueued = 1;
3024                    unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", srcStaInfo->updateTimReqQueued,
3025                                srcStaInfo->aid);
3026                }
3027            }
3028        }
3029    }
3030    unifi_trace(priv, UDBG3, "leaving uf_process_pm_bit_for_peer\n");
3031    return powerSaveChanged;
3032}
3033
3034
3035
3036void uf_process_ps_poll(unifi_priv_t *priv,u8* sa,u8* da,u8 pmBit,u16 interfaceTag)
3037{
3038    CsrWifiRouterCtrlStaInfo_t *staRecord =
3039    CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, sa, interfaceTag);
3040    tx_buffered_packets_t * buffered_pkt = NULL;
3041    CsrWifiMacAddress peerMacAddress;
3042    unsigned long lock_flags;
3043    s8 r =0;
3044    u8 moreData = FALSE;
3045    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3046
3047    unifi_trace(priv, UDBG3, "entering uf_process_ps_poll\n");
3048    if(!staRecord) {
3049        memcpy(peerMacAddress.a,sa,ETH_ALEN);
3050        unifi_trace(priv, UDBG3, "In uf_process_ps_poll, sta record not found:unexpected frame addr = %x:%x:%x:%x:%x:%x\n",
3051                sa[0], sa[1],sa[2], sa[3], sa[4],sa[5]);
3052        CsrWifiRouterCtrlUnexpectedFrameIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0,interfaceTag,peerMacAddress);
3053        return;
3054    }
3055
3056    uf_process_pm_bit_for_peer(priv,staRecord,pmBit,interfaceTag);
3057
3058    /* Update station last activity time */
3059    staRecord->activity_flag = TRUE;
3060
3061    /* This should not change the PM bit as PS-POLL has PM bit always set */
3062    if(!pmBit) {
3063        unifi_notice (priv," PM bit reset in PS-POLL\n");
3064        return;
3065    }
3066
3067    if(IS_DTIM_ACTIVE(interfacePriv->dtimActive,interfacePriv->multicastPduHostTag)) {
3068        /* giving more priority to multicast packets so dropping ps-poll*/
3069        unifi_notice (priv," multicast transmission is going on so don't take action on PS-POLL\n");
3070        return;
3071    }
3072
3073    if(!staRecord->wmmOrQosEnabled) {
3074        if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
3075            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
3076            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
3077                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
3078                        !list_empty(&staRecord->mgtFrames));
3079
3080            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3081            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3082                /* Clear the trigger bit transmission control*/
3083                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3084                /* Enqueue at the head of the queue */
3085                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3086                list_add(&buffered_pkt->q, &staRecord->mgtFrames);
3087                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3088                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3089                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
3090            } else {
3091                if(r){
3092                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3093                    /* the PDU failed where we can't do any thing so free the storage */
3094                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3095                }
3096                kfree(buffered_pkt);
3097            }
3098        } else if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]))) {
3099            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
3100            moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
3101                        !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]));
3102
3103            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3104            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3105                /* Clear the trigger bit transmission control*/
3106                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3107                /* Enqueue at the head of the queue */
3108                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3109                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]);
3110                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3111                priv->pausedStaHandle[3]=(u8)(staRecord->assignedHandle);
3112                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3113            } else {
3114                if(r){
3115                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3116                    /* the PDU failed where we can't do any thing so free the storage */
3117                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3118                }
3119                kfree(buffered_pkt);
3120            }
3121        } else  if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]))) {
3122            buffered_pkt->transmissionControl |= TRANSMISSION_CONTROL_TRIGGER_MASK;
3123            moreData = !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
3124
3125            buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3126            if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3127                /* Clear the trigger bit transmission control*/
3128                buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3129                /* Enqueue at the head of the queue */
3130                spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3131                list_add(&buffered_pkt->q, &staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]);
3132                spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3133                priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
3134                unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3135            } else {
3136                if(r){
3137                    unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3138                    /* the PDU failed where we can't do any thing so free the storage */
3139                    unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3140                }
3141                kfree(buffered_pkt);
3142            }
3143        } else {
3144         /* Actually since we have sent an ACK, there
3145         * there is no need to send a NULL frame*/
3146        }
3147        moreData = (!list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_VO]) ||
3148           !list_empty(&staRecord->dataPdu[UNIFI_TRAFFIC_Q_CONTENTION]) ||
3149            !list_empty(&staRecord->mgtFrames));
3150        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
3151            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
3152            if (!staRecord->timRequestPendingFlag){
3153                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
3154            }
3155            else
3156            {
3157                /* Cache the TimSet value so that it will processed immidiatly after
3158                 * completing the current setTim Request
3159                 */
3160                staRecord->updateTimReqQueued = 0;
3161                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
3162                            staRecord->aid);
3163            }
3164        }
3165    } else {
3166
3167        u8 allDeliveryEnabled = 0, dataAvailable = 0;
3168        unifi_trace(priv, UDBG3,"Qos Support station.Processing PS-Poll\n");
3169
3170        /*Send Data From Management Frames*/
3171        /* Priority orders for delivering the buffered packets are
3172         * 1. Deliver the Management frames if there
3173         * 2. Other access category frames which are non deliver enable including UNIFI_TRAFFIC_Q_VO
3174         * priority is from VO->BK
3175         */
3176
3177        /* Check if all AC's are Delivery Enabled */
3178        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
3179
3180        if (allDeliveryEnabled) {
3181            unifi_trace(priv, UDBG3, "uf_process_ps_poll: All ACs are delivery enable so Sending QOS Null in response of Ps-poll\n");
3182            uf_send_qos_null(priv,interfaceTag,sa,CSR_QOS_UP0,staRecord);
3183            return;
3184        }
3185
3186        if (!list_empty(&staRecord->mgtFrames)) {
3187             if ((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->mgtFrames))) {
3188                    /* We dont have packets in non delivery enabled UNIFI_TRAFFIC_Q_VO, So we are looking in management
3189                     * queue of the station record
3190                     */
3191                    moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
3192                    buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3193
3194                    /* Last parameter is EOSP & its false always for PS-POLL processing */
3195                    if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3196                        /* Clear the trigger bit transmission control*/
3197                        buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3198                        /* Enqueue at the head of the queue */
3199                        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3200                        list_add(&buffered_pkt->q, &staRecord->mgtFrames);
3201                        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3202                        priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
3203                        unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3204                    } else {
3205                        if(r){
3206                            unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3207                            /* the PDU failed where we can't do any thing so free the storage */
3208                            unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3209                        }
3210                        kfree(buffered_pkt);
3211                    }
3212                } else {
3213                    unifi_error(priv, "uf_process_ps_poll: Mgt frame list empty!! \n");
3214                }
3215
3216        } else {
3217            s8 i;
3218            /* We dont have buffered packet in mangement frame queue (1 failed), So proceed with condition 2
3219             * UNIFI_TRAFFIC_Q_VO -> VI -> BE -> BK
3220             */
3221            for(i= 3; i>=0; i--) {
3222                if (!IS_DELIVERY_ENABLED(staRecord->powersaveMode[i])) {
3223                    /* Send One packet, if queue is NULL then continue */
3224                    if((buffered_pkt=dequeue_tx_data_pdu(priv, &staRecord->dataPdu[i]))) {
3225                        moreData = uf_is_more_data_for_non_delivery_ac(staRecord);
3226
3227                        buffered_pkt->transmissionControl |= (TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3228
3229                        /* Last parameter is EOSP & its false always for PS-POLL processing */
3230                        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staRecord,moreData,FALSE)) == -ENOSPC) {
3231                            /* Clear the trigger bit transmission control*/
3232                            buffered_pkt->transmissionControl &= ~(TRANSMISSION_CONTROL_TRIGGER_MASK | TRANSMISSION_CONTROL_EOSP_MASK);
3233                            /* Enqueue at the head of the queue */
3234                            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3235                            list_add(&buffered_pkt->q, &staRecord->dataPdu[i]);
3236                            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3237                            priv->pausedStaHandle[0]=(u8)(staRecord->assignedHandle);
3238                            unifi_trace(priv, UDBG1, "(ENOSPC) PS-POLL received : PDU sending failed \n");
3239                        } else {
3240                            if(r) {
3241                                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3242                                /* the PDU failed where we can't do any thing so free the storage */
3243                                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3244                            }
3245                            kfree(buffered_pkt);
3246                        }
3247                        break;
3248                    }
3249                }
3250            }
3251        }
3252        /* Check if all AC's are Delivery Enabled */
3253        is_all_ac_deliver_enabled_and_moredata(staRecord, &allDeliveryEnabled, &dataAvailable);
3254        /*check for more data in non-delivery enabled queues*/
3255        moreData = (uf_is_more_data_for_non_delivery_ac(staRecord) || (allDeliveryEnabled && dataAvailable));
3256        if(!moreData && (staRecord->timSet == CSR_WIFI_TIM_SET)) {
3257            unifi_trace(priv, UDBG3, "more data = NULL, set tim to 0 in uf_process_ps_poll\n");
3258            if (!staRecord->timRequestPendingFlag){
3259                update_tim(priv,staRecord->aid,0,interfaceTag, staRecord->assignedHandle);
3260            }
3261            else
3262            {
3263                /* Cache the TimSet value so that it will processed immidiatly after
3264                 * completing the current setTim Request
3265                 */
3266                staRecord->updateTimReqQueued = 0;
3267                unifi_trace(priv, UDBG6, "update_tim : One more UpdateTim Request (Tim value:%d) Queued for AID %x\n", staRecord->updateTimReqQueued,
3268                            staRecord->aid);
3269            }
3270
3271        }
3272    }
3273
3274        unifi_trace(priv, UDBG3, "leaving uf_process_ps_poll\n");
3275}
3276
3277
3278
3279void add_to_send_cfm_list(unifi_priv_t * priv,
3280                          tx_buffered_packets_t *tx_q_item,
3281                          struct list_head *frames_need_cfm_list)
3282{
3283    tx_buffered_packets_t *send_cfm_list_item = NULL;
3284
3285    send_cfm_list_item = kmalloc(sizeof(tx_buffered_packets_t), GFP_ATOMIC);
3286
3287    if(send_cfm_list_item == NULL){
3288        unifi_warning(priv, "%s: Failed to allocate memory for new list item \n");
3289        return;
3290    }
3291
3292    INIT_LIST_HEAD(&send_cfm_list_item->q);
3293
3294    send_cfm_list_item->hostTag = tx_q_item->hostTag;
3295    send_cfm_list_item->interfaceTag = tx_q_item->interfaceTag;
3296    send_cfm_list_item->transmissionControl = tx_q_item->transmissionControl;
3297    send_cfm_list_item->leSenderProcessId = tx_q_item->leSenderProcessId;
3298    send_cfm_list_item->rate = tx_q_item->rate;
3299    memcpy(send_cfm_list_item->peerMacAddress.a, tx_q_item->peerMacAddress.a, ETH_ALEN);
3300    send_cfm_list_item->priority = tx_q_item->priority;
3301
3302    list_add_tail(&send_cfm_list_item->q, frames_need_cfm_list);
3303}
3304
3305void uf_prepare_send_cfm_list_for_queued_pkts(unifi_priv_t * priv,
3306                                                 struct list_head *frames_need_cfm_list,
3307                                                 struct list_head * list)
3308{
3309    tx_buffered_packets_t *tx_q_item = NULL;
3310    struct list_head *listHead;
3311    struct list_head *placeHolder;
3312    unsigned long lock_flags;
3313
3314    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3315
3316    /* Search through the list and if confirmation required for any frames,
3317    add it to the send_cfm list */
3318    list_for_each_safe(listHead, placeHolder, list) {
3319        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
3320
3321        if(!tx_q_item) {
3322            unifi_error(priv, "Entry should exist, otherwise it is a (BUG)\n");
3323            continue;
3324        }
3325
3326        /* check if confirmation is requested and if the sender ID
3327        is not netdevice client then save the entry in the list for need cfms */
3328        if (!(tx_q_item->transmissionControl & CSR_NO_CONFIRM_REQUIRED) &&
3329            (tx_q_item->leSenderProcessId != priv->netdev_client->sender_id)){
3330             unifi_trace(priv, UDBG1, "%s: SenderProcessID=%x host tag=%x transmission control=%x\n",
3331                __FUNCTION__,
3332                tx_q_item->leSenderProcessId,
3333                tx_q_item->hostTag,
3334                tx_q_item->transmissionControl);
3335
3336             add_to_send_cfm_list(priv, tx_q_item, frames_need_cfm_list);
3337        }
3338    }
3339
3340    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3341
3342}
3343
3344
3345
3346void uf_flush_list(unifi_priv_t * priv, struct list_head * list)
3347{
3348    tx_buffered_packets_t *tx_q_item;
3349    struct list_head *listHead;
3350    struct list_head *placeHolder;
3351    unsigned long lock_flags;
3352
3353    unifi_trace(priv, UDBG5, "entering the uf_flush_list \n");
3354
3355    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3356    /* go through list, delete & free memory */
3357    list_for_each_safe(listHead, placeHolder, list) {
3358        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
3359
3360        if(!tx_q_item) {
3361            unifi_error(priv, "entry should exists, otherwise crashes (bug)\n");
3362        }
3363        unifi_trace(priv, UDBG5,
3364                "proccess_tx:  in uf_flush_list peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
3365                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
3366                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
3367                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
3368                tx_q_item->leSenderProcessId);
3369
3370        list_del(listHead);
3371        /* free the allocated memory */
3372        unifi_net_data_free(priv, &tx_q_item->bulkdata);
3373        kfree(tx_q_item);
3374        tx_q_item = NULL;
3375        if (!priv->noOfPktQueuedInDriver) {
3376            unifi_error(priv, "packets queued in driver 0 still decrementing in %s\n", __FUNCTION__);
3377        } else {
3378            priv->noOfPktQueuedInDriver--;
3379        }
3380    }
3381    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3382}
3383
3384tx_buffered_packets_t *dequeue_tx_data_pdu(unifi_priv_t *priv, struct list_head *txList)
3385{
3386    /* dequeue the tx data packets from the appropriate queue */
3387    tx_buffered_packets_t *tx_q_item = NULL;
3388    struct list_head *listHead;
3389    struct list_head *placeHolder;
3390    unsigned long lock_flags;
3391
3392    unifi_trace(priv, UDBG5, "entering dequeue_tx_data_pdu\n");
3393    /* check for list empty */
3394    if (list_empty(txList)) {
3395        unifi_trace(priv, UDBG5, "In dequeue_tx_data_pdu, the list is empty\n");
3396        return NULL;
3397    }
3398
3399    /* Verification, if packet count is negetive */
3400    if (priv->noOfPktQueuedInDriver == 0xFFFF) {
3401        unifi_warning(priv, "no packet available in queue: debug");
3402        return NULL;
3403    }
3404
3405    /* return first node after header, & delete from the list  && atleast one item exist */
3406    spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3407    list_for_each_safe(listHead, placeHolder, txList) {
3408        tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
3409        list_del(listHead);
3410        break;
3411    }
3412    spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3413
3414    if (tx_q_item) {
3415        unifi_trace(priv, UDBG5,
3416                "proccess_tx:  In dequeue_tx_data_pdu peerMacAddress=%02X%02X%02X%02X%02X%02X senderProcessId=%x\n",
3417                tx_q_item->peerMacAddress.a[0], tx_q_item->peerMacAddress.a[1],
3418                tx_q_item->peerMacAddress.a[2], tx_q_item->peerMacAddress.a[3],
3419                tx_q_item->peerMacAddress.a[4], tx_q_item->peerMacAddress.a[5],
3420                tx_q_item->leSenderProcessId);
3421    }
3422
3423    unifi_trace(priv, UDBG5, "leaving dequeue_tx_data_pdu\n");
3424    return tx_q_item;
3425}
3426/* generic function to get the station record handler */
3427CsrWifiRouterCtrlStaInfo_t *CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(unifi_priv_t *priv,
3428        const u8 *peerMacAddress,
3429        u16 interfaceTag)
3430{
3431    u8 i;
3432    netInterface_priv_t *interfacePriv;
3433    unsigned long lock_flags;
3434
3435    if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) {
3436        unifi_error(priv, "interfaceTag is not proper, interfaceTag = %d\n", interfaceTag);
3437        return NULL;
3438    }
3439
3440    interfacePriv = priv->interfacePriv[interfaceTag];
3441
3442    /* disable the preemption until station record is fetched */
3443    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
3444
3445    for (i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
3446        if (interfacePriv->staInfo[i]!= NULL) {
3447            if (!memcmp(((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]))->peerMacAddress.a, peerMacAddress, ETH_ALEN)) {
3448                /* enable the preemption as station record is fetched */
3449                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3450                unifi_trace(priv, UDBG5, "peer entry found in station record\n");
3451                return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[i]));
3452            }
3453        }
3454    }
3455    /* enable the preemption as station record is fetched */
3456    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3457    unifi_trace(priv, UDBG5, "peer entry not found in station record\n");
3458    return NULL;
3459}
3460/* generic function to get the station record handler from the handle */
3461CsrWifiRouterCtrlStaInfo_t * CsrWifiRouterCtrlGetStationRecordFromHandle(unifi_priv_t *priv,
3462                                                                 u32 handle,
3463                                                                 u16 interfaceTag)
3464{
3465    netInterface_priv_t *interfacePriv;
3466
3467    if ((handle >= UNIFI_MAX_CONNECTIONS) || (interfaceTag >= CSR_WIFI_NUM_INTERFACES)) {
3468        unifi_error(priv, "handle/interfaceTag is not proper, handle = %d, interfaceTag = %d\n", handle, interfaceTag);
3469        return NULL;
3470    }
3471    interfacePriv = priv->interfacePriv[interfaceTag];
3472    return ((CsrWifiRouterCtrlStaInfo_t *) (interfacePriv->staInfo[handle]));
3473}
3474
3475/* Function to do inactivity */
3476void uf_check_inactivity(unifi_priv_t *priv, u16 interfaceTag, u32 currentTime)
3477{
3478    u32 i;
3479    CsrWifiRouterCtrlStaInfo_t *staInfo;
3480    u32 elapsedTime;    /* Time in microseconds */
3481    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3482    CsrWifiMacAddress peerMacAddress;
3483    unsigned long lock_flags;
3484
3485    if (interfacePriv == NULL) {
3486        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
3487        return;
3488    }
3489
3490    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
3491    /* Go through the list of stations to check for inactivity */
3492    for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
3493        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv, i, interfaceTag);
3494        if(!staInfo ) {
3495            continue;
3496        }
3497
3498        unifi_trace(priv, UDBG3, "Running Inactivity handler Time %xus station's last activity %xus\n",
3499                currentTime, staInfo->lastActivity);
3500
3501
3502        elapsedTime = (currentTime >= staInfo->lastActivity)?
3503                (currentTime - staInfo->lastActivity):
3504                (~((u32)0) - staInfo->lastActivity + currentTime);
3505        spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3506
3507        if (elapsedTime > MAX_INACTIVITY_INTERVAL) {
3508            memcpy((u8*)&peerMacAddress, (u8*)&staInfo->peerMacAddress, sizeof(CsrWifiMacAddress));
3509
3510            /* Indicate inactivity for the station */
3511            unifi_trace(priv, UDBG3, "Station %x:%x:%x:%x:%x:%x inactive since %xus\n sending Inactive Ind\n",
3512                        peerMacAddress.a[0], peerMacAddress.a[1],
3513                        peerMacAddress.a[2], peerMacAddress.a[3],
3514                        peerMacAddress.a[4], peerMacAddress.a[5],
3515                        elapsedTime);
3516
3517            CsrWifiRouterCtrlStaInactiveIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, peerMacAddress);
3518        }
3519    }
3520
3521    interfacePriv->last_inactivity_check = currentTime;
3522}
3523
3524/* Function to update activity of a station */
3525void uf_update_sta_activity(unifi_priv_t *priv, u16 interfaceTag, const u8 *peerMacAddress)
3526{
3527    u32 elapsedTime, currentTime;    /* Time in microseconds */
3528    u32 timeHi;         /* Not used - Time in microseconds */
3529    CsrWifiRouterCtrlStaInfo_t *staInfo;
3530    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3531    unsigned long lock_flags;
3532
3533    if (interfacePriv == NULL) {
3534        unifi_trace(priv, UDBG3, "uf_check_inactivity: Interface priv is NULL \n");
3535        return;
3536    }
3537
3538    currentTime = CsrTimeGet(&timeHi);
3539
3540
3541    staInfo = CsrWifiRouterCtrlGetStationRecordFromPeerMacAddress(priv, peerMacAddress, interfaceTag);
3542
3543    if (staInfo == NULL) {
3544        unifi_trace(priv, UDBG4, "Sta does not exist yet");
3545        return;
3546    }
3547
3548    spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
3549    /* Update activity */
3550    staInfo->lastActivity = currentTime;
3551
3552    /* See if inactivity handler needs to be run
3553     * Here it is theoretically possible that the counter may have wrapped around. But
3554     * since we just want to know when to run the inactivity handler it does not really matter.
3555     * Especially since this is data path it makes sense in keeping it simple and avoiding
3556     * 64 bit handling */
3557    elapsedTime = (currentTime >= interfacePriv->last_inactivity_check)?
3558                    (currentTime - interfacePriv->last_inactivity_check):
3559                    (~((u32)0) - interfacePriv->last_inactivity_check + currentTime);
3560
3561    spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3562
3563    /* Check if it is time to run the inactivity handler */
3564    if (elapsedTime > INACTIVITY_CHECK_INTERVAL) {
3565        uf_check_inactivity(priv, interfaceTag, currentTime);
3566    }
3567}
3568void resume_unicast_buffered_frames(unifi_priv_t *priv, u16 interfaceTag)
3569{
3570
3571   netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3572   u8 i;
3573   int j;
3574   tx_buffered_packets_t * buffered_pkt = NULL;
3575   u8 hipslotFree[4] = {TRUE,TRUE,TRUE,TRUE};
3576   int r;
3577   unsigned long lock_flags;
3578
3579   while(!isRouterBufferEnabled(priv,3) &&
3580                            ((buffered_pkt=dequeue_tx_data_pdu(priv,&interfacePriv->genericMgtFrames))!=NULL)) {
3581        buffered_pkt->transmissionControl &=
3582                     ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3583        if((r=frame_and_send_queued_pdu(priv,buffered_pkt,NULL,0,FALSE)) == -ENOSPC) {
3584            /* Enqueue at the head of the queue */
3585            spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3586            list_add(&buffered_pkt->q, &interfacePriv->genericMgtFrames);
3587            spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3588            hipslotFree[3]=FALSE;
3589            break;
3590        }else {
3591            if(r){
3592                unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3593                /* the PDU failed where we can't do any thing so free the storage */
3594                unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3595            }
3596            kfree(buffered_pkt);
3597        }
3598   }
3599   for(i = 0; i < UNIFI_MAX_CONNECTIONS; i++) {
3600        CsrWifiRouterCtrlStaInfo_t *staInfo = interfacePriv->staInfo[i];
3601        if(!hipslotFree[0] && !hipslotFree[1] && !hipslotFree[2] && !hipslotFree[3]) {
3602            unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full \n");
3603            break;
3604        }
3605        if (staInfo && (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)) {
3606          while((( TRUE == hipslotFree[3] ) && (buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->mgtFrames)))) {
3607              buffered_pkt->transmissionControl &=
3608                           ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3609              if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
3610                  unifi_trace(priv, UDBG3, "(ENOSPC) in resume_unicast_buffered_frames:: hip slots are full for voice queue\n");
3611                  /* Enqueue at the head of the queue */
3612                  spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3613                  list_add(&buffered_pkt->q, &staInfo->mgtFrames);
3614                  spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3615                  priv->pausedStaHandle[3]=(u8)(staInfo->assignedHandle);
3616                  hipslotFree[3] = FALSE;
3617                  break;
3618              } else {
3619                  if(r){
3620                      unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3621                      /* the PDU failed where we can't do any thing so free the storage */
3622                      unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3623                  }
3624                  kfree(buffered_pkt);
3625              }
3626          }
3627
3628          for(j=3;j>=0;j--) {
3629              if(!hipslotFree[j])
3630                  continue;
3631
3632              while((buffered_pkt=dequeue_tx_data_pdu(priv, &staInfo->dataPdu[j]))) {
3633                 buffered_pkt->transmissionControl &=
3634                            ~(TRANSMISSION_CONTROL_TRIGGER_MASK|TRANSMISSION_CONTROL_EOSP_MASK);
3635                 if((r=frame_and_send_queued_pdu(priv,buffered_pkt,staInfo,0,FALSE)) == -ENOSPC) {
3636                     /* Enqueue at the head of the queue */
3637                     spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3638                     list_add(&buffered_pkt->q, &staInfo->dataPdu[j]);
3639                     spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3640                     priv->pausedStaHandle[j]=(u8)(staInfo->assignedHandle);
3641                     hipslotFree[j]=FALSE;
3642                     break;
3643                 } else {
3644                    if(r){
3645                        unifi_trace (priv, UDBG1, " HIP validation failure : PDU sending failed \n");
3646                        /* the PDU failed where we can't do any thing so free the storage */
3647                        unifi_net_data_free(priv, &buffered_pkt->bulkdata);
3648                     }
3649                    kfree(buffered_pkt);
3650                 }
3651              }
3652          }
3653       }
3654    }
3655}
3656void update_eosp_to_head_of_broadcast_list_head(unifi_priv_t *priv,u16 interfaceTag)
3657{
3658
3659    netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag];
3660    unsigned long lock_flags;
3661    struct list_head *listHead;
3662    struct list_head *placeHolder;
3663    tx_buffered_packets_t *tx_q_item;
3664
3665    if (interfacePriv->noOfbroadcastPktQueued) {
3666
3667        /* Update the EOSP to the HEAD of b/c list
3668         * because we have received any mgmt packet so it should not hold for long time
3669         * peer may time out.
3670         */
3671        spin_lock_irqsave(&priv->tx_q_lock,lock_flags);
3672        list_for_each_safe(listHead, placeHolder, &interfacePriv->genericMulticastOrBroadCastFrames) {
3673            tx_q_item = list_entry(listHead, tx_buffered_packets_t, q);
3674            tx_q_item->transmissionControl |= TRANSMISSION_CONTROL_EOSP_MASK;
3675            tx_q_item->transmissionControl = (tx_q_item->transmissionControl & ~(CSR_NO_CONFIRM_REQUIRED));
3676            unifi_trace(priv, UDBG1,"updating eosp for list Head hostTag:= 0x%x ",tx_q_item->hostTag);
3677            break;
3678        }
3679        spin_unlock_irqrestore(&priv->tx_q_lock,lock_flags);
3680    }
3681}
3682
3683/*
3684 * ---------------------------------------------------------------------------
3685 *  resume_suspended_uapsd
3686 *
3687 *      This function takes care processing packets of Unscheduled Service Period,
3688 *      which been suspended earlier due to DTIM/HIP ENOSPC scenarios
3689 *
3690 *  Arguments:
3691 *      priv            Pointer to device private context struct
3692 *      interfaceTag    For which resume should happen
3693 * ---------------------------------------------------------------------------
3694 */
3695void resume_suspended_uapsd(unifi_priv_t* priv,u16 interfaceTag)
3696{
3697
3698   u8 startIndex;
3699   CsrWifiRouterCtrlStaInfo_t * staInfo = NULL;
3700    unsigned long lock_flags;
3701
3702    unifi_trace(priv, UDBG2, "++resume_suspended_uapsd: \n");
3703    for(startIndex= 0; startIndex < UNIFI_MAX_CONNECTIONS;startIndex++) {
3704        staInfo =  CsrWifiRouterCtrlGetStationRecordFromHandle(priv,startIndex,interfaceTag);
3705
3706        if(!staInfo || !staInfo->wmmOrQosEnabled) {
3707            continue;
3708        } else if((staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_POWER_SAVE)
3709                   &&staInfo->uapsdActive && staInfo->uspSuspend) {
3710            /* U-APSD Still active & previously suspended either ENOSPC of FH queues OR
3711             * due to DTIM activity
3712             */
3713            uf_handle_uspframes_delivery(priv, staInfo, interfaceTag);
3714        } else {
3715            unifi_trace(priv, UDBG2, "resume_suspended_uapsd: PS state=%x, uapsdActive?=%x, suspend?=%x\n",
3716                        staInfo->currentPeerState, staInfo->uapsdActive, staInfo->uspSuspend);
3717            if (staInfo->currentPeerState == CSR_WIFI_ROUTER_CTRL_PEER_CONNECTED_ACTIVE)
3718            {
3719                spin_lock_irqsave(&priv->staRecord_lock,lock_flags);
3720                staInfo->uapsdActive = FALSE;
3721                staInfo->uspSuspend = FALSE;
3722                spin_unlock_irqrestore(&priv->staRecord_lock,lock_flags);
3723            }
3724        }
3725    }
3726    unifi_trace(priv, UDBG2, "--resume_suspended_uapsd:\n");
3727}
3728
3729#endif
3730