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