diff options
Diffstat (limited to 'drivers/net/wireless/ray_cs.c')
-rw-r--r-- | drivers/net/wireless/ray_cs.c | 866 |
1 files changed, 451 insertions, 415 deletions
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 0e0ba614259a..e9c5ea0f5535 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -53,6 +53,7 @@ #include <pcmcia/ds.h> #include <pcmcia/mem_op.h> +#include <net/ieee80211.h> #include <linux/wireless.h> #include <asm/io.h> @@ -64,7 +65,6 @@ #define WIRELESS_SPY /* Enable spying addresses */ /* Definitions we need for spy */ typedef struct iw_statistics iw_stats; -typedef struct iw_quality iw_qual; typedef u_char mac_addr[ETH_ALEN]; /* Hardware address */ #include "rayctl.h" @@ -101,7 +101,6 @@ static int ray_dev_close(struct net_device *dev); static int ray_dev_config(struct net_device *dev, struct ifmap *map); static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); -static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); static struct ethtool_ops netdev_ethtool_ops; @@ -114,9 +113,8 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx, static void ray_build_header(ray_dev_t *local, struct tx_msg __iomem *ptx, UCHAR msg_type, unsigned char *data); static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len); -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ static iw_stats * ray_get_wireless_stats(struct net_device * dev); -#endif /* WIRELESS_EXT > 7 */ +static const struct iw_handler_def ray_handler_def; /***** Prototypes for raylink functions **************************************/ static int asc_to_int(char a); @@ -373,11 +371,12 @@ static dev_link_t *ray_attach(void) dev->hard_start_xmit = &ray_dev_start_xmit; dev->set_config = &ray_dev_config; dev->get_stats = &ray_get_stats; - dev->do_ioctl = &ray_dev_ioctl; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ - dev->get_wireless_stats = ray_get_wireless_stats; -#endif + dev->wireless_handlers = &ray_handler_def; +#ifdef WIRELESS_SPY + local->wireless_data.spy_data = &local->spy_data; + dev->wireless_data = &local->wireless_data; +#endif /* WIRELESS_SPY */ dev->set_multicast_list = &set_multicast_list; @@ -1201,436 +1200,420 @@ static struct ethtool_ops netdev_ethtool_ops = { /*====================================================================*/ -static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get protocol name + */ +static int ray_get_name(struct net_device *dev, + struct iw_request_info *info, + char *cwrq, + char *extra) { - ray_dev_t *local = (ray_dev_t *)dev->priv; - dev_link_t *link = local->finder; - int err = 0; -#if WIRELESS_EXT > 7 - struct iwreq *wrq = (struct iwreq *) ifr; -#endif /* WIRELESS_EXT > 7 */ -#ifdef WIRELESS_SPY - struct sockaddr address[IW_MAX_SPY]; -#endif /* WIRELESS_SPY */ + strcpy(cwrq, "IEEE 802.11-FH"); + return 0; +} - if (!(link->state & DEV_PRESENT)) { - DEBUG(2,"ray_dev_ioctl - device not present\n"); - return -1; - } - DEBUG(2,"ray_cs IOCTL dev=%p, ifr=%p, cmd = 0x%x\n",dev,ifr,cmd); - /* Validate the command */ - switch (cmd) - { -#if WIRELESS_EXT > 7 - /* --------------- WIRELESS EXTENSIONS --------------- */ - /* Get name */ - case SIOCGIWNAME: - strcpy(wrq->u.name, "IEEE 802.11-FH"); - break; - - /* Get frequency/channel */ - case SIOCGIWFREQ: - wrq->u.freq.m = local->sparm.b5.a_hop_pattern; - wrq->u.freq.e = 0; - break; - - /* Set frequency/channel */ - case SIOCSIWFREQ: - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set frequency + */ +static int ray_set_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int err = -EINPROGRESS; /* Call commit handler */ - /* Setting by channel number */ - if ((wrq->u.freq.m > USA_HOP_MOD) || (wrq->u.freq.e > 0)) - err = -EOPNOTSUPP; - else - local->sparm.b5.a_hop_pattern = wrq->u.freq.m; - break; + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; - /* Get current network name (ESSID) */ - case SIOCGIWESSID: - if (wrq->u.data.pointer) - { - char essid[IW_ESSID_MAX_SIZE + 1]; - /* Get the essid that was set */ - memcpy(essid, local->sparm.b5.a_current_ess_id, - IW_ESSID_MAX_SIZE); - essid[IW_ESSID_MAX_SIZE] = '\0'; - - /* Push it out ! */ - wrq->u.data.length = strlen(essid) + 1; - wrq->u.data.flags = 1; /* active */ - if (copy_to_user(wrq->u.data.pointer, essid, sizeof(essid))) - err = -EFAULT; - } - break; + /* Setting by channel number */ + if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) + err = -EOPNOTSUPP; + else + local->sparm.b5.a_hop_pattern = fwrq->m; - /* Set desired network name (ESSID) */ - case SIOCSIWESSID: - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } + return err; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get frequency + */ +static int ray_get_freq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *fwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; - if (wrq->u.data.pointer) - { - char card_essid[IW_ESSID_MAX_SIZE + 1]; - - /* Check if we asked for `any' */ - if(wrq->u.data.flags == 0) - { + fwrq->m = local->sparm.b5.a_hop_pattern; + fwrq->e = 0; + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set ESSID + */ +static int ray_set_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* Check if we asked for `any' */ + if(dwrq->flags == 0) { /* Corey : can you do that ? */ - err = -EOPNOTSUPP; - } - else - { + return -EOPNOTSUPP; + } else { /* Check the size of the string */ - if(wrq->u.data.length > - IW_ESSID_MAX_SIZE + 1) - { - err = -E2BIG; - break; - } - if (copy_from_user(card_essid, - wrq->u.data.pointer, - wrq->u.data.length)) { - err = -EFAULT; - break; + if(dwrq->length > IW_ESSID_MAX_SIZE + 1) { + return -E2BIG; } - card_essid[IW_ESSID_MAX_SIZE] = '\0'; /* Set the ESSID in the card */ - memcpy(local->sparm.b5.a_current_ess_id, card_essid, - IW_ESSID_MAX_SIZE); - } + memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); + memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); } - break; - - /* Get current Access Point (BSSID in our case) */ - case SIOCGIWAP: - memcpy(wrq->u.ap_addr.sa_data, local->bss_id, ETH_ALEN); - wrq->u.ap_addr.sa_family = ARPHRD_ETHER; - break; - - /* Get the current bit-rate */ - case SIOCGIWRATE: - if(local->net_default_tx_rate == 3) - wrq->u.bitrate.value = 2000000; /* Hum... */ - else - wrq->u.bitrate.value = local->net_default_tx_rate * 500000; - wrq->u.bitrate.fixed = 0; /* We are in auto mode */ - break; - - /* Set the desired bit-rate */ - case SIOCSIWRATE: - /* Check if rate is in range */ - if((wrq->u.bitrate.value != 1000000) && - (wrq->u.bitrate.value != 2000000)) - { - err = -EINVAL; - break; - } - /* Hack for 1.5 Mb/s instead of 2 Mb/s */ - if((local->fw_ver == 0x55) && /* Please check */ - (wrq->u.bitrate.value == 2000000)) - local->net_default_tx_rate = 3; - else - local->net_default_tx_rate = wrq->u.bitrate.value/500000; - break; - - /* Get the current RTS threshold */ - case SIOCGIWRTS: - wrq->u.rts.value = (local->sparm.b5.a_rts_threshold[0] << 8) - + local->sparm.b5.a_rts_threshold[1]; -#if WIRELESS_EXT > 8 - wrq->u.rts.disabled = (wrq->u.rts.value == 32767); -#endif /* WIRELESS_EXT > 8 */ - wrq->u.rts.fixed = 1; - break; - - /* Set the desired RTS threshold */ - case SIOCSIWRTS: - { - int rthr = wrq->u.rts.value; - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } + return -EINPROGRESS; /* Call commit handler */ +} - /* if(wrq->u.rts.fixed == 0) we should complain */ -#if WIRELESS_EXT > 8 - if(wrq->u.rts.disabled) - rthr = 32767; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get ESSID + */ +static int ray_get_essid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Get the essid that was set */ + memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); + extra[IW_ESSID_MAX_SIZE] = '\0'; + + /* Push it out ! */ + dwrq->length = strlen(extra) + 1; + dwrq->flags = 1; /* active */ + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get AP address + */ +static int ray_get_wap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *awrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); + awrq->sa_family = ARPHRD_ETHER; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Bit-Rate + */ +static int ray_set_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* Check if rate is in range */ + if((vwrq->value != 1000000) && (vwrq->value != 2000000)) + return -EINVAL; + + /* Hack for 1.5 Mb/s instead of 2 Mb/s */ + if((local->fw_ver == 0x55) && /* Please check */ + (vwrq->value == 2000000)) + local->net_default_tx_rate = 3; else -#endif /* WIRELESS_EXT > 8 */ - if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ - { - err = -EINVAL; - break; - } + local->net_default_tx_rate = vwrq->value/500000; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Bit-Rate + */ +static int ray_get_rate(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + if(local->net_default_tx_rate == 3) + vwrq->value = 2000000; /* Hum... */ + else + vwrq->value = local->net_default_tx_rate * 500000; + vwrq->fixed = 0; /* We are in auto mode */ + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set RTS threshold + */ +static int ray_set_rts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int rthr = vwrq->value; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + /* if(wrq->u.rts.fixed == 0) we should complain */ + if(vwrq->disabled) + rthr = 32767; + else { + if((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ + return -EINVAL; + } local->sparm.b5.a_rts_threshold[0] = (rthr >> 8) & 0xFF; local->sparm.b5.a_rts_threshold[1] = rthr & 0xFF; - } - break; - /* Get the current fragmentation threshold */ - case SIOCGIWFRAG: - wrq->u.frag.value = (local->sparm.b5.a_frag_threshold[0] << 8) - + local->sparm.b5.a_frag_threshold[1]; -#if WIRELESS_EXT > 8 - wrq->u.frag.disabled = (wrq->u.frag.value == 32767); -#endif /* WIRELESS_EXT > 8 */ - wrq->u.frag.fixed = 1; - break; + return -EINPROGRESS; /* Call commit handler */ +} - /* Set the desired fragmentation threshold */ - case SIOCSIWFRAG: - { - int fthr = wrq->u.frag.value; - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get RTS threshold + */ +static int ray_get_rts(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + + vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) + + local->sparm.b5.a_rts_threshold[1]; + vwrq->disabled = (vwrq->value == 32767); + vwrq->fixed = 1; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Fragmentation threshold + */ +static int ray_set_frag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int fthr = vwrq->value; + + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; /* if(wrq->u.frag.fixed == 0) should complain */ -#if WIRELESS_EXT > 8 - if(wrq->u.frag.disabled) - fthr = 32767; - else -#endif /* WIRELESS_EXT > 8 */ - if((fthr < 256) || (fthr > 2347)) /* To check out ! */ - { - err = -EINVAL; - break; - } + if(vwrq->disabled) + fthr = 32767; + else { + if((fthr < 256) || (fthr > 2347)) /* To check out ! */ + return -EINVAL; + } local->sparm.b5.a_frag_threshold[0] = (fthr >> 8) & 0xFF; local->sparm.b5.a_frag_threshold[1] = fthr & 0xFF; - } - break; -#endif /* WIRELESS_EXT > 7 */ -#if WIRELESS_EXT > 8 + return -EINPROGRESS; /* Call commit handler */ +} - /* Get the current mode of operation */ - case SIOCGIWMODE: - if(local->sparm.b5.a_network_type) - wrq->u.mode = IW_MODE_INFRA; - else - wrq->u.mode = IW_MODE_ADHOC; - break; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Fragmentation threshold + */ +static int ray_get_frag(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; - /* Set the current mode of operation */ - case SIOCSIWMODE: - { + vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) + + local->sparm.b5.a_frag_threshold[1]; + vwrq->disabled = (vwrq->value == 32767); + vwrq->fixed = 1; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : set Mode of Operation + */ +static int ray_set_mode(struct net_device *dev, + struct iw_request_info *info, + __u32 *uwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; + int err = -EINPROGRESS; /* Call commit handler */ char card_mode = 1; - - /* Reject if card is already initialised */ - if(local->card_status != CARD_AWAITING_PARAM) - { - err = -EBUSY; - break; - } - switch (wrq->u.mode) + /* Reject if card is already initialised */ + if(local->card_status != CARD_AWAITING_PARAM) + return -EBUSY; + + switch (*uwrq) { case IW_MODE_ADHOC: - card_mode = 0; - // Fall through + card_mode = 0; + // Fall through case IW_MODE_INFRA: - local->sparm.b5.a_network_type = card_mode; - break; + local->sparm.b5.a_network_type = card_mode; + break; default: - err = -EINVAL; + err = -EINVAL; } - } - break; -#endif /* WIRELESS_EXT > 8 */ -#if WIRELESS_EXT > 7 - /* ------------------ IWSPY SUPPORT ------------------ */ - /* Define the range (variations) of above parameters */ - case SIOCGIWRANGE: - /* Basic checking... */ - if(wrq->u.data.pointer != (caddr_t) 0) - { - struct iw_range range; - memset((char *) &range, 0, sizeof(struct iw_range)); - - /* Set the length (very important for backward compatibility) */ - wrq->u.data.length = sizeof(struct iw_range); - -#if WIRELESS_EXT > 10 - /* Set the Wireless Extension versions */ - range.we_version_compiled = WIRELESS_EXT; - range.we_version_source = 9; -#endif /* WIRELESS_EXT > 10 */ - - /* Set information in the range struct */ - range.throughput = 1.1 * 1000 * 1000; /* Put the right number here */ - range.num_channels = hop_pattern_length[(int)country]; - range.num_frequency = 0; - range.max_qual.qual = 0; - range.max_qual.level = 255; /* What's the correct value ? */ - range.max_qual.noise = 255; /* Idem */ - range.num_bitrates = 2; - range.bitrate[0] = 1000000; /* 1 Mb/s */ - range.bitrate[1] = 2000000; /* 2 Mb/s */ - - /* Copy structure to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, &range, - sizeof(struct iw_range))) - err = -EFAULT; - } - break; + return err; +} -#ifdef WIRELESS_SPY - /* Set addresses to spy */ - case SIOCSIWSPY: - /* Check the number of addresses */ - if(wrq->u.data.length > IW_MAX_SPY) - { - err = -E2BIG; - break; - } - local->spy_number = wrq->u.data.length; +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get Mode of Operation + */ +static int ray_get_mode(struct net_device *dev, + struct iw_request_info *info, + __u32 *uwrq, + char *extra) +{ + ray_dev_t *local = (ray_dev_t *)dev->priv; - /* If there is some addresses to copy */ - if(local->spy_number > 0) - { - int i; - - /* Copy addresses to the driver */ - if(copy_from_user(address, wrq->u.data.pointer, - sizeof(struct sockaddr) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Copy addresses to the lp structure */ - for(i = 0; i < local->spy_number; i++) - memcpy(local->spy_address[i], address[i].sa_data, ETH_ALEN); - - /* Reset structure... */ - memset(local->spy_stat, 0x00, sizeof(iw_qual) * IW_MAX_SPY); - -#ifdef DEBUG_IOCTL_INFO - printk(KERN_DEBUG "SetSpy - Set of new addresses is :\n"); - for(i = 0; i < local->spy_number; i++) - printk(KERN_DEBUG "%02X:%02X:%02X:%02X:%02X:%02X\n", - local->spy_address[i][0], - local->spy_address[i][1], - local->spy_address[i][2], - local->spy_address[i][3], - local->spy_address[i][4], - local->spy_address[i][5]); -#endif /* DEBUG_IOCTL_INFO */ - } - break; + if(local->sparm.b5.a_network_type) + *uwrq = IW_MODE_INFRA; + else + *uwrq = IW_MODE_ADHOC; - /* Get the spy list and spy stats */ - case SIOCGIWSPY: - /* Set the number of addresses */ - wrq->u.data.length = local->spy_number; + return 0; +} - /* If the user want to have the addresses back... */ - if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0)) - { - int i; - - /* Copy addresses from the lp structure */ - for(i = 0; i < local->spy_number; i++) - { - memcpy(address[i].sa_data, local->spy_address[i], ETH_ALEN); - address[i].sa_family = ARPHRD_ETHER; - } - - /* Copy addresses to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, address, - sizeof(struct sockaddr) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Copy stats to the user buffer (just after) */ - if(copy_to_user(wrq->u.data.pointer + - (sizeof(struct sockaddr) * local->spy_number), - local->spy_stat, sizeof(iw_qual) * local->spy_number)) - { - err = -EFAULT; - break; - } - - /* Reset updated flags */ - for(i = 0; i < local->spy_number; i++) - local->spy_stat[i].updated = 0x0; - } /* if(pointer != NULL) */ - - break; -#endif /* WIRELESS_SPY */ +/*------------------------------------------------------------------*/ +/* + * Wireless Handler : get range info + */ +static int ray_get_range(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *dwrq, + char *extra) +{ + struct iw_range *range = (struct iw_range *) extra; + + memset((char *) range, 0, sizeof(struct iw_range)); + + /* Set the length (very important for backward compatibility) */ + dwrq->length = sizeof(struct iw_range); + + /* Set the Wireless Extension versions */ + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 9; + + /* Set information in the range struct */ + range->throughput = 1.1 * 1000 * 1000; /* Put the right number here */ + range->num_channels = hop_pattern_length[(int)country]; + range->num_frequency = 0; + range->max_qual.qual = 0; + range->max_qual.level = 255; /* What's the correct value ? */ + range->max_qual.noise = 255; /* Idem */ + range->num_bitrates = 2; + range->bitrate[0] = 1000000; /* 1 Mb/s */ + range->bitrate[1] = 2000000; /* 2 Mb/s */ + return 0; +} - /* ------------------ PRIVATE IOCTL ------------------ */ -#ifndef SIOCIWFIRSTPRIV -#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE -#endif /* SIOCIWFIRSTPRIV */ -#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ -#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ -#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ - case SIOCSIPFRAMING: - if(!capable(CAP_NET_ADMIN)) /* For private IOCTLs, we need to check permissions */ - { - err = -EPERM; - break; - } - translate = *(wrq->u.name); /* Set framing mode */ - break; - case SIOCGIPFRAMING: - *(wrq->u.name) = translate; - break; - case SIOCGIPCOUNTRY: - *(wrq->u.name) = country; - break; - case SIOCGIWPRIV: - /* Export our "private" intercace */ - if(wrq->u.data.pointer != (caddr_t) 0) - { - struct iw_priv_args priv[] = - { /* cmd, set_args, get_args, name */ - { SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, - { SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, - { SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, - }; - /* Set the number of ioctl available */ - wrq->u.data.length = 3; - /* Copy structure to the user buffer */ - if(copy_to_user(wrq->u.data.pointer, (u_char *) priv, - sizeof(priv))) - err = -EFAULT; - } - break; -#endif /* WIRELESS_EXT > 7 */ +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : set framing mode + */ +static int ray_set_framing(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + translate = *(extra); /* Set framing mode */ + return 0; +} - default: - DEBUG(0,"ray_dev_ioctl cmd = 0x%x\n", cmd); - err = -EOPNOTSUPP; - } - return err; -} /* end ray_dev_ioctl */ -/*===========================================================================*/ -#if WIRELESS_EXT > 7 /* If wireless extension exist in the kernel */ +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : get framing mode + */ +static int ray_get_framing(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + *(extra) = translate; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Wireless Private Handler : get country + */ +static int ray_get_country(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + *(extra) = country; + + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Commit handler : called after a bunch of SET operations + */ +static int ray_commit(struct net_device *dev, + struct iw_request_info *info, /* NULL */ + void *zwrq, /* NULL */ + char *extra) /* NULL */ +{ + return 0; +} + +/*------------------------------------------------------------------*/ +/* + * Stats handler : return Wireless Stats + */ static iw_stats * ray_get_wireless_stats(struct net_device * dev) { ray_dev_t * local = (ray_dev_t *) dev->priv; @@ -1642,13 +1625,13 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) local->wstats.status = local->card_status; #ifdef WIRELESS_SPY - if((local->spy_number > 0) && (local->sparm.b5.a_network_type == 0)) + if((local->spy_data.spy_number > 0) && (local->sparm.b5.a_network_type == 0)) { /* Get it from the first node in spy list */ - local->wstats.qual.qual = local->spy_stat[0].qual; - local->wstats.qual.level = local->spy_stat[0].level; - local->wstats.qual.noise = local->spy_stat[0].noise; - local->wstats.qual.updated = local->spy_stat[0].updated; + local->wstats.qual.qual = local->spy_data.spy_stat[0].qual; + local->wstats.qual.level = local->spy_data.spy_stat[0].level; + local->wstats.qual.noise = local->spy_data.spy_stat[0].noise; + local->wstats.qual.updated = local->spy_data.spy_stat[0].updated; } #endif /* WIRELESS_SPY */ @@ -1659,7 +1642,65 @@ static iw_stats * ray_get_wireless_stats(struct net_device * dev) return &local->wstats; } /* end ray_get_wireless_stats */ -#endif /* WIRELESS_EXT > 7 */ + +/*------------------------------------------------------------------*/ +/* + * Structures to export the Wireless Handlers + */ + +static const iw_handler ray_handler[] = { + [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit, + [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) ray_get_name, + [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) ray_set_freq, + [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) ray_get_freq, + [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) ray_set_mode, + [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) ray_get_mode, + [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range, +#ifdef WIRELESS_SPY + [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_set_spy, + [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) iw_handler_get_spy, + [SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy, + [SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy, +#endif /* WIRELESS_SPY */ + [SIOCGIWAP -SIOCIWFIRST] (iw_handler) ray_get_wap, + [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid, + [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid, + [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) ray_set_rate, + [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) ray_get_rate, + [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) ray_set_rts, + [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) ray_get_rts, + [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) ray_set_frag, + [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) ray_get_frag, +}; + +#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ +#define SIOCGIPFRAMING SIOCIWFIRSTPRIV + 1 /* Get framing mode */ +#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ + +static const iw_handler ray_private_handler[] = { + [0] (iw_handler) ray_set_framing, + [1] (iw_handler) ray_get_framing, + [3] (iw_handler) ray_get_country, +}; + +static const struct iw_priv_args ray_private_args[] = { +/* cmd, set_args, get_args, name */ +{ SIOCSIPFRAMING, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "set_framing" }, +{ SIOCGIPFRAMING, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_framing" }, +{ SIOCGIPCOUNTRY, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "get_country" }, +}; + +static const struct iw_handler_def ray_handler_def = +{ + .num_standard = sizeof(ray_handler)/sizeof(iw_handler), + .num_private = sizeof(ray_private_handler)/sizeof(iw_handler), + .num_private_args = sizeof(ray_private_args)/sizeof(struct iw_priv_args), + .standard = ray_handler, + .private = ray_private_handler, + .private_args = ray_private_args, + .get_wireless_stats = ray_get_wireless_stats, +}; + /*===========================================================================*/ static int ray_open(struct net_device *dev) { @@ -2392,20 +2433,15 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs, unsigned i /*local->wstats.qual.noise = none ? */ local->wstats.qual.updated = 0x2; } - /* Now, for the addresses in the spy list */ + /* Now, update the spy stuff */ { - int i; - /* Look all addresses */ - for(i = 0; i < local->spy_number; i++) - /* If match */ - if(!memcmp(linksrcaddr, local->spy_address[i], ETH_ALEN)) - { - /* Update statistics */ - /*local->spy_stat[i].qual = none ? */ - local->spy_stat[i].level = siglev; - /*local->spy_stat[i].noise = none ? */ - local->spy_stat[i].updated = 0x2; - } + struct iw_quality wstats; + wstats.level = siglev; + /* wstats.noise = none ? */ + /* wstats.qual = none ? */ + wstats.updated = 0x2; + /* Update spy records */ + wireless_spy_update(dev, linksrcaddr, &wstats); } #endif /* WIRELESS_SPY */ } /* end rx_data */ |