HandleControlPacket.c 6.7 KB

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