mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +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
db21e578e5
@ -2768,7 +2768,7 @@ static int airo_test_wpa_capable(struct airo_info *ai)
|
||||
|
||||
/* Only firmware versions 5.30.17 or better can do WPA */
|
||||
if ((cap_rid.softVer > 0x530)
|
||||
|| ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 0x17))) {
|
||||
|| ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) {
|
||||
airo_print_info(name, "WPA is supported.");
|
||||
return 1;
|
||||
}
|
||||
|
@ -128,13 +128,15 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
|
||||
static struct pci_device_id bcm43xx_pci_tbl[] = {
|
||||
/* Broadcom 4303 802.11b */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4307 802.11b */
|
||||
/* Broadcom 4307 802.11b */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4318 802.11b/g */
|
||||
/* Broadcom 4318 802.11b/g */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4319 802.11a/b/g */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4306 802.11b/g */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4306 802.11a */
|
||||
/* Broadcom 4306 802.11a */
|
||||
// { PCI_VENDOR_ID_BROADCOM, 0x4321, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
/* Broadcom 4309 802.11a/b/g */
|
||||
{ PCI_VENDOR_ID_BROADCOM, 0x4324, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
|
||||
|
@ -534,5 +534,4 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
|
||||
EXPORT_SYMBOL(hostap_dump_tx_80211);
|
||||
EXPORT_SYMBOL(hostap_master_start_xmit);
|
||||
|
@ -3276,17 +3276,6 @@ EXPORT_SYMBOL(hostap_init_data);
|
||||
EXPORT_SYMBOL(hostap_init_ap_proc);
|
||||
EXPORT_SYMBOL(hostap_free_data);
|
||||
EXPORT_SYMBOL(hostap_check_sta_fw_version);
|
||||
EXPORT_SYMBOL(hostap_handle_sta_tx);
|
||||
EXPORT_SYMBOL(hostap_handle_sta_release);
|
||||
EXPORT_SYMBOL(hostap_handle_sta_tx_exc);
|
||||
EXPORT_SYMBOL(hostap_update_sta_ps);
|
||||
EXPORT_SYMBOL(hostap_handle_sta_rx);
|
||||
EXPORT_SYMBOL(hostap_is_sta_assoc);
|
||||
EXPORT_SYMBOL(hostap_is_sta_authorized);
|
||||
EXPORT_SYMBOL(hostap_add_sta);
|
||||
EXPORT_SYMBOL(hostap_update_rates);
|
||||
EXPORT_SYMBOL(hostap_add_wds_links);
|
||||
EXPORT_SYMBOL(hostap_wds_link_oper);
|
||||
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
|
||||
EXPORT_SYMBOL(hostap_deauth_all_stas);
|
||||
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
|
||||
|
@ -881,6 +881,12 @@ static struct pcmcia_device_id hostap_cs_ids[] = {
|
||||
PCMCIA_DEVICE_PROD_ID12(
|
||||
"ZoomAir 11Mbps High", "Rate wireless Networking",
|
||||
0x273fe3db, 0x32a1eaee),
|
||||
PCMCIA_DEVICE_PROD_ID123(
|
||||
"Pretec", "CompactWLAN Card 802.11b", "2.5",
|
||||
0x1cadd3e5, 0xe697636c, 0x7a5bfcf1),
|
||||
PCMCIA_DEVICE_PROD_ID123(
|
||||
"U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02",
|
||||
0xc7b8df9d, 0x1700d087, 0x4b74baa0),
|
||||
PCMCIA_DEVICE_NULL
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pcmcia, hostap_cs_ids);
|
||||
|
@ -1125,11 +1125,9 @@ EXPORT_SYMBOL(hostap_set_auth_algs);
|
||||
EXPORT_SYMBOL(hostap_dump_rx_header);
|
||||
EXPORT_SYMBOL(hostap_dump_tx_header);
|
||||
EXPORT_SYMBOL(hostap_80211_header_parse);
|
||||
EXPORT_SYMBOL(hostap_80211_prism_header_parse);
|
||||
EXPORT_SYMBOL(hostap_80211_get_hdrlen);
|
||||
EXPORT_SYMBOL(hostap_get_stats);
|
||||
EXPORT_SYMBOL(hostap_setup_dev);
|
||||
EXPORT_SYMBOL(hostap_proc);
|
||||
EXPORT_SYMBOL(hostap_set_multicast_list_queue);
|
||||
EXPORT_SYMBOL(hostap_set_hostapd);
|
||||
EXPORT_SYMBOL(hostap_set_hostapd_sta);
|
||||
|
@ -147,14 +147,11 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
orinoco_cs_release(link);
|
||||
|
||||
DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
|
||||
if (link->dev_node) {
|
||||
DEBUG(0, PFX "About to unregister net device %p\n",
|
||||
dev);
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
free_orinocodev(dev);
|
||||
} /* orinoco_cs_detach */
|
||||
|
||||
@ -346,19 +343,10 @@ orinoco_cs_config(struct pcmcia_device *link)
|
||||
net_device has been registered */
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: index 0x%02x: ",
|
||||
dev->name, link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp / 10,
|
||||
link->conf.Vpp % 10);
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
if (link->io.NumPorts2)
|
||||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
|
||||
"0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
|
||||
link->irq.AssignedIRQ, link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -427,7 +415,6 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
int err = 0;
|
||||
unsigned long flags;
|
||||
|
||||
if (! test_bit(0, &card->hard_reset_in_progress)) {
|
||||
err = orinoco_reinit_firmware(dev);
|
||||
@ -437,7 +424,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
netif_device_attach(dev);
|
||||
priv->hw_unavailable--;
|
||||
@ -449,10 +436,10 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
|
||||
dev->name, err);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock(&priv->lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,7 +206,6 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
|
||||
err = -EBUSY;
|
||||
goto fail_irq;
|
||||
}
|
||||
orinoco_pci_setup_netdev(dev, pdev, 2);
|
||||
|
||||
err = orinoco_nortel_hw_init(card);
|
||||
if (err) {
|
||||
@ -227,6 +226,8 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
|
||||
pci_name(pdev));
|
||||
|
||||
return 0;
|
||||
|
||||
@ -265,7 +266,7 @@ static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev)
|
||||
iowrite16(0, card->bridge_io + 10);
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_orinocodev(dev);
|
||||
pci_iounmap(pdev, priv->hw.iobase);
|
||||
|
@ -161,7 +161,6 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
|
||||
err = -EBUSY;
|
||||
goto fail_irq;
|
||||
}
|
||||
orinoco_pci_setup_netdev(dev, pdev, 0);
|
||||
|
||||
err = orinoco_pci_cor_reset(priv);
|
||||
if (err) {
|
||||
@ -176,6 +175,8 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
|
||||
pci_name(pdev));
|
||||
|
||||
return 0;
|
||||
|
||||
@ -204,7 +205,7 @@ static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_orinocodev(dev);
|
||||
pci_iounmap(pdev, priv->hw.iobase);
|
||||
|
@ -18,32 +18,7 @@ struct orinoco_pci_card {
|
||||
void __iomem *attr_io;
|
||||
};
|
||||
|
||||
/* Set base address or memory range of the network device based on
|
||||
* the PCI device it's using. Specify BAR of the "main" resource.
|
||||
* To be used after request_irq(). */
|
||||
static inline void orinoco_pci_setup_netdev(struct net_device *dev,
|
||||
struct pci_dev *pdev, int bar)
|
||||
{
|
||||
char *range_type;
|
||||
unsigned long start = pci_resource_start(pdev, bar);
|
||||
unsigned long len = pci_resource_len(pdev, bar);
|
||||
unsigned long flags = pci_resource_flags(pdev, bar);
|
||||
unsigned long end = start + len - 1;
|
||||
|
||||
dev->irq = pdev->irq;
|
||||
if (flags & IORESOURCE_IO) {
|
||||
dev->base_addr = start;
|
||||
range_type = "ports";
|
||||
} else {
|
||||
dev->mem_start = start;
|
||||
dev->mem_end = end;
|
||||
range_type = "memory";
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG PFX "%s: irq %d, %s 0x%lx-0x%lx\n",
|
||||
pci_name(pdev), pdev->irq, range_type, start, end);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
@ -121,5 +96,9 @@ static int orinoco_pci_resume(struct pci_dev *pdev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define orinoco_pci_suspend NULL
|
||||
#define orinoco_pci_resume NULL
|
||||
#endif
|
||||
|
||||
#endif /* _ORINOCO_PCI_H */
|
||||
|
@ -245,7 +245,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
|
||||
err = -EBUSY;
|
||||
goto fail_irq;
|
||||
}
|
||||
orinoco_pci_setup_netdev(dev, pdev, 2);
|
||||
|
||||
err = orinoco_plx_hw_init(card);
|
||||
if (err) {
|
||||
@ -266,6 +265,8 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
|
||||
pci_name(pdev));
|
||||
|
||||
return 0;
|
||||
|
||||
@ -301,7 +302,7 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
|
||||
struct orinoco_pci_card *card = priv->card;
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_orinocodev(dev);
|
||||
pci_iounmap(pdev, priv->hw.iobase);
|
||||
|
@ -147,7 +147,6 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
|
||||
err = -EBUSY;
|
||||
goto fail_irq;
|
||||
}
|
||||
orinoco_pci_setup_netdev(dev, pdev, 2);
|
||||
|
||||
err = orinoco_tmd_cor_reset(priv);
|
||||
if (err) {
|
||||
@ -162,6 +161,8 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
|
||||
pci_name(pdev));
|
||||
|
||||
return 0;
|
||||
|
||||
@ -194,7 +195,7 @@ static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
|
||||
struct orinoco_pci_card *card = priv->card;
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
free_irq(pdev->irq, dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_orinocodev(dev);
|
||||
pci_iounmap(pdev, priv->hw.iobase);
|
||||
|
@ -625,14 +625,11 @@ static void spectrum_cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
||||
spectrum_cs_release(link);
|
||||
|
||||
DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
|
||||
if (link->dev_node) {
|
||||
DEBUG(0, PFX "About to unregister net device %p\n",
|
||||
dev);
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
free_orinocodev(dev);
|
||||
} /* spectrum_cs_detach */
|
||||
|
||||
@ -825,19 +822,10 @@ spectrum_cs_config(struct pcmcia_device *link)
|
||||
net_device has been registered */
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: index 0x%02x: ",
|
||||
dev->name, link->conf.ConfigIndex);
|
||||
if (link->conf.Vpp)
|
||||
printk(", Vpp %d.%d", link->conf.Vpp / 10,
|
||||
link->conf.Vpp % 10);
|
||||
printk(", irq %d", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
if (link->io.NumPorts2)
|
||||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
|
||||
"0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
|
||||
link->irq.AssignedIRQ, link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -878,11 +866,10 @@ spectrum_cs_suspend(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct orinoco_private *priv = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
int err = 0;
|
||||
|
||||
/* Mark the device as stopped, to block IO until later */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
err = __orinoco_down(dev);
|
||||
if (err)
|
||||
@ -892,9 +879,9 @@ spectrum_cs_suspend(struct pcmcia_device *link)
|
||||
netif_device_detach(dev);
|
||||
priv->hw_unavailable++;
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -86,6 +86,9 @@ struct ieee80211softmac_assoc_info {
|
||||
|
||||
/* BSSID we're trying to associate to */
|
||||
char bssid[ETH_ALEN];
|
||||
|
||||
/* Rates supported by the network */
|
||||
struct ieee80211softmac_ratesinfo supported_rates;
|
||||
|
||||
/* some flags.
|
||||
* static_essid is valid if the essid is constant,
|
||||
@ -132,23 +135,26 @@ enum {
|
||||
struct ieee80211softmac_txrates {
|
||||
/* The Bit-Rate to be used for multicast frames. */
|
||||
u8 mcast_rate;
|
||||
/* The Bit-Rate to be used for multicast fallback
|
||||
* (If the device supports fallback and hardware-retry)
|
||||
*/
|
||||
u8 mcast_fallback;
|
||||
|
||||
/* The Bit-Rate to be used for multicast management frames. */
|
||||
u8 mgt_mcast_rate;
|
||||
|
||||
/* The Bit-Rate to be used for any other (normal) data packet. */
|
||||
u8 default_rate;
|
||||
/* The Bit-Rate to be used for default fallback
|
||||
* (If the device supports fallback and hardware-retry)
|
||||
*/
|
||||
u8 default_fallback;
|
||||
|
||||
/* This is the rate that the user asked for */
|
||||
u8 user_rate;
|
||||
};
|
||||
|
||||
/* Bits for txrates_change callback. */
|
||||
#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT (1 << 0) /* default_rate */
|
||||
#define IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK (1 << 1) /* default_fallback */
|
||||
#define IEEE80211SOFTMAC_TXRATECHG_MCAST (1 << 2) /* mcast_rate */
|
||||
#define IEEE80211SOFTMAC_TXRATECHG_MCAST_FBACK (1 << 3) /* mcast_fallback */
|
||||
#define IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST (1 << 3) /* mgt_mcast_rate */
|
||||
|
||||
struct ieee80211softmac_device {
|
||||
/* 802.11 structure for data stuff */
|
||||
@ -250,6 +256,28 @@ extern void ieee80211softmac_fragment_lost(struct net_device *dev,
|
||||
* Note that the rates need to be sorted. */
|
||||
extern void ieee80211softmac_set_rates(struct net_device *dev, u8 count, u8 *rates);
|
||||
|
||||
/* Helper function which advises you the rate at which a frame should be
|
||||
* transmitted at. */
|
||||
static inline u8 ieee80211softmac_suggest_txrate(struct ieee80211softmac_device *mac,
|
||||
int is_multicast,
|
||||
int is_mgt)
|
||||
{
|
||||
struct ieee80211softmac_txrates *txrates = &mac->txrates;
|
||||
|
||||
if (!mac->associated)
|
||||
return txrates->mgt_mcast_rate;
|
||||
|
||||
/* We are associated, sending unicast frame */
|
||||
if (!is_multicast)
|
||||
return txrates->default_rate;
|
||||
|
||||
/* We are associated, sending multicast frame */
|
||||
if (is_mgt)
|
||||
return txrates->mgt_mcast_rate;
|
||||
else
|
||||
return txrates->mcast_rate;
|
||||
}
|
||||
|
||||
/* Start the SoftMAC. Call this after you initialized the device
|
||||
* and it is ready to run.
|
||||
*/
|
||||
|
@ -503,7 +503,7 @@ int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
|
||||
len = sec->key_sizes[key];
|
||||
memcpy(keybuf, sec->keys[key], len);
|
||||
|
||||
erq->length = (len >= 0 ? len : 0);
|
||||
erq->length = len;
|
||||
erq->flags |= IW_ENCODE_ENABLED;
|
||||
|
||||
if (ieee->open_wep)
|
||||
|
@ -82,51 +82,52 @@ ieee80211softmac_assoc_timeout(void *d)
|
||||
ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
|
||||
}
|
||||
|
||||
/* Sends out a disassociation request to the desired AP */
|
||||
void
|
||||
ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason)
|
||||
ieee80211softmac_disassoc(struct ieee80211softmac_device *mac)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mac->lock, flags);
|
||||
if (mac->associnfo.associating)
|
||||
cancel_delayed_work(&mac->associnfo.timeout);
|
||||
|
||||
netif_carrier_off(mac->dev);
|
||||
|
||||
mac->associated = 0;
|
||||
mac->associnfo.bssvalid = 0;
|
||||
mac->associnfo.associating = 0;
|
||||
ieee80211softmac_init_txrates(mac);
|
||||
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
|
||||
spin_unlock_irqrestore(&mac->lock, flags);
|
||||
}
|
||||
|
||||
/* Sends out a disassociation request to the desired AP */
|
||||
void
|
||||
ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason)
|
||||
{
|
||||
struct ieee80211softmac_network *found;
|
||||
|
||||
if (mac->associnfo.bssvalid && mac->associated) {
|
||||
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
|
||||
if (found)
|
||||
ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason);
|
||||
} else if (mac->associnfo.associating) {
|
||||
cancel_delayed_work(&mac->associnfo.timeout);
|
||||
}
|
||||
|
||||
/* Change our state */
|
||||
spin_lock_irqsave(&mac->lock, flags);
|
||||
/* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
|
||||
mac->associated = 0;
|
||||
mac->associnfo.associating = 0;
|
||||
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
|
||||
spin_unlock_irqrestore(&mac->lock, flags);
|
||||
ieee80211softmac_disassoc(mac);
|
||||
}
|
||||
|
||||
static inline int
|
||||
we_support_all_basic_rates(struct ieee80211softmac_device *mac, u8 *from, u8 from_len)
|
||||
{
|
||||
int idx, search, found;
|
||||
u8 rate, search_rate;
|
||||
int idx;
|
||||
u8 rate;
|
||||
|
||||
for (idx = 0; idx < (from_len); idx++) {
|
||||
rate = (from)[idx];
|
||||
if (!(rate & IEEE80211_BASIC_RATE_MASK))
|
||||
continue;
|
||||
found = 0;
|
||||
rate &= ~IEEE80211_BASIC_RATE_MASK;
|
||||
for (search = 0; search < mac->ratesinfo.count; search++) {
|
||||
search_rate = mac->ratesinfo.rates[search];
|
||||
search_rate &= ~IEEE80211_BASIC_RATE_MASK;
|
||||
if (rate == search_rate) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
if (!ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -176,14 +177,18 @@ ieee80211softmac_assoc_work(void *d)
|
||||
struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
|
||||
struct ieee80211softmac_network *found = NULL;
|
||||
struct ieee80211_network *net = NULL, *best = NULL;
|
||||
int bssvalid;
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
/* ieee80211_disassoc might clear this */
|
||||
bssvalid = mac->associnfo.bssvalid;
|
||||
|
||||
/* meh */
|
||||
if (mac->associated)
|
||||
ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
|
||||
ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
|
||||
|
||||
/* try to find the requested network in our list, if we found one already */
|
||||
if (mac->associnfo.bssvalid || mac->associnfo.bssfixed)
|
||||
if (bssvalid || mac->associnfo.bssfixed)
|
||||
found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
|
||||
|
||||
/* Search the ieee80211 networks for this network if we didn't find it by bssid,
|
||||
@ -297,6 +302,9 @@ ieee80211softmac_associated(struct ieee80211softmac_device *mac,
|
||||
struct ieee80211softmac_network *net)
|
||||
{
|
||||
mac->associnfo.associating = 0;
|
||||
mac->associnfo.supported_rates = net->supported_rates;
|
||||
ieee80211softmac_recalc_txrates(mac);
|
||||
|
||||
mac->associated = 1;
|
||||
if (mac->set_bssid_filter)
|
||||
mac->set_bssid_filter(mac->dev, net->bssid);
|
||||
@ -380,7 +388,6 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
|
||||
struct ieee80211_disassoc *disassoc)
|
||||
{
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(!mac->running))
|
||||
return -ENODEV;
|
||||
@ -392,14 +399,11 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
|
||||
return 0;
|
||||
|
||||
dprintk(KERN_INFO PFX "got disassoc frame\n");
|
||||
netif_carrier_off(dev);
|
||||
spin_lock_irqsave(&mac->lock, flags);
|
||||
mac->associnfo.bssvalid = 0;
|
||||
mac->associated = 0;
|
||||
ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
|
||||
ieee80211softmac_disassoc(mac);
|
||||
|
||||
/* try to reassociate */
|
||||
schedule_work(&mac->associnfo.work);
|
||||
spin_unlock_irqrestore(&mac->lock, flags);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -279,6 +279,9 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
|
||||
struct list_head *list_ptr;
|
||||
unsigned long flags;
|
||||
|
||||
/* deauthentication implies disassociation */
|
||||
ieee80211softmac_disassoc(mac);
|
||||
|
||||
/* Lock and reset status flags */
|
||||
spin_lock_irqsave(&mac->lock, flags);
|
||||
net->authenticating = 0;
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "ieee80211softmac_priv.h"
|
||||
#include <linux/sort.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
struct net_device *alloc_ieee80211softmac(int sizeof_priv)
|
||||
{
|
||||
@ -61,14 +62,6 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
|
||||
softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
|
||||
softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
|
||||
|
||||
//TODO: The mcast rate has to be assigned dynamically somewhere (in scanning, association. Not sure...)
|
||||
// It has to be set to the highest rate all stations in the current network can handle.
|
||||
softmac->txrates.mcast_rate = IEEE80211_CCK_RATE_1MB;
|
||||
softmac->txrates.mcast_fallback = IEEE80211_CCK_RATE_1MB;
|
||||
/* This is reassigned in ieee80211softmac_start to sane values. */
|
||||
softmac->txrates.default_rate = IEEE80211_CCK_RATE_1MB;
|
||||
softmac->txrates.default_fallback = IEEE80211_CCK_RATE_1MB;
|
||||
|
||||
/* to start with, we can't send anything ... */
|
||||
netif_carrier_off(dev);
|
||||
|
||||
@ -170,15 +163,82 @@ static void ieee80211softmac_start_check_rates(struct ieee80211softmac_device *m
|
||||
}
|
||||
}
|
||||
|
||||
void ieee80211softmac_start(struct net_device *dev)
|
||||
int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate)
|
||||
{
|
||||
int search;
|
||||
u8 search_rate;
|
||||
|
||||
for (search = 0; search < ri->count; search++) {
|
||||
search_rate = ri->rates[search];
|
||||
search_rate &= ~IEEE80211_BASIC_RATE_MASK;
|
||||
if (rate == search_rate)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Finds the highest rate which is:
|
||||
* 1. Present in ri (optionally a basic rate)
|
||||
* 2. Supported by the device
|
||||
* 3. Less than or equal to the user-defined rate
|
||||
*/
|
||||
static u8 highest_supported_rate(struct ieee80211softmac_device *mac,
|
||||
struct ieee80211softmac_ratesinfo *ri, int basic_only)
|
||||
{
|
||||
u8 user_rate = mac->txrates.user_rate;
|
||||
int i;
|
||||
|
||||
if (ri->count == 0) {
|
||||
dprintk(KERN_ERR PFX "empty ratesinfo?\n");
|
||||
return IEEE80211_CCK_RATE_1MB;
|
||||
}
|
||||
|
||||
for (i = ri->count - 1; i >= 0; i--) {
|
||||
u8 rate = ri->rates[i];
|
||||
if (basic_only && !(rate & IEEE80211_BASIC_RATE_MASK))
|
||||
continue;
|
||||
rate &= ~IEEE80211_BASIC_RATE_MASK;
|
||||
if (rate > user_rate)
|
||||
continue;
|
||||
if (ieee80211softmac_ratesinfo_rate_supported(&mac->ratesinfo, rate))
|
||||
return rate;
|
||||
}
|
||||
|
||||
/* If we haven't found a suitable rate by now, just trust the user */
|
||||
return user_rate;
|
||||
}
|
||||
|
||||
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac)
|
||||
{
|
||||
struct ieee80211softmac_txrates *txrates = &mac->txrates;
|
||||
struct ieee80211softmac_txrates oldrates;
|
||||
u32 change = 0;
|
||||
|
||||
if (mac->txrates_change)
|
||||
oldrates = mac->txrates;
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
|
||||
txrates->default_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 0);
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
|
||||
txrates->default_fallback = lower_rate(mac, txrates->default_rate);
|
||||
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
|
||||
txrates->mcast_rate = highest_supported_rate(mac, &mac->associnfo.supported_rates, 1);
|
||||
|
||||
if (mac->txrates_change)
|
||||
mac->txrates_change(mac->dev, change, &oldrates);
|
||||
|
||||
}
|
||||
|
||||
void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac)
|
||||
{
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
struct ieee80211_device *ieee = mac->ieee;
|
||||
u32 change = 0;
|
||||
struct ieee80211softmac_txrates *txrates = &mac->txrates;
|
||||
struct ieee80211softmac_txrates oldrates;
|
||||
|
||||
ieee80211softmac_start_check_rates(mac);
|
||||
|
||||
/* TODO: We need some kind of state machine to lower the default rates
|
||||
* if we loose too many packets.
|
||||
*/
|
||||
@ -193,22 +253,37 @@ void ieee80211softmac_start(struct net_device *dev)
|
||||
more reliable. Note similar logic in
|
||||
ieee80211softmac_wx_set_rate() */
|
||||
if (ieee->modulation & IEEE80211_CCK_MODULATION) {
|
||||
mac->txrates.default_rate = IEEE80211_CCK_RATE_11MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
|
||||
mac->txrates.default_fallback = IEEE80211_CCK_RATE_5MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
|
||||
txrates->user_rate = IEEE80211_CCK_RATE_11MB;
|
||||
} else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
|
||||
mac->txrates.default_rate = IEEE80211_OFDM_RATE_54MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
|
||||
mac->txrates.default_fallback = IEEE80211_OFDM_RATE_24MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
|
||||
txrates->user_rate = IEEE80211_OFDM_RATE_54MB;
|
||||
} else
|
||||
assert(0);
|
||||
|
||||
txrates->default_rate = IEEE80211_CCK_RATE_1MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
|
||||
|
||||
txrates->default_fallback = IEEE80211_CCK_RATE_1MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT_FBACK;
|
||||
|
||||
txrates->mcast_rate = IEEE80211_CCK_RATE_1MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_MCAST;
|
||||
|
||||
txrates->mgt_mcast_rate = IEEE80211_CCK_RATE_1MB;
|
||||
change |= IEEE80211SOFTMAC_TXRATECHG_MGT_MCAST;
|
||||
|
||||
if (mac->txrates_change)
|
||||
mac->txrates_change(dev, change, &oldrates);
|
||||
mac->txrates_change(mac->dev, change, &oldrates);
|
||||
|
||||
mac->running = 1;
|
||||
}
|
||||
|
||||
void ieee80211softmac_start(struct net_device *dev)
|
||||
{
|
||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||
|
||||
ieee80211softmac_start_check_rates(mac);
|
||||
ieee80211softmac_init_txrates(mac);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
|
||||
|
||||
void ieee80211softmac_stop(struct net_device *dev)
|
||||
|
@ -116,7 +116,10 @@ ieee80211softmac_get_network_by_essid(struct ieee80211softmac_device *mac,
|
||||
struct ieee80211softmac_essid *essid);
|
||||
|
||||
/* Rates related */
|
||||
int ieee80211softmac_ratesinfo_rate_supported(struct ieee80211softmac_ratesinfo *ri, u8 rate);
|
||||
u8 ieee80211softmac_lower_rate_delta(struct ieee80211softmac_device *mac, u8 rate, int delta);
|
||||
void ieee80211softmac_init_txrates(struct ieee80211softmac_device *mac);
|
||||
void ieee80211softmac_recalc_txrates(struct ieee80211softmac_device *mac);
|
||||
static inline u8 lower_rate(struct ieee80211softmac_device *mac, u8 rate) {
|
||||
return ieee80211softmac_lower_rate_delta(mac, rate, 1);
|
||||
}
|
||||
@ -150,7 +153,8 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev,
|
||||
int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
|
||||
struct ieee80211_reassoc_request * reassoc);
|
||||
void ieee80211softmac_assoc_timeout(void *d);
|
||||
void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason);
|
||||
void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
|
||||
void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
|
||||
|
||||
/* some helper functions */
|
||||
static inline int ieee80211softmac_scan_handlers_check_self(struct ieee80211softmac_device *sm)
|
||||
|
@ -211,8 +211,8 @@ ieee80211softmac_wx_set_rate(struct net_device *net_dev,
|
||||
if (is_ofdm && !(ieee->modulation & IEEE80211_OFDM_MODULATION))
|
||||
goto out_unlock;
|
||||
|
||||
mac->txrates.default_rate = rate;
|
||||
mac->txrates.default_fallback = lower_rate(mac, rate);
|
||||
mac->txrates.user_rate = rate;
|
||||
ieee80211softmac_recalc_txrates(mac);
|
||||
err = 0;
|
||||
|
||||
out_unlock:
|
||||
@ -456,7 +456,7 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
|
||||
}
|
||||
return ieee80211softmac_deauth_req(mac, net, reason);
|
||||
case IW_MLME_DISASSOC:
|
||||
ieee80211softmac_disassoc(mac, reason);
|
||||
ieee80211softmac_send_disassoc_req(mac, reason);
|
||||
return 0;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
Loading…
Reference in New Issue
Block a user