linux/drivers/staging/bcm/HandleControlPacket.c
<<
>>
Prefs
   1/**
   2 * @file HandleControlPacket.c
   3 * This file contains the routines to deal with
   4 * sending and receiving of control packets.
   5 */
   6#include "headers.h"
   7
   8/**
   9 * When a control packet is received, analyze the
  10 * "status" and call appropriate response function.
  11 * Enqueue the control packet for Application.
  12 * @return None
  13 */
  14static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter, struct sk_buff *skb)
  15{
  16        struct bcm_tarang_data *pTarang = NULL;
  17        BOOLEAN HighPriorityMessage = FALSE;
  18        struct sk_buff *newPacket = NULL;
  19        CHAR cntrl_msg_mask_bit = 0;
  20        BOOLEAN drop_pkt_flag = TRUE;
  21        USHORT usStatus = *(PUSHORT)(skb->data);
  22
  23        if (netif_msg_pktdata(Adapter))
  24                print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE,
  25                                16, 1, skb->data, skb->len, 0);
  26
  27        switch (usStatus) {
  28        case CM_RESPONSES:               /* 0xA0 */
  29                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
  30                        DBG_LVL_ALL,
  31                        "MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
  32                HighPriorityMessage = TRUE;
  33                break;
  34        case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
  35                HighPriorityMessage = TRUE;
  36                if (Adapter->LinkStatus == LINKUP_DONE)
  37                        CmControlResponseMessage(Adapter,
  38                                (skb->data + sizeof(USHORT)));
  39                break;
  40        case LINK_CONTROL_RESP:          /* 0xA2 */
  41        case STATUS_RSP:                 /* 0xA1 */
  42                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
  43                        DBG_LVL_ALL, "LINK_CONTROL_RESP");
  44                HighPriorityMessage = TRUE;
  45                LinkControlResponseMessage(Adapter,
  46                        (skb->data + sizeof(USHORT)));
  47                break;
  48        case STATS_POINTER_RESP:         /* 0xA6 */
  49                HighPriorityMessage = TRUE;
  50                StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
  51                break;
  52        case IDLE_MODE_STATUS:           /* 0xA3 */
  53                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
  54                        DBG_LVL_ALL,
  55                        "IDLE_MODE_STATUS Type Message Got from F/W");
  56                InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
  57                                        sizeof(USHORT)));
  58                HighPriorityMessage = TRUE;
  59                break;
  60
  61        case AUTH_SS_HOST_MSG:
  62                HighPriorityMessage = TRUE;
  63                break;
  64
  65        default:
  66                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
  67                        DBG_LVL_ALL, "Got Default Response");
  68                /* Let the Application Deal with This Packet */
  69                break;
  70        }
  71
  72        /* Queue The Control Packet to The Application Queues */
  73        down(&Adapter->RxAppControlQueuelock);
  74
  75        for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
  76                if (Adapter->device_removed)
  77                        break;
  78
  79                drop_pkt_flag = TRUE;
  80                /*
  81                 * There are cntrl msg from A0 to AC. It has been mapped to 0 to
  82                 * C bit in the cntrl mask.
  83                 * Also, by default AD to BF has been masked to the rest of the
  84                 * bits... which wil be ON by default.
  85                 * if mask bit is enable to particular pkt status, send it out
  86                 * to app else stop it.
  87                 */
  88                cntrl_msg_mask_bit = (usStatus & 0x1F);
  89                /*
  90                 * printk("\ninew  msg  mask bit which is disable in mask:%X",
  91                 *      cntrl_msg_mask_bit);
  92                 */
  93                if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
  94                        drop_pkt_flag = FALSE;
  95
  96                if ((drop_pkt_flag == TRUE) ||
  97                                (pTarang->AppCtrlQueueLen > MAX_APP_QUEUE_LEN)
  98                                || ((pTarang->AppCtrlQueueLen >
  99                                        MAX_APP_QUEUE_LEN / 2) &&
 100                                    (HighPriorityMessage == FALSE))) {
 101                        /*
 102                         * Assumption:-
 103                         * 1. every tarang manages it own dropped pkt
 104                         *    statitistics
 105                         * 2. Total packet dropped per tarang will be equal to
 106                         *    the sum of all types of dropped pkt by that
 107                         *    tarang only.
 108                         */
 109                        switch (*(PUSHORT)skb->data) {
 110                        case CM_RESPONSES:
 111                                pTarang->stDroppedAppCntrlMsgs.cm_responses++;
 112                                break;
 113                        case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
 114                                pTarang->stDroppedAppCntrlMsgs.cm_control_newdsx_multiclassifier_resp++;
 115                                break;
 116                        case LINK_CONTROL_RESP:
 117                                pTarang->stDroppedAppCntrlMsgs.link_control_resp++;
 118                                break;
 119                        case STATUS_RSP:
 120                                pTarang->stDroppedAppCntrlMsgs.status_rsp++;
 121                                break;
 122                        case STATS_POINTER_RESP:
 123                                pTarang->stDroppedAppCntrlMsgs.stats_pointer_resp++;
 124                                break;
 125                        case IDLE_MODE_STATUS:
 126                                pTarang->stDroppedAppCntrlMsgs.idle_mode_status++;
 127                                break;
 128                        case AUTH_SS_HOST_MSG:
 129                                pTarang->stDroppedAppCntrlMsgs.auth_ss_host_msg++;
 130                                break;
 131                        default:
 132                                pTarang->stDroppedAppCntrlMsgs.low_priority_message++;
 133                                break;
 134                        }
 135
 136                        continue;
 137                }
 138
 139                newPacket = skb_clone(skb, GFP_KERNEL);
 140                if (!newPacket)
 141                        break;
 142                ENQUEUEPACKET(pTarang->RxAppControlHead,
 143                                pTarang->RxAppControlTail, newPacket);
 144                pTarang->AppCtrlQueueLen++;
 145        }
 146        up(&Adapter->RxAppControlQueuelock);
 147        wake_up(&Adapter->process_read_wait_queue);
 148        dev_kfree_skb(skb);
 149        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
 150                        "After wake_up_interruptible");
 151}
 152
 153/**
 154 * @ingroup ctrl_pkt_functions
 155 * Thread to handle control pkt reception
 156 */
 157int control_packet_handler(struct bcm_mini_adapter *Adapter /* pointer to adapter object*/)
 158{
 159        struct sk_buff *ctrl_packet = NULL;
 160        unsigned long flags = 0;
 161        /* struct timeval tv; */
 162        /* int *puiBuffer = NULL; */
 163        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
 164                "Entering to make thread wait on control packet event!");
 165        while (1) {
 166                wait_event_interruptible(Adapter->process_rx_cntrlpkt,
 167                        atomic_read(&Adapter->cntrlpktCnt) ||
 168                        Adapter->bWakeUpDevice ||
 169                        kthread_should_stop());
 170
 171
 172                if (kthread_should_stop()) {
 173                        BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
 174                                DBG_LVL_ALL, "Exiting\n");
 175                        return 0;
 176                }
 177                if (TRUE == Adapter->bWakeUpDevice) {
 178                        Adapter->bWakeUpDevice = FALSE;
 179                        if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode)
 180                                        && ((TRUE == Adapter->IdleMode) ||
 181                                            (TRUE == Adapter->bShutStatus))) {
 182                                BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 183                                        CP_CTRL_PKT, DBG_LVL_ALL,
 184                                        "Calling InterfaceAbortIdlemode\n");
 185                                /*
 186                                 * Adapter->bTriedToWakeUpFromlowPowerMode
 187                                 *                                      = TRUE;
 188                                 */
 189                                InterfaceIdleModeWakeup(Adapter);
 190                        }
 191                        continue;
 192                }
 193
 194                while (atomic_read(&Adapter->cntrlpktCnt)) {
 195                        spin_lock_irqsave(&Adapter->control_queue_lock, flags);
 196                        ctrl_packet = Adapter->RxControlHead;
 197                        if (ctrl_packet) {
 198                                DEQUEUEPACKET(Adapter->RxControlHead,
 199                                        Adapter->RxControlTail);
 200                                /* Adapter->RxControlHead=ctrl_packet->next; */
 201                        }
 202
 203                        spin_unlock_irqrestore(&Adapter->control_queue_lock,
 204                                                flags);
 205                        handle_rx_control_packet(Adapter, ctrl_packet);
 206                        atomic_dec(&Adapter->cntrlpktCnt);
 207                }
 208
 209                SetUpTargetDsxBuffers(Adapter);
 210        }
 211        return STATUS_SUCCESS;
 212}
 213
 214INT flushAllAppQ(void)
 215{
 216        struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
 217        struct bcm_tarang_data *pTarang = NULL;
 218        struct sk_buff *PacketToDrop = NULL;
 219        for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
 220                while (pTarang->RxAppControlHead != NULL) {
 221                        PacketToDrop = pTarang->RxAppControlHead;
 222                        DEQUEUEPACKET(pTarang->RxAppControlHead,
 223                                        pTarang->RxAppControlTail);
 224                        dev_kfree_skb(PacketToDrop);
 225                }
 226                pTarang->AppCtrlQueueLen = 0;
 227                /* dropped contrl packet statistics also should be reset. */
 228                memset((PVOID)&pTarang->stDroppedAppCntrlMsgs, 0,
 229                        sizeof(struct bcm_mibs_dropped_cntrl_msg));
 230
 231        }
 232        return STATUS_SUCCESS;
 233}
 234
 235
 236