/** 
 * \fn     wlanDrvIf_Start
 * \brief  Start driver
 * 
 * Called by network stack upon opening network interface (ifconfig up).
 * Can also be called from user application or CLI for flight mode.
 * Start the driver initialization process up to OPERATIONAL state.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 if succeeded, error if driver not available
 * \sa     wlanDrvIf_Stop
 */ 
int wlanDrvIf_Start (struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Start()\n");
	printk("%s\n", __func__);
    if (!drv->tCommon.hDrvMain)
    {
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver not created!\n");
		return -ENODEV;
	}

	if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver failed!\n");
		return -ENODEV;
	}

	/*
	 *  Insert Start command in DrvMain action queue, request driver scheduling 
	 *      and wait for action completion (all init process).
	 */
	os_wake_lock_timeout_enable(drv);
    if (TI_OK != drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_START)) 
    {
        return -ENODEV;
    }

    return 0;
}
Esempio n. 2
0
/**
 * \fn     wlanDrvIf_Open
 * \brief  Start driver
 *
 * Called by network stack upon opening network interface (ifconfig up).
 * Can also be called from user application or CLI for flight mode.
 * Start the driver initialization process up to OPERATIONAL state.
 *
 * \note
 * \param  dev - The driver network-interface handle
 * \return 0 if succeeded, error if driver not available
 * \sa     wlanDrvIf_Release
 */
int wlanDrvIf_Open (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
    int status = 0;
    WLAN_OS_REPORT(("wlanDrvIf_Open()\n"));

    if (!drv->tCommon.hDrvMain)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Open() Driver not created!\n");
        return -ENODEV;
    }
    if (drv->tCommon.eDriverState == DRV_STATE_FAILED)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "Driver in FAILED state!\n");
        return -EPERM;
    }
    if (drv->tCommon.eDriverState != DRV_STATE_RUNNING)
    {
	status = wlanDrvIf_Start(dev);
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
	drv->netdev->hard_start_xmit = wlanDrvIf_Xmit;
#else
	drv->netdev->netdev_ops = &tiwlan_ops_pri;
#endif
	drv->netdev->addr_len = MAC_ADDR_LEN;
    netif_start_queue (dev);

    }
	return status;
}
Esempio n. 3
0
/** 
 * \fn     wlanDrvIf_Open
 * \brief  Start driver
 * 
 * Called by network stack upon opening network interface (ifconfig up).
 * Can also be called from user application or CLI for flight mode.
 * Start the driver initialization process up to OPERATIONAL state.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 if succeeded, error if driver not available
 * \sa     wlanDrvIf_Release
 */ 
int wlanDrvIf_Open (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Open()\n");

    if (!drv->tCommon.hDrvMain)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Open() Driver not created!\n");
        return -ENODEV;
    }
    if (drv->tCommon.eDriverState == DRV_STATE_FAILED) 
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "Driver in FAILED state!\n");
        return -EPERM;
    }
    if (drv->tCommon.eDriverState != DRV_STATE_RUNNING) 
	{
        wlanDrvIf_Start(dev);
    }

#ifndef AP_MODE_ENABLED 
	netif_start_queue (dev); /* Temporal, use wlanDrvIf_Enable/DisableTx in STA mode */
#endif

    /* register 3430 PM hooks in our SDIO driver */
#ifdef CONFIG_PM
    /*sdioDrv_register_pm(wlanDrvIf_pm_resume, wlanDrvIf_pm_suspend);*/
#endif

    return 0;
}
int wlanDrvIf_Open (struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
	int status = 0;

	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Open()\n");
	printk("%s\n", __func__);
	if (!drv->tCommon.hDrvMain) {
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Open() Driver not created!\n");
		return -ENODEV;
	}

	if (drv->tCommon.eDriverState == DRV_STATE_STOPPED ||
	    drv->tCommon.eDriverState == DRV_STATE_IDLE) {
		status = wlanDrvIf_Start(dev);
	}

	/*
	 *  Finalize network interface setup
	 */
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
	drv->netdev->hard_start_xmit = wlanDrvIf_Xmit;
#else
	drv->netdev->netdev_ops = &tiwlan_ops_pri;
#endif
	drv->netdev->addr_len = MAC_ADDR_LEN;
	netif_start_queue (dev);

	return status;
}
Esempio n. 5
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);

   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, 31))
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
	dev->validate_addr = NULL;
