mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-11 21:14:07 +08:00
Merge branch 'upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream
This commit is contained in:
commit
ba9b28d19a
@ -531,6 +531,23 @@ config PRISM54
|
||||
say M here and read <file:Documentation/modules.txt>. The module
|
||||
will be called prism54.ko.
|
||||
|
||||
config USB_ZD1201
|
||||
tristate "USB ZD1201 based Wireless device support"
|
||||
depends on USB && NET_RADIO
|
||||
select FW_LOADER
|
||||
---help---
|
||||
Say Y if you want to use wireless LAN adapters based on the ZyDAS
|
||||
ZD1201 chip.
|
||||
|
||||
This driver makes the adapter appear as a normal Ethernet interface,
|
||||
typically on wlan0.
|
||||
|
||||
The zd1201 device requires external firmware to be loaded.
|
||||
This can be found at http://linux-lc100020.sourceforge.net/
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called zd1201.
|
||||
|
||||
source "drivers/net/wireless/hostap/Kconfig"
|
||||
source "drivers/net/wireless/bcm43xx/Kconfig"
|
||||
|
||||
|
@ -40,3 +40,5 @@ obj-$(CONFIG_BCM43XX) += bcm43xx/
|
||||
# 16-bit wireless PCMCIA client drivers
|
||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||
obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
|
||||
|
||||
obj-$(CONFIG_USB_ZD1201) += zd1201.o
|
||||
|
@ -3555,7 +3555,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
|
||||
unsigned long flags;
|
||||
int keyidx;
|
||||
|
||||
dprintk(KERN_INFO PFX "set security called\n");
|
||||
dprintk(KERN_INFO PFX "set security called");
|
||||
|
||||
bcm43xx_lock_mmio(bcm, flags);
|
||||
|
||||
@ -3568,24 +3568,25 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev,
|
||||
|
||||
if (sec->flags & SEC_ACTIVE_KEY) {
|
||||
secinfo->active_key = sec->active_key;
|
||||
dprintk(KERN_INFO PFX " .active_key = %d\n", sec->active_key);
|
||||
dprintk(", .active_key = %d", sec->active_key);
|
||||
}
|
||||
if (sec->flags & SEC_UNICAST_GROUP) {
|
||||
secinfo->unicast_uses_group = sec->unicast_uses_group;
|
||||
dprintk(KERN_INFO PFX " .unicast_uses_group = %d\n", sec->unicast_uses_group);
|
||||
dprintk(", .unicast_uses_group = %d", sec->unicast_uses_group);
|
||||
}
|
||||
if (sec->flags & SEC_LEVEL) {
|
||||
secinfo->level = sec->level;
|
||||
dprintk(KERN_INFO PFX " .level = %d\n", sec->level);
|
||||
dprintk(", .level = %d", sec->level);
|
||||
}
|
||||
if (sec->flags & SEC_ENABLED) {
|
||||
secinfo->enabled = sec->enabled;
|
||||
dprintk(KERN_INFO PFX " .enabled = %d\n", sec->enabled);
|
||||
dprintk(", .enabled = %d", sec->enabled);
|
||||
}
|
||||
if (sec->flags & SEC_ENCRYPT) {
|
||||
secinfo->encrypt = sec->encrypt;
|
||||
dprintk(KERN_INFO PFX " .encrypt = %d\n", sec->encrypt);
|
||||
dprintk(", .encrypt = %d", sec->encrypt);
|
||||
}
|
||||
dprintk("\n");
|
||||
if (bcm->initialized && !bcm->ieee->host_encrypt) {
|
||||
if (secinfo->enabled) {
|
||||
/* upload WEP keys to hardware */
|
||||
|
@ -33,7 +33,7 @@ static struct usb_device_id zd1201_table[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static int ap = 0; /* Are we an AP or a normal station? */
|
||||
static int ap; /* Are we an AP or a normal station? */
|
||||
|
||||
#define ZD1201_VERSION "0.15"
|
||||
|
||||
@ -49,7 +49,7 @@ MODULE_DEVICE_TABLE(usb, zd1201_table);
|
||||
static int zd1201_fw_upload(struct usb_device *dev, int apfw)
|
||||
{
|
||||
const struct firmware *fw_entry;
|
||||
char* data;
|
||||
char *data;
|
||||
unsigned long len;
|
||||
int err;
|
||||
unsigned char ret;
|
||||
@ -65,7 +65,7 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
|
||||
if (err) {
|
||||
dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
|
||||
dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n");
|
||||
dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info\n");
|
||||
dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -94,12 +94,12 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
|
||||
USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
|
||||
err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
|
||||
USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
|
||||
if (ret & 0x80) {
|
||||
err = -EIO;
|
||||
goto exit;
|
||||
@ -166,13 +166,13 @@ static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
|
||||
return -ENOMEM;
|
||||
}
|
||||
usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out2),
|
||||
command, 16, zd1201_usbfree, zd);
|
||||
command, 16, zd1201_usbfree, zd);
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
kfree(command);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -316,7 +316,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
|
||||
fc = le16_to_cpu(*(__le16 *)&data[datalen-16]);
|
||||
seq = le16_to_cpu(*(__le16 *)&data[datalen-24]);
|
||||
|
||||
if(zd->monitor) {
|
||||
if (zd->monitor) {
|
||||
if (datalen < 24)
|
||||
goto resubmit;
|
||||
if (!(skb = dev_alloc_skb(datalen+24)))
|
||||
@ -364,7 +364,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
|
||||
goto resubmit;
|
||||
}
|
||||
hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
|
||||
if(frag->seq == (seq&IEEE80211_SCTL_SEQ))
|
||||
if (frag->seq == (seq&IEEE80211_SCTL_SEQ))
|
||||
break;
|
||||
if (!frag)
|
||||
goto resubmit;
|
||||
@ -376,7 +376,6 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
|
||||
goto resubmit;
|
||||
hlist_del_init(&frag->fnode);
|
||||
kfree(frag);
|
||||
/* Fallthrough */
|
||||
} else {
|
||||
if (datalen<14)
|
||||
goto resubmit;
|
||||
@ -422,7 +421,7 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
|
||||
int rid_fid;
|
||||
int length;
|
||||
unsigned char *pdata;
|
||||
|
||||
|
||||
zd->rxdatas = 0;
|
||||
err = zd1201_docmd(zd, ZD1201_CMDCODE_ACCESS, rid, 0, 0);
|
||||
if (err)
|
||||
@ -471,11 +470,11 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
|
||||
length = zd->rxlen;
|
||||
|
||||
do {
|
||||
int actual_length;
|
||||
int actual_length;
|
||||
|
||||
actual_length = (length > 64) ? 64 : length;
|
||||
|
||||
if(pdata[0] != 0x3) {
|
||||
if (pdata[0] != 0x3) {
|
||||
dev_dbg(&zd->usb->dev, "Rx Resource packet type error: %02X\n",
|
||||
pdata[0]);
|
||||
return -EINVAL;
|
||||
@ -487,11 +486,10 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
|
||||
}
|
||||
|
||||
/* Skip the 4 bytes header (RID length and RID) */
|
||||
if(i == 0) {
|
||||
if (i == 0) {
|
||||
pdata += 8;
|
||||
actual_length -= 8;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pdata += 4;
|
||||
actual_length -= 4;
|
||||
}
|
||||
@ -620,7 +618,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
|
||||
short max;
|
||||
__le16 zdmax;
|
||||
unsigned char *buffer;
|
||||
|
||||
|
||||
buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
@ -632,7 +630,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
|
||||
err = usb_submit_urb(zd->rx_urb, GFP_KERNEL);
|
||||
if (err)
|
||||
goto err_buffer;
|
||||
|
||||
|
||||
err = zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
||||
if (err)
|
||||
goto err_urb;
|
||||
@ -684,7 +682,7 @@ static int zd1201_enable(struct zd1201 *zd)
|
||||
static int zd1201_disable(struct zd1201 *zd)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
if (!zd->mac_enabled)
|
||||
return 0;
|
||||
if (zd->monitor) {
|
||||
@ -764,7 +762,6 @@ static int zd1201_net_open(struct net_device *dev)
|
||||
static int zd1201_net_stop(struct net_device *dev)
|
||||
{
|
||||
netif_stop_queue(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -915,7 +912,6 @@ static int zd1201_get_name(struct net_device *dev,
|
||||
struct iw_request_info *info, char *name, char *extra)
|
||||
{
|
||||
strcpy(name, "IEEE 802.11b");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1013,11 +1009,10 @@ static int zd1201_set_mode(struct net_device *dev,
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
zd->monitor=monitor;
|
||||
zd->monitor = monitor;
|
||||
/* If monitor mode is set we don't actually turn it on here since it
|
||||
* is done during mac reset anyway (see zd1201_mac_enable).
|
||||
*/
|
||||
|
||||
zd1201_mac_reset(zd);
|
||||
|
||||
return 0;
|
||||
@ -1117,7 +1112,7 @@ static int zd1201_get_wap(struct net_device *dev,
|
||||
zd->iwstats.qual.updated = 2;
|
||||
}
|
||||
|
||||
return zd1201_getconfig(zd,ZD1201_RID_CURRENTBSSID,ap_addr->sa_data,6);
|
||||
return zd1201_getconfig(zd, ZD1201_RID_CURRENTBSSID, ap_addr->sa_data, 6);
|
||||
}
|
||||
|
||||
static int zd1201_set_scan(struct net_device *dev,
|
||||
@ -1275,7 +1270,7 @@ static int zd1201_set_rate(struct net_device *dev,
|
||||
if (!rrq->fixed) { /* Also enable all lower bitrates */
|
||||
rate |= rate-1;
|
||||
}
|
||||
|
||||
|
||||
err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);
|
||||
if (err)
|
||||
return err;
|
||||
@ -1486,7 +1481,7 @@ static int zd1201_get_encode(struct net_device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
erq->flags |= i+1;
|
||||
|
||||
|
||||
erq->length = zd->encode_keylen[i];
|
||||
memcpy(key, zd->encode_keys[i], erq->length);
|
||||
|
||||
@ -1529,11 +1524,7 @@ static int zd1201_set_power(struct net_device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
out:
|
||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
return zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
|
||||
}
|
||||
|
||||
static int zd1201_get_power(struct net_device *dev,
|
||||
@ -1627,15 +1618,11 @@ static int zd1201_set_hostauth(struct net_device *dev,
|
||||
struct iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||
{
|
||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||
int err;
|
||||
|
||||
if (!zd->ap)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
|
||||
if (err)
|
||||
return err;
|
||||
return 0;
|
||||
return zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
|
||||
}
|
||||
|
||||
static int zd1201_get_hostauth(struct net_device *dev,
|
||||
@ -1744,7 +1731,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
{
|
||||
struct zd1201 *zd;
|
||||
struct usb_device *usb;
|
||||
int i, err;
|
||||
int err;
|
||||
short porttype;
|
||||
char buf[IW_ESSID_MAX_SIZE+2];
|
||||
|
||||
@ -1773,9 +1760,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
if (!zd->rx_urb || !zd->tx_urb)
|
||||
goto err_zd;
|
||||
|
||||
for(i = 0; i<100; i++)
|
||||
udelay(1000);
|
||||
|
||||
mdelay(100);
|
||||
err = zd1201_drvr_start(zd);
|
||||
if (err)
|
||||
goto err_zd;
|
||||
@ -1833,7 +1818,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||
goto err_net;
|
||||
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
||||
zd->dev->name);
|
||||
|
||||
|
||||
usb_set_intfdata(interface, zd);
|
||||
return 0;
|
||||
|
@ -301,21 +301,4 @@ config USB_NET_ZAURUS
|
||||
some cases CDC MDLM) protocol, not "g_ether".
|
||||
|
||||
|
||||
config USB_ZD1201
|
||||
tristate "USB ZD1201 based Wireless device support"
|
||||
depends on NET_RADIO
|
||||
select FW_LOADER
|
||||
---help---
|
||||
Say Y if you want to use wireless LAN adapters based on the ZyDAS
|
||||
ZD1201 chip.
|
||||
|
||||
This driver makes the adapter appear as a normal Ethernet interface,
|
||||
typically on wlan0.
|
||||
|
||||
The zd1201 device requires external firmware to be loaded.
|
||||
This can be found at http://linux-lc100020.sourceforge.net/
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called zd1201.
|
||||
|
||||
endmenu
|
||||
|
@ -15,7 +15,6 @@ obj-$(CONFIG_USB_NET_RNDIS_HOST) += rndis_host.o
|
||||
obj-$(CONFIG_USB_NET_CDC_SUBSET) += cdc_subset.o
|
||||
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
|
||||
obj-$(CONFIG_USB_USBNET) += usbnet.o
|
||||
obj-$(CONFIG_USB_ZD1201) += zd1201.o
|
||||
|
||||
ifeq ($(CONFIG_USB_DEBUG),y)
|
||||
EXTRA_CFLAGS += -DDEBUG
|
||||
|
@ -1247,7 +1247,8 @@ extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
|
||||
extern int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
extern void ieee80211_txb_free(struct ieee80211_txb *);
|
||||
extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||
struct ieee80211_hdr *frame, int len);
|
||||
struct ieee80211_hdr *frame, int hdr_len,
|
||||
int total_len, int encrypt_mpdu);
|
||||
|
||||
/* ieee80211_rx.c */
|
||||
extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
|
||||
|
@ -310,7 +310,7 @@ extern void ieee80211softmac_stop(struct net_device *dev);
|
||||
* - context set to the context data you want passed
|
||||
* The return value is 0, or an error.
|
||||
*/
|
||||
typedef void (*notify_function_ptr)(struct net_device *dev, void *context);
|
||||
typedef void (*notify_function_ptr)(struct net_device *dev, int event_type, void *context);
|
||||
|
||||
#define ieee80211softmac_notify(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_KERNEL);
|
||||
#define ieee80211softmac_notify_atomic(dev, event, fun, context) ieee80211softmac_notify_gfp(dev, event, fun, context, GFP_ATOMIC);
|
||||
|
@ -555,7 +555,8 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
/* Incoming 802.11 strucure is converted to a TXB
|
||||
* a block of 802.11 fragment packets (stored as skbs) */
|
||||
int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||
struct ieee80211_hdr *frame, int len)
|
||||
struct ieee80211_hdr *frame, int hdr_len, int total_len,
|
||||
int encrypt_mpdu)
|
||||
{
|
||||
struct ieee80211_txb *txb = NULL;
|
||||
unsigned long flags;
|
||||
@ -565,6 +566,9 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||
|
||||
spin_lock_irqsave(&ieee->lock, flags);
|
||||
|
||||
if (encrypt_mpdu && !ieee->sec.encrypt)
|
||||
encrypt_mpdu = 0;
|
||||
|
||||
/* If there is no driver handler to take the TXB, dont' bother
|
||||
* creating it... */
|
||||
if (!ieee->hard_start_xmit) {
|
||||
@ -572,32 +576,41 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (unlikely(len < 24)) {
|
||||
if (unlikely(total_len < 24)) {
|
||||
printk(KERN_WARNING "%s: skb too small (%d).\n",
|
||||
ieee->dev->name, len);
|
||||
ieee->dev->name, total_len);
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (encrypt_mpdu)
|
||||
frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
|
||||
/* When we allocate the TXB we allocate enough space for the reserve
|
||||
* and full fragment bytes (bytes_per_frag doesn't include prefix,
|
||||
* postfix, header, FCS, etc.) */
|
||||
txb = ieee80211_alloc_txb(1, len, ieee->tx_headroom, GFP_ATOMIC);
|
||||
txb = ieee80211_alloc_txb(1, total_len, ieee->tx_headroom, GFP_ATOMIC);
|
||||
if (unlikely(!txb)) {
|
||||
printk(KERN_WARNING "%s: Could not allocate TXB\n",
|
||||
ieee->dev->name);
|
||||
goto failed;
|
||||
}
|
||||
txb->encrypted = 0;
|
||||
txb->payload_size = len;
|
||||
txb->payload_size = total_len;
|
||||
|
||||
skb_frag = txb->fragments[0];
|
||||
|
||||
memcpy(skb_put(skb_frag, len), frame, len);
|
||||
memcpy(skb_put(skb_frag, total_len), frame, total_len);
|
||||
|
||||
if (ieee->config &
|
||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
||||
skb_put(skb_frag, 4);
|
||||
|
||||
/* To avoid overcomplicating things, we do the corner-case frame
|
||||
* encryption in software. The only real situation where encryption is
|
||||
* needed here is during software-based shared key authentication. */
|
||||
if (encrypt_mpdu)
|
||||
ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
|
||||
|
||||
success:
|
||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
||||
|
||||
|
@ -2,6 +2,7 @@ config IEEE80211_SOFTMAC
|
||||
tristate "Software MAC add-on to the IEEE 802.11 networking stack"
|
||||
depends on IEEE80211 && EXPERIMENTAL
|
||||
select WIRELESS_EXT
|
||||
select IEEE80211_CRYPT_WEP
|
||||
---help---
|
||||
This option enables the hardware independent software MAC addon
|
||||
for the IEEE 802.11 networking stack.
|
||||
|
@ -164,12 +164,28 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211softmac_assoc_notify(struct net_device *dev, void *context)
|
||||
ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
|
||||
{
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
ieee80211softmac_assoc_work((void*)mac);
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void *context)
|
||||
{
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
|
||||
switch (event_type) {
|
||||
case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
|
||||
ieee80211softmac_assoc_work((void*)mac);
|
||||
break;
|
||||
case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
|
||||
case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
|
||||
ieee80211softmac_disassoc(mac);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called to handle userspace requests (asynchronously) */
|
||||
void
|
||||
ieee80211softmac_assoc_work(void *d)
|
||||
@ -249,7 +265,7 @@ ieee80211softmac_assoc_work(void *d)
|
||||
* Maybe we can hope to have more memory after scanning finishes ;)
|
||||
*/
|
||||
dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
|
||||
ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify, NULL);
|
||||
ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
|
||||
if (ieee80211softmac_start_scan(mac))
|
||||
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
|
||||
return;
|
||||
@ -284,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
|
||||
* otherwise adding the notification would be racy. */
|
||||
if (!ieee80211softmac_auth_req(mac, found)) {
|
||||
dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
|
||||
ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify, NULL, GFP_KERNEL);
|
||||
ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
|
||||
} else {
|
||||
printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
|
||||
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
|
||||
|
@ -107,6 +107,7 @@ ieee80211softmac_auth_queue(void *data)
|
||||
printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid));
|
||||
/* Remove this item from the queue */
|
||||
spin_lock_irqsave(&mac->lock, flags);
|
||||
net->authenticating = 0;
|
||||
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
|
||||
cancel_delayed_work(&auth->work); /* just to make sure... */
|
||||
list_del(&auth->list);
|
||||
@ -212,13 +213,13 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
|
||||
aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
|
||||
spin_unlock_irqrestore(&mac->lock, flags);
|
||||
|
||||
/* Switch to correct channel for this network */
|
||||
mac->set_channel(mac->dev, net->channel);
|
||||
|
||||
/* Send our response (How to encrypt?) */
|
||||
/* Send our response */
|
||||
ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
|
||||
break;
|
||||
return 0;
|
||||
case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
|
||||
kfree(net->challenge);
|
||||
net->challenge = NULL;
|
||||
net->challenge_len = 0;
|
||||
/* Check the status code of the response */
|
||||
switch(auth->status) {
|
||||
case WLAN_STATUS_SUCCESS:
|
||||
@ -229,6 +230,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
|
||||
spin_unlock_irqrestore(&mac->lock, flags);
|
||||
printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n",
|
||||
MAC_ARG(net->bssid));
|
||||
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
|
||||
break;
|
||||
default:
|
||||
printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n",
|
||||
|
@ -78,7 +78,7 @@ ieee80211softmac_notify_callback(void *d)
|
||||
struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d;
|
||||
kfree(d);
|
||||
|
||||
event.fun(event.mac->dev, event.context);
|
||||
event.fun(event.mac->dev, event.event_type, event.context);
|
||||
}
|
||||
|
||||
int
|
||||
@ -167,6 +167,9 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve
|
||||
if ((eventptr->event_type == event || eventptr->event_type == -1)
|
||||
&& (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
|
||||
list_del(&eventptr->list);
|
||||
/* User may have subscribed to ANY event, so
|
||||
* we tell them which event triggered it. */
|
||||
eventptr->event_type = event;
|
||||
schedule_work(&eventptr->work);
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +149,56 @@ ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
|
||||
* shouldn't the sequence number be in ieee80211? */
|
||||
}
|
||||
|
||||
static u16
|
||||
ieee80211softmac_capabilities(struct ieee80211softmac_device *mac,
|
||||
struct ieee80211softmac_network *net)
|
||||
{
|
||||
u16 capability = 0;
|
||||
|
||||
/* ESS and IBSS bits are set according to the current mode */
|
||||
switch (mac->ieee->iw_mode) {
|
||||
case IW_MODE_INFRA:
|
||||
capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
|
||||
break;
|
||||
case IW_MODE_ADHOC:
|
||||
capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
|
||||
break;
|
||||
case IW_MODE_AUTO:
|
||||
capability = net->capabilities &
|
||||
(WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
|
||||
break;
|
||||
default:
|
||||
/* bleh. we don't ever go to these modes */
|
||||
printk(KERN_ERR PFX "invalid iw_mode!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* CF Pollable / CF Poll Request */
|
||||
/* Needs to be implemented, for now, the 0's == not supported */
|
||||
|
||||
/* Privacy Bit */
|
||||
capability |= mac->ieee->sec.level ?
|
||||
cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
|
||||
|
||||
/* Short Preamble */
|
||||
/* Always supported: we probably won't ever be powering devices which
|
||||
* dont support this... */
|
||||
capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
|
||||
|
||||
/* PBCC */
|
||||
/* Not widely used */
|
||||
|
||||
/* Channel Agility */
|
||||
/* Not widely used */
|
||||
|
||||
/* Short Slot */
|
||||
/* Will be implemented later */
|
||||
|
||||
/* DSSS-OFDM */
|
||||
/* Not widely used */
|
||||
|
||||
return capability;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Create Management packets
|
||||
@ -179,27 +229,6 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
|
||||
return 0;
|
||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
|
||||
|
||||
/* Fill in capability Info */
|
||||
switch (mac->ieee->iw_mode) {
|
||||
case IW_MODE_INFRA:
|
||||
(*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
|
||||
break;
|
||||
case IW_MODE_ADHOC:
|
||||
(*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
|
||||
break;
|
||||
case IW_MODE_AUTO:
|
||||
(*pkt)->capability = net->capabilities & (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
|
||||
break;
|
||||
default:
|
||||
/* bleh. we don't ever go to these modes */
|
||||
printk(KERN_ERR PFX "invalid iw_mode!\n");
|
||||
break;
|
||||
}
|
||||
/* Need to add this
|
||||
(*pkt)->capability |= mac->ieee->short_slot ?
|
||||
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
|
||||
*/
|
||||
(*pkt)->capability |= mac->ieee->sec.level ? cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
|
||||
/* Fill in Listen Interval (?) */
|
||||
(*pkt)->listen_interval = cpu_to_le16(10);
|
||||
|
||||
@ -239,17 +268,9 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
|
||||
return 0;
|
||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
|
||||
|
||||
/* Fill in capability Info */
|
||||
(*pkt)->capability = mac->ieee->iw_mode == IW_MODE_MASTER ?
|
||||
cpu_to_le16(WLAN_CAPABILITY_ESS) :
|
||||
cpu_to_le16(WLAN_CAPABILITY_IBSS);
|
||||
/*
|
||||
(*pkt)->capability |= mac->ieee->short_slot ?
|
||||
cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
|
||||
*/
|
||||
(*pkt)->capability |= mac->ieee->sec.level ?
|
||||
cpu_to_le16(WLAN_CAPABILITY_PRIVACY) : 0;
|
||||
|
||||
/* Fill in the capabilities */
|
||||
(*pkt)->capability = ieee80211softmac_capabilities(mac, net);
|
||||
|
||||
/* Fill in Listen Interval (?) */
|
||||
(*pkt)->listen_interval = cpu_to_le16(10);
|
||||
/* Fill in the current AP MAC */
|
||||
@ -268,26 +289,27 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
|
||||
static u32
|
||||
ieee80211softmac_auth(struct ieee80211_auth **pkt,
|
||||
struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
|
||||
u16 transaction, u16 status)
|
||||
u16 transaction, u16 status, int *encrypt_mpdu)
|
||||
{
|
||||
u8 *data;
|
||||
int auth_mode = mac->ieee->sec.auth_mode;
|
||||
int is_shared_response = (auth_mode == WLAN_AUTH_SHARED_KEY
|
||||
&& transaction == IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE);
|
||||
|
||||
/* Allocate Packet */
|
||||
(*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
|
||||
2 + /* Auth Algorithm */
|
||||
2 + /* Auth Transaction Seq */
|
||||
2 + /* Status Code */
|
||||
/* Challenge Text IE */
|
||||
mac->ieee->open_wep ? 0 :
|
||||
1 + 1 + WLAN_AUTH_CHALLENGE_LEN
|
||||
);
|
||||
is_shared_response ? 0 : 1 + 1 + net->challenge_len
|
||||
);
|
||||
if (unlikely((*pkt) == NULL))
|
||||
return 0;
|
||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
|
||||
|
||||
/* Algorithm */
|
||||
(*pkt)->algorithm = mac->ieee->open_wep ?
|
||||
cpu_to_le16(WLAN_AUTH_OPEN) :
|
||||
cpu_to_le16(WLAN_AUTH_SHARED_KEY);
|
||||
(*pkt)->algorithm = cpu_to_le16(auth_mode);
|
||||
/* Transaction */
|
||||
(*pkt)->transaction = cpu_to_le16(transaction);
|
||||
/* Status */
|
||||
@ -295,18 +317,20 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
|
||||
|
||||
data = (u8 *)(*pkt)->info_element;
|
||||
/* Challenge Text */
|
||||
if(!mac->ieee->open_wep){
|
||||
if (is_shared_response) {
|
||||
*data = MFIE_TYPE_CHALLENGE;
|
||||
data++;
|
||||
|
||||
/* Copy the challenge in */
|
||||
// *data = challenge length
|
||||
// data += sizeof(u16);
|
||||
// memcpy(data, challenge, challenge length);
|
||||
// data += challenge length;
|
||||
|
||||
/* Add the full size to the packet length */
|
||||
}
|
||||
*data = net->challenge_len;
|
||||
data++;
|
||||
memcpy(data, net->challenge, net->challenge_len);
|
||||
data += net->challenge_len;
|
||||
|
||||
/* Make sure this frame gets encrypted with the shared key */
|
||||
*encrypt_mpdu = 1;
|
||||
} else
|
||||
*encrypt_mpdu = 0;
|
||||
|
||||
/* Return the packet size */
|
||||
return (data - (u8 *)(*pkt));
|
||||
@ -396,6 +420,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
|
||||
{
|
||||
void *pkt = NULL;
|
||||
u32 pkt_size = 0;
|
||||
int encrypt_mpdu = 0;
|
||||
|
||||
switch(type) {
|
||||
case IEEE80211_STYPE_ASSOC_REQ:
|
||||
@ -405,7 +430,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
|
||||
pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
|
||||
break;
|
||||
case IEEE80211_STYPE_AUTH:
|
||||
pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16));
|
||||
pkt_size = ieee80211softmac_auth((struct ieee80211_auth **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg, (u16)(arg & 0xFFFF), (u16) (arg >> 16), &encrypt_mpdu);
|
||||
break;
|
||||
case IEEE80211_STYPE_DISASSOC:
|
||||
case IEEE80211_STYPE_DEAUTH:
|
||||
@ -434,52 +459,8 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
|
||||
* or get rid of it alltogether?
|
||||
* Does this work for you now?
|
||||
*/
|
||||
ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt, pkt_size);
|
||||
|
||||
kfree(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create an rts/cts frame */
|
||||
static u32
|
||||
ieee80211softmac_rts_cts(struct ieee80211_hdr_2addr **pkt,
|
||||
struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
|
||||
u32 type)
|
||||
{
|
||||
/* Allocate Packet */
|
||||
(*pkt) = kmalloc(IEEE80211_2ADDR_LEN, GFP_ATOMIC);
|
||||
memset(*pkt, 0, IEEE80211_2ADDR_LEN);
|
||||
if((*pkt) == NULL)
|
||||
return 0;
|
||||
ieee80211softmac_hdr_2addr(mac, (*pkt), type, net->bssid);
|
||||
return IEEE80211_2ADDR_LEN;
|
||||
}
|
||||
|
||||
|
||||
/* Sends a control packet */
|
||||
static int
|
||||
ieee80211softmac_send_ctl_frame(struct ieee80211softmac_device *mac,
|
||||
struct ieee80211softmac_network *net, u32 type, u32 arg)
|
||||
{
|
||||
void *pkt = NULL;
|
||||
u32 pkt_size = 0;
|
||||
|
||||
switch(type) {
|
||||
case IEEE80211_STYPE_RTS:
|
||||
case IEEE80211_STYPE_CTS:
|
||||
pkt_size = ieee80211softmac_rts_cts((struct ieee80211_hdr_2addr **)(&pkt), mac, net, type);
|
||||
break;
|
||||
default:
|
||||
printkl(KERN_DEBUG PFX "Unsupported Control Frame type: %i\n", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(pkt_size == 0)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Send the packet to the ieee80211 layer for tx */
|
||||
ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *) pkt, pkt_size);
|
||||
ieee80211_tx_frame(mac->ieee, (struct ieee80211_hdr *)pkt,
|
||||
IEEE80211_3ADDR_LEN, pkt_size, encrypt_mpdu);
|
||||
|
||||
kfree(pkt);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user