at v3.13 7.0 kB view raw
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 bool HighPriorityMessage = false; 18 struct sk_buff *newPacket = NULL; 19 CHAR cntrl_msg_mask_bit = 0; 20 bool 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