blob: 033556ddacb1a50da9c0059f0272f3d378551455 [file] [log] [blame]
/*
Copyright 2004, 2005 Jean-Baptiste Note
Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
Copyright (c) 2006 Red Hat, Inc.
This file is part of prism54usb.
prism54usb is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
prism54usb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with prism54usb; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/wireless.h>
#include <linux/netdevice.h> /* needed by iw_handler */
#include <linux/if_arp.h>
#include <net/iw_handler.h>
#include "islsm_ioctl.h"
#include "isl_sm.h"
#include "islsm_log.h"
#ifdef MADWIFI
#include "linux/version.h"
#include "net80211/ieee80211_linux.h"
#else
#include <linux/etherdevice.h>
#include <net/ieee80211softmac_wx.h>
#endif /* MADWIFI */
/*
* private ioctl to allow experimentation
*/
#ifndef MADWIFI
#define MAX_PKT_LEN 200
static int
islsm_ioctl_sendannouncedpkt(struct net_device *netdev,
struct iw_request_info *unused, union iwreq_data *u, char *extra)
{
struct islsm *islsm = ISLSM_OF_NETDEV(netdev);
char *data;
size_t pktsize;
int err = 0;
FN_ENTER;
if (u == 0) {
err = -ENOTSUPP;
goto exit;
}
pktsize = u->data.length;
if (pktsize > MAX_PKT_LEN) {
err = -ENOTSUPP;
goto exit;
}
data = u->data.pointer;
/* note : this does not work with second-generation devices */
islsm_outofband_msg(islsm, data, pktsize);
exit:
FN_EXIT1(err);
return err;
}
#endif /* MADWIFI */
/* add ioctls to change the verbosity of the driver */
#define SUPPORTED_WIRELESS_EXT 16
#ifdef CONFIG_WLAN_80211
#ifndef MADWIFI
/**** WARNING *****/
/* _ALL_ of these calls are bogus except for set_channel_freq */
/* I expect to complete statistics soon enough */
struct iw_statistics *islsm_wireless_stats(struct net_device *ndev)
{
struct islsm *priv = ISLSM_OF_NETDEV(ndev);
/* completely bogus */
return &priv->iwstatistics;
}
static int
prism54_commit(struct net_device *ndev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
return 0;
}
static int
prism54_get_name(struct net_device *ndev, struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
char *capabilities;
capabilities = "IEEE 802.11b"; /* Default. Add 'a' later. */
strncpy(data->name, capabilities, IFNAMSIZ);
return 0;
}
static int
prism54_set_freq(struct net_device *netdev, struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
struct iw_freq *fwrq = &data->freq;
struct islsm *islsm = ISLSM_OF_NETDEV(netdev);
unsigned int c;
if (fwrq->m < 1000 && fwrq->m >= 1 && fwrq->m <= ISLSM_NR_CHANNELS) {
/* we have a valid channel number */
c = fwrq->m;
} else {
if (fwrq->m <= 0)
return -EINVAL;
c = islsm_freq_to_chan(fwrq->m);
if (c == 0 || c > ISLSM_NR_CHANNELS)
return -EINVAL;
}
/* XXX Semaphore here */
islsm_freq_change(islsm,
c, islsm_chan_to_freq(c),
ISLSM_TX_CONTROL_CHANNEL_MAGIC1_SCAN,
ISLSM_TX_CONTROL_CHANNEL_MAGIC2_SCAN);
islsm->last_chan = c;
return 0;
}
static int prism54_get_freq(struct net_device *netdev,
struct iw_request_info *info, union iwreq_data *data, char *extra)
{
struct iw_freq *fwrq = &data->freq;
struct islsm *islsm = ISLSM_OF_NETDEV(netdev);
memset(fwrq, 0, sizeof(struct iw_freq));
fwrq->m = islsm->last_chan;
fwrq->e = 0;
fwrq->flags = 1; /* It was a fixed setting */
return 0;
}
static int
prism54_set_mode(struct net_device *ndev, struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
struct islsm *islsm = ISLSM_OF_NETDEV(ndev);
int mode = data->mode;
int err = 0;
/* XXX Locking */
switch (mode) {
case IW_MODE_MONITOR:
islsm->ieee->iw_mode = mode;
ndev->type = ARPHRD_IEEE80211;
break;
case IW_MODE_ADHOC:
case IW_MODE_INFRA:
/* case IW_MODE_MASTER: */ /* XXX support AP mode */
islsm->ieee->iw_mode = mode;
ndev->type = ARPHRD_ETHER;
break;
default:
return -EINVAL;
}
if (ndev->flags & IFF_RUNNING) {
err = islsm_mode_set_filter(ndev, mode);
if (err)
printk(KERN_WARNING "error setting filter : %i", err);
}
return 0;
}
static int
prism54_get_mode(struct net_device *ndev, struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
struct islsm *islsm = ISLSM_OF_NETDEV(ndev);
unsigned long flags;
spin_lock_irqsave(&islsm->ieee->lock, flags);
data->mode = islsm->ieee->iw_mode;
spin_unlock_irqrestore(&islsm->ieee->lock, flags);
return 0;
}
/* we use DOT11_OID_EDTHRESHOLD. From what I guess the card will not try to
* emit data if (sensitivity > rssi - noise) (in dBm).
* prism54_set_sens does not seem to work.
*/
static int
prism54_set_sens(struct net_device *ndev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
/* islpci_private *priv = ISLSM_OF_NETDEV(ndev); */
/* u32 sens; */
/* /\* by default the card sets this to 20. *\/ */
/* sens = vwrq->disabled ? 20 : vwrq->value; */
/* return mgt_set_request(priv, DOT11_OID_EDTHRESHOLD, 0, &sens); */
return 0;
}
static int
prism54_get_sens(struct net_device *ndev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra)
{
/* islpci_private *priv = ISLSM_OF_NETDEV(ndev); */
/* union oid_res_t r; */
/* int rvalue; */
/* rvalue = mgt_get_request(priv, DOT11_OID_EDTHRESHOLD, 0, NULL, &r); */
vwrq->value = 0;
vwrq->disabled = (vwrq->value == 0);
vwrq->fixed = 1;
return 0;
}
static int
prism54_get_range(struct net_device *ndev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
{
struct iw_range *range = (struct iw_range *) extra;
memset(range, 0, sizeof (struct iw_range));
dwrq->length = sizeof (struct iw_range);
/* set the wireless extension version number */
range->we_version_source = SUPPORTED_WIRELESS_EXT;
range->we_version_compiled = WIRELESS_EXT;
/* Now the encoding capabilities */
range->num_encoding_sizes = 3;
/* 64(40) bits WEP */
range->encoding_size[0] = 5;
/* 128(104) bits WEP */
range->encoding_size[1] = 13;
/* 256 bits for WPA-PSK */
range->encoding_size[2] = 32;
/* 4 keys are allowed */
range->max_encoding_tokens = 4;
/* we don't know the quality range... */
range->max_qual.level = 0;
range->max_qual.noise = 0;
range->max_qual.qual = 0;
/* these value describe an average quality. Needs more tweaking... */
range->avg_qual.level = -80; /* -80 dBm */
range->avg_qual.noise = 0; /* don't know what to put here */
range->avg_qual.qual = 0;
range->sensitivity = 200;
/* retry limit capabilities */
range->retry_capa = IW_RETRY_LIMIT | IW_RETRY_LIFETIME;
range->retry_flags = IW_RETRY_LIMIT;
range->r_time_flags = IW_RETRY_LIFETIME;
/* I don't know the range. Put stupid things here */
range->min_retry = 1;
range->max_retry = 65535;
range->min_r_time = 1024;
range->max_r_time = 65535 * 1024;
/* txpower is supported in dBm's */
range->txpower_capa = IW_TXPOW_DBM;
return 0;
}
static int
prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *data, char *extra)
{
/* We only do a passive scan for now. */
return 0;
}
static const iw_handler prism54_handler[] = {
prism54_commit, /* SIOCSIWCOMMIT */
prism54_get_name, /* SIOCGIWNAME */
NULL, /* SIOCSIWNWID */
NULL, /* SIOCGIWNWID */
prism54_set_freq, /* SIOCSIWFREQ */
prism54_get_freq, /* SIOCGIWFREQ */
prism54_set_mode, /* SIOCSIWMODE */
prism54_get_mode, /* SIOCGIWMODE */
(iw_handler) prism54_set_sens, /* SIOCSIWSENS */
(iw_handler) prism54_get_sens, /* SIOCGIWSENS */
NULL, /* SIOCSIWRANGE */
(iw_handler) prism54_get_range, /* SIOCGIWRANGE */
NULL, /* SIOCSIWPRIV */
NULL, /* SIOCGIWPRIV */
NULL, /* SIOCSIWSTATS */
NULL, /* SIOCGIWSTATS */
NULL, // prism54_set_spy, /* SIOCSIWSPY */
NULL, // iw_handler_get_spy, /* SIOCGIWSPY */
NULL, // iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
NULL, // iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
ieee80211softmac_wx_set_wap, /* SIOCSIWAP */
ieee80211softmac_wx_get_wap, /* SIOCGIWAP */
NULL, /* 0x16 -- hole -- */
NULL, /* SIOCGIWAPLIST depreciated */
prism54_set_scan, /* SIOCSIWSCAN */
ieee80211softmac_wx_get_scan_results, /* SIOCGIWSCAN */
ieee80211softmac_wx_set_essid, /* SIOCSIWESSID */
ieee80211softmac_wx_get_essid, /* SIOCGIWESSID */
NULL, // (iw_handler) prism54_set_nick, /* SIOCSIWNICKN */
NULL, // (iw_handler) prism54_get_nick, /* SIOCGIWNICKN */
NULL, /* 0x1E -- hole -- */
NULL, /* 0x1F -- hole -- */
NULL, // (iw_handler) prism54_set_rate, /* SIOCSIWRATE */
NULL, // (iw_handler) prism54_get_rate, /* SIOCGIWRATE */
NULL, // (iw_handler) prism54_set_rts, /* SIOCSIWRTS */
NULL, // (iw_handler) prism54_get_rts, /* SIOCGIWRTS */
NULL, // (iw_handler) prism54_set_frag, /* SIOCSIWFRAG */
NULL, // (iw_handler) prism54_get_frag, /* SIOCGIWFRAG */
NULL, // (iw_handler) prism54_set_txpower, /* SIOCSIWTXPOW */
NULL, // (iw_handler) prism54_get_txpower, /* SIOCGIWTXPOW */
NULL, // (iw_handler) prism54_set_retry, /* SIOCSIWRETRY */
NULL, // (iw_handler) prism54_get_retry, /* SIOCGIWRETRY */
NULL, // (iw_handler) prism54_set_encode, /* SIOCSIWENCODE */
NULL, // (iw_handler) prism54_get_encode, /* SIOCGIWENCODE */
NULL, /* SIOCSIWPOWER */
NULL, /* SIOCGIWPOWER */
NULL, /* 0x2E -- hole -- */
NULL, /* 0x2F -- hole -- */
NULL, /* SIOCSIWGENIE */
NULL, /* SIOCGIWGENIE */
NULL, /* SIOCSIWAUTH */
NULL, /* SIOCGIWAUTH */
NULL, /* SIOCSIWENCODEEXT */
NULL, /* SIOCGIWENCODEEXT */
NULL, /* SIOCSIWPMKSA */
};
/* XXX MAX_PKT_LEN use below is bogus - masking with decimal 200 */
static const struct iw_priv_args prism54_private_args[] = {
[0] = { /* args for islsm_ioctl_sendannouncedpkt */
.cmd = SIOCIWFIRSTPRIV,
.set_args = ((IW_PRIV_TYPE_MASK & IW_PRIV_TYPE_BYTE) | /* type of args */
(IW_PRIV_SIZE_MASK & MAX_PKT_LEN)) /* max number of args */
&(~IW_PRIV_SIZE_FIXED), /* size is not fixed */
.get_args = 0, /* Type and number of args */
.name = "set_announcedpkt", /* Name of the extension */
},
};
static const iw_handler prism54_private_handler[] = {
islsm_ioctl_sendannouncedpkt, /* SIOCWFIRSTPRIV+15 */
};
struct iw_handler_def islsm_iw_handler_def = {
.num_standard = sizeof (prism54_handler) / sizeof (iw_handler),
.num_private = sizeof (prism54_private_handler) / sizeof (iw_handler),
.num_private_args =
sizeof (prism54_private_args) / sizeof (prism54_private_args[0]),
.standard = prism54_handler,
.private = prism54_private_handler,
.private_args = prism54_private_args,
.get_wireless_stats = islsm_wireless_stats,
};
#else /* MADWIFI */
/*
* Return wireless extensions statistics.
*/
struct iw_statistics *
islsm_wireless_stats(struct net_device *dev)
{
struct islsm *sc = dev->priv;
struct ieee80211com *ic = &sc->sc_ic;
struct iw_statistics *is = &sc->iwstatistics;
ieee80211_iw_getstats(ic, is);
/* add in statistics maintained by the driver */
/* is->discard.code += sc->sc_stats.ast_rx_badcrypt; */
/* is->discard.retries += sc->sc_stats.ast_tx_xretries; */
/* is->discard.misc += sc->sc_stats.ast_tx_encap */
/* + sc->sc_stats.ast_tx_nonode */
/* + sc->sc_stats.ast_tx_xretries */
/* + sc->sc_stats.ast_tx_fifoerr */
/* + sc->sc_stats.ast_tx_filtered */
/* + sc->sc_stats.ast_tx_nobuf */
/* + sc->sc_stats.ast_tx_nobufmgt; */
/* ; */
/* is->miss.beacon = sc->sc_stats.ast_bmiss; */
return &sc->iwstatistics;
}
#include <net/iw_handler.h>
/*
* Bounce functions to get to the 802.11 code. These are
* necessary for now because wireless extensions operations
* are done on the underlying device and not the 802.11 instance.
* This will change when there can be multiple 802.11 instances
* associated with a device and we must have a net_device for
* each so we can manipulate them individually.
*/
#define ISLSM_CHAR_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
char *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_POINT_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
struct iw_point *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_PARAM_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
struct iw_param *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_SOCKADDR_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
struct sockaddr *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_FREQ_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
struct iw_freq *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_U32_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
__u32 *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
#define ISLSM_VOID_BOUNCE(name) \
static int \
islsm_ioctl_##name(struct net_device *dev, struct iw_request_info *info, \
void *erq, char *extra) \
{ \
struct islsm *sc = dev->priv; \
return ieee80211_ioctl_##name(&sc->sc_ic, info, erq, extra); \
}
ISLSM_CHAR_BOUNCE(giwname)
ISLSM_POINT_BOUNCE(siwencode)
ISLSM_POINT_BOUNCE(giwencode)
ISLSM_PARAM_BOUNCE(siwrate)
ISLSM_PARAM_BOUNCE(giwrate)
ISLSM_PARAM_BOUNCE(siwsens)
ISLSM_PARAM_BOUNCE(giwsens)
ISLSM_PARAM_BOUNCE(siwrts)
ISLSM_PARAM_BOUNCE(giwrts)
ISLSM_PARAM_BOUNCE(siwfrag)
ISLSM_PARAM_BOUNCE(giwfrag)
ISLSM_SOCKADDR_BOUNCE(siwap)
ISLSM_SOCKADDR_BOUNCE(giwap)
ISLSM_POINT_BOUNCE(siwnickn)
ISLSM_POINT_BOUNCE(giwnickn)
ISLSM_FREQ_BOUNCE(siwfreq)
ISLSM_FREQ_BOUNCE(giwfreq)
ISLSM_POINT_BOUNCE(siwessid)
ISLSM_POINT_BOUNCE(giwessid)
ISLSM_POINT_BOUNCE(giwrange)
ISLSM_U32_BOUNCE(siwmode)
ISLSM_U32_BOUNCE(giwmode)
ISLSM_PARAM_BOUNCE(siwpower)
ISLSM_PARAM_BOUNCE(giwpower)
ISLSM_PARAM_BOUNCE(siwretry)
ISLSM_PARAM_BOUNCE(giwretry)
ISLSM_PARAM_BOUNCE(siwtxpow)
ISLSM_PARAM_BOUNCE(giwtxpow)
ISLSM_POINT_BOUNCE(iwaplist)
#ifdef SIOCGIWSCAN
ISLSM_POINT_BOUNCE(siwscan)
ISLSM_POINT_BOUNCE(giwscan)
#endif
ISLSM_VOID_BOUNCE(setparam)
ISLSM_VOID_BOUNCE(getparam)
ISLSM_VOID_BOUNCE(setkey)
ISLSM_VOID_BOUNCE(delkey)
ISLSM_VOID_BOUNCE(setmlme)
ISLSM_VOID_BOUNCE(setoptie)
ISLSM_VOID_BOUNCE(getoptie)
ISLSM_VOID_BOUNCE(addmac)
ISLSM_VOID_BOUNCE(delmac)
ISLSM_VOID_BOUNCE(chanlist)
/* Structures to export the Wireless Handlers */
static const iw_handler islsm_handlers[] = {
(iw_handler) NULL, /* SIOCSIWCOMMIT */
(iw_handler) islsm_ioctl_giwname, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
(iw_handler) islsm_ioctl_siwfreq, /* SIOCSIWFREQ */
(iw_handler) islsm_ioctl_giwfreq, /* SIOCGIWFREQ */
(iw_handler) islsm_ioctl_siwmode, /* SIOCSIWMODE */
(iw_handler) islsm_ioctl_giwmode, /* SIOCGIWMODE */
(iw_handler) islsm_ioctl_siwsens, /* SIOCSIWSENS */
(iw_handler) islsm_ioctl_giwsens, /* SIOCGIWSENS */
(iw_handler) NULL /* not used */ , /* SIOCSIWRANGE */
(iw_handler) islsm_ioctl_giwrange, /* SIOCGIWRANGE */
(iw_handler) NULL /* not used */ , /* SIOCSIWPRIV */
(iw_handler) NULL /* kernel code */ , /* SIOCGIWPRIV */
(iw_handler) NULL /* not used */ , /* SIOCSIWSTATS */
(iw_handler) NULL /* kernel code */ , /* SIOCGIWSTATS */
(iw_handler) NULL, /* SIOCSIWSPY */
(iw_handler) NULL, /* SIOCGIWSPY */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) islsm_ioctl_siwap, /* SIOCSIWAP */
(iw_handler) islsm_ioctl_giwap, /* SIOCGIWAP */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) islsm_ioctl_iwaplist, /* SIOCGIWAPLIST */
#ifdef SIOCGIWSCAN
(iw_handler) islsm_ioctl_siwscan, /* SIOCSIWSCAN */
(iw_handler) islsm_ioctl_giwscan, /* SIOCGIWSCAN */
#else
(iw_handler) NULL, /* SIOCSIWSCAN */
(iw_handler) NULL, /* SIOCGIWSCAN */
#endif /* SIOCGIWSCAN */
(iw_handler) islsm_ioctl_siwessid, /* SIOCSIWESSID */
(iw_handler) islsm_ioctl_giwessid, /* SIOCGIWESSID */
(iw_handler) islsm_ioctl_siwnickn, /* SIOCSIWNICKN */
(iw_handler) islsm_ioctl_giwnickn, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) islsm_ioctl_siwrate, /* SIOCSIWRATE */
(iw_handler) islsm_ioctl_giwrate, /* SIOCGIWRATE */
(iw_handler) islsm_ioctl_siwrts, /* SIOCSIWRTS */
(iw_handler) islsm_ioctl_giwrts, /* SIOCGIWRTS */
(iw_handler) islsm_ioctl_siwfrag, /* SIOCSIWFRAG */
(iw_handler) islsm_ioctl_giwfrag, /* SIOCGIWFRAG */
(iw_handler) islsm_ioctl_siwtxpow, /* SIOCSIWTXPOW */
(iw_handler) islsm_ioctl_giwtxpow, /* SIOCGIWTXPOW */
(iw_handler) islsm_ioctl_siwretry, /* SIOCSIWRETRY */
(iw_handler) islsm_ioctl_giwretry, /* SIOCGIWRETRY */
(iw_handler) islsm_ioctl_siwencode, /* SIOCSIWENCODE */
(iw_handler) islsm_ioctl_giwencode, /* SIOCGIWENCODE */
(iw_handler) islsm_ioctl_siwpower, /* SIOCSIWPOWER */
(iw_handler) islsm_ioctl_giwpower, /* SIOCGIWPOWER */
};
static const iw_handler islsm_priv_handlers[] = {
(iw_handler) islsm_ioctl_setparam, /* SIOCWFIRSTPRIV+0 */
(iw_handler) islsm_ioctl_getparam, /* SIOCWFIRSTPRIV+1 */
(iw_handler) islsm_ioctl_setkey, /* SIOCWFIRSTPRIV+2 */
(iw_handler) NULL, /* SIOCWFIRSTPRIV+3 */
(iw_handler) islsm_ioctl_delkey, /* SIOCWFIRSTPRIV+4 */
(iw_handler) NULL, /* SIOCWFIRSTPRIV+5 */
(iw_handler) islsm_ioctl_setmlme, /* SIOCWFIRSTPRIV+6 */
(iw_handler) NULL, /* SIOCWFIRSTPRIV+7 */
(iw_handler) islsm_ioctl_setoptie, /* SIOCWFIRSTPRIV+8 */
(iw_handler) islsm_ioctl_getoptie, /* SIOCWFIRSTPRIV+9 */
(iw_handler) islsm_ioctl_addmac, /* SIOCWFIRSTPRIV+10 */
(iw_handler) NULL, /* SIOCWFIRSTPRIV+11 */
(iw_handler) islsm_ioctl_delmac, /* SIOCWFIRSTPRIV+12 */
(iw_handler) NULL, /* SIOCWFIRSTPRIV+13 */
(iw_handler) islsm_ioctl_chanlist, /* SIOCWFIRSTPRIV+14 */
};
struct iw_handler_def islsm_iw_handler_def = {
#define N(a) (sizeof (a) / sizeof (a[0]))
.standard = (iw_handler *) islsm_handlers,
.num_standard = N(islsm_handlers),
.private = (iw_handler *) islsm_priv_handlers,
.num_private = N(islsm_priv_handlers),
#undef N
};
#endif /* MADWIFI */
#endif /* CONFIG_WLAN_80211 */