Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *************************************************************************
  3  * Ralink Tech Inc.
  4  * 5F., No.36, Taiyuan St., Jhubei City,
  5  * Hsinchu County 302,
  6  * Taiwan, R.O.C.
  7  *
  8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
  9  *
 10  * This program is free software; you can redistribute it and/or modify  *
 11  * it under the terms of the GNU General Public License as published by  *
 12  * the Free Software Foundation; either version 2 of the License, or     *
 13  * (at your option) any later version.                                   *
 14  *                                                                       *
 15  * This program is distributed in the hope that it will be useful,       *
 16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 18  * GNU General Public License for more details.                          *
 19  *                                                                       *
 20  * You should have received a copy of the GNU General Public License     *
 21  * along with this program; if not, write to the                         *
 22  * Free Software Foundation, Inc.,                                       *
 23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 24  *                                                                       *
 25  *************************************************************************
 26  */
 27 
 28 #include "rt_config.h"
 29 
 30 ULONG   RTDebugLevel = RT_DEBUG_ERROR;
 31 
 32 BUILD_TIMER_FUNCTION(MlmePeriodicExec);
 33 BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
 34 BUILD_TIMER_FUNCTION(APSDPeriodicExec);
 35 BUILD_TIMER_FUNCTION(AsicRfTuningExec);
 36 #ifdef RT2870
 37 BUILD_TIMER_FUNCTION(BeaconUpdateExec);
 38 #endif // RT2870 //
 39 
 40 BUILD_TIMER_FUNCTION(BeaconTimeout);
 41 BUILD_TIMER_FUNCTION(ScanTimeout);
 42 BUILD_TIMER_FUNCTION(AuthTimeout);
 43 BUILD_TIMER_FUNCTION(AssocTimeout);
 44 BUILD_TIMER_FUNCTION(ReassocTimeout);
 45 BUILD_TIMER_FUNCTION(DisassocTimeout);
 46 BUILD_TIMER_FUNCTION(LinkDownExec);
 47 BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
 48 BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
 49 #ifdef RT2860
 50 BUILD_TIMER_FUNCTION(PsPollWakeExec);
 51 BUILD_TIMER_FUNCTION(RadioOnExec);
 52 #endif
 53 
 54 // for wireless system event message
 55 char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
 56         // system status event
 57     "had associated successfully",                                                      /* IW_ASSOC_EVENT_FLAG */
 58     "had disassociated",                                                                        /* IW_DISASSOC_EVENT_FLAG */
 59     "had deauthenticated",                                                                      /* IW_DEAUTH_EVENT_FLAG */
 60     "had been aged-out and disassociated",                                      /* IW_AGEOUT_EVENT_FLAG */
 61     "occurred CounterMeasures attack",                                          /* IW_COUNTER_MEASURES_EVENT_FLAG */
 62     "occurred replay counter different in Key Handshaking",     /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
 63     "occurred RSNIE different in Key Handshaking",                      /* IW_RSNIE_DIFF_EVENT_FLAG */
 64     "occurred MIC different in Key Handshaking",                        /* IW_MIC_DIFF_EVENT_FLAG */
 65     "occurred ICV error in RX",                                                         /* IW_ICV_ERROR_EVENT_FLAG */
 66     "occurred MIC error in RX",                                                         /* IW_MIC_ERROR_EVENT_FLAG */
 67         "Group Key Handshaking timeout",                                                /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
 68         "Pairwise Key Handshaking timeout",                                             /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
 69         "RSN IE sanity check failure",                                                  /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
 70         "set key done in WPA/WPAPSK",                                                   /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
 71         "set key done in WPA2/WPA2PSK",                         /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
 72         "connects with our wireless client",                    /* IW_STA_LINKUP_EVENT_FLAG */
 73         "disconnects with our wireless client",                 /* IW_STA_LINKDOWN_EVENT_FLAG */
 74         "scan completed"                                                                                /* IW_SCAN_COMPLETED_EVENT_FLAG */
 75         "scan terminate!! Busy!! Enqueue fail!!"                                /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
 76         };
 77 
 78 // for wireless IDS_spoof_attack event message
 79 char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
 80     "detected conflict SSID",                                                           /* IW_CONFLICT_SSID_EVENT_FLAG */
 81     "detected spoofed association response",                            /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
 82     "detected spoofed reassociation responses",                         /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
 83     "detected spoofed probe response",                                          /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
 84     "detected spoofed beacon",                                                          /* IW_SPOOF_BEACON_EVENT_FLAG */
 85     "detected spoofed disassociation",                                          /* IW_SPOOF_DISASSOC_EVENT_FLAG */
 86     "detected spoofed authentication",                                          /* IW_SPOOF_AUTH_EVENT_FLAG */
 87     "detected spoofed deauthentication",                                        /* IW_SPOOF_DEAUTH_EVENT_FLAG */
 88     "detected spoofed unknown management frame",                        /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
 89         "detected replay attack"                                                                /* IW_REPLAY_ATTACK_EVENT_FLAG */
 90         };
 91 
 92 // for wireless IDS_flooding_attack event message
 93 char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
 94         "detected authentication flooding",                                             /* IW_FLOOD_AUTH_EVENT_FLAG */
 95     "detected association request flooding",                            /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
 96     "detected reassociation request flooding",                          /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
 97     "detected probe request flooding",                                          /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
 98     "detected disassociation flooding",                                         /* IW_FLOOD_DISASSOC_EVENT_FLAG */
 99     "detected deauthentication flooding",                                       /* IW_FLOOD_DEAUTH_EVENT_FLAG */
