/drivers/net/wireless/tiwlan1251/pform/linux/src/ioctl_list.c
C | 263 lines | 179 code | 32 blank | 52 comment | 33 complexity | e2b0dec48d0ba0edbf2275dade66621e MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0, LGPL-2.0
- /****************************************************************************
- **+-----------------------------------------------------------------------+**
- **| |**
- **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
- **| All rights reserved. |**
- **| |**
- **| Redistribution and use in source and binary forms, with or without |**
- **| modification, are permitted provided that the following conditions |**
- **| are met: |**
- **| |**
- **| * Redistributions of source code must retain the above copyright |**
- **| notice, this list of conditions and the following disclaimer. |**
- **| * Redistributions in binary form must reproduce the above copyright |**
- **| notice, this list of conditions and the following disclaimer in |**
- **| the documentation and/or other materials provided with the |**
- **| distribution. |**
- **| * Neither the name Texas Instruments nor the names of its |**
- **| contributors may be used to endorse or promote products derived |**
- **| from this software without specific prior written permission. |**
- **| |**
- **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
- **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
- **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
- **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
- **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
- **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
- **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
- **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
- **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
- **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
- **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
- **| |**
- **+-----------------------------------------------------------------------+**
- ****************************************************************************/
- #include "arch_ti.h"
- #include <asm/uaccess.h> /* copy_to_user() */
- #include <linux/netdevice.h>
- #include <linux/ioctl.h>
- #include <linux/completion.h>
- #include <linux/vmalloc.h>
- #include "esta_drv.h"
- #include "tiwlan_profile.h"
- #include "ioctl_init.h"
- #include "ioctl_utils.h"
- #include "tiioctl.h"
- #include "ipc_k.h"
- void print_priv_ioctl_params(struct net_device *dev, tiioctl_req_t *req, char *extra)
- {
- print_deb(" priv_ioctl_params(*dev:%p,*req:%p, *extra:%p)\n", dev, req, extra);
- print_deb(" wrqu.point: user_data=%p, length=%ld, cmd=%ld\n", (void *) req->user_data_pointer,
- req->length, req->cmd );
- print_deb(" wrqu dump: ");
- print_memory_dump((char *) req, sizeof(*req) );
- print_deb("\n");
- if( extra )
- {
- print_deb(" extra (%p) :", extra );
- print_memory_dump(extra, req->length );
- print_deb("\n");
- }
- }
- /*sends complete to the user after to signal the completion of the asynchronous */
- /*operation (need to set *pIoCompleteFlag = FALSE, at osCmd.c).*/
- void os_IoctlComplete(PTIWLN_ADAPTER_T pAdapter, TI_STATUS ReturnStatus )
- {
- *pAdapter->pCompleteReply = (int)ReturnStatus;
- complete(pAdapter->IoctlComp);
- }
- NTSTATUS DispatchCommand(PTIWLN_ADAPTER_T pAdapter,ULONG ioControlCode,PULONG outBufLen,
- ULONG inBufLen,PVOID ioBuffer,PUINT8 pIoCompleteFlag);
- 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;
- }
- 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);
- }
- }
- #endif
- else
- {
- res = tiwlan_send_wait_reply((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev), ti1610_ioctl_priv_proc_tl,
- (unsigned long)req, (unsigned long)extra, 0, 0);
- }
- if( !res )
- {
- if( (req->cmd_type & IOCTL_GET) && kbuf /*req->length > aval_data_size*/ )
- {
- print_deb("ti1610_do_ioctl(): ...copy from %p to %p %ld bytes\n\n", extra, (void *) req->user_data_pointer, req->length );
- print_memory_dump(extra, min(32,(int) req->length) );
- if( copy_to_user( (void *) req->user_data_pointer, extra, req->length ) )
- return -EFAULT;
- }
- }
- print_deb("ti1610_do_ioctl() = %d (req = %p, user_data_pointer=0x%lx, extra=%p)\n\n", res, req, req->user_data_pointer, extra );
- if( kbuf ){
- os_memoryFree(NULL,kbuf,sizeof(kbuf));
- #ifdef TI_MEM_ALLOC_TRACE
- os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, kbuf, -req->length);
- #endif/*I_MEM_ALLOC_TRACE*/
- }
- return res;
- }
- int tiwlan_ioctl_init( struct net_device *dev )
- {
- #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
- dev->do_ioctl = ti1610_do_ioctl;
- #endif
- return 0;
- }