462 |
#include <linux/if_arp.h> |
#include <linux/if_arp.h> |
463 |
#include <linux/etherdevice.h> |
#include <linux/etherdevice.h> |
464 |
#include <linux/wireless.h> |
#include <linux/wireless.h> |
465 |
|
#if WIRELESS_EXT > 12 |
466 |
|
#include <net/iw_handler.h> |
467 |
|
#endif /* WIRELESS_EXT > 12 */ |
468 |
|
|
469 |
#include <asm/uaccess.h> |
#include <asm/uaccess.h> |
470 |
#include <asm/io.h> |
#include <asm/io.h> |
500 |
/********************************************************************/ |
/********************************************************************/ |
501 |
|
|
502 |
/* Wireless extensions backwards compatibility */ |
/* Wireless extensions backwards compatibility */ |
503 |
|
#if WIRELESS_EXT <= 12 |
504 |
|
/* Taken verbatim from iw_handler.h */ |
505 |
|
struct iw_request_info |
506 |
|
{ |
507 |
|
u16 cmd; /* Wireless Extension command */ |
508 |
|
u16 flags; /* More to come ;-) */ |
509 |
|
}; |
510 |
|
|
511 |
#ifndef SIOCIWFIRSTPRIV |
#ifndef SIOCIWFIRSTPRIV |
512 |
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE |
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE |
513 |
#endif /* SIOCIWFIRSTPRIV */ |
#define SIOCIWLASTPRIV (SIOCDEVPRIVATE + 0xF) |
514 |
|
#endif /* !SIOCIWFIRSTPRIV */ |
515 |
|
|
516 |
|
#endif /* WIRELESS_EXT <= 12 */ |
517 |
|
|
518 |
/* We do this this way to avoid ifdefs in the actual code */ |
/* We do this this way to avoid ifdefs in the actual code */ |
519 |
#ifdef WIRELESS_SPY |
#ifdef WIRELESS_SPY |
2649 |
return 0; |
return 0; |
2650 |
} |
} |
2651 |
|
|
2652 |
|
static int orinoco_ioctl_getname(struct net_device *dev, |
2653 |
|
struct iw_request_info *info, |
2654 |
|
char *name, |
2655 |
|
char *extra) |
2656 |
|
{ |
2657 |
|
strcpy(name, "IEEE 802.11-DS"); |
2658 |
|
return 0; |
2659 |
|
} |
2660 |
|
|
2661 |
|
static int orinoco_ioctl_getwap(struct net_device *dev, |
2662 |
|
struct iw_request_info *info, |
2663 |
|
struct sockaddr *ap_addr, |
2664 |
|
char *extra) |
2665 |
|
{ |
2666 |
|
struct orinoco_private *priv = dev->priv; |
2667 |
|
|
2668 |
|
ap_addr->sa_family = ARPHRD_ETHER; |
2669 |
|
return orinoco_hw_get_bssid(priv, ap_addr->sa_data); |
2670 |
|
} |
2671 |
|
|
2672 |
|
static int orinoco_ioctl_setmode(struct net_device *dev, |
2673 |
|
struct iw_request_info *info, |
2674 |
|
u32 *mode, |
2675 |
|
char *extra) |
2676 |
|
{ |
2677 |
|
struct orinoco_private *priv = dev->priv; |
2678 |
|
int err = -EINPROGRESS; /* Call commit handler */ |
2679 |
|
unsigned long flags; |
2680 |
|
|
2681 |
|
if (orinoco_lock(priv, &flags) != 0) |
2682 |
|
return -EBUSY; |
2683 |
|
|
2684 |
|
switch (*mode) { |
2685 |
|
case IW_MODE_ADHOC: |
2686 |
|
if (priv->has_ibss || priv->has_port3) |
2687 |
|
priv->iw_mode = IW_MODE_ADHOC; |
2688 |
|
else |
2689 |
|
err = -EINVAL; |
2690 |
|
|
2691 |
|
break; |
2692 |
|
|
2693 |
|
case IW_MODE_INFRA: |
2694 |
|
priv->iw_mode = IW_MODE_INFRA; |
2695 |
|
break; |
2696 |
|
|
2697 |
|
default: |
2698 |
|
err = -EINVAL; |
2699 |
|
break; |
2700 |
|
} |
2701 |
|
set_port_type(priv); |
2702 |
|
orinoco_unlock(priv, &flags); |
2703 |
|
|
2704 |
|
return err; |
2705 |
|
} |
2706 |
|
|
2707 |
|
static int orinoco_ioctl_getmode(struct net_device *dev, |
2708 |
|
struct iw_request_info *info, |
2709 |
|
u32 *mode, |
2710 |
|
char *extra) |
2711 |
|
{ |
2712 |
|
struct orinoco_private *priv = dev->priv; |
2713 |
|
unsigned long flags; |
2714 |
|
|
2715 |
|
/* No real need to lock here */ |
2716 |
|
if (orinoco_lock(priv, &flags) != 0) |
2717 |
|
return -EBUSY; |
2718 |
|
*mode = priv->iw_mode; |
2719 |
|
orinoco_unlock(priv, &flags); |
2720 |
|
return 0; |
2721 |
|
} |
2722 |
|
|
2723 |
|
|
2724 |
static int orinoco_ioctl_getiwrange(struct net_device *dev, |
static int orinoco_ioctl_getiwrange(struct net_device *dev, |
2725 |
struct iw_point *rrq) |
struct iw_point *rrq) |
2726 |
{ |
{ |
3776 |
return 0; |
return 0; |
3777 |
} |
} |
3778 |
|
|
3779 |
|
/* Commit handler, called after set operations */ |
3780 |
|
static int orinoco_ioctl_commit(struct net_device *dev, |
3781 |
|
struct iw_request_info *info, |
3782 |
|
void *wrqu, |
3783 |
|
char *extra) |
3784 |
|
{ |
3785 |
|
return orinoco_reconfigure(dev); |
3786 |
|
} |
3787 |
|
|
3788 |
static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
static int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
3789 |
{ |
{ |
3790 |
struct orinoco_private *priv = dev->priv; |
struct orinoco_private *priv = dev->priv; |
3807 |
|
|
3808 |
switch (cmd) { |
switch (cmd) { |
3809 |
case SIOCGIWNAME: |
case SIOCGIWNAME: |
3810 |
strcpy(wrq->u.name, "IEEE 802.11-DS"); |
err = orinoco_ioctl_getname(dev, NULL, wrq->u.name, NULL); |
3811 |
break; |
break; |
3812 |
|
|
3813 |
case SIOCGIWAP: |
case SIOCGIWAP: |
3814 |
wrq->u.ap_addr.sa_family = ARPHRD_ETHER; |
err = orinoco_ioctl_getwap(dev, NULL, &wrq->u.ap_addr, NULL); |
|
err = orinoco_hw_get_bssid(priv, wrq->u.ap_addr.sa_data); |
|
3815 |
break; |
break; |
3816 |
|
|
3817 |
case SIOCGIWRANGE: |
case SIOCGIWRANGE: |
3819 |
break; |
break; |
3820 |
|
|
3821 |
case SIOCSIWMODE: |
case SIOCSIWMODE: |
3822 |
err = orinoco_lock(priv, &flags); |
err = orinoco_ioctl_setmode(dev, NULL, &wrq->u.mode, NULL); |
|
if (err) |
|
|
return err; |
|
|
switch (wrq->u.mode) { |
|
|
case IW_MODE_ADHOC: |
|
|
if (! (priv->has_ibss || priv->has_port3) ) |
|
|
err = -EINVAL; |
|
|
else { |
|
|
priv->iw_mode = IW_MODE_ADHOC; |
|
|
need_reconfigure = 1; |
|
|
} |
|
|
break; |
|
|
|
|
|
case IW_MODE_INFRA: |
|
|
priv->iw_mode = IW_MODE_INFRA; |
|
|
need_reconfigure = 1; |
|
|
break; |
|
|
|
|
|
default: |
|
|
err = -EINVAL; |
|
|
break; |
|
|
} |
|
|
set_port_type(priv); |
|
|
orinoco_unlock(priv, &flags); |
|
3823 |
break; |
break; |
3824 |
|
|
3825 |
case SIOCGIWMODE: |
case SIOCGIWMODE: |
3826 |
err = orinoco_lock(priv, &flags); |
err = orinoco_ioctl_getmode(dev, NULL, &wrq->u.mode, NULL); |
|
if (err) |
|
|
return err; |
|
|
wrq->u.mode = priv->iw_mode; |
|
|
orinoco_unlock(priv, &flags); |
|
3827 |
break; |
break; |
3828 |
|
|
3829 |
case SIOCSIWENCODE: |
case SIOCSIWENCODE: |
4096 |
|
|
4097 |
if (! err && need_reconfigure && netif_running(dev)) { |
if (! err && need_reconfigure && netif_running(dev)) { |
4098 |
err = orinoco_reconfigure(dev); |
err = orinoco_reconfigure(dev); |
4099 |
} |
} |
4100 |
|
/* This should go away when all handlers are converted */ |
4101 |
|
if (need_reconfigure) |
4102 |
|
err = -EINPROGRESS; |
4103 |
|
|
4104 |
|
if (err == -EINPROGRESS) { |
4105 |
|
if (netif_running(dev)) |
4106 |
|
err = orinoco_ioctl_commit(dev, NULL, NULL, NULL); |
4107 |
|
else |
4108 |
|
err = 0; |
4109 |
|
} |
4110 |
TRACE_EXIT(dev->name); |
TRACE_EXIT(dev->name); |
4111 |
|
|
4112 |
return err; |
return err; |