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
, struct sk_buff
*skb
)
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
);
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);
28 case CM_RESPONSES
: /* 0xA0 */
29 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, CP_CTRL_PKT
,
31 "MAC Version Seems to be Non Multi-Classifier, rejected by Driver");
32 HighPriorityMessage
= TRUE
;
34 case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP
:
35 HighPriorityMessage
= TRUE
;
36 if (Adapter
->LinkStatus
== LINKUP_DONE
)
37 CmControlResponseMessage(Adapter
,
38 (skb
->data
+ sizeof(USHORT
)));
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
)));
48 case STATS_POINTER_RESP
: /* 0xA6 */
49 HighPriorityMessage
= TRUE
;
50 StatisticsResponse(Adapter
, (skb
->data
+ sizeof(USHORT
)));
52 case IDLE_MODE_STATUS
: /* 0xA3 */
53 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, CP_CTRL_PKT
,
55 "IDLE_MODE_STATUS Type Message Got from F/W");
56 InterfaceIdleModeRespond(Adapter
, (PUINT
)(skb
->data
+
58 HighPriorityMessage
= TRUE
;
61 case AUTH_SS_HOST_MSG
:
62 HighPriorityMessage
= TRUE
;
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 */
72 /* Queue The Control Packet to The Application Queues */
73 down(&Adapter
->RxAppControlQueuelock
);
75 for (pTarang
= Adapter
->pTarangs
; pTarang
; pTarang
= pTarang
->next
) {
76 if (Adapter
->device_removed
)
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.
88 cntrl_msg_mask_bit
= (usStatus
& 0x1F);
90 * printk("\ninew msg mask bit which is disable in mask:%X",
91 * cntrl_msg_mask_bit);
93 if (pTarang
->RxCntrlMsgBitMask
& (1 << cntrl_msg_mask_bit
))
94 drop_pkt_flag
= false;
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))) {
103 * 1. every tarang manages it own dropped pkt
105 * 2. Total packet dropped per tarang will be equal to
106 * the sum of all types of dropped pkt by that
109 switch (*(PUSHORT
)skb
->data
) {
111 pTarang
->stDroppedAppCntrlMsgs
.cm_responses
++;
113 case CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP
:
114 pTarang
->stDroppedAppCntrlMsgs
.cm_control_newdsx_multiclassifier_resp
++;
116 case LINK_CONTROL_RESP
:
117 pTarang
->stDroppedAppCntrlMsgs
.link_control_resp
++;
120 pTarang
->stDroppedAppCntrlMsgs
.status_rsp
++;
122 case STATS_POINTER_RESP
:
123 pTarang
->stDroppedAppCntrlMsgs
.stats_pointer_resp
++;
125 case IDLE_MODE_STATUS
:
126 pTarang
->stDroppedAppCntrlMsgs
.idle_mode_status
++;
128 case AUTH_SS_HOST_MSG
:
129 pTarang
->stDroppedAppCntrlMsgs
.auth_ss_host_msg
++;
132 pTarang
->stDroppedAppCntrlMsgs
.low_priority_message
++;
139 newPacket
= skb_clone(skb
, GFP_KERNEL
);
142 ENQUEUEPACKET(pTarang
->RxAppControlHead
,
143 pTarang
->RxAppControlTail
, newPacket
);
144 pTarang
->AppCtrlQueueLen
++;
146 up(&Adapter
->RxAppControlQueuelock
);
147 wake_up(&Adapter
->process_read_wait_queue
);
149 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, CP_CTRL_PKT
, DBG_LVL_ALL
,
150 "After wake_up_interruptible");
154 * @ingroup ctrl_pkt_functions
155 * Thread to handle control pkt reception
157 int control_packet_handler(struct bcm_mini_adapter
*Adapter
/* pointer to adapter object*/)
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!");
166 wait_event_interruptible(Adapter
->process_rx_cntrlpkt
,
167 atomic_read(&Adapter
->cntrlpktCnt
) ||
168 Adapter
->bWakeUpDevice
||
169 kthread_should_stop());
172 if (kthread_should_stop()) {
173 BCM_DEBUG_PRINT(Adapter
, DBG_TYPE_OTHERS
, CP_CTRL_PKT
,
174 DBG_LVL_ALL
, "Exiting\n");
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");
186 * Adapter->bTriedToWakeUpFromlowPowerMode
189 InterfaceIdleModeWakeup(Adapter
);
194 while (atomic_read(&Adapter
->cntrlpktCnt
)) {
195 spin_lock_irqsave(&Adapter
->control_queue_lock
, flags
);
196 ctrl_packet
= Adapter
->RxControlHead
;
198 DEQUEUEPACKET(Adapter
->RxControlHead
,
199 Adapter
->RxControlTail
);
200 /* Adapter->RxControlHead=ctrl_packet->next; */
203 spin_unlock_irqrestore(&Adapter
->control_queue_lock
,
205 handle_rx_control_packet(Adapter
, ctrl_packet
);
206 atomic_dec(&Adapter
->cntrlpktCnt
);
209 SetUpTargetDsxBuffers(Adapter
);
211 return STATUS_SUCCESS
;
214 INT
flushAllAppQ(void)
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
);
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
));
232 return STATUS_SUCCESS
;