#endif
    /* 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 */
    dev->open = wlanDrvIf_Open;
    dev->stop = wlanDrvIf_Release;
   dev->hard_start_xmit = wlanDrvIf_Xmit;
    dev->get_stats = wlanDrvIf_NetGetStat;
    dev->do_ioctl = NULL;
#else
   dev->netdev_ops = &tiwlan_ops_pri;
#endif
	dev->tx_queue_len = 100;

    /* 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;
    }

   /* Setup power-management callbacks */
   hPlatform_SetupPm(SuspendCb, ResumeCb, pDrvStaticHandle);

    /*
    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;
}
/** 
 * \fn     wlanDrvIf_Stop
 * \brief  Stop driver
 * 
 * Called by network stack upon closing network interface (ifconfig down).
 * Can also be called from user application or CLI for flight mode.
 * Stop the driver and turn off the device.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 (OK)
 * \sa     wlanDrvIf_Start
 */ 
int wlanDrvIf_Stop (struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Stop()\n");

	if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
	{
		return -ENODEV;
	}

	/* 
	 *  Insert Stop command in DrvMain action queue, request driver scheduling 
	 *      and wait for Stop process completion.
	 */
	os_printf("%s LINE %d\n", __func__, __LINE__);
	os_wake_lock_timeout_enable(drv);
	os_printf("%s LINE %d\n", __func__, __LINE__);
    if (TI_OK != drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_STOP)) 
    {
        return -ENODEV;
    }
	os_printf("%s\n", __func__);
	return 0;
}
Esempio n. 7
0
/** 
 * \fn     wlanDrvIf_NetGetStat
 * \brief  Provides driver statistics
 * 
 * Provides driver Tx and Rx statistics to network stack.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return The statistics pointer 
 * \sa     
 */ 
static struct net_device_stats *wlanDrvIf_NetGetStat (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_NetGetStat()\n");
    
    return &drv->stats;
}
TI_INT32 IPC_EventSend(TI_HANDLE hAdapter, TI_UINT8* pEvData, TI_UINT32 EvDataSize)
{
	 struct sk_buff *skb;
     int res;
     TWlanDrvIfObj *drv = (TWlanDrvIfObj *) hAdapter;
     TI_UINT32 realSize = 0;
     TI_UINT32 msgSize;
	 struct nlmsghdr *nlh;
     TI_UINT8 *msg;

     os_wake_lock_timeout_enable(drv);
     /* This event is targetted to the OS process Id 0 is not a valid pId for LINUX*/

     if ((( IPC_EVENT_PARAMS *) pEvData) ->uProcessID == 0) 
     {
         (( IPC_EVENT_PARAMS *) pEvData) ->pfEventCallback(( IPC_EV_DATA *) pEvData);
         return 0;
     }

     /* set the payload size */
	 msgSize = (( IPC_EV_DATA *) pEvData) ->uBufferSize + offsetof(IPC_EV_DATA,uBuffer);
     
	 /* add the netlink header size */
	 realSize = NLMSG_SPACE(msgSize);

	 /* allocate the complete message */
	 skb = dev_alloc_skb(realSize);
	 if (!skb) {
		printk(KERN_ERR "Failed to allocate new skb with size=%u.\n",realSize);
		return -1;
	 }

	 /* set the netlink header params */
	 nlh = NLMSG_PUT(skb, 0, 0, NLMSG_DONE, realSize - sizeof(*nlh));
	 
	 /* get the payload pointer */
	 msg = (char *)NLMSG_DATA(nlh);
	 
	 /* copy the data to the payload */ 
     memcpy(msg,pEvData,msgSize);

	 NETLINK_CB(skb).pid = 0;   /* from kernel */
#define RTMGRP_LINK 1
     NETLINK_CB(skb).dst_group = RTMGRP_LINK;

	 /* send the message*/
	 res = netlink_unicast(drv->wl_sock, skb, (( IPC_EVENT_PARAMS *) pEvData) ->uProcessID, MSG_DONTWAIT);

     /* Sanity checks. As far as we're concerned this error is unrecovarable.*/
     if (res >= 0)
     {
		return 0;
     }

nlmsg_failure:
    ti_dprintf(TIWLAN_LOG_INFO,"IPC kernel: did not send the netlink message\n");
	return -1;

}
Esempio n. 9
0
int wlanDrvIf_Release (struct net_device *dev)
{
	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Release()\n");

	/* Disable network interface queue */
	netif_stop_queue (dev);
	return 0;
}
Esempio n. 10
0
/** 
 * \fn     wlanDrvIf_Release
 * \brief  Stop driver
 * 
 * Called by network stack upon closing network interface (ifconfig down).
 * Can also be called from user application or CLI for flight mode.
 * Stop the driver and turn off the device.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 (OK)
 * \sa     wlanDrvIf_Open
 */ 
