PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/pform/linux/src/ioctl_list.c

http://github.com/CyanogenMod/cm-kernel
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
  1. /****************************************************************************
  2. **+-----------------------------------------------------------------------+**
  3. **| |**
  4. **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
  5. **| All rights reserved. |**
  6. **| |**
  7. **| Redistribution and use in source and binary forms, with or without |**
  8. **| modification, are permitted provided that the following conditions |**
  9. **| are met: |**
  10. **| |**
  11. **| * Redistributions of source code must retain the above copyright |**
  12. **| notice, this list of conditions and the following disclaimer. |**
  13. **| * Redistributions in binary form must reproduce the above copyright |**
  14. **| notice, this list of conditions and the following disclaimer in |**
  15. **| the documentation and/or other materials provided with the |**
  16. **| distribution. |**
  17. **| * Neither the name Texas Instruments nor the names of its |**
  18. **| contributors may be used to endorse or promote products derived |**
  19. **| from this software without specific prior written permission. |**
  20. **| |**
  21. **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
  22. **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
  23. **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
  24. **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
  25. **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
  26. **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
  27. **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
  28. **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
  29. **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
  30. **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
  31. **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
  32. **| |**
  33. **+-----------------------------------------------------------------------+**
  34. ****************************************************************************/
  35. #include "arch_ti.h"
  36. #include <asm/uaccess.h> /* copy_to_user() */
  37. #include <linux/netdevice.h>
  38. #include <linux/ioctl.h>
  39. #include <linux/completion.h>
  40. #include <linux/vmalloc.h>
  41. #include "esta_drv.h"
  42. #include "tiwlan_profile.h"
  43. #include "ioctl_init.h"
  44. #include "ioctl_utils.h"
  45. #include "tiioctl.h"
  46. #include "ipc_k.h"
  47. void print_priv_ioctl_params(struct net_device *dev, tiioctl_req_t *req, char *extra)
  48. {
  49. print_deb(" priv_ioctl_params(*dev:%p,*req:%p, *extra:%p)\n", dev, req, extra);
  50. print_deb(" wrqu.point: user_data=%p, length=%ld, cmd=%ld\n", (void *) req->user_data_pointer,
  51. req->length, req->cmd );
  52. print_deb(" wrqu dump: ");
  53. print_memory_dump((char *) req, sizeof(*req) );
  54. print_deb("\n");
  55. if( extra )
  56. {
  57. print_deb(" extra (%p) :", extra );
  58. print_memory_dump(extra, req->length );
  59. print_deb("\n");
  60. }
  61. }
  62. /*sends complete to the user after to signal the completion of the asynchronous */
  63. /*operation (need to set *pIoCompleteFlag = FALSE, at osCmd.c).*/
  64. void os_IoctlComplete(PTIWLN_ADAPTER_T pAdapter, TI_STATUS ReturnStatus )
  65. {
  66. *pAdapter->pCompleteReply = (int)ReturnStatus;
  67. complete(pAdapter->IoctlComp);
  68. }
  69. NTSTATUS DispatchCommand(PTIWLN_ADAPTER_T pAdapter,ULONG ioControlCode,PULONG outBufLen,
  70. ULONG inBufLen,PVOID ioBuffer,PUINT8 pIoCompleteFlag);
  71. int ti1610_ioctl_priv_proc_tl(tiwlan_req_t *req_data)
  72. {
  73. struct net_device *dev = req_data->drv->netdev;
  74. tiioctl_req_t *req = (tiioctl_req_t *) req_data->u.req.p1;
  75. static unsigned int drv_started = 0;
  76. static UINT8 IoCompleteFlag ;
  77. ULONG *data = (ULONG *) req_data->u.req.p2;
  78. int res = -EINVAL;
  79. print_deb("priv_ioctl_proc(): cmd=%ld, data=%p (user_data=%lx), lenght=%ld\n",
  80. req->cmd, data, req->user_data_pointer, req->length);
  81. if( !drv_started && (req->cmd != TIWLN_DRIVER_STATUS_SET)) { /* Dm: Fix */
  82. return res;
  83. }
  84. switch( req->cmd ) {
  85. case TIWLN_DRIVER_STATUS_SET:
  86. if(*data)
  87. res = tiwlan_start_drv( (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev) );
  88. else
  89. res = tiwlan_stop_drv( (tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev) );
  90. if( res == OK )
  91. drv_started = !drv_started;
  92. break;
  93. case TIWLN_SEND_EAPOL_PACKET:
  94. res = os_sendPacket(dev, data, req->length);
  95. break;
  96. #ifdef TI_DBG
  97. case TIWLN_DRIVER_DEBUG_PRINT:
  98. res = util_hal_debug_print(dev, data);
  99. break;
  100. #endif /* TI_DBG */
  101. default:
  102. {
  103. res = DispatchCommand(&req_data->drv->adapter, req->cmd, &req->length, req->length, data,&IoCompleteFlag );
  104. /* If we do not have to send complete to user back then set the Falg to FALSE
  105. The Complete will be sent from another contect of command completion from FW */
  106. if(IoCompleteFlag == FALSE)
  107. {
  108. req_data->u.req.reply_expected = FALSE;
  109. /****** TO DO - This solution will have a problem in case of two async ioctrls (in case of two utility adapters). ******/
  110. /* Store the semaphore for later competion */
  111. (req_data->drv->adapter).IoctlComp = &(req_data->u.req.comp);
  112. /* Store the pointer of the result status for later competion */
  113. (req_data->drv->adapter).pCompleteReply = &(req_data->u.reply);
  114. }
  115. }
  116. }
  117. return res;
  118. }
  119. int ti1610_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  120. {
  121. tiioctl_req_t *req = (tiioctl_req_t *) &rq->ifr_ifru;
  122. char *extra, *kbuf = NULL;
  123. int res, aval_data_size = ((char *) req + sizeof(*req)) - (char *)&req->user_data_pointer; /* = ~4 bytes */
  124. /*int is_get_cmd = (req->cmd_type & IOCTL_GET);*/
  125. print_deb("ti1610_do_ioctl(cmd=%lu(%s%s)) - user_data_pointer=0x%lx, len = %lu, aval_data_size=%d\n",
  126. req->cmd,
  127. (req->cmd_type & IOCTL_GET) ? "GET" : "", (req->cmd_type & IOCTL_SET) ? "SET" : "",
  128. req->user_data_pointer, req->length, aval_data_size );
  129. /* driver is already initialized */
  130. if ((req->cmd == TIWLN_SET_INIT_INFO) && (((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev))->adapter.CoreHalCtx))
  131. {
  132. return 0;
  133. }
  134. if( req->length > aval_data_size )
  135. {
  136. if( req->user_data_pointer == 0 )
  137. return -EFAULT;
  138. print_deb("ti1610_do_ioctl() - alloc %ld bytes\n", req->length );
  139. kbuf = extra = os_memoryAlloc(NULL,req->length);
  140. #ifdef TI_MEM_ALLOC_TRACE
  141. os_printf("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, req->length, GFP_KERNEL, req->length);
  142. #endif/*I_MEM_ALLOC_TRACE*/
  143. if( !extra )
  144. return -ENOBUFS;
  145. if( req->cmd_type & IOCTL_SET )
  146. {
  147. if( copy_from_user(extra, (void *) req->user_data_pointer, req->length) )
  148. return -EFAULT;
  149. }
  150. else {
  151. os_memoryZero( NULL, extra, req->length );
  152. }
  153. } else
  154. extra = (char *) &req->user_data_pointer;
  155. /* Driver initialization must be performed in process context.
  156. The rest is handled in the context of dedicated tasklet
  157. */
  158. if (req->cmd == TIWLN_SET_INIT_INFO)
  159. {
  160. tiwlan_dev_init_t *init_info = (tiwlan_dev_init_t *)extra;
  161. print_deb("TIWLN_SET_INIT_INFO: el=%d il=%d, fl=%d\n",
  162. init_info?init_info->eeprom_image_length:0,
  163. init_info?init_info->init_file_length:0,
  164. init_info?init_info->firmware_image_length:0 );
  165. res = tiwlan_init_drv((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev), init_info);
  166. }
  167. #ifdef DRIVER_PROFILING
  168. else if (req->cmd == TIWLAN_PROFILING_REPORT)
  169. {
  170. res = tiwlan_profile_report((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
  171. }
  172. else if (req->cmd == TIWLAN_PROFILING_CPU_ESTIMATOR_CMD) {
  173. /* get the command cpu estimator command parameter */
  174. unsigned int command_param = *((unsigned int *)extra);
  175. /* extract the command type which is the MSB byte of the command param*/
  176. unsigned int command_type = 0xFF & (command_param >> 24);
  177. /* extract the data of the command which are the 3 LSB bytes of the command param */
  178. unsigned int command_data = 0xFFFFFF & command_param;
  179. /* execute the command according to its type */
  180. switch (command_type)
  181. {
  182. case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_START:
  183. res = tiwlan_profile_cpu_usage_estimator_start((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev),
  184. /* the data in this case is the estimator
  185. resolution in milliseconds */
  186. command_data * 1000);
  187. break;
  188. case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_STOP:
  189. res = tiwlan_profile_cpu_usage_estimator_stop((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
  190. break;
  191. case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_RESET:
  192. res =tiwlan_profile_cpu_usage_estimator_reset((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev));
  193. break;
  194. default:
  195. res = 0;
  196. printk("\n\n%s: cpu usage estimator unknow command: param = %x\n\n\n",
  197. __FUNCTION__, command_param);
  198. }
  199. }
  200. #endif
  201. else
  202. {
  203. res = tiwlan_send_wait_reply((tiwlan_net_dev_t *)NETDEV_GET_PRIVATE(dev), ti1610_ioctl_priv_proc_tl,
  204. (unsigned long)req, (unsigned long)extra, 0, 0);
  205. }
  206. if( !res )
  207. {
  208. if( (req->cmd_type & IOCTL_GET) && kbuf /*req->length > aval_data_size*/ )
  209. {
  210. print_deb("ti1610_do_ioctl(): ...copy from %p to %p %ld bytes\n\n", extra, (void *) req->user_data_pointer, req->length );
  211. print_memory_dump(extra, min(32,(int) req->length) );
  212. if( copy_to_user( (void *) req->user_data_pointer, extra, req->length ) )
  213. return -EFAULT;
  214. }
  215. }
  216. print_deb("ti1610_do_ioctl() = %d (req = %p, user_data_pointer=0x%lx, extra=%p)\n\n", res, req, req->user_data_pointer, extra );
  217. if( kbuf ){
  218. os_memoryFree(NULL,kbuf,sizeof(kbuf));
  219. #ifdef TI_MEM_ALLOC_TRACE
  220. os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, kbuf, -req->length);
  221. #endif/*I_MEM_ALLOC_TRACE*/
  222. }
  223. return res;
  224. }
  225. int tiwlan_ioctl_init( struct net_device *dev )
  226. {
  227. #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
  228. dev->do_ioctl = ti1610_do_ioctl;
  229. #endif
  230. return 0;
  231. }