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