int ti1610_ioctl_priv_proc_tl(tiwlan_req_t *req_data)
{
    struct net_device *dev = req_data->drv->netdev;
    tiioctl_req_t *req = (tiioctl_req_t *) req_data->u.req.p1;
    static unsigned int drv_started = 0;
	static UINT8 IoCompleteFlag ;

    ULONG *data = (ULONG *) req_data->u.req.p2;

    int res = -EINVAL;

    print_deb("priv_ioctl_proc(): cmd=%ld, data=%p (user_data=%lx), lenght=%ld\n",
                req->cmd, data, req->user_data_pointer, req->length);
    if( !drv_started && (req->cmd != TIWLN_DRIVER_STATUS_SET)) { /* Dm: Fix */
            return res;
    }
					
    switch( req->cmd ) {
        case TIWLN_DRIVER_STATUS_SET:
            if(*data)
                res = tiwlan_start_drv( (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev) );
            else
                res = tiwlan_stop_drv( (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev) );

            if( res == OK )
                    drv_started = !drv_started;
            break;

        case TIWLN_SEND_EAPOL_PACKET:
            res = os_sendPacket(dev, data, req->length);
            break;
#ifdef TI_DBG
        case TIWLN_DRIVER_DEBUG_PRINT:
                res = util_hal_debug_print(dev, data);
                break;
#endif /* TI_DBG */
        default:
		{
            res = DispatchCommand(&req_data->drv->adapter, req->cmd, &req->length, req->length, data,&IoCompleteFlag );
			/* If we do not have to send complete to user back then set the Falg to FALSE 
			The Complete will be sent from another contect of command completion from FW */
			if(IoCompleteFlag == FALSE)
			{
			   req_data->u.req.reply_expected = FALSE;
			   /****** TO DO - This solution will have a problem in case of two async ioctrls (in case of two utility adapters). ******/
			   /* Store the semaphore for later competion */
			   (req_data->drv->adapter).IoctlComp = &(req_data->u.req.comp);
			   /* Store the pointer of the result status for later competion */
			   (req_data->drv->adapter).pCompleteReply = &(req_data->u.reply);
			}

		}
    }
    return res;
}
예제 #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);

    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;
}
예제 #3
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;
}
/** 
 * \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;
}
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;
}
예제 #6
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;
}
/** 
 * \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;
}
예제 #8
0
/** 
 * \fn     wlanDrvIf_Xmit
 * \brief  Packets transmission
 * 
 * The network stack calls this function in order to transmit a packet
 *     through the WLAN interface.
 * The packet is inserted to the drver Tx queues and its handling is continued
 *     after switching to the driver context.
 *
 * \note   
 * \param  skb - The Linux packet buffer structure
 * \param  dev - The driver network-interface handle
 * \return 0 (= OK)
 * \sa     
 */ 
static int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev)
{
 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

     if ( drv->tCommon.eDriverState != DRV_STATE_RUNNING )
	              return -ENODEV;


    return xmit_Bridge(skb, dev, NULL);
}
예제 #9
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;
}
예제 #10
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;
}
/** 
 * \fn     wlanDrvIf_Xmit
 * \brief  Packets transmission
 * 
 * The network stack calls this function in order to transmit a packet
 *     through the WLAN interface.
 * The packet is inserted to the drver Tx queues and its handling is continued
 *     after switching to the driver context.
 *
 * \note   
 * \param  skb - The Linux packet buffer structure
 * \param  dev - The driver network-interface handle
 * \return 0 (= OK)
 * \sa     
 */ 
