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 -------- ---------- ----------------------------------------------
36 Sample Mar/21/07 Merge RT2870 and RT2860 drivers.
39 #include "rt_config.h"
41 #define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min
43 /*---------------------------------------------------------------------*/
44 /* Private Variables Used */
45 /*---------------------------------------------------------------------*/
46 //static RALINK_TIMER_STRUCT PeriodicTimer;
48 char *mac
= ""; // default 00:00:00:00:00:00
49 char *hostname
= ""; // default CMPC
50 module_param (mac
, charp
, 0);
51 MODULE_PARM_DESC (mac
, "rt28xx: wireless mac addr");
54 /*---------------------------------------------------------------------*/
55 /* Prototypes of Functions Used */
56 /*---------------------------------------------------------------------*/
57 extern BOOLEAN
ba_reordering_resource_init(PRTMP_ADAPTER pAd
, int num
);
58 extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd
);
59 extern NDIS_STATUS
NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd
);
62 extern void init_thread_task(PRTMP_ADAPTER pAd
);
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
);
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
);
73 static void CfgInitHook(PRTMP_ADAPTER pAd
);
75 extern const struct iw_handler_def rt28xx_iw_handler_def
;
77 // This function will be called when query /proc
78 struct iw_statistics
*rt28xx_get_wireless_stats(
79 IN
struct net_device
*net_dev
);
81 struct net_device_stats
*RT28xx_get_ether_stats(
82 IN
struct net_device
*net_dev
);
85 ========================================================================
90 *net_dev the raxx interface pointer
97 1. if open fail, kernel will not call the close function.
99 (1) Mlme Memory Handler: MlmeHalt()
100 (2) TX & RX: RTMPFreeTxRxRingMemory()
101 (3) BA Reordering: ba_reordering_resource_release()
102 ========================================================================
104 int MainVirtualIF_close(IN
struct net_device
*net_dev
)
106 RTMP_ADAPTER
*pAd
= net_dev
->ml_priv
;
108 // Sanity check for pAd
110 return 0; // close ok
112 netif_carrier_off(pAd
->net_dev
);
113 netif_stop_queue(pAd
->net_dev
);
116 VIRTUAL_IF_DOWN(pAd
);
118 RT_MOD_DEC_USE_COUNT();
120 return 0; // close ok
124 ========================================================================
129 *net_dev the raxx interface pointer
136 1. if open fail, kernel will not call the close function.
138 (1) Mlme Memory Handler: MlmeHalt()
139 (2) TX & RX: RTMPFreeTxRxRingMemory()
140 (3) BA Reordering: ba_reordering_resource_release()
141 ========================================================================
143 int MainVirtualIF_open(IN
struct net_device
*net_dev
)
145 RTMP_ADAPTER
*pAd
= net_dev
->ml_priv
;
147 // Sanity check for pAd
149 return 0; // close ok
151 if (VIRTUAL_IF_UP(pAd
) != 0)
154 // increase MODULE use count
155 RT_MOD_INC_USE_COUNT();
157 netif_start_queue(net_dev
);
158 netif_carrier_on(net_dev
);
159 netif_wake_queue(net_dev
);
165 ========================================================================
167 Close raxx interface.
170 *net_dev the raxx interface pointer
177 1. if open fail, kernel will not call the close function.
179 (1) Mlme Memory Handler: MlmeHalt()
180 (2) TX & RX: RTMPFreeTxRxRingMemory()
181 (3) BA Reordering: ba_reordering_resource_release()
182 ========================================================================
184 int rt28xx_close(IN PNET_DEV dev
)
186 struct net_device
* net_dev
= (struct net_device
*)dev
;
187 RTMP_ADAPTER
*pAd
= net_dev
->ml_priv
;
188 BOOLEAN Cancelled
= FALSE
;
191 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup
);
192 DECLARE_WAITQUEUE(wait
, current
);
194 //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
198 DBGPRINT(RT_DEBUG_TRACE
, ("===> rt28xx_close\n"));
200 // Sanity check for pAd
202 return 0; // close ok
205 // If dirver doesn't wake up firmware here,
206 // NICLoadFirmware will hang forever when interface is up again.
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
))
213 if (OPSTATUS_TEST_FLAG(pAd
, fOP_STATUS_DOZE
))
217 AsicForceWakeup(pAd
, RTMP_HALT
);
220 AsicForceWakeup(pAd
, TRUE
);
225 (!RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_NIC_NOT_EXIST
)))
227 MLME_DISASSOC_REQ_STRUCT DisReq
;
228 MLME_QUEUE_ELEM
*MsgElem
= (MLME_QUEUE_ELEM
*) kmalloc(sizeof(MLME_QUEUE_ELEM
), MEM_ALLOC_FLAG
);
230 COPY_MAC_ADDR(DisReq
.Addr
, pAd
->CommonCfg
.Bssid
);
231 DisReq
.Reason
= REASON_DEAUTH_STA_LEAVING
;
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
));
238 // Prevent to connect AP again in STAMlmePeriodicExec
239 pAd
->MlmeAux
.AutoReconnectSsidLen
= 32;
240 NdisZeroMemory(pAd
->MlmeAux
.AutoReconnectSsid
, pAd
->MlmeAux
.AutoReconnectSsidLen
);
242 pAd
->Mlme
.CntlMachine
.CurrState
= CNTL_WAIT_OID_DISASSOC
;
243 MlmeDisassocReqAction(pAd
, MsgElem
);
250 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_REMOVE_IN_PROGRESS
);
254 RTMPCancelTimer(&pAd
->StaCfg
.LeapAuthTimer
, &Cancelled
);
257 RTMPCancelTimer(&pAd
->StaCfg
.StaQuickResponeForRateUpTimer
, &Cancelled
);
258 RTMPCancelTimer(&pAd
->StaCfg
.WpaDisassocAndBlockAssocTimer
, &Cancelled
);
262 pAd
->bPCIclkOff
= FALSE
;
266 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
268 for (i
= 0 ; i
< NUM_OF_TX_RING
; i
++)
270 while (pAd
->DeQueueRunning
[i
] == TRUE
)
272 printk("Waiting for TxQueue[%d] done..........\n", i
);
278 // ensure there are no more active urbs.
279 add_wait_queue (&unlink_wakeup
, &wait
);
280 pAd
->wait
= &unlink_wakeup
;
282 // maybe wait for deletions to finish.
284 //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
287 unsigned long IrqFlags
;
289 RTMP_IRQ_LOCK(&pAd
->BulkInLock
, IrqFlags
);
290 if (pAd
->PendingRx
== 0)
292 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
295 RTMP_IRQ_UNLOCK(&pAd
->BulkInLock
, IrqFlags
);
297 msleep(UNLINK_TIMEOUT_MS
); //Time in millisecond
301 remove_wait_queue (&unlink_wakeup
, &wait
);
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
);
311 // Stop Mlme state machine
314 // Close kernel threads or tasklets
315 kill_thread_task(pAd
);
319 MeasureReqTabExit(pAd
);
323 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
))
325 NICDisableInterrupt(pAd
);
328 // Disable Rx, register value supposed will remain after reset
332 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
))
334 // Deregister interrupt function
335 RT28XX_IRQ_RELEASE(net_dev
)
336 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
340 // Free Ring or USB buffers
341 RTMPFreeTxRxRingMemory(pAd
);
343 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_HALT_IN_PROGRESS
);
345 // Free BA reorder resource
346 ba_reordering_resource_release(pAd
);
348 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
350 return 0; // close ok
351 } /* End of rt28xx_close */
353 static int rt28xx_init(IN
struct net_device
*net_dev
)
356 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
)net_dev
->ml_priv
;
359 PRTMP_ADAPTER pAd
= net_dev
->ml_priv
;
366 // Allocate BA Reordering memory
367 ba_reordering_resource_init(pAd
, MAX_REORDERING_MPDU_NUM
);
369 // Make sure MAC gets ready.
373 RTMP_IO_READ32(pAd
, MAC_CSR0
, &MacCsr0
);
374 pAd
->MACVersion
= MacCsr0
;
376 if ((pAd
->MACVersion
!= 0x00) && (pAd
->MACVersion
!= 0xFFFFFFFF))
380 } while (index
++ < 100);
382 DBGPRINT(RT_DEBUG_TRACE
, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd
->MACVersion
));
383 /*Iverson patch PCIE L1 issue */
386 RT28XXDMADisable(pAd
);
388 // Load 8051 firmware
389 Status
= NICLoadFirmware(pAd
);
390 if (Status
!= NDIS_STATUS_SUCCESS
)
392 DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status
));
396 NICLoadRateSwitchingParams(pAd
);
398 // Disable interrupts here which is as soon as possible
399 // This statement should never be true. We might consider to remove it later
401 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_ACTIVE
))
403 NICDisableInterrupt(pAd
);
407 Status
= RTMPAllocTxRxRingMemory(pAd
);
408 if (Status
!= NDIS_STATUS_SUCCESS
)
410 DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status
));
414 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
419 Status
= MlmeInit(pAd
);
420 if (Status
!= NDIS_STATUS_SUCCESS
)
422 DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status
));
426 // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
431 // We need init timerQ related structure before create the timer thread.
432 RT2870_TimerQ_Init(pAd
);
435 RT28XX_TASK_THREAD_INIT(pAd
, Status
);
436 if (Status
!= NDIS_STATUS_SUCCESS
)
441 NdisAllocateSpinLock(&pAd
->MacTabLock
);
443 MeasureReqTabInit(pAd
);
447 // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
449 Status
= NICInitializeAdapter(pAd
, TRUE
);
450 if (Status
!= NDIS_STATUS_SUCCESS
)
452 DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status
));
453 if (Status
!= NDIS_STATUS_SUCCESS
)
457 // Read parameters from Config File
458 Status
= RTMPReadParametersHook(pAd
);
460 printk("1. Phy Mode = %d\n", pAd
->CommonCfg
.PhyMode
);
461 if (Status
!= NDIS_STATUS_SUCCESS
)
463 DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status
));
468 pAd
->CommonCfg
.bMultipleIRP
= FALSE
;
470 if (pAd
->CommonCfg
.bMultipleIRP
)
471 pAd
->CommonCfg
.NumOfBulkInIRP
= RX_RING_SIZE
;
473 pAd
->CommonCfg
.NumOfBulkInIRP
= 1;
477 //Init Ba Capability parameters.
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
;
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
;
487 printk("2. Phy Mode = %d\n", pAd
->CommonCfg
.PhyMode
);
489 // We should read EEPROM for all cases. rt2860b
490 NICReadEEPROMParameters(pAd
, mac
);
492 printk("3. Phy Mode = %d\n", pAd
->CommonCfg
.PhyMode
);
494 NICInitAsicFromEEPROM(pAd
); //rt2860b
496 // Set PHY to appropriate mode
497 TmpPhy
= pAd
->CommonCfg
.PhyMode
;
498 pAd
->CommonCfg
.PhyMode
= 0xff;
499 RTMPSetPhyMode(pAd
, TmpPhy
);
502 // No valid channels.
503 if (pAd
->ChannelListNum
== 0)
505 printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
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]);
514 //Init RT30xx RFRegisters after read RFIC type from EEPROM
515 NICInitRT30xxRFRegisters(pAd
);
520 // Initialize RF register to default value
522 AsicSwitchChannel(pAd
, pAd
->CommonCfg
.Channel
, FALSE
);
523 AsicLockChannel(pAd
, pAd
->CommonCfg
.Channel
);
526 // 8051 firmware require the signal during booting time.
527 AsicSendCommandToMcu(pAd
, 0x72, 0xFF, 0x00, 0x00);
530 if (pAd
&& (Status
!= NDIS_STATUS_SUCCESS
))
533 // Undo everything if it failed
535 if (RTMP_TEST_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
))
537 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_INTERRUPT_IN_USE
);
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
);
546 DBGPRINT(RT_DEBUG_TRACE
, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
550 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_RESET_IN_PROGRESS
);
551 RTMP_CLEAR_FLAG(pAd
, fRTMP_ADAPTER_REMOVE_IN_PROGRESS
);
554 // Support multiple BulkIn IRP,
555 // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
557 for(index
=0; index
<pAd
->CommonCfg
.NumOfBulkInIRP
; index
++)
559 RTUSBBulkReceive(pAd
);
560 DBGPRINT(RT_DEBUG_TRACE
, ("RTUSBBulkReceive!\n" ));
566 DBGPRINT_S(Status
, ("<==== RTMPInitialize, Status=%x\n", Status
));
575 RTMPFreeTxRxRingMemory(pAd
);
577 os_free_mem(pAd
, pAd
->mpdu_blk_pool
.mem
); // free BA pool
578 RT28XX_IRQ_RELEASE(net_dev
);
580 // shall not set ml_priv to NULL here because the ml_priv didn't been free yet.
581 //net_dev->ml_priv = 0;
583 printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME
);
585 } /* End of rt28xx_init */
589 ========================================================================
594 *net_dev the raxx interface pointer
601 ========================================================================
603 int rt28xx_open(IN PNET_DEV dev
)
605 struct net_device
* net_dev
= (struct net_device
*)dev
;
606 PRTMP_ADAPTER pAd
= net_dev
->ml_priv
;
611 // Sanity check for pAd
614 /* if 1st open fail, pAd will be free;
615 So the net_dev->ml_priv will be NULL in 2rd open */
620 pObj
= (POS_COOKIE
)pAd
->OS_Cookie
;
622 // reset Adapter flags
623 RTMP_CLEAR_FLAGS(pAd
);
625 // Request interrupt service routine for PCI device
626 // register the interrupt routine with the os
627 RT28XX_IRQ_REQUEST(net_dev
);
630 // Init BssTab & ChannelInfo tabbles for auto channel select.
634 if (rt28xx_init(net_dev
) == FALSE
)
637 NdisZeroMemory(pAd
->StaCfg
.dev_name
, 16);
638 NdisMoveMemory(pAd
->StaCfg
.dev_name
, net_dev
->name
, strlen(net_dev
->name
));
640 // Set up the Mac address
641 NdisMoveMemory(net_dev
->dev_addr
, (void *) pAd
->CurrentAddress
, 6);
643 // Init IRQ parameters
644 RT28XX_IRQ_INIT(pAd
);
646 // Various AP function init
649 RT28XX_IRQ_ENABLE(pAd
);
653 RTMP_SET_FLAG(pAd
, fRTMP_ADAPTER_START_UP
);
657 RTMP_IO_READ32(pAd
, 0x1300, ®
); // clear garbage interrupts
658 printk("0x1300 = %08x\n", reg
);
662 RTMPInitPCIeLinkCtrlValue(pAd
);
668 } /* End of rt28xx_open */
670 static const struct net_device_ops rt2860_netdev_ops
= {
671 .ndo_open
= MainVirtualIF_open
,
672 .ndo_stop
= MainVirtualIF_close
,
673 .ndo_do_ioctl
= rt28xx_sta_ioctl
,
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
,
678 .ndo_start_xmit
= rt28xx_send_packets
,
681 /* Must not be called for mdev and apdev */
682 static NDIS_STATUS
rt_ieee80211_if_setup(struct net_device
*dev
, PRTMP_ADAPTER pAd
)
686 CHAR slot_name
[IFNAMSIZ
];
687 struct net_device
*device
;
689 if (pAd
->OpMode
== OPMODE_STA
)
691 dev
->wireless_handlers
= &rt28xx_iw_handler_def
;
694 dev
->priv_flags
= INT_MAIN
;
695 dev
->netdev_ops
= &rt2860_netdev_ops
;
696 // find available device name
697 for (i
= 0; i
< 8; i
++)
699 sprintf(slot_name
, "wlan%d", i
);
701 device
= dev_get_by_name(dev_net(dev
), slot_name
);
711 DBGPRINT(RT_DEBUG_ERROR
, ("No available slot name\n"));
712 Status
= NDIS_STATUS_FAILURE
;
716 sprintf(dev
->name
, "wlan%d", i
);
717 Status
= NDIS_STATUS_SUCCESS
;
725 ========================================================================
727 Probe RT28XX chipset.
730 _dev_p Point to the PCI or USB device
731 _dev_id_p Point to the PCI or USB device ID
738 ========================================================================
740 INT __devinit
rt28xx_probe(
744 OUT PRTMP_ADAPTER
*ppAd
)
746 struct net_device
*net_dev
;
747 PRTMP_ADAPTER pAd
= (PRTMP_ADAPTER
) NULL
;
751 struct pci_dev
*dev_p
= (struct pci_dev
*)_dev_p
;
754 struct usb_interface
*intf
= (struct usb_interface
*)_dev_p
;
755 struct usb_device
*dev_p
= interface_to_usbdev(intf
);
757 dev_p
= usb_get_dev(dev_p
);
760 DBGPRINT(RT_DEBUG_TRACE
, ("STA Driver version-%s\n", STA_DRIVER_VERSION
));
762 net_dev
= alloc_etherdev(sizeof(PRTMP_ADAPTER
));
765 printk("alloc_netdev failed\n");
770 netif_stop_queue(net_dev
);
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.
776 SET_NETDEV_DEV(net_dev
, &(dev_p
->dev
));
778 // Allocate RTMP_ADAPTER miniport adapter structure
779 handle
= kmalloc(sizeof(struct os_cookie
), GFP_KERNEL
);
781 goto err_out_free_netdev
;;
782 RT28XX_HANDLE_DEV_ASSIGN(handle
, dev_p
);
784 status
= RTMPAllocAdapterBlock(handle
, &pAd
);
785 if (status
!= NDIS_STATUS_SUCCESS
)
786 goto err_out_free_netdev
;
788 net_dev
->ml_priv
= (PVOID
)pAd
;
789 pAd
->net_dev
= net_dev
; // must be before RT28XXNetDevInit()
791 RT28XXNetDevInit(_dev_p
, net_dev
, pAd
);
793 pAd
->StaCfg
.OriDevType
= net_dev
->type
;
796 if (RT28XXProbePostConfig(_dev_p
, pAd
, 0) == FALSE
)
799 pAd
->OpMode
= OPMODE_STA
;
802 if (rt_ieee80211_if_setup(net_dev
, pAd
) != NDIS_STATUS_SUCCESS
)
805 // Register this device
806 status
= register_netdev(net_dev
);
811 RT28XX_DRVDATA_SET(_dev_p
);
814 return 0; // probe ok
817 /* --------------------------- ERROR HANDLE --------------------------- */
819 RTMPFreeAdapter(pAd
);
823 free_netdev(net_dev
);
826 RT28XX_PUT_DEVICE(dev_p
);
828 return -ENODEV
; /* probe fail */
829 } /* End of rt28xx_probe */
833 ========================================================================
835 The entry point for Linux kernel sent packet to our driver.
838 sk_buff *skb the pointer refer to a sk_buffer.
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
847 ========================================================================
849 int rt28xx_packet_xmit(struct sk_buff
*skb
)
851 struct net_device
*net_dev
= skb
->dev
;
852 PRTMP_ADAPTER pAd
= net_dev
->ml_priv
;
853 int status
= NETDEV_TX_OK
;
854 PNDIS_PACKET pPacket
= (PNDIS_PACKET
) skb
;
857 // Drop send request since we are in monitor mode
860 RELEASE_NDIS_PACKET(pAd
, pPacket
, NDIS_STATUS_FAILURE
);
865 // EapolStart size is 18
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
);
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);
881 STASendPackets((NDIS_HANDLE
)pAd
, (PPNDIS_PACKET
) &pPacket
, 1);
883 status
= NETDEV_TX_OK
;
891 ========================================================================
893 Send a packet to WLAN.
896 skb_p points to our adapter
897 dev_p which WLAN network interface
900 0: transmit successfully
901 otherwise: transmit fail
904 ========================================================================
906 INT
rt28xx_send_packets(
907 IN
struct sk_buff
*skb_p
,
908 IN
struct net_device
*net_dev
)
910 RTMP_ADAPTER
*pAd
= net_dev
->ml_priv
;
911 if (!(net_dev
->flags
& IFF_UP
))
913 RELEASE_NDIS_PACKET(pAd
, (PNDIS_PACKET
)skb_p
, NDIS_STATUS_FAILURE
);
917 NdisZeroMemory((PUCHAR
)&skb_p
->cb
[CB_OFF
], 15);
918 RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p
, MAIN_MBSSID
);
920 return rt28xx_packet_xmit(skb_p
);
922 } /* End of MBSS_VirtualIF_PacketSend */
927 void CfgInitHook(PRTMP_ADAPTER pAd
)
929 pAd
->bBroadComHT
= TRUE
;
930 } /* End of CfgInitHook */
933 // This function will be called when query /proc
934 struct iw_statistics
*rt28xx_get_wireless_stats(
935 IN
struct net_device
*net_dev
)
937 PRTMP_ADAPTER pAd
= net_dev
->ml_priv
;
940 DBGPRINT(RT_DEBUG_TRACE
, ("rt28xx_get_wireless_stats --->\n"));
942 pAd
->iw_stats
.status
= 0; // Status - device dependent for now
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;
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
);
952 pAd
->iw_stats
.qual
.noise
= pAd
->BbpWriteLatch
[66]; // noise level (dBm)
954 pAd
->iw_stats
.qual
.noise
+= 256 - 143;
955 pAd
->iw_stats
.qual
.updated
= 1; // Flags to know if updated
957 pAd
->iw_stats
.qual
.updated
|= IW_QUAL_DBM
; // Level + Noise are dBm
958 #endif // IW_QUAL_DBM //
960 pAd
->iw_stats
.discard
.nwid
= 0; // Rx : Wrong nwid/essid
961 pAd
->iw_stats
.miss
.beacon
= 0; // Missed beacons/superframe
963 DBGPRINT(RT_DEBUG_TRACE
, ("<--- rt28xx_get_wireless_stats\n"));
964 return &pAd
->iw_stats
;
965 } /* End of rt28xx_get_wireless_stats */
969 void tbtt_tasklet(unsigned long data
)
971 #define MAX_TX_IN_TBTT (16)
976 ========================================================================
979 return ethernet statistics counter
982 net_dev Pointer to net_device
989 ========================================================================
991 struct net_device_stats
*RT28xx_get_ether_stats(
992 IN
struct net_device
*net_dev
)
994 RTMP_ADAPTER
*pAd
= NULL
;
997 pAd
= net_dev
->ml_priv
;
1002 pAd
->stats
.rx_packets
= pAd
->WlanCounters
.ReceivedFragmentCount
.QuadPart
;
1003 pAd
->stats
.tx_packets
= pAd
->WlanCounters
.TransmittedFragmentCount
.QuadPart
;
1005 pAd
->stats
.rx_bytes
= pAd
->RalinkCounters
.ReceivedByteCount
;
1006 pAd
->stats
.tx_bytes
= pAd
->RalinkCounters
.TransmittedByteCount
;
1008 pAd
->stats
.rx_errors
= pAd
->Counters8023
.RxErrors
;
1009 pAd
->stats
.tx_errors
= pAd
->Counters8023
.TxErrors
;
1011 pAd
->stats
.rx_dropped
= 0;
1012 pAd
->stats
.tx_dropped
= 0;
1014 pAd
->stats
.multicast
= pAd
->WlanCounters
.MulticastReceivedFrameCount
.QuadPart
; // multicast packets received
1015 pAd
->stats
.collisions
= pAd
->Counters8023
.OneCollision
+ pAd
->Counters8023
.MoreCollisions
; // Collision packets
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
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;
1032 pAd
->stats
.rx_compressed
= 0;
1033 pAd
->stats
.tx_compressed
= 0;