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