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 Justin P. Mattock 11/07/2010 Fix typos in comments
36 -------- ---------- ----------------------------------------------
39 #include "rt_config.h"
41 /*---------------------------------------------------------------------*/
42 /* Private Variables Used */
43 /*---------------------------------------------------------------------*/
45 char *mac
= ""; /* default 00:00:00:00:00:00 */
46 char *hostname
= ""; /* default CMPC */
47 module_param(mac
, charp
, 0);
48 MODULE_PARM_DESC(mac
, "rt28xx: wireless mac addr");
50 /*---------------------------------------------------------------------*/
51 /* Prototypes of Functions Used */
52 /*---------------------------------------------------------------------*/
54 /* public function prototype */
55 int rt28xx_close(IN
struct net_device
*net_dev
);
56 int rt28xx_open(struct net_device
*net_dev
);
58 /* private function prototype */
59 static int rt28xx_send_packets(IN
struct sk_buff
*skb_p
,
60 IN
struct net_device
*net_dev
);
62 static struct net_device_stats
*RT28xx_get_ether_stats(IN
struct net_device
66 ========================================================================
71 *net_dev the raxx interface pointer
78 1. if open fail, kernel will not call the close function.
80 (1) Mlme Memory Handler: MlmeHalt()
81 (2) TX & RX: RTMPFreeTxRxRingMemory()
82 (3) BA Reordering: ba_reordering_resource_release()
83 ========================================================================
85 int MainVirtualIF_close(IN
struct net_device
*net_dev
)
87 struct rt_rtmp_adapter
*pAd
= NULL
;
89 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
91 /* Sanity check for pAd */
93 return 0; /* close ok */
95 netif_carrier_off(pAd
->net_dev
);
96 netif_stop_queue(pAd
->net_dev
);
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
),
109 COPY_MAC_ADDR(DisReq
.Addr
,
110 pAd
->CommonCfg
.Bssid
);
111 DisReq
.Reason
= REASON_DEAUTH_STA_LEAVING
;
113 MsgElem
->Machine
= ASSOC_STATE_MACHINE
;
114 MsgElem
->MsgType
= MT2_MLME_DISASSOC_REQ
;
116 sizeof(struct rt_mlme_disassoc_req
);
117 NdisMoveMemory(MsgElem
->Msg
, &DisReq
,
119 (struct rt_mlme_disassoc_req
));
121 /* Prevent to connect AP again in STAMlmePeriodicExec */
122 pAd
->MlmeAux
.AutoReconnectSsidLen
= 32;
123 NdisZeroMemory(pAd
->MlmeAux
.AutoReconnectSsid
,
125 AutoReconnectSsidLen
);
127 pAd
->Mlme
.CntlMachine
.CurrState
=
128 CNTL_WAIT_OID_DISASSOC
;
129 MlmeDisassocReqAction(pAd
, MsgElem
);
136 RTMPCancelTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
,
138 RTMPCancelTimer(&pAd
->StaCfg
.WpaDisassocAndBlockAssocTimer
,
142 VIRTUAL_IF_DOWN(pAd
);
144 RT_MOD_DEC_USE_COUNT();
146 return 0; /* close ok */
150 ========================================================================
155 *net_dev the raxx interface pointer
162 1. if open fail, kernel will not call the close function.
164 (1) Mlme Memory Handler: MlmeHalt()
165 (2) TX & RX: RTMPFreeTxRxRingMemory()
166 (3) BA Reordering: ba_reordering_resource_release()
167 ========================================================================
169 int MainVirtualIF_open(IN
struct net_device
*net_dev
)
171 struct rt_rtmp_adapter
*pAd
= NULL
;
173 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
175 /* Sanity check for pAd */
177 return 0; /* close ok */
179 if (VIRTUAL_IF_UP(pAd
) != 0)
182 /* increase MODULE use count */
183 RT_MOD_INC_USE_COUNT();
185 netif_start_queue(net_dev
);
186 netif_carrier_on(net_dev
);
187 netif_wake_queue(net_dev
);
193 ========================================================================
195 Close raxx interface.
198 *net_dev the raxx interface pointer
205 1. if open fail, kernel will not call the close function.
207 (1) Mlme Memory Handler: MlmeHalt()
208 (2) TX & RX: RTMPFreeTxRxRingMemory()
209 (3) BA Reordering: ba_reordering_resource_release()
210 ========================================================================
212 int rt28xx_close(struct net_device
*dev
)
214 struct net_device
*net_dev
= (struct net_device
*)dev
;
215 struct rt_rtmp_adapter
*pAd
= NULL
;
220 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup
);
221 DECLARE_WAITQUEUE(wait
, current
);
222 #endif /* RTMP_MAC_USB // */
224 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
226 DBGPRINT(RT_DEBUG_TRACE
, ("===> rt28xx_close\n"));
229 /* Sanity check for pAd */
231 return 0; /* close ok */
235 RTMPPCIeLinkCtrlValueRestore(pAd
, RESTORE_CLOSE
);
236 #endif /* RTMP_MAC_PCI // */
238 /* If driver doesn't wake up firmware here, */
239 /* NICLoadFirmware will hang forever when interface is up again. */
240 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
)) {
241 AsicForceWakeup(pAd
, TRUE
);
244 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_REMOVE_IN_PROGRESS
);
245 #endif /* RTMP_MAC_USB // */
249 pAd
->bPCIclkOff
= FALSE
;
250 #endif /* RTMP_MAC_PCI // */
253 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
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",
265 /* ensure there are no more active urbs. */
266 add_wait_queue(&unlink_wakeup
, &wait
);
267 pAd
->wait
= &unlink_wakeup
;
269 /* maybe wait for deletions to finish. */
271 /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
273 unsigned long IrqFlags
;
275 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
276 if (pAd
->PendingRx
== 0) {
277 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
280 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
282 msleep(UNLINK_TIMEOUT_MS
); /*Time in millisecond */
286 remove_wait_queue(&unlink_wakeup
, &wait
);
287 #endif /* RTMP_MAC_USB // */
289 /* Stop Mlme state machine */
292 /* Close net tasklets */
293 RtmpNetTaskExit(pAd
);
299 MeasureReqTabExit(pAd
);
302 /* Close kernel threads */
303 RtmpMgmtTaskExit(pAd
);
308 /* unsigned long Value; */
310 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
)) {
311 RTMP_ASIC_INTERRUPT_DISABLE(pAd
);
313 /* Receive packets to clear DMA index after disable interrupt. */
314 /* RTMPHandleRxDoneInterrupt(pAd); */
315 /* put radio off to save power when driver unloads. After radiooff, can't write/read register, so need to finish all. */
316 /* register access before Radio off. */
318 brc
= RT28xxPciAsicRadioOff(pAd
, RTMP_HALT
, 0);
320 /*In solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
321 pAd
->bPCIclkOff
= FALSE
;
324 DBGPRINT(RT_DEBUG_ERROR
,
325 ("%s call RT28xxPciAsicRadioOff fail!\n",
331 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
333 RTMP_ASIC_INTERRUPT_DISABLE(pAd);
336 // Disable Rx, register value supposed will remain after reset
339 #endif /* RTMP_MAC_PCI // */
342 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
)) {
344 /* Deregister interrupt function */
345 RtmpOSIRQRelease(net_dev
);
346 #endif /* RTMP_MAC_PCI // */
347 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
349 /* Free Ring or USB buffers */
350 RTMPFreeTxRxRingMemory(pAd
);
352 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
354 /* Free BA reorder resource */
355 ba_reordering_resource_release(pAd
);
357 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
359 /*+++Modify by woody to solve the bulk fail+++*/
363 DBGPRINT(RT_DEBUG_TRACE
, ("<=== rt28xx_close\n"));
364 return 0; /* close ok */
365 } /* End of rt28xx_close */
368 ========================================================================
373 *net_dev the raxx interface pointer
380 ========================================================================
382 int rt28xx_open(struct net_device
*dev
)
384 struct net_device
*net_dev
= (struct net_device
*)dev
;
385 struct rt_rtmp_adapter
*pAd
= NULL
;
387 /*struct os_cookie *pObj; */
389 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
391 /* Sanity check for pAd */
393 /* if 1st open fail, pAd will be free;
394 So the net_dev->ml_priv will be NULL in 2rd open */
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
;
403 /* Request interrupt service routine for PCI device */
404 /* register the interrupt routine with the os */
405 RtmpOSIRQRequest(net_dev
);
407 /* Init IRQ parameters stored in pAd */
410 /* Chip & other init */
411 if (rt28xx_init(pAd
, mac
, hostname
) == FALSE
)
414 /* Enable Interrupt */
415 RTMP_IRQ_ENABLE(pAd
);
417 /* Now Enable RxTx */
419 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
423 RTMP_IO_READ32(pAd
, 0x1300, ®
); /* clear garbage interrupts */
424 printk(KERN_DEBUG
"0x1300 = %08x\n", reg
);
432 /* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, ®); */
435 /* reg = (reg & 0xffff0000) | tmp; */
436 /* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
440 RTMPInitPCIeLinkCtrlValue(pAd
);
441 #endif /* RTMP_MAC_PCI // */
446 /*+++Add by shiang, move from rt28xx_init() to here. */
447 RtmpOSIRQRelease(net_dev
);
448 /*---Add by shiang, move from rt28xx_init() to here. */
450 } /* End of rt28xx_open */
452 static 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
,
463 struct net_device
*RtmpPhyNetDevInit(struct rt_rtmp_adapter
*pAd
,
464 struct rt_rtmp_os_netdev_op_hook
*pNetDevHook
)
466 struct net_device
*net_dev
= NULL
;
470 RtmpOSNetDevCreate(pAd
, INT_MAIN
, 0, sizeof(struct rt_rtmp_adapter
*),
472 if (net_dev
== NULL
) {
474 ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
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
;
484 net_dev
->ml_priv
= (void *)pAd
;
485 pAd
->net_dev
= net_dev
;
492 ========================================================================
494 The entry point for Linux kernel sent packet to our driver.
497 sk_buff *skb the pointer refer to a sk_buffer.
503 This function is the entry point of Tx Path for Os delivery packet to
504 our driver. You only can put OS-depened & STA/AP common handle procedures
506 ========================================================================
508 int rt28xx_packet_xmit(struct sk_buff
*skb
)
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
;
515 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
517 /* RT2870STA does this in RTMPSendPackets() */
520 /* Drop send request since we are in monitor mode */
521 if (MONITOR_ON(pAd
)) {
522 RELEASE_NDIS_PACKET(pAd
, pPacket
, NDIS_STATUS_FAILURE
);
527 /* EapolStart size is 18 */
529 /*printk("bad packet size: %d\n", pkt->len); */
530 hex_dump("bad packet", skb
->data
, skb
->len
);
531 RELEASE_NDIS_PACKET(pAd
, pPacket
, NDIS_STATUS_FAILURE
);
535 RTMP_SET_PACKET_5VT(pPacket
, 0);
536 STASendPackets((void *)pAd
, (void **)&pPacket
, 1);
538 status
= NETDEV_TX_OK
;
545 ========================================================================
547 Send a packet to WLAN.
550 skb_p points to our adapter
551 dev_p which WLAN network interface
554 0: transmit successfully
555 otherwise: transmit fail
558 ========================================================================
560 static int rt28xx_send_packets(IN
struct sk_buff
*skb_p
,
561 IN
struct net_device
*net_dev
)
563 struct rt_rtmp_adapter
*pAd
= NULL
;
565 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
567 if (!(net_dev
->flags
& IFF_UP
)) {
568 RELEASE_NDIS_PACKET(pAd
, (void *)skb_p
,
569 NDIS_STATUS_FAILURE
);
573 NdisZeroMemory((u8
*)&skb_p
->cb
[CB_OFF
], 15);
574 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p
, MAIN_MBSSID
);
576 return rt28xx_packet_xmit(skb_p
);
579 /* This function will be called when query /proc */
580 struct iw_statistics
*rt28xx_get_wireless_stats(IN
struct net_device
*net_dev
)
582 struct rt_rtmp_adapter
*pAd
= NULL
;
584 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
586 DBGPRINT(RT_DEBUG_TRACE
, ("rt28xx_get_wireless_stats --->\n"));
588 pAd
->iw_stats
.status
= 0; /* Status - device dependent for now */
591 if (pAd
->OpMode
== OPMODE_STA
)
592 pAd
->iw_stats
.qual
.qual
=
593 ((pAd
->Mlme
.ChannelQuality
* 12) / 10 + 10);
595 if (pAd
->iw_stats
.qual
.qual
> 100)
596 pAd
->iw_stats
.qual
.qual
= 100;
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
);
605 pAd
->iw_stats
.qual
.noise
= pAd
->BbpWriteLatch
[66]; /* noise level (dBm) */
607 pAd
->iw_stats
.qual
.noise
+= 256 - 143;
608 pAd
->iw_stats
.qual
.updated
= 1; /* Flags to know if updated */
610 pAd
->iw_stats
.qual
.updated
|= IW_QUAL_DBM
; /* Level + Noise are dBm */
611 #endif /* IW_QUAL_DBM // */
613 pAd
->iw_stats
.discard
.nwid
= 0; /* Rx : Wrong nwid/essid */
614 pAd
->iw_stats
.miss
.beacon
= 0; /* Missed beacons/superframe */
616 DBGPRINT(RT_DEBUG_TRACE
, ("<--- rt28xx_get_wireless_stats\n"));
617 return &pAd
->iw_stats
;
620 void tbtt_tasklet(unsigned long data
)
622 /*#define MAX_TX_IN_TBTT (16) */
627 ========================================================================
630 return ethernet statistics counter
633 net_dev Pointer to net_device
640 ========================================================================
642 static struct net_device_stats
*RT28xx_get_ether_stats(IN
struct net_device
645 struct rt_rtmp_adapter
*pAd
= NULL
;
648 GET_PAD_FROM_NET_DEV(pAd
, net_dev
);
652 pAd
->stats
.rx_packets
=
653 pAd
->WlanCounters
.ReceivedFragmentCount
.QuadPart
;
654 pAd
->stats
.tx_packets
=
655 pAd
->WlanCounters
.TransmittedFragmentCount
.QuadPart
;
657 pAd
->stats
.rx_bytes
= pAd
->RalinkCounters
.ReceivedByteCount
;
658 pAd
->stats
.tx_bytes
= pAd
->RalinkCounters
.TransmittedByteCount
;
660 pAd
->stats
.rx_errors
= pAd
->Counters8023
.RxErrors
;
661 pAd
->stats
.tx_errors
= pAd
->Counters8023
.TxErrors
;
663 pAd
->stats
.rx_dropped
= 0;
664 pAd
->stats
.tx_dropped
= 0;
666 pAd
->stats
.multicast
= pAd
->WlanCounters
.MulticastReceivedFrameCount
.QuadPart
; /* multicast packets received */
667 pAd
->stats
.collisions
= pAd
->Counters8023
.OneCollision
+ pAd
->Counters8023
.MoreCollisions
; /* Collision packets */
669 pAd
->stats
.rx_length_errors
= 0;
670 pAd
->stats
.rx_over_errors
= pAd
->Counters8023
.RxNoBuffer
; /* receiver ring buff overflow */
671 pAd
->stats
.rx_crc_errors
= 0; /*pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error */
672 pAd
->stats
.rx_frame_errors
= pAd
->Counters8023
.RcvAlignmentErrors
; /* recv'd frame alignment error */
673 pAd
->stats
.rx_fifo_errors
= pAd
->Counters8023
.RxNoBuffer
; /* recv'r fifo overrun */
674 pAd
->stats
.rx_missed_errors
= 0; /* receiver missed packet */
676 /* detailed tx_errors */
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;
684 pAd
->stats
.rx_compressed
= 0;
685 pAd
->stats
.tx_compressed
= 0;
692 BOOLEAN
RtmpPhyNetDevExit(struct rt_rtmp_adapter
*pAd
, struct net_device
*net_dev
)
695 /* Unregister network device */
696 if (net_dev
!= NULL
) {
698 ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
700 RtmpOSNetDevDetach(net_dev
);
708 ========================================================================
710 Allocate memory for adapter control block.
713 pAd Pointer to our adapter
718 NDIS_STATUS_RESOURCES
721 ========================================================================
723 int AdapterBlockAllocateMemory(void *handle
, void ** ppAd
)
726 *ppAd
= vmalloc(sizeof(struct rt_rtmp_adapter
));
727 /* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
730 NdisZeroMemory(*ppAd
, sizeof(struct rt_rtmp_adapter
));
731 ((struct rt_rtmp_adapter
*)*ppAd
)->OS_Cookie
= handle
;
732 return NDIS_STATUS_SUCCESS
;
734 return NDIS_STATUS_FAILURE
;