Beispiel #1
0
/**
 * \fn     wlanDrvIf_Destroy
 * \brief  Destroy the driver instance
 *
 * Destroy all driver modules.
 * Release driver OS resources (IRQ, workqueue, events socket)
 * Release driver network interface.
 * Free init files memory.
 * Free driver object.
 *
 * \note
 * \param  drv - The driver object handle
 * \return void
 * \sa     wlanDrvIf_Create
 */
static void wlanDrvIf_Destroy (TWlanDrvIfObj *drv)
{
	if (!drv)
		return;

	/* Release the driver network interface */
	if (drv->netdev)
	{
		netif_stop_queue  (drv->netdev);
		if (drv->tCommon.eDriverState != DRV_STATE_IDLE)
		{
			wlanDrvIf_Stop    (drv->netdev);
		}
		unregister_netdev (drv->netdev);
		free_netdev (drv->netdev);
	}

	destroy_workqueue (drv->pWorkQueue);

	/* Destroy all driver modules */
	if (drv->tCommon.hDrvMain)
	{
		drvMain_Destroy (drv->tCommon.hDrvMain);
	}

	/* close the ipc_kernel socket*/
	if (drv && drv->wl_sock)
	{
		sock_release (drv->wl_sock->sk_socket);
	}

	/* Release the driver interrupt (or polling timer) */
#ifdef PRIODIC_INTERRUPT
	os_timerDestroy (drv, drv->hPollTimer);
#else
	if (drv->irq)
	{
		hPlatform_freeInterrupt (drv);
	}
#endif

#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&drv->wl_wifi);
	wake_lock_destroy(&drv->wl_rxwake);
#endif

	/*
	 *  Free init files memory
	 */
	if (drv->tCommon.tFwImage.pImage)
	{
		os_memoryFree (drv, drv->tCommon.tFwImage.pImage, drv->tCommon.tFwImage.uSize);
#ifdef TI_MEM_ALLOC_TRACE
		os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
		           __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, -drv->tCommon.tFwImage.uSize);
#endif
	}
	if (drv->tCommon.tNvsImage.pImage)
	{
		kfree (drv->tCommon.tNvsImage.pImage);
#ifdef TI_MEM_ALLOC_TRACE
		os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
		           __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, -drv->tCommon.tNvsImage.uSize);
#endif
	}
	if (drv->tCommon.tIniFile.pImage)
	{
		kfree (drv->tCommon.tIniFile.pImage);
#ifdef TI_MEM_ALLOC_TRACE
		os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
		           __FUNCTION__, __LINE__, drv->tCommon.tIniFile.uSize, -drv->tCommon.tIniFile.uSize);
#endif
	}

	/* Free the driver object */
#ifdef TI_DBG
	tb_destroy();
#endif
	kfree (drv);

#ifdef CONFIG_PM
	/* unregister PM hooks from SDIO driver */
	sdioDrv_register_pm(NULL, NULL);
#endif
}
Beispiel #2
0
/** 
 * \fn     wlanDrvIf_SetupNetif
 * \brief  Setup driver network interface
 * 
 * Called in driver creation process.
 * Setup driver network interface.
 *
 * \note   
 * \param  drv - The driver object handle
 * \return 0 - OK, else - failure
 * \sa     
 */ 