100     "detected 802.1x eap-request flooding"                                      /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
101         };
102 
103 /* timeout -- ms */
104 VOID RTMP_SetPeriodicTimer(
105         IN      NDIS_MINIPORT_TIMER *pTimer,
106         IN      unsigned long timeout)
107 {
108         timeout = ((timeout*HZ) / 1000);
109         pTimer->expires = jiffies + timeout;
110         add_timer(pTimer);
111 }
112 
113 /* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
114 VOID RTMP_OS_Init_Timer(
115         IN      PRTMP_ADAPTER pAd,
116         IN      NDIS_MINIPORT_TIMER *pTimer,
117         IN      TIMER_FUNCTION function,
118         IN      PVOID data)
119 {
120         init_timer(pTimer);
121     pTimer->data = (unsigned long)data;
122     pTimer->function = function;
123 }
124 
125 
126 VOID RTMP_OS_Add_Timer(
127         IN      NDIS_MINIPORT_TIMER             *pTimer,
128         IN      unsigned long timeout)
129 {
130         if (timer_pending(pTimer))
131                 return;
132 
133         timeout = ((timeout*HZ) / 1000);
134         pTimer->expires = jiffies + timeout;
135         add_timer(pTimer);
136 }
137 
138 VOID RTMP_OS_Mod_Timer(
139         IN      NDIS_MINIPORT_TIMER             *pTimer,
140         IN      unsigned long timeout)
141 {
142         timeout = ((timeout*HZ) / 1000);
143         mod_timer(pTimer, jiffies + timeout);
144 }
145 
146 VOID RTMP_OS_Del_Timer(
147         IN      NDIS_MINIPORT_TIMER             *pTimer,
148         OUT     BOOLEAN                                 *pCancelled)
149 {
150         if (timer_pending(pTimer))
151         {
152                 *pCancelled = del_timer_sync(pTimer);
153         }
154         else
155         {
156                 *pCancelled = TRUE;
157         }
158 
159 }
160 
161 VOID RTMP_OS_Release_Packet(
162         IN      PRTMP_ADAPTER pAd,
163         IN      PQUEUE_ENTRY  pEntry)
164 {
165         //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
166 }
167 
168 // Unify all delay routine by using udelay
169 VOID RTMPusecDelay(
170         IN      ULONG   usec)
171 {
172         ULONG   i;
173 
174         for (i = 0; i < (usec / 50); i++)
175                 udelay(50);
176 
177         if (usec % 50)
178                 udelay(usec % 50);
179 }
180 
181 void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
182 {
183         time->u.LowPart = jiffies;
184 }
185 
186 // pAd MUST allow to be NULL
187 NDIS_STATUS os_alloc_mem(
188         IN      PRTMP_ADAPTER pAd,
189         OUT     PUCHAR *mem,
190         IN      ULONG  size)
191 {
192         *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
193         if (*mem)
194                 return (NDIS_STATUS_SUCCESS);
195         else
196                 return (NDIS_STATUS_FAILURE);
197 }
198 
199 // pAd MUST allow to be NULL
200 NDIS_STATUS os_free_mem(
201         IN      PRTMP_ADAPTER pAd,
202         IN      PUCHAR mem)
203 {
204 
205         ASSERT(mem);
206         kfree(mem);
207         return (NDIS_STATUS_SUCCESS);
208 }
209 
210 
211 PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
212         IN      PRTMP_ADAPTER pAd,
213         IN      ULONG   Length)
214 {
215         struct sk_buff *pkt;
216 
217         pkt = dev_alloc_skb(Length);
218 
219         if (pkt == NULL)
220         {
221                 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
222         }
223 
224         if (pkt)
225         {
226                 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
227         }
228 
229         return (PNDIS_PACKET) pkt;
230 }
231 
232 
233 PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
234         IN      PRTMP_ADAPTER pAd,
235         IN      ULONG   Length,
236         IN      BOOLEAN Cached,
237         OUT     PVOID   *VirtualAddress)
238 {
239         struct sk_buff *pkt;
240 
241         pkt = dev_alloc_skb(Length);
242 
243         if (pkt == NULL)
244         {
245                 DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
246         }
247 
248         if (pkt)
249         {
250                 RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
251                 *VirtualAddress = (PVOID) pkt->data;
252         }
253         else
254         {
255                 *VirtualAddress = (PVOID) NULL;
256         }
257 
258         return (PNDIS_PACKET) pkt;
259 }
260 
261 
262 VOID build_tx_packet(
263         IN      PRTMP_ADAPTER   pAd,
264         IN      PNDIS_PACKET    pPacket,
265         IN      PUCHAR  pFrame,
266         IN      ULONG   FrameLen)
267 {
268 
269         struct sk_buff  *pTxPkt;
270 
271         ASSERT(pPacket);
272         pTxPkt = RTPKT_TO_OSPKT(pPacket);
273 
274         NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
275 }
276 
277 VOID    RTMPFreeAdapter(
278         IN      PRTMP_ADAPTER   pAd)
279 {
280     POS_COOKIE os_cookie;
281         int index;
282 
283         os_cookie=(POS_COOKIE)pAd->OS_Cookie;
284 
285         kfree(pAd->BeaconBuf);
286 
287 
288         NdisFreeSpinLock(&pAd->MgmtRingLock);
289 #ifdef RT2860
290         NdisFreeSpinLock(&pAd->RxRingLock);
291 #endif
292         for (index =0 ; index < NUM_OF_TX_RING; index++)
293         {
294         NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
295                 NdisFreeSpinLock(&pAd->DeQueueLock[index]);
296                 pAd->DeQueueRunning[index] = FALSE;
297         }
298 
299         NdisFreeSpinLock(&pAd->irq_lock);
300 
301         vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
302         kfree(os_cookie);
303 }
304 
305 BOOLEAN OS_Need_Clone_Packet(void)
306 {
307         return (FALSE);
308 }
309 
310 
311 
312 /*
313         ========================================================================
314 
315         Routine Description:
316                 clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
317                 must have only one NDIS BUFFER
318                 return - byte copied. 0 means can't create NDIS PACKET
319                 NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
320 
321         Arguments:
322                 pAd     Pointer to our adapter
323                 pInsAMSDUHdr    EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
324                 *pSrcTotalLen                   return total packet length. This lenght is calculated with 802.3 format packet.
325 
326         Return Value:
327                 NDIS_STATUS_SUCCESS
328                 NDIS_STATUS_FAILURE
329 
330         Note:
331 
332         ========================================================================
333 */
334 NDIS_STATUS RTMPCloneNdisPacket(
335         IN      PRTMP_ADAPTER   pAd,
336         IN      BOOLEAN                 pInsAMSDUHdr,
337         IN      PNDIS_PACKET    pInPacket,
338         OUT PNDIS_PACKET   *ppOutPacket)
339 {
340 
341         struct sk_buff *pkt;
342 
343         ASSERT(pInPacket);
344         ASSERT(ppOutPacket);
345 
346         // 1. Allocate a packet
347         pkt = dev_alloc_skb(2048);
348 
349         if (pkt == NULL)
350         {
351                 return NDIS_STATUS_FAILURE;
352         }
353 
354         skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
355         NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
356         *ppOutPacket = OSPKT_TO_RTPKT(pkt);
357 
358 
359         RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
360 
361         printk("###Clone###\n");
362 
363         return NDIS_STATUS_SUCCESS;
364 }
365 
366 
367 // the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
368 NDIS_STATUS RTMPAllocateNdisPacket(
369         IN      PRTMP_ADAPTER   pAd,
370         OUT PNDIS_PACKET   *ppPacket,
371         IN      PUCHAR                  pHeader,
372         IN      UINT                    HeaderLen,
373         IN      PUCHAR                  pData,
374         IN      UINT                    DataLen)
375 {
376         PNDIS_PACKET    pPacket;
377         ASSERT(pData);
378         ASSERT(DataLen);
379 
380         // 1. Allocate a packet
381         pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
382         if (pPacket == NULL)
383         {
384                 *ppPacket = NULL;
385 #ifdef DEBUG
386                 printk("RTMPAllocateNdisPacket Fail\n\n");
387 #endif
388                 return NDIS_STATUS_FAILURE;
389         }
390 
391         // 2. clone the frame content
392         if (HeaderLen > 0)
393                 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
394         if (DataLen > 0)
395                 NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
396 
397         // 3. update length of packet
398         skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
399 
400         RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
401 //      printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket));
402         *ppPacket = pPacket;
403         return NDIS_STATUS_SUCCESS;
404 }
405 
406 /*
407   ========================================================================
408   Description:
409         This routine frees a miniport internally allocated NDIS_PACKET and its
410         corresponding NDIS_BUFFER and allocated memory.
411   ========================================================================
412 */
413 VOID RTMPFreeNdisPacket(
414         IN PRTMP_ADAPTER pAd,
415         IN PNDIS_PACKET  pPacket)
416 {
417         dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
418 }
419 
420 
421 // IRQL = DISPATCH_LEVEL
422 // NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
423 //                       scatter gather buffer
424 NDIS_STATUS Sniff2BytesFromNdisBuffer(
425         IN      PNDIS_BUFFER    pFirstBuffer,
426         IN      UCHAR                   DesiredOffset,
427         OUT PUCHAR                      pByte0,
428         OUT PUCHAR                      pByte1)
429 {
430     *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
431     *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
432 
433         return NDIS_STATUS_SUCCESS;
434 }
435 
436 
437 void RTMP_QueryPacketInfo(
438         IN  PNDIS_PACKET pPacket,
439         OUT PACKET_INFO  *pPacketInfo,
440         OUT PUCHAR               *pSrcBufVA,
441         OUT     UINT             *pSrcBufLen)
442 {
443         pPacketInfo->BufferCount = 1;
444         pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
445         pPacketInfo->PhysicalBufferCount = 1;
446         pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
447 
448         *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
449         *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
450 }
451 
452 void RTMP_QueryNextPacketInfo(
453         IN  PNDIS_PACKET *ppPacket,
454         OUT PACKET_INFO  *pPacketInfo,
455         OUT PUCHAR               *pSrcBufVA,
456         OUT     UINT             *pSrcBufLen)
457 {
458         PNDIS_PACKET pPacket = NULL;
459 
460         if (*ppPacket)
461                 pPacket = GET_OS_PKT_NEXT(*ppPacket);
462 
463         if (pPacket)
464         {
465                 pPacketInfo->BufferCount = 1;
466                 pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
467                 pPacketInfo->PhysicalBufferCount = 1;
468                 pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
469 
470                 *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
471                 *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
472                 *ppPacket = GET_OS_PKT_NEXT(pPacket);
473         }
474         else
475         {
476                 pPacketInfo->BufferCount = 0;
477                 pPacketInfo->pFirstBuffer = NULL;
478                 pPacketInfo->PhysicalBufferCount = 0;
479                 pPacketInfo->TotalPacketLength = 0;
480 
481                 *pSrcBufVA = NULL;
482                 *pSrcBufLen = 0;
483                 *ppPacket = NULL;
484         }
485 }
486 
487 // not yet support MBSS
488 PNET_DEV get_netdev_from_bssid(
489         IN      PRTMP_ADAPTER   pAd,
490         IN      UCHAR                   FromWhichBSSID)
491 {
492     PNET_DEV dev_p = NULL;
493 
494         dev_p = pAd->net_dev;
495 
496         ASSERT(dev_p);
497         return dev_p; /* return one of MBSS */
498 }
499 
500 PNDIS_PACKET DuplicatePacket(
501         IN      PRTMP_ADAPTER   pAd,
502         IN      PNDIS_PACKET    pPacket,
503         IN      UCHAR                   FromWhichBSSID)
504 {
505         struct sk_buff  *skb;
506         PNDIS_PACKET    pRetPacket = NULL;
507         USHORT                  DataSize;
508         UCHAR                   *pData;
509 
510         DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
511         pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
512 
513 
514         skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
515         if (skb)
516         {
517                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
518                 pRetPacket = OSPKT_TO_RTPKT(skb);
519         }
520 
521         return pRetPacket;
522 
523 }
524 
525 PNDIS_PACKET duplicate_pkt(
526         IN      PRTMP_ADAPTER   pAd,
527         IN      PUCHAR                  pHeader802_3,
528     IN  UINT            HdrLen,
529         IN      PUCHAR                  pData,
530         IN      ULONG                   DataSize,
531         IN      UCHAR                   FromWhichBSSID)
532 {
533         struct sk_buff  *skb;
534         PNDIS_PACKET    pPacket = NULL;
535 
536 
537         if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
538         {
539                 skb_reserve(skb, 2);
540                 NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
541                 skb_put(skb, HdrLen);
542                 NdisMoveMemory(skb->tail, pData, DataSize);
543                 skb_put(skb, DataSize);
544                 skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
545                 pPacket = OSPKT_TO_RTPKT(skb);
546         }
547 
548         return pPacket;
549 }
550 
551 
552 #define TKIP_TX_MIC_SIZE                8
553 PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
554         IN      PRTMP_ADAPTER   pAd,
555         IN      PNDIS_PACKET    pPacket)
556 {
557         struct sk_buff  *skb, *newskb;
558 
559 
560         skb = RTPKT_TO_OSPKT(pPacket);
561         if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
562         {
563                 // alloc a new skb and copy the packet
564                 newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
565                 dev_kfree_skb_any(skb);
566                 if (newskb == NULL)
567                 {
568                         DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
569                         return NULL;
570                 }
571                 skb = newskb;
572         }
573 
574         return OSPKT_TO_RTPKT(skb);
575 }
576 
577 
578 
579 
580 PNDIS_PACKET ClonePacket(
581         IN      PRTMP_ADAPTER   pAd,
582         IN      PNDIS_PACKET    pPacket,
583         IN      PUCHAR                  pData,
584         IN      ULONG                   DataSize)
585 {
586         struct sk_buff  *pRxPkt;
587         struct sk_buff  *pClonedPkt;
588 
589         ASSERT(pPacket);
590         pRxPkt = RTPKT_TO_OSPKT(pPacket);
591 
592         // clone the packet
593         pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
594 
595         if (pClonedPkt)
596         {
597         // set the correct dataptr and data len
598         pClonedPkt->dev = pRxPkt->dev;
599         pClonedPkt->data = pData;
600         pClonedPkt->len = DataSize;
601         pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
602                 ASSERT(DataSize < 1530);
603         }
604         return pClonedPkt;
605 }
606 
607 //
608 // change OS packet DataPtr and DataLen
609 //
610 void  update_os_packet_info(
611         IN      PRTMP_ADAPTER   pAd,
612         IN      RX_BLK                  *pRxBlk,
613         IN  UCHAR                       FromWhichBSSID)
614 {
615         struct sk_buff  *pOSPkt;
616 
617         ASSERT(pRxBlk->pRxPacket);
618         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
619 
620         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
621         pOSPkt->data = pRxBlk->pData;
622         pOSPkt->len = pRxBlk->DataSize;
623         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
624 }
625 
626 
627 void wlan_802_11_to_802_3_packet(
628         IN      PRTMP_ADAPTER   pAd,
629         IN      RX_BLK                  *pRxBlk,
630         IN      PUCHAR                  pHeader802_3,
631         IN  UCHAR                       FromWhichBSSID)
632 {
633         struct sk_buff  *pOSPkt;
634 
635         ASSERT(pRxBlk->pRxPacket);
636         ASSERT(pHeader802_3);
637 
638         pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
639 
640         pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
641         pOSPkt->data = pRxBlk->pData;
642         pOSPkt->len = pRxBlk->DataSize;
643         pOSPkt->tail = pOSPkt->data + pOSPkt->len;
644 
645         //
646         // copy 802.3 header
647         //
648         //
649 
650         NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
651 }
652 
653 void announce_802_3_packet(
654         IN      PRTMP_ADAPTER   pAd,
655         IN      PNDIS_PACKET    pPacket)
656 {
657 
658         struct sk_buff  *pRxPkt;
659 
660         ASSERT(pPacket);
661 
662         pRxPkt = RTPKT_TO_OSPKT(pPacket);
663 
664     /* Push up the protocol stack */
665 #ifdef IKANOS_VX_1X0
666         IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
667 #else
668         pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
669 
670         netif_rx(pRxPkt);
671 #endif // IKANOS_VX_1X0 //
672 }
673 
674 
675 PRTMP_SCATTER_GATHER_LIST
676 rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
677 {
678         sg->NumberOfElements = 1;
679         sg->Elements[0].Address =  GET_OS_PKT_DATAPTR(pPacket);
680         sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
681         return (sg);
682 }
683 
684 void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
685 {
686         unsigned char *pt;
687         int x;
688 
689         if (RTDebugLevel < RT_DEBUG_TRACE)
690                 return;
691 
692         pt = pSrcBufVA;
693         printk("%s: %p, len = %d\n",str,  pSrcBufVA, SrcBufLen);
694         for (x=0; x<SrcBufLen; x++)
695         {
696                 if (x % 16 == 0)
697                         printk("0x%04x : ", x);
698                 printk("%02x ", ((unsigned char)pt[x]));
699                 if (x%16 == 15) printk("\n");
700         }
701         printk("\n");
702 }
703 
704 /*
705         ========================================================================
706 
707         Routine Description:
708                 Send log message through wireless event
709 
710                 Support standard iw_event with IWEVCUSTOM. It is used below.
711 
712                 iwreq_data.data.flags is used to store event_flag that is defined by user.
713                 iwreq_data.data.length is the length of the event log.
714 
715                 The format of the event log is composed of the entry's MAC address and
716                 the desired log message (refer to pWirelessEventText).
717 
718                         ex: 11:22:33:44:55:66 has associated successfully
719 
720                 p.s. The requirement of Wireless Extension is v15 or newer.
721 
722         ========================================================================
723 */
724 VOID RTMPSendWirelessEvent(
725         IN      PRTMP_ADAPTER   pAd,
726         IN      USHORT                  Event_flag,
727         IN      PUCHAR                  pAddr,
728         IN      UCHAR                   BssIdx,
729         IN      CHAR                    Rssi)
730 {
731 #if WIRELESS_EXT >= 15
732 
733         union   iwreq_data      wrqu;
734         PUCHAR  pBuf = NULL, pBufPtr = NULL;
735         USHORT  event, type, BufLen;
736         UCHAR   event_table_len = 0;
737 
738         type = Event_flag & 0xFF00;
739         event = Event_flag & 0x00FF;
740 
741         switch (type)
742         {
743                 case IW_SYS_EVENT_FLAG_START:
744                         event_table_len = IW_SYS_EVENT_TYPE_NUM;
745                         break;
746 
747                 case IW_SPOOF_EVENT_FLAG_START:
748                         event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
749                         break;
750 
751                 case IW_FLOOD_EVENT_FLAG_START:
752                         event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
753                         break;
754         }
755 
756         if (event_table_len == 0)
757         {
758                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __func__, type));
759                 return;
760         }
761 
762         if (event >= event_table_len)
763         {
764                 DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __func__, event));
765                 return;
766         }
767 
768         //Allocate memory and copy the msg.
769         if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
770         {
771                 //Prepare the payload
772                 memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
773 
774                 pBufPtr = pBuf;
775 
776                 if (pAddr)
777                         pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
778                 else if (BssIdx < MAX_MBSSID_NUM)
779                         pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
780                 else
781                         pBufPtr += sprintf(pBufPtr, "(RT2860) ");
782 
783                 if (type == IW_SYS_EVENT_FLAG_START)
784                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
785                 else if (type == IW_SPOOF_EVENT_FLAG_START)
786                         pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
787                 else if (type == IW_FLOOD_EVENT_FLAG_START)
788                         pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
789                 else
790                         pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
791 
792                 pBufPtr[pBufPtr - pBuf] = '\0';
793                 BufLen = pBufPtr - pBuf;
794 
795                 memset(&wrqu, 0, sizeof(wrqu));
796             wrqu.data.flags = Event_flag;
797                 wrqu.data.length = BufLen;
798 
799                 //send wireless event
800             wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
801 
802                 //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf));
803 
804                 kfree(pBuf);
805         }
806         else
807                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __func__));
808 #else
809         DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __func__));
810 #endif  /* WIRELESS_EXT >= 15 */
811 }
812 
813 void send_monitor_packets(
814         IN      PRTMP_ADAPTER   pAd,
815         IN      RX_BLK                  *pRxBlk)
816 {
817     struct sk_buff      *pOSPkt;
818     wlan_ng_prism2_header *ph;
819     int rate_index = 0;
820     USHORT header_len = 0;
821     UCHAR temp_header[40] = {0};
822 
823     u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96,  108,   109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
824         54, 108, 162, 216, 324, 432, 486, 540,  14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10,
825         11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
826 
827 
828     ASSERT(pRxBlk->pRxPacket);
829     if (pRxBlk->DataSize < 10)
830     {
831         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __func__, pRxBlk->DataSize));
832                 goto err_free_sk_buff;
833     }
834 
835     if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
836     {
837 #ifndef RT30xx
838         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
839 #endif
840 #ifdef RT30xx
841         DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
842 #endif
843                 goto err_free_sk_buff;
844     }
845 
846     pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
847         pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
848     if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
849     {
850         pRxBlk->DataSize -= LENGTH_802_11;
851         if ((pRxBlk->pHeader->FC.ToDs == 1) &&
852             (pRxBlk->pHeader->FC.FrDs == 1))
853             header_len = LENGTH_802_11_WITH_ADDR4;
854         else
855             header_len = LENGTH_802_11;
856 
857         // QOS
858         if (pRxBlk->pHeader->FC.SubType & 0x08)
859         {
860             header_len += 2;
861                 // Data skip QOS contorl field
862                 pRxBlk->DataSize -=2;
863         }
864 
865         // Order bit: A-Ralink or HTC+
866         if (pRxBlk->pHeader->FC.Order)
867         {
868             header_len += 4;
869                         // Data skip HTC contorl field
870                         pRxBlk->DataSize -= 4;
871         }
872 
873         // Copy Header
874         if (header_len <= 40)
875             NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
876 
877         // skip HW padding
878         if (pRxBlk->RxD.L2PAD)
879             pRxBlk->pData += (header_len + 2);
880         else
881             pRxBlk->pData += header_len;
882     } //end if
883 
884 
885         if (pRxBlk->DataSize < pOSPkt->len) {
886         skb_trim(pOSPkt,pRxBlk->DataSize);
887     } else {
888         skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
889     } //end if
890 
891     if ((pRxBlk->pData - pOSPkt->data) > 0) {
892             skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
893             skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
894     } //end if
895 
896     if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
897         if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
898                 DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __func__));
899                         goto err_free_sk_buff;
900             } //end if
901     } //end if
902 
903     if (header_len > 0)
904         NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
905 
906     ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
907         NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
908 
909     ph->msgcode             = DIDmsg_lnxind_wlansniffrm;
910         ph->msglen                  = sizeof(wlan_ng_prism2_header);
911         strcpy(ph->devname, pAd->net_dev->name);
912 
913     ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
914         ph->hosttime.status = 0;
915         ph->hosttime.len = 4;
916         ph->hosttime.data = jiffies;
917 
918         ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
919         ph->mactime.status = 0;
920         ph->mactime.len = 0;
921         ph->mactime.data = 0;
922 
923     ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
924         ph->istx.status = 0;
925         ph->istx.len = 0;
926         ph->istx.data = 0;
927 
928     ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
929         ph->channel.status = 0;
930         ph->channel.len = 4;
931 
932     ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
933 
934     ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
935         ph->rssi.status = 0;
936         ph->rssi.len = 4;
937     ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
938 
939         ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
940         ph->signal.status = 0;
941         ph->signal.len = 4;
942         ph->signal.data = 0; //rssi + noise;
943 
944         ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
945         ph->noise.status = 0;
946         ph->noise.len = 4;
947         ph->noise.data = 0;
948 
949     if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
950     {
951         rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
952     }
953     else
954         if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
955         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
956     else
957         rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
958     if (rate_index < 0)
959         rate_index = 0;
960     if (rate_index > 255)
961         rate_index = 255;
962 
963         ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
964         ph->rate.status = 0;
965         ph->rate.len = 4;
966     ph->rate.data = ralinkrate[rate_index];
967 
968         ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
969     ph->frmlen.status = 0;
970         ph->frmlen.len = 4;
971         ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
972 
973 
974     pOSPkt->pkt_type = PACKET_OTHERHOST;
975     pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
976     pOSPkt->ip_summed = CHECKSUM_NONE;
977     netif_rx(pOSPkt);
978 
979     return;
980 
981 err_free_sk_buff:
982         RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
983         return;
984 
985 }
986 
987 void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
988 {
989         daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
990 
991         allow_signal(SIGTERM);
992         allow_signal(SIGKILL);
993         current->flags |= PF_NOFREEZE;
994 
995         /* signal that we've started the thread */
996         complete(pNotify);
997 }
998 
999 void RTMP_IndicateMediaState(
1000         IN      PRTMP_ADAPTER   pAd)
1001 {
1002         if (pAd->CommonCfg.bWirelessEvent)
1003         {
1004                 if (pAd->IndicateMediaState == NdisMediaStateConnected)
1005                 {
1006                         RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1007                 }
1008                 else
1009                 {
1010                         RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
1011                 }
1012         }
1013 }
1014 
1015 
  This page was automatically generated by the LXR engine.