1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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  *************************************************************************
26 
27     Module Name:
28     rt_main_dev.c
29 
30     Abstract:
31     Create and register network interface.
32 
33     Revision History:
34     Who         	When            What
35     Justin P. Mattock	11/07/2010	Fix typos in comments
36     --------    ----------      ----------------------------------------------
37 */
38 
39 #include "rt_config.h"
40 
41 /*---------------------------------------------------------------------*/
42 /* Private Variables Used                                              */
43 /*---------------------------------------------------------------------*/
44 
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");
49 
50 /*---------------------------------------------------------------------*/
51 /* Prototypes of Functions Used                                        */
52 /*---------------------------------------------------------------------*/
53 
54 /* public function prototype */
55 int rt28xx_close(IN struct net_device *net_dev);
56 int rt28xx_open(struct net_device *net_dev);
57 
58 /* private function prototype */
59 static int rt28xx_send_packets(IN struct sk_buff *skb_p,
60 			       IN struct net_device *net_dev);
61 
62 static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
63 						       *net_dev);
64 
65 /*
66 ========================================================================
67 Routine Description:
68     Close raxx interface.
69 
70 Arguments:
71 	*net_dev			the raxx interface pointer
72 
73 Return Value:
74     0					Open OK
75 	otherwise			Open Fail
76 
77 Note:
78 	1. if open fail, kernel will not call the close function.
79 	2. Free memory for
80 		(1) Mlme Memory Handler:		MlmeHalt()
81 		(2) TX & RX:					RTMPFreeTxRxRingMemory()
82 		(3) BA Reordering: 				ba_reordering_resource_release()
83 ========================================================================
84 */
MainVirtualIF_close(IN struct net_device * net_dev)85 int 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 	/* Sanity check for pAd */
92 	if (pAd == NULL)
93 		return 0;	/* close ok */
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 				/* Prevent to connect AP again in STAMlmePeriodicExec */
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;		/* close ok */
147 }
148 
149 /*
150 ========================================================================
151 Routine Description:
152     Open raxx interface.
153 
154 Arguments:
155 	*net_dev			the raxx interface pointer
156 
157 Return Value:
158     0					Open OK
159 	otherwise			Open Fail
160 
161 Note:
162 	1. if open fail, kernel will not call the close function.
163 	2. Free memory for
164 		(1) Mlme Memory Handler:		MlmeHalt()
165 		(2) TX & RX:					RTMPFreeTxRxRingMemory()
166 		(3) BA Reordering: 				ba_reordering_resource_release()
167 ========================================================================
168 */
MainVirtualIF_open(IN struct net_device * net_dev)169 int 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 	/* Sanity check for pAd */
176 	if (pAd == NULL)
177 		return 0;	/* close ok */
178 
179 	if (VIRTUAL_IF_UP(pAd) != 0)
180 		return -1;
181 
182 	/* increase MODULE use count */
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 Routine Description:
195     Close raxx interface.
196 
197 Arguments:
198 	*net_dev			the raxx interface pointer
199 
200 Return Value:
201     0					Open OK
202 	otherwise			Open Fail
203 
204 Note:
205 	1. if open fail, kernel will not call the close function.
206 	2. Free memory for
207 		(1) Mlme Memory Handler:		MlmeHalt()
208 		(2) TX & RX:					RTMPFreeTxRxRingMemory()
209 		(3) BA Reordering: 				ba_reordering_resource_release()
210 ========================================================================
211 */
rt28xx_close(struct net_device * dev)212 int 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 /* RTMP_MAC_USB // */
223 
224 	GET_PAD_FROM_NET_DEV(pAd, net_dev);
225 
226 	DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
227 
228 	Cancelled = FALSE;
229 	/* Sanity check for pAd */
230 	if (pAd == NULL)
231 		return 0;	/* close ok */
232 
233 	{
234 #ifdef RTMP_MAC_PCI
235 		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
236 #endif /* RTMP_MAC_PCI // */
237 
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);
242 		}
243 #ifdef RTMP_MAC_USB
244 		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
245 #endif /* RTMP_MAC_USB // */
246 
247 		MlmeRadioOff(pAd);
248 #ifdef RTMP_MAC_PCI
249 		pAd->bPCIclkOff = FALSE;
250 #endif /* RTMP_MAC_PCI // */
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 	/* ensure there are no more active urbs. */
266 	add_wait_queue(&unlink_wakeup, &wait);
267 	pAd->wait = &unlink_wakeup;
268 
269 	/* maybe wait for deletions to finish. */
270 	i = 0;
271 	/*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
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);	/*Time in millisecond */
283 		i++;
284 	}
285 	pAd->wait = NULL;
286 	remove_wait_queue(&unlink_wakeup, &wait);
287 #endif /* RTMP_MAC_USB // */
288 
289 	/* Stop Mlme state machine */
290 	MlmeHalt(pAd);
291 
292 	/* Close net tasklets */
293 	RtmpNetTaskExit(pAd);
294 
295 	{
296 		MacTableReset(pAd);
297 	}
298 
299 	MeasureReqTabExit(pAd);
300 	TpcReqTabExit(pAd);
301 
302 	/* Close kernel threads */
303 	RtmpMgmtTaskExit(pAd);
304 
305 #ifdef RTMP_MAC_PCI
306 	{
307 		BOOLEAN brc;
308 		/*      unsigned long                   Value; */
309 
310 		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
311 			RTMP_ASIC_INTERRUPT_DISABLE(pAd);
312 		}
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. */
317 
318 		brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
319 
320 /*In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
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 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
332 	{
333 		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
334 	}
335 
336 	// Disable Rx, register value supposed will remain after reset
337 	NICIssueReset(pAd);
338 */
339 #endif /* RTMP_MAC_PCI // */
340 
341 	/* Free IRQ */
342 	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
343 #ifdef RTMP_MAC_PCI
344 		/* Deregister interrupt function */
345 		RtmpOSIRQRelease(net_dev);
346 #endif /* RTMP_MAC_PCI // */
347 		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
348 	}
349 	/* Free Ring or USB buffers */
350 	RTMPFreeTxRxRingMemory(pAd);
351 
352 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
353 
354 	/* Free BA reorder resource */
355 	ba_reordering_resource_release(pAd);
356 
357 	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
358 
359 /*+++Modify by woody to solve the bulk fail+++*/
360 	{
361 	}
362 
363 	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
364 	return 0;		/* close ok */
365 }				/* End of rt28xx_close */
366 
367 /*
368 ========================================================================
369 Routine Description:
370     Open raxx interface.
371 
372 Arguments:
373 	*net_dev			the raxx interface pointer
374 
375 Return Value:
376     0					Open OK
377 	otherwise			Open Fail
378 
379 Note:
380 ========================================================================
381 */
rt28xx_open(struct net_device * dev)382 int 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 	/*struct os_cookie *pObj; */
388 
389 	GET_PAD_FROM_NET_DEV(pAd, net_dev);
390 
391 	/* Sanity check for pAd */
392 	if (pAd == NULL) {
393 		/* if 1st open fail, pAd will be free;
394 		   So the net_dev->ml_priv will be NULL in 2rd open */
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 	/* Request interrupt service routine for PCI device */
404 	/* register the interrupt routine with the os */
405 	RtmpOSIRQRequest(net_dev);
406 
407 	/* Init IRQ parameters stored in pAd */
408 	RTMP_IRQ_INIT(pAd);
409 
410 	/* Chip & other init */
411 	if (rt28xx_init(pAd, mac, hostname) == FALSE)
412 		goto err;
413 
414 	/* Enable Interrupt */
415 	RTMP_IRQ_ENABLE(pAd);
416 
417 	/* Now Enable RxTx */
418 	RTMPEnableRxTx(pAd);
419 	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
420 
421 	{
422 		u32 reg = 0;
423 		RTMP_IO_READ32(pAd, 0x1300, &reg);	/* clear garbage interrupts */
424 		printk(KERN_DEBUG "0x1300 = %08x\n", reg);
425 	}
426 
427 	{
428 /*      u32 reg; */
429 /*      u8  byte; */
430 /*      u16 tmp; */
431 
432 /*      RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg); */
433 
434 /*      tmp = 0x0805; */
435 /*      reg  = (reg & 0xffff0000) | tmp; */
436 /*      RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
437 
438 	}
439 #ifdef RTMP_MAC_PCI
440 	RTMPInitPCIeLinkCtrlValue(pAd);
441 #endif /* RTMP_MAC_PCI // */
442 
443 	return retval;
444 
445 err:
446 /*+++Add by shiang, move from rt28xx_init() to here. */
447 	RtmpOSIRQRelease(net_dev);
448 /*---Add by shiang, move from rt28xx_init() to here. */
449 	return -1;
450 }				/* End of rt28xx_open */
451 
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,
461 };
462 
RtmpPhyNetDevInit(struct rt_rtmp_adapter * pAd,struct rt_rtmp_os_netdev_op_hook * pNetDevHook)463 struct 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 /*      int             Status; */
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 Routine Description:
494     The entry point for Linux kernel sent packet to our driver.
495 
496 Arguments:
497     sk_buff *skb		the pointer refer to a sk_buffer.
498 
499 Return Value:
500     0
501 
502 Note:
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
505 	in here.
506 ========================================================================
507 */
rt28xx_packet_xmit(struct sk_buff * skb)508 int 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 	/* RT2870STA does this in RTMPSendPackets() */
518 
519 	{
520 		/* Drop send request since we are in monitor mode */
521 		if (MONITOR_ON(pAd)) {
522 			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
523 			goto done;
524 		}
525 	}
526 
527 	/* EapolStart size is 18 */
528 	if (skb->len < 14) {
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);
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;
539 done:
540 
541 	return status;
542 }
543 
544 /*
545 ========================================================================
546 Routine Description:
547     Send a packet to WLAN.
548 
549 Arguments:
550     skb_p           points to our adapter
551     dev_p           which WLAN network interface
552 
553 Return Value:
554     0: transmit successfully
555     otherwise: transmit fail
556 
557 Note:
558 ========================================================================
559 */
rt28xx_send_packets(IN struct sk_buff * skb_p,IN struct net_device * net_dev)560 static 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 /* This function will be called when query /proc */
rt28xx_get_wireless_stats(IN struct net_device * net_dev)580 struct 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;	/* Status - device dependent for now */
589 
590 	/* link quality */
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];	/* noise level (dBm) */
606 
607 	pAd->iw_stats.qual.noise += 256 - 143;
608 	pAd->iw_stats.qual.updated = 1;	/* Flags to know if updated */
609 #ifdef IW_QUAL_DBM
610 	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	/* Level + Noise are dBm */
611 #endif /* IW_QUAL_DBM // */
612 
613 	pAd->iw_stats.discard.nwid = 0;	/* Rx : Wrong nwid/essid */
614 	pAd->iw_stats.miss.beacon = 0;	/* Missed beacons/superframe */
615 
616 	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
617 	return &pAd->iw_stats;
618 }
619 
tbtt_tasklet(unsigned long data)620 void tbtt_tasklet(unsigned long data)
621 {
622 /*#define MAX_TX_IN_TBTT                (16) */
623 
624 }
625 
626 /*
627     ========================================================================
628 
629     Routine Description:
630 	return ethernet statistics counter
631 
632     Arguments:
633 	net_dev				Pointer to net_device
634 
635     Return Value:
636 	net_device_stats*
637 
638     Note:
639 
640     ========================================================================
641 */
RT28xx_get_ether_stats(IN struct net_device * net_dev)642 static 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;	/* multicast packets received */
667 		pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;	/* Collision packets */
668 
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 */
675 
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;
682 
683 		/* for cslip etc */
684 		pAd->stats.rx_compressed = 0;
685 		pAd->stats.tx_compressed = 0;
686 
687 		return &pAd->stats;
688 	} else
689 		return NULL;
690 }
691 
RtmpPhyNetDevExit(struct rt_rtmp_adapter * pAd,struct net_device * net_dev)692 BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
693 {
694 
695 	/* Unregister network device */
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 Routine Description:
710     Allocate memory for adapter control block.
711 
712 Arguments:
713     pAd					Pointer to our adapter
714 
715 Return Value:
716 	NDIS_STATUS_SUCCESS
717 	NDIS_STATUS_FAILURE
718 	NDIS_STATUS_RESOURCES
719 
720 Note:
721 ========================================================================
722 */
AdapterBlockAllocateMemory(void * handle,void ** ppAd)723 int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
724 {
725 
726 	*ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
727 	/* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
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