aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/Bcmnet.c
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-09-08 14:46:36 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2010-09-08 21:15:06 -0700
commitf8942e07a3db9d82e8fb11d3d494876b8bae9ff9 (patch)
tree2406636a4f9a4ac6b0bfc90e07aefa8b1b18b8ff /drivers/staging/bcm/Bcmnet.c
parentStaging: keucr: fix up some coding style issues in the .h files (diff)
downloadlinux-dev-f8942e07a3db9d82e8fb11d3d494876b8bae9ff9.tar.xz
linux-dev-f8942e07a3db9d82e8fb11d3d494876b8bae9ff9.zip
staging: Beeceem USB Wimax driver
The Sprint 4G network uses a Wimax dongle with Beecem chipset. The driver is typical of out of tree drivers, but maybe useful for people, and the hardware is readily available. Here is a staging ready version (i.e warts and all) 0. Started with Rel_5.2.7.3P1_USB from Sprint4GDeveloperPack-1.1 1. Consolidated files in staging 2. Remove Dos cr/lf 3. Remove unnecessary ioctl from usbbcm_fops Applied patches that were in the developer pack, surprising there were ones for 2.6.35 already. This is compile tested only, see TODO for what still needs to be done. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/bcm/Bcmnet.c')
-rw-r--r--drivers/staging/bcm/Bcmnet.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c
new file mode 100644
index 000000000000..d4f4800ca5dd
--- /dev/null
+++ b/drivers/staging/bcm/Bcmnet.c
@@ -0,0 +1,266 @@
+#include "headers.h"
+
+static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev)
+{
+ struct net_device *ndev = (struct net_device*)dev;
+ PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
+ //PMINI_ADAPTER Adapter = (PMINI_ADAPTER)ndev->priv;
+ if(strncmp(ndev->name,gblpnetdev->name,5)==0)
+ {
+ switch(event)
+ {
+ case NETDEV_CHANGEADDR:
+ case NETDEV_GOING_DOWN:
+ /*ignore this */
+ break;
+ case NETDEV_DOWN:
+ break;
+
+ case NETDEV_UP:
+ break;
+
+ case NETDEV_REGISTER:
+ /* Increment the Reference Count for "veth0" */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n",
+ atomic_read(&ndev->refcnt));
+ atomic_inc(&ndev->refcnt);
+ break;
+
+ case NETDEV_UNREGISTER:
+ /* Decrement the Reference Count for "veth0" */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n",
+ atomic_read(&ndev->refcnt));
+ atomic_dec(&ndev->refcnt);
+ if((int)atomic_read(&ndev->refcnt) < 0)
+ atomic_set(&ndev->refcnt, 0);
+ break;
+ };
+ }
+ return NOTIFY_DONE;
+}
+
+/* Notifier block to receive netdevice events */
+static struct notifier_block bcm_notifier_block =
+{
+ .notifier_call = bcm_notify_event,
+};
+
+struct net_device *gblpnetdev;
+/***************************************************************************************/
+/* proto-type of lower function */
+#ifdef BCM_SHM_INTERFACE
+const char *bcmVirtDeviceName="bcmeth";
+#endif
+
+static INT bcm_open(struct net_device *dev)
+{
+ PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv;
+ Adapter = GET_BCM_ADAPTER(dev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>");
+ if(Adapter->fw_download_done==FALSE)
+ return -EINVAL;
+ Adapter->if_up=1;
+ if(Adapter->LinkUpStatus == 1){
+ if(netif_queue_stopped(Adapter->dev)){
+ netif_carrier_on(Adapter->dev);
+ netif_start_queue(Adapter->dev);
+ }
+ }
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======");
+ return 0;
+}
+
+static INT bcm_close(struct net_device *dev)
+{
+ PMINI_ADAPTER Adapter = NULL ;//gpadapter ;
+ Adapter = GET_BCM_ADAPTER(dev);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>");
+ Adapter->if_up=0;
+ if(!netif_queue_stopped(dev)) {
+ netif_carrier_off(dev);
+ netif_stop_queue(dev);
+ }
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<=====");
+ return 0;
+}
+
+static struct net_device_stats *bcm_get_stats(struct net_device *dev)
+{
+ PLINUX_DEP_DATA pLinuxData=NULL;
+ PMINI_ADAPTER Adapter = NULL ;// gpadapter ;
+ Adapter = GET_BCM_ADAPTER(dev);
+ pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData);
+
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData);
+ pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs;
+ pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount);
+ pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount);
+ pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount);
+ pLinuxData->netstats.rx_length_errors=0;
+ pLinuxData->netstats.rx_frame_errors=0;
+ pLinuxData->netstats.rx_crc_errors=0;
+ pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount);
+ pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount);
+ pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount);
+
+ return &(pLinuxData->netstats);
+}
+/**
+@ingroup init_functions
+Register other driver entry points with the kernel
+*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+struct net_device_ops bcmNetDevOps = {
+ .ndo_open = bcm_open,
+ .ndo_stop = bcm_close,
+ .ndo_get_stats = bcm_get_stats,
+ .ndo_start_xmit = bcm_transmit,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
+};
+#endif
+
+int register_networkdev(PMINI_ADAPTER Adapter)
+{
+ int result=0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ int *temp = NULL ;
+#endif
+ Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER));
+ if(!Adapter->dev)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev");
+ return -ENOMEM;
+ }
+ gblpnetdev = Adapter->dev;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+ Adapter->dev->priv = Adapter;
+#else
+ temp = netdev_priv(Adapter->dev);
+ *temp = (UINT)Adapter;
+#endif
+ //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
+ Adapter->dev->netdev_ops = &bcmNetDevOps;
+#else
+ Adapter->dev->open = bcm_open;
+ Adapter->dev->stop = bcm_close;
+ Adapter->dev->get_stats = bcm_get_stats;
+ Adapter->dev->hard_start_xmit = bcm_transmit;
+ Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE;
+#endif
+
+#ifndef BCM_SHM_INTERFACE
+ Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */
+ /* Read the MAC Address from EEPROM */
+ ReadMacAddressFromNVM(Adapter);
+
+
+ /* Register the notifier block for getting netdevice events */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n");
+ result = register_netdevice_notifier(&bcm_notifier_block);
+ if(result)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered");
+ Adapter->bNetdeviceNotifierRegistered = FALSE;
+ return result;
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered");
+ Adapter->bNetdeviceNotifierRegistered = TRUE;
+ }
+
+#else
+
+ Adapter->dev->mtu = CPE_MTU_SIZE;
+
+#if 0
+ //for CPE - harcode the virtual mac address
+ Adapter->dev->dev_addr[0] = MII_WIMAX_MACADDRESS[0];
+ Adapter->dev->dev_addr[1] = MII_WIMAX_MACADDRESS[1];
+ Adapter->dev->dev_addr[2] = MII_WIMAX_MACADDRESS[2];
+ Adapter->dev->dev_addr[3] = MII_WIMAX_MACADDRESS[3];
+ Adapter->dev->dev_addr[4] = MII_WIMAX_MACADDRESS[4];
+ Adapter->dev->dev_addr[5] = MII_WIMAX_MACADDRESS[5];
+#else
+ ReadMacAddressFromNVM(Adapter);
+#endif
+ strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name
+
+#endif
+
+ result = register_netdev(Adapter->dev);
+ if (!result)
+ {
+ Adapter->bNetworkInterfaceRegistered = TRUE ;
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name);
+ }
+ else
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!");
+ Adapter->bNetworkInterfaceRegistered = FALSE ;
+ return result;
+ }
+
+#if 0
+ Adapter->stDebugState.debug_level = DBG_LVL_CURR;
+ Adapter->stDebugState.type =(UINT)0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff;
+ Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff;
+
+ printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]);
+ printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]);
+#endif
+
+ return 0;
+}
+
+void bcm_unregister_networkdev(PMINI_ADAPTER Adapter)
+{
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n");
+ if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered)
+ unregister_netdev(Adapter->dev);
+ /* Unregister the notifier block */
+ if(Adapter->bNetdeviceNotifierRegistered == TRUE)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n");
+ unregister_netdevice_notifier(&bcm_notifier_block);
+ }
+}
+
+static int bcm_init(void)
+{
+ int result;
+ result = InterfaceInitialize();
+ if(result)
+ {
+ printk("Initialisation failed for usbbcm");
+ }
+ else
+ {
+ printk("Initialised usbbcm");
+ }
+ return result;
+}
+
+
+static void bcm_exit(void)
+{
+ printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__);
+ InterfaceExit();
+ printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__);
+}
+
+module_init(bcm_init);
+module_exit(bcm_exit);
+MODULE_LICENSE ("GPL");
+
+