static int wlanDrvIf_SetupNetif (TWlanDrvIfObj *drv)
{
   struct net_device *dev;
   int res;

   /* Allocate network interface structure for the driver */
   dev = alloc_etherdev (0);
   if (dev == NULL)
   {
      ti_dprintf (TIWLAN_LOG_ERROR, "alloc_etherdev() failed\n");
      return -ENOMEM;
   }

   /* Setup the network interface */
   ether_setup (dev);

/* the following is required on at least BSP 23.8 and higher.
    Without it, the Open function of the driver will not be called
    when trying to 'ifconfig up' the interface */
//#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
//   dev->validate_addr   = NULL;
//#endif

   NETDEV_SET_PRIVATE(dev,drv);
   drv->netdev = dev;
   strcpy (dev->name, TIWLAN_DRV_IF_NAME);
   netif_carrier_off (dev);
/*
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
   dev->open = wlanDrvIf_Start;
   dev->stop = wlanDrvIf_Stop;
#else
   dev->open = wlanDrvIf_Open;
   dev->stop = wlanDrvIf_Release;
#endif
*/
   /*dev->hard_start_xmit = wlanDrvIf_XmitDummy;*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)  
   dev->netdev_ops = &tiwlan_netdev_ops;
#else
   dev->open = wlanDrvIf_Start;
   dev->stop = wlanDrvIf_Stop;
   dev->hard_start_xmit = wlanDrvIf_Xmit;
   dev->addr_len = MAC_ADDR_LEN;
   dev->get_stats = wlanDrvIf_NetGetStat;
   dev->tx_queue_len = 100;
   dev->do_ioctl = NULL;
#endif

   /* Initialize Wireless Extensions interface (WEXT) */
   wlanDrvWext_Init (dev);

   res = register_netdev (dev);
   if (res != 0)
   {
      ti_dprintf (TIWLAN_LOG_ERROR, "register_netdev() failed : %d\n", res);
      kfree (dev);
      return res;
   }
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
#if defined HOST_PLATFORM_OMAP3430 || defined HOST_PLATFORM_ZOOM2 || defined HOST_PLATFORM_ZOOM1 || defined HOST_PLATFORM_MX25
   sdioDrv_register_pm(wlanDrvIf_pm_resume, wlanDrvIf_pm_suspend);
#endif
#else
#ifdef CONFIG_PM
   sdioDrv_register_pm(wlanDrvIf_pm_resume, wlanDrvIf_pm_suspend);
#endif
#endif
/*
On the latest Kernel there is no more support for the below macro.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
   SET_MODULE_OWNER (dev);
#endif
   return 0;
}
Beispiel #3
0
/**
 * \fn     wlanDrvIf_Create
 * \brief  Create the driver instance
 *
 * Allocate driver object.
 * Initialize driver OS resources (IRQ, workqueue, events socket)
 * Setup driver network interface.
 * Create and link all driver modules.
 *
 * \note
 * \param  void
 * \return 0 - OK, else - failure
 * \sa     wlanDrvIf_Destroy
 */
static int wlanDrvIf_Create (void)
{
	TWlanDrvIfObj *drv;
	int rc;

	/* Allocate driver's structure */
	drv = kmalloc (sizeof(TWlanDrvIfObj), GFP_KERNEL);
	if (!drv)
	{
		return -ENOMEM;
	}
#ifdef TI_DBG
	tb_init(TB_OPTION_NONE);
#endif
	pDrvStaticHandle = drv;  /* save for module destroy */
#ifdef TI_MEM_ALLOC_TRACE
	os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(TWlanDrvIfObj), GFP_KERNEL, sizeof(TWlanDrvIfObj));
#endif
	memset (drv, 0, sizeof(TWlanDrvIfObj));

	drv->tCommon.eDriverState = DRV_STATE_IDLE;

	drv->pWorkQueue = create_singlethread_workqueue(TIWLAN_WQ_NAME);
	if (!drv->pWorkQueue)
	{
		return -ENOMEM;
	}

	drv->wl_packet = 0;
	drv->wl_count = 0;
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_init(&drv->wl_wifi, WAKE_LOCK_SUSPEND, "wifi_wake");
	wake_lock_init(&drv->wl_rxwake, WAKE_LOCK_SUSPEND, "wifi_rx_wake");
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask, (void *)drv);
#else
	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask);
#endif
	spin_lock_init (&drv->lock);

	/* Setup driver network interface. */
	rc = wlanDrvIf_SetupNetif (drv);
	if (rc)
	{
		kfree (drv);
		return rc;
	}


	/* Create the events socket interface */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
	drv->wl_sock = netlink_kernel_create( NETLINK_USERSOCK, 0, NULL, THIS_MODULE );
#else
	drv->wl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE );
#endif
	if (drv->wl_sock == NULL)
	{
		ti_dprintf (TIWLAN_LOG_ERROR, "netlink_kernel_create() failed !\n");
		return -EINVAL;
	}

	/* Create all driver modules and link their handles */
	drvMain_Create (drv,
	                &drv->tCommon.hDrvMain,
	                &drv->tCommon.hCmdHndlr,
	                &drv->tCommon.hContext,
	                &drv->tCommon.hTxDataQ,
	                &drv->tCommon.hTxMgmtQ,
	                &drv->tCommon.hTxCtrl,
	                &drv->tCommon.hTWD,
	                &drv->tCommon.hEvHandler,
	                &drv->tCommon.hCmdDispatch,
	                &drv->tCommon.hReport);

	/*
	 *  Initialize interrupts (or polling mode for debug):
	 */
#ifdef PRIODIC_INTERRUPT
	/* Debug mode: Polling (the timer is started by HwInit process) */
	drv->hPollTimer = os_timerCreate ((TI_HANDLE)drv, wlanDrvIf_PollIrqHandler, (TI_HANDLE)drv);
#else
	/* Normal mode: Interrupts (the default mode) */
	rc = hPlatform_initInterrupt (drv, (void*)wlanDrvIf_HandleInterrupt);
	if (rc)
	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to register interrupt handler!\n");
		return rc;
	}
#endif  /* PRIODIC_INTERRUPT */

#ifdef CONFIG_PM
	/* register PM hooks in our SDIO driver */
	sdioDrv_register_pm(wlanDrvIf_Resume, wlanDrvIf_Suspend);
#endif


	return 0;
}