int wlanDrvIf_Release (struct net_device *dev)
{
    /* TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); */

    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Release()\n");

    /* Disable network interface queue */
    netif_stop_queue (dev);
    return 0;
}
Esempio n. 11
0
/** 
 * \fn     wlanDrvIf_Start
 * \brief  Start driver
 * 
 * Called by network stack upon opening network interface (ifconfig up).
 * Can also be called from user application or CLI for flight mode.
 * Start the driver initialization process up to OPERATIONAL state.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 if succeeded, error if driver not available
 * \sa     wlanDrvIf_Stop
 */ 
int wlanDrvIf_Start (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Start()\n");

    if (!drv->tCommon.hDrvMain)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver not created!\n");
        return -ENODEV;
    }


    /* 
     *  Insert Start command in DrvMain action queue, request driver scheduling 
     *      and wait for action completion (all init process).
     */
    drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_START);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
     /* 
     *  Finalize network interface setup
     */
  
  netif_start_queue (dev);
#ifdef AP_MODE_ENABLED
    netif_carrier_on (dev);
#endif


    /* register 3430 PM hooks in our SDIO driver */
#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

#endif
    return 0;
}
Esempio n. 12
0
/**
 * \fn     wlanDrvIf_Start
 * \brief  Start driver
 *
 * Called by network stack upon opening network interface (ifconfig up).
 * Can also be called from user application or CLI for flight mode.
 * Start the driver initialization process up to OPERATIONAL state.
 *
 * \note
 * \param  dev - The driver network-interface handle
 * \return 0 if succeeded, error if driver not available
 * \sa     wlanDrvIf_Stop
 */
int wlanDrvIf_Start (struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Start()\n");

	if (!drv->tCommon.hDrvMain)
	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver not created!\n");
		return -ENODEV;
	}


	/*before inserting an action - check driver state*/
	if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
	{
		return -ENODEV;
	}

	os_wake_lock_timeout_enable(drv);
	drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_START);

	return 0;
}
Esempio n. 13
0
/**
 * \fn     wlanDrvIf_UpdateDriverState
 * \brief  Update the driver state
 *
 * The DrvMain uses this function to update the OAL with the driver steady state
 *     that is relevant for the driver users.
 *
 * \note
 * \param  hOs          - The driver object handle
 * \param  eDriverState - The new driver state
 * \return void
 * \sa
 */
void wlanDrvIf_UpdateDriverState (TI_HANDLE hOs, EDriverSteadyState eDriverState)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;

	ti_dprintf(TIWLAN_LOG_OTHER, "wlanDrvIf_UpdateDriverState(): State = %d\n", eDriverState);

	/* Save the new state */
	drv->tCommon.eDriverState = eDriverState;

	/* If the new state is not RUNNING, replace the Tx handler to a dummy one. */
	if (eDriverState != DRV_STATE_RUNNING)
	{
		drv->netdev->hard_start_xmit = wlanDrvIf_XmitDummy;
	}
}
Esempio n. 14
0
/** 
 * \fn     wlanDrvIf_Stop
 * \brief  Stop driver
 * 
 * Called by network stack upon closing network interface (ifconfig down).
 * Can also be called from user application or CLI for flight mode.
 * Stop the driver and turn off the device.
 *
 * \note   
 * \param  dev - The driver network-interface handle
 * \return 0 (OK)
 * \sa     wlanDrvIf_Start
 */ 
int wlanDrvIf_Stop (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Stop()\n");

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
    /* Disable network interface queue */
    netif_stop_queue (dev);
#endif
    /* 
     *  Insert Stop command in DrvMain action queue, request driver scheduling 
     *      and wait for Stop process completion.
     */
    drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_STOP);
    return 0;
}
/** 
 * \fn     wlanDrvIf_UpdateDriverState
 * \brief  Update the driver state
 * 
 * The DrvMain uses this function to update the OAL with the driver steady state
 *     that is relevant for the driver users.
 * 
 * \note   
 * \param  hOs          - The driver object handle
 * \param  eDriverState - The new driver state
 * \return void
 * \sa     
 */ 