static int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
	TTxCtrlBlk *  pPktCtrlBlk;
	int status;

	CL_TRACE_START_L1();

	os_profile (drv, 0, 0);
	drv->stats.tx_packets++;
	drv->stats.tx_bytes += skb->len;

	/* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
	pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);

	pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
	pPktCtrlBlk->tTxDescriptor.length       = skb->len;
	pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;

	/* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
	pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
	pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
	pPktCtrlBlk->tTxnStruct.aLen[2] = 0;

	/* Send the packet to the driver for transmission. */
	status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority);

	/* If failed (queue full or driver not running), drop the packet. */
    if (status != TI_OK)
    {
        drv->stats.tx_errors++;
    }
	os_profile (drv, 1, 0);

	CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");

	return 0;
}
예제 #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;
    }


    /* 
     *  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;
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
0
static int xmit_Bridge (struct sk_buff *skb, struct net_device *dev, TIntraBssBridge *pBssBridgeParam)
{
    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
    TTxCtrlBlk *  pPktCtrlBlk;
    TEthernetHeader *pEthHead = (TEthernetHeader *)(skb->data);
    int status;

    CL_TRACE_START_L1();

    os_profile (drv, 0, 0);
    drv->stats.tx_packets++;
    drv->stats.tx_bytes += skb->len;

    /* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
    pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);
    if (pPktCtrlBlk == NULL)
    {
        drv->stats.tx_errors++;
        os_profile (drv, 1, 0);
        CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");
        return 0;
    }

    /* Set interface type according to net device interface number */
    if (drv->tCommon.eIfRole == IF_ROLE_TYPE_AP) 
        SET_PKT_TYPE_IF_ROLE_AP(pPktCtrlBlk);
    else
        SET_PKT_TYPE_IF_ROLE_STA(pPktCtrlBlk);
    pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
    pPktCtrlBlk->tTxDescriptor.length       = skb->len;
    pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;

    /* Check MGMT packet from hostapd, forward it to the Mgmt-Queue and exit without ethernet header */
    if (HTOWLANS(pEthHead->type) == AP_MGMT_ETH_TYPE)
    {
        /* Copy WLAN header into aPktHdr - format for MGMT packets */
        memcpy (pPktCtrlBlk->aPktHdr, skb->data + ETHERNET_HDR_LEN , WLAN_HDR_LEN );

        /* Skip ethernet header, send as management frame */
        pPktCtrlBlk->tTxPktParams.uPktType = TX_PKT_TYPE_MGMT;
        pPktCtrlBlk->tTxnStruct.aBuf[0] = (TI_UINT8 *)pPktCtrlBlk->aPktHdr;
        pPktCtrlBlk->tTxnStruct.aLen[0] = WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN + WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN - WLAN_HDR_LEN;
        pPktCtrlBlk->tTxnStruct.aLen[2] = 0;
        pPktCtrlBlk->tTxPktParams.uInputPktLen = skb->len;
        pPktCtrlBlk->tTxDescriptor.length = (TI_UINT16)((pPktCtrlBlk->tTxnStruct.aLen[0]) + (pPktCtrlBlk->tTxnStruct.aLen[1]));

        status = txMgmtQ_Xmit (drv->tCommon.hTxMgmtQ, pPktCtrlBlk, TI_TRUE);
    }
    else

    {
    /* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
    pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
    pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
    pPktCtrlBlk->tTxnStruct.aLen[2] = 0;

    /* Send the packet to the driver for transmission. */
    status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority, pBssBridgeParam);
    }

    /* If failed (queue full or driver not running), drop the packet. */
    if (status != TI_OK)
    {
        drv->stats.tx_errors++;
    }
    os_profile (drv, 1, 0);

    CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");

    return 0;
}
예제 #16
0
/* Return driver statistics */
static struct iw_statistics *wlanDrvWext_GetWirelessStats(struct net_device *dev)
{
	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);

    return (struct iw_statistics *) cmdHndlr_GetStat (drv->tCommon.hCmdHndlr);
}
예제 #17
0
int wlanDrvWext_Handler (struct net_device *dev,
                     struct iw_request_info *info, 
                     void *iw_req, 
                     void *extra)
{
   int              rc;
   TWlanDrvIfObj   *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
   ti_private_cmd_t my_command; 
   struct iw_mlme   mlme;
   struct iw_scan_req scanreq;

   void             *copy_to_buf=NULL, *param3=NULL; 

   os_memoryZero(drv, &my_command, sizeof(ti_private_cmd_t));
   os_memoryZero(drv, &mlme,       sizeof(struct iw_mlme));
   os_memoryZero(drv, &scanreq, sizeof(struct iw_scan_req));
   
   switch (info->cmd)
   {
     case SIOCIWFIRSTPRIV:
     {
	   void *copy_from_buf;

 	   if (os_memoryCopyFromUser(drv, &my_command, ((union iwreq_data *)iw_req)->data.pointer, sizeof(ti_private_cmd_t)))
	   {
		 os_printf ("wlanDrvWext_Handler() os_memoryCopyFromUser FAILED !!!\n");
		 return TI_NOK;
	   }
	   if (IS_PARAM_FOR_MODULE(my_command.cmd, DRIVER_MODULE_PARAM))
       {
		   /* If it's a driver level command, handle it here and exit */
           switch (my_command.cmd)
           {
           case DRIVER_INIT_PARAM:
               return wlanDrvIf_LoadFiles (drv, my_command.in_buffer);
                
           case DRIVER_START_PARAM:
               return wlanDrvIf_Open (dev);

           case DRIVER_STOP_PARAM:
               return wlanDrvIf_Stop (dev);

           case DRIVER_STATUS_PARAM:
               *(TI_UINT32 *)my_command.out_buffer = 
                   (drv->tCommon.eDriverState == DRV_STATE_RUNNING) ? TI_TRUE : TI_FALSE;
               return TI_OK;
           }
       }
	   /* if we are still here handle a normal private command*/

	   if ((my_command.in_buffer) && (my_command.in_buffer_len))
       {
		 copy_from_buf        = my_command.in_buffer;
		 my_command.in_buffer = os_memoryAlloc(drv, my_command.in_buffer_len);
		 if (os_memoryCopyFromUser(drv, my_command.in_buffer, copy_from_buf, my_command.in_buffer_len))
		 {
		   os_printf ("wlanDrvWext_Handler() os_memoryCopyFromUser 1 FAILED !!!\n");
		   return TI_NOK;
		 }
	   }
	   if ((my_command.out_buffer) && (my_command.out_buffer_len))
	   {
		 copy_to_buf          = my_command.out_buffer;
		 my_command.out_buffer = os_memoryAlloc(drv, my_command.out_buffer_len);
	   }
	   param3 = &my_command;
     }
	 break;

     case SIOCSIWMLME:
     {
		os_memoryCopyFromUser(drv, &mlme, ((union iwreq_data *)iw_req)->data.pointer, sizeof(struct iw_mlme));
		param3 = &mlme;
     }
	 break;

	 case SIOCSIWSCAN:
	 {
		 if (((union iwreq_data *)iw_req)->data.pointer)
	     {
			 os_memoryCopyFromUser(drv, &scanreq, ((union iwreq_data *)iw_req)->data.pointer, sizeof(struct iw_scan_req));
			 param3 = &scanreq;
		 }
	 }
	 break; 

     case SIOCSIWGENIE:
     {
         TI_UINT16 ie_length = ((union iwreq_data *)iw_req)->data.length;
         TI_UINT8 *ie_content = ((union iwreq_data *)iw_req)->data.pointer;

         if ((ie_length == 0) && (ie_content == NULL)) {
                 /* Do nothing, deleting the IE */
         } else if ((ie_content != NULL) && (ie_length <= RSN_MAX_GENERIC_IE_LENGTH) && (ie_length > 0)) { 
                 /* One IE cannot be larger than RSN_MAX_GENERIC_IE_LENGTH bytes */
                 my_command.in_buffer = os_memoryAlloc(drv, ie_length);
                 os_memoryCopyFromUser(drv, my_command.in_buffer, ie_content, ie_length );
                 param3 = my_command.in_buffer;
         } else {
                 return TI_NOK;
         }
     }
	 break;
   }
   /* If the friver is not running, return NOK */
   if (drv->tCommon.eDriverState != DRV_STATE_RUNNING)
   {
       return TI_NOK;
   }

   /* Call the Cmd module with the given user paramters */
   rc = (cmdHndlr_InsertCommand (drv->tCommon.hCmdHndlr, 
                                   info->cmd, 
                                   info->flags, 
                                   iw_req, 
                                   0, 
                                   extra, 
                                   0, 
                                   param3, 
                                   NULL));
   /* Here we are after the command was completed */
   if (my_command.in_buffer)
   {
	 os_memoryFree (drv, my_command.in_buffer, my_command.in_buffer_len);
   }
   if (my_command.out_buffer)
   {
	 if (os_memoryCopyToUser(drv, copy_to_buf, my_command.out_buffer, my_command.out_buffer_len))
	 {
	   os_printf ("wlanDrvWext_Handler() os_memoryCopyToUser FAILED !!!\n");
	   rc = TI_NOK;
	 }
	 os_memoryFree (drv, my_command.out_buffer, my_command.out_buffer_len);
   }

   return rc;
}
int ti1610_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
    tiioctl_req_t *req = (tiioctl_req_t *) &rq->ifr_ifru;
    char *extra, *kbuf = NULL;
    int res, aval_data_size = ((char *) req + sizeof(*req)) - (char *)&req->user_data_pointer;      /* = ~4 bytes */
    /*int is_get_cmd = (req->cmd_type & IOCTL_GET);*/

    print_deb("ti1610_do_ioctl(cmd=%lu(%s%s)) - user_data_pointer=0x%lx, len = %lu, aval_data_size=%d\n",
                req->cmd,
                (req->cmd_type & IOCTL_GET) ? "GET" : "", (req->cmd_type & IOCTL_SET) ? "SET" : "",
                req->user_data_pointer, req->length, aval_data_size );

	/* driver is already initialized */
	if ((req->cmd == TIWLN_SET_INIT_INFO) && (((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev))->adapter.CoreHalCtx))
	{
		return 0;
	}

	if( req->length > aval_data_size )
    {
        if( req->user_data_pointer == 0 )
            return -EFAULT;

        print_deb("ti1610_do_ioctl() - alloc %ld bytes\n", req->length );
		kbuf = extra = os_memoryAlloc(NULL,req->length);
#ifdef TI_MEM_ALLOC_TRACE        
        os_printf("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, req->length, GFP_KERNEL, req->length);
#endif/*I_MEM_ALLOC_TRACE*/

        if( !extra )
            return -ENOBUFS;
        if( req->cmd_type & IOCTL_SET )
        {
            if( copy_from_user(extra, (void *) req->user_data_pointer, req->length) )
                return -EFAULT;
        }
        else {
            os_memoryZero( NULL, extra, req->length );
        }
    } else
            extra = (char *) &req->user_data_pointer;

    /* Driver initialization must be performed in process context.
       The rest is handled in the context of dedicated tasklet
    */
    if (req->cmd == TIWLN_SET_INIT_INFO)
    {
       tiwlan_dev_init_t *init_info = (tiwlan_dev_init_t *)extra;
       print_deb("TIWLN_SET_INIT_INFO: el=%d il=%d, fl=%d\n",
              init_info?init_info->eeprom_image_length:0,
              init_info?init_info->init_file_length:0,
              init_info?init_info->firmware_image_length:0 );
       res = tiwlan_init_drv((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev), init_info);
    }

#ifdef DRIVER_PROFILING
    else if (req->cmd == TIWLAN_PROFILING_REPORT) 
    {
       res = tiwlan_profile_report((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
    }
    else if (req->cmd == TIWLAN_PROFILING_CPU_ESTIMATOR_CMD) {
       /* get the command cpu estimator command parameter */
       unsigned int command_param = *((unsigned int *)extra);
       /* extract the command type which is the MSB byte of the command param*/
       unsigned int command_type = 0xFF & (command_param >> 24);
       /* extract the data of the command which are the 3 LSB bytes of the command param */
       unsigned int command_data = 0xFFFFFF & command_param;
       /* execute the command according to its type */
       switch (command_type) 
       {
       case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_START:
           res = tiwlan_profile_cpu_usage_estimator_start((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev),
                                                          /* the data in this case is the estimator
                                                          resolution in milliseconds */
                                                          command_data * 1000);
           break;
       case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_STOP:
           res = tiwlan_profile_cpu_usage_estimator_stop((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
           break;
       case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_RESET:
           res =tiwlan_profile_cpu_usage_estimator_reset((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
           break;
       default:
           res = 0;
           printk("\n\n%s: cpu usage estimator unknow command: param = %x\n\n\n",
                     __FUNCTION__, command_param);
       }
    }