mirror of https://gitee.com/openkylin/linux.git
Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
This commit is contained in:
commit
23aee82e75
|
@ -939,9 +939,9 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
|
static int bcm43xx_geo_init(struct bcm43xx_private *bcm)
|
||||||
{
|
{
|
||||||
struct ieee80211_geo geo;
|
struct ieee80211_geo *geo;
|
||||||
struct ieee80211_channel *chan;
|
struct ieee80211_channel *chan;
|
||||||
int have_a = 0, have_bg = 0;
|
int have_a = 0, have_bg = 0;
|
||||||
int i;
|
int i;
|
||||||
|
@ -949,7 +949,10 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
|
||||||
struct bcm43xx_phyinfo *phy;
|
struct bcm43xx_phyinfo *phy;
|
||||||
const char *iso_country;
|
const char *iso_country;
|
||||||
|
|
||||||
memset(&geo, 0, sizeof(geo));
|
geo = kzalloc(sizeof(*geo), GFP_KERNEL);
|
||||||
|
if (!geo)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < bcm->nr_80211_available; i++) {
|
for (i = 0; i < bcm->nr_80211_available; i++) {
|
||||||
phy = &(bcm->core_80211_ext[i].phy);
|
phy = &(bcm->core_80211_ext[i].phy);
|
||||||
switch (phy->type) {
|
switch (phy->type) {
|
||||||
|
@ -967,31 +970,36 @@ static void bcm43xx_geo_init(struct bcm43xx_private *bcm)
|
||||||
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
|
iso_country = bcm43xx_locale_iso(bcm->sprom.locale);
|
||||||
|
|
||||||
if (have_a) {
|
if (have_a) {
|
||||||
for (i = 0, channel = 0; channel < 201; channel++) {
|
for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL;
|
||||||
chan = &geo.a[i++];
|
channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) {
|
||||||
|
chan = &geo->a[i++];
|
||||||
chan->freq = bcm43xx_channel_to_freq_a(channel);
|
chan->freq = bcm43xx_channel_to_freq_a(channel);
|
||||||
chan->channel = channel;
|
chan->channel = channel;
|
||||||
}
|
}
|
||||||
geo.a_channels = i;
|
geo->a_channels = i;
|
||||||
}
|
}
|
||||||
if (have_bg) {
|
if (have_bg) {
|
||||||
for (i = 0, channel = 1; channel < 15; channel++) {
|
for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL;
|
||||||
chan = &geo.bg[i++];
|
channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) {
|
||||||
|
chan = &geo->bg[i++];
|
||||||
chan->freq = bcm43xx_channel_to_freq_bg(channel);
|
chan->freq = bcm43xx_channel_to_freq_bg(channel);
|
||||||
chan->channel = channel;
|
chan->channel = channel;
|
||||||
}
|
}
|
||||||
geo.bg_channels = i;
|
geo->bg_channels = i;
|
||||||
}
|
}
|
||||||
memcpy(geo.name, iso_country, 2);
|
memcpy(geo->name, iso_country, 2);
|
||||||
if (0 /*TODO: Outdoor use only */)
|
if (0 /*TODO: Outdoor use only */)
|
||||||
geo.name[2] = 'O';
|
geo->name[2] = 'O';
|
||||||
else if (0 /*TODO: Indoor use only */)
|
else if (0 /*TODO: Indoor use only */)
|
||||||
geo.name[2] = 'I';
|
geo->name[2] = 'I';
|
||||||
else
|
else
|
||||||
geo.name[2] = ' ';
|
geo->name[2] = ' ';
|
||||||
geo.name[3] = '\0';
|
geo->name[3] = '\0';
|
||||||
|
|
||||||
ieee80211_set_geo(bcm->ieee, &geo);
|
ieee80211_set_geo(bcm->ieee, geo);
|
||||||
|
kfree(geo);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DummyTransmission function, as documented on
|
/* DummyTransmission function, as documented on
|
||||||
|
@ -3479,16 +3487,17 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
|
||||||
goto err_80211_unwind;
|
goto err_80211_unwind;
|
||||||
bcm43xx_wireless_core_disable(bcm);
|
bcm43xx_wireless_core_disable(bcm);
|
||||||
}
|
}
|
||||||
|
err = bcm43xx_geo_init(bcm);
|
||||||
|
if (err)
|
||||||
|
goto err_80211_unwind;
|
||||||
bcm43xx_pctl_set_crystal(bcm, 0);
|
bcm43xx_pctl_set_crystal(bcm, 0);
|
||||||
|
|
||||||
/* Set the MAC address in the networking subsystem */
|
/* Set the MAC address in the networking subsystem */
|
||||||
if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A)
|
if (is_valid_ether_addr(bcm->sprom.et1macaddr))
|
||||||
memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
|
memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6);
|
||||||
else
|
else
|
||||||
memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
|
memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6);
|
||||||
|
|
||||||
bcm43xx_geo_init(bcm);
|
|
||||||
|
|
||||||
snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
|
snprintf(bcm->nick, IW_ESSID_MAX_SIZE,
|
||||||
"Broadcom %04X", bcm->chip_id);
|
"Broadcom %04X", bcm->chip_id);
|
||||||
|
|
||||||
|
|
|
@ -118,12 +118,14 @@ int bcm43xx_channel_to_freq(struct bcm43xx_private *bcm,
|
||||||
static inline
|
static inline
|
||||||
int bcm43xx_is_valid_channel_a(u8 channel)
|
int bcm43xx_is_valid_channel_a(u8 channel)
|
||||||
{
|
{
|
||||||
return (channel <= 200);
|
return (channel >= IEEE80211_52GHZ_MIN_CHANNEL
|
||||||
|
&& channel <= IEEE80211_52GHZ_MAX_CHANNEL);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
int bcm43xx_is_valid_channel_bg(u8 channel)
|
int bcm43xx_is_valid_channel_bg(u8 channel)
|
||||||
{
|
{
|
||||||
return (channel >= 1 && channel <= 14);
|
return (channel >= IEEE80211_24GHZ_MIN_CHANNEL
|
||||||
|
&& channel <= IEEE80211_24GHZ_MAX_CHANNEL);
|
||||||
}
|
}
|
||||||
static inline
|
static inline
|
||||||
int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
|
int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
|
||||||
|
|
|
@ -1287,7 +1287,7 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
|
||||||
if (radio->revision == 8)
|
if (radio->revision == 8)
|
||||||
bcm43xx_phy_write(bcm, 0x0805, 0x3230);
|
bcm43xx_phy_write(bcm, 0x0805, 0x3230);
|
||||||
bcm43xx_phy_init_pctl(bcm);
|
bcm43xx_phy_init_pctl(bcm);
|
||||||
if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) {
|
if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) {
|
||||||
bcm43xx_phy_write(bcm, 0x0429,
|
bcm43xx_phy_write(bcm, 0x0429,
|
||||||
bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
|
bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF);
|
||||||
bcm43xx_phy_write(bcm, 0x04C3,
|
bcm43xx_phy_write(bcm, 0x04C3,
|
||||||
|
|
|
@ -182,8 +182,11 @@ static int bcm43xx_wx_set_mode(struct net_device *net_dev,
|
||||||
mode = BCM43xx_INITIAL_IWMODE;
|
mode = BCM43xx_INITIAL_IWMODE;
|
||||||
|
|
||||||
bcm43xx_lock_mmio(bcm, flags);
|
bcm43xx_lock_mmio(bcm, flags);
|
||||||
|
if (bcm->initialized) {
|
||||||
if (bcm->ieee->iw_mode != mode)
|
if (bcm->ieee->iw_mode != mode)
|
||||||
bcm43xx_set_iwmode(bcm, mode);
|
bcm43xx_set_iwmode(bcm, mode);
|
||||||
|
} else
|
||||||
|
bcm->ieee->iw_mode = mode;
|
||||||
bcm43xx_unlock_mmio(bcm, flags);
|
bcm43xx_unlock_mmio(bcm, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -955,11 +955,13 @@ enum ieee80211_state {
|
||||||
|
|
||||||
#define IEEE80211_24GHZ_MIN_CHANNEL 1
|
#define IEEE80211_24GHZ_MIN_CHANNEL 1
|
||||||
#define IEEE80211_24GHZ_MAX_CHANNEL 14
|
#define IEEE80211_24GHZ_MAX_CHANNEL 14
|
||||||
#define IEEE80211_24GHZ_CHANNELS 14
|
#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \
|
||||||
|
IEEE80211_24GHZ_MIN_CHANNEL + 1)
|
||||||
|
|
||||||
#define IEEE80211_52GHZ_MIN_CHANNEL 34
|
#define IEEE80211_52GHZ_MIN_CHANNEL 34
|
||||||
#define IEEE80211_52GHZ_MAX_CHANNEL 165
|
#define IEEE80211_52GHZ_MAX_CHANNEL 165
|
||||||
#define IEEE80211_52GHZ_CHANNELS 131
|
#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \
|
||||||
|
IEEE80211_52GHZ_MIN_CHANNEL + 1)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
|
IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
|
||||||
|
|
|
@ -204,7 +204,8 @@ struct ieee80211softmac_device {
|
||||||
|
|
||||||
/* couple of flags */
|
/* couple of flags */
|
||||||
u8 scanning:1, /* protects scanning from being done multiple times at once */
|
u8 scanning:1, /* protects scanning from being done multiple times at once */
|
||||||
associated:1;
|
associated:1,
|
||||||
|
running:1;
|
||||||
|
|
||||||
struct ieee80211softmac_scaninfo *scaninfo;
|
struct ieee80211softmac_scaninfo *scaninfo;
|
||||||
struct ieee80211softmac_assoc_info associnfo;
|
struct ieee80211softmac_assoc_info associnfo;
|
||||||
|
|
|
@ -51,11 +51,12 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
mac->associnfo.associating = 1;
|
mac->associnfo.associating = 1;
|
||||||
mac->associated = 0; /* just to make sure */
|
mac->associated = 0; /* just to make sure */
|
||||||
spin_unlock_irqrestore(&mac->lock, flags);
|
|
||||||
|
|
||||||
/* Set a timer for timeout */
|
/* Set a timer for timeout */
|
||||||
/* FIXME: make timeout configurable */
|
/* FIXME: make timeout configurable */
|
||||||
|
if (likely(mac->running))
|
||||||
schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
|
schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
|
||||||
|
spin_unlock_irqrestore(&mac->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -320,6 +321,9 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
|
||||||
struct ieee80211softmac_network *network = NULL;
|
struct ieee80211softmac_network *network = NULL;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (unlikely(!mac->running))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
|
|
||||||
if (!mac->associnfo.associating) {
|
if (!mac->associnfo.associating) {
|
||||||
|
@ -377,10 +381,16 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
|
||||||
{
|
{
|
||||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (unlikely(!mac->running))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
|
if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
|
if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dprintk(KERN_INFO PFX "got disassoc frame\n");
|
dprintk(KERN_INFO PFX "got disassoc frame\n");
|
||||||
netif_carrier_off(dev);
|
netif_carrier_off(dev);
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
|
@ -400,6 +410,9 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
|
||||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||||
struct ieee80211softmac_network *network;
|
struct ieee80211softmac_network *network;
|
||||||
|
|
||||||
|
if (unlikely(!mac->running))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
|
network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
|
||||||
if (!network) {
|
if (!network) {
|
||||||
dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
|
dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
|
||||||
|
|
|
@ -86,6 +86,11 @@ ieee80211softmac_auth_queue(void *data)
|
||||||
|
|
||||||
/* Lock and set flags */
|
/* Lock and set flags */
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
|
if (unlikely(!mac->running)) {
|
||||||
|
/* Prevent reschedule on workqueue flush */
|
||||||
|
spin_unlock_irqrestore(&mac->lock, flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
net->authenticated = 0;
|
net->authenticated = 0;
|
||||||
net->authenticating = 1;
|
net->authenticating = 1;
|
||||||
/* add a timeout call so we eventually give up waiting for an auth reply */
|
/* add a timeout call so we eventually give up waiting for an auth reply */
|
||||||
|
@ -124,6 +129,9 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u8 * data;
|
u8 * data;
|
||||||
|
|
||||||
|
if (unlikely(!mac->running))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
/* Find correct auth queue item */
|
/* Find correct auth queue item */
|
||||||
spin_lock_irqsave(&mac->lock, flags);
|
spin_lock_irqsave(&mac->lock, flags);
|
||||||
list_for_each(list_ptr, &mac->auth_queue) {
|
list_for_each(list_ptr, &mac->auth_queue) {
|
||||||
|
@ -298,8 +306,6 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
|
||||||
|
|
||||||
/* can't transmit data right now... */
|
/* can't transmit data right now... */
|
||||||
netif_carrier_off(mac->dev);
|
netif_carrier_off(mac->dev);
|
||||||
/* let's try to re-associate */
|
|
||||||
schedule_work(&mac->associnfo.work);
|
|
||||||
spin_unlock_irqrestore(&mac->lock, flags);
|
spin_unlock_irqrestore(&mac->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +344,9 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
|
||||||
struct ieee80211softmac_network *net = NULL;
|
struct ieee80211softmac_network *net = NULL;
|
||||||
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
|
||||||
|
|
||||||
|
if (unlikely(!mac->running))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
if (!deauth) {
|
if (!deauth) {
|
||||||
dprintk("deauth without deauth packet. eek!\n");
|
dprintk("deauth without deauth packet. eek!\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -360,5 +369,8 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
|
||||||
}
|
}
|
||||||
|
|
||||||
ieee80211softmac_deauth_from_net(mac, net);
|
ieee80211softmac_deauth_from_net(mac, net);
|
||||||
|
|
||||||
|
/* let's try to re-associate */
|
||||||
|
schedule_work(&mac->associnfo.work);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,8 @@ ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
|
||||||
ieee80211softmac_wait_for_scan(sm);
|
ieee80211softmac_wait_for_scan(sm);
|
||||||
|
|
||||||
spin_lock_irqsave(&sm->lock, flags);
|
spin_lock_irqsave(&sm->lock, flags);
|
||||||
|
sm->running = 0;
|
||||||
|
|
||||||
/* Free all pending assoc work items */
|
/* Free all pending assoc work items */
|
||||||
cancel_delayed_work(&sm->associnfo.work);
|
cancel_delayed_work(&sm->associnfo.work);
|
||||||
|
|
||||||
|
@ -204,6 +206,8 @@ void ieee80211softmac_start(struct net_device *dev)
|
||||||
assert(0);
|
assert(0);
|
||||||
if (mac->txrates_change)
|
if (mac->txrates_change)
|
||||||
mac->txrates_change(dev, change, &oldrates);
|
mac->txrates_change(dev, change, &oldrates);
|
||||||
|
|
||||||
|
mac->running = 1;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
|
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,15 @@ void ieee80211softmac_scan(void *d)
|
||||||
// TODO: is this if correct, or should we do this only if scanning from assoc request?
|
// TODO: is this if correct, or should we do this only if scanning from assoc request?
|
||||||
if (sm->associnfo.req_essid.len)
|
if (sm->associnfo.req_essid.len)
|
||||||
ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
|
ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&sm->lock, flags);
|
||||||
|
if (unlikely(!sm->running)) {
|
||||||
|
/* Prevent reschedule on workqueue flush */
|
||||||
|
spin_unlock_irqrestore(&sm->lock, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
|
schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
|
||||||
|
spin_unlock_irqrestore(&sm->lock, flags);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
|
dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
|
||||||
|
|
Loading…
Reference in New Issue