2 * @file HandleControlPacket.c
3 * This file contains the routines to deal with
4 * sending and receiving of control packets.
9 * When a control packet is received, analyze the
10 * "status" and call appropriate response function.
11 * Enqueue the control packet for Application.
14 static VOID handle_rx_control_packet(struct bcm_mini_adapter *Adapter,
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);
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);
29 case CM_RESPONSES: /* 0xA0 */
30 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
32 "MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
33 HighPriorityMessage = TRUE;
35 case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
36 HighPriorityMessage = TRUE;
37 if (Adapter->LinkStatus == LINKUP_DONE)
38 CmControlResponseMessage(Adapter,
39 (skb->data + sizeof(USHORT)));
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)));
49 case STATS_POINTER_RESP: /* 0xA6 */
50 HighPriorityMessage = TRUE;
51 StatisticsResponse(Adapter, (skb->data + sizeof(USHORT)));
53 case IDLE_MODE_STATUS: /* 0xA3 */
54 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
56 "IDLE_MODE_STATUS Type Message Got from F/W");
57 InterfaceIdleModeRespond(Adapter, (PUINT)(skb->data +
59 HighPriorityMessage = TRUE;
62 case AUTH_SS_HOST_MSG:
63 HighPriorityMessage = TRUE;
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 */
73 /* Queue The Control Packet to The Application Queues */
74 down(&Adapter->RxAppControlQueuelock);
76 for (pTarang = Adapter->pTarangs; pTarang; pTarang = pTarang->next) {
77 if (Adapter->device_removed)
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.
89 cntrl_msg_mask_bit = (usStatus & 0x1F);
91 * printk("\ninew msg mask bit which is disable in mask:%X",
92 * cntrl_msg_mask_bit);
94 if (pTarang->RxCntrlMsgBitMask & (1 << cntrl_msg_mask_bit))
95 drop_pkt_flag = false;
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))) {
104 * 1. every tarang manages it own dropped pkt
106 * 2. Total packet dropped per tarang will be equal to
107 * the sum of all types of dropped pkt by that
110 struct bcm_mibs_dropped_cntrl_msg *msg =
111 &pTarang->stDroppedAppCntrlMsgs;
112 switch (*(PUSHORT)skb->data) {
116 case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP:
117 msg->cm_control_newdsx_multiclassifier_resp++;
119 case LINK_CONTROL_RESP:
120 msg->link_control_resp++;
125 case STATS_POINTER_RESP:
126 msg->stats_pointer_resp++;
128 case IDLE_MODE_STATUS:
129 msg->idle_mode_status++;
131 case AUTH_SS_HOST_MSG:
132 msg->auth_ss_host_msg++;
135 msg->low_priority_message++;
142 newPacket = skb_clone(skb, GFP_KERNEL);
145 ENQUEUEPACKET(pTarang->RxAppControlHead,
146 pTarang->RxAppControlTail, newPacket);
147 pTarang->AppCtrlQueueLen++;
149 up(&Adapter->RxAppControlQueuelock);
150 wake_up(&Adapter->process_read_wait_queue);
152 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL,
153 "After wake_up_interruptible");
157 * @ingroup ctrl_pkt_functions
158 * Thread to handle control pkt reception
161 /* pointer to adapter object*/
162 int control_packet_handler(struct bcm_mini_adapter *Adapter)
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!");
171 wait_event_interruptible(Adapter->process_rx_cntrlpkt,
172 atomic_read(&Adapter->cntrlpktCnt) ||
173 Adapter->bWakeUpDevice ||
174 kthread_should_stop());
177 if (kthread_should_stop()) {
178 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, CP_CTRL_PKT,
179 DBG_LVL_ALL, "Exiting\n");
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");
191 * Adapter->bTriedToWakeUpFromlowPowerMode
194 InterfaceIdleModeWakeup(Adapter);
199 while (atomic_read(&Adapter->cntrlpktCnt)) {
200 spin_lock_irqsave(&Adapter->control_queue_lock, flags);
201 ctrl_packet = Adapter->RxControlHead;
203 DEQUEUEPACKET(Adapter->RxControlHead,
204 Adapter->RxControlTail);
205 /* Adapter->RxControlHead=ctrl_packet->next; */
208 spin_unlock_irqrestore(&Adapter->control_queue_lock,
210 handle_rx_control_packet(Adapter, ctrl_packet);
211 atomic_dec(&Adapter->cntrlpktCnt);
214 SetUpTargetDsxBuffers(Adapter);
216 return STATUS_SUCCESS;
219 INT flushAllAppQ(void)
221 struct bcm_mini_adapter *Adapter = GET_BCM_ADAPTER(gblpnetdev);
222 struct bcm_tarang_data *pTarang = NULL;
223 struct sk_buff *PacketToDrop = NULL;
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);
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));
238 return STATUS_SUCCESS;