Commit | Line | Data |
---|---|---|
91980990 GKH |
1 | /* |
2 | ************************************************************************* | |
3 | * Ralink Tech Inc. | |
4 | * 5F., No.36, Taiyuan St., Jhubei City, | |
5 | * Hsinchu County 302, | |
6 | * Taiwan, R.O.C. | |
7 | * | |
8 | * (c) Copyright 2002-2007, Ralink Technology, Inc. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify * | |
11 | * it under the terms of the GNU General Public License as published by * | |
12 | * the Free Software Foundation; either version 2 of the License, or * | |
13 | * (at your option) any later version. * | |
14 | * * | |
15 | * This program is distributed in the hope that it will be useful, * | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
18 | * GNU General Public License for more details. * | |
19 | * * | |
20 | * You should have received a copy of the GNU General Public License * | |
21 | * along with this program; if not, write to the * | |
22 | * Free Software Foundation, Inc., * | |
23 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |
24 | * * | |
25 | ************************************************************************* | |
26 | ||
27 | Module Name: | |
28 | rt_main_dev.c | |
29 | ||
30 | Abstract: | |
31 | Create and register network interface. | |
32 | ||
33 | Revision History: | |
34 | Who When What | |
35 | -------- ---------- ---------------------------------------------- | |
36 | Sample Mar/21/07 Merge RT2870 and RT2860 drivers. | |
37 | */ | |
38 | ||
39 | #include "rt_config.h" | |
40 | ||
41 | #define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min | |
42 | ||
91980990 GKH |
43 | /*---------------------------------------------------------------------*/ |
44 | /* Private Variables Used */ | |
45 | /*---------------------------------------------------------------------*/ | |
46 | //static RALINK_TIMER_STRUCT PeriodicTimer; | |
47 | ||
48 | char *mac = ""; // default 00:00:00:00:00:00 | |
49 | char *hostname = ""; // default CMPC | |
91980990 | 50 | module_param (mac, charp, 0); |
91980990 GKH |
51 | MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr"); |
52 | ||
53 | ||
54 | /*---------------------------------------------------------------------*/ | |
55 | /* Prototypes of Functions Used */ | |
56 | /*---------------------------------------------------------------------*/ | |
91980990 GKH |
57 | extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num); |
58 | extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd); | |
91980990 GKH |
59 | extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd); |
60 | ||
3a32ed12 | 61 | #ifdef RT2860 |
91980990 | 62 | extern void init_thread_task(PRTMP_ADAPTER pAd); |
3a32ed12 | 63 | #endif |
91980990 GKH |
64 | |
65 | // public function prototype | |
66 | INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p, | |
67 | IN UINT argc, OUT PRTMP_ADAPTER *ppAd); | |
68 | ||
69 | // private function prototype | |
70 | static int rt28xx_init(IN struct net_device *net_dev); | |
71 | INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev); | |
72 | ||
91980990 GKH |
73 | static void CfgInitHook(PRTMP_ADAPTER pAd); |
74 | ||
91980990 | 75 | extern const struct iw_handler_def rt28xx_iw_handler_def; |
91980990 | 76 | |
91980990 GKH |
77 | #if WIRELESS_EXT >= 12 |
78 | // This function will be called when query /proc | |
79 | struct iw_statistics *rt28xx_get_wireless_stats( | |
80 | IN struct net_device *net_dev); | |
81 | #endif | |
82 | ||
83 | struct net_device_stats *RT28xx_get_ether_stats( | |
84 | IN struct net_device *net_dev); | |
85 | ||
86 | /* | |
87 | ======================================================================== | |
88 | Routine Description: | |
89 | Close raxx interface. | |
90 | ||
91 | Arguments: | |
92 | *net_dev the raxx interface pointer | |
93 | ||
94 | Return Value: | |
95 | 0 Open OK | |
96 | otherwise Open Fail | |
97 | ||
98 | Note: | |
99 | 1. if open fail, kernel will not call the close function. | |
100 | 2. Free memory for | |
101 | (1) Mlme Memory Handler: MlmeHalt() | |
102 | (2) TX & RX: RTMPFreeTxRxRingMemory() | |
103 | (3) BA Reordering: ba_reordering_resource_release() | |
104 | ======================================================================== | |
105 | */ | |
106 | int MainVirtualIF_close(IN struct net_device *net_dev) | |
107 | { | |
739b7979 | 108 | RTMP_ADAPTER *pAd = net_dev->ml_priv; |
91980990 GKH |
109 | |
110 | // Sanity check for pAd | |
111 | if (pAd == NULL) | |
112 | return 0; // close ok | |
113 | ||
114 | netif_carrier_off(pAd->net_dev); | |
115 | netif_stop_queue(pAd->net_dev); | |
116 | ||
117 | ||
118 | VIRTUAL_IF_DOWN(pAd); | |
119 | ||
120 | RT_MOD_DEC_USE_COUNT(); | |
121 | ||
122 | return 0; // close ok | |
123 | } | |
124 | ||
125 | /* | |
126 | ======================================================================== | |
127 | Routine Description: | |
128 | Open raxx interface. | |
129 | ||
130 | Arguments: | |
131 | *net_dev the raxx interface pointer | |
132 | ||
133 | Return Value: | |
134 | 0 Open OK | |
135 | otherwise Open Fail | |
136 | ||
137 | Note: | |
138 | 1. if open fail, kernel will not call the close function. | |
139 | 2. Free memory for | |
140 | (1) Mlme Memory Handler: MlmeHalt() | |
141 | (2) TX & RX: RTMPFreeTxRxRingMemory() | |
142 | (3) BA Reordering: ba_reordering_resource_release() | |
143 | ======================================================================== | |
144 | */ | |
145 | int MainVirtualIF_open(IN struct net_device *net_dev) | |
146 | { | |
739b7979 | 147 | RTMP_ADAPTER *pAd = net_dev->ml_priv; |
91980990 GKH |
148 | |
149 | // Sanity check for pAd | |
150 | if (pAd == NULL) | |
151 | return 0; // close ok | |
152 | ||
153 | if (VIRTUAL_IF_UP(pAd) != 0) | |
154 | return -1; | |
155 | ||
156 | // increase MODULE use count | |
157 | RT_MOD_INC_USE_COUNT(); | |
158 | ||
159 | netif_start_queue(net_dev); | |
160 | netif_carrier_on(net_dev); | |
161 | netif_wake_queue(net_dev); | |
162 | ||
163 | return 0; | |
164 | } | |
165 | ||
166 | /* | |
167 | ======================================================================== | |
168 | Routine Description: | |
169 | Close raxx interface. | |
170 | ||
171 | Arguments: | |
172 | *net_dev the raxx interface pointer | |
173 | ||
174 | Return Value: | |
175 | 0 Open OK | |
176 | otherwise Open Fail | |
177 | ||
178 | Note: | |
179 | 1. if open fail, kernel will not call the close function. | |
180 | 2. Free memory for | |
181 | (1) Mlme Memory Handler: MlmeHalt() | |
182 | (2) TX & RX: RTMPFreeTxRxRingMemory() | |
183 | (3) BA Reordering: ba_reordering_resource_release() | |
184 | ======================================================================== | |
185 | */ | |
186 | int rt28xx_close(IN PNET_DEV dev) | |
187 | { | |
188 | struct net_device * net_dev = (struct net_device *)dev; | |
739b7979 | 189 | RTMP_ADAPTER *pAd = net_dev->ml_priv; |
91980990 GKH |
190 | BOOLEAN Cancelled = FALSE; |
191 | UINT32 i = 0; | |
3a32ed12 BZ |
192 | #ifdef RT2870 |
193 | DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup); | |
194 | DECLARE_WAITQUEUE(wait, current); | |
195 | ||
196 | //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); | |
197 | #endif // RT2870 // | |
91980990 GKH |
198 | |
199 | ||
200 | DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n")); | |
201 | ||
202 | // Sanity check for pAd | |
203 | if (pAd == NULL) | |
204 | return 0; // close ok | |
205 | ||
91980990 | 206 | { |
91980990 GKH |
207 | // If dirver doesn't wake up firmware here, |
208 | // NICLoadFirmware will hang forever when interface is up again. | |
3a32ed12 | 209 | #ifdef RT2860 |
ed291e80 AM |
210 | if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) || |
211 | RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) || | |
212 | RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) | |
3a32ed12 BZ |
213 | #endif |
214 | #ifdef RT2870 | |
215 | if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) | |
216 | #endif | |
91980990 | 217 | { |
3a32ed12 | 218 | #ifdef RT2860 |
ed291e80 | 219 | AsicForceWakeup(pAd, RTMP_HALT); |
3a32ed12 BZ |
220 | #endif |
221 | #ifdef RT2870 | |
222 | AsicForceWakeup(pAd, TRUE); | |
223 | #endif | |
91980990 GKH |
224 | } |
225 | ||
91980990 GKH |
226 | if (INFRA_ON(pAd) && |
227 | (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) | |
228 | { | |
229 | MLME_DISASSOC_REQ_STRUCT DisReq; | |
230 | MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG); | |
231 | ||
232 | COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid); | |
233 | DisReq.Reason = REASON_DEAUTH_STA_LEAVING; | |
234 | ||
235 | MsgElem->Machine = ASSOC_STATE_MACHINE; | |
236 | MsgElem->MsgType = MT2_MLME_DISASSOC_REQ; | |
237 | MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT); | |
238 | NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT)); | |
239 | ||
240 | // Prevent to connect AP again in STAMlmePeriodicExec | |
241 | pAd->MlmeAux.AutoReconnectSsidLen= 32; | |
242 | NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); | |
243 | ||
244 | pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC; | |
245 | MlmeDisassocReqAction(pAd, MsgElem); | |
246 | kfree(MsgElem); | |
247 | ||
248 | RTMPusecDelay(1000); | |
249 | } | |
250 | ||
3a32ed12 BZ |
251 | #ifdef RT2870 |
252 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); | |
253 | #endif // RT2870 // | |
91980990 GKH |
254 | |
255 | #ifdef CCX_SUPPORT | |
256 | RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled); | |
257 | #endif | |
258 | ||
259 | RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled); | |
260 | RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled); | |
261 | ||
91980990 | 262 | MlmeRadioOff(pAd); |
3a32ed12 | 263 | #ifdef RT2860 |
91980990 | 264 | pAd->bPCIclkOff = FALSE; |
3a32ed12 | 265 | #endif |
91980990 | 266 | } |
91980990 GKH |
267 | |
268 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); | |
269 | ||
270 | for (i = 0 ; i < NUM_OF_TX_RING; i++) | |
271 | { | |
272 | while (pAd->DeQueueRunning[i] == TRUE) | |
273 | { | |
274 | printk("Waiting for TxQueue[%d] done..........\n", i); | |
275 | RTMPusecDelay(1000); | |
276 | } | |
277 | } | |
278 | ||
3a32ed12 BZ |
279 | #ifdef RT2870 |
280 | // ensure there are no more active urbs. | |
281 | add_wait_queue (&unlink_wakeup, &wait); | |
282 | pAd->wait = &unlink_wakeup; | |
283 | ||
284 | // maybe wait for deletions to finish. | |
285 | i = 0; | |
286 | //while((i < 25) && atomic_read(&pAd->PendingRx) > 0) | |
287 | while(i < 25) | |
288 | { | |
289 | unsigned long IrqFlags; | |
290 | ||
291 | RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags); | |
292 | if (pAd->PendingRx == 0) | |
293 | { | |
294 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
295 | break; | |
296 | } | |
297 | RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags); | |
298 | ||
299 | msleep(UNLINK_TIMEOUT_MS); //Time in millisecond | |
300 | i++; | |
301 | } | |
302 | pAd->wait = NULL; | |
303 | remove_wait_queue (&unlink_wakeup, &wait); | |
304 | #endif // RT2870 // | |
305 | ||
306 | #ifdef RT2870 | |
307 | // We need clear timerQ related structure before exits of the timer thread. | |
308 | RT2870_TimerQ_Exit(pAd); | |
309 | // Close kernel threads or tasklets | |
310 | RT28xxThreadTerminate(pAd); | |
311 | #endif // RT2870 // | |
312 | ||
91980990 GKH |
313 | // Stop Mlme state machine |
314 | MlmeHalt(pAd); | |
315 | ||
316 | // Close kernel threads or tasklets | |
317 | kill_thread_task(pAd); | |
318 | ||
5a911fd6 | 319 | MacTableReset(pAd); |
91980990 GKH |
320 | |
321 | MeasureReqTabExit(pAd); | |
322 | TpcReqTabExit(pAd); | |
323 | ||
3a32ed12 | 324 | #ifdef RT2860 |
91980990 GKH |
325 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) |
326 | { | |
327 | NICDisableInterrupt(pAd); | |
328 | } | |
329 | ||
330 | // Disable Rx, register value supposed will remain after reset | |
331 | NICIssueReset(pAd); | |
332 | ||
333 | // Free IRQ | |
334 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) | |
335 | { | |
336 | // Deregister interrupt function | |
337 | RT28XX_IRQ_RELEASE(net_dev) | |
338 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); | |
339 | } | |
3a32ed12 | 340 | #endif |
91980990 GKH |
341 | |
342 | // Free Ring or USB buffers | |
343 | RTMPFreeTxRxRingMemory(pAd); | |
344 | ||
345 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); | |
346 | ||
91980990 GKH |
347 | // Free BA reorder resource |
348 | ba_reordering_resource_release(pAd); | |
91980990 GKH |
349 | |
350 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP); | |
351 | ||
352 | return 0; // close ok | |
353 | } /* End of rt28xx_close */ | |
354 | ||
355 | static int rt28xx_init(IN struct net_device *net_dev) | |
356 | { | |
3a32ed12 | 357 | #ifdef RT2860 |
739b7979 | 358 | PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)net_dev->ml_priv; |
3a32ed12 BZ |
359 | #endif |
360 | #ifdef RT2870 | |
361 | PRTMP_ADAPTER pAd = net_dev->ml_priv; | |
362 | #endif | |
91980990 GKH |
363 | UINT index; |
364 | UCHAR TmpPhy; | |
365 | NDIS_STATUS Status; | |
366 | UINT32 MacCsr0 = 0; | |
367 | ||
91980990 GKH |
368 | // Allocate BA Reordering memory |
369 | ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM); | |
91980990 GKH |
370 | |
371 | // Make sure MAC gets ready. | |
372 | index = 0; | |
373 | do | |
374 | { | |
375 | RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0); | |
376 | pAd->MACVersion = MacCsr0; | |
377 | ||
378 | if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF)) | |
379 | break; | |
380 | ||
381 | RTMPusecDelay(10); | |
382 | } while (index++ < 100); | |
383 | ||
384 | DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion)); | |
3a32ed12 | 385 | /*Iverson patch PCIE L1 issue */ |
91980990 GKH |
386 | |
387 | // Disable DMA | |
388 | RT28XXDMADisable(pAd); | |
389 | ||
91980990 GKH |
390 | // Load 8051 firmware |
391 | Status = NICLoadFirmware(pAd); | |
392 | if (Status != NDIS_STATUS_SUCCESS) | |
393 | { | |
394 | DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status)); | |
395 | goto err1; | |
396 | } | |
397 | ||
398 | NICLoadRateSwitchingParams(pAd); | |
399 | ||
400 | // Disable interrupts here which is as soon as possible | |
401 | // This statement should never be true. We might consider to remove it later | |
3a32ed12 | 402 | #ifdef RT2860 |
91980990 GKH |
403 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) |
404 | { | |
405 | NICDisableInterrupt(pAd); | |
406 | } | |
3a32ed12 | 407 | #endif |
91980990 GKH |
408 | |
409 | Status = RTMPAllocTxRxRingMemory(pAd); | |
410 | if (Status != NDIS_STATUS_SUCCESS) | |
411 | { | |
412 | DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status)); | |
413 | goto err1; | |
414 | } | |
415 | ||
416 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); | |
417 | ||
418 | // initialize MLME | |
419 | // | |
420 | ||
421 | Status = MlmeInit(pAd); | |
422 | if (Status != NDIS_STATUS_SUCCESS) | |
423 | { | |
424 | DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); | |
425 | goto err2; | |
426 | } | |
427 | ||
428 | // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default | |
429 | // | |
430 | UserCfgInit(pAd); | |
431 | ||
3a32ed12 BZ |
432 | #ifdef RT2870 |
433 | // We need init timerQ related structure before create the timer thread. | |
434 | RT2870_TimerQ_Init(pAd); | |
435 | #endif // RT2870 // | |
91980990 GKH |
436 | |
437 | RT28XX_TASK_THREAD_INIT(pAd, Status); | |
438 | if (Status != NDIS_STATUS_SUCCESS) | |
439 | goto err1; | |
440 | ||
441 | CfgInitHook(pAd); | |
442 | ||
5a911fd6 | 443 | NdisAllocateSpinLock(&pAd->MacTabLock); |
91980990 GKH |
444 | |
445 | MeasureReqTabInit(pAd); | |
446 | TpcReqTabInit(pAd); | |
447 | ||
448 | // | |
449 | // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset | |
450 | // | |
451 | Status = NICInitializeAdapter(pAd, TRUE); | |
452 | if (Status != NDIS_STATUS_SUCCESS) | |
453 | { | |
454 | DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status)); | |
455 | if (Status != NDIS_STATUS_SUCCESS) | |
456 | goto err3; | |
457 | } | |
458 | ||
459 | // Read parameters from Config File | |
460 | Status = RTMPReadParametersHook(pAd); | |
461 | ||
462 | printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); | |
463 | if (Status != NDIS_STATUS_SUCCESS) | |
464 | { | |
465 | DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status)); | |
466 | goto err4; | |
467 | } | |
468 | ||
3a32ed12 BZ |
469 | #ifdef RT2870 |
470 | pAd->CommonCfg.bMultipleIRP = FALSE; | |
471 | ||
472 | if (pAd->CommonCfg.bMultipleIRP) | |
473 | pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE; | |
474 | else | |
475 | pAd->CommonCfg.NumOfBulkInIRP = 1; | |
476 | #endif // RT2870 // | |
91980990 GKH |
477 | |
478 | ||
479 | //Init Ba Capability parameters. | |
91980990 GKH |
480 | pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; |
481 | pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable; | |
482 | pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; | |
483 | pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; | |
484 | // UPdata to HT IE | |
485 | pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode; | |
486 | pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize; | |
487 | pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity; | |
91980990 GKH |
488 | |
489 | printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); | |
490 | ||
491 | // We should read EEPROM for all cases. rt2860b | |
492 | NICReadEEPROMParameters(pAd, mac); | |
493 | ||
494 | printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode); | |
495 | ||
496 | NICInitAsicFromEEPROM(pAd); //rt2860b | |
497 | ||
498 | // Set PHY to appropriate mode | |
499 | TmpPhy = pAd->CommonCfg.PhyMode; | |
500 | pAd->CommonCfg.PhyMode = 0xff; | |
501 | RTMPSetPhyMode(pAd, TmpPhy); | |
91980990 | 502 | SetCommonHT(pAd); |
91980990 GKH |
503 | |
504 | // No valid channels. | |
505 | if (pAd->ChannelListNum == 0) | |
506 | { | |
507 | printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"); | |
508 | goto err4; | |
509 | } | |
510 | ||
91980990 GKH |
511 | printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0], |
512 | pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2], | |
513 | pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]); | |
91980990 | 514 | |
3a32ed12 BZ |
515 | #ifdef RT2870 |
516 | //Init RT30xx RFRegisters after read RFIC type from EEPROM | |
517 | NICInitRT30xxRFRegisters(pAd); | |
518 | #endif // RT2870 // | |
519 | ||
91980990 GKH |
520 | #ifdef IKANOS_VX_1X0 |
521 | VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress); | |
522 | #endif // IKANOS_VX_1X0 // | |
523 | ||
524 | // | |
525 | // Initialize RF register to default value | |
526 | // | |
527 | AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); | |
528 | AsicLockChannel(pAd, pAd->CommonCfg.Channel); | |
529 | ||
3a32ed12 | 530 | #ifndef RT30xx |
91980990 GKH |
531 | // 8051 firmware require the signal during booting time. |
532 | AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); | |
3a32ed12 | 533 | #endif |
91980990 GKH |
534 | |
535 | if (pAd && (Status != NDIS_STATUS_SUCCESS)) | |
536 | { | |
537 | // | |
538 | // Undo everything if it failed | |
539 | // | |
540 | if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) | |
541 | { | |
542 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE); | |
543 | } | |
544 | } | |
545 | else if (pAd) | |
546 | { | |
547 | // Microsoft HCT require driver send a disconnect event after driver initialization. | |
548 | OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); | |
549 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE); | |
3a32ed12 | 550 | |
91980990 GKH |
551 | DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n")); |
552 | ||
553 | ||
3a32ed12 BZ |
554 | #ifdef RT2870 |
555 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); | |
556 | RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); | |
557 | ||
558 | // | |
559 | // Support multiple BulkIn IRP, | |
560 | // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. | |
561 | // | |
562 | for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++) | |
563 | { | |
564 | RTUSBBulkReceive(pAd); | |
565 | DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" )); | |
566 | } | |
567 | #endif // RT2870 // | |
91980990 GKH |
568 | }// end of else |
569 | ||
570 | ||
571 | DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status)); | |
572 | ||
573 | return TRUE; | |
574 | ||
575 | ||
576 | err4: | |
577 | err3: | |
578 | MlmeHalt(pAd); | |
579 | err2: | |
580 | RTMPFreeTxRxRingMemory(pAd); | |
581 | err1: | |
91980990 | 582 | os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool |
91980990 GKH |
583 | RT28XX_IRQ_RELEASE(net_dev); |
584 | ||
739b7979 GKH |
585 | // shall not set ml_priv to NULL here because the ml_priv didn't been free yet. |
586 | //net_dev->ml_priv = 0; | |
2074a80c | 587 | |
91980990 GKH |
588 | printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME); |
589 | return FALSE; | |
590 | } /* End of rt28xx_init */ | |
591 | ||
592 | ||
593 | /* | |
594 | ======================================================================== | |
595 | Routine Description: | |
596 | Open raxx interface. | |
597 | ||
598 | Arguments: | |
599 | *net_dev the raxx interface pointer | |
600 | ||
601 | Return Value: | |
602 | 0 Open OK | |
603 | otherwise Open Fail | |
604 | ||
605 | Note: | |
606 | ======================================================================== | |
607 | */ | |
608 | int rt28xx_open(IN PNET_DEV dev) | |
609 | { | |
610 | struct net_device * net_dev = (struct net_device *)dev; | |
739b7979 | 611 | PRTMP_ADAPTER pAd = net_dev->ml_priv; |
91980990 GKH |
612 | int retval = 0; |
613 | POS_COOKIE pObj; | |
614 | ||
615 | ||
616 | // Sanity check for pAd | |
617 | if (pAd == NULL) | |
618 | { | |
619 | /* if 1st open fail, pAd will be free; | |
739b7979 | 620 | So the net_dev->ml_priv will be NULL in 2rd open */ |
91980990 GKH |
621 | return -1; |
622 | } | |
623 | ||
91980990 GKH |
624 | // Init |
625 | pObj = (POS_COOKIE)pAd->OS_Cookie; | |
626 | ||
627 | // reset Adapter flags | |
628 | RTMP_CLEAR_FLAGS(pAd); | |
629 | ||
630 | // Request interrupt service routine for PCI device | |
631 | // register the interrupt routine with the os | |
632 | RT28XX_IRQ_REQUEST(net_dev); | |
633 | ||
634 | ||
635 | // Init BssTab & ChannelInfo tabbles for auto channel select. | |
636 | ||
637 | ||
638 | // Chip & other init | |
639 | if (rt28xx_init(net_dev) == FALSE) | |
640 | goto err; | |
641 | ||
5a911fd6 BZ |
642 | NdisZeroMemory(pAd->StaCfg.dev_name, 16); |
643 | NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name)); | |
91980990 GKH |
644 | |
645 | // Set up the Mac address | |
646 | NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6); | |
647 | ||
648 | // Init IRQ parameters | |
649 | RT28XX_IRQ_INIT(pAd); | |
650 | ||
651 | // Various AP function init | |
652 | ||
91980990 GKH |
653 | // Enable Interrupt |
654 | RT28XX_IRQ_ENABLE(pAd); | |
655 | ||
656 | // Now Enable RxTx | |
657 | RTMPEnableRxTx(pAd); | |
658 | RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP); | |
659 | ||
660 | { | |
661 | UINT32 reg = 0; | |
662 | RTMP_IO_READ32(pAd, 0x1300, ®); // clear garbage interrupts | |
663 | printk("0x1300 = %08x\n", reg); | |
664 | } | |
665 | ||
3a32ed12 | 666 | #ifdef RT2860 |
91980990 | 667 | RTMPInitPCIeLinkCtrlValue(pAd); |
3a32ed12 | 668 | #endif |
91980990 GKH |
669 | return (retval); |
670 | ||
671 | err: | |
672 | return (-1); | |
673 | } /* End of rt28xx_open */ | |
674 | ||
ca7d2dbb AB |
675 | static const struct net_device_ops rt2860_netdev_ops = { |
676 | .ndo_open = MainVirtualIF_open, | |
677 | .ndo_stop = MainVirtualIF_close, | |
678 | .ndo_do_ioctl = rt28xx_ioctl, | |
679 | .ndo_get_stats = RT28xx_get_ether_stats, | |
680 | .ndo_validate_addr = NULL, | |
681 | .ndo_set_mac_address = eth_mac_addr, | |
682 | .ndo_change_mtu = eth_change_mtu, | |
683 | #ifdef IKANOS_VX_1X0 | |
684 | .ndo_start_xmit = IKANOS_DataFramesTx, | |
685 | #else | |
686 | .ndo_start_xmit = rt28xx_send_packets, | |
687 | #endif | |
688 | }; | |
91980990 GKH |
689 | |
690 | /* Must not be called for mdev and apdev */ | |
691 | static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd) | |
692 | { | |
693 | NDIS_STATUS Status; | |
694 | INT i=0; | |
695 | CHAR slot_name[IFNAMSIZ]; | |
696 | struct net_device *device; | |
697 | ||
91980990 GKH |
698 | #if WIRELESS_EXT >= 12 |
699 | if (pAd->OpMode == OPMODE_STA) | |
700 | { | |
701 | dev->wireless_handlers = &rt28xx_iw_handler_def; | |
702 | } | |
703 | #endif //WIRELESS_EXT >= 12 | |
91980990 | 704 | |
91980990 GKH |
705 | #if WIRELESS_EXT < 21 |
706 | dev->get_wireless_stats = rt28xx_get_wireless_stats; | |
707 | #endif | |
91980990 | 708 | dev->priv_flags = INT_MAIN; |
ca7d2dbb | 709 | dev->netdev_ops = &rt2860_netdev_ops; |
91980990 GKH |
710 | // find available device name |
711 | for (i = 0; i < 8; i++) | |
712 | { | |
91980990 GKH |
713 | sprintf(slot_name, "ra%d", i); |
714 | ||
7f20a18d PE |
715 | device = dev_get_by_name(dev_net(dev), slot_name); |
716 | if (device != NULL) | |
717 | dev_put(device); | |
718 | ||
719 | if (device == NULL) | |
91980990 GKH |
720 | break; |
721 | } | |
722 | ||
723 | if(i == 8) | |
724 | { | |
725 | DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n")); | |
726 | Status = NDIS_STATUS_FAILURE; | |
727 | } | |
728 | else | |
729 | { | |
91980990 GKH |
730 | sprintf(dev->name, "ra%d", i); |
731 | Status = NDIS_STATUS_SUCCESS; | |
732 | } | |
733 | ||
734 | return Status; | |
735 | ||
736 | } | |
737 | ||
91980990 GKH |
738 | /* |
739 | ======================================================================== | |
740 | Routine Description: | |
741 | Probe RT28XX chipset. | |
742 | ||
743 | Arguments: | |
744 | _dev_p Point to the PCI or USB device | |
745 | _dev_id_p Point to the PCI or USB device ID | |
746 | ||
747 | Return Value: | |
748 | 0 Probe OK | |
749 | -ENODEV Probe Fail | |
750 | ||
751 | Note: | |
752 | ======================================================================== | |
753 | */ | |
754 | INT __devinit rt28xx_probe( | |
755 | IN void *_dev_p, | |
756 | IN void *_dev_id_p, | |
757 | IN UINT argc, | |
758 | OUT PRTMP_ADAPTER *ppAd) | |
759 | { | |
760 | struct net_device *net_dev; | |
761 | PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL; | |
762 | INT status; | |
763 | PVOID handle; | |
3a32ed12 | 764 | #ifdef RT2860 |
91980990 | 765 | struct pci_dev *dev_p = (struct pci_dev *)_dev_p; |
3a32ed12 BZ |
766 | #endif |
767 | #ifdef RT2870 | |
768 | struct usb_interface *intf = (struct usb_interface *)_dev_p; | |
769 | struct usb_device *dev_p = interface_to_usbdev(intf); | |
91980990 | 770 | |
3a32ed12 BZ |
771 | dev_p = usb_get_dev(dev_p); |
772 | #endif // RT2870 // | |
91980990 | 773 | |
91980990 | 774 | DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION)); |
91980990 | 775 | |
91980990 | 776 | net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER)); |
91980990 GKH |
777 | if (net_dev == NULL) |
778 | { | |
779 | printk("alloc_netdev failed\n"); | |
780 | ||
91980990 GKH |
781 | goto err_out; |
782 | } | |
783 | ||
91980990 | 784 | netif_stop_queue(net_dev); |
2684d166 | 785 | |
91980990 GKH |
786 | /* for supporting Network Manager */ |
787 | /* Set the sysfs physical device reference for the network logical device | |
788 | * if set prior to registration will cause a symlink during initialization. | |
789 | */ | |
91980990 | 790 | SET_NETDEV_DEV(net_dev, &(dev_p->dev)); |
91980990 GKH |
791 | |
792 | // Allocate RTMP_ADAPTER miniport adapter structure | |
793 | handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL); | |
794 | RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p); | |
795 | ||
796 | status = RTMPAllocAdapterBlock(handle, &pAd); | |
797 | if (status != NDIS_STATUS_SUCCESS) | |
798 | goto err_out_free_netdev; | |
799 | ||
739b7979 | 800 | net_dev->ml_priv = (PVOID)pAd; |
91980990 GKH |
801 | pAd->net_dev = net_dev; // must be before RT28XXNetDevInit() |
802 | ||
803 | RT28XXNetDevInit(_dev_p, net_dev, pAd); | |
804 | ||
91980990 | 805 | pAd->StaCfg.OriDevType = net_dev->type; |
91980990 GKH |
806 | |
807 | // Post config | |
91980990 GKH |
808 | if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE) |
809 | goto err_out_unmap; | |
91980990 | 810 | |
91980990 | 811 | pAd->OpMode = OPMODE_STA; |
91980990 | 812 | |
91980990 GKH |
813 | // sample move |
814 | if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS) | |
815 | goto err_out_unmap; | |
816 | ||
817 | // Register this device | |
818 | status = register_netdev(net_dev); | |
819 | if (status) | |
820 | goto err_out_unmap; | |
821 | ||
822 | // Set driver data | |
823 | RT28XX_DRVDATA_SET(_dev_p); | |
824 | ||
825 | *ppAd = pAd; | |
826 | return 0; // probe ok | |
827 | ||
828 | ||
829 | /* --------------------------- ERROR HANDLE --------------------------- */ | |
830 | err_out_unmap: | |
831 | RTMPFreeAdapter(pAd); | |
832 | RT28XX_UNMAP(); | |
833 | ||
834 | err_out_free_netdev: | |
7f20a18d | 835 | free_netdev(net_dev); |
91980990 GKH |
836 | |
837 | err_out: | |
838 | RT28XX_PUT_DEVICE(dev_p); | |
839 | ||
7f20a18d | 840 | return -ENODEV; /* probe fail */ |
91980990 GKH |
841 | } /* End of rt28xx_probe */ |
842 | ||
843 | ||
844 | /* | |
845 | ======================================================================== | |
846 | Routine Description: | |
847 | The entry point for Linux kernel sent packet to our driver. | |
848 | ||
849 | Arguments: | |
850 | sk_buff *skb the pointer refer to a sk_buffer. | |
851 | ||
852 | Return Value: | |
853 | 0 | |
854 | ||
855 | Note: | |
856 | This function is the entry point of Tx Path for Os delivery packet to | |
857 | our driver. You only can put OS-depened & STA/AP common handle procedures | |
858 | in here. | |
859 | ======================================================================== | |
860 | */ | |
861 | int rt28xx_packet_xmit(struct sk_buff *skb) | |
862 | { | |
863 | struct net_device *net_dev = skb->dev; | |
739b7979 | 864 | PRTMP_ADAPTER pAd = net_dev->ml_priv; |
ec634fe3 | 865 | int status = NETDEV_TX_OK; |
91980990 GKH |
866 | PNDIS_PACKET pPacket = (PNDIS_PACKET) skb; |
867 | ||
91980990 GKH |
868 | { |
869 | // Drop send request since we are in monitor mode | |
870 | if (MONITOR_ON(pAd)) | |
871 | { | |
872 | RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); | |
873 | goto done; | |
874 | } | |
875 | } | |
91980990 GKH |
876 | |
877 | // EapolStart size is 18 | |
878 | if (skb->len < 14) | |
879 | { | |
880 | //printk("bad packet size: %d\n", pkt->len); | |
881 | hex_dump("bad packet", skb->data, skb->len); | |
882 | RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); | |
883 | goto done; | |
884 | } | |
885 | ||
886 | RTMP_SET_PACKET_5VT(pPacket, 0); | |
887 | #ifdef CONFIG_5VT_ENHANCE | |
888 | if (*(int*)(skb->cb) == BRIDGE_TAG) { | |
889 | RTMP_SET_PACKET_5VT(pPacket, 1); | |
890 | } | |
891 | #endif | |
892 | ||
5a911fd6 | 893 | STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1); |
91980990 | 894 | |
ec634fe3 | 895 | status = NETDEV_TX_OK; |
91980990 GKH |
896 | done: |
897 | ||
898 | return status; | |
899 | } | |
900 | ||
901 | ||
902 | /* | |
903 | ======================================================================== | |
904 | Routine Description: | |
905 | Send a packet to WLAN. | |
906 | ||
907 | Arguments: | |
908 | skb_p points to our adapter | |
909 | dev_p which WLAN network interface | |
910 | ||
911 | Return Value: | |
912 | 0: transmit successfully | |
913 | otherwise: transmit fail | |
914 | ||
915 | Note: | |
916 | ======================================================================== | |
917 | */ | |
918 | INT rt28xx_send_packets( | |
919 | IN struct sk_buff *skb_p, | |
920 | IN struct net_device *net_dev) | |
921 | { | |
739b7979 | 922 | RTMP_ADAPTER *pAd = net_dev->ml_priv; |
91980990 GKH |
923 | if (!(net_dev->flags & IFF_UP)) |
924 | { | |
925 | RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE); | |
ec634fe3 | 926 | return NETDEV_TX_OK; |
91980990 GKH |
927 | } |
928 | ||
929 | NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15); | |
930 | RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID); | |
931 | ||
932 | return rt28xx_packet_xmit(skb_p); | |
933 | ||
934 | } /* End of MBSS_VirtualIF_PacketSend */ | |
935 | ||
936 | ||
937 | ||
938 | ||
91980990 GKH |
939 | void CfgInitHook(PRTMP_ADAPTER pAd) |
940 | { | |
941 | pAd->bBroadComHT = TRUE; | |
942 | } /* End of CfgInitHook */ | |
943 | ||
944 | ||
945 | #if WIRELESS_EXT >= 12 | |
946 | // This function will be called when query /proc | |
947 | struct iw_statistics *rt28xx_get_wireless_stats( | |
948 | IN struct net_device *net_dev) | |
949 | { | |
739b7979 | 950 | PRTMP_ADAPTER pAd = net_dev->ml_priv; |
91980990 GKH |
951 | |
952 | ||
953 | DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n")); | |
954 | ||
955 | pAd->iw_stats.status = 0; // Status - device dependent for now | |
956 | ||
957 | // link quality | |
958 | pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10); | |
959 | if(pAd->iw_stats.qual.qual > 100) | |
960 | pAd->iw_stats.qual.qual = 100; | |
961 | ||
91980990 GKH |
962 | if (pAd->OpMode == OPMODE_STA) |
963 | pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2); | |
91980990 GKH |
964 | |
965 | pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm) | |
966 | ||
967 | pAd->iw_stats.qual.noise += 256 - 143; | |
968 | pAd->iw_stats.qual.updated = 1; // Flags to know if updated | |
969 | #ifdef IW_QUAL_DBM | |
970 | pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm | |
971 | #endif // IW_QUAL_DBM // | |
972 | ||
973 | pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid | |
974 | pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe | |
975 | ||
976 | DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n")); | |
977 | return &pAd->iw_stats; | |
978 | } /* End of rt28xx_get_wireless_stats */ | |
979 | #endif // WIRELESS_EXT // | |
980 | ||
981 | ||
982 | ||
983 | void tbtt_tasklet(unsigned long data) | |
984 | { | |
985 | #define MAX_TX_IN_TBTT (16) | |
986 | ||
987 | } | |
988 | ||
989 | INT rt28xx_ioctl( | |
990 | IN struct net_device *net_dev, | |
991 | IN OUT struct ifreq *rq, | |
992 | IN INT cmd) | |
993 | { | |
994 | VIRTUAL_ADAPTER *pVirtualAd = NULL; | |
995 | RTMP_ADAPTER *pAd = NULL; | |
996 | INT ret = 0; | |
997 | ||
998 | if (net_dev->priv_flags == INT_MAIN) | |
999 | { | |
739b7979 | 1000 | pAd = net_dev->ml_priv; |
91980990 GKH |
1001 | } |
1002 | else | |
1003 | { | |
739b7979 GKH |
1004 | pVirtualAd = net_dev->ml_priv; |
1005 | pAd = pVirtualAd->RtmpDev->ml_priv; | |
91980990 GKH |
1006 | } |
1007 | ||
1008 | if (pAd == NULL) | |
1009 | { | |
1010 | /* if 1st open fail, pAd will be free; | |
739b7979 | 1011 | So the net_dev->ml_priv will be NULL in 2rd open */ |
91980990 GKH |
1012 | return -ENETDOWN; |
1013 | } | |
1014 | ||
5a911fd6 | 1015 | ret = rt28xx_sta_ioctl(net_dev, rq, cmd); |
91980990 GKH |
1016 | |
1017 | return ret; | |
1018 | } | |
1019 | ||
1020 | /* | |
1021 | ======================================================================== | |
1022 | ||
1023 | Routine Description: | |
1024 | return ethernet statistics counter | |
1025 | ||
1026 | Arguments: | |
1027 | net_dev Pointer to net_device | |
1028 | ||
1029 | Return Value: | |
1030 | net_device_stats* | |
1031 | ||
1032 | Note: | |
1033 | ||
1034 | ======================================================================== | |
1035 | */ | |
1036 | struct net_device_stats *RT28xx_get_ether_stats( | |
1037 | IN struct net_device *net_dev) | |
1038 | { | |
1039 | RTMP_ADAPTER *pAd = NULL; | |
1040 | ||
1041 | if (net_dev) | |
739b7979 | 1042 | pAd = net_dev->ml_priv; |
91980990 GKH |
1043 | |
1044 | if (pAd) | |
1045 | { | |
1046 | ||
1047 | pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart; | |
1048 | pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart; | |
1049 | ||
1050 | pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount; | |
1051 | pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount; | |
1052 | ||
1053 | pAd->stats.rx_errors = pAd->Counters8023.RxErrors; | |
1054 | pAd->stats.tx_errors = pAd->Counters8023.TxErrors; | |
1055 | ||
1056 | pAd->stats.rx_dropped = 0; | |
1057 | pAd->stats.tx_dropped = 0; | |
1058 | ||
1059 | pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received | |
1060 | pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets | |
1061 | ||
1062 | pAd->stats.rx_length_errors = 0; | |
1063 | pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow | |
1064 | pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error | |
1065 | pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error | |
1066 | pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun | |
1067 | pAd->stats.rx_missed_errors = 0; // receiver missed packet | |
1068 | ||
1069 | // detailed tx_errors | |
1070 | pAd->stats.tx_aborted_errors = 0; | |
1071 | pAd->stats.tx_carrier_errors = 0; | |
1072 | pAd->stats.tx_fifo_errors = 0; | |
1073 | pAd->stats.tx_heartbeat_errors = 0; | |
1074 | pAd->stats.tx_window_errors = 0; | |
1075 | ||
1076 | // for cslip etc | |
1077 | pAd->stats.rx_compressed = 0; | |
1078 | pAd->stats.tx_compressed = 0; | |
1079 | ||
1080 | return &pAd->stats; | |
1081 | } | |
1082 | else | |
1083 | return NULL; | |
1084 | } | |
1085 |