2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
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. *
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. *
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. *
25 *************************************************************************
31 Create and register network interface.
35 -------- ---------- ----------------------------------------------
38 #include "rt_config.h"
40 /*---------------------------------------------------------------------*/
41 /* Private Variables Used */
42 /*---------------------------------------------------------------------*/
44 char *mac
= ""; /* default 00:00:00:00:00:00 */
45 char *hostname
= ""; /* default CMPC */
46 module_param(mac
, charp
, 0);
47 MODULE_PARM_DESC(mac
, "rt28xx: wireless mac addr");
49 /*---------------------------------------------------------------------*/
50 /* Prototypes of Functions Used */
51 /*---------------------------------------------------------------------*/
53 /* public function prototype */
54 int rt28xx_close(IN
struct net_device
*net_dev
);
55 int rt28xx_open(struct net_device
*net_dev
);
57 /* private function prototype */
58 static int rt28xx_send_packets(IN
struct sk_buff
*skb_p
,
59 IN
struct net_device
*net_dev
);
61 static struct net_device_stats
*RT28xx_get_ether_stats(IN
struct net_device
65 ========================================================================
70 *net_dev the raxx interface pointer
77 1. if open fail, kernel will not call the close function.
79 (1) Mlme Memory Handler: MlmeHalt()
80 (2) TX & RX: RTMPFreeTxRxRingMemory()
81 (3) BA Reordering: ba_reordering_resource_release()
82 ========================================================================
84 int MainVirtualIF_close(IN
struct net_device
*net_dev
)
86 struct rt_rtmp_adapter
*pAd
= NULL
;
88 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
90 /* Sanity check for pAd */
92 return 0; /* close ok */
94 netif_carrier_off(pAd
->net_dev
);
95 netif_stop_queue(pAd
->net_dev
);
101 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
))) {
102 struct rt_mlme_disassoc_req DisReq
;
103 struct rt_mlme_queue_elem
*MsgElem
=
104 (struct rt_mlme_queue_elem
*)kmalloc(sizeof(struct rt_mlme_queue_elem
),
108 COPY_MAC_ADDR(DisReq
.Addr
,
109 pAd
->CommonCfg
.Bssid
);
110 DisReq
.Reason
= REASON_DEAUTH_STA_LEAVING
;
112 MsgElem
->Machine
= ASSOC_STATE_MACHINE
;
113 MsgElem
->MsgType
= MT2_MLME_DISASSOC_REQ
;
115 sizeof(struct rt_mlme_disassoc_req
);
116 NdisMoveMemory(MsgElem
->Msg
, &DisReq
,
118 (struct rt_mlme_disassoc_req
));
120 /* Prevent to connect AP again in STAMlmePeriodicExec */
121 pAd
->MlmeAux
.AutoReconnectSsidLen
= 32;
122 NdisZeroMemory(pAd
->MlmeAux
.AutoReconnectSsid
,
124 AutoReconnectSsidLen
);
126 pAd
->Mlme
.CntlMachine
.CurrState
=
127 CNTL_WAIT_OID_DISASSOC
;
128 MlmeDisassocReqAction(pAd
, MsgElem
);
135 RTMPCancelTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
,
137 RTMPCancelTimer(&pAd
->StaCfg
.WpaDisassocAndBlockAssocTimer
,
141 VIRTUAL_IF_DOWN(pAd
);
143 RT_MOD_DEC_USE_COUNT();
145 return 0; /* close ok */
149 ========================================================================
154 *net_dev the raxx interface pointer
161 1. if open fail, kernel will not call the close function.
163 (1) Mlme Memory Handler: MlmeHalt()
164 (2) TX & RX: RTMPFreeTxRxRingMemory()
165 (3) BA Reordering: ba_reordering_resource_release()
166 ========================================================================
168 int MainVirtualIF_open(IN
struct net_device
*net_dev
)
170 struct rt_rtmp_adapter
*pAd
= NULL
;
172 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
174 /* Sanity check for pAd */
176 return 0; /* close ok */
178 if (VIRTUAL_IF_UP(pAd
) != 0)
181 /* increase MODULE use count */
182 RT_MOD_INC_USE_COUNT();
184 netif_start_queue(net_dev
);
185 netif_carrier_on(net_dev
);
186 netif_wake_queue(net_dev
);
192 ========================================================================
194 Close raxx interface.
197 *net_dev the raxx interface pointer
204 1. if open fail, kernel will not call the close function.
206 (1) Mlme Memory Handler: MlmeHalt()
207 (2) TX & RX: RTMPFreeTxRxRingMemory()
208 (3) BA Reordering: ba_reordering_resource_release()
209 ========================================================================
211 int rt28xx_close(struct net_device
*dev
)
213 struct net_device
*net_dev
= (struct net_device
*)dev
;
214 struct rt_rtmp_adapter
*pAd
= NULL
;
219 DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup
);
220 DECLARE_WAITQUEUE(wait
, current
);
221 #endif /* RTMP_MAC_USB // */
223 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
225 DBGPRINT(RT_DEBUG_TRACE
, ("===> rt28xx_close\n"));
228 /* Sanity check for pAd */
230 return 0; /* close ok */
234 RTMPPCIeLinkCtrlValueRestore(pAd
, RESTORE_CLOSE
);
235 #endif /* RTMP_MAC_PCI // */
237 /* If dirver doesn't wake up firmware here, */
238 /* NICLoadFirmware will hang forever when interface is up again. */
239 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)) {
240 AsicForceWakeup(pAd
, TRUE
);
243 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_REMOVE_IN_PROGRESS
);
244 #endif /* RTMP_MAC_USB // */
248 pAd
->bPCIclkOff
= FALSE
;
249 #endif /* RTMP_MAC_PCI // */
252 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
254 for (i
= 0; i
< NUM_OF_TX_RING
; i
++) {
255 while (pAd
->DeQueueRunning
[i
] == TRUE
) {
256 DBGPRINT(RT_DEBUG_TRACE
,
257 ("Waiting for TxQueue[%d] done..........\n",
264 /* ensure there are no more active urbs. */
265 add_wait_queue(&unlink_wakeup
, &wait
);
266 pAd
->wait
= &unlink_wakeup
;
268 /* maybe wait for deletions to finish. */
270 /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
272 unsigned long IrqFlags
;
274 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
275 if (pAd
->PendingRx
== 0) {
276 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
279 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
281 msleep(UNLINK_TIMEOUT_MS
); /*Time in millisecond */
285 remove_wait_queue(&unlink_wakeup
, &wait
);
286 #endif /* RTMP_MAC_USB // */
288 /* Stop Mlme state machine */
291 /* Close net tasklets */
292 RtmpNetTaskExit(pAd
);
298 MeasureReqTabExit(pAd
);
301 /* Close kernel threads */
302 RtmpMgmtTaskExit(pAd
);
307 /* unsigned long Value; */
309 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
)) {
310 RTMP_ASIC_INTERRUPT_DISABLE(pAd
);
312 /* Receive packets to clear DMA index after disable interrupt. */
313 /*RTMPHandleRxDoneInterrupt(pAd); */
314 /* put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all */
315 /* register access before Radio off. */
317 brc
= RT28xxPciAsicRadioOff(pAd
, RTMP_HALT
, 0);
319 /*In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
320 pAd
->bPCIclkOff
= FALSE
;
323 DBGPRINT(RT_DEBUG_ERROR
,
324 ("%s call RT28xxPciAsicRadioOff fail!\n",
330 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
332 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
335 // Disable Rx, register value supposed will remain after reset
338 #endif /* RTMP_MAC_PCI // */
341 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
)) {
343 /* Deregister interrupt function */
344 RtmpOSIRQRelease(net_dev
);
345 #endif /* RTMP_MAC_PCI // */
346 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
348 /* Free Ring or USB buffers */
349 RTMPFreeTxRxRingMemory(pAd
);
351 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
353 /* Free BA reorder resource */
354 ba_reordering_resource_release(pAd
);
356 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
358 /*+++Modify by woody to solve the bulk fail+++*/
362 DBGPRINT(RT_DEBUG_TRACE
, ("<=== rt28xx_close\n"));
363 return 0; /* close ok */
364 } /* End of rt28xx_close */
367 ========================================================================
372 *net_dev the raxx interface pointer
379 ========================================================================
381 int rt28xx_open(struct net_device
*dev
)
383 struct net_device
*net_dev
= (struct net_device
*)dev
;
384 struct rt_rtmp_adapter
*pAd
= NULL
;
386 /*struct os_cookie *pObj; */
388 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
390 /* Sanity check for pAd */
392 /* if 1st open fail, pAd will be free;
393 So the net_dev->ml_priv will be NULL in 2rd open */
397 if (net_dev
->priv_flags
== INT_MAIN
) {
398 if (pAd
->OpMode
== OPMODE_STA
)
399 net_dev
->wireless_handlers
=
400 (struct iw_handler_def
*)&rt28xx_iw_handler_def
;
402 /* Request interrupt service routine for PCI device */
403 /* register the interrupt routine with the os */
404 RtmpOSIRQRequest(net_dev
);
406 /* Init IRQ parameters stored in pAd */
409 /* Chip & other init */
410 if (rt28xx_init(pAd
, mac
, hostname
) == FALSE
)
413 /* Enable Interrupt */
414 RTMP_IRQ_ENABLE(pAd
);
416 /* Now Enable RxTx */
418 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
422 RTMP_IO_READ32(pAd
, 0x1300, ®
); /* clear garbage interrupts */
423 printk("0x1300 = %08x\n", reg
);
431 /* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); */
434 /* reg = (reg & 0xffff0000) | tmp; */
435 /* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
439 RTMPInitPCIeLinkCtrlValue(pAd
);
440 #endif /* RTMP_MAC_PCI // */
445 /*+++Add by shiang, move from rt28xx_init() to here. */
446 RtmpOSIRQRelease(net_dev
);
447 /*---Add by shiang, move from rt28xx_init() to here. */
449 } /* End of rt28xx_open */
451 static const struct net_device_ops rt2860_netdev_ops
= {
452 .ndo_open
= MainVirtualIF_open
,
453 .ndo_stop
= MainVirtualIF_close
,
454 .ndo_do_ioctl
= rt28xx_sta_ioctl
,
455 .ndo_get_stats
= RT28xx_get_ether_stats
,
456 .ndo_validate_addr
= NULL
,
457 .ndo_set_mac_address
= eth_mac_addr
,
458 .ndo_change_mtu
= eth_change_mtu
,
459 .ndo_start_xmit
= rt28xx_send_packets
,
462 struct net_device
*RtmpPhyNetDevInit(struct rt_rtmp_adapter
*pAd
,
463 struct rt_rtmp_os_netdev_op_hook
*pNetDevHook
)
465 struct net_device
*net_dev
= NULL
;
469 RtmpOSNetDevCreate(pAd
, INT_MAIN
, 0, sizeof(struct rt_rtmp_adapter
*),
471 if (net_dev
== NULL
) {
473 ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
477 NdisZeroMemory((unsigned char *)pNetDevHook
,
478 sizeof(struct rt_rtmp_os_netdev_op_hook
));
479 pNetDevHook
->netdev_ops
= &rt2860_netdev_ops
;
480 pNetDevHook
->priv_flags
= INT_MAIN
;
481 pNetDevHook
->needProtcted
= FALSE
;
483 net_dev
->ml_priv
= (void *)pAd
;
484 pAd
->net_dev
= net_dev
;
491 ========================================================================
493 The entry point for Linux kernel sent packet to our driver.
496 sk_buff *skb the pointer refer to a sk_buffer.
502 This function is the entry point of Tx Path for Os delivery packet to
503 our driver. You only can put OS-depened & STA/AP common handle procedures
505 ========================================================================
507 int rt28xx_packet_xmit(struct sk_buff
*skb
)
509 struct net_device
*net_dev
= skb
->dev
;
510 struct rt_rtmp_adapter
*pAd
= NULL
;
511 int status
= NETDEV_TX_OK
;
512 void *pPacket
= (void *)skb
;
514 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
516 /* RT2870STA does this in RTMPSendPackets() */
519 /* Drop send request since we are in monitor mode */
520 if (MONITOR_ON(pAd
)) {
521 RELEASE_NDIS_PACKET(pAd
, pPacket
, NDIS_STATUS_FAILURE
);
526 /* EapolStart size is 18 */
528 /*printk("bad packet size: %d\n", pkt->len); */
529 hex_dump("bad packet", skb
->data
, skb
->len
);
530 RELEASE_NDIS_PACKET(pAd
, pPacket
, NDIS_STATUS_FAILURE
);
534 RTMP_SET_PACKET_5VT(pPacket
, 0);
535 STASendPackets((void *)pAd
, (void **)& pPacket
, 1);
537 status
= NETDEV_TX_OK
;
544 ========================================================================
546 Send a packet to WLAN.
549 skb_p points to our adapter
550 dev_p which WLAN network interface
553 0: transmit successfully
554 otherwise: transmit fail
557 ========================================================================
559 static int rt28xx_send_packets(IN
struct sk_buff
*skb_p
,
560 IN
struct net_device
*net_dev
)
562 struct rt_rtmp_adapter
*pAd
= NULL
;
564 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
566 if (!(net_dev
->flags
& IFF_UP
)) {
567 RELEASE_NDIS_PACKET(pAd
, (void *)skb_p
,
568 NDIS_STATUS_FAILURE
);
572 NdisZeroMemory((u8
*)& skb_p
->cb
[CB_OFF
], 15);
573 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p
, MAIN_MBSSID
);
575 return rt28xx_packet_xmit(skb_p
);
578 /* This function will be called when query /proc */
579 struct iw_statistics
*rt28xx_get_wireless_stats(IN
struct net_device
*net_dev
)
581 struct rt_rtmp_adapter
*pAd
= NULL
;
583 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
585 DBGPRINT(RT_DEBUG_TRACE
, ("rt28xx_get_wireless_stats --->\n"));
587 pAd
->iw_stats
.status
= 0; /* Status - device dependent for now */
590 if (pAd
->OpMode
== OPMODE_STA
)
591 pAd
->iw_stats
.qual
.qual
=
592 ((pAd
->Mlme
.ChannelQuality
* 12) / 10 + 10);
594 if (pAd
->iw_stats
.qual
.qual
> 100)
595 pAd
->iw_stats
.qual
.qual
= 100;
597 if (pAd
->OpMode
== OPMODE_STA
) {
598 pAd
->iw_stats
.qual
.level
=
599 RTMPMaxRssi(pAd
, pAd
->StaCfg
.RssiSample
.LastRssi0
,
600 pAd
->StaCfg
.RssiSample
.LastRssi1
,
601 pAd
->StaCfg
.RssiSample
.LastRssi2
);
604 pAd
->iw_stats
.qual
.noise
= pAd
->BbpWriteLatch
[66]; /* noise level (dBm) */
606 pAd
->iw_stats
.qual
.noise
+= 256 - 143;
607 pAd
->iw_stats
.qual
.updated
= 1; /* Flags to know if updated */
609 pAd
->iw_stats
.qual
.updated
|= IW_QUAL_DBM
; /* Level + Noise are dBm */
610 #endif /* IW_QUAL_DBM // */
612 pAd
->iw_stats
.discard
.nwid
= 0; /* Rx : Wrong nwid/essid */
613 pAd
->iw_stats
.miss
.beacon
= 0; /* Missed beacons/superframe */
615 DBGPRINT(RT_DEBUG_TRACE
, ("<--- rt28xx_get_wireless_stats\n"));
616 return &pAd
->iw_stats
;
619 void tbtt_tasklet(unsigned long data
)
621 /*#define MAX_TX_IN_TBTT (16) */
626 ========================================================================
629 return ethernet statistics counter
632 net_dev Pointer to net_device
639 ========================================================================
641 static struct net_device_stats
*RT28xx_get_ether_stats(IN
struct net_device
644 struct rt_rtmp_adapter
*pAd
= NULL
;
647 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
651 pAd
->stats
.rx_packets
=
652 pAd
->WlanCounters
.ReceivedFragmentCount
.QuadPart
;
653 pAd
->stats
.tx_packets
=
654 pAd
->WlanCounters
.TransmittedFragmentCount
.QuadPart
;
656 pAd
->stats
.rx_bytes
= pAd
->RalinkCounters
.ReceivedByteCount
;
657 pAd
->stats
.tx_bytes
= pAd
->RalinkCounters
.TransmittedByteCount
;
659 pAd
->stats
.rx_errors
= pAd
->Counters8023
.RxErrors
;
660 pAd
->stats
.tx_errors
= pAd
->Counters8023
.TxErrors
;
662 pAd
->stats
.rx_dropped
= 0;
663 pAd
->stats
.tx_dropped
= 0;
665 pAd
->stats
.multicast
= pAd
->WlanCounters
.MulticastReceivedFrameCount
.QuadPart
; /* multicast packets received */
666 pAd
->stats
.collisions
= pAd
->Counters8023
.OneCollision
+ pAd
->Counters8023
.MoreCollisions
; /* Collision packets */
668 pAd
->stats
.rx_length_errors
= 0;
669 pAd
->stats
.rx_over_errors
= pAd
->Counters8023
.RxNoBuffer
; /* receiver ring buff overflow */
670 pAd
->stats
.rx_crc_errors
= 0; /*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */
671 pAd
->stats
.rx_frame_errors
= pAd
->Counters8023
.RcvAlignmentErrors
; /* recv'd frame alignment error */
672 pAd
->stats
.rx_fifo_errors
= pAd
->Counters8023
.RxNoBuffer
; /* recv'r fifo overrun */
673 pAd
->stats
.rx_missed_errors
= 0; /* receiver missed packet */
675 /* detailed tx_errors */
676 pAd
->stats
.tx_aborted_errors
= 0;
677 pAd
->stats
.tx_carrier_errors
= 0;
678 pAd
->stats
.tx_fifo_errors
= 0;
679 pAd
->stats
.tx_heartbeat_errors
= 0;
680 pAd
->stats
.tx_window_errors
= 0;
683 pAd
->stats
.rx_compressed
= 0;
684 pAd
->stats
.tx_compressed
= 0;
691 BOOLEAN
RtmpPhyNetDevExit(struct rt_rtmp_adapter
*pAd
, struct net_device
*net_dev
)
694 /* Unregister network device */
695 if (net_dev
!= NULL
) {
697 ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
699 RtmpOSNetDevDetach(net_dev
);
707 ========================================================================
709 Allocate memory for adapter control block.
712 pAd Pointer to our adapter
717 NDIS_STATUS_RESOURCES
720 ========================================================================
722 int AdapterBlockAllocateMemory(void *handle
, void ** ppAd
)
725 *ppAd
= (void *)vmalloc(sizeof(struct rt_rtmp_adapter
)); /*pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
728 NdisZeroMemory(*ppAd
, sizeof(struct rt_rtmp_adapter
));
729 ((struct rt_rtmp_adapter
*)* ppAd
)->OS_Cookie
= handle
;
730 return (NDIS_STATUS_SUCCESS
);
732 return (NDIS_STATUS_FAILURE
);