add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / nic / nic_rx.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/nic/nic_rx.c#3 $
3 */
4
5 /*! \file   nic_rx.c
6     \brief  Functions that provide many rx-related functions
7
8     This file includes the functions used to process RFB and dispatch RFBs to
9     the appropriate related rx functions for protocols.
10 */
11
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
14 *
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
18 * MediaTek Inc.
19 ********************************************************************************
20 */
21
22 /*******************************************************************************
23 * LEGAL DISCLAIMER
24 *
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
38 *
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
44 *
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
50 * (ICC).
51 ********************************************************************************
52 */
53
54 /*
55 ** $Log: nic_rx.c $
56  *
57  * 01 17 2012 yuche.tsai
58  * NULL
59  * Update mgmt frame filter setting.
60  * Please also update FW 2.1
61  *
62  * 01 13 2012 yuche.tsai
63  * NULL
64  * WiFi Hot Spot Tethering for ICS ALPHA testing version.
65  *
66  * 11 19 2011 yuche.tsai
67  * NULL
68  * Add P2P RSSI Link Quality Query Support. (Default Off)
69  *
70  * 11 17 2011 tsaiyuan.hsu
71  * [WCXRP00001115] [MT6620 Wi-Fi][DRV] avoid deactivating staRec when changing state 3 to 3.
72  * avoid deactivating staRec when changing state from 3 to 3.
73  *
74  * 11 11 2011 wh.su
75  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
76  * modify the xlog related code.
77  *
78  * 11 10 2011 eddie.chen
79  * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
80  * Modify the QM xlog level and remove LOG_FUNC.
81  *
82  * 11 09 2011 eddie.chen
83  * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
84  * Add xlog for beacon timeout and sta aging timeout.
85  *
86  * 11 08 2011 eddie.chen
87  * [WCXRP00001096] [MT6620 Wi-Fi][Driver/FW] Enhance the log function (xlog)
88  * Add xlog function.
89  *
90  * 11 04 2011 tsaiyuan.hsu
91  * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
92  * add debug counters and periodically dump counters for Xlog debugging.
93  *
94  * 10 19 2011 yuche.tsai
95  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
96  * Branch 2.1
97  * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926.
98  *
99  * 08 26 2011 cp.wu
100  * [WCXRP00000958] [MT6620 Wi-Fi][Driver] Extend polling timeout from 25ms to 1sec due to RF calibration might took up to 600ms
101  * extend polling RX response timeout period from 25ms to 1000ms.
102  *
103  * 08 11 2011 cp.wu
104  * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
105  * sparse channel detection:
106  * driver: collect sparse channel information with scan-done event
107  *
108  * 07 28 2011 chinghwa.yu
109  * [WCXRP00000063] Update BCM CoEx design and settings
110  * Add BWCS cmd and event.
111  *
112  * 06 27 2011 tsaiyuan.hsu
113  * [WCXRP00000816] [MT6620 Wi-Fi][Driver] add control to enable rx data dump or not
114  * add control to enable rx data dump by packet type.
115  *
116  * 06 09 2011 tsaiyuan.hsu
117  * [WCXRP00000760] [MT5931 Wi-Fi][FW] Refine rxmHandleMacRxDone to reduce code size
118  * move send_auth at rxmHandleMacRxDone in firmware to driver to reduce code size.
119  *
120  * 05 16 2011 eddie.chen
121  * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
122  * Sync from ALPS.
123  *
124  * 05 09 2011 eddie.chen
125  * [WCXRP00000709] [MT6620 Wi-Fi][Driver] Check free number before copying broadcast packet
126  * Check free number before copying broadcast packet.
127  *
128  * 04 18 2011 terry.wu
129  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
130  * Remove flag CFG_WIFI_DIRECT_MOVED.
131  *
132  * 04 12 2011 cm.chang
133  * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
134  * .
135  *
136  * 04 10 2011 yuche.tsai
137  * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
138  * Add device discoverability support. (Phase I)
139  *
140  * 04 01 2011 tsaiyuan.hsu
141  * [WCXRP00000615] [MT 6620 Wi-Fi][Driver] Fix klocwork issues
142  * fix the klocwork issues, 57500, 57501, 57502 and 57503.
143  *
144  * 03 19 2011 yuche.tsai
145  * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
146  * Add beacon timeout support for WiFi Direct Netwrok.
147  *
148  * 03 18 2011 cp.wu
149  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
150  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
151  *
152  * 03 18 2011 wh.su
153  * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
154  * enable the Anti_piracy check at driver .
155  *
156  * 03 17 2011 cp.wu
157  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
158  * use pre-allocated buffer for storing enhanced interrupt response as well
159  *
160  * 03 15 2011 cp.wu
161  * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
162  * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
163  * 2. Use common coalescing buffer for both TX/RX directions
164  *
165  *
166  * 03 07 2011 wh.su
167  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
168  * rename the define to anti_pviracy.
169  *
170  * 03 05 2011 wh.su
171  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
172  * add the code to get the check rsponse and indicate to app.
173  *
174  * 03 02 2011 wh.su
175  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
176  * Add security check code.
177  *
178  * 03 02 2011 cp.wu
179  * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after connection is built.
180  * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
181  *
182  * 02 10 2011 yuche.tsai
183  * [WCXRP00000419] [Volunteer Patch][MT6620/MT5931][Driver] Provide function of disconnect to target station for AAA module.
184  * Remove Station Record after Aging timeout.
185  *
186  * 02 10 2011 cp.wu
187  * [WCXRP00000434] [MT6620 Wi-Fi][Driver] Obsolete unused event packet handlers
188  * EVENT_ID_CONNECTION_STATUS has been obsoleted and no need to handle.
189  *
190  * 02 09 2011 yuche.tsai
191  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
192  * Add MLME deauthentication support for Hot-Spot mode.
193  *
194  * 02 09 2011 eddie.chen
195  * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
196  * Adjust variable order.
197  *
198  * 02 08 2011 eddie.chen
199  * [WCXRP00000426] [MT6620 Wi-Fi][FW/Driver] Add STA aging timeout and defualtHwRatein AP mode
200  * Add event STA agint timeout
201  *
202  * 01 27 2011 tsaiyuan.hsu
203  * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
204  * add roaming fsm
205  * 1. not support 11r, only use strength of signal to determine roaming.
206  * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
207  * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
208  * 4. assume that change of link quality in smooth way.
209  *
210  * 01 26 2011 cm.chang
211  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
212  * .
213  *
214  * 01 24 2011 eddie.chen
215  * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
216  * Remove comments.
217  *
218  * 01 24 2011 eddie.chen
219  * [WCXRP00000385] [MT6620 Wi-Fi][DRV] Add destination decision for forwarding packets
220  * Add destination decision in AP mode.
221  *
222  * 01 24 2011 cm.chang
223  * [WCXRP00000384] [MT6620 Wi-Fi][Driver][FW] Handle 20/40 action frame in AP mode and stop ampdu timer when sta_rec is freed
224  * Process received 20/40 coexistence action frame for AP mode
225  *
226  * 01 24 2011 cp.wu
227  * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
228  * 1. add an extra counter for tracking pending forward frames.
229  * 2. notify TX service thread as well when there is pending forward frame
230  * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
231  *
232  * 01 12 2011 cp.wu
233  * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
234  * implementation of separate BT_OVER_WIFI data path.
235  *
236  * 12 29 2010 eddie.chen
237  * [WCXRP00000322] Add WMM IE in beacon,
238 Add per station flow control when STA is in PS
239
240  * 1) PS flow control event
241  *
242  * 2) WMM IE in beacon, assoc resp, probe resp
243  *
244  * 12 15 2010 george.huang
245  * [WCXRP00000152] [MT6620 Wi-Fi] AP mode power saving function
246  * update beacon for NoA
247  *
248  * 11 01 2010 cp.wu
249  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
250  * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
251  * 2) Remove CNM CH-RECOVER event handling
252  * 3) cfg read/write API renamed with kal prefix for unified naming rules.
253  *
254  * 10 27 2010 george.huang
255  * [WCXRP00000127] [MT6620 Wi-Fi][Driver] Add a registry to disable Beacon Timeout function for SQA test by using E1 EVB
256  * Support registry option for disable beacon lost detection.
257  *
258  * 10 20 2010 wh.su
259  * NULL
260  * add a cmd to reset the p2p key
261  *
262  * 10 20 2010 wh.su
263  * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
264  * Add the code to support disconnect p2p group
265  *
266  * 09 29 2010 wh.su
267  * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
268  * fixed compilier error.
269  *
270  * 09 29 2010 wh.su
271  * [WCXRP00000072] [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue
272  * [MT6620 Wi-Fi][Driver] Fix TKIP Counter Measure EAPoL callback register issue.
273  *
274  * 09 23 2010 cp.wu
275  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
276  * eliminate reference of CFG_RESPONSE_MAX_PKT_SIZE
277  *
278  * 09 21 2010 cp.wu
279  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
280  * release RX packet to packet pool when in RF test mode
281  *
282  * 09 21 2010 cp.wu
283  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
284  * Do a complete reset with STA-REC null checking for RF test re-entry
285  *
286  * 09 08 2010 cp.wu
287  * NULL
288  * use static memory pool for storing IEs of scanning result.
289  *
290  * 09 07 2010 yuche.tsai
291  * NULL
292  * Add a common buffer, store the IE of a P2P device in this common buffer.
293  *
294  * 09 03 2010 kevin.huang
295  * NULL
296  * Refine #include sequence and solve recursive/nested #include issue
297  *
298  * 08 31 2010 kevin.huang
299  * NULL
300  * Use LINK LIST operation to process SCAN result
301  *
302  * 08 30 2010 cp.wu
303  * NULL
304  * eliminate klockwork errors
305  *
306  * 08 20 2010 cm.chang
307  * NULL
308  * Migrate RLM code to host from FW
309  *
310  * 08 20 2010 yuche.tsai
311  * NULL
312  * When enable WiFi Direct function, check each packet to tell which interface to indicate.
313  *
314  * 08 05 2010 yuche.tsai
315  * NULL
316  * Add P2P Device Discovery Function.
317  *
318  * 08 03 2010 cp.wu
319  * NULL
320  * surpress compilation warning.
321  *
322  * 08 03 2010 george.huang
323  * NULL
324  * handle event for updating NOA parameters indicated from FW
325  *
326  * 08 02 2010 yuche.tsai
327  * NULL
328  * Add support API for RX public action frame.
329  *
330  * 08 02 2010 jeffrey.chang
331  * NULL
332  * 1) modify tx service thread to avoid busy looping
333  * 2) add spin lock declartion for linux build
334  *
335  * 07 30 2010 cp.wu
336  * NULL
337  * 1) BoW wrapper: use definitions instead of hard-coded constant for error code
338  * 2) AIS-FSM: eliminate use of desired RF parameters, use prTargetBssDesc instead
339  * 3) add handling for RX_PKT_DESTINATION_HOST_WITH_FORWARD for GO-broadcast frames
340  *
341  * 07 26 2010 yuche.tsai
342  *
343  * Update Device Capability Bitmap & Group Capability Bitmap from 16 bits to 8 bits.
344  *
345  * 07 24 2010 wh.su
346  *
347  * .support the Wi-Fi RSN
348  *
349  * 07 23 2010 cp.wu
350  *
351  * add AIS-FSM handling for beacon timeout event.
352  *
353  * 07 21 2010 yuche.tsai
354  *
355  * Add P2P Scan & Scan Result Parsing & Saving.
356  *
357  * 07 19 2010 cm.chang
358  *
359  * Set RLM parameters and enable CNM channel manager
360  *
361  * 07 19 2010 cp.wu
362  *
363  * [WPD00003833] [MT6620 and MT5931] Driver migration.
364  * Add Ad-Hoc support to AIS-FSM
365  *
366  * 07 19 2010 jeffrey.chang
367  *
368  * Linux port modification
369  *
370  * 07 16 2010 yarco.yang
371  *
372  * 1. Support BSS Absence/Presence Event
373  * 2. Support STA change PS mode Event
374  * 3. Support BMC forwarding for AP mode.
375  *
376  * 07 15 2010 cp.wu
377  *
378  * sync. bluetooth-over-Wi-Fi interface to driver interface document v0.2.6.
379  *
380  * 07 08 2010 cp.wu
381  *
382  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
383  *
384  * 07 07 2010 cp.wu
385  * [WPD00003833][MT6620 and MT5931] Driver migration
386  * fill ucStaRecIdx into SW_RFB_T.
387  *
388  * 07 02 2010 cp.wu
389  * [WPD00003833][MT6620 and MT5931] Driver migration
390  * 1) for event packet, no need to fill RFB.
391  * 2) when wlanAdapterStart() failed, no need to initialize state machines
392  * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
393  *
394  * 07 01 2010 cp.wu
395  * [WPD00003833][MT6620 and MT5931] Driver migration
396  * implementation of DRV-SCN and related mailbox message handling.
397  *
398  * 06 29 2010 yarco.yang
399  * [WPD00003837][MT6620]Data Path Refine
400  * replace g_rQM with Adpater->rQM
401  *
402  * 06 23 2010 yarco.yang
403  * [WPD00003837][MT6620]Data Path Refine
404  * Merge g_arStaRec[] into adapter->arStaRec[]
405  *
406  * 06 22 2010 cp.wu
407  * [WPD00003833][MT6620 and MT5931] Driver migration
408  * 1) add command warpper for STA-REC/BSS-INFO sync.
409  * 2) enhance command packet sending procedure for non-oid part
410  * 3) add command packet definitions for STA-REC/BSS-INFO sync.
411  *
412  * 06 21 2010 cp.wu
413  * [WPD00003833][MT6620 and MT5931] Driver migration
414  * refine TX-DONE callback.
415  *
416  * 06 21 2010 cp.wu
417  * [WPD00003833][MT6620 and MT5931] Driver migration
418  * implement TX_DONE callback path.
419  *
420  * 06 21 2010 yarco.yang
421  * [WPD00003837][MT6620]Data Path Refine
422  * Add TX Done Event handle entry
423  *
424  * 06 21 2010 wh.su
425  * [WPD00003840][MT6620 5931] Security migration
426  * remove duplicate variable for migration.
427  *
428  * 06 15 2010 cp.wu
429  * [WPD00003833][MT6620 and MT5931] Driver migration
430  * .
431  *
432  * 06 15 2010 cp.wu
433  * [WPD00003833][MT6620 and MT5931] Driver migration
434  * .
435  *
436  * 06 14 2010 cp.wu
437  * [WPD00003833][MT6620 and MT5931] Driver migration
438  * saa_fsm.c is migrated.
439  *
440  * 06 14 2010 cp.wu
441  * [WPD00003833][MT6620 and MT5931] Driver migration
442  * add management dispatching function table.
443  *
444  * 06 11 2010 cp.wu
445  * [WPD00003833][MT6620 and MT5931] Driver migration
446  * 1) migrate assoc.c.
447  * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
448  * 3) add configuration options for CNM_MEM and RSN modules
449  * 4) add data path for management frames
450  * 5) eliminate rPacketInfo of MSDU_INFO_T
451  *
452  * 06 10 2010 cp.wu
453  * [WPD00003833][MT6620 and MT5931] Driver migration
454  * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
455  * 2) when disconnected, indicate nic directly (no event is needed)
456  *
457  * 06 08 2010 cp.wu
458  * [WPD00003833][MT6620 and MT5931] Driver migration
459  * cnm_timer has been migrated.
460  *
461  * 06 07 2010 cp.wu
462  * [WPD00003833][MT6620 and MT5931] Driver migration
463  * merge wlan_def.h.
464  *
465  * 06 07 2010 cp.wu
466  * [WPD00003833][MT6620 and MT5931] Driver migration
467  * sync with MT6620 driver for scan result replacement policy
468  *
469  * 06 06 2010 kevin.huang
470  * [WPD00003832][MT6620 5931] Create driver base
471  * [MT6620 5931] Create driver base
472  *
473  * 05 20 2010 cp.wu
474  * [WPD00001943]Create WiFi test driver framework on WinXP
475  * 1) integrate OID_GEN_NETWORK_LAYER_ADDRESSES with CMD_ID_SET_IP_ADDRESS
476  * 2) buffer statistics data for 2 seconds
477  * 3) use default value for adhoc parameters instead of 0
478  *
479  * 05 19 2010 cp.wu
480  * [WPD00001943]Create WiFi test driver framework on WinXP
481  * 1) do not take timeout mechanism for power mode oids
482  * 2) retrieve network type from connection status
483  * 3) after disassciation, set radio state to off
484  * 4) TCP option over IPv6 is supported
485  *
486  * 04 29 2010 wh.su
487  * [WPD00003816][MT6620 Wi-Fi] Adding the security support
488  * fixing the PMKID candicate indicate code.
489  *
490  * 04 28 2010 cp.wu
491  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
492  * change prefix for data structure used to communicate with 802.11 PAL
493  * to avoid ambiguous naming with firmware interface
494  *
495  * 04 27 2010 cp.wu
496  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
497  * basic implementation for EVENT_BT_OVER_WIFI
498  *
499  * 04 23 2010 cp.wu
500  * [WPD00001943]Create WiFi test driver framework on WinXP
501  * surpress compiler warning
502  *
503  * 04 22 2010 jeffrey.chang
504  * [WPD00003826]Initial import for Linux port
505  *
506  * 1) modify rx path code for supporting Wi-Fi direct
507  * 2) modify config.h since Linux dont need to consider retaining packet
508  *
509  * 04 16 2010 cp.wu
510  * [WPD00001943]Create WiFi test driver framework on WinXP
511  * treat BUS access failure as kind of card removal.
512  *
513  * 04 14 2010 cp.wu
514  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
515  * nicRxProcessEvent packet doesn't access spin-lock directly from now on.
516  *
517  * 04 14 2010 cp.wu
518  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
519  * do not need to release the spin lock due to it is done inside nicGetPendingCmdInfo()
520  *
521  * 04 13 2010 cp.wu
522  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
523  * add framework for BT-over-Wi-Fi support.
524  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
525  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
526  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
527  *
528  * 04 12 2010 cp.wu
529  * [WPD00001943]Create WiFi test driver framework on WinXP
530  * add channel frequency <-> number conversion
531  *
532  * 04 09 2010 jeffrey.chang
533  * [WPD00003826]Initial import for Linux port
534  * 1) add spinlock
535  * 2) add KAPI for handling association info
536  *
537  * 04 07 2010 cp.wu
538  * [WPD00001943]Create WiFi test driver framework on WinXP
539  * rWlanInfo should be placed at adapter rather than glue due to most operations
540  *  *  *  *  * are done in adapter layer.
541  *
542  * 04 07 2010 cp.wu
543  * [WPD00001943]Create WiFi test driver framework on WinXP
544  * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
545  *
546  * 04 06 2010 cp.wu
547  * [WPD00001943]Create WiFi test driver framework on WinXP
548  * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
549  *
550  * 04 01 2010 jeffrey.chang
551  * [WPD00003826]Initial import for Linux port
552  * improve Linux supplicant compliance
553  *
554  * 03 31 2010 jeffrey.chang
555  * [WPD00003826]Initial import for Linux port
556  * fix ioctl which may cause cmdinfo memory leak
557  *
558  * 03 30 2010 cp.wu
559  * [WPD00001943]Create WiFi test driver framework on WinXP
560  * remove driver-land statistics.
561  *
562  * 03 29 2010 jeffrey.chang
563  * [WPD00003826]Initial import for Linux port
564  * improve none-glue code portability
565  *
566  * 03 28 2010 jeffrey.chang
567  * [WPD00003826]Initial import for Linux port
568  * rWlanInfo is modified before data is indicated to OS
569  *
570  * 03 28 2010 jeffrey.chang
571  * [WPD00003826]Initial import for Linux port
572  * rWlanInfo is modified before data is indicated to OS
573  *
574  * 03 26 2010 cp.wu
575  * [WPD00001943]Create WiFi test driver framework on WinXP
576  * add a temporary flag for integration with CMD/EVENT v0.9.
577  *
578  * 03 25 2010 cp.wu
579  * [WPD00001943]Create WiFi test driver framework on WinXP
580  * 1) correct OID_802_11_CONFIGURATION with frequency setting behavior.
581  *  *  * the frequency is used for adhoc connection only
582  *  *  * 2) update with SD1 v0.9 CMD/EVENT documentation
583  *
584  * 03 24 2010 jeffrey.chang
585  * [WPD00003826]Initial import for Linux port
586  * initial import for Linux port
587  *
588  * 03 24 2010 cp.wu
589  * [WPD00001943]Create WiFi test driver framework on WinXP
590  * .
591  *
592  * 03 24 2010 cp.wu
593  * [WPD00001943]Create WiFi test driver framework on WinXP
594  * generate information for OID_GEN_RCV_OK & OID_GEN_XMIT_OK
595  *  *  *  *
596  *
597  * 03 19 2010 cp.wu
598  * [WPD00001943]Create WiFi test driver framework on WinXP
599  * 1) add ACPI D0/D3 state switching support
600  *  *  *  *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
601  *
602  * 03 15 2010 kevin.huang
603  * [WPD00003820][MT6620 Wi-Fi] Modify the code for meet the WHQL test
604  * Add event for activate STA_RECORD_T
605  *
606  * 03 12 2010 cp.wu
607  * [WPD00001943]Create WiFi test driver framework on WinXP
608  * correct fgSetQuery/fgNeedResp check
609  *
610  * 03 11 2010 cp.wu
611  * [WPD00003821][BUG] Host driver stops processing RX packets from HIF RX0
612  * add RX starvation warning debug message controlled by CFG_HIF_RX_STARVATION_WARNING
613  *
614  * 03 10 2010 cp.wu
615  * [WPD00001943]Create WiFi test driver framework on WinXP
616  * code clean: removing unused variables and structure definitions
617  *
618  * 03 08 2010 cp.wu
619  * [WPD00001943]Create WiFi test driver framework on WinXP
620  * 1) add another spin-lock to protect MsduInfoList due to it might be accessed by different thread.
621  *  *  * 2) change own-back acquiring procedure to wait for up to 16.67 seconds
622  *
623  * 03 02 2010 cp.wu
624  * [WPD00001943]Create WiFi test driver framework on WinXP
625  * 1) the use of prPendingOid revised, all accessing are now protected by spin lock
626  *  *  *  * 2) ensure wlanReleasePendingOid will clear all command queues
627  *
628  * 03 02 2010 cp.wu
629  * [WPD00001943]Create WiFi test driver framework on WinXP
630  * add mutex to avoid multiple access to qmTxQueue simultaneously.
631  *
632  * 02 26 2010 cp.wu
633  * [WPD00001943]Create WiFi test driver framework on WinXP
634  * move EVENT_ID_ASSOC_INFO from nic_rx.c to gl_kal_ndis_51.c
635  *  * 'cause it involves OS dependent data structure handling
636  *
637  * 02 25 2010 cp.wu
638  * [WPD00001943]Create WiFi test driver framework on WinXP
639  * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
640  *
641  * 02 24 2010 tehuang.liu
642  * [WPD00001943]Create WiFi test driver framework on WinXP
643  * Updated API interfaces for qmHandleEventRxAddBa() and qmHandleEventRxDelBa()
644  *
645  * 02 10 2010 cp.wu
646  * [WPD00001943]Create WiFi test driver framework on WinXP
647  * implement host-side firmware download logic
648  *
649  * 02 10 2010 cp.wu
650  * [WPD00001943]Create WiFi test driver framework on WinXP
651  * 1) remove unused function in nic_rx.c [which has been handled in que_mgt.c]
652  *  *  *  *  * 2) firmware image length is now retrieved via NdisFileOpen
653  *  *  *  *  * 3) firmware image is not structured by (P_IMG_SEC_HDR_T) anymore
654  *  *  *  *  * 4) nicRxWaitResponse() revised
655  *  *  *  *  * 5) another set of TQ counter default value is added for fw-download state
656  *  *  *  *  * 6) Wi-Fi load address is now retrieved from registry too
657  *
658  * 02 09 2010 cp.wu
659  * [WPD00001943]Create WiFi test driver framework on WinXP
660  * 1. Permanent and current MAC address are now retrieved by CMD/EVENT packets instead of hard-coded address
661  *  *  *  *  *  *  *  * 2. follow MSDN defined behavior when associates to another AP
662  *  *  *  *  *  *  *  * 3. for firmware download, packet size could be up to 2048 bytes
663  *
664  * 01 27 2010 wh.su
665  * [WPD00003816][MT6620 Wi-Fi] Adding the security support
666  * .
667  *
668  * 01 22 2010 cp.wu
669  * [WPD00001943]Create WiFi test driver framework on WinXP
670  * implement following 802.11 OIDs:
671  *  *  *  *  *  * OID_802_11_RSSI,
672  *  *  *  *  *  * OID_802_11_RSSI_TRIGGER,
673  *  *  *  *  *  * OID_802_11_STATISTICS,
674  *  *  *  *  *  * OID_802_11_DISASSOCIATE,
675  *  *  *  *  *  * OID_802_11_POWER_MODE
676  *
677  * 12 30 2009 cp.wu
678  * [WPD00001943]Create WiFi test driver framework on WinXP
679  * 1) According to CMD/EVENT documentation v0.8,
680  *  *  *  *  *  *  *  *  * OID_CUSTOM_TEST_RX_STATUS & OID_CUSTOM_TEST_TX_STATUS is no longer used,
681  *  *  *  *  *  *  *  *  * and result is retrieved by get ATInfo instead
682  *  *  *  *  *  *  *  *  * 2) add 4 counter for recording aggregation statistics
683  *
684  * 12 23 2009 cp.wu
685  * [WPD00001943]Create WiFi test driver framework on WinXP
686  * add a precheck: if free sw rfb is not enough, do not invoke read transactionu1rwduu`wvpghlqg|fu+rp
687  *
688  * 12 22 2009 cp.wu
689  * [WPD00003809][Bug] Host driver will crash when processing reordered MSDUs
690  * The root cause is pointer accessing by mistake. After dequeued from reordering-buffer, handling logic should access returned pointer instead of pointer which has been passed in before.
691 **  \main\maintrunk.MT6620WiFiDriver_Prj\58 2009-12-17 13:40:33 GMT mtk02752
692 **  always update prAdapter->rSDIOCtrl when enhanced response is read by RX
693 **  \main\maintrunk.MT6620WiFiDriver_Prj\57 2009-12-16 18:01:38 GMT mtk02752
694 **  if interrupt enhanced response is fetched by RX enhanced response, RX needs to invoke interrupt handlers too
695 **  \main\maintrunk.MT6620WiFiDriver_Prj\56 2009-12-16 14:16:52 GMT mtk02752
696 **  \main\maintrunk.MT6620WiFiDriver_Prj\55 2009-12-15 20:03:12 GMT mtk02752
697 **  ASSERT when RX FreeSwRfb is not enough
698 **  \main\maintrunk.MT6620WiFiDriver_Prj\54 2009-12-15 17:01:29 GMT mtk02752
699 **  when CFG_SDIO_RX_ENHANCE is enabled, after enhanced response is read, rx procedure should process 1) TX_DONE_INT 2) D2H INT as well
700 **  \main\maintrunk.MT6620WiFiDriver_Prj\53 2009-12-14 20:45:28 GMT mtk02752
701 **  when CFG_SDIO_RX_ENHANCE is set, TC counter must be updated each time RX enhance response is read
702 **
703 **  \main\maintrunk.MT6620WiFiDriver_Prj\52 2009-12-14 11:34:16 GMT mtk02752
704 **  correct a trivial logic issue
705 **  \main\maintrunk.MT6620WiFiDriver_Prj\51 2009-12-14 10:28:25 GMT mtk02752
706 **  add a protection to avoid out-of-boundary access
707 **  \main\maintrunk.MT6620WiFiDriver_Prj\50 2009-12-10 16:55:18 GMT mtk02752
708 **  code clean
709 **  \main\maintrunk.MT6620WiFiDriver_Prj\49 2009-12-09 14:06:47 GMT MTK02468
710 **  Added parsing event packets with EVENT_ID_RX_ADDBA or EVENT_ID_RX_DELBA
711 **  \main\maintrunk.MT6620WiFiDriver_Prj\48 2009-12-08 17:37:51 GMT mtk02752
712 **  handle EVENT_ID_TEST_STATUS as well
713 **  \main\maintrunk.MT6620WiFiDriver_Prj\47 2009-12-04 17:59:11 GMT mtk02752
714 **  to pass free-build compilation check
715 **  \main\maintrunk.MT6620WiFiDriver_Prj\46 2009-12-04 12:09:52 GMT mtk02752
716 **  correct trivial mistake
717 **  \main\maintrunk.MT6620WiFiDriver_Prj\45 2009-12-04 11:53:37 GMT mtk02752
718 **  all API should be compilable under SD1_SD3_DATAPATH_INTEGRATION == 0
719 **  \main\maintrunk.MT6620WiFiDriver_Prj\44 2009-12-03 16:19:48 GMT mtk01461
720 **  Fix the Connected Event
721 **  \main\maintrunk.MT6620WiFiDriver_Prj\43 2009-11-30 10:56:18 GMT mtk02752
722 **  1st DW of WIFI_EVENT_T is shared with HIF_RX_HEADER_T
723 **  \main\maintrunk.MT6620WiFiDriver_Prj\42 2009-11-30 10:11:27 GMT mtk02752
724 **  implement replacement for bss scan result
725 **  \main\maintrunk.MT6620WiFiDriver_Prj\41 2009-11-27 11:08:05 GMT mtk02752
726 **  add flush for reset
727 **  \main\maintrunk.MT6620WiFiDriver_Prj\40 2009-11-26 09:38:59 GMT mtk02752
728 **  \main\maintrunk.MT6620WiFiDriver_Prj\39 2009-11-26 09:29:40 GMT mtk02752
729 **  enable packet forwarding path (for AP mode)
730 **  \main\maintrunk.MT6620WiFiDriver_Prj\38 2009-11-25 21:37:00 GMT mtk02752
731 **  sync. with EVENT_SCAN_RESULT_T change, and add an assert for checking event size
732 **  \main\maintrunk.MT6620WiFiDriver_Prj\37 2009-11-25 20:17:41 GMT mtk02752
733 **  fill HIF_TX_HEADER_T.u2SeqNo
734 **  \main\maintrunk.MT6620WiFiDriver_Prj\36 2009-11-25 18:18:57 GMT mtk02752
735 **  buffer scan result to prGlueInfo->rWlanInfo.arScanResult directly.
736 **  \main\maintrunk.MT6620WiFiDriver_Prj\35 2009-11-24 22:42:45 GMT mtk02752
737 **  add nicRxAddScanResult() to prepare to handle SCAN_RESULT event (not implemented yet)
738 **  \main\maintrunk.MT6620WiFiDriver_Prj\34 2009-11-24 20:51:41 GMT mtk02752
739 **  integrate with SD1's data path API
740 **  \main\maintrunk.MT6620WiFiDriver_Prj\33 2009-11-24 19:56:17 GMT mtk02752
741 **  adopt P_HIF_RX_HEADER_T in new path
742 **  \main\maintrunk.MT6620WiFiDriver_Prj\32 2009-11-23 20:31:21 GMT mtk02752
743 **  payload to send into pfCmdDoneHandler() will not include WIFI_EVENT_T
744 **  \main\maintrunk.MT6620WiFiDriver_Prj\31 2009-11-23 17:51:34 GMT mtk02752
745 **  when event packet corresponding to some pendingOID is received, pendingOID should be cleared
746 **  \main\maintrunk.MT6620WiFiDriver_Prj\30 2009-11-23 14:46:54 GMT mtk02752
747 **  implement nicRxProcessEventPacket()
748 **  \main\maintrunk.MT6620WiFiDriver_Prj\29 2009-11-17 22:40:54 GMT mtk01084
749 **  \main\maintrunk.MT6620WiFiDriver_Prj\28 2009-11-16 21:48:22 GMT mtk02752
750 **  add SD1_SD3_DATAPATH_INTEGRATION data path handling
751 **  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-11-16 15:41:18 GMT mtk01084
752 **  modify the length to be read in emu mode
753 **  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-11-13 17:00:12 GMT mtk02752
754 **  add blank function for event packet
755 **  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-11-13 13:54:24 GMT mtk01084
756 **  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-11-11 14:41:51 GMT mtk02752
757 **  fix typo
758 **  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-11 14:33:46 GMT mtk02752
759 **  add protection when there is no packet avilable
760 **  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-11 12:33:36 GMT mtk02752
761 **  add RX1 read path for aggregated/enhanced/normal packet read procedures
762 **  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:18 GMT mtk01084
763 **  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-04 14:11:08 GMT mtk01084
764 **  modify lines in RX aggregation
765 **  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:23 GMT mtk01084
766 **  modify RX aggregation handling
767 **  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:56:12 GMT mtk01084
768 **  modify HAL part
769 **  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:34 GMT mtk01084
770 **  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:20 GMT mtk01084
771 **  update for new HW design
772 **  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-10-02 13:59:08 GMT mtk01725
773 **  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-21 23:39:05 GMT mtk01461
774 **  Fix the paste error of RX STATUS in OOB of HIF Loopback CTRL
775 **  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-20 12:25:32 GMT mtk01461
776 **  Fix process of Read Done, and add u4MaxEventBufferLen to nicRxWaitResponse()
777 **  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 21:13:18 GMT mtk01426
778 **  Fixed compiler error
779 **  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-18 21:05:29 GMT mtk01426
780 **  Fixed nicRxSDIOAggReceiveRFBs() ASSERT issue
781 **  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:38:43 GMT mtk01461
782 **  Fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode and refine  nicRxSDIOAggeceiveRFBs() for RX Aggregation
783 **  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-22 09:12:17 GMT mtk01461
784 **  Fix nicRxProcessHIFLoopbackPacket(), the size of HIF CTRL LENTH field is 1 byte
785 **  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-14 15:51:26 GMT mtk01426
786 **  Update RX OOB Setting
787 **  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-03 14:58:58 GMT mtk01426
788 **  Fixed logical error
789 **  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:58:31 GMT mtk01461
790 **  Rename the HIF_PKT_TYPE_DATA
791 **  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-23 21:51:18 GMT mtk01461
792 **  Fix u4HeaderOffset in nicRxProcessHIFLoopbackPacket()
793 **  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:02:58 GMT mtk01426
794 **  Add CFG_SDIO_RX_ENHANCE and CFG_HIF_LOOPBACK support
795 **  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-17 20:20:59 GMT mtk01426
796 **  Add nicRxWaitResponse function
797 **  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:26:01 GMT mtk01426
798 **  Init for develop
799 **
800 */
801
802 /*******************************************************************************
803 *                         C O M P I L E R   F L A G S
804 ********************************************************************************
805 */
806
807 /*******************************************************************************
808 *                    E X T E R N A L   R E F E R E N C E S
809 ********************************************************************************
810 */
811 #include "precomp.h"
812
813 #ifndef LINUX
814 #include <limits.h>
815 #else
816 #include <linux/limits.h>
817 #endif
818
819 /*******************************************************************************
820 *                              C O N S T A N T S
821 ********************************************************************************
822 */
823 #define RX_RESPONSE_TIMEOUT (1000)
824
825 /*******************************************************************************
826 *                             D A T A   T Y P E S
827 ********************************************************************************
828 */
829
830 /*******************************************************************************
831 *                            P U B L I C   D A T A
832 ********************************************************************************
833 */
834
835 /*******************************************************************************
836 *                           P R I V A T E   D A T A
837 ********************************************************************************
838 */
839
840 #if CFG_MGMT_FRAME_HANDLING
841 static PROCESS_RX_MGT_FUNCTION apfnProcessRxMgtFrame[MAX_NUM_OF_FC_SUBTYPES] = {
842     #if CFG_SUPPORT_AAA
843     aaaFsmRunEventRxAssoc,              /* subtype 0000: Association request */
844     #else
845     NULL,                               /* subtype 0000: Association request */
846     #endif /* CFG_SUPPORT_AAA */
847     saaFsmRunEventRxAssoc,              /* subtype 0001: Association response */
848     #if CFG_SUPPORT_AAA
849     aaaFsmRunEventRxAssoc,              /* subtype 0010: Reassociation request */
850     #else
851     NULL,                               /* subtype 0010: Reassociation request */
852     #endif /* CFG_SUPPORT_AAA */
853     saaFsmRunEventRxAssoc,              /* subtype 0011: Reassociation response */
854     #if CFG_SUPPORT_ADHOC
855     bssProcessProbeRequest,             /* subtype 0100: Probe request */
856     #else
857     NULL,                               /* subtype 0100: Probe request */
858     #endif /* CFG_SUPPORT_ADHOC */
859     scanProcessBeaconAndProbeResp,      /* subtype 0101: Probe response */
860     NULL,                               /* subtype 0110: reserved */
861     NULL,                               /* subtype 0111: reserved */
862     scanProcessBeaconAndProbeResp,      /* subtype 1000: Beacon */
863     NULL,                               /* subtype 1001: ATIM */
864     saaFsmRunEventRxDisassoc,           /* subtype 1010: Disassociation */
865     authCheckRxAuthFrameTransSeq,       /* subtype 1011: Authentication */
866     saaFsmRunEventRxDeauth,             /* subtype 1100: Deauthentication */
867     nicRxProcessActionFrame,            /* subtype 1101: Action */
868     NULL,                               /* subtype 1110: reserved */
869     NULL                                /* subtype 1111: reserved */
870 };
871 #endif
872
873
874 /*******************************************************************************
875 *                                 M A C R O S
876 ********************************************************************************
877 */
878
879 /*******************************************************************************
880 *                   F U N C T I O N   D E C L A R A T I O N S
881 ********************************************************************************
882 */
883
884 /*******************************************************************************
885 *                              F U N C T I O N S
886 ********************************************************************************
887 */
888 /*----------------------------------------------------------------------------*/
889 /*!
890 * @brief Initialize the RFBs
891 *
892 * @param prAdapter      Pointer to the Adapter structure.
893 *
894 * @return (none)
895 */
896 /*----------------------------------------------------------------------------*/
897 VOID
898 nicRxInitialize (
899     IN P_ADAPTER_T prAdapter
900     )
901 {
902     P_RX_CTRL_T prRxCtrl;
903     PUINT_8 pucMemHandle;
904     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
905     UINT_32 i;
906
907     DEBUGFUNC("nicRxInitialize");
908
909     ASSERT(prAdapter);
910     prRxCtrl = &prAdapter->rRxCtrl;
911
912     //4 <0> Clear allocated memory.
913     kalMemZero((PVOID) prRxCtrl->pucRxCached, prRxCtrl->u4RxCachedSize);
914
915     //4 <1> Initialize the RFB lists
916     QUEUE_INITIALIZE(&prRxCtrl->rFreeSwRfbList);
917     QUEUE_INITIALIZE(&prRxCtrl->rReceivedRfbList);
918     QUEUE_INITIALIZE(&prRxCtrl->rIndicatedRfbList);
919
920     pucMemHandle = prRxCtrl->pucRxCached;
921     for (i = CFG_RX_MAX_PKT_NUM; i != 0; i--) {
922         prSwRfb = (P_SW_RFB_T)pucMemHandle;
923
924         nicRxSetupRFB(prAdapter, prSwRfb);
925         nicRxReturnRFB(prAdapter, prSwRfb);
926
927         pucMemHandle += ALIGN_4(sizeof(SW_RFB_T));
928     }
929
930     ASSERT(prRxCtrl->rFreeSwRfbList.u4NumElem == CFG_RX_MAX_PKT_NUM);
931     /* Check if the memory allocation consist with this initialization function */
932     ASSERT((UINT_32)(pucMemHandle - prRxCtrl->pucRxCached) == prRxCtrl->u4RxCachedSize);
933
934     //4 <2> Clear all RX counters
935     RX_RESET_ALL_CNTS(prRxCtrl);
936
937 #if CFG_SDIO_RX_AGG
938     prRxCtrl->pucRxCoalescingBufPtr = prAdapter->pucCoalescingBufCached;
939     #if !defined(MT5931)
940     HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM);
941     #endif
942 #else
943     #if !defined(MT5931)
944     HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1);
945     #endif
946 #endif
947
948 #if CFG_HIF_STATISTICS
949     prRxCtrl->u4TotalRxAccessNum = 0;
950     prRxCtrl->u4TotalRxPacketNum = 0;
951 #endif
952
953 #if CFG_HIF_RX_STARVATION_WARNING
954     prRxCtrl->u4QueuedCnt = 0;
955     prRxCtrl->u4DequeuedCnt = 0;
956 #endif
957
958     return;
959 } /* end of nicRxInitialize() */
960
961
962 #if defined(MT5931)
963 /*----------------------------------------------------------------------------*/
964 /*!
965 * @brief Initialize HIF RX control registers explicitly
966 *
967 * @param prAdapter      Pointer to the Adapter structure.
968 *
969 * @return (none)
970 */
971 /*----------------------------------------------------------------------------*/
972 VOID
973 nicRxPostInitialize (
974     IN P_ADAPTER_T prAdapter
975     )
976 {
977     P_RX_CTRL_T prRxCtrl;
978     DEBUGFUNC("nicRxPostInitialize");
979
980     ASSERT(prAdapter);
981     prRxCtrl = &prAdapter->rRxCtrl;
982
983 #if CFG_SDIO_RX_AGG
984     HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, CFG_SDIO_MAX_RX_AGG_NUM);
985 #else
986     HAL_CFG_MAX_HIF_RX_LEN_NUM(prAdapter, 1);
987 #endif
988
989 } /* end of nicRxPostInitialize() */
990 #endif
991
992
993 /*----------------------------------------------------------------------------*/
994 /*!
995 * @brief Uninitialize the RFBs
996 *
997 * @param prAdapter      Pointer to the Adapter structure.
998 *
999 * @return (none)
1000 */
1001 /*----------------------------------------------------------------------------*/
1002 VOID
1003 nicRxUninitialize (
1004     IN P_ADAPTER_T prAdapter
1005     )
1006 {
1007     P_RX_CTRL_T prRxCtrl;
1008     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
1009     KAL_SPIN_LOCK_DECLARATION();
1010
1011     ASSERT(prAdapter);
1012     prRxCtrl = &prAdapter->rRxCtrl;
1013     ASSERT(prRxCtrl);
1014
1015     nicRxFlush(prAdapter);
1016
1017     do {
1018         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1019         QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T);
1020         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1021         if (prSwRfb){
1022             if (prSwRfb->pvPacket) {
1023                 kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket);
1024             }
1025             prSwRfb->pvPacket = NULL;
1026         }
1027         else {
1028             break;
1029         }
1030     }while (TRUE);
1031
1032     do {
1033         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1034         QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
1035         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1036         if (prSwRfb){
1037             if (prSwRfb->pvPacket) {
1038                 kalPacketFree(prAdapter->prGlueInfo, prSwRfb->pvPacket);
1039             }
1040             prSwRfb->pvPacket = NULL;
1041         }
1042         else {
1043             break;
1044         }
1045     }while (TRUE);
1046
1047     return;
1048 } /* end of nicRxUninitialize() */
1049
1050
1051 /*----------------------------------------------------------------------------*/
1052 /*!
1053 * @brief Fill RFB
1054 *
1055 * @param prAdapter pointer to the Adapter handler
1056 * @param prSWRfb   specify the RFB to receive rx data
1057 *
1058 * @return (none)
1059 *
1060 */
1061 /*----------------------------------------------------------------------------*/
1062 VOID
1063 nicRxFillRFB (
1064     IN P_ADAPTER_T    prAdapter,
1065     IN OUT P_SW_RFB_T prSwRfb
1066     )
1067 {
1068     P_HIF_RX_HEADER_T prHifRxHdr;
1069
1070     UINT_32 u4PktLen = 0;
1071     UINT_32 u4MacHeaderLen;
1072     UINT_32 u4HeaderOffset;
1073
1074     DEBUGFUNC("nicRxFillRFB");
1075
1076     ASSERT(prAdapter);
1077     ASSERT(prSwRfb);
1078
1079     prHifRxHdr = prSwRfb->prHifRxHdr;
1080     ASSERT(prHifRxHdr);
1081
1082     u4PktLen= prHifRxHdr->u2PacketLen;
1083
1084     u4HeaderOffset = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_OFFSET_MASK);
1085     u4MacHeaderLen = (UINT_32)(prHifRxHdr->ucHerderLenOffset & HIF_RX_HDR_HEADER_LEN)
1086                     >> HIF_RX_HDR_HEADER_LEN_OFFSET;
1087
1088     //DBGLOG(RX, TRACE, ("u4HeaderOffset = %d, u4MacHeaderLen = %d\n",
1089     //    u4HeaderOffset, u4MacHeaderLen));
1090
1091     prSwRfb->u2HeaderLen = (UINT_16)u4MacHeaderLen;
1092     prSwRfb->pvHeader = (PUINT_8)prHifRxHdr + HIF_RX_HDR_SIZE + u4HeaderOffset;
1093     prSwRfb->u2PacketLen = (UINT_16)(u4PktLen - (HIF_RX_HDR_SIZE + u4HeaderOffset));
1094
1095     //DBGLOG(RX, TRACE, ("Dump Rx packet, u2PacketLen = %d\n", prSwRfb->u2PacketLen));
1096     //DBGLOG_MEM8(RX, TRACE, prSwRfb->pvHeader, prSwRfb->u2PacketLen);
1097
1098 #if 0
1099     if (prHifRxHdr->ucReorder & HIF_RX_HDR_80211_HEADER_FORMAT){
1100         prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_802_11_FORMAT;
1101         DBGLOG(RX, TRACE, ("HIF_RX_HDR_FLAG_802_11_FORMAT\n"));
1102     }
1103
1104     if (prHifRxHdr->ucReorder & HIF_RX_HDR_DO_REORDER){
1105         prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_DO_REORDERING;
1106         DBGLOG(RX, TRACE, ("HIF_RX_HDR_FLAG_DO_REORDERING\n"));
1107
1108         /* Get Seq. No and TID, Wlan Index info */
1109         if (prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_BAR_FRAME){
1110             prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_BAR_FRAME;
1111             DBGLOG(RX, TRACE, ("HIF_RX_HDR_FLAG_BAR_FRAME\n"));
1112         }
1113
1114         prSwRfb->u2SSN = prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_SEQ_NO_MASK;
1115         prSwRfb->ucTid = (UINT_8)((prHifRxHdr->u2SeqNoTid & HIF_RX_HDR_TID_MASK)
1116                         >> HIF_RX_HDR_TID_OFFSET);
1117         DBGLOG(RX, TRACE, ("u2SSN = %d, ucTid = %d\n",
1118             prSwRfb->u2SSN, prSwRfb->ucTid));
1119     }
1120
1121     if (prHifRxHdr->ucReorder & HIF_RX_HDR_WDS){
1122         prSwRfb->u4HifRxHdrFlag |= HIF_RX_HDR_FLAG_AMP_WDS;
1123         DBGLOG(RX, TRACE, ("HIF_RX_HDR_FLAG_AMP_WDS\n"));
1124     }
1125 #endif
1126 }
1127
1128
1129 #if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
1130 /*----------------------------------------------------------------------------*/
1131 /*!
1132 * @brief Fill checksum status in RFB
1133 *
1134 * @param prAdapter pointer to the Adapter handler
1135 * @param prSWRfb the RFB to receive rx data
1136 * @param u4TcpUdpIpCksStatus specify the Checksum status
1137 *
1138 * @return (none)
1139 *
1140 */
1141 /*----------------------------------------------------------------------------*/
1142 VOID
1143 nicRxFillChksumStatus(
1144     IN  P_ADAPTER_T   prAdapter,
1145     IN OUT P_SW_RFB_T prSwRfb,
1146     IN  UINT_32 u4TcpUdpIpCksStatus
1147 )
1148 {
1149
1150     ASSERT(prAdapter);
1151     ASSERT(prSwRfb);
1152
1153     if (prAdapter->u4CSUMFlags != CSUM_NOT_SUPPORTED){
1154         if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv4) { // IPv4 packet
1155             prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE;
1156             if(u4TcpUdpIpCksStatus & RX_CS_STATUS_IP) { //IP packet csum failed
1157                 prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_FAILED;
1158             } else {
1159                 prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_SUCCESS;
1160             }
1161
1162             if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { //TCP packet
1163                 prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
1164                 if(u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { //TCP packet csum failed
1165                     prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED;
1166                 } else {
1167                     prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS;
1168                 }
1169             }
1170             else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { //UDP packet
1171                 prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
1172                 if(u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { //UDP packet csum failed
1173                     prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED;
1174                 } else {
1175                     prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS;
1176                 }
1177             }
1178             else {
1179                 prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
1180                 prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
1181             }
1182         }
1183         else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_IPv6) {//IPv6 packet
1184             prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE;
1185             prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_SUCCESS;
1186
1187             if (u4TcpUdpIpCksStatus & RX_CS_TYPE_TCP) { //TCP packet
1188                 prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
1189                 if(u4TcpUdpIpCksStatus & RX_CS_STATUS_TCP) { //TCP packet csum failed
1190                     prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_FAILED;
1191                 } else {
1192                     prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_SUCCESS;
1193                 }
1194             }
1195             else if (u4TcpUdpIpCksStatus & RX_CS_TYPE_UDP) { //UDP packet
1196                 prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
1197                 if(u4TcpUdpIpCksStatus & RX_CS_STATUS_UDP) { //UDP packet csum failed
1198                     prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_FAILED;
1199                 } else {
1200                     prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_SUCCESS;
1201                 }
1202             }
1203             else {
1204                 prSwRfb->aeCSUM[CSUM_TYPE_UDP] = CSUM_RES_NONE;
1205                 prSwRfb->aeCSUM[CSUM_TYPE_TCP] = CSUM_RES_NONE;
1206             }
1207         }
1208         else {
1209             prSwRfb->aeCSUM[CSUM_TYPE_IPV4] = CSUM_RES_NONE;
1210             prSwRfb->aeCSUM[CSUM_TYPE_IPV6] = CSUM_RES_NONE;
1211         }
1212     }
1213
1214 }
1215 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
1216
1217
1218 /*----------------------------------------------------------------------------*/
1219 /*!
1220 * @brief Process packet doesn't need to do buffer reordering
1221 *
1222 * @param prAdapter pointer to the Adapter handler
1223 * @param prSWRfb the RFB to receive rx data
1224 *
1225 * @return (none)
1226 *
1227 */
1228 /*----------------------------------------------------------------------------*/
1229 VOID
1230 nicRxProcessPktWithoutReorder (
1231     IN P_ADAPTER_T prAdapter,
1232     IN P_SW_RFB_T  prSwRfb
1233     )
1234 {
1235     P_RX_CTRL_T prRxCtrl;
1236     P_TX_CTRL_T prTxCtrl;
1237     BOOL fgIsRetained = FALSE;
1238     UINT_32 u4CurrentRxBufferCount;
1239     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
1240
1241     DEBUGFUNC("nicRxProcessPktWithoutReorder");
1242     //DBGLOG(RX, TRACE, ("\n"));
1243
1244     ASSERT(prAdapter);
1245     ASSERT(prSwRfb);
1246
1247     prRxCtrl = &prAdapter->rRxCtrl;
1248     ASSERT(prRxCtrl);
1249
1250     prTxCtrl = &prAdapter->rTxCtrl;
1251     ASSERT(prTxCtrl);
1252
1253     u4CurrentRxBufferCount = prRxCtrl->rFreeSwRfbList.u4NumElem;
1254     /* QM USED = $A, AVAILABLE COUNT = $B, INDICATED TO OS = $C
1255      * TOTAL = $A + $B + $C
1256      *
1257      * Case #1 (Retain)
1258      * -------------------------------------------------------
1259      * $A + $B < THRESHOLD := $A + $B + $C < THRESHOLD + $C := $TOTAL - THRESHOLD < $C
1260      * => $C used too much, retain
1261      *
1262      * Case #2 (Non-Retain)
1263      * -------------------------------------------------------
1264      * $A + $B > THRESHOLD := $A + $B + $C > THRESHOLD + $C := $TOTAL - THRESHOLD > $C
1265      * => still availble for $C to use
1266      *
1267      */
1268     fgIsRetained = (((u4CurrentRxBufferCount +
1269                     qmGetRxReorderQueuedBufferCount(prAdapter) +
1270                     prTxCtrl->i4PendingFwdFrameCount) < CFG_RX_RETAINED_PKT_THRESHOLD) ?
1271                            TRUE : FALSE);
1272
1273     //DBGLOG(RX, INFO, ("fgIsRetained = %d\n", fgIsRetained));
1274
1275     if (kalProcessRxPacket(prAdapter->prGlueInfo,
1276                          prSwRfb->pvPacket,
1277                          prSwRfb->pvHeader,
1278                          (UINT_32)prSwRfb->u2PacketLen,
1279                          fgIsRetained,
1280                          prSwRfb->aeCSUM) != WLAN_STATUS_SUCCESS) {
1281         DBGLOG(RX, ERROR, ("kalProcessRxPacket return value != WLAN_STATUS_SUCCESS\n"));
1282         ASSERT(0);
1283
1284         nicRxReturnRFB(prAdapter, prSwRfb);
1285         return;
1286     }
1287     else {
1288         prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1289
1290         if (prStaRec) {
1291 #if CFG_ENABLE_WIFI_DIRECT
1292             if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX &&
1293                 prAdapter->fgIsP2PRegistered == TRUE) {
1294                 GLUE_SET_PKT_FLAG_P2P(prSwRfb->pvPacket);
1295             }
1296 #endif
1297 #if CFG_ENABLE_BT_OVER_WIFI
1298             if (prStaRec->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
1299                 GLUE_SET_PKT_FLAG_PAL(prSwRfb->pvPacket);
1300             }
1301 #endif
1302         }
1303         prRxCtrl->apvIndPacket[prRxCtrl->ucNumIndPacket] = prSwRfb->pvPacket;
1304         prRxCtrl->ucNumIndPacket++;
1305     }
1306
1307     if (fgIsRetained) {
1308         prRxCtrl->apvRetainedPacket[prRxCtrl->ucNumRetainedPacket] = prSwRfb->pvPacket;
1309         prRxCtrl->ucNumRetainedPacket++;
1310             /* TODO : error handling of nicRxSetupRFB */
1311         nicRxSetupRFB(prAdapter, prSwRfb);
1312         nicRxReturnRFB(prAdapter, prSwRfb);
1313     }
1314     else{
1315         prSwRfb->pvPacket = NULL;
1316         nicRxReturnRFB(prAdapter, prSwRfb);
1317     }
1318 }
1319
1320
1321 /*----------------------------------------------------------------------------*/
1322 /*!
1323 * @brief Process forwarding data packet
1324 *
1325 * @param prAdapter pointer to the Adapter handler
1326 * @param prSWRfb the RFB to receive rx data
1327 *
1328 * @return (none)
1329 *
1330 */
1331 /*----------------------------------------------------------------------------*/
1332 VOID
1333 nicRxProcessForwardPkt (
1334     IN P_ADAPTER_T prAdapter,
1335     IN P_SW_RFB_T  prSwRfb
1336     )
1337 {
1338     P_MSDU_INFO_T prMsduInfo, prRetMsduInfoList;
1339     P_TX_CTRL_T prTxCtrl;
1340     P_RX_CTRL_T prRxCtrl;
1341     KAL_SPIN_LOCK_DECLARATION();
1342
1343     DEBUGFUNC("nicRxProcessForwardPkt");
1344
1345     ASSERT(prAdapter);
1346     ASSERT(prSwRfb);
1347
1348     prTxCtrl = &prAdapter->rTxCtrl;
1349     prRxCtrl = &prAdapter->rRxCtrl;
1350
1351     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
1352     QUEUE_REMOVE_HEAD(&prTxCtrl->rFreeMsduInfoList, prMsduInfo, P_MSDU_INFO_T);
1353     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_MSDU_INFO_LIST);
1354
1355     if(prMsduInfo && kalProcessRxPacket(prAdapter->prGlueInfo,
1356                 prSwRfb->pvPacket,
1357                 prSwRfb->pvHeader,
1358                 (UINT_32)prSwRfb->u2PacketLen,
1359                 prRxCtrl->rFreeSwRfbList.u4NumElem < CFG_RX_RETAINED_PKT_THRESHOLD ? TRUE : FALSE,
1360                 prSwRfb->aeCSUM) == WLAN_STATUS_SUCCESS) {
1361
1362         prMsduInfo->eSrc = TX_PACKET_FORWARDING;
1363         // pack into MSDU_INFO_T
1364         nicTxFillMsduInfo(prAdapter, prMsduInfo, (P_NATIVE_PACKET)(prSwRfb->pvPacket));
1365         // Overwrite the ucNetworkType
1366         prMsduInfo->ucNetworkType = HIF_RX_HDR_GET_NETWORK_IDX(prSwRfb->prHifRxHdr);
1367
1368         // release RX buffer (to rIndicatedRfbList)
1369         prSwRfb->pvPacket = NULL;
1370         nicRxReturnRFB(prAdapter, prSwRfb);
1371
1372         // increase forward frame counter
1373         GLUE_INC_REF_CNT(prTxCtrl->i4PendingFwdFrameCount);
1374
1375         // send into TX queue
1376         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
1377         prRetMsduInfoList = qmEnqueueTxPackets(prAdapter, prMsduInfo);
1378         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_QM_TX_QUEUE);
1379
1380         if(prRetMsduInfoList != NULL) { // TX queue refuses queuing the packet
1381             nicTxFreeMsduInfoPacket(prAdapter, prRetMsduInfoList);
1382             nicTxReturnMsduInfo(prAdapter, prRetMsduInfoList);
1383         }
1384         /* indicate service thread for sending */
1385         if(prTxCtrl->i4PendingFwdFrameCount > 0) {
1386             kalSetEvent(prAdapter->prGlueInfo);
1387         }
1388     }
1389     else { // no TX resource
1390         nicRxReturnRFB(prAdapter, prSwRfb);
1391     }
1392
1393     return;
1394 }
1395
1396
1397 /*----------------------------------------------------------------------------*/
1398 /*!
1399 * @brief Process broadcast data packet for both host and forwarding
1400 *
1401 * @param prAdapter pointer to the Adapter handler
1402 * @param prSWRfb the RFB to receive rx data
1403 *
1404 * @return (none)
1405 *
1406 */
1407 /*----------------------------------------------------------------------------*/
1408 VOID
1409 nicRxProcessGOBroadcastPkt (
1410     IN P_ADAPTER_T prAdapter,
1411     IN P_SW_RFB_T  prSwRfb
1412     )
1413 {
1414     P_SW_RFB_T prSwRfbDuplicated;
1415     P_TX_CTRL_T prTxCtrl;
1416     P_RX_CTRL_T prRxCtrl;
1417     P_HIF_RX_HEADER_T prHifRxHdr;
1418
1419     KAL_SPIN_LOCK_DECLARATION();
1420
1421     DEBUGFUNC("nicRxProcessGOBroadcastPkt");
1422
1423     ASSERT(prAdapter);
1424     ASSERT(prSwRfb);
1425
1426     prTxCtrl = &prAdapter->rTxCtrl;
1427     prRxCtrl = &prAdapter->rRxCtrl;
1428
1429     prHifRxHdr = prSwRfb->prHifRxHdr;
1430     ASSERT(prHifRxHdr);
1431
1432     ASSERT(CFG_NUM_OF_QM_RX_PKT_NUM >= 16);
1433
1434     if( prRxCtrl->rFreeSwRfbList.u4NumElem
1435                     >= (CFG_RX_MAX_PKT_NUM - (CFG_NUM_OF_QM_RX_PKT_NUM - 16 /* Reserved for others */) )  ) {
1436
1437         /* 1. Duplicate SW_RFB_T */
1438         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1439         QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfbDuplicated, P_SW_RFB_T);
1440         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
1441
1442         if(prSwRfbDuplicated){
1443             kalMemCopy(prSwRfbDuplicated->pucRecvBuff,
1444                     prSwRfb->pucRecvBuff,
1445                     ALIGN_4(prHifRxHdr->u2PacketLen + HIF_RX_HW_APPENDED_LEN));
1446
1447             prSwRfbDuplicated->ucPacketType = HIF_RX_PKT_TYPE_DATA;
1448             prSwRfbDuplicated->ucStaRecIdx = (UINT_8)(prHifRxHdr->ucStaRecIdx);
1449             nicRxFillRFB(prAdapter, prSwRfbDuplicated);
1450
1451             /* 2. Modify eDst */
1452             prSwRfbDuplicated->eDst = RX_PKT_DESTINATION_FORWARD;
1453
1454             /* 4. Forward */
1455             nicRxProcessForwardPkt(prAdapter, prSwRfbDuplicated);
1456         }
1457     }
1458     else {
1459         DBGLOG(RX, WARN, ("Stop to forward BMC packet due to less free Sw Rfb %u\n", prRxCtrl->rFreeSwRfbList.u4NumElem));
1460     }
1461
1462     /* 3. Indicate to host */
1463     prSwRfb->eDst = RX_PKT_DESTINATION_HOST;
1464     nicRxProcessPktWithoutReorder(prAdapter, prSwRfb);
1465
1466     return;
1467 }
1468
1469
1470 /*----------------------------------------------------------------------------*/
1471 /*!
1472 * @brief Process HIF data packet
1473 *
1474 * @param prAdapter pointer to the Adapter handler
1475 * @param prSWRfb the RFB to receive rx data
1476 *
1477 * @return (none)
1478 *
1479 */
1480 /*----------------------------------------------------------------------------*/
1481 VOID
1482 nicRxProcessDataPacket (
1483     IN P_ADAPTER_T    prAdapter,
1484     IN OUT P_SW_RFB_T prSwRfb
1485     )
1486 {
1487     P_RX_CTRL_T prRxCtrl;
1488     P_SW_RFB_T prRetSwRfb, prNextSwRfb;
1489     P_HIF_RX_HEADER_T prHifRxHdr;
1490     P_STA_RECORD_T prStaRec;
1491
1492     DEBUGFUNC("nicRxProcessDataPacket");
1493     //DBGLOG(INIT, TRACE, ("\n"));
1494
1495     ASSERT(prAdapter);
1496     ASSERT(prSwRfb);
1497
1498     prHifRxHdr = prSwRfb->prHifRxHdr;
1499     prRxCtrl = &prAdapter->rRxCtrl;
1500
1501     nicRxFillRFB(prAdapter, prSwRfb);
1502
1503 #if 1 /* Check 1x Pkt */
1504     if (prSwRfb->u2PacketLen > 14) {
1505         PUINT_8 pc = (PUINT_8)prSwRfb->pvHeader;
1506         UINT_16 u2Etype = 0;
1507
1508         u2Etype = (pc[ETH_TYPE_LEN_OFFSET] << 8) | (pc[ETH_TYPE_LEN_OFFSET + 1]);
1509
1510 #if CFG_SUPPORT_WAPI
1511         if (u2Etype == ETH_P_1X || u2Etype == ETH_WPI_1X) {
1512             DBGLOG(RSN, INFO, ("R1X len=%d\n", prSwRfb->u2PacketLen));
1513         }
1514 #else
1515         if (u2Etype == ETH_P_1X) {
1516             DBGLOG(RSN, INFO, ("R1X len=%d\n", prSwRfb->u2PacketLen));
1517         }
1518 #endif
1519         else if (u2Etype == ETH_P_PRE_1X) {
1520             DBGLOG(RSN, INFO, ("Pre R1X len=%d\n", prSwRfb->u2PacketLen));
1521         }
1522     }
1523 #endif
1524
1525 #if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
1526     {
1527         UINT_32 u4TcpUdpIpCksStatus;
1528
1529         u4TcpUdpIpCksStatus = *((PUINT_32)((UINT_32)prHifRxHdr +
1530                 (UINT_32)(ALIGN_4(prHifRxHdr->u2PacketLen))));
1531         nicRxFillChksumStatus(prAdapter, prSwRfb, u4TcpUdpIpCksStatus);
1532
1533     }
1534 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
1535
1536     prStaRec = cnmGetStaRecByIndex(prAdapter, prHifRxHdr->ucStaRecIdx);
1537     if(secCheckClassError(prAdapter, prSwRfb, prStaRec) == TRUE &&
1538          prAdapter->fgTestMode == FALSE) {
1539 #if CFG_HIF_RX_STARVATION_WARNING
1540         prRxCtrl->u4QueuedCnt++;
1541 #endif
1542
1543         if((prRetSwRfb = qmHandleRxPackets(prAdapter, prSwRfb)) != NULL) {
1544             do {
1545                 // save next first
1546                 prNextSwRfb = (P_SW_RFB_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prRetSwRfb);
1547
1548                 switch(prRetSwRfb->eDst) {
1549                 case RX_PKT_DESTINATION_HOST:
1550                     nicRxProcessPktWithoutReorder(prAdapter, prRetSwRfb);
1551                     break;
1552
1553                 case RX_PKT_DESTINATION_FORWARD:
1554                     nicRxProcessForwardPkt(prAdapter, prRetSwRfb);
1555                     break;
1556
1557                 case RX_PKT_DESTINATION_HOST_WITH_FORWARD:
1558                     nicRxProcessGOBroadcastPkt(prAdapter, prRetSwRfb);
1559                     break;
1560
1561                 case RX_PKT_DESTINATION_NULL:
1562                     nicRxReturnRFB(prAdapter, prRetSwRfb);
1563                     RX_INC_CNT(prRxCtrl, RX_DST_NULL_DROP_COUNT);
1564                     RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
1565                     break;
1566
1567                 default:
1568                     break;
1569                 }
1570 #if CFG_HIF_RX_STARVATION_WARNING
1571                 prRxCtrl->u4DequeuedCnt++;
1572 #endif
1573                 prRetSwRfb = prNextSwRfb;
1574             } while(prRetSwRfb);
1575         }
1576     }
1577     else {
1578         nicRxReturnRFB(prAdapter, prSwRfb);
1579         RX_INC_CNT(prRxCtrl, RX_CLASS_ERR_DROP_COUNT);
1580         RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
1581     }
1582 }
1583
1584
1585 /*----------------------------------------------------------------------------*/
1586 /*!
1587 * @brief Process HIF event packet
1588 *
1589 * @param prAdapter pointer to the Adapter handler
1590 * @param prSWRfb the RFB to receive rx data
1591 *
1592 * @return (none)
1593 *
1594 */
1595 /*----------------------------------------------------------------------------*/
1596 VOID
1597 nicRxProcessEventPacket (
1598     IN P_ADAPTER_T    prAdapter,
1599     IN OUT P_SW_RFB_T prSwRfb
1600     )
1601 {
1602     P_CMD_INFO_T prCmdInfo;
1603     P_MSDU_INFO_T prMsduInfo;
1604     P_WIFI_EVENT_T prEvent;
1605     P_GLUE_INFO_T prGlueInfo;
1606
1607     DEBUGFUNC("nicRxProcessEventPacket");
1608     //DBGLOG(INIT, TRACE, ("\n"));
1609
1610     ASSERT(prAdapter);
1611     ASSERT(prSwRfb);
1612
1613     prEvent = (P_WIFI_EVENT_T) prSwRfb->pucRecvBuff;
1614     prGlueInfo = prAdapter->prGlueInfo;
1615
1616     // Event Handling
1617     switch(prEvent->ucEID) {
1618     case EVENT_ID_CMD_RESULT:
1619         prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
1620
1621         if(prCmdInfo != NULL) {
1622             P_EVENT_CMD_RESULT prCmdResult;
1623             prCmdResult = (P_EVENT_CMD_RESULT) ((PUINT_8)prEvent + EVENT_HDR_SIZE);
1624
1625             /* CMD_RESULT should be only in response to Set commands */
1626             ASSERT(prCmdInfo->fgSetQuery == FALSE || prCmdInfo->fgNeedResp == TRUE);
1627
1628             if(prCmdResult->ucStatus == 0) { // success
1629                 if(prCmdInfo->pfCmdDoneHandler) {
1630                     prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
1631                 }
1632                 else if(prCmdInfo->fgIsOid == TRUE) {
1633                     kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
1634                 }
1635             }
1636             else if(prCmdResult->ucStatus == 1) { // reject
1637                 if(prCmdInfo->fgIsOid == TRUE)
1638                     kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_FAILURE);
1639             }
1640             else if(prCmdResult->ucStatus == 2) { // unknown CMD
1641                 if(prCmdInfo->fgIsOid == TRUE)
1642                     kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_NOT_SUPPORTED);
1643             }
1644
1645             // return prCmdInfo
1646             cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
1647         }
1648
1649         break;
1650
1651 #if 0
1652     case EVENT_ID_CONNECTION_STATUS:
1653         /* OBSELETE */
1654         {
1655             P_EVENT_CONNECTION_STATUS prConnectionStatus;
1656             prConnectionStatus = (P_EVENT_CONNECTION_STATUS) (prEvent->aucBuffer);
1657
1658             DbgPrint("RX EVENT: EVENT_ID_CONNECTION_STATUS = %d\n", prConnectionStatus->ucMediaStatus);
1659             if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { // disconnected
1660                 if(kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) {
1661
1662                     kalIndicateStatusAndComplete(prGlueInfo,
1663                             WLAN_STATUS_MEDIA_DISCONNECT,
1664                             NULL,
1665                             0);
1666
1667                     prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
1668                 }
1669             }
1670             else if(prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { // connected
1671                 prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
1672
1673                 // fill information for association result
1674                 prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen
1675                     = prConnectionStatus->ucSsidLen;
1676                 kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
1677                         prConnectionStatus->aucSsid,
1678                         prConnectionStatus->ucSsidLen);
1679
1680                 kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
1681                         prConnectionStatus->aucBssid,
1682                         MAC_ADDR_LEN);
1683
1684                 prAdapter->rWlanInfo.rCurrBssId.u4Privacy
1685                     = prConnectionStatus->ucEncryptStatus; // @FIXME
1686                 prAdapter->rWlanInfo.rCurrBssId.rRssi
1687                     = 0; //@FIXME
1688                 prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse
1689                     = PARAM_NETWORK_TYPE_AUTOMODE; //@FIXME
1690                 prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod
1691                     = prConnectionStatus->u2BeaconPeriod;
1692                 prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow
1693                     = prConnectionStatus->u2ATIMWindow;
1694                 prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig
1695                     = prConnectionStatus->u4FreqInKHz;
1696                 prAdapter->rWlanInfo.ucNetworkType
1697                     = prConnectionStatus->ucNetworkType;
1698
1699                 switch(prConnectionStatus->ucInfraMode) {
1700                 case 0:
1701                     prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_IBSS;
1702                     break;
1703                 case 1:
1704                     prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_INFRA;
1705                     break;
1706                 case 2:
1707                 default:
1708                     prAdapter->rWlanInfo.rCurrBssId.eOpMode = NET_TYPE_AUTO_SWITCH;
1709                     break;
1710                 }
1711                 // always indicate to OS according to MSDN (re-association/roaming)
1712                 kalIndicateStatusAndComplete(prGlueInfo,
1713                         WLAN_STATUS_MEDIA_CONNECT,
1714                         NULL,
1715                         0);
1716             }
1717         }
1718         break;
1719
1720     case EVENT_ID_SCAN_RESULT:
1721         /* OBSELETE */
1722         break;
1723 #endif
1724
1725     case EVENT_ID_RX_ADDBA:
1726         /* The FW indicates that an RX BA agreement will be established */
1727         qmHandleEventRxAddBa(prAdapter, prEvent);
1728         break;
1729
1730     case EVENT_ID_RX_DELBA:
1731         /* The FW indicates that an RX BA agreement has been deleted */
1732         qmHandleEventRxDelBa(prAdapter, prEvent);
1733         break;
1734
1735     case EVENT_ID_LINK_QUALITY:
1736 #if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY
1737         if (prEvent->u2PacketLen == EVENT_HDR_SIZE + sizeof(EVENT_LINK_QUALITY_EX)) {
1738             P_EVENT_LINK_QUALITY_EX prLqEx = (P_EVENT_LINK_QUALITY_EX)(prEvent->aucBuffer);
1739
1740             if (prLqEx->ucIsLQ0Rdy) {
1741                 nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY)prLqEx);
1742             }
1743
1744
1745             if (prLqEx->ucIsLQ1Rdy) {
1746                 nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_P2P_INDEX, (P_EVENT_LINK_QUALITY)prLqEx);
1747             }
1748         }
1749         else {
1750             /* For old FW, P2P may invoke link quality query, and make driver flag becone TRUE. */
1751             DBGLOG(P2P, WARN, ("Old FW version, not support P2P RSSI query.\n"));
1752
1753             /* Must not use NETWORK_TYPE_P2P_INDEX, cause the structure is mismatch. */
1754         nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY)(prEvent->aucBuffer));
1755         }
1756
1757 #else
1758         nicUpdateLinkQuality(prAdapter, NETWORK_TYPE_AIS_INDEX, (P_EVENT_LINK_QUALITY)(prEvent->aucBuffer));
1759 #endif
1760
1761         /* command response handling */
1762         prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
1763
1764         if(prCmdInfo != NULL) {
1765             if (prCmdInfo->pfCmdDoneHandler) {
1766                 prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
1767             }
1768             else if(prCmdInfo->fgIsOid) {
1769                 kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
1770             }
1771
1772             // return prCmdInfo
1773             cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
1774         }
1775
1776         #ifndef LINUX
1777         if(prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_GREATER &&
1778                 prAdapter->rWlanInfo.rRssiTriggerValue >= (PARAM_RSSI)(prAdapter->rLinkQuality.cRssi)) {
1779             prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED;
1780
1781             kalIndicateStatusAndComplete(prGlueInfo,
1782                     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1783                     (PVOID) &(prAdapter->rWlanInfo.rRssiTriggerValue), sizeof(PARAM_RSSI));
1784         }
1785         else if(prAdapter->rWlanInfo.eRssiTriggerType == ENUM_RSSI_TRIGGER_LESS &&
1786                 prAdapter->rWlanInfo.rRssiTriggerValue <= (PARAM_RSSI)(prAdapter->rLinkQuality.cRssi)) {
1787             prAdapter->rWlanInfo.eRssiTriggerType = ENUM_RSSI_TRIGGER_TRIGGERED;
1788
1789             kalIndicateStatusAndComplete(prGlueInfo,
1790                     WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1791                     (PVOID) &(prAdapter->rWlanInfo.rRssiTriggerValue), sizeof(PARAM_RSSI));
1792         }
1793         #endif
1794
1795         break;
1796
1797     case EVENT_ID_MIC_ERR_INFO:
1798         {
1799             P_EVENT_MIC_ERR_INFO prMicError;
1800             //P_PARAM_AUTH_EVENT_T prAuthEvent;
1801             P_STA_RECORD_T prStaRec;
1802
1803             DBGLOG(RSN, EVENT, ("EVENT_ID_MIC_ERR_INFO\n"));
1804
1805             prMicError = (P_EVENT_MIC_ERR_INFO)(prEvent->aucBuffer);
1806             prStaRec = cnmGetStaRecByAddress(prAdapter,
1807                             (UINT_8) NETWORK_TYPE_AIS_INDEX,
1808                             prAdapter->rWlanInfo.rCurrBssId.arMacAddress);
1809             ASSERT(prStaRec);
1810
1811             if (prStaRec) {
1812                 rsnTkipHandleMICFailure(prAdapter, prStaRec, (BOOLEAN)prMicError->u4Flags);
1813             }
1814             else {
1815                 DBGLOG(RSN, INFO, ("No STA rec!!\n"));
1816             }
1817 #if 0
1818             prAuthEvent = (P_PARAM_AUTH_EVENT_T)prAdapter->aucIndicationEventBuffer;
1819
1820             /* Status type: Authentication Event */
1821             prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_AUTHENTICATION;
1822
1823             /* Authentication request */
1824             prAuthEvent->arRequest[0].u4Length = sizeof(PARAM_AUTH_REQUEST_T);
1825             kalMemCopy((PVOID)prAuthEvent->arRequest[0].arBssid,
1826                 (PVOID)prAdapter->rWlanInfo.rCurrBssId.arMacAddress, /* whsu:Todo? */
1827                 PARAM_MAC_ADDR_LEN);
1828
1829             if (prMicError->u4Flags != 0) {
1830                 prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_GROUP_ERROR;
1831             }
1832             else {
1833                 prAuthEvent->arRequest[0].u4Flags = PARAM_AUTH_REQUEST_PAIRWISE_ERROR;
1834             }
1835
1836             kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1837                 WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1838                 (PVOID)prAuthEvent,
1839                 sizeof(PARAM_STATUS_INDICATION_T) + sizeof(PARAM_AUTH_REQUEST_T));
1840 #endif
1841         }
1842         break;
1843
1844     case EVENT_ID_ASSOC_INFO:
1845         {
1846             P_EVENT_ASSOC_INFO prAssocInfo;
1847             prAssocInfo = (P_EVENT_ASSOC_INFO)(prEvent->aucBuffer);
1848
1849             kalHandleAssocInfo(prAdapter->prGlueInfo, prAssocInfo);
1850         }
1851         break;
1852
1853     case EVENT_ID_802_11_PMKID:
1854         {
1855             P_PARAM_AUTH_EVENT_T           prAuthEvent;
1856             PUINT_8                        cp;
1857             UINT_32                        u4LenOfUsedBuffer;
1858
1859             prAuthEvent = (P_PARAM_AUTH_EVENT_T)prAdapter->aucIndicationEventBuffer;
1860
1861             prAuthEvent->rStatus.eStatusType = ENUM_STATUS_TYPE_CANDIDATE_LIST;
1862
1863             u4LenOfUsedBuffer = (UINT_32)(prEvent->u2PacketLen - 8);
1864
1865             prAuthEvent->arRequest[0].u4Length = u4LenOfUsedBuffer;
1866
1867             cp = (PUINT_8)&prAuthEvent->arRequest[0];
1868
1869             /* Status type: PMKID Candidatelist Event */
1870             kalMemCopy(cp, (P_EVENT_PMKID_CANDIDATE_LIST_T)(prEvent->aucBuffer), prEvent->u2PacketLen - 8);
1871
1872             kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
1873                 WLAN_STATUS_MEDIA_SPECIFIC_INDICATION,
1874                 (PVOID)prAuthEvent,
1875                 sizeof(PARAM_STATUS_INDICATION_T) + u4LenOfUsedBuffer);
1876         }
1877         break;
1878
1879 #if 0
1880     case EVENT_ID_ACTIVATE_STA_REC_T:
1881         {
1882             P_EVENT_ACTIVATE_STA_REC_T prActivateStaRec;
1883             prActivateStaRec = (P_EVENT_ACTIVATE_STA_REC_T)(prEvent->aucBuffer);
1884
1885             DbgPrint("RX EVENT: EVENT_ID_ACTIVATE_STA_REC_T Index:%d, MAC:["MACSTR"]\n",
1886                 prActivateStaRec->ucStaRecIdx,
1887                 MAC2STR(prActivateStaRec->aucMacAddr));
1888
1889             qmActivateStaRec(prAdapter,
1890                              (UINT_32)prActivateStaRec->ucStaRecIdx,
1891                              ((prActivateStaRec->fgIsQoS) ? TRUE: FALSE),
1892                              prActivateStaRec->ucNetworkTypeIndex,
1893                              ((prActivateStaRec->fgIsAP) ? TRUE: FALSE),
1894                              prActivateStaRec->aucMacAddr);
1895
1896         }
1897         break;
1898
1899     case EVENT_ID_DEACTIVATE_STA_REC_T:
1900         {
1901             P_EVENT_DEACTIVATE_STA_REC_T prDeactivateStaRec;
1902             prDeactivateStaRec = (P_EVENT_DEACTIVATE_STA_REC_T)(prEvent->aucBuffer);
1903
1904             DbgPrint("RX EVENT: EVENT_ID_DEACTIVATE_STA_REC_T Index:%d, MAC:["MACSTR"]\n",
1905                 prDeactivateStaRec->ucStaRecIdx);
1906
1907             qmDeactivateStaRec(prAdapter,
1908                                prDeactivateStaRec->ucStaRecIdx);
1909         }
1910         break;
1911 #endif
1912
1913     case EVENT_ID_SCAN_DONE:
1914         scnEventScanDone(prAdapter, (P_EVENT_SCAN_DONE)(prEvent->aucBuffer));
1915         break;
1916
1917     case EVENT_ID_TX_DONE:
1918         {
1919             P_EVENT_TX_DONE_T prTxDone;
1920             prTxDone = (P_EVENT_TX_DONE_T)(prEvent->aucBuffer);
1921
1922             DBGLOG(INIT, TRACE,("EVENT_ID_TX_DONE PacketSeq:%u ucStatus: %u SN: %u\n",
1923                 prTxDone->ucPacketSeq, prTxDone->ucStatus, prTxDone->u2SequenceNumber));
1924
1925             /* call related TX Done Handler */
1926             prMsduInfo = nicGetPendingTxMsduInfo(prAdapter, prTxDone->ucPacketSeq);
1927
1928             if(prMsduInfo) {
1929                 prMsduInfo->pfTxDoneHandler(prAdapter, prMsduInfo, (ENUM_TX_RESULT_CODE_T)(prTxDone->ucStatus));
1930
1931                 cnmMgtPktFree(prAdapter, prMsduInfo);
1932             }
1933         }
1934         break;
1935
1936     case EVENT_ID_SLEEPY_NOTIFY:
1937         {
1938             P_EVENT_SLEEPY_NOTIFY prEventSleepyNotify;
1939             prEventSleepyNotify = (P_EVENT_SLEEPY_NOTIFY)(prEvent->aucBuffer);
1940
1941             //DBGLOG(RX, INFO, ("ucSleepyState = %d\n", prEventSleepyNotify->ucSleepyState));
1942
1943             prAdapter->fgWiFiInSleepyState = (BOOLEAN)(prEventSleepyNotify->ucSleepyState);
1944         }
1945         break;
1946     case EVENT_ID_BT_OVER_WIFI:
1947 #if CFG_ENABLE_BT_OVER_WIFI
1948         {
1949             UINT_8 aucTmp[sizeof(AMPC_EVENT) + sizeof(BOW_LINK_DISCONNECTED)];
1950             P_EVENT_BT_OVER_WIFI prEventBtOverWifi;
1951             P_AMPC_EVENT prBowEvent;
1952             P_BOW_LINK_CONNECTED prBowLinkConnected;
1953             P_BOW_LINK_DISCONNECTED prBowLinkDisconnected;
1954
1955             prEventBtOverWifi = (P_EVENT_BT_OVER_WIFI)(prEvent->aucBuffer);
1956
1957             // construct event header
1958             prBowEvent = (P_AMPC_EVENT)aucTmp;
1959
1960             if(prEventBtOverWifi->ucLinkStatus == 0) {
1961                 // Connection
1962                 prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_CONNECTED;
1963                 prBowEvent->rHeader.ucSeqNumber = 0;
1964                 prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_CONNECTED);
1965
1966                 // fill event body
1967                 prBowLinkConnected = (P_BOW_LINK_CONNECTED)(prBowEvent->aucPayload);
1968                 prBowLinkConnected->rChannel.ucChannelNum = prEventBtOverWifi->ucSelectedChannel;
1969                 kalMemZero(prBowLinkConnected->aucPeerAddress, MAC_ADDR_LEN); //@FIXME
1970
1971                 kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent);
1972             }
1973             else {
1974                 // Disconnection
1975                 prBowEvent->rHeader.ucEventId = BOW_EVENT_ID_LINK_DISCONNECTED;
1976                 prBowEvent->rHeader.ucSeqNumber = 0;
1977                 prBowEvent->rHeader.u2PayloadLength = sizeof(BOW_LINK_DISCONNECTED);
1978
1979                 // fill event body
1980                 prBowLinkDisconnected = (P_BOW_LINK_DISCONNECTED)(prBowEvent->aucPayload);
1981                 prBowLinkDisconnected->ucReason = 0; //@FIXME
1982                 kalMemZero(prBowLinkDisconnected->aucPeerAddress, MAC_ADDR_LEN); //@FIXME
1983
1984                 kalIndicateBOWEvent(prAdapter->prGlueInfo, prBowEvent);
1985             }
1986         }
1987         break;
1988 #endif
1989     case EVENT_ID_STATISTICS:
1990         /* buffer statistics for further query */
1991         prAdapter->fgIsStatValid = TRUE;
1992         prAdapter->rStatUpdateTime = kalGetTimeTick();
1993         kalMemCopy(&prAdapter->rStatStruct, prEvent->aucBuffer, sizeof(EVENT_STATISTICS));
1994
1995         /* command response handling */
1996         prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
1997
1998         if(prCmdInfo != NULL) {
1999             if (prCmdInfo->pfCmdDoneHandler) {
2000                 prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
2001             }
2002             else if(prCmdInfo->fgIsOid) {
2003                 kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
2004             }
2005
2006             // return prCmdInfo
2007             cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
2008         }
2009
2010         break;
2011
2012     case EVENT_ID_CH_PRIVILEGE:
2013         cnmChMngrHandleChEvent(prAdapter, prEvent);
2014         break;
2015
2016     case EVENT_ID_BSS_ABSENCE_PRESENCE:
2017         qmHandleEventBssAbsencePresence(prAdapter, prEvent);
2018         break;
2019
2020     case EVENT_ID_STA_CHANGE_PS_MODE:
2021         qmHandleEventStaChangePsMode(prAdapter, prEvent);
2022         break;
2023 #if CFG_ENABLE_WIFI_DIRECT
2024     case EVENT_ID_STA_UPDATE_FREE_QUOTA:
2025         qmHandleEventStaUpdateFreeQuota(prAdapter, prEvent);
2026         break;
2027 #endif
2028     case EVENT_ID_BSS_BEACON_TIMEOUT:
2029         DBGLOG(INIT, INFO,("EVENT_ID_BSS_BEACON_TIMEOUT\n"));
2030
2031         if (prAdapter->fgDisBcnLostDetection == FALSE) {
2032             P_EVENT_BSS_BEACON_TIMEOUT_T prEventBssBeaconTimeout;
2033             prEventBssBeaconTimeout = (P_EVENT_BSS_BEACON_TIMEOUT_T)(prEvent->aucBuffer);
2034
2035             if(prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2036                 aisBssBeaconTimeout(prAdapter);
2037             }
2038 #if CFG_ENABLE_WIFI_DIRECT
2039             else if((prAdapter->fgIsP2PRegistered) &&
2040                 (prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX)) {
2041
2042                 prAdapter->rP2pFuncLkr.prP2pFsmRunEventBeaconTimeout(prAdapter);
2043             }
2044 #endif
2045 #if CFG_ENABLE_BT_OVER_WIFI
2046             else if(prEventBssBeaconTimeout->ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
2047             }
2048 #endif
2049             else {
2050                 DBGLOG(RX, ERROR, ("EVENT_ID_BSS_BEACON_TIMEOUT: (ucNetTypeIdx = %d)\n",
2051                             prEventBssBeaconTimeout->ucNetTypeIndex));
2052             }
2053         }
2054
2055         break;
2056     case EVENT_ID_UPDATE_NOA_PARAMS:
2057 #if CFG_ENABLE_WIFI_DIRECT
2058         if(prAdapter->fgIsP2PRegistered){
2059             P_EVENT_UPDATE_NOA_PARAMS_T prEventUpdateNoaParam;
2060             prEventUpdateNoaParam = (P_EVENT_UPDATE_NOA_PARAMS_T)(prEvent->aucBuffer);
2061
2062             if (prEventUpdateNoaParam->ucNetTypeIndex == NETWORK_TYPE_P2P_INDEX) {
2063                 prAdapter->rP2pFuncLkr.prP2pProcessEvent_UpdateNOAParam(prAdapter,
2064                                                 prEventUpdateNoaParam->ucNetTypeIndex,
2065                                                 prEventUpdateNoaParam);
2066             } else {
2067                 ASSERT(0);
2068             }
2069         }
2070 #else
2071         ASSERT(0);
2072 #endif
2073         break;
2074
2075     case EVENT_ID_STA_AGING_TIMEOUT:
2076 #if CFG_ENABLE_WIFI_DIRECT
2077         {
2078             P_EVENT_STA_AGING_TIMEOUT_T prEventStaAgingTimeout;
2079             P_STA_RECORD_T prStaRec;
2080             P_BSS_INFO_T prBssInfo = (P_BSS_INFO_T)NULL;
2081
2082             prEventStaAgingTimeout = (P_EVENT_STA_AGING_TIMEOUT_T)(prEvent->aucBuffer);
2083             prStaRec = cnmGetStaRecByIndex(prAdapter, prEventStaAgingTimeout->ucStaRecIdx);
2084             if (prStaRec == NULL) {
2085                 break;
2086             }
2087
2088
2089                 DBGLOG(INIT, INFO,("EVENT_ID_STA_AGING_TIMEOUT %u " MACSTR "\n",
2090                             prEventStaAgingTimeout->ucStaRecIdx, MAC2STR(prStaRec->aucMacAddr)));
2091             prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
2092
2093             /* Call False Auth */
2094             if(prAdapter->fgIsP2PRegistered){
2095                 if(prAdapter->rP2pFuncLkr.prP2pFuncDisconnect) {
2096                     prAdapter->rP2pFuncLkr.prP2pFuncDisconnect(prAdapter, prStaRec, TRUE, REASON_CODE_DISASSOC_INACTIVITY);
2097                 }
2098             }
2099
2100             bssRemoveStaRecFromClientList(prAdapter, prBssInfo, prStaRec);
2101         }
2102 #endif
2103         break;
2104
2105     case EVENT_ID_AP_OBSS_STATUS:
2106 #if CFG_ENABLE_WIFI_DIRECT
2107         if(prAdapter->fgIsP2PRegistered){
2108             ASSERT(prAdapter->rP2pFuncLkr.prRlmHandleObssStatusEventPkt);
2109             prAdapter->rP2pFuncLkr.prRlmHandleObssStatusEventPkt(
2110                 prAdapter,
2111                 (P_EVENT_AP_OBSS_STATUS_T) prEvent->aucBuffer);
2112         }
2113 #endif
2114         break;
2115
2116     case EVENT_ID_ROAMING_STATUS:
2117 #if CFG_SUPPORT_ROAMING
2118         {
2119             P_ROAMING_PARAM_T prParam;
2120
2121             prParam = (P_ROAMING_PARAM_T)(prEvent->aucBuffer);
2122             roamingFsmProcessEvent(prAdapter, prParam);
2123         }
2124 #endif /* CFG_SUPPORT_ROAMING */
2125         break;
2126 #if 0 // CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_ANTI_PIRACY
2127     case EVENT_ID_SEC_CHECK_RSP:
2128         if(prAdapter->fgIsP2PRegistered){
2129             ASSERT(prAdapter->rP2pFuncLkr.prP2pHandleSecCheckRsp);
2130
2131             prAdapter->rP2pFuncLkr.prP2pHandleSecCheckRsp(
2132                 prAdapter,
2133                 (PUINT_8) prEvent->aucBuffer,
2134                 prEvent->u2PacketLen - EVENT_HDR_SIZE);
2135
2136             /* command response handling */
2137             prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
2138
2139             if(prCmdInfo != NULL) {
2140                 if (prCmdInfo->pfCmdDoneHandler) {
2141                     prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
2142                 }
2143                 else if(prCmdInfo->fgIsOid) {
2144                     kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
2145                 }
2146
2147                 // return prCmdInfo
2148                 cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
2149             }
2150         }
2151         break;
2152 #endif
2153     case EVENT_ID_SEND_DEAUTH:
2154 #if DBG
2155         {
2156             P_WLAN_MAC_HEADER_T prWlanMacHeader;
2157
2158             prWlanMacHeader = (P_WLAN_MAC_HEADER_T)&prEvent->aucBuffer[0];
2159             DBGLOG(RX, INFO, ("nicRx: aucAddr1: "MACSTR"\n", MAC2STR(prWlanMacHeader->aucAddr1)));
2160             DBGLOG(RX, INFO, ("nicRx: aucAddr2: "MACSTR"\n", MAC2STR(prWlanMacHeader->aucAddr2)));
2161         }
2162 #endif
2163           /* receive packets without StaRec */
2164           prSwRfb->pvHeader = (P_WLAN_MAC_HEADER_T)&prEvent->aucBuffer[0];
2165           if (WLAN_STATUS_SUCCESS == authSendDeauthFrame(prAdapter,
2166                                                        NULL,
2167                                                        prSwRfb,
2168                                                        REASON_CODE_CLASS_3_ERR,
2169                                                        (PFN_TX_DONE_HANDLER)NULL)) {
2170             DBGLOG(RX, INFO, ("Send Deauth Error\n"));
2171         }
2172           break;
2173
2174 #if CFG_SUPPORT_RDD_TEST_MODE
2175     case EVENT_ID_UPDATE_RDD_STATUS:
2176         {
2177             P_EVENT_RDD_STATUS_T prEventRddStatus;
2178
2179             prEventRddStatus = (P_EVENT_RDD_STATUS_T) (prEvent->aucBuffer);
2180
2181             prAdapter->ucRddStatus = prEventRddStatus->ucRddStatus;
2182         }
2183
2184         break;
2185 #endif
2186
2187 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
2188     case EVENT_ID_UPDATE_BWCS_STATUS:
2189         {
2190             P_PTA_IPC_T prEventBwcsStatus;
2191
2192             prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer);
2193
2194 #if CFG_SUPPORT_BCM_BWCS_DEBUG
2195             printk(KERN_INFO DRV_NAME "BCM BWCS Event: %02x%02x%02x%02x\n", prEventBwcsStatus->u.aucBTPParams[0],
2196                 prEventBwcsStatus->u.aucBTPParams[1],
2197                 prEventBwcsStatus->u.aucBTPParams[2],
2198                 prEventBwcsStatus->u.aucBTPParams[3]);
2199
2200             printk(KERN_INFO DRV_NAME "BCM BWCS Event: aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[3] = %02x\n",
2201                 prEventBwcsStatus->u.aucBTPParams[0],
2202                 prEventBwcsStatus->u.aucBTPParams[1],
2203                 prEventBwcsStatus->u.aucBTPParams[2],
2204                 prEventBwcsStatus->u.aucBTPParams[3]);
2205 #endif
2206
2207             kalIndicateStatusAndComplete(prAdapter->prGlueInfo,
2208                 WLAN_STATUS_BWCS_UPDATE,
2209                 (PVOID) prEventBwcsStatus,
2210                 sizeof(PTA_IPC_T));
2211         }
2212
2213         break;
2214
2215     case EVENT_ID_UPDATE_BCM_DEBUG:
2216         {
2217             P_PTA_IPC_T prEventBwcsStatus;
2218
2219             prEventBwcsStatus = (P_PTA_IPC_T) (prEvent->aucBuffer);
2220
2221 #if CFG_SUPPORT_BCM_BWCS_DEBUG
2222             printk(KERN_INFO DRV_NAME "BCM FW status: %02x%02x%02x%02x\n", prEventBwcsStatus->u.aucBTPParams[0],
2223                 prEventBwcsStatus->u.aucBTPParams[1],
2224                 prEventBwcsStatus->u.aucBTPParams[2],
2225                 prEventBwcsStatus->u.aucBTPParams[3]);
2226
2227             printk(KERN_INFO DRV_NAME "BCM FW status: aucBTPParams[0] = %02x, aucBTPParams[1] = %02x, aucBTPParams[2] = %02x, aucBTPParams[3] = %02x\n",
2228                 prEventBwcsStatus->u.aucBTPParams[0],
2229                 prEventBwcsStatus->u.aucBTPParams[1],
2230                 prEventBwcsStatus->u.aucBTPParams[2],
2231                 prEventBwcsStatus->u.aucBTPParams[3]);
2232 #endif
2233         }
2234
2235         break;
2236 #endif
2237
2238     case EVENT_ID_ACCESS_REG:
2239     case EVENT_ID_NIC_CAPABILITY:
2240     case EVENT_ID_BASIC_CONFIG:
2241     case EVENT_ID_MAC_MCAST_ADDR:
2242     case EVENT_ID_ACCESS_EEPROM:
2243     case EVENT_ID_TEST_STATUS:
2244     default:
2245         prCmdInfo = nicGetPendingCmdInfo(prAdapter, prEvent->ucSeqNum);
2246
2247         if(prCmdInfo != NULL) {
2248             if (prCmdInfo->pfCmdDoneHandler) {
2249                 prCmdInfo->pfCmdDoneHandler(prAdapter, prCmdInfo, prEvent->aucBuffer);
2250             }
2251             else if(prCmdInfo->fgIsOid) {
2252                 kalOidComplete(prAdapter->prGlueInfo, prCmdInfo->fgSetQuery, 0, WLAN_STATUS_SUCCESS);
2253             }
2254
2255             // return prCmdInfo
2256             cmdBufFreeCmdInfo(prAdapter, prCmdInfo);
2257         }
2258
2259         break;
2260     }
2261
2262     nicRxReturnRFB(prAdapter, prSwRfb);
2263 }
2264
2265
2266 /*----------------------------------------------------------------------------*/
2267 /*!
2268 * @brief nicRxProcessMgmtPacket is used to dispatch management frames
2269 *        to corresponding modules
2270 *
2271 * @param prAdapter Pointer to the Adapter structure.
2272 * @param prSWRfb the RFB to receive rx data
2273 *
2274 * @return (none)
2275 */
2276 /*----------------------------------------------------------------------------*/
2277 VOID
2278 nicRxProcessMgmtPacket (
2279     IN P_ADAPTER_T    prAdapter,
2280     IN OUT P_SW_RFB_T prSwRfb
2281     )
2282 {
2283     UINT_8 ucSubtype;
2284 #if CFG_SUPPORT_802_11W
2285     BOOL   fgMfgDrop = FALSE;
2286 #endif
2287     ASSERT(prAdapter);
2288     ASSERT(prSwRfb);
2289
2290     nicRxFillRFB(prAdapter, prSwRfb);
2291
2292     ucSubtype = (*(PUINT_8)(prSwRfb->pvHeader) & MASK_FC_SUBTYPE )>> OFFSET_OF_FC_SUBTYPE;
2293
2294 #if CFG_RX_PKTS_DUMP
2295     {
2296         P_HIF_RX_HEADER_T   prHifRxHdr;
2297         UINT_16 u2TxFrameCtrl;
2298
2299         prHifRxHdr = prSwRfb->prHifRxHdr;
2300         u2TxFrameCtrl = (*(PUINT_8)(prSwRfb->pvHeader) & MASK_FRAME_TYPE);
2301         if (prAdapter->rRxCtrl.u4RxPktsDumpTypeMask & BIT(HIF_RX_PKT_TYPE_MANAGEMENT)) {
2302             if (u2TxFrameCtrl == MAC_FRAME_BEACON ||
2303                   u2TxFrameCtrl == MAC_FRAME_PROBE_RSP) {
2304
2305                 DBGLOG(SW4, INFO, ("QM RX MGT: net %u sta idx %u wlan idx %u ssn %u ptype %u subtype %u 11 %u\n",
2306                     HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr),
2307                     prHifRxHdr->ucStaRecIdx,
2308                     prSwRfb->ucWlanIdx,
2309                     HIF_RX_HDR_GET_SN(prHifRxHdr),  /* The new SN of the frame */
2310                     prSwRfb->ucPacketType,
2311                     ucSubtype,
2312                     HIF_RX_HDR_GET_80211_FLAG(prHifRxHdr)));
2313
2314                 DBGLOG_MEM8(SW4, TRACE, (PUINT_8)prSwRfb->pvHeader, prSwRfb->u2PacketLen);
2315             }
2316         }
2317     }
2318 #endif
2319
2320     if(prAdapter->fgTestMode == FALSE) {
2321 #if CFG_MGMT_FRAME_HANDLING
2322 #if CFG_SUPPORT_802_11W
2323         fgMfgDrop = rsnCheckRxMgmt(prAdapter, prSwRfb, ucSubtype);
2324         if (fgMfgDrop) {
2325             #if DBG
2326             LOG_FUNC("QM RX MGT: Drop Unprotected Mgmt frame!!!\n");
2327             #endif
2328             nicRxReturnRFB(prAdapter, prSwRfb);
2329             RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
2330             return;
2331         }
2332         else
2333 #endif
2334         if(apfnProcessRxMgtFrame[ucSubtype]) {
2335             switch(apfnProcessRxMgtFrame[ucSubtype](prAdapter, prSwRfb)){
2336             case WLAN_STATUS_PENDING:
2337                 return;
2338             case WLAN_STATUS_SUCCESS:
2339             case WLAN_STATUS_FAILURE:
2340                 break;
2341
2342             default:
2343                 ASSERT(0);
2344                 break;
2345             }
2346         }
2347 #endif
2348     }
2349
2350     nicRxReturnRFB(prAdapter, prSwRfb);
2351 }
2352
2353 /*----------------------------------------------------------------------------*/
2354 /*!
2355 * @brief nicProcessRFBs is used to process RFBs in the rReceivedRFBList queue.
2356 *
2357 * @param prAdapter Pointer to the Adapter structure.
2358 *
2359 * @return (none)
2360 */
2361 /*----------------------------------------------------------------------------*/
2362 VOID
2363 nicRxProcessRFBs (
2364     IN  P_ADAPTER_T prAdapter
2365     )
2366 {
2367     P_RX_CTRL_T prRxCtrl;
2368     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
2369     KAL_SPIN_LOCK_DECLARATION();
2370
2371     DEBUGFUNC("nicRxProcessRFBs");
2372
2373     ASSERT(prAdapter);
2374
2375     prRxCtrl = &prAdapter->rRxCtrl;
2376     ASSERT(prRxCtrl);
2377
2378     prRxCtrl->ucNumIndPacket = 0;
2379     prRxCtrl->ucNumRetainedPacket = 0;
2380
2381     do {
2382         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2383         QUEUE_REMOVE_HEAD(&prRxCtrl->rReceivedRfbList, prSwRfb, P_SW_RFB_T);
2384         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2385
2386         if (prSwRfb){
2387             switch(prSwRfb->ucPacketType){
2388                 case HIF_RX_PKT_TYPE_DATA:
2389                     nicRxProcessDataPacket(prAdapter, prSwRfb);
2390                     break;
2391
2392                 case HIF_RX_PKT_TYPE_EVENT:
2393                     nicRxProcessEventPacket(prAdapter, prSwRfb);
2394                     break;
2395
2396                 case HIF_RX_PKT_TYPE_TX_LOOPBACK:
2397                     DBGLOG(RX, ERROR, ("ucPacketType = %d\n", prSwRfb->ucPacketType));
2398                     break;
2399
2400                 case HIF_RX_PKT_TYPE_MANAGEMENT:
2401                     nicRxProcessMgmtPacket(prAdapter, prSwRfb);
2402                     break;
2403
2404                 default:
2405                     RX_INC_CNT(prRxCtrl, RX_TYPE_ERR_DROP_COUNT);
2406                     RX_INC_CNT(prRxCtrl, RX_DROP_TOTAL_COUNT);
2407                     DBGLOG(RX, ERROR, ("ucPacketType = %d\n", prSwRfb->ucPacketType));
2408                     break;
2409             }
2410         }
2411         else {
2412             break;
2413         }
2414     }while(TRUE);
2415
2416      if (prRxCtrl->ucNumIndPacket > 0) {
2417         RX_ADD_CNT(prRxCtrl, RX_DATA_INDICATION_COUNT, prRxCtrl->ucNumIndPacket);
2418         RX_ADD_CNT(prRxCtrl, RX_DATA_RETAINED_COUNT, prRxCtrl->ucNumRetainedPacket);
2419
2420         //DBGLOG(RX, INFO, ("%d packets indicated, Retained cnt = %d\n",
2421         //    prRxCtrl->ucNumIndPacket, prRxCtrl->ucNumRetainedPacket));
2422     #if CFG_NATIVE_802_11
2423         kalRxIndicatePkts(prAdapter->prGlueInfo, (UINT_32)prRxCtrl->ucNumIndPacket, (UINT_32)prRxCtrl->ucNumRetainedPacket);
2424     #else
2425         kalRxIndicatePkts(prAdapter->prGlueInfo, prRxCtrl->apvIndPacket, (UINT_32)prRxCtrl->ucNumIndPacket);
2426     #endif
2427     }
2428
2429 } /* end of nicRxProcessRFBs() */
2430
2431
2432 #if !CFG_SDIO_INTR_ENHANCE
2433 /*----------------------------------------------------------------------------*/
2434 /*!
2435 * @brief Read the rx data from data port and setup RFB
2436 *
2437 * @param prAdapter pointer to the Adapter handler
2438 * @param prSWRfb the RFB to receive rx data
2439 *
2440 * @retval WLAN_STATUS_SUCCESS: SUCCESS
2441 * @retval WLAN_STATUS_FAILURE: FAILURE
2442 *
2443 */
2444 /*----------------------------------------------------------------------------*/
2445 WLAN_STATUS
2446 nicRxReadBuffer (
2447     IN P_ADAPTER_T prAdapter,
2448     IN OUT P_SW_RFB_T prSwRfb
2449     )
2450 {
2451     P_RX_CTRL_T prRxCtrl;
2452     PUINT_8 pucBuf;
2453     P_HIF_RX_HEADER_T prHifRxHdr;
2454     UINT_32 u4PktLen = 0, u4ReadBytes;
2455     WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
2456     BOOL fgResult = TRUE;
2457     UINT_32 u4RegValue;
2458     UINT_32 rxNum;
2459
2460     DEBUGFUNC("nicRxReadBuffer");
2461
2462     ASSERT(prAdapter);
2463     ASSERT(prSwRfb);
2464
2465     prRxCtrl = &prAdapter->rRxCtrl;
2466     ASSERT(prRxCtrl);
2467
2468     pucBuf = prSwRfb->pucRecvBuff;
2469     prHifRxHdr = prSwRfb->prHifRxHdr;
2470     ASSERT(pucBuf);
2471     DBGLOG(RX, TRACE, ("pucBuf= 0x%x, prHifRxHdr= 0x%x\n", pucBuf, prHifRxHdr));
2472
2473     do {
2474         /* Read the RFB DW length and packet length */
2475         HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4RegValue);
2476         if (!fgResult) {
2477             DBGLOG(RX, ERROR, ("Read RX Packet Lentgh Error\n"));
2478             return WLAN_STATUS_FAILURE;
2479         }
2480
2481         //20091021 move the line to get the HIF RX header (for RX0/1)
2482         if(u4RegValue == 0) {
2483             DBGLOG(RX, ERROR, ("No RX packet\n"));
2484             return WLAN_STATUS_FAILURE;
2485         }
2486
2487         u4PktLen = u4RegValue & BITS(0, 15);
2488         if(u4PktLen != 0) {
2489             rxNum = 0;
2490         }
2491         else {
2492             rxNum = 1;
2493             u4PktLen = (u4RegValue & BITS(16, 31)) >> 16;
2494         }
2495
2496         DBGLOG(RX, TRACE, ("RX%d: u4PktLen = %d\n", rxNum, u4PktLen));
2497
2498         //4 <4> Read Entire RFB and packet, include HW appended DW (Checksum Status)
2499         u4ReadBytes = ALIGN_4(u4PktLen) + 4;
2500         HAL_READ_RX_PORT(prAdapter, rxNum, u4ReadBytes, pucBuf, CFG_RX_MAX_PKT_SIZE);
2501
2502         //20091021 move the line to get the HIF RX header
2503         //u4PktLen = (UINT_32)prHifRxHdr->u2PacketLen;
2504         if (u4PktLen != (UINT_32)prHifRxHdr->u2PacketLen) {
2505            DBGLOG(RX, ERROR, ("Read u4PktLen = %d, prHifRxHdr->u2PacketLen: %d\n",
2506                                 u4PktLen, prHifRxHdr->u2PacketLen));
2507     #if DBG
2508             dumpMemory8((PUINT_8)prHifRxHdr, (prHifRxHdr->u2PacketLen > 4096) ? 4096 : prHifRxHdr->u2PacketLen);
2509     #endif
2510             ASSERT(0);
2511         }
2512         /* u4PktLen is byte unit, not inlude HW appended DW */
2513
2514         prSwRfb->ucPacketType = (UINT_8)(prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
2515         DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType));
2516
2517         prSwRfb->ucStaRecIdx = (UINT_8)(prHifRxHdr->ucStaRecIdx);
2518
2519         /* fgResult will be updated in MACRO */
2520         if (!fgResult) {
2521             return WLAN_STATUS_FAILURE;
2522         }
2523
2524         DBGLOG(RX, TRACE, ("Dump RX buffer, length = 0x%x\n", u4ReadBytes));
2525         DBGLOG_MEM8(RX, TRACE, pucBuf, u4ReadBytes);
2526     }while(FALSE);
2527
2528     return u4Status;
2529 }
2530
2531
2532 /*----------------------------------------------------------------------------*/
2533 /*!
2534 * @brief Read frames from the data port, fill RFB
2535 *        and put each frame into the rReceivedRFBList queue.
2536 *
2537 * @param prAdapter   Pointer to the Adapter structure.
2538 *
2539 * @return (none)
2540 */
2541 /*----------------------------------------------------------------------------*/
2542 VOID
2543 nicRxReceiveRFBs (
2544     IN P_ADAPTER_T  prAdapter
2545     )
2546 {
2547     P_RX_CTRL_T prRxCtrl;
2548     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
2549     P_HIF_RX_HEADER_T prHifRxHdr;
2550
2551     UINT_32 u4HwAppendDW;
2552
2553     KAL_SPIN_LOCK_DECLARATION();
2554
2555     DEBUGFUNC("nicRxReceiveRFBs");
2556
2557     ASSERT(prAdapter);
2558
2559     prRxCtrl = &prAdapter->rRxCtrl;
2560     ASSERT(prRxCtrl);
2561
2562     do {
2563         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2564         QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
2565         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2566
2567         if (!prSwRfb) {
2568             DBGLOG(RX, TRACE, ("No More RFB\n"));
2569             break;
2570         }
2571
2572         // need to consider
2573         if (nicRxReadBuffer(prAdapter, prSwRfb) == WLAN_STATUS_FAILURE) {
2574             DBGLOG(RX, TRACE, ("halRxFillRFB failed\n"));
2575             nicRxReturnRFB(prAdapter, prSwRfb);
2576             break;
2577         }
2578
2579         KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2580         QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
2581         RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
2582         KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2583
2584         prHifRxHdr = prSwRfb->prHifRxHdr;
2585         u4HwAppendDW = *((PUINT_32)((UINT_32)prHifRxHdr +
2586             (UINT_32)(ALIGN_4(prHifRxHdr->u2PacketLen))));
2587         DBGLOG(RX, TRACE, ("u4HwAppendDW = 0x%x\n", u4HwAppendDW));
2588         DBGLOG(RX, TRACE, ("u2PacketLen = 0x%x\n", prHifRxHdr->u2PacketLen));
2589       }
2590 //    while (RX_STATUS_TEST_MORE_FLAG(u4HwAppendDW));
2591     while (FALSE);
2592
2593     return;
2594
2595 } /* end of nicReceiveRFBs() */
2596
2597 #else
2598 /*----------------------------------------------------------------------------*/
2599 /*!
2600 * @brief Read frames from the data port, fill RFB
2601 *        and put each frame into the rReceivedRFBList queue.
2602 *
2603 * @param prAdapter      Pointer to the Adapter structure.
2604 * @param u4DataPort     Specify which port to read
2605 * @param u2RxLength     Specify to the the rx packet length in Byte.
2606 * @param prSwRfb        the RFB to receive rx data.
2607 *
2608 * @return (none)
2609 */
2610 /*----------------------------------------------------------------------------*/
2611
2612 WLAN_STATUS
2613 nicRxEnhanceReadBuffer (
2614     IN P_ADAPTER_T prAdapter,
2615     IN UINT_32      u4DataPort,
2616     IN UINT_16      u2RxLength,
2617     IN OUT P_SW_RFB_T prSwRfb
2618     )
2619 {
2620     P_RX_CTRL_T prRxCtrl;
2621     PUINT_8 pucBuf;
2622     P_HIF_RX_HEADER_T prHifRxHdr;
2623     UINT_32 u4PktLen = 0;
2624     WLAN_STATUS u4Status = WLAN_STATUS_FAILURE;
2625     BOOL fgResult = TRUE;
2626
2627     DEBUGFUNC("nicRxEnhanceReadBuffer");
2628
2629     ASSERT(prAdapter);
2630     ASSERT(prSwRfb);
2631
2632     prRxCtrl = &prAdapter->rRxCtrl;
2633     ASSERT(prRxCtrl);
2634
2635     pucBuf = prSwRfb->pucRecvBuff;
2636     ASSERT(pucBuf);
2637
2638     prHifRxHdr = prSwRfb->prHifRxHdr;
2639     ASSERT(prHifRxHdr);
2640
2641     //DBGLOG(RX, TRACE, ("u2RxLength = %d\n", u2RxLength));
2642
2643     do {
2644         //4 <1> Read RFB frame from MCR_WRDR0, include HW appended DW
2645         HAL_READ_RX_PORT(prAdapter,
2646                          u4DataPort,
2647                          ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN),
2648                          pucBuf,
2649                          CFG_RX_MAX_PKT_SIZE);
2650
2651         if (!fgResult) {
2652             DBGLOG(RX, ERROR, ("Read RX Packet Lentgh Error\n"));
2653             break;
2654         }
2655
2656         u4PktLen = (UINT_32)(prHifRxHdr->u2PacketLen);
2657         //DBGLOG(RX, TRACE, ("u4PktLen = %d\n", u4PktLen));
2658
2659         prSwRfb->ucPacketType = (UINT_8)(prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
2660         //DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType));
2661
2662         prSwRfb->ucStaRecIdx = (UINT_8)(prHifRxHdr->ucStaRecIdx);
2663
2664         //4 <2> if the RFB dw size or packet size is zero
2665         if (u4PktLen == 0) {
2666             DBGLOG(RX, ERROR, ("Packet Length = %d\n", u4PktLen));
2667             ASSERT(0);
2668             break;
2669         }
2670
2671         //4 <3> if the packet is too large or too small
2672         if (u4PktLen > CFG_RX_MAX_PKT_SIZE) {
2673             DBGLOG(RX, TRACE, ("Read RX Packet Lentgh Error (%d)\n", u4PktLen));
2674             ASSERT(0);
2675             break;
2676         }
2677
2678         u4Status = WLAN_STATUS_SUCCESS;
2679     }
2680     while (FALSE);
2681
2682     DBGLOG_MEM8(RX, TRACE, pucBuf, ALIGN_4(u2RxLength + HIF_RX_HW_APPENDED_LEN));
2683     return u4Status;
2684 }
2685
2686
2687 /*----------------------------------------------------------------------------*/
2688 /*!
2689 * @brief Read frames from the data port for SDIO
2690 *        I/F, fill RFB and put each frame into the rReceivedRFBList queue.
2691 *
2692 * @param prAdapter      Pointer to the Adapter structure.
2693 *
2694 * @return (none)
2695 */
2696 /*----------------------------------------------------------------------------*/
2697 VOID
2698 nicRxSDIOReceiveRFBs (
2699     IN  P_ADAPTER_T prAdapter
2700     )
2701 {
2702     P_SDIO_CTRL_T prSDIOCtrl;
2703     P_RX_CTRL_T prRxCtrl;
2704     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
2705     UINT_32 i, rxNum;
2706     UINT_16 u2RxPktNum, u2RxLength = 0, u2Tmp = 0;
2707     KAL_SPIN_LOCK_DECLARATION();
2708
2709     DEBUGFUNC("nicRxSDIOReceiveRFBs");
2710
2711     ASSERT(prAdapter);
2712
2713     prSDIOCtrl = prAdapter->prSDIOCtrl;
2714     ASSERT(prSDIOCtrl);
2715
2716     prRxCtrl = &prAdapter->rRxCtrl;
2717     ASSERT(prRxCtrl);
2718
2719     for (rxNum = 0 ; rxNum < 2 ; rxNum++) {
2720         u2RxPktNum = (rxNum == 0 ? prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len : prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len);
2721
2722         if(u2RxPktNum == 0) {
2723             continue;
2724         }
2725
2726         for (i = 0; i < u2RxPktNum; i++) {
2727             if(rxNum == 0) {
2728                 HAL_READ_RX_LENGTH(prAdapter, &u2RxLength, &u2Tmp);
2729             }
2730             else if(rxNum == 1) {
2731                 HAL_READ_RX_LENGTH(prAdapter, &u2Tmp, &u2RxLength);
2732             }
2733
2734             if (!u2RxLength) {
2735                 break;
2736             }
2737
2738
2739             KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2740             QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
2741             KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2742
2743             if (!prSwRfb) {
2744                 DBGLOG(RX, TRACE, ("No More RFB\n"));
2745                 break;
2746             }
2747             ASSERT(prSwRfb);
2748
2749             if (nicRxEnhanceReadBuffer(prAdapter, rxNum, u2RxLength, prSwRfb) == WLAN_STATUS_FAILURE) {
2750                 DBGLOG(RX, TRACE, ("nicRxEnhanceRxReadBuffer failed\n"));
2751                 nicRxReturnRFB(prAdapter, prSwRfb);
2752                 break;
2753             }
2754
2755             //prSDIOCtrl->au4RxLength[i] = 0;
2756
2757             KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2758             QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
2759             RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
2760             KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2761         }
2762     }
2763
2764     prSDIOCtrl->rRxInfo.u.u2NumValidRx0Len = 0;
2765     prSDIOCtrl->rRxInfo.u.u2NumValidRx1Len = 0;
2766
2767     return;
2768 }/* end of nicRxSDIOReceiveRFBs() */
2769
2770 #endif /* CFG_SDIO_INTR_ENHANCE */
2771
2772
2773
2774 #if CFG_SDIO_RX_AGG
2775 /*----------------------------------------------------------------------------*/
2776 /*!
2777 * @brief Read frames from the data port for SDIO with Rx aggregation enabled
2778 *        I/F, fill RFB and put each frame into the rReceivedRFBList queue.
2779 *
2780 * @param prAdapter      Pointer to the Adapter structure.
2781 *
2782 * @return (none)
2783 */
2784 /*----------------------------------------------------------------------------*/
2785 VOID
2786 nicRxSDIOAggReceiveRFBs (
2787     IN  P_ADAPTER_T prAdapter
2788     )
2789 {
2790     P_ENHANCE_MODE_DATA_STRUCT_T prEnhDataStr;
2791     P_RX_CTRL_T prRxCtrl;
2792     P_SDIO_CTRL_T prSDIOCtrl;
2793     P_SW_RFB_T prSwRfb = (P_SW_RFB_T)NULL;
2794     UINT_32 u4RxLength;
2795     UINT_32 i, rxNum;
2796     UINT_32 u4RxAggCount = 0, u4RxAggLength = 0;
2797     UINT_32 u4RxAvailAggLen, u4CurrAvailFreeRfbCnt;
2798     PUINT_8 pucSrcAddr;
2799     P_HIF_RX_HEADER_T prHifRxHdr;
2800     BOOL fgResult = TRUE;
2801     BOOLEAN fgIsRxEnhanceMode;
2802     UINT_16 u2RxPktNum;
2803 #if CFG_SDIO_RX_ENHANCE
2804     UINT_32 u4MaxLoopCount = CFG_MAX_RX_ENHANCE_LOOP_COUNT;
2805 #endif
2806
2807     KAL_SPIN_LOCK_DECLARATION();
2808
2809     DEBUGFUNC("nicRxSDIOAggReceiveRFBs");
2810
2811     ASSERT(prAdapter);
2812     prEnhDataStr = prAdapter->prSDIOCtrl;
2813     prRxCtrl = &prAdapter->rRxCtrl;
2814     prSDIOCtrl = prAdapter->prSDIOCtrl;
2815
2816 #if CFG_SDIO_RX_ENHANCE
2817     fgIsRxEnhanceMode = TRUE;
2818 #else
2819     fgIsRxEnhanceMode = FALSE;
2820 #endif
2821
2822     do {
2823 #if CFG_SDIO_RX_ENHANCE
2824         /* to limit maximum loop for RX */
2825         u4MaxLoopCount--;
2826         if (u4MaxLoopCount == 0) {
2827             break;
2828         }
2829 #endif
2830
2831         if(prEnhDataStr->rRxInfo.u.u2NumValidRx0Len == 0 &&
2832                 prEnhDataStr->rRxInfo.u.u2NumValidRx1Len == 0) {
2833             break;
2834         }
2835
2836         for(rxNum = 0 ; rxNum < 2 ; rxNum++) {
2837             u2RxPktNum = (rxNum == 0 ? prEnhDataStr->rRxInfo.u.u2NumValidRx0Len : prEnhDataStr->rRxInfo.u.u2NumValidRx1Len);
2838
2839             // if this assertion happened, it is most likely a F/W bug
2840             ASSERT(u2RxPktNum <= 16);
2841
2842             if (u2RxPktNum > 16)
2843                   continue;
2844
2845             if(u2RxPktNum == 0)
2846                 continue;
2847
2848     #if CFG_HIF_STATISTICS
2849             prRxCtrl->u4TotalRxAccessNum++;
2850             prRxCtrl->u4TotalRxPacketNum += u2RxPktNum;
2851     #endif
2852
2853             u4CurrAvailFreeRfbCnt = prRxCtrl->rFreeSwRfbList.u4NumElem;
2854
2855             // if SwRfb is not enough, abort reading this time
2856              if(u4CurrAvailFreeRfbCnt < u2RxPktNum) {
2857     #if CFG_HIF_RX_STARVATION_WARNING
2858                 DbgPrint("FreeRfb is not enough: %d available, need %d\n", u4CurrAvailFreeRfbCnt, u2RxPktNum);
2859                 DbgPrint("Queued Count: %d / Dequeud Count: %d\n", prRxCtrl->u4QueuedCnt, prRxCtrl->u4DequeuedCnt);
2860     #endif
2861                 continue;
2862             }
2863
2864 #if CFG_SDIO_RX_ENHANCE
2865             u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE - (sizeof(ENHANCE_MODE_DATA_STRUCT_T) + 4/* extra HW padding */);
2866 #else
2867             u4RxAvailAggLen = CFG_RX_COALESCING_BUFFER_SIZE;
2868 #endif
2869             u4RxAggCount = 0;
2870
2871             for (i = 0; i < u2RxPktNum ; i++) {
2872                 u4RxLength = (rxNum == 0 ?
2873                         (UINT_32)prEnhDataStr->rRxInfo.u.au2Rx0Len[i] :
2874                         (UINT_32)prEnhDataStr->rRxInfo.u.au2Rx1Len[i]);
2875
2876                 if (!u4RxLength) {
2877                     ASSERT(0);
2878                     break;
2879                 }
2880
2881                 if (ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN) < u4RxAvailAggLen) {
2882                     if (u4RxAggCount < u4CurrAvailFreeRfbCnt) {
2883                         u4RxAvailAggLen -= ALIGN_4(u4RxLength + HIF_RX_HW_APPENDED_LEN);
2884                         u4RxAggCount++;
2885                     }
2886                     else {
2887                         // no FreeSwRfb for rx packet
2888                         ASSERT(0);
2889                         break;
2890                     }
2891                 }
2892                 else {
2893                     // CFG_RX_COALESCING_BUFFER_SIZE is not large enough
2894                     ASSERT(0);
2895                     break;
2896                 }
2897             }
2898
2899             u4RxAggLength = (CFG_RX_COALESCING_BUFFER_SIZE - u4RxAvailAggLen);
2900             //DBGLOG(RX, INFO, ("u4RxAggCount = %d, u4RxAggLength = %d\n",
2901             //            u4RxAggCount, u4RxAggLength));
2902
2903             HAL_READ_RX_PORT(prAdapter,
2904                          rxNum,
2905                          u4RxAggLength,
2906                          prRxCtrl->pucRxCoalescingBufPtr,
2907                          CFG_RX_COALESCING_BUFFER_SIZE);
2908             if (!fgResult) {
2909                 DBGLOG(RX, ERROR, ("Read RX Agg Packet Error\n"));
2910                 continue;
2911             }
2912
2913             pucSrcAddr = prRxCtrl->pucRxCoalescingBufPtr;
2914             for (i = 0; i < u4RxAggCount; i++) {
2915                 UINT_16 u2PktLength;
2916
2917                 u2PktLength = (rxNum == 0 ?
2918                         prEnhDataStr->rRxInfo.u.au2Rx0Len[i] :
2919                         prEnhDataStr->rRxInfo.u.au2Rx1Len[i]);
2920
2921                 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2922                 QUEUE_REMOVE_HEAD(&prRxCtrl->rFreeSwRfbList, prSwRfb, P_SW_RFB_T);
2923                 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2924
2925                 ASSERT(prSwRfb);
2926                 kalMemCopy(prSwRfb->pucRecvBuff, pucSrcAddr,
2927                         ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN));
2928
2929                 prHifRxHdr = prSwRfb->prHifRxHdr;
2930                 ASSERT(prHifRxHdr);
2931
2932                 prSwRfb->ucPacketType = (UINT_8)(prHifRxHdr->u2PacketType & HIF_RX_HDR_PACKET_TYPE_MASK);
2933                 //DBGLOG(RX, TRACE, ("ucPacketType = %d\n", prSwRfb->ucPacketType));
2934
2935                 prSwRfb->ucStaRecIdx = (UINT_8)(prHifRxHdr->ucStaRecIdx);
2936
2937                 KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2938                 QUEUE_INSERT_TAIL(&prRxCtrl->rReceivedRfbList, &prSwRfb->rQueEntry);
2939                 RX_INC_CNT(prRxCtrl, RX_MPDU_TOTAL_COUNT);
2940                 KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
2941
2942                 pucSrcAddr += ALIGN_4(u2PktLength + HIF_RX_HW_APPENDED_LEN);
2943                 //prEnhDataStr->au4RxLength[i] = 0;
2944             }
2945
2946 #if CFG_SDIO_RX_ENHANCE
2947             kalMemCopy(prAdapter->prSDIOCtrl, (pucSrcAddr + 4), sizeof(ENHANCE_MODE_DATA_STRUCT_T));
2948
2949             /* do the same thing what nicSDIOReadIntStatus() does */
2950             if((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 &&
2951                     (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) {
2952                 prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT;
2953             }
2954
2955             if((prSDIOCtrl->u4WHISR & BIT(31)) == 0 &&
2956                     HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE &&
2957                     (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) {
2958                 prSDIOCtrl->u4WHISR |= BIT(31);
2959             }
2960
2961             /* dispatch to interrupt handler with RX bits masked */
2962             nicProcessIST_impl(prAdapter, prSDIOCtrl->u4WHISR & (~(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT)));
2963 #endif
2964         }
2965
2966 #if !CFG_SDIO_RX_ENHANCE
2967         prEnhDataStr->rRxInfo.u.u2NumValidRx0Len = 0;
2968         prEnhDataStr->rRxInfo.u.u2NumValidRx1Len = 0;
2969 #endif
2970     }
2971     while ((prEnhDataStr->rRxInfo.u.u2NumValidRx0Len
2972                 || prEnhDataStr->rRxInfo.u.u2NumValidRx1Len)
2973             && fgIsRxEnhanceMode);
2974
2975     return;
2976 }
2977 #endif /* CFG_SDIO_RX_AGG */
2978
2979
2980 /*----------------------------------------------------------------------------*/
2981 /*!
2982 * @brief Setup a RFB and allocate the os packet to the RFB
2983 *
2984 * @param prAdapter      Pointer to the Adapter structure.
2985 * @param prSwRfb        Pointer to the RFB
2986 *
2987 * @retval WLAN_STATUS_SUCCESS
2988 * @retval WLAN_STATUS_RESOURCES
2989 */
2990 /*----------------------------------------------------------------------------*/
2991 WLAN_STATUS
2992 nicRxSetupRFB (
2993     IN P_ADAPTER_T prAdapter,
2994     IN P_SW_RFB_T  prSwRfb
2995     )
2996 {
2997     PVOID   pvPacket;
2998     PUINT_8 pucRecvBuff;
2999
3000     ASSERT(prAdapter);
3001     ASSERT(prSwRfb);
3002
3003     if (!prSwRfb->pvPacket) {
3004         kalMemZero(prSwRfb, sizeof(SW_RFB_T));
3005         pvPacket = kalPacketAlloc(prAdapter->prGlueInfo, CFG_RX_MAX_PKT_SIZE,
3006             &pucRecvBuff);
3007         if (pvPacket == NULL) {
3008             return WLAN_STATUS_RESOURCES;
3009         }
3010
3011         prSwRfb->pvPacket = pvPacket;
3012         prSwRfb->pucRecvBuff= (PVOID)pucRecvBuff;
3013     }
3014     else {
3015         kalMemZero(((PUINT_8)prSwRfb + OFFSET_OF(SW_RFB_T, prHifRxHdr)),
3016             (sizeof(SW_RFB_T)-OFFSET_OF(SW_RFB_T, prHifRxHdr)));
3017     }
3018
3019     prSwRfb->prHifRxHdr = (P_HIF_RX_HEADER_T)(prSwRfb->pucRecvBuff);
3020
3021     return WLAN_STATUS_SUCCESS;
3022
3023 } /* end of nicRxSetupRFB() */
3024
3025
3026 /*----------------------------------------------------------------------------*/
3027 /*!
3028 * @brief This routine is called to put a RFB back onto the "RFB with Buffer" list
3029 *        or "RFB without buffer" list according to pvPacket.
3030 *
3031 * @param prAdapter      Pointer to the Adapter structure.
3032 * @param prSwRfb          Pointer to the RFB
3033 *
3034 * @return (none)
3035 */
3036 /*----------------------------------------------------------------------------*/
3037 VOID
3038 nicRxReturnRFB (
3039     IN P_ADAPTER_T prAdapter,
3040     IN P_SW_RFB_T  prSwRfb
3041     )
3042 {
3043     P_RX_CTRL_T prRxCtrl;
3044     P_QUE_ENTRY_T prQueEntry;
3045     KAL_SPIN_LOCK_DECLARATION();
3046
3047     ASSERT(prAdapter);
3048     ASSERT(prSwRfb);
3049     prRxCtrl = &prAdapter->rRxCtrl;
3050     prQueEntry = &prSwRfb->rQueEntry;
3051
3052     ASSERT(prQueEntry);
3053
3054     /* The processing on this RFB is done, so put it back on the tail of
3055        our list */
3056     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
3057
3058     if (prSwRfb->pvPacket) {
3059         QUEUE_INSERT_TAIL(&prRxCtrl->rFreeSwRfbList, prQueEntry);
3060     }
3061     else {
3062         QUEUE_INSERT_TAIL(&prRxCtrl->rIndicatedRfbList, prQueEntry);
3063     }
3064
3065     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_RX_QUE);
3066     return;
3067 } /* end of nicRxReturnRFB() */
3068
3069 /*----------------------------------------------------------------------------*/
3070 /*!
3071 * @brief Process rx interrupt. When the rx
3072 *        Interrupt is asserted, it means there are frames in queue.
3073 *
3074 * @param prAdapter      Pointer to the Adapter structure.
3075 *
3076 * @return (none)
3077 */
3078 /*----------------------------------------------------------------------------*/
3079 VOID
3080 nicProcessRxInterrupt (
3081     IN  P_ADAPTER_T prAdapter
3082     )
3083 {
3084     ASSERT(prAdapter);
3085
3086 #if CFG_SDIO_INTR_ENHANCE
3087     #if CFG_SDIO_RX_AGG
3088         nicRxSDIOAggReceiveRFBs(prAdapter);
3089     #else
3090         nicRxSDIOReceiveRFBs(prAdapter);
3091     #endif
3092 #else
3093     nicRxReceiveRFBs(prAdapter);
3094 #endif /* CFG_SDIO_INTR_ENHANCE */
3095
3096     nicRxProcessRFBs(prAdapter);
3097
3098     return;
3099
3100 } /* end of nicProcessRxInterrupt() */
3101
3102
3103 #if CFG_TCP_IP_CHKSUM_OFFLOAD
3104 /*----------------------------------------------------------------------------*/
3105 /*!
3106 * @brief Used to update IP/TCP/UDP checksum statistics of RX Module.
3107 *
3108 * @param prAdapter  Pointer to the Adapter structure.
3109 * @param aeCSUM     The array of checksum result.
3110 *
3111 * @return (none)
3112 */
3113 /*----------------------------------------------------------------------------*/
3114 VOID
3115 nicRxUpdateCSUMStatistics (
3116     IN P_ADAPTER_T prAdapter,
3117     IN const ENUM_CSUM_RESULT_T aeCSUM[]
3118     )
3119 {
3120     P_RX_CTRL_T prRxCtrl;
3121
3122     ASSERT(prAdapter);
3123     ASSERT(aeCSUM);
3124
3125     prRxCtrl = &prAdapter->rRxCtrl;
3126     ASSERT(prRxCtrl);
3127
3128     if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS) ||
3129         (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)) {
3130
3131         RX_INC_CNT(prRxCtrl, RX_CSUM_IP_SUCCESS_COUNT);
3132     }
3133     else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) ||
3134              (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_FAILED)) {
3135
3136         RX_INC_CNT(prRxCtrl, RX_CSUM_IP_FAILED_COUNT);
3137     }
3138     else if ((aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE) &&
3139              (aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE)) {
3140
3141         RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L3_PKT_COUNT);
3142     }
3143     else {
3144         ASSERT(0);
3145     }
3146
3147     if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) {
3148         RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_SUCCESS_COUNT);
3149     }
3150     else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) {
3151         RX_INC_CNT(prRxCtrl, RX_CSUM_TCP_FAILED_COUNT);
3152     }
3153     else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS) {
3154         RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_SUCCESS_COUNT);
3155     }
3156     else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) {
3157         RX_INC_CNT(prRxCtrl, RX_CSUM_UDP_FAILED_COUNT);
3158     }
3159     else if ((aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_NONE) &&
3160              (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_NONE)) {
3161
3162         RX_INC_CNT(prRxCtrl, RX_CSUM_UNKNOWN_L4_PKT_COUNT);
3163     }
3164     else {
3165         ASSERT(0);
3166     }
3167
3168     return;
3169 } /* end of nicRxUpdateCSUMStatistics() */
3170 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
3171
3172
3173 /*----------------------------------------------------------------------------*/
3174 /*!
3175 * @brief This function is used to query current status of RX Module.
3176 *
3177 * @param prAdapter      Pointer to the Adapter structure.
3178 * @param pucBuffer      Pointer to the message buffer.
3179 * @param pu4Count      Pointer to the buffer of message length count.
3180 *
3181 * @return (none)
3182 */
3183 /*----------------------------------------------------------------------------*/
3184 VOID
3185 nicRxQueryStatus (
3186     IN P_ADAPTER_T prAdapter,
3187     IN PUINT_8 pucBuffer,
3188     OUT PUINT_32 pu4Count
3189     )
3190 {
3191     P_RX_CTRL_T prRxCtrl;
3192     PUINT_8 pucCurrBuf = pucBuffer;
3193
3194
3195     ASSERT(prAdapter);
3196     prRxCtrl = &prAdapter->rRxCtrl;
3197     ASSERT(prRxCtrl);
3198
3199     //if (pucBuffer) {} /* For Windows, we'll print directly instead of sprintf() */
3200     ASSERT(pu4Count);
3201
3202     SPRINTF(pucCurrBuf, ("\n\nRX CTRL STATUS:"));
3203     SPRINTF(pucCurrBuf, ("\n==============="));
3204     SPRINTF(pucCurrBuf, ("\nFREE RFB w/i BUF LIST :%9ld", prRxCtrl->rFreeSwRfbList.u4NumElem));
3205     SPRINTF(pucCurrBuf, ("\nFREE RFB w/o BUF LIST :%9ld", prRxCtrl->rIndicatedRfbList.u4NumElem));
3206     SPRINTF(pucCurrBuf, ("\nRECEIVED RFB LIST     :%9ld", prRxCtrl->rReceivedRfbList.u4NumElem));
3207
3208     SPRINTF(pucCurrBuf, ("\n\n"));
3209
3210     //*pu4Count = (UINT_32)((UINT_32)pucCurrBuf - (UINT_32)pucBuffer);
3211
3212     return;
3213 } /* end of nicRxQueryStatus() */
3214
3215
3216 /*----------------------------------------------------------------------------*/
3217 /*!
3218 * @brief Clear RX related counters
3219 *
3220 * @param prAdapter Pointer of Adapter Data Structure
3221 *
3222 * @return - (none)
3223 */
3224 /*----------------------------------------------------------------------------*/
3225 VOID
3226 nicRxClearStatistics (
3227     IN P_ADAPTER_T prAdapter
3228     )
3229 {
3230     P_RX_CTRL_T prRxCtrl;
3231
3232     ASSERT(prAdapter);
3233     prRxCtrl = &prAdapter->rRxCtrl;
3234     ASSERT(prRxCtrl);
3235
3236     RX_RESET_ALL_CNTS(prRxCtrl);
3237     return;
3238 }
3239
3240
3241 /*----------------------------------------------------------------------------*/
3242 /*!
3243 * @brief This function is used to query current statistics of RX Module.
3244 *
3245 * @param prAdapter      Pointer to the Adapter structure.
3246 * @param pucBuffer      Pointer to the message buffer.
3247 * @param pu4Count      Pointer to the buffer of message length count.
3248 *
3249 * @return (none)
3250 */
3251 /*----------------------------------------------------------------------------*/
3252 VOID
3253 nicRxQueryStatistics (
3254     IN P_ADAPTER_T prAdapter,
3255     IN PUINT_8 pucBuffer,
3256     OUT PUINT_32 pu4Count
3257     )
3258 {
3259     P_RX_CTRL_T prRxCtrl;
3260     PUINT_8 pucCurrBuf = pucBuffer;
3261
3262     ASSERT(prAdapter);
3263     prRxCtrl = &prAdapter->rRxCtrl;
3264     ASSERT(prRxCtrl);
3265
3266     //if (pucBuffer) {} /* For Windows, we'll print directly instead of sprintf() */
3267     ASSERT(pu4Count);
3268
3269 #define SPRINTF_RX_COUNTER(eCounter) \
3270     SPRINTF(pucCurrBuf, ("%-30s : %ld\n", #eCounter, (UINT_32)prRxCtrl->au8Statistics[eCounter]))
3271
3272     SPRINTF_RX_COUNTER(RX_MPDU_TOTAL_COUNT);
3273     SPRINTF_RX_COUNTER(RX_SIZE_ERR_DROP_COUNT);
3274     SPRINTF_RX_COUNTER(RX_DATA_INDICATION_COUNT);
3275     SPRINTF_RX_COUNTER(RX_DATA_RETURNED_COUNT);
3276     SPRINTF_RX_COUNTER(RX_DATA_RETAINED_COUNT);
3277
3278 #if CFG_TCP_IP_CHKSUM_OFFLOAD || CFG_TCP_IP_CHKSUM_OFFLOAD_NDIS_60
3279     SPRINTF_RX_COUNTER(RX_CSUM_TCP_FAILED_COUNT);
3280     SPRINTF_RX_COUNTER(RX_CSUM_UDP_FAILED_COUNT);
3281     SPRINTF_RX_COUNTER(RX_CSUM_IP_FAILED_COUNT);
3282     SPRINTF_RX_COUNTER(RX_CSUM_TCP_SUCCESS_COUNT);
3283     SPRINTF_RX_COUNTER(RX_CSUM_UDP_SUCCESS_COUNT);
3284     SPRINTF_RX_COUNTER(RX_CSUM_IP_SUCCESS_COUNT);
3285     SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L4_PKT_COUNT);
3286     SPRINTF_RX_COUNTER(RX_CSUM_UNKNOWN_L3_PKT_COUNT);
3287     SPRINTF_RX_COUNTER(RX_IP_V6_PKT_CCOUNT);
3288 #endif
3289
3290     //*pu4Count = (UINT_32)(pucCurrBuf - pucBuffer);
3291
3292     nicRxClearStatistics(prAdapter);
3293
3294     return;
3295 }
3296
3297 /*----------------------------------------------------------------------------*/
3298 /*!
3299 * @brief Read the Response data from data port
3300 *
3301 * @param prAdapter pointer to the Adapter handler
3302 * @param pucRspBuffer pointer to the Response buffer
3303 *
3304 * @retval WLAN_STATUS_SUCCESS: Response packet has been read
3305 * @retval WLAN_STATUS_FAILURE: Read Response packet timeout or error occurred
3306 *
3307 */
3308 /*----------------------------------------------------------------------------*/
3309 WLAN_STATUS
3310 nicRxWaitResponse (
3311     IN P_ADAPTER_T prAdapter,
3312     IN UINT_8 ucPortIdx,
3313     OUT PUINT_8 pucRspBuffer,
3314     IN UINT_32 u4MaxRespBufferLen,
3315     OUT PUINT_32 pu4Length
3316     )
3317 {
3318     UINT_32 u4Value = 0, u4PktLen = 0, i = 0;
3319     WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
3320     BOOL fgResult = TRUE;
3321     UINT_32 u4Time, u4Current;
3322
3323     DEBUGFUNC("nicRxWaitResponse");
3324
3325     ASSERT(prAdapter);
3326     ASSERT(pucRspBuffer);
3327     ASSERT(ucPortIdx < 2);
3328
3329     u4Time = (UINT_32)kalGetTimeTick();
3330
3331     do {
3332         /* Read the packet length */
3333         HAL_MCR_RD(prAdapter, MCR_WRPLR, &u4Value);
3334
3335         if (!fgResult) {
3336             DBGLOG(RX, ERROR, ("Read Response Packet Error\n"));
3337             return WLAN_STATUS_FAILURE;
3338         }
3339
3340         if(ucPortIdx == 0) {
3341             u4PktLen = u4Value & 0xFFFF;
3342         }
3343         else {
3344             u4PktLen = (u4Value >> 16) & 0xFFFF;
3345         }
3346
3347         DBGLOG(RX, TRACE, ("i = %d, u4PktLen = %d\n", i, u4PktLen));
3348
3349         if (u4PktLen == 0) {
3350             /* timeout exceeding check */
3351             u4Current = (UINT_32)kalGetTimeTick();
3352
3353             if((u4Current > u4Time) && ((u4Current - u4Time) > RX_RESPONSE_TIMEOUT)) {
3354                 return WLAN_STATUS_FAILURE;
3355             }
3356             else if(u4Current < u4Time && ((u4Current + (0xFFFFFFFF - u4Time)) > RX_RESPONSE_TIMEOUT)) {
3357                 return WLAN_STATUS_FAILURE;
3358             }
3359
3360             /* Response packet is not ready */
3361             kalUdelay(50);
3362
3363             i++;
3364         }
3365         else if (u4PktLen > u4MaxRespBufferLen) {
3366             DBGLOG(RX, WARN, ("Not enough Event Buffer: required length = 0x%x, available buffer length = %d\n",
3367                 u4PktLen, u4MaxRespBufferLen));
3368
3369             return WLAN_STATUS_FAILURE;
3370         }
3371         else {
3372             HAL_PORT_RD(prAdapter,
3373                         ucPortIdx == 0 ? MCR_WRDR0 : MCR_WRDR1,
3374                         u4PktLen,
3375                         pucRspBuffer,
3376                         u4MaxRespBufferLen);
3377
3378             /* fgResult will be updated in MACRO */
3379             if (!fgResult) {
3380                 DBGLOG(RX, ERROR, ("Read Response Packet Error\n"));
3381                 return WLAN_STATUS_FAILURE;
3382             }
3383
3384             DBGLOG(RX, TRACE, ("Dump Response buffer, length = 0x%x\n",
3385                 u4PktLen));
3386             DBGLOG_MEM8(RX, TRACE, pucRspBuffer, u4PktLen);
3387
3388             *pu4Length = u4PktLen;
3389             break;
3390         }
3391     } while(TRUE);
3392
3393     return u4Status;
3394 }
3395
3396 /*----------------------------------------------------------------------------*/
3397 /*!
3398 * @brief Set filter to enable Promiscuous Mode
3399 *
3400 * @param prAdapter          Pointer to the Adapter structure.
3401 *
3402 * @return (none)
3403 */
3404 /*----------------------------------------------------------------------------*/
3405 VOID
3406 nicRxEnablePromiscuousMode (
3407     IN P_ADAPTER_T prAdapter
3408     )
3409 {
3410     ASSERT(prAdapter);
3411
3412     return;
3413 } /* end of nicRxEnablePromiscuousMode() */
3414
3415
3416 /*----------------------------------------------------------------------------*/
3417 /*!
3418 * @brief Set filter to disable Promiscuous Mode
3419 *
3420 * @param prAdapter  Pointer to the Adapter structure.
3421 *
3422 * @return (none)
3423 */
3424 /*----------------------------------------------------------------------------*/
3425 VOID
3426 nicRxDisablePromiscuousMode (
3427     IN P_ADAPTER_T prAdapter
3428     )
3429 {
3430     ASSERT(prAdapter);
3431
3432     return;
3433 } /* end of nicRxDisablePromiscuousMode() */
3434
3435
3436 /*----------------------------------------------------------------------------*/
3437 /*!
3438 * @brief this function flushes all packets queued in reordering module
3439 *
3440 * @param prAdapter              Pointer to the Adapter structure.
3441 *
3442 * @retval WLAN_STATUS_SUCCESS   Flushed successfully
3443 */
3444 /*----------------------------------------------------------------------------*/
3445 WLAN_STATUS
3446 nicRxFlush (
3447     IN P_ADAPTER_T  prAdapter
3448     )
3449 {
3450     P_SW_RFB_T prSwRfb;
3451
3452     ASSERT(prAdapter);
3453
3454     if((prSwRfb = qmFlushRxQueues(prAdapter)) != NULL) {
3455         do {
3456             P_SW_RFB_T prNextSwRfb;
3457
3458             // save next first
3459             prNextSwRfb = (P_SW_RFB_T)QUEUE_GET_NEXT_ENTRY((P_QUE_ENTRY_T)prSwRfb);
3460
3461             // free
3462             nicRxReturnRFB(prAdapter, prSwRfb);
3463
3464             prSwRfb = prNextSwRfb;
3465         } while(prSwRfb);
3466     }
3467
3468     return WLAN_STATUS_SUCCESS;
3469 }
3470
3471
3472 /*----------------------------------------------------------------------------*/
3473 /*!
3474 * @brief
3475 *
3476 * @param
3477 *
3478 * @retval
3479 */
3480 /*----------------------------------------------------------------------------*/
3481 WLAN_STATUS
3482 nicRxProcessActionFrame (
3483     IN P_ADAPTER_T      prAdapter,
3484     IN P_SW_RFB_T       prSwRfb
3485     )
3486 {
3487     P_WLAN_ACTION_FRAME prActFrame;
3488
3489     ASSERT(prAdapter);
3490     ASSERT(prSwRfb);
3491
3492     if (prSwRfb->u2PacketLen < sizeof(WLAN_ACTION_FRAME) - 1) {
3493         return WLAN_STATUS_INVALID_PACKET;
3494     }
3495     prActFrame = (P_WLAN_ACTION_FRAME) prSwRfb->pvHeader;
3496
3497     switch (prActFrame->ucCategory) {
3498     case CATEGORY_PUBLIC_ACTION:
3499
3500     #if CFG_ENABLE_WIFI_DIRECT
3501         if (prAdapter->fgIsP2PRegistered) {
3502             ASSERT(prAdapter->rP2pFuncLkr.prRlmProcessPublicAction);
3503             if (prAdapter->rP2pFuncLkr.prRlmProcessPublicAction) {
3504                 prAdapter->rP2pFuncLkr.prRlmProcessPublicAction(
3505                         prAdapter, prSwRfb);
3506             }
3507
3508             ASSERT(prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame);
3509             if (prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame) {
3510                 prAdapter->rP2pFuncLkr.prP2pRxPublicActionFrame(
3511                         prAdapter, prSwRfb);
3512             }
3513         }
3514     #endif
3515         break;
3516
3517     case CATEGORY_HT_ACTION:
3518     #if CFG_ENABLE_WIFI_DIRECT
3519         if (prAdapter->fgIsP2PRegistered) {
3520             ASSERT(prAdapter->rP2pFuncLkr.prRlmProcessHtAction);
3521             if (prAdapter->rP2pFuncLkr.prRlmProcessHtAction) {
3522                 prAdapter->rP2pFuncLkr.prRlmProcessHtAction(
3523                         prAdapter, prSwRfb);
3524             }
3525         }
3526     #endif
3527         break;
3528     case CATEGORY_VENDOR_SPECIFIC_ACTION:
3529     #if CFG_ENABLE_WIFI_DIRECT
3530         if (prAdapter->fgIsP2PRegistered) {
3531             ASSERT(prAdapter->rP2pFuncLkr.prP2pRxActionFrame);
3532             if (prAdapter->rP2pFuncLkr.prP2pRxActionFrame) {
3533
3534                 prAdapter->rP2pFuncLkr.prP2pRxActionFrame(prAdapter, prSwRfb);
3535             }
3536         }
3537
3538     #endif
3539         break;
3540 #if CFG_SUPPORT_802_11W
3541     case CATEGORY_SA_QUERT_ACTION:
3542         {
3543             P_HIF_RX_HEADER_T   prHifRxHdr;
3544
3545             prHifRxHdr = prSwRfb->prHifRxHdr;
3546
3547             if ((HIF_RX_HDR_GET_NETWORK_IDX(prHifRxHdr) == NETWORK_TYPE_AIS_INDEX) &&
3548                 prAdapter->rWifiVar.rAisSpecificBssInfo.fgMgmtProtection /* Use MFP */
3549                 ) {
3550                 if (!(prHifRxHdr->ucReserved & CONTROL_FLAG_UC_MGMT_NO_ENC)) {
3551                     /* MFP test plan 5.3.3.4 */
3552                     rsnSaQueryAction(prAdapter, prSwRfb);
3553                 }
3554                 else {
3555                     DBGLOG(RSN, TRACE, ("Un-Protected SA Query, do nothing\n"));
3556                 }
3557             }
3558         }
3559         break;
3560 #endif
3561     default:
3562         break;
3563     } /* end of switch case */
3564
3565     return WLAN_STATUS_SUCCESS;
3566 }
3567
3568