Linux 2.6.33.13
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / rt2860 / rt_main_dev.c
blobdf559dac768a1cfb5b8f626b13ec96f7d0e8c2a6
1 /*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
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. *
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 *************************************************************************
27 Module Name:
28 rt_main_dev.c
30 Abstract:
31 Create and register network interface.
33 Revision History:
34 Who When What
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
62 *net_dev);
65 ========================================================================
66 Routine Description:
67 Close raxx interface.
69 Arguments:
70 *net_dev the raxx interface pointer
72 Return Value:
73 0 Open OK
74 otherwise Open Fail
76 Note:
77 1. if open fail, kernel will not call the close function.
78 2. Free memory for
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 */
91 if (pAd == NULL)
92 return 0; /* close ok */
94 netif_carrier_off(pAd->net_dev);
95 netif_stop_queue(pAd->net_dev);
98 BOOLEAN Cancelled;
100 if (INFRA_ON(pAd) &&
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),
105 MEM_ALLOC_FLAG);
107 if (MsgElem) {
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;
114 MsgElem->MsgLen =
115 sizeof(struct rt_mlme_disassoc_req);
116 NdisMoveMemory(MsgElem->Msg, &DisReq,
117 sizeof
118 (struct rt_mlme_disassoc_req));
120 /* Prevent to connect AP again in STAMlmePeriodicExec */
121 pAd->MlmeAux.AutoReconnectSsidLen = 32;
122 NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
123 pAd->MlmeAux.
124 AutoReconnectSsidLen);
126 pAd->Mlme.CntlMachine.CurrState =
127 CNTL_WAIT_OID_DISASSOC;
128 MlmeDisassocReqAction(pAd, MsgElem);
129 kfree(MsgElem);
132 RTMPusecDelay(1000);
135 RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer,
136 &Cancelled);
137 RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
138 &Cancelled);
141 VIRTUAL_IF_DOWN(pAd);
143 RT_MOD_DEC_USE_COUNT();
145 return 0; /* close ok */
149 ========================================================================
150 Routine Description:
151 Open raxx interface.
153 Arguments:
154 *net_dev the raxx interface pointer
156 Return Value:
157 0 Open OK
158 otherwise Open Fail
160 Note:
161 1. if open fail, kernel will not call the close function.
162 2. Free memory for
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 */
175 if (pAd == NULL)
176 return 0; /* close ok */
178 if (VIRTUAL_IF_UP(pAd) != 0)
179 return -1;
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);
188 return 0;
192 ========================================================================
193 Routine Description:
194 Close raxx interface.
196 Arguments:
197 *net_dev the raxx interface pointer
199 Return Value:
200 0 Open OK
201 otherwise Open Fail
203 Note:
204 1. if open fail, kernel will not call the close function.
205 2. Free memory for
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;
215 BOOLEAN Cancelled;
216 u32 i = 0;
218 #ifdef RTMP_MAC_USB
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"));
227 Cancelled = FALSE;
228 /* Sanity check for pAd */
229 if (pAd == NULL)
230 return 0; /* close ok */
233 #ifdef RTMP_MAC_PCI
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);
242 #ifdef RTMP_MAC_USB
243 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
244 #endif /* RTMP_MAC_USB // */
246 MlmeRadioOff(pAd);
247 #ifdef RTMP_MAC_PCI
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",
258 i));
259 RTMPusecDelay(1000);
263 #ifdef RTMP_MAC_USB
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. */
269 i = 0;
270 /*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
271 while (i < 25) {
272 unsigned long IrqFlags;
274 RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
275 if (pAd->PendingRx == 0) {
276 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
277 break;
279 RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
281 msleep(UNLINK_TIMEOUT_MS); /*Time in millisecond */
282 i++;
284 pAd->wait = NULL;
285 remove_wait_queue(&unlink_wakeup, &wait);
286 #endif /* RTMP_MAC_USB // */
288 /* Stop Mlme state machine */
289 MlmeHalt(pAd);
291 /* Close net tasklets */
292 RtmpNetTaskExit(pAd);
295 MacTableReset(pAd);
298 MeasureReqTabExit(pAd);
299 TpcReqTabExit(pAd);
301 /* Close kernel threads */
302 RtmpMgmtTaskExit(pAd);
304 #ifdef RTMP_MAC_PCI
306 BOOLEAN brc;
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;
322 if (brc == FALSE) {
323 DBGPRINT(RT_DEBUG_ERROR,
324 ("%s call RT28xxPciAsicRadioOff fail!\n",
325 __func__));
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
336 NICIssueReset(pAd);
338 #endif /* RTMP_MAC_PCI // */
340 /* Free IRQ */
341 if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
342 #ifdef RTMP_MAC_PCI
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 ========================================================================
368 Routine Description:
369 Open raxx interface.
371 Arguments:
372 *net_dev the raxx interface pointer
374 Return Value:
375 0 Open OK
376 otherwise Open Fail
378 Note:
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;
385 int retval = 0;
386 /*struct os_cookie *pObj; */
388 GET_PAD_FROM_NET_DEV(pAd, net_dev);
390 /* Sanity check for pAd */
391 if (pAd == NULL) {
392 /* if 1st open fail, pAd will be free;
393 So the net_dev->ml_priv will be NULL in 2rd open */
394 return -1;
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 */
407 RTMP_IRQ_INIT(pAd);
409 /* Chip & other init */
410 if (rt28xx_init(pAd, mac, hostname) == FALSE)
411 goto err;
413 /* Enable Interrupt */
414 RTMP_IRQ_ENABLE(pAd);
416 /* Now Enable RxTx */
417 RTMPEnableRxTx(pAd);
418 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
421 u32 reg = 0;
422 RTMP_IO_READ32(pAd, 0x1300, &reg); /* clear garbage interrupts */
423 printk("0x1300 = %08x\n", reg);
427 /* u32 reg; */
428 /* u8 byte; */
429 /* u16 tmp; */
431 /* RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg); */
433 /* tmp = 0x0805; */
434 /* reg = (reg & 0xffff0000) | tmp; */
435 /* RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
438 #ifdef RTMP_MAC_PCI
439 RTMPInitPCIeLinkCtrlValue(pAd);
440 #endif /* RTMP_MAC_PCI // */
442 return (retval);
444 err:
445 /*+++Add by shiang, move from rt28xx_init() to here. */
446 RtmpOSIRQRelease(net_dev);
447 /*---Add by shiang, move from rt28xx_init() to here. */
448 return (-1);
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;
466 /* int Status; */
468 net_dev =
469 RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *),
470 INF_MAIN_DEV_NAME);
471 if (net_dev == NULL) {
472 printk
473 ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
474 return NULL;
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;
486 return net_dev;
491 ========================================================================
492 Routine Description:
493 The entry point for Linux kernel sent packet to our driver.
495 Arguments:
496 sk_buff *skb the pointer refer to a sk_buffer.
498 Return Value:
501 Note:
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
504 in here.
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);
522 goto done;
526 /* EapolStart size is 18 */
527 if (skb->len < 14) {
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);
531 goto done;
534 RTMP_SET_PACKET_5VT(pPacket, 0);
535 STASendPackets((void *)pAd, (void **)& pPacket, 1);
537 status = NETDEV_TX_OK;
538 done:
540 return status;
544 ========================================================================
545 Routine Description:
546 Send a packet to WLAN.
548 Arguments:
549 skb_p points to our adapter
550 dev_p which WLAN network interface
552 Return Value:
553 0: transmit successfully
554 otherwise: transmit fail
556 Note:
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);
569 return NETDEV_TX_OK;
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 */
589 /* link quality */
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 */
608 #ifdef IW_QUAL_DBM
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 ========================================================================
628 Routine Description:
629 return ethernet statistics counter
631 Arguments:
632 net_dev Pointer to net_device
634 Return Value:
635 net_device_stats*
637 Note:
639 ========================================================================
641 static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
642 *net_dev)
644 struct rt_rtmp_adapter *pAd = NULL;
646 if (net_dev)
647 GET_PAD_FROM_NET_DEV(pAd, net_dev);
649 if (pAd) {
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;
682 /* for cslip etc */
683 pAd->stats.rx_compressed = 0;
684 pAd->stats.tx_compressed = 0;
686 return &pAd->stats;
687 } else
688 return NULL;
691 BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
694 /* Unregister network device */
695 if (net_dev != NULL) {
696 printk
697 ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
698 net_dev->name);
699 RtmpOSNetDevDetach(net_dev);
702 return TRUE;
707 ========================================================================
708 Routine Description:
709 Allocate memory for adapter control block.
711 Arguments:
712 pAd Pointer to our adapter
714 Return Value:
715 NDIS_STATUS_SUCCESS
716 NDIS_STATUS_FAILURE
717 NDIS_STATUS_RESOURCES
719 Note:
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); */
727 if (*ppAd) {
728 NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
729 ((struct rt_rtmp_adapter *)* ppAd)->OS_Cookie = handle;
730 return (NDIS_STATUS_SUCCESS);
731 } else {
732 return (NDIS_STATUS_FAILURE);