• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/usb/Beceem_driver/src/Common/
1/*
2* Bcmnet.c
3*
4*Copyright (C) 2010 Beceem Communications, Inc.
5*
6*This program is free software: you can redistribute it and/or modify
7*it under the terms of the GNU General Public License version 2 as
8*published by the Free Software Foundation.
9*
10*This program is distributed in the hope that it will be useful,but
11*WITHOUT ANY WARRANTY; without even the implied warranty of
12*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*See the GNU General Public License for more details.
14*
15*You should have received a copy of the GNU General Public License
16*along with this program. If not, write to the Free Software Foundation, Inc.,
17*51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18*
19*/
20
21
22#include<headers.h>
23
24static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev)
25{
26	struct net_device *ndev = (struct net_device*)dev;
27    PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
28	//PMINI_ADAPTER 	Adapter = (PMINI_ADAPTER)ndev->priv;
29	if(strncmp(ndev->name,gblpnetdev->name,5)==0)
30	{
31		switch(event)
32		{
33			case NETDEV_CHANGEADDR:
34			case NETDEV_GOING_DOWN:
35				/*ignore this */
36					break;
37			case NETDEV_DOWN:
38				break;
39
40			case NETDEV_UP:
41				break;
42
43			case NETDEV_REGISTER:
44				 /* Increment the Reference Count for "veth0" */
45				 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n",
46									atomic_read(&ndev->refcnt));
47				 atomic_inc(&ndev->refcnt);
48				 break;
49
50			case NETDEV_UNREGISTER:
51				 /* Decrement the Reference Count for "veth0" */
52				BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n",
53									atomic_read(&ndev->refcnt));
54				atomic_dec(&ndev->refcnt);
55				if((int)atomic_read(&ndev->refcnt) < 0)
56					atomic_set(&ndev->refcnt, 0);
57				break;
58		};
59	}
60	return NOTIFY_DONE;
61}
62
63/* Notifier block to receive netdevice events */
64static struct notifier_block bcm_notifier_block =
65{
66	.notifier_call = bcm_notify_event,
67};
68
69struct net_device *gblpnetdev;
70/***************************************************************************************/
71/* proto-type of lower function */
72#ifdef BCM_SHM_INTERFACE
73const char *bcmVirtDeviceName="bcmeth";
74#endif
75
76static INT bcm_open(struct net_device *dev)
77{
78    PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
79	Adapter = GET_BCM_ADAPTER(dev);
80    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
81    if(Adapter->fw_download_done==FALSE)
82        return -EINVAL;
83	Adapter->if_up=1;
84	if(Adapter->LinkUpStatus == 1){
85		if(netif_queue_stopped(Adapter->dev)){
86			netif_carrier_on(Adapter->dev);
87			netif_start_queue(Adapter->dev);
88		}
89	}
90
91	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
92    return 0;
93}
94
95static INT bcm_close(struct net_device *dev)
96{
97   PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
98   Adapter = GET_BCM_ADAPTER(dev);
99    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
100	Adapter->if_up=0;
101	if(!netif_queue_stopped(dev)) {
102		netif_carrier_off(dev);
103	    netif_stop_queue(dev);
104	}
105    BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
106    return 0;
107}
108
109static struct net_device_stats *bcm_get_stats(struct net_device *dev)
110{
111    PLINUX_DEP_DATA pLinuxData=NULL;
112	PMINI_ADAPTER Adapter = NULL ;// gpadapter ;
113	Adapter = GET_BCM_ADAPTER(dev);
114    pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData);
115
116    //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData);
117	pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs;
118	pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount);
119	pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount);
120	pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount);
121	pLinuxData->netstats.rx_length_errors=0;
122	pLinuxData->netstats.rx_frame_errors=0;
123	pLinuxData->netstats.rx_crc_errors=0;
124	pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount);
125	pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount);
126	pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount);
127
128    return &(pLinuxData->netstats);
129}
130
131
132#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
133static const struct net_device_ops bcm_netdev_ops = {
134.ndo_open 	= bcm_open,
135.ndo_stop	= bcm_close,
136.ndo_get_stats 	= bcm_get_stats,
137.ndo_start_xmit = bcm_transmit,
138};
139#endif
140
141
142/**
143@ingroup init_functions
144Register other driver entry points with the kernel
145*/
146int register_networkdev(PMINI_ADAPTER Adapter)
147{
148	int result=0, reg_to_os = TRUE;
149#ifdef BCM_SHM_INTERFACE
150	int value = 0;
151#endif
152
153#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
154	int *temp = NULL ;
155#endif
156	Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER));
157	if(!Adapter->dev)
158	{
159		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev");
160		return -ENOMEM;
161	}
162	gblpnetdev							= Adapter->dev;
163#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
164	Adapter->dev->priv      			= Adapter;
165#else
166	temp = netdev_priv(Adapter->dev);
167	*temp = (UINT)Adapter;
168#endif
169	//BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp);
170#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)
171	Adapter->dev->open      			= bcm_open;
172	Adapter->dev->stop               	= bcm_close;
173	Adapter->dev->get_stats          	= bcm_get_stats;
174	Adapter->dev->hard_start_xmit    	= bcm_transmit;
175#else
176    Adapter->dev->netdev_ops = &bcm_netdev_ops;
177#endif
178
179	Adapter->dev->hard_header_len    	= ETH_HLEN + LEADER_SIZE;
180	Adapter->dev->mtu					= MTU_SIZE;
181
182	/* Read the MAC Address from EEPROM */
183	ReadMacAddressFromNVM(Adapter);
184
185
186#ifndef BCM_SHM_INTERFACE
187
188	/* Register the notifier block for getting netdevice events */
189	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n");
190	result = register_netdevice_notifier(&bcm_notifier_block);
191	if(result)
192	{
193		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered");
194		Adapter->bNetdeviceNotifierRegistered = FALSE;
195		return result;
196	}
197	else
198	{
199		BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered");
200		Adapter->bNetdeviceNotifierRegistered = TRUE;
201	}
202
203#else
204
205	strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name
206	rdmalt(Adapter,VEOSHM_OLD_SCHEME_START, &value, sizeof(value));
207
208	if((Adapter->CPUId == WP_CPU_ID) && (value != CPE_O_SCHEME_MAGIC_PATTERN))
209		reg_to_os = FALSE;
210
211#endif
212
213	if(reg_to_os == FALSE)
214	{
215		printk("Not registering to OS\n");
216		Adapter->if_up = 1;
217	}
218	else
219	{
220		result = register_netdev(Adapter->dev);
221		if (!result)
222		{
223			Adapter->bNetworkInterfaceRegistered = TRUE ;
224			BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name);
225		}
226		else
227		{
228	    	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!");
229			Adapter->bNetworkInterfaceRegistered = FALSE ;
230			return result;
231		}
232	}
233#if 0
234 Adapter->stDebugState.debug_level = DBG_LVL_CURR;
235 Adapter->stDebugState.type =(UINT)0xffffffff;
236 Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff;
237 Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff;
238 Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff;
239 Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff;
240
241 printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type);
242 printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]);
243 printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]);
244 printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]);
245#endif
246
247	return 0;
248}
249
250void bcm_unregister_networkdev(PMINI_ADAPTER Adapter)
251{
252	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n");
253	if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
254		unregister_netdev(Adapter->dev);
255		/* Unregister the notifier block */
256	if(Adapter->bNetdeviceNotifierRegistered == TRUE)
257	{
258	BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
259			unregister_netdevice_notifier(&bcm_notifier_block);
260  }
261}
262
263static int bcm_init(void)
264{
265	int result;
266   	result = InterfaceInitialize();
267	if(result)
268	{
269 		printk("Initialisation failed for usbbcm");
270	}
271	else
272	{
273		printk("Initialised usbbcm");
274	}
275	return result;
276}
277
278
279static void bcm_exit(void)
280{
281    printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
282	InterfaceExit();
283    printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
284}
285
286module_init(bcm_init);
287module_exit(bcm_exit);
288MODULE_LICENSE ("GPL");
289
290
291