blob: afdd147b3ad590680bad81ccc6cdb5d2b045a33f [file] [log] [blame]
/*
* WlanDrvWext.c
*
* Copyright(c) 1998 - 2009 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.
*/
/*
* src/wext.c
*
* Support for Linux Wireless Extensions
*
*/
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/if.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
#include "WlanDrvIf.h"
#include "CmdHndlr.h"
#include "CmdInterpretWext.h"
#include "privateCmd.h"
#include "DrvMain.h"
/* Routine prototypes */
int wlanDrvWext_Handler (struct net_device *dev,
struct iw_request_info *info,
void *iw_req,
void *extra);
static struct iw_statistics *wlanDrvWext_GetWirelessStats (struct net_device *dev);
extern int wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitInfo);
extern int wlanDrvIf_Start (struct net_device *dev);
extern int wlanDrvIf_Stop (struct net_device *dev);
/* callbacks for WEXT commands */
static const iw_handler aWextHandlers[] = {
(iw_handler) NULL, /* SIOCSIWCOMMIT */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWFREQ */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWFREQ */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWMODE */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWMODE */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWSENS */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWSENS */
(iw_handler) NULL, /* SIOCSIWRANGE - not used */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWRANGE */
(iw_handler) NULL, /* SIOCSIWPRIV - not used */
(iw_handler) NULL, /* SIOCGIWPRIV - kernel code */
(iw_handler) NULL, /* SIOCSIWSTATS - not used */
(iw_handler) NULL, /* SIOCGIWSTATS - kernel code */
(iw_handler) NULL, /* SIOCSIWSPY */
(iw_handler) NULL, /* SIOCGIWSPY */
(iw_handler) NULL, /* SIOCSIWTHRSPY */
(iw_handler) NULL, /* SIOCGIWTHRSPY */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWAP */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWAP */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWMLME */
(iw_handler) NULL, /* SIOCGIWAPLIST */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWSCAN */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWSCAN */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWESSID */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWESSID */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWNICKN */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWRATE */
(iw_handler) NULL, /* SIOCGIWRATE */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWRTS */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWRTS */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWFRAG */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWFRAG */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWTXPOW */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWTXPOW */
(iw_handler) NULL, /* SIOCSIWRETRY */
(iw_handler) NULL, /* SIOCGIWRETRY */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWENCODE */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWENCODE */
(iw_handler) NULL, /* SIOCSIWPOWER */
(iw_handler) NULL, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* SIOCSIWGENIE */
(iw_handler) NULL, /* SIOCGIWGENIE */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWAUTH */
(iw_handler) wlanDrvWext_Handler, /* SIOCGIWAUTH */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWENCODEEXT */
(iw_handler) NULL, /* SIOCGIWENCODEEXT */
(iw_handler) wlanDrvWext_Handler, /* SIOCSIWPMKSA */
};
/* callbacks for private commands */
static const iw_handler aPrivateHandlers[] = {
(iw_handler) wlanDrvWext_Handler, /* SIOCIWFIRSTPRIV+0 (set) */
(iw_handler) wlanDrvWext_Handler, /* SIOCIWFIRSTPRIV+1 (get) */
};
/* Describe the level of WEXT support to kernel */
static struct iw_handler_def tWextIf = {
#define N(a) (sizeof (a) / sizeof (a[0]))
.standard = (iw_handler *) aWextHandlers,
.num_standard = N(aWextHandlers),
.private = (iw_handler *) aPrivateHandlers,
.num_private = N(aPrivateHandlers),
.private_args = NULL,
.num_private_args = 0,
.get_wireless_stats = wlanDrvWext_GetWirelessStats,
#undef N
};
/* Initialite WEXT support - Register callbacks in kernel */
void wlanDrvWext_Init (struct net_device *dev)
{
#ifdef HOST_PLATFORM_OMAP3430
dev->get_wireless_stats = wlanDrvWext_GetWirelessStats;
#endif
dev->wireless_handlers = &tWextIf;
}
/* Return driver statistics - currently not supported */
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);
}
/* Generic callback for WEXT commands */
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;
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));
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_Start (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;
}
/* 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;
}