void wlanDrvIf_UpdateDriverState (TI_HANDLE hOs, EDriverSteadyState eDriverState)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;

	ti_dprintf(TIWLAN_LOG_OTHER, "wlanDrvIf_UpdateDriverState(): State = %d\n", eDriverState);

	/* Save the new state */
	drv->tCommon.eDriverState = eDriverState;

	/* If the new state is not RUNNING, replace the Tx handler to a dummy one. */
	if (eDriverState != DRV_STATE_RUNNING) {
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
		drv->netdev->hard_start_xmit = wlanDrvIf_XmitDummy;
#else
		drv->netdev->netdev_ops = &tiwlan_ops_dummy;
#endif
	}
}
Esempio n. 16
0
int wlanDrvIf_Open (struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
	WLAN_OS_REPORT(("wlanDrvIf_Open()\n"));
	if (!drv->tCommon.hDrvMain)
	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Open() Driver not created!\n");
		return -ENODEV;
	}

	wlanDrvIf_Start(dev);
	/*
	 *  Finalize network interface setup
	 */
	drv->netdev->hard_start_xmit = wlanDrvIf_Xmit;
	drv->netdev->addr_len = MAC_ADDR_LEN;
	netif_start_queue (dev);

	return 0;
}
Esempio n. 17
0
/**
 * \fn     wlanDrvIf_Stop
 * \brief  Stop driver
 *
 * Called by network stack upon closing network interface (ifconfig down).
 * Can also be called from user application or CLI for flight mode.
 * Stop the driver and turn off the device.
 *
 * \note
 * \param  dev - The driver network-interface handle
 * \return 0 (OK)
 * \sa     wlanDrvIf_Start
 */
int wlanDrvIf_Stop (struct net_device *dev)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

    ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Stop()\n");

    /* Disable network interface queue */
    netif_stop_queue (dev);

    /*before inserting an action - check driver state*/
    if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
    {
        return -ENODEV;
    }
    /*
     *  Insert Stop command in DrvMain action queue, request driver scheduling
     *      and wait for Stop process completion.
     */
    if (TI_OK != drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_STOP)) 
    {
        return -ENODEV;
    }
    return 0;
}
Esempio n. 18
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));
/*
#if defined HOST_PLATFORM_OMAP3430 || defined HOST_PLATFORM_ZOOM2 || defined HOST_PLATFORM_ZOOM1

	if(g_external_board)
	{
		WLAN_OS_REPORT(("\nZoom2 use external board"));
		drv->irq = (OMAP_GPIO_IRQ(IRQ_GPIO_EXT));
	}
	else
	{
		drv->irq = (OMAP_GPIO_IRQ(IRQ_GPIO));
	}
#endif   
*/
    drv->irq = tiwlan_ext_int_init(); 

    drv->tCommon.eDriverState = DRV_STATE_IDLE;
#ifdef AP_MODE_ENABLED
    /* for STA role, need to allocate another driver and to set STA role */
    drv->tCommon.eIfRole = IF_ROLE_TYPE_AP;
#endif

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

#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;
    }
#ifdef  HOST_PLATFORM_OMAP2430
    set_irq_type (drv->irq, IRQT_FALLING);
#endif
#endif  /* PRIODIC_INTERRUPT */

   return 0;
}
Esempio n. 19
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;
}
Esempio n. 20
0
/** 
 * \fn     wlanDrvIf_GetFile
 * \brief  Provides access to a requested init file
 * 
 * Provide the requested file information and call the requester callback.
 * Note that in Linux the files were previously loaded to driver memory 
 *     by the loader (see wlanDrvIf_LoadFiles).
 *
 * \note   
 * \param  hOs       - The driver object handle
 * \param  pFileInfo - The requested file's properties
 * \return TI_OK
 * \sa     wlanDrvIf_LoadFiles
 */ 
int wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;

    if (drv == NULL || pFileInfo == NULL) {
        ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: Null File Handler, Exiting");
        return TI_NOK;
    }

    /* Future option for getting the FW image part by part */ 
    pFileInfo->hOsFileDesc = NULL;

    /* Fill the file's location and size in the file's info structure */
    switch (pFileInfo->eFileType) 
    {
    case FILE_TYPE_INI: 
        pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tIniFile.pImage; 
        pFileInfo->uLength = drv->tCommon.tIniFile.uSize; 
        break;
    case FILE_TYPE_NVS:     
        pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tNvsImage.pImage; 
        pFileInfo->uLength = drv->tCommon.tNvsImage.uSize; 
        break;
    case FILE_TYPE_FW:
        pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tFwImage.pImage; 
        pFileInfo->bLast        = TI_FALSE;
        pFileInfo->uLength  = 0;
        pFileInfo->uOffset              = 0;
        pFileInfo->uChunkBytesLeft      = 0;
        pFileInfo->uChunksLeft          = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
        /* check uChunksLeft's Validity */
        if (( pFileInfo->uChunksLeft == 0 ) || ( pFileInfo->uChunksLeft > MAX_CHUNKS_IN_FILE ))
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() Read Invalid Chunks Left: %d!\n",pFileInfo->uChunksLeft);
            return TI_NOK;
        }
        pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
        /* FALL THROUGH */
    case FILE_TYPE_FW_NEXT:
        /* check dec. validity */
        if ( pFileInfo->uChunkBytesLeft >= pFileInfo->uLength )
        {
            pFileInfo->uChunkBytesLeft      -= pFileInfo->uLength;
        }
        /* invalid Dec. */
        else
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() No. of Bytes Left < File Length\n");
            return TI_NOK;
        }
        pFileInfo->pBuffer  += pFileInfo->uLength; 

        /* Finished reading all Previous Chunk */
        if ( pFileInfo->uChunkBytesLeft == 0 )
        {
            /* check dec. validity */
            if ( pFileInfo->uChunksLeft > 0 )
            {
                pFileInfo->uChunksLeft--;
            }
            /* invalid Dec. */
            else
            {
                ti_dprintf (TIWLAN_LOG_ERROR, "No. of Bytes Left = 0 and Chunks Left <= 0\n");
                return TI_NOK;
            }
            /* read Chunk's address */
            pFileInfo->uAddress = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
            pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
            /* read Portion's length */
            pFileInfo->uChunkBytesLeft = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
            pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
        }
        /* Reading Chunk is NOT complete */
        else
        {
            pFileInfo->uAddress += pFileInfo->uLength;
        }
        
        if ( pFileInfo->uChunkBytesLeft < OS_SPECIFIC_RAM_ALLOC_LIMIT )
        {
            pFileInfo->uLength = pFileInfo->uChunkBytesLeft;
        }
        else
        {
            pFileInfo->uLength = OS_SPECIFIC_RAM_ALLOC_LIMIT;
        }

        /* If last chunk to download */
        if (( pFileInfo->uChunksLeft == 0 ) && 
            ( pFileInfo->uLength == pFileInfo->uChunkBytesLeft ))
        {
            pFileInfo->bLast = TI_TRUE;
        }

        break;
    }

    /* Call the requester callback */
    if (pFileInfo->fCbFunc)
    {
        pFileInfo->fCbFunc (pFileInfo->hCbHndl);
    }

    return TI_OK;
}
Esempio n. 21
0
/** 
 * \fn     wlanDrvIf_LoadFiles
 * \brief  Load init files from loader
 * 
 * This function is called from the loader context right after the driver
 *     is created (in IDLE state).
 * It copies the following files to the driver's memory:
 *     - Ini-File - The driver's default parameters values
 *     - NVS-File - The NVS data for FW usage
 *     - FW-Image - The FW program image
 *
 * \note   
 * \param  drv - The driver object handle
 * \return void
 * \sa     wlanDrvIf_GetFile
 */ 
int wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitFiles)
{
    if (!pInitFiles)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No Init Files!\n");
        return -EINVAL;
    }

    if (drv->tCommon.eDriverState != DRV_STATE_IDLE)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "Trying to load files not in IDLE state!\n");
        return -EINVAL;
    }

    if (pInitFiles->uIniFileLength) 
    {
        drv->tCommon.tIniFile.uSize = pInitFiles->uIniFileLength;
        drv->tCommon.tIniFile.pImage = kmalloc (pInitFiles->uIniFileLength, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, pInitFiles->uIniFileLength, GFP_KERNEL, pInitFiles->uIniFileLength);
        #endif
        if (!drv->tCommon.tIniFile.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for Ini-File!\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tIniFile.pImage,
                &pInitFiles->data[pInitFiles->uNvsFileLength + pInitFiles->uFwFileLength],
                drv->tCommon.tIniFile.uSize);
    }

    if (pInitFiles->uNvsFileLength)
    {
        drv->tCommon.tNvsImage.uSize = pInitFiles->uNvsFileLength;
        drv->tCommon.tNvsImage.pImage = kmalloc (drv->tCommon.tNvsImage.uSize, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
              __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, GFP_KERNEL, drv->tCommon.tNvsImage.uSize);
        #endif
        if (!drv->tCommon.tNvsImage.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for NVS image\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tNvsImage.pImage, &pInitFiles->data[0], drv->tCommon.tNvsImage.uSize );
    }
    
    drv->tCommon.tFwImage.uSize = pInitFiles->uFwFileLength;
    if (!drv->tCommon.tFwImage.uSize)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n");
        return -EINVAL;
    }
    drv->tCommon.tFwImage.pImage = os_memoryAlloc (drv, drv->tCommon.tFwImage.uSize);
    #ifdef TI_MEM_ALLOC_TRACE        
      os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
          __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, GFP_KERNEL, drv->tCommon.tFwImage.uSize);
    #endif
    if (!drv->tCommon.tFwImage.pImage)
    {
        ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n");
        return -ENOMEM;
    }
    memcpy (drv->tCommon.tFwImage.pImage,
            &pInitFiles->data[pInitFiles->uNvsFileLength],
            drv->tCommon.tFwImage.uSize);

    ti_dprintf(TIWLAN_LOG_OTHER, "--------- Eeeprom=%p(%lu), Firmware=%p(%lu), IniFile=%p(%lu)\n", 
        drv->tCommon.tNvsImage.pImage, drv->tCommon.tNvsImage.uSize, 
        drv->tCommon.tFwImage.pImage,  drv->tCommon.tFwImage.uSize,
        drv->tCommon.tIniFile.pImage,  drv->tCommon.tIniFile.uSize);
    
    return 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; /* Dm: Failure is not cleaned properly !!! */
	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));

	/* Dm:    drv->irq = TNETW_IRQ; */
	drv->tCommon.eDriverState = DRV_STATE_IDLE;

	drv->tiwlan_wq = create_freezeable_workqueue(DRIVERWQ_NAME);
	if (!drv->tiwlan_wq) {
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to create workQ!\n");
		rc = -EINVAL;
		goto drv_create_end_1;
	}
	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)	{
		goto drv_create_end_2;
	}

	/* 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");
		rc = -EINVAL;
		goto drv_create_end_3;
	}

	/* Create all driver modules and link their handles */
	rc = 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);
	if (rc != TI_OK) {
		ti_dprintf (TIWLAN_LOG_ERROR, "%s: Failed to dvrMain_Create!\n", __func__);
		rc = -EINVAL;
		goto drv_create_end_4;
	}
	/*
	 *  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 1 //wait to debug
	if (rc)	{
		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to register interrupt handler!\n");
		goto drv_create_end_5;
	}
#endif
#endif  /* PRIODIC_INTERRUPT */
	return 0;
#if 1 //wait to debug
drv_create_end_5:
	/* Destroy all driver modules */
	if (drv->tCommon.hDrvMain) {
		drvMain_Destroy (drv->tCommon.hDrvMain);
	}
#endif
drv_create_end_4:
	if (drv->wl_sock) {
		sock_release (drv->wl_sock->sk_socket);
	}

drv_create_end_3:
	/* Release the driver network interface */
	if (drv->netdev) {
		unregister_netdev (drv->netdev);
		free_netdev (drv->netdev);
	}

drv_create_end_2:
#ifdef CONFIG_HAS_WAKELOCK
	wake_lock_destroy(&drv->wl_wifi);
	wake_lock_destroy(&drv->wl_rxwake);
#endif
	if (drv->tiwlan_wq)
		destroy_workqueue(drv->tiwlan_wq);

drv_create_end_1:
	kfree(drv);
	printk("%s: Fail\n", __func__);
	return rc;
}
Esempio n. 23
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;
}
static void wlanDrvIf_DriverTask (void *hDrv)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hDrv;
#else
static void wlanDrvIf_DriverTask(struct work_struct *work)
{
#ifdef STACK_PROFILE
	register unsigned long sp asm ("sp");
	unsigned long local_sp = sp;
#endif
	TWlanDrvIfObj *drv = container_of(work, TWlanDrvIfObj, tWork);
#endif

#ifdef STACK_PROFILE
	unsigned long curr1, base1;
	unsigned long curr2, base2;
	static unsigned long maximum_stack = 0;
#endif   
	os_profile (drv, 0, 0);

#ifdef STACK_PROFILE
	curr1 = check_stack_start(&base1, local_sp + 4, 0);
#endif

	/* Call the driver main task */
	context_DriverTask (drv->tCommon.hContext);

	os_profile (drv, 1, 0);
	os_wake_lock_timeout(drv);
	os_wake_unlock(drv);
#ifdef STACK_PROFILE
	curr2 = check_stack_stop(&base2, 0);
	if (base2 == base1) {
	/* if the current measurement is bigger then the maximum store it and print*/
		if ((curr1 - curr2) > maximum_stack) {
			printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n");
			printk("current operation stack use=%lu \n",(curr1 - curr2));
			printk("total stack use=%lu \n",8192 - curr2 + base2);
			printk("total stack usage=%lu percent \n",100 * (8192 - curr2 + base2) / 8192);
			maximum_stack = curr1 - curr2;
		}
	}
#endif
}


/** 
 * \fn     wlanDrvIf_LoadFiles
 * \brief  Load init files from loader
 * 
 * This function is called from the loader context right after the driver
 *     is created (in IDLE state).
 * It copies the following files to the driver's memory:
 *     - Ini-File - The driver's default parameters values
 *     - NVS-File - The NVS data for FW usage
 *     - FW-Image - The FW program image
 *
 * \note   
 * \param  drv - The driver object handle
 * \return void
 * \sa     wlanDrvIf_GetFile
 */ 
int wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitFiles)
{
    if (!pInitFiles)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No Init Files!\n");
        return -EINVAL;
    }

    if (drv->tCommon.eDriverState != DRV_STATE_IDLE)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "Trying to load files not in IDLE state!\n");
        return -EINVAL;
    }

    if (pInitFiles->uIniFileLength) 
    {
        drv->tCommon.tIniFile.uSize = pInitFiles->uIniFileLength;
        drv->tCommon.tIniFile.pImage = kmalloc (pInitFiles->uIniFileLength, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, pInitFiles->uIniFileLength, GFP_KERNEL, pInitFiles->uIniFileLength);
        #endif
        if (!drv->tCommon.tIniFile.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for Ini-File!\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tIniFile.pImage,
                &pInitFiles->data[pInitFiles->uNvsFileLength + pInitFiles->uFwFileLength],
                drv->tCommon.tIniFile.uSize);
    }

    if (pInitFiles->uNvsFileLength)
    {
        drv->tCommon.tNvsImage.uSize = pInitFiles->uNvsFileLength;
        drv->tCommon.tNvsImage.pImage = kmalloc (drv->tCommon.tNvsImage.uSize, GFP_KERNEL);
        #ifdef TI_MEM_ALLOC_TRACE        
          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
              __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, GFP_KERNEL, drv->tCommon.tNvsImage.uSize);
        #endif
        if (!drv->tCommon.tNvsImage.pImage)
        {
            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for NVS image\n");
            return -ENOMEM;
        }
        memcpy (drv->tCommon.tNvsImage.pImage, &pInitFiles->data[0], drv->tCommon.tNvsImage.uSize );
    }
    
    drv->tCommon.tFwImage.uSize = pInitFiles->uFwFileLength;
    if (!drv->tCommon.tFwImage.uSize)
    {
        ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n");
        return -EINVAL;
    }
    drv->tCommon.tFwImage.pImage = os_memoryAlloc (drv, drv->tCommon.tFwImage.uSize);
    #ifdef TI_MEM_ALLOC_TRACE        
      os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", 
          __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, GFP_KERNEL, drv->tCommon.tFwImage.uSize);
    #endif
    if (!drv->tCommon.tFwImage.pImage)
    {
        ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n");
        return -ENOMEM;
    }
    memcpy (drv->tCommon.tFwImage.pImage,
            &pInitFiles->data[pInitFiles->uNvsFileLength],
            drv->tCommon.tFwImage.uSize);

    ti_dprintf(TIWLAN_LOG_OTHER, "--------- Eeeprom=%p(%lu), Firmware=%p(%lu), IniFile=%p(%lu)\n", 
        drv->tCommon.tNvsImage.pImage, drv->tCommon.tNvsImage.uSize, 
        drv->tCommon.tFwImage.pImage,  drv->tCommon.tFwImage.uSize,
        drv->tCommon.tIniFile.pImage,  drv->tCommon.tIniFile.uSize);
    
    return 0;
}


/** 
 * \fn     wlanDrvIf_GetFile
 * \brief  Provides access to a requested init file
 * 
 * Provide the requested file information and call the requester callback.
 * Note that in Linux the files were previously loaded to driver memory 
 *     by the loader (see wlanDrvIf_LoadFiles).
 *
 * \note   
 * \param  hOs       - The driver object handle
 * \param  pFileInfo - The requested file's properties
 * \return TI_OK
 * \sa     wlanDrvIf_LoadFiles
 */ 
int wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;

	if (drv == NULL || pFileInfo == NULL) {
		ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: Null File Handler, Exiting");
		return TI_NOK;
	}

	/* Future option for getting the FW image part by part */ 
	pFileInfo->hOsFileDesc = NULL;

	/* Fill the file's location and size in the file's info structure */
	switch (pFileInfo->eFileType) 
	{
	case FILE_TYPE_INI: 
		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tIniFile.pImage; 
		pFileInfo->uLength = drv->tCommon.tIniFile.uSize; 
		break;
	case FILE_TYPE_NVS:     
		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tNvsImage.pImage; 
		pFileInfo->uLength = drv->tCommon.tNvsImage.uSize; 
		break;
	case FILE_TYPE_FW:
		if (drv->tCommon.tFwImage.pImage == NULL)
		{
			ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: no Firmware image, exiting\n");
			return TI_NOK;
		}

		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tFwImage.pImage; 
		pFileInfo->bLast		= TI_FALSE;
		pFileInfo->uLength	= 0;
		pFileInfo->uOffset 				= 0;
		pFileInfo->uChunkBytesLeft 		= 0;
		pFileInfo->uChunksLeft 			= BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
		/* check uChunksLeft's Validity */
		if (( pFileInfo->uChunksLeft == 0 ) || ( pFileInfo->uChunksLeft > MAX_CHUNKS_IN_FILE ))
		{
			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() Read Invalid Chunks Left: %d!\n",pFileInfo->uChunksLeft);
			return TI_NOK;
		}
		pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
		/* FALL THROUGH */
	case FILE_TYPE_FW_NEXT:
		/* check dec. validity */
		if ( pFileInfo->uChunkBytesLeft >= pFileInfo->uLength )
		{
			pFileInfo->uChunkBytesLeft 		-= pFileInfo->uLength;
		}
		/* invalid Dec. */
		else
		{
			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() No. of Bytes Left < File Length\n");
			return TI_NOK;
		}
		pFileInfo->pBuffer 	+= pFileInfo->uLength; 

		/* Finished reading all Previous Chunk */
		if ( pFileInfo->uChunkBytesLeft == 0 )
		{
			/* check dec. validity */
			if ( pFileInfo->uChunksLeft > 0 )
			{
				pFileInfo->uChunksLeft--;
			}
			/* invalid Dec. */
			else
			{
				ti_dprintf (TIWLAN_LOG_ERROR, "No. of Bytes Left = 0 and Chunks Left <= 0\n");
				return TI_NOK;
			}
			/* read Chunk's address */
			pFileInfo->uAddress = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
			/* read Portion's length */
			pFileInfo->uChunkBytesLeft = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
		}
		/* Reading Chunk is NOT complete */
		else
		{
			pFileInfo->uAddress += pFileInfo->uLength;
		}
		
		if ( pFileInfo->uChunkBytesLeft < OS_SPECIFIC_RAM_ALLOC_LIMIT )
		{
			pFileInfo->uLength = pFileInfo->uChunkBytesLeft;
		}
		else
		{
			pFileInfo->uLength = OS_SPECIFIC_RAM_ALLOC_LIMIT;
		}

		/* If last chunk to download */
		if (( pFileInfo->uChunksLeft == 0 ) && 
			( pFileInfo->uLength == pFileInfo->uChunkBytesLeft ))
		{
			pFileInfo->bLast = TI_TRUE;
		}

		break;
	}

	/* Call the requester callback */
	if (pFileInfo->fCbFunc)
	{
		pFileInfo->fCbFunc (pFileInfo->hCbHndl);
	}

	return TI_OK;
}