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