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
|
say M here and read <file:Documentation/modules.txt>. The module
|
||||||
will be called prism54.ko.
|
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/hostap/Kconfig"
|
||||||
source "drivers/net/wireless/bcm43xx/Kconfig"
|
source "drivers/net/wireless/bcm43xx/Kconfig"
|
||||||
|
|
||||||
|
|
|
@ -40,3 +40,5 @@ obj-$(CONFIG_BCM43XX) += bcm43xx/
|
||||||
# 16-bit wireless PCMCIA client drivers
|
# 16-bit wireless PCMCIA client drivers
|
||||||
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
|
||||||
obj-$(CONFIG_PCMCIA_WL3501) += wl3501_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;
|
unsigned long flags;
|
||||||
int keyidx;
|
int keyidx;
|
||||||
|
|
||||||
dprintk(KERN_INFO PFX "set security called\n");
|
dprintk(KERN_INFO PFX "set security called");
|
||||||
|
|
||||||
bcm43xx_lock_mmio(bcm, flags);
|
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) {
|
if (sec->flags & SEC_ACTIVE_KEY) {
|
||||||
secinfo->active_key = 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) {
|
if (sec->flags & SEC_UNICAST_GROUP) {
|
||||||
secinfo->unicast_uses_group = sec->unicast_uses_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) {
|
if (sec->flags & SEC_LEVEL) {
|
||||||
secinfo->level = 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) {
|
if (sec->flags & SEC_ENABLED) {
|
||||||
secinfo->enabled = 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) {
|
if (sec->flags & SEC_ENCRYPT) {
|
||||||
secinfo->encrypt = 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 (bcm->initialized && !bcm->ieee->host_encrypt) {
|
||||||
if (secinfo->enabled) {
|
if (secinfo->enabled) {
|
||||||
/* upload WEP keys to hardware */
|
/* 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"
|
#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)
|
static int zd1201_fw_upload(struct usb_device *dev, int apfw)
|
||||||
{
|
{
|
||||||
const struct firmware *fw_entry;
|
const struct firmware *fw_entry;
|
||||||
char* data;
|
char *data;
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
int err;
|
int err;
|
||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
|
@ -65,7 +65,7 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw)
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
|
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, "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;
|
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);
|
USB_DIR_OUT | 0x40, 0, 0, NULL, 0, ZD1201_FW_TIMEOUT);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
|
err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4,
|
||||||
USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
|
USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (ret & 0x80) {
|
if (ret & 0x80) {
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -166,13 +166,13 @@ static int zd1201_docmd(struct zd1201 *zd, int cmd, int parm0,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
usb_fill_bulk_urb(urb, zd->usb, usb_sndbulkpipe(zd->usb, zd->endp_out2),
|
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);
|
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(command);
|
kfree(command);
|
||||||
usb_free_urb(urb);
|
usb_free_urb(urb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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]);
|
fc = le16_to_cpu(*(__le16 *)&data[datalen-16]);
|
||||||
seq = le16_to_cpu(*(__le16 *)&data[datalen-24]);
|
seq = le16_to_cpu(*(__le16 *)&data[datalen-24]);
|
||||||
|
|
||||||
if(zd->monitor) {
|
if (zd->monitor) {
|
||||||
if (datalen < 24)
|
if (datalen < 24)
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
if (!(skb = dev_alloc_skb(datalen+24)))
|
if (!(skb = dev_alloc_skb(datalen+24)))
|
||||||
|
@ -364,7 +364,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
}
|
}
|
||||||
hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
|
hlist_for_each_entry(frag, node, &zd->fraglist, fnode)
|
||||||
if(frag->seq == (seq&IEEE80211_SCTL_SEQ))
|
if (frag->seq == (seq&IEEE80211_SCTL_SEQ))
|
||||||
break;
|
break;
|
||||||
if (!frag)
|
if (!frag)
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
|
@ -376,7 +376,6 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs)
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
hlist_del_init(&frag->fnode);
|
hlist_del_init(&frag->fnode);
|
||||||
kfree(frag);
|
kfree(frag);
|
||||||
/* Fallthrough */
|
|
||||||
} else {
|
} else {
|
||||||
if (datalen<14)
|
if (datalen<14)
|
||||||
goto resubmit;
|
goto resubmit;
|
||||||
|
@ -422,7 +421,7 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
|
||||||
int rid_fid;
|
int rid_fid;
|
||||||
int length;
|
int length;
|
||||||
unsigned char *pdata;
|
unsigned char *pdata;
|
||||||
|
|
||||||
zd->rxdatas = 0;
|
zd->rxdatas = 0;
|
||||||
err = zd1201_docmd(zd, ZD1201_CMDCODE_ACCESS, rid, 0, 0);
|
err = zd1201_docmd(zd, ZD1201_CMDCODE_ACCESS, rid, 0, 0);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -471,11 +470,11 @@ static int zd1201_getconfig(struct zd1201 *zd, int rid, void *riddata,
|
||||||
length = zd->rxlen;
|
length = zd->rxlen;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int actual_length;
|
int actual_length;
|
||||||
|
|
||||||
actual_length = (length > 64) ? 64 : 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",
|
dev_dbg(&zd->usb->dev, "Rx Resource packet type error: %02X\n",
|
||||||
pdata[0]);
|
pdata[0]);
|
||||||
return -EINVAL;
|
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) */
|
/* Skip the 4 bytes header (RID length and RID) */
|
||||||
if(i == 0) {
|
if (i == 0) {
|
||||||
pdata += 8;
|
pdata += 8;
|
||||||
actual_length -= 8;
|
actual_length -= 8;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pdata += 4;
|
pdata += 4;
|
||||||
actual_length -= 4;
|
actual_length -= 4;
|
||||||
}
|
}
|
||||||
|
@ -620,7 +618,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
|
||||||
short max;
|
short max;
|
||||||
__le16 zdmax;
|
__le16 zdmax;
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
|
|
||||||
buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL);
|
buffer = kzalloc(ZD1201_RXSIZE, GFP_KERNEL);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -632,7 +630,7 @@ static int zd1201_drvr_start(struct zd1201 *zd)
|
||||||
err = usb_submit_urb(zd->rx_urb, GFP_KERNEL);
|
err = usb_submit_urb(zd->rx_urb, GFP_KERNEL);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_buffer;
|
goto err_buffer;
|
||||||
|
|
||||||
err = zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
err = zd1201_docmd(zd, ZD1201_CMDCODE_INIT, 0, 0, 0);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_urb;
|
goto err_urb;
|
||||||
|
@ -684,7 +682,7 @@ static int zd1201_enable(struct zd1201 *zd)
|
||||||
static int zd1201_disable(struct zd1201 *zd)
|
static int zd1201_disable(struct zd1201 *zd)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!zd->mac_enabled)
|
if (!zd->mac_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
if (zd->monitor) {
|
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)
|
static int zd1201_net_stop(struct net_device *dev)
|
||||||
{
|
{
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -915,7 +912,6 @@ static int zd1201_get_name(struct net_device *dev,
|
||||||
struct iw_request_info *info, char *name, char *extra)
|
struct iw_request_info *info, char *name, char *extra)
|
||||||
{
|
{
|
||||||
strcpy(name, "IEEE 802.11b");
|
strcpy(name, "IEEE 802.11b");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,11 +1009,10 @@ static int zd1201_set_mode(struct net_device *dev,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
zd->monitor=monitor;
|
zd->monitor = monitor;
|
||||||
/* If monitor mode is set we don't actually turn it on here since it
|
/* 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).
|
* is done during mac reset anyway (see zd1201_mac_enable).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
zd1201_mac_reset(zd);
|
zd1201_mac_reset(zd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1117,7 +1112,7 @@ static int zd1201_get_wap(struct net_device *dev,
|
||||||
zd->iwstats.qual.updated = 2;
|
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,
|
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 */
|
if (!rrq->fixed) { /* Also enable all lower bitrates */
|
||||||
rate |= rate-1;
|
rate |= rate-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);
|
err = zd1201_setconfig16(zd, ZD1201_RID_TXRATECNTL, rate);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1486,7 +1481,7 @@ static int zd1201_get_encode(struct net_device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
erq->flags |= i+1;
|
erq->flags |= i+1;
|
||||||
|
|
||||||
erq->length = zd->encode_keylen[i];
|
erq->length = zd->encode_keylen[i];
|
||||||
memcpy(key, zd->encode_keys[i], erq->length);
|
memcpy(key, zd->encode_keys[i], erq->length);
|
||||||
|
|
||||||
|
@ -1529,11 +1524,7 @@ static int zd1201_set_power(struct net_device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
|
return zd1201_setconfig16(zd, ZD1201_RID_CNFPMENABLED, enabled);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zd1201_get_power(struct net_device *dev,
|
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 iw_request_info *info, struct iw_param *rrq, char *extra)
|
||||||
{
|
{
|
||||||
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
struct zd1201 *zd = (struct zd1201 *)dev->priv;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!zd->ap)
|
if (!zd->ap)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
err = zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
|
return zd1201_setconfig16(zd, ZD1201_RID_CNFHOSTAUTH, rrq->value);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zd1201_get_hostauth(struct net_device *dev,
|
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 zd1201 *zd;
|
||||||
struct usb_device *usb;
|
struct usb_device *usb;
|
||||||
int i, err;
|
int err;
|
||||||
short porttype;
|
short porttype;
|
||||||
char buf[IW_ESSID_MAX_SIZE+2];
|
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)
|
if (!zd->rx_urb || !zd->tx_urb)
|
||||||
goto err_zd;
|
goto err_zd;
|
||||||
|
|
||||||
for(i = 0; i<100; i++)
|
mdelay(100);
|
||||||
udelay(1000);
|
|
||||||
|
|
||||||
err = zd1201_drvr_start(zd);
|
err = zd1201_drvr_start(zd);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_zd;
|
goto err_zd;
|
||||||
|
@ -1833,7 +1818,7 @@ static int zd1201_probe(struct usb_interface *interface,
|
||||||
goto err_net;
|
goto err_net;
|
||||||
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
dev_info(&usb->dev, "%s: ZD1201 USB Wireless interface\n",
|
||||||
zd->dev->name);
|
zd->dev->name);
|
||||||
|
|
||||||
usb_set_intfdata(interface, zd);
|
usb_set_intfdata(interface, zd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -301,21 +301,4 @@ config USB_NET_ZAURUS
|
||||||
some cases CDC MDLM) protocol, not "g_ether".
|
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
|
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_CDC_SUBSET) += cdc_subset.o
|
||||||
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
|
obj-$(CONFIG_USB_NET_ZAURUS) += zaurus.o
|
||||||
obj-$(CONFIG_USB_USBNET) += usbnet.o
|
obj-$(CONFIG_USB_USBNET) += usbnet.o
|
||||||
obj-$(CONFIG_USB_ZD1201) += zd1201.o
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_USB_DEBUG),y)
|
ifeq ($(CONFIG_USB_DEBUG),y)
|
||||||
EXTRA_CFLAGS += -DDEBUG
|
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 int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||||
extern void ieee80211_txb_free(struct ieee80211_txb *);
|
extern void ieee80211_txb_free(struct ieee80211_txb *);
|
||||||
extern int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
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 */
|
/* ieee80211_rx.c */
|
||||||
extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
|
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
|
* - context set to the context data you want passed
|
||||||
* The return value is 0, or an error.
|
* 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(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);
|
#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
|
/* Incoming 802.11 strucure is converted to a TXB
|
||||||
* a block of 802.11 fragment packets (stored as skbs) */
|
* a block of 802.11 fragment packets (stored as skbs) */
|
||||||
int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
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;
|
struct ieee80211_txb *txb = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -565,6 +566,9 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||||
|
|
||||||
spin_lock_irqsave(&ieee->lock, flags);
|
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
|
/* If there is no driver handler to take the TXB, dont' bother
|
||||||
* creating it... */
|
* creating it... */
|
||||||
if (!ieee->hard_start_xmit) {
|
if (!ieee->hard_start_xmit) {
|
||||||
|
@ -572,32 +576,41 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
|
||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(len < 24)) {
|
if (unlikely(total_len < 24)) {
|
||||||
printk(KERN_WARNING "%s: skb too small (%d).\n",
|
printk(KERN_WARNING "%s: skb too small (%d).\n",
|
||||||
ieee->dev->name, len);
|
ieee->dev->name, total_len);
|
||||||
goto success;
|
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
|
/* When we allocate the TXB we allocate enough space for the reserve
|
||||||
* and full fragment bytes (bytes_per_frag doesn't include prefix,
|
* and full fragment bytes (bytes_per_frag doesn't include prefix,
|
||||||
* postfix, header, FCS, etc.) */
|
* 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)) {
|
if (unlikely(!txb)) {
|
||||||
printk(KERN_WARNING "%s: Could not allocate TXB\n",
|
printk(KERN_WARNING "%s: Could not allocate TXB\n",
|
||||||
ieee->dev->name);
|
ieee->dev->name);
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
txb->encrypted = 0;
|
txb->encrypted = 0;
|
||||||
txb->payload_size = len;
|
txb->payload_size = total_len;
|
||||||
|
|
||||||
skb_frag = txb->fragments[0];
|
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 &
|
if (ieee->config &
|
||||||
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
(CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
|
||||||
skb_put(skb_frag, 4);
|
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:
|
success:
|
||||||
spin_unlock_irqrestore(&ieee->lock, flags);
|
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"
|
tristate "Software MAC add-on to the IEEE 802.11 networking stack"
|
||||||
depends on IEEE80211 && EXPERIMENTAL
|
depends on IEEE80211 && EXPERIMENTAL
|
||||||
select WIRELESS_EXT
|
select WIRELESS_EXT
|
||||||
|
select IEEE80211_CRYPT_WEP
|
||||||
---help---
|
---help---
|
||||||
This option enables the hardware independent software MAC addon
|
This option enables the hardware independent software MAC addon
|
||||||
for the IEEE 802.11 networking stack.
|
for the IEEE 802.11 networking stack.
|
||||||
|
|
|
@ -164,12 +164,28 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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);
|
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||||
ieee80211softmac_assoc_work((void*)mac);
|
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) */
|
/* This function is called to handle userspace requests (asynchronously) */
|
||||||
void
|
void
|
||||||
ieee80211softmac_assoc_work(void *d)
|
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 ;)
|
* Maybe we can hope to have more memory after scanning finishes ;)
|
||||||
*/
|
*/
|
||||||
dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
|
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))
|
if (ieee80211softmac_start_scan(mac))
|
||||||
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
|
dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
|
||||||
return;
|
return;
|
||||||
|
@ -284,7 +300,7 @@ ieee80211softmac_assoc_work(void *d)
|
||||||
* otherwise adding the notification would be racy. */
|
* otherwise adding the notification would be racy. */
|
||||||
if (!ieee80211softmac_auth_req(mac, found)) {
|
if (!ieee80211softmac_auth_req(mac, found)) {
|
||||||
dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n");
|
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 {
|
} else {
|
||||||
printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
|
printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
|
||||||
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
|
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));
|
printkl(KERN_WARNING PFX "Authentication timed out with "MAC_FMT"\n", MAC_ARG(net->bssid));
|
||||||
/* Remove this item from the queue */
|
/* Remove this item from the queue */
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
|
net->authenticating = 0;
|
||||||
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
|
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT, net);
|
||||||
cancel_delayed_work(&auth->work); /* just to make sure... */
|
cancel_delayed_work(&auth->work); /* just to make sure... */
|
||||||
list_del(&auth->list);
|
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;
|
aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
|
||||||
spin_unlock_irqrestore(&mac->lock, flags);
|
spin_unlock_irqrestore(&mac->lock, flags);
|
||||||
|
|
||||||
/* Switch to correct channel for this network */
|
/* Send our response */
|
||||||
mac->set_channel(mac->dev, net->channel);
|
|
||||||
|
|
||||||
/* Send our response (How to encrypt?) */
|
|
||||||
ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
|
ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
|
||||||
break;
|
return 0;
|
||||||
case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
|
case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
|
||||||
|
kfree(net->challenge);
|
||||||
|
net->challenge = NULL;
|
||||||
|
net->challenge_len = 0;
|
||||||
/* Check the status code of the response */
|
/* Check the status code of the response */
|
||||||
switch(auth->status) {
|
switch(auth->status) {
|
||||||
case WLAN_STATUS_SUCCESS:
|
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);
|
spin_unlock_irqrestore(&mac->lock, flags);
|
||||||
printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n",
|
printkl(KERN_NOTICE PFX "Shared Key Authentication completed with "MAC_FMT"\n",
|
||||||
MAC_ARG(net->bssid));
|
MAC_ARG(net->bssid));
|
||||||
|
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_AUTHENTICATED, net);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printkl(KERN_NOTICE PFX "Shared Key Authentication with "MAC_FMT" failed, error code: %i\n",
|
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;
|
struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d;
|
||||||
kfree(d);
|
kfree(d);
|
||||||
|
|
||||||
event.fun(event.mac->dev, event.context);
|
event.fun(event.mac->dev, event.event_type, event.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -167,6 +167,9 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve
|
||||||
if ((eventptr->event_type == event || eventptr->event_type == -1)
|
if ((eventptr->event_type == event || eventptr->event_type == -1)
|
||||||
&& (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
|
&& (eventptr->event_context == NULL || eventptr->event_context == event_ctx)) {
|
||||||
list_del(&eventptr->list);
|
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);
|
schedule_work(&eventptr->work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,56 @@ ieee80211softmac_hdr_3addr(struct ieee80211softmac_device *mac,
|
||||||
* shouldn't the sequence number be in ieee80211? */
|
* 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
|
* Create Management packets
|
||||||
|
@ -179,27 +229,6 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
|
||||||
return 0;
|
return 0;
|
||||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
|
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 (?) */
|
/* Fill in Listen Interval (?) */
|
||||||
(*pkt)->listen_interval = cpu_to_le16(10);
|
(*pkt)->listen_interval = cpu_to_le16(10);
|
||||||
|
|
||||||
|
@ -239,17 +268,9 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
|
||||||
return 0;
|
return 0;
|
||||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
|
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_REASSOC_REQ, net->bssid, net->bssid);
|
||||||
|
|
||||||
/* Fill in capability Info */
|
/* Fill in the capabilities */
|
||||||
(*pkt)->capability = mac->ieee->iw_mode == IW_MODE_MASTER ?
|
(*pkt)->capability = ieee80211softmac_capabilities(mac, net);
|
||||||
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 Listen Interval (?) */
|
/* Fill in Listen Interval (?) */
|
||||||
(*pkt)->listen_interval = cpu_to_le16(10);
|
(*pkt)->listen_interval = cpu_to_le16(10);
|
||||||
/* Fill in the current AP MAC */
|
/* Fill in the current AP MAC */
|
||||||
|
@ -268,26 +289,27 @@ ieee80211softmac_reassoc_req(struct ieee80211_reassoc_request **pkt,
|
||||||
static u32
|
static u32
|
||||||
ieee80211softmac_auth(struct ieee80211_auth **pkt,
|
ieee80211softmac_auth(struct ieee80211_auth **pkt,
|
||||||
struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
|
struct ieee80211softmac_device *mac, struct ieee80211softmac_network *net,
|
||||||
u16 transaction, u16 status)
|
u16 transaction, u16 status, int *encrypt_mpdu)
|
||||||
{
|
{
|
||||||
u8 *data;
|
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 */
|
/* Allocate Packet */
|
||||||
(*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
|
(*pkt) = (struct ieee80211_auth *)ieee80211softmac_alloc_mgt(
|
||||||
2 + /* Auth Algorithm */
|
2 + /* Auth Algorithm */
|
||||||
2 + /* Auth Transaction Seq */
|
2 + /* Auth Transaction Seq */
|
||||||
2 + /* Status Code */
|
2 + /* Status Code */
|
||||||
/* Challenge Text IE */
|
/* Challenge Text IE */
|
||||||
mac->ieee->open_wep ? 0 :
|
is_shared_response ? 0 : 1 + 1 + net->challenge_len
|
||||||
1 + 1 + WLAN_AUTH_CHALLENGE_LEN
|
);
|
||||||
);
|
|
||||||
if (unlikely((*pkt) == NULL))
|
if (unlikely((*pkt) == NULL))
|
||||||
return 0;
|
return 0;
|
||||||
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
|
ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_AUTH, net->bssid, net->bssid);
|
||||||
|
|
||||||
/* Algorithm */
|
/* Algorithm */
|
||||||
(*pkt)->algorithm = mac->ieee->open_wep ?
|
(*pkt)->algorithm = cpu_to_le16(auth_mode);
|
||||||
cpu_to_le16(WLAN_AUTH_OPEN) :
|
|
||||||
cpu_to_le16(WLAN_AUTH_SHARED_KEY);
|
|
||||||
/* Transaction */
|
/* Transaction */
|
||||||
(*pkt)->transaction = cpu_to_le16(transaction);
|
(*pkt)->transaction = cpu_to_le16(transaction);
|
||||||
/* Status */
|
/* Status */
|
||||||
|
@ -295,18 +317,20 @@ ieee80211softmac_auth(struct ieee80211_auth **pkt,
|
||||||
|
|
||||||
data = (u8 *)(*pkt)->info_element;
|
data = (u8 *)(*pkt)->info_element;
|
||||||
/* Challenge Text */
|
/* Challenge Text */
|
||||||
if(!mac->ieee->open_wep){
|
if (is_shared_response) {
|
||||||
*data = MFIE_TYPE_CHALLENGE;
|
*data = MFIE_TYPE_CHALLENGE;
|
||||||
data++;
|
data++;
|
||||||
|
|
||||||
/* Copy the challenge in */
|
/* Copy the challenge in */
|
||||||
// *data = challenge length
|
*data = net->challenge_len;
|
||||||
// data += sizeof(u16);
|
data++;
|
||||||
// memcpy(data, challenge, challenge length);
|
memcpy(data, net->challenge, net->challenge_len);
|
||||||
// data += challenge length;
|
data += net->challenge_len;
|
||||||
|
|
||||||
/* Add the full size to the packet length */
|
/* Make sure this frame gets encrypted with the shared key */
|
||||||
}
|
*encrypt_mpdu = 1;
|
||||||
|
} else
|
||||||
|
*encrypt_mpdu = 0;
|
||||||
|
|
||||||
/* Return the packet size */
|
/* Return the packet size */
|
||||||
return (data - (u8 *)(*pkt));
|
return (data - (u8 *)(*pkt));
|
||||||
|
@ -396,6 +420,7 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
|
||||||
{
|
{
|
||||||
void *pkt = NULL;
|
void *pkt = NULL;
|
||||||
u32 pkt_size = 0;
|
u32 pkt_size = 0;
|
||||||
|
int encrypt_mpdu = 0;
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case IEEE80211_STYPE_ASSOC_REQ:
|
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);
|
pkt_size = ieee80211softmac_reassoc_req((struct ieee80211_reassoc_request **)(&pkt), mac, (struct ieee80211softmac_network *)ptrarg);
|
||||||
break;
|
break;
|
||||||
case IEEE80211_STYPE_AUTH:
|
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;
|
break;
|
||||||
case IEEE80211_STYPE_DISASSOC:
|
case IEEE80211_STYPE_DISASSOC:
|
||||||
case IEEE80211_STYPE_DEAUTH:
|
case IEEE80211_STYPE_DEAUTH:
|
||||||
|
@ -434,52 +459,8 @@ ieee80211softmac_send_mgt_frame(struct ieee80211softmac_device *mac,
|
||||||
* or get rid of it alltogether?
|
* or get rid of it alltogether?
|
||||||
* Does this work for you now?
|
* Does this work for you now?
|
||||||
*/
|
*/
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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);
|
|
||||||
|
|
||||||
kfree(pkt);
|
kfree(pkt);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue