1 /* 2 * WlanDrvWext.c 3 * 4 * Copyright(c) 1998 - 2009 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 /* 36 * src/wext.c 37 * 38 * Support for Linux Wireless Extensions 39 * 40 */ 41 #include <linux/types.h> 42 #include <linux/socket.h> 43 #include <linux/if.h> 44 #include <linux/wireless.h> 45 #include <net/iw_handler.h> 46 #include "WlanDrvIf.h" 47 #include "CmdHndlr.h" 48 #include "CmdInterpretWext.h" 49 #include "privateCmd.h" 50 #include "DrvMain.h" 51 52 /* Routine prototypes */ 53 54 int wlanDrvWext_Handler (struct net_device *dev, 55 struct iw_request_info *info, 56 void *iw_req, 57 void *extra); 58 59 static struct iw_statistics *wlanDrvWext_GetWirelessStats (struct net_device *dev); 60 61 extern int wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitInfo); 62 extern int wlanDrvIf_Start (struct net_device *dev); 63 extern int wlanDrvIf_Stop (struct net_device *dev); 64 65 66 /* callbacks for WEXT commands */ 67 static const iw_handler aWextHandlers[] = { 68 (iw_handler) NULL, /* SIOCSIWCOMMIT */ 69 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWNAME */ 70 (iw_handler) NULL, /* SIOCSIWNWID */ 71 (iw_handler) NULL, /* SIOCGIWNWID */ 72 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWFREQ */ 73 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWFREQ */ 74 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWMODE */ 75 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWMODE */ 76 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWSENS */ 77 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWSENS */ 78 (iw_handler) NULL, /* SIOCSIWRANGE - not used */ 79 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWRANGE */ 80 (iw_handler) NULL, /* SIOCSIWPRIV - not used */ 81 (iw_handler) NULL, /* SIOCGIWPRIV - kernel code */ 82 (iw_handler) NULL, /* SIOCSIWSTATS - not used */ 83 (iw_handler) NULL, /* SIOCGIWSTATS - kernel code */ 84 (iw_handler) NULL, /* SIOCSIWSPY */ 85 (iw_handler) NULL, /* SIOCGIWSPY */ 86 (iw_handler) NULL, /* SIOCSIWTHRSPY */ 87 (iw_handler) NULL, /* SIOCGIWTHRSPY */ 88 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWAP */ 89 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWAP */ 90 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWMLME */ 91 (iw_handler) NULL, /* SIOCGIWAPLIST */ 92 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWSCAN */ 93 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWSCAN */ 94 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWESSID */ 95 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWESSID */ 96 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWNICKN */ 97 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWNICKN */ 98 (iw_handler) NULL, /* -- hole -- */ 99 (iw_handler) NULL, /* -- hole -- */ 100 (iw_handler) NULL, /* SIOCSIWRATE */ 101 (iw_handler) NULL, /* SIOCGIWRATE */ 102 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWRTS */ 103 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWRTS */ 104 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWFRAG */ 105 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWFRAG */ 106 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWTXPOW */ 107 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWTXPOW */ 108 (iw_handler) NULL, /* SIOCSIWRETRY */ 109 (iw_handler) NULL, /* SIOCGIWRETRY */ 110 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWENCODE */ 111 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWENCODE */ 112 (iw_handler) NULL, /* SIOCSIWPOWER */ 113 (iw_handler) NULL, /* SIOCGIWPOWER */ 114 (iw_handler) NULL, /* -- hole -- */ 115 (iw_handler) NULL, /* -- hole -- */ 116 (iw_handler) NULL, /* SIOCSIWGENIE */ 117 (iw_handler) NULL, /* SIOCGIWGENIE */ 118 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWAUTH */ 119 (iw_handler) wlanDrvWext_Handler, /* SIOCGIWAUTH */ 120 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWENCODEEXT */ 121 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 122 (iw_handler) wlanDrvWext_Handler, /* SIOCSIWPMKSA */ 123 }; 124 125 /* callbacks for private commands */ 126 static const iw_handler aPrivateHandlers[] = { 127 (iw_handler) wlanDrvWext_Handler, /* SIOCIWFIRSTPRIV+0 (set) */ 128 (iw_handler) wlanDrvWext_Handler, /* SIOCIWFIRSTPRIV+1 (get) */ 129 }; 130 131 /* Describe the level of WEXT support to kernel */ 132 static struct iw_handler_def tWextIf = { 133 #define N(a) (sizeof (a) / sizeof (a[0])) 134 .standard = (iw_handler *) aWextHandlers, 135 .num_standard = N(aWextHandlers), 136 .private = (iw_handler *) aPrivateHandlers, 137 .num_private = N(aPrivateHandlers), 138 .private_args = NULL, 139 .num_private_args = 0, 140 .get_wireless_stats = wlanDrvWext_GetWirelessStats, 141 #undef N 142 }; 143 144 /* Initialite WEXT support - Register callbacks in kernel */ 145 void wlanDrvWext_Init (struct net_device *dev) 146 { 147 #ifdef HOST_PLATFORM_OMAP3430 148 dev->get_wireless_stats = wlanDrvWext_GetWirelessStats; 149 #endif 150 dev->wireless_handlers = &tWextIf; 151 152 } 153 154 /* Return driver statistics - currently not supported */ 155 static struct iw_statistics *wlanDrvWext_GetWirelessStats(struct net_device *dev) 156 { 157 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); 158 159 return (struct iw_statistics *) cmdHndlr_GetStat (drv->tCommon.hCmdHndlr); 160 } 161 162 /* Generic callback for WEXT commands */ 163 164 int wlanDrvWext_Handler (struct net_device *dev, 165 struct iw_request_info *info, 166 void *iw_req, 167 void *extra) 168 { 169 int rc; 170 TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); 171 ti_private_cmd_t my_command; 172 struct iw_mlme mlme; 173 void *copy_to_buf=NULL, *param3=NULL; 174 175 os_memoryZero(drv, &my_command, sizeof(ti_private_cmd_t)); 176 os_memoryZero(drv, &mlme, sizeof(struct iw_mlme)); 177 178 switch (info->cmd) 179 { 180 case SIOCIWFIRSTPRIV: 181 { 182 void *copy_from_buf; 183 184 if (os_memoryCopyFromUser(drv, &my_command, ((union iwreq_data *)iw_req)->data.pointer, sizeof(ti_private_cmd_t))) 185 { 186 os_printf ("wlanDrvWext_Handler() os_memoryCopyFromUser FAILED !!!\n"); 187 return TI_NOK; 188 } 189 if (IS_PARAM_FOR_MODULE(my_command.cmd, DRIVER_MODULE_PARAM)) 190 { 191 /* If it's a driver level command, handle it here and exit */ 192 switch (my_command.cmd) 193 { 194 case DRIVER_INIT_PARAM: 195 return wlanDrvIf_LoadFiles(drv, my_command.in_buffer); 196 197 case DRIVER_START_PARAM: 198 return wlanDrvIf_Start(dev); 199 200 case DRIVER_STOP_PARAM: 201 return wlanDrvIf_Stop(dev); 202 203 case DRIVER_STATUS_PARAM: 204 *(TI_UINT32 *)my_command.out_buffer = 205 (drv->tCommon.eDriverState == DRV_STATE_RUNNING) ? TI_TRUE : TI_FALSE; 206 return TI_OK; 207 } 208 } 209 /* if we are still here handle a normal private command*/ 210 211 if ((my_command.in_buffer) && (my_command.in_buffer_len)) 212 { 213 copy_from_buf = my_command.in_buffer; 214 my_command.in_buffer = os_memoryAlloc(drv, my_command.in_buffer_len); 215 if (os_memoryCopyFromUser(drv, my_command.in_buffer, copy_from_buf, my_command.in_buffer_len)) 216 { 217 os_printf("wlanDrvWext_Handler() os_memoryCopyFromUser 1 FAILED !!!\n"); 218 return TI_NOK; 219 } 220 } 221 if ((my_command.out_buffer) && (my_command.out_buffer_len)) 222 { 223 copy_to_buf = my_command.out_buffer; 224 my_command.out_buffer = os_memoryAlloc(drv, my_command.out_buffer_len); 225 } 226 param3 = &my_command; 227 } 228 break; 229 230 case SIOCSIWMLME: 231 { 232 os_memoryCopyFromUser(drv, &mlme, ((union iwreq_data *)iw_req)->data.pointer, sizeof(struct iw_mlme)); 233 param3 = &mlme; 234 } 235 break; 236 } 237 /* If the friver is not running, return NOK */ 238 if (drv->tCommon.eDriverState != DRV_STATE_RUNNING) 239 { 240 if (my_command.in_buffer) 241 os_memoryFree(drv, my_command.in_buffer, my_command.in_buffer_len); 242 if (my_command.out_buffer) 243 os_memoryFree(drv,my_command.out_buffer,my_command.out_buffer_len); 244 return TI_NOK; 245 } 246 247 /* Call the Cmd module with the given user paramters */ 248 rc = cmdHndlr_InsertCommand(drv->tCommon.hCmdHndlr, 249 info->cmd, 250 info->flags, 251 iw_req, 252 0, 253 extra, 254 0, 255 param3, 256 NULL); 257 /* Here we are after the command was completed */ 258 if (my_command.in_buffer) 259 { 260 os_memoryFree(drv, my_command.in_buffer, my_command.in_buffer_len); 261 } 262 if (my_command.out_buffer) 263 { 264 if (os_memoryCopyToUser(drv, copy_to_buf, my_command.out_buffer, my_command.out_buffer_len)) 265 { 266 os_printf("wlanDrvWext_Handler() os_memoryCopyToUser FAILED !!!\n"); 267 rc = TI_NOK; 268 } 269 os_memoryFree(drv, my_command.out_buffer, my_command.out_buffer_len); 270 } 271 return rc; 272 } 273