1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#include "rt_config.h"
40
41
42
43
44
45char *mac = "";
46char *hostname = "";
47module_param(mac, charp, 0);
48MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr");
49
50
51
52
53
54
55int rt28xx_close(IN struct net_device *net_dev);
56int rt28xx_open(struct net_device *net_dev);
57
58
59static int rt28xx_send_packets(IN struct sk_buff *skb_p,
60 IN struct net_device *net_dev);
61
62static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
63 *net_dev);
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85int MainVirtualIF_close(IN struct net_device *net_dev)
86{
87 struct rt_rtmp_adapter *pAd = NULL;
88
89 GET_PAD_FROM_NET_DEV(pAd, net_dev);
90
91
92 if (pAd == NULL)
93 return 0;
94
95 netif_carrier_off(pAd->net_dev);
96 netif_stop_queue(pAd->net_dev);
97
98 {
99 BOOLEAN Cancelled;
100
101 if (INFRA_ON(pAd) &&
102 (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
103 struct rt_mlme_disassoc_req DisReq;
104 struct rt_mlme_queue_elem *MsgElem =
105 kmalloc(sizeof(struct rt_mlme_queue_elem),
106 MEM_ALLOC_FLAG);
107
108 if (MsgElem) {
109 COPY_MAC_ADDR(DisReq.Addr,
110 pAd->CommonCfg.Bssid);
111 DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
112
113 MsgElem->Machine = ASSOC_STATE_MACHINE;
114 MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
115 MsgElem->MsgLen =
116 sizeof(struct rt_mlme_disassoc_req);
117 NdisMoveMemory(MsgElem->Msg, &DisReq,
118 sizeof
119 (struct rt_mlme_disassoc_req));
120
121
122 pAd->MlmeAux.AutoReconnectSsidLen = 32;
123 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
124 pAd->MlmeAux.
125 AutoReconnectSsidLen);
126
127 pAd->Mlme.CntlMachine.CurrState =
128 CNTL_WAIT_OID_DISASSOC;
129 MlmeDisassocReqAction(pAd, MsgElem);
130 kfree(MsgElem);
131 }
132
133 RTMPusecDelay(1000);
134 }
135
136 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer,
137 &Cancelled);
138 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
139 &Cancelled);
140 }
141
142 VIRTUAL_IF_DOWN(pAd);
143
144 RT_MOD_DEC_USE_COUNT();
145
146 return 0;
147}
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169int MainVirtualIF_open(IN struct net_device *net_dev)
170{
171 struct rt_rtmp_adapter *pAd = NULL;
172
173 GET_PAD_FROM_NET_DEV(pAd, net_dev);
174
175
176 if (pAd == NULL)
177 return 0;
178
179 if (VIRTUAL_IF_UP(pAd) != 0)
180 return -1;
181
182
183 RT_MOD_INC_USE_COUNT();
184
185 netif_start_queue(net_dev);
186 netif_carrier_on(net_dev);
187 netif_wake_queue(net_dev);
188
189 return 0;
190}
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212int rt28xx_close(struct net_device *dev)
213{
214 struct net_device *net_dev = (struct net_device *)dev;
215 struct rt_rtmp_adapter *pAd = NULL;
216 BOOLEAN Cancelled;
217 u32 i = 0;
218
219#ifdef RTMP_MAC_USB
220 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
221 DECLARE_WAITQUEUE(wait, current);
222#endif
223
224 GET_PAD_FROM_NET_DEV(pAd, net_dev);
225
226 DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
227
228 Cancelled = FALSE;
229
230 if (pAd == NULL)
231 return 0;
232
233 {
234#ifdef RTMP_MAC_PCI
235 RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
236#endif
237
238
239
240 if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
241 AsicForceWakeup(pAd, TRUE);
242 }
243#ifdef RTMP_MAC_USB
244 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
245#endif
246
247 MlmeRadioOff(pAd);
248#ifdef RTMP_MAC_PCI
249 pAd->bPCIclkOff = FALSE;
250#endif
251 }
252
253 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
254
255 for (i = 0; i < NUM_OF_TX_RING; i++) {
256 while (pAd->DeQueueRunning[i] == TRUE) {
257 DBGPRINT(RT_DEBUG_TRACE,
258 ("Waiting for TxQueue[%d] done..........\n",
259 i));
260 RTMPusecDelay(1000);
261 }
262 }
263
264#ifdef RTMP_MAC_USB
265
266 add_wait_queue(&unlink_wakeup, &wait);
267 pAd->wait = &unlink_wakeup;
268
269
270 i = 0;
271
272 while (i < 25) {
273 unsigned long IrqFlags;
274
275 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
276 if (pAd->PendingRx == 0) {
277 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
278 break;
279 }
280 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
281
282 msleep(UNLINK_TIMEOUT_MS);
283 i++;
284 }
285 pAd->wait = NULL;
286 remove_wait_queue(&unlink_wakeup, &wait);
287#endif
288
289
290 MlmeHalt(pAd);
291
292
293 RtmpNetTaskExit(pAd);
294
295 {
296 MacTableReset(pAd);
297 }
298
299 MeasureReqTabExit(pAd);
300 TpcReqTabExit(pAd);
301
302
303 RtmpMgmtTaskExit(pAd);
304
305#ifdef RTMP_MAC_PCI
306 {
307 BOOLEAN brc;
308
309
310 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
311 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
312 }
313
314
315
316
317
318 brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
319
320
321 pAd->bPCIclkOff = FALSE;
322
323 if (brc == FALSE) {
324 DBGPRINT(RT_DEBUG_ERROR,
325 ("%s call RT28xxPciAsicRadioOff fail!\n",
326 __func__));
327 }
328 }
329
330
331
332
333
334
335
336
337
338
339#endif
340
341
342 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
343#ifdef RTMP_MAC_PCI
344
345 RtmpOSIRQRelease(net_dev);
346#endif
347 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
348 }
349
350 RTMPFreeTxRxRingMemory(pAd);
351
352 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
353
354
355 ba_reordering_resource_release(pAd);
356
357 RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
358
359
360 {
361 }
362
363 DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
364 return 0;
365}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382int rt28xx_open(struct net_device *dev)
383{
384 struct net_device *net_dev = (struct net_device *)dev;
385 struct rt_rtmp_adapter *pAd = NULL;
386 int retval = 0;
387
388
389 GET_PAD_FROM_NET_DEV(pAd, net_dev);
390
391
392 if (pAd == NULL) {
393
394
395 return -1;
396 }
397
398 if (net_dev->priv_flags == INT_MAIN) {
399 if (pAd->OpMode == OPMODE_STA)
400 net_dev->wireless_handlers =
401 (struct iw_handler_def *)&rt28xx_iw_handler_def;
402 }
403
404
405 RtmpOSIRQRequest(net_dev);
406
407
408 RTMP_IRQ_INIT(pAd);
409
410
411 if (rt28xx_init(pAd, mac, hostname) == FALSE)
412 goto err;
413
414
415 RTMP_IRQ_ENABLE(pAd);
416
417
418 RTMPEnableRxTx(pAd);
419 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
420
421 {
422 u32 reg = 0;
423 RTMP_IO_READ32(pAd, 0x1300, ®);
424 printk(KERN_DEBUG "0x1300 = %08x\n", reg);
425 }
426
427 {
428
429
430
431
432
433
434
435
436
437
438 }
439#ifdef RTMP_MAC_PCI
440 RTMPInitPCIeLinkCtrlValue(pAd);
441#endif
442
443 return retval;
444
445err:
446
447 RtmpOSIRQRelease(net_dev);
448
449 return -1;
450}
451
452static const struct net_device_ops rt2860_netdev_ops = {
453 .ndo_open = MainVirtualIF_open,
454 .ndo_stop = MainVirtualIF_close,
455 .ndo_do_ioctl = rt28xx_sta_ioctl,
456 .ndo_get_stats = RT28xx_get_ether_stats,
457 .ndo_validate_addr = NULL,
458 .ndo_set_mac_address = eth_mac_addr,
459 .ndo_change_mtu = eth_change_mtu,
460 .ndo_start_xmit = rt28xx_send_packets,
461};
462
463struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
464 struct rt_rtmp_os_netdev_op_hook *pNetDevHook)
465{
466 struct net_device *net_dev = NULL;
467
468
469 net_dev =
470 RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *),
471 INF_MAIN_DEV_NAME);
472 if (net_dev == NULL) {
473 printk
474 ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
475 return NULL;
476 }
477
478 NdisZeroMemory((unsigned char *)pNetDevHook,
479 sizeof(struct rt_rtmp_os_netdev_op_hook));
480 pNetDevHook->netdev_ops = &rt2860_netdev_ops;
481 pNetDevHook->priv_flags = INT_MAIN;
482 pNetDevHook->needProtcted = FALSE;
483
484 net_dev->ml_priv = (void *)pAd;
485 pAd->net_dev = net_dev;
486
487 return net_dev;
488
489}
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508int rt28xx_packet_xmit(struct sk_buff *skb)
509{
510 struct net_device *net_dev = skb->dev;
511 struct rt_rtmp_adapter *pAd = NULL;
512 int status = NETDEV_TX_OK;
513 void *pPacket = (void *)skb;
514
515 GET_PAD_FROM_NET_DEV(pAd, net_dev);
516
517
518
519 {
520
521 if (MONITOR_ON(pAd)) {
522 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
523 goto done;
524 }
525 }
526
527
528 if (skb->len < 14) {
529
530 hex_dump("bad packet", skb->data, skb->len);
531 RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
532 goto done;
533 }
534
535 RTMP_SET_PACKET_5VT(pPacket, 0);
536 STASendPackets((void *)pAd, (void **)&pPacket, 1);
537
538 status = NETDEV_TX_OK;
539done:
540
541 return status;
542}
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560static int rt28xx_send_packets(IN struct sk_buff *skb_p,
561 IN struct net_device *net_dev)
562{
563 struct rt_rtmp_adapter *pAd = NULL;
564
565 GET_PAD_FROM_NET_DEV(pAd, net_dev);
566
567 if (!(net_dev->flags & IFF_UP)) {
568 RELEASE_NDIS_PACKET(pAd, (void *)skb_p,
569 NDIS_STATUS_FAILURE);
570 return NETDEV_TX_OK;
571 }
572
573 NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15);
574 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
575
576 return rt28xx_packet_xmit(skb_p);
577}
578
579
580struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev)
581{
582 struct rt_rtmp_adapter *pAd = NULL;
583
584 GET_PAD_FROM_NET_DEV(pAd, net_dev);
585
586 DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
587
588 pAd->iw_stats.status = 0;
589
590
591 if (pAd->OpMode == OPMODE_STA)
592 pAd->iw_stats.qual.qual =
593 ((pAd->Mlme.ChannelQuality * 12) / 10 + 10);
594
595 if (pAd->iw_stats.qual.qual > 100)
596 pAd->iw_stats.qual.qual = 100;
597
598 if (pAd->OpMode == OPMODE_STA) {
599 pAd->iw_stats.qual.level =
600 RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
601 pAd->StaCfg.RssiSample.LastRssi1,
602 pAd->StaCfg.RssiSample.LastRssi2);
603 }
604
605 pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66];
606
607 pAd->iw_stats.qual.noise += 256 - 143;
608 pAd->iw_stats.qual.updated = 1;
609#ifdef IW_QUAL_DBM
610 pAd->iw_stats.qual.updated |= IW_QUAL_DBM;
611#endif
612
613 pAd->iw_stats.discard.nwid = 0;
614 pAd->iw_stats.miss.beacon = 0;
615
616 DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
617 return &pAd->iw_stats;
618}
619
620void tbtt_tasklet(unsigned long data)
621{
622
623
624}
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
643 *net_dev)
644{
645 struct rt_rtmp_adapter *pAd = NULL;
646
647 if (net_dev)
648 GET_PAD_FROM_NET_DEV(pAd, net_dev);
649
650 if (pAd) {
651
652 pAd->stats.rx_packets =
653 pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
654 pAd->stats.tx_packets =
655 pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
656
657 pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
658 pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
659
660 pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
661 pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
662
663 pAd->stats.rx_dropped = 0;
664 pAd->stats.tx_dropped = 0;
665
666 pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;
667 pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;
668
669 pAd->stats.rx_length_errors = 0;
670 pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;
671 pAd->stats.rx_crc_errors = 0;
672 pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;
673 pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;
674 pAd->stats.rx_missed_errors = 0;
675
676
677 pAd->stats.tx_aborted_errors = 0;
678 pAd->stats.tx_carrier_errors = 0;
679 pAd->stats.tx_fifo_errors = 0;
680 pAd->stats.tx_heartbeat_errors = 0;
681 pAd->stats.tx_window_errors = 0;
682
683
684 pAd->stats.rx_compressed = 0;
685 pAd->stats.tx_compressed = 0;
686
687 return &pAd->stats;
688 } else
689 return NULL;
690}
691
692BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
693{
694
695
696 if (net_dev != NULL) {
697 printk
698 ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
699 net_dev->name);
700 RtmpOSNetDevDetach(net_dev);
701 }
702
703 return TRUE;
704
705}
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
724{
725
726 *ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
727
728
729 if (*ppAd) {
730 NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
731 ((struct rt_rtmp_adapter *)*ppAd)->OS_Cookie = handle;
732 return NDIS_STATUS_SUCCESS;
733 } else {
734 return NDIS_STATUS_FAILURE;
735 }
736}
737