Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6

+84 -30
+27 -18
drivers/net/wireless/bcm43xx/bcm43xx_main.c
··· 939 return 0; 940 } 941 942 - static void bcm43xx_geo_init(struct bcm43xx_private *bcm) 943 { 944 - struct ieee80211_geo geo; 945 struct ieee80211_channel *chan; 946 int have_a = 0, have_bg = 0; 947 int i; ··· 949 struct bcm43xx_phyinfo *phy; 950 const char *iso_country; 951 952 - memset(&geo, 0, sizeof(geo)); 953 for (i = 0; i < bcm->nr_80211_available; i++) { 954 phy = &(bcm->core_80211_ext[i].phy); 955 switch (phy->type) { ··· 970 iso_country = bcm43xx_locale_iso(bcm->sprom.locale); 971 972 if (have_a) { 973 - for (i = 0, channel = 0; channel < 201; channel++) { 974 - chan = &geo.a[i++]; 975 chan->freq = bcm43xx_channel_to_freq_a(channel); 976 chan->channel = channel; 977 } 978 - geo.a_channels = i; 979 } 980 if (have_bg) { 981 - for (i = 0, channel = 1; channel < 15; channel++) { 982 - chan = &geo.bg[i++]; 983 chan->freq = bcm43xx_channel_to_freq_bg(channel); 984 chan->channel = channel; 985 } 986 - geo.bg_channels = i; 987 } 988 - memcpy(geo.name, iso_country, 2); 989 if (0 /*TODO: Outdoor use only */) 990 - geo.name[2] = 'O'; 991 else if (0 /*TODO: Indoor use only */) 992 - geo.name[2] = 'I'; 993 else 994 - geo.name[2] = ' '; 995 - geo.name[3] = '\0'; 996 997 - ieee80211_set_geo(bcm->ieee, &geo); 998 } 999 1000 /* DummyTransmission function, as documented on ··· 3487 goto err_80211_unwind; 3488 bcm43xx_wireless_core_disable(bcm); 3489 } 3490 bcm43xx_pctl_set_crystal(bcm, 0); 3491 3492 /* Set the MAC address in the networking subsystem */ 3493 - if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) 3494 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); 3495 else 3496 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); 3497 - 3498 - bcm43xx_geo_init(bcm); 3499 3500 snprintf(bcm->nick, IW_ESSID_MAX_SIZE, 3501 "Broadcom %04X", bcm->chip_id);
··· 939 return 0; 940 } 941 942 + static int bcm43xx_geo_init(struct bcm43xx_private *bcm) 943 { 944 + struct ieee80211_geo *geo; 945 struct ieee80211_channel *chan; 946 int have_a = 0, have_bg = 0; 947 int i; ··· 949 struct bcm43xx_phyinfo *phy; 950 const char *iso_country; 951 952 + geo = kzalloc(sizeof(*geo), GFP_KERNEL); 953 + if (!geo) 954 + return -ENOMEM; 955 + 956 for (i = 0; i < bcm->nr_80211_available; i++) { 957 phy = &(bcm->core_80211_ext[i].phy); 958 switch (phy->type) { ··· 967 iso_country = bcm43xx_locale_iso(bcm->sprom.locale); 968 969 if (have_a) { 970 + for (i = 0, channel = IEEE80211_52GHZ_MIN_CHANNEL; 971 + channel <= IEEE80211_52GHZ_MAX_CHANNEL; channel++) { 972 + chan = &geo->a[i++]; 973 chan->freq = bcm43xx_channel_to_freq_a(channel); 974 chan->channel = channel; 975 } 976 + geo->a_channels = i; 977 } 978 if (have_bg) { 979 + for (i = 0, channel = IEEE80211_24GHZ_MIN_CHANNEL; 980 + channel <= IEEE80211_24GHZ_MAX_CHANNEL; channel++) { 981 + chan = &geo->bg[i++]; 982 chan->freq = bcm43xx_channel_to_freq_bg(channel); 983 chan->channel = channel; 984 } 985 + geo->bg_channels = i; 986 } 987 + memcpy(geo->name, iso_country, 2); 988 if (0 /*TODO: Outdoor use only */) 989 + geo->name[2] = 'O'; 990 else if (0 /*TODO: Indoor use only */) 991 + geo->name[2] = 'I'; 992 else 993 + geo->name[2] = ' '; 994 + geo->name[3] = '\0'; 995 996 + ieee80211_set_geo(bcm->ieee, geo); 997 + kfree(geo); 998 + 999 + return 0; 1000 } 1001 1002 /* DummyTransmission function, as documented on ··· 3479 goto err_80211_unwind; 3480 bcm43xx_wireless_core_disable(bcm); 3481 } 3482 + err = bcm43xx_geo_init(bcm); 3483 + if (err) 3484 + goto err_80211_unwind; 3485 bcm43xx_pctl_set_crystal(bcm, 0); 3486 3487 /* Set the MAC address in the networking subsystem */ 3488 + if (is_valid_ether_addr(bcm->sprom.et1macaddr)) 3489 memcpy(bcm->net_dev->dev_addr, bcm->sprom.et1macaddr, 6); 3490 else 3491 memcpy(bcm->net_dev->dev_addr, bcm->sprom.il0macaddr, 6); 3492 3493 snprintf(bcm->nick, IW_ESSID_MAX_SIZE, 3494 "Broadcom %04X", bcm->chip_id);
+4 -2
drivers/net/wireless/bcm43xx/bcm43xx_main.h
··· 118 static inline 119 int bcm43xx_is_valid_channel_a(u8 channel) 120 { 121 - return (channel <= 200); 122 } 123 static inline 124 int bcm43xx_is_valid_channel_bg(u8 channel) 125 { 126 - return (channel >= 1 && channel <= 14); 127 } 128 static inline 129 int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
··· 118 static inline 119 int bcm43xx_is_valid_channel_a(u8 channel) 120 { 121 + return (channel >= IEEE80211_52GHZ_MIN_CHANNEL 122 + && channel <= IEEE80211_52GHZ_MAX_CHANNEL); 123 } 124 static inline 125 int bcm43xx_is_valid_channel_bg(u8 channel) 126 { 127 + return (channel >= IEEE80211_24GHZ_MIN_CHANNEL 128 + && channel <= IEEE80211_24GHZ_MAX_CHANNEL); 129 } 130 static inline 131 int bcm43xx_is_valid_channel(struct bcm43xx_private *bcm,
+1 -1
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
··· 1287 if (radio->revision == 8) 1288 bcm43xx_phy_write(bcm, 0x0805, 0x3230); 1289 bcm43xx_phy_init_pctl(bcm); 1290 - if (bcm->chip_id == 0x4306 && bcm->chip_package != 2) { 1291 bcm43xx_phy_write(bcm, 0x0429, 1292 bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); 1293 bcm43xx_phy_write(bcm, 0x04C3,
··· 1287 if (radio->revision == 8) 1288 bcm43xx_phy_write(bcm, 0x0805, 0x3230); 1289 bcm43xx_phy_init_pctl(bcm); 1290 + if (bcm->chip_id == 0x4306 && bcm->chip_package == 2) { 1291 bcm43xx_phy_write(bcm, 0x0429, 1292 bcm43xx_phy_read(bcm, 0x0429) & 0xBFFF); 1293 bcm43xx_phy_write(bcm, 0x04C3,
+5 -2
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
··· 182 mode = BCM43xx_INITIAL_IWMODE; 183 184 bcm43xx_lock_mmio(bcm, flags); 185 - if (bcm->ieee->iw_mode != mode) 186 - bcm43xx_set_iwmode(bcm, mode); 187 bcm43xx_unlock_mmio(bcm, flags); 188 189 return 0;
··· 182 mode = BCM43xx_INITIAL_IWMODE; 183 184 bcm43xx_lock_mmio(bcm, flags); 185 + if (bcm->initialized) { 186 + if (bcm->ieee->iw_mode != mode) 187 + bcm43xx_set_iwmode(bcm, mode); 188 + } else 189 + bcm->ieee->iw_mode = mode; 190 bcm43xx_unlock_mmio(bcm, flags); 191 192 return 0;
+4 -2
include/net/ieee80211.h
··· 955 956 #define IEEE80211_24GHZ_MIN_CHANNEL 1 957 #define IEEE80211_24GHZ_MAX_CHANNEL 14 958 - #define IEEE80211_24GHZ_CHANNELS 14 959 960 #define IEEE80211_52GHZ_MIN_CHANNEL 34 961 #define IEEE80211_52GHZ_MAX_CHANNEL 165 962 - #define IEEE80211_52GHZ_CHANNELS 131 963 964 enum { 965 IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
··· 955 956 #define IEEE80211_24GHZ_MIN_CHANNEL 1 957 #define IEEE80211_24GHZ_MAX_CHANNEL 14 958 + #define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ 959 + IEEE80211_24GHZ_MIN_CHANNEL + 1) 960 961 #define IEEE80211_52GHZ_MIN_CHANNEL 34 962 #define IEEE80211_52GHZ_MAX_CHANNEL 165 963 + #define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ 964 + IEEE80211_52GHZ_MIN_CHANNEL + 1) 965 966 enum { 967 IEEE80211_CH_PASSIVE_ONLY = (1 << 0),
+2 -1
include/net/ieee80211softmac.h
··· 204 205 /* couple of flags */ 206 u8 scanning:1, /* protects scanning from being done multiple times at once */ 207 - associated:1; 208 209 struct ieee80211softmac_scaninfo *scaninfo; 210 struct ieee80211softmac_assoc_info associnfo;
··· 204 205 /* couple of flags */ 206 u8 scanning:1, /* protects scanning from being done multiple times at once */ 207 + associated:1, 208 + running:1; 209 210 struct ieee80211softmac_scaninfo *scaninfo; 211 struct ieee80211softmac_assoc_info associnfo;
+15 -2
net/ieee80211/softmac/ieee80211softmac_assoc.c
··· 51 spin_lock_irqsave(&mac->lock, flags); 52 mac->associnfo.associating = 1; 53 mac->associated = 0; /* just to make sure */ 54 - spin_unlock_irqrestore(&mac->lock, flags); 55 56 /* Set a timer for timeout */ 57 /* FIXME: make timeout configurable */ 58 - schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ); 59 } 60 61 void ··· 320 u16 status = le16_to_cpup(&resp->status); 321 struct ieee80211softmac_network *network = NULL; 322 unsigned long flags; 323 324 spin_lock_irqsave(&mac->lock, flags); 325 ··· 381 { 382 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 383 unsigned long flags; 384 if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN)) 385 return 0; 386 if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN)) 387 return 0; 388 dprintk(KERN_INFO PFX "got disassoc frame\n"); 389 netif_carrier_off(dev); 390 spin_lock_irqsave(&mac->lock, flags); ··· 409 { 410 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 411 struct ieee80211softmac_network *network; 412 413 network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3); 414 if (!network) {
··· 51 spin_lock_irqsave(&mac->lock, flags); 52 mac->associnfo.associating = 1; 53 mac->associated = 0; /* just to make sure */ 54 55 /* Set a timer for timeout */ 56 /* FIXME: make timeout configurable */ 57 + if (likely(mac->running)) 58 + schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ); 59 + spin_unlock_irqrestore(&mac->lock, flags); 60 } 61 62 void ··· 319 u16 status = le16_to_cpup(&resp->status); 320 struct ieee80211softmac_network *network = NULL; 321 unsigned long flags; 322 + 323 + if (unlikely(!mac->running)) 324 + return -ENODEV; 325 326 spin_lock_irqsave(&mac->lock, flags); 327 ··· 377 { 378 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 379 unsigned long flags; 380 + 381 + if (unlikely(!mac->running)) 382 + return -ENODEV; 383 + 384 if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN)) 385 return 0; 386 + 387 if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN)) 388 return 0; 389 + 390 dprintk(KERN_INFO PFX "got disassoc frame\n"); 391 netif_carrier_off(dev); 392 spin_lock_irqsave(&mac->lock, flags); ··· 399 { 400 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 401 struct ieee80211softmac_network *network; 402 + 403 + if (unlikely(!mac->running)) 404 + return -ENODEV; 405 406 network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3); 407 if (!network) {
+14 -2
net/ieee80211/softmac/ieee80211softmac_auth.c
··· 86 87 /* Lock and set flags */ 88 spin_lock_irqsave(&mac->lock, flags); 89 net->authenticated = 0; 90 net->authenticating = 1; 91 /* add a timeout call so we eventually give up waiting for an auth reply */ ··· 129 unsigned long flags; 130 u8 * data; 131 132 /* Find correct auth queue item */ 133 spin_lock_irqsave(&mac->lock, flags); 134 list_for_each(list_ptr, &mac->auth_queue) { ··· 306 307 /* can't transmit data right now... */ 308 netif_carrier_off(mac->dev); 309 - /* let's try to re-associate */ 310 - schedule_work(&mac->associnfo.work); 311 spin_unlock_irqrestore(&mac->lock, flags); 312 } 313 ··· 344 struct ieee80211softmac_network *net = NULL; 345 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 346 347 if (!deauth) { 348 dprintk("deauth without deauth packet. eek!\n"); 349 return 0; ··· 369 } 370 371 ieee80211softmac_deauth_from_net(mac, net); 372 return 0; 373 }
··· 86 87 /* Lock and set flags */ 88 spin_lock_irqsave(&mac->lock, flags); 89 + if (unlikely(!mac->running)) { 90 + /* Prevent reschedule on workqueue flush */ 91 + spin_unlock_irqrestore(&mac->lock, flags); 92 + return; 93 + } 94 net->authenticated = 0; 95 net->authenticating = 1; 96 /* add a timeout call so we eventually give up waiting for an auth reply */ ··· 124 unsigned long flags; 125 u8 * data; 126 127 + if (unlikely(!mac->running)) 128 + return -ENODEV; 129 + 130 /* Find correct auth queue item */ 131 spin_lock_irqsave(&mac->lock, flags); 132 list_for_each(list_ptr, &mac->auth_queue) { ··· 298 299 /* can't transmit data right now... */ 300 netif_carrier_off(mac->dev); 301 spin_unlock_irqrestore(&mac->lock, flags); 302 } 303 ··· 338 struct ieee80211softmac_network *net = NULL; 339 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 340 341 + if (unlikely(!mac->running)) 342 + return -ENODEV; 343 + 344 if (!deauth) { 345 dprintk("deauth without deauth packet. eek!\n"); 346 return 0; ··· 360 } 361 362 ieee80211softmac_deauth_from_net(mac, net); 363 + 364 + /* let's try to re-associate */ 365 + schedule_work(&mac->associnfo.work); 366 return 0; 367 }
+4
net/ieee80211/softmac/ieee80211softmac_module.c
··· 89 ieee80211softmac_wait_for_scan(sm); 90 91 spin_lock_irqsave(&sm->lock, flags); 92 /* Free all pending assoc work items */ 93 cancel_delayed_work(&sm->associnfo.work); 94 ··· 206 assert(0); 207 if (mac->txrates_change) 208 mac->txrates_change(dev, change, &oldrates); 209 } 210 EXPORT_SYMBOL_GPL(ieee80211softmac_start); 211
··· 89 ieee80211softmac_wait_for_scan(sm); 90 91 spin_lock_irqsave(&sm->lock, flags); 92 + sm->running = 0; 93 + 94 /* Free all pending assoc work items */ 95 cancel_delayed_work(&sm->associnfo.work); 96 ··· 204 assert(0); 205 if (mac->txrates_change) 206 mac->txrates_change(dev, change, &oldrates); 207 + 208 + mac->running = 1; 209 } 210 EXPORT_SYMBOL_GPL(ieee80211softmac_start); 211
+8
net/ieee80211/softmac/ieee80211softmac_scan.c
··· 115 // TODO: is this if correct, or should we do this only if scanning from assoc request? 116 if (sm->associnfo.req_essid.len) 117 ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0); 118 schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY); 119 return; 120 } else { 121 dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);
··· 115 // TODO: is this if correct, or should we do this only if scanning from assoc request? 116 if (sm->associnfo.req_essid.len) 117 ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0); 118 + 119 + spin_lock_irqsave(&sm->lock, flags); 120 + if (unlikely(!sm->running)) { 121 + /* Prevent reschedule on workqueue flush */ 122 + spin_unlock_irqrestore(&sm->lock, flags); 123 + break; 124 + } 125 schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY); 126 + spin_unlock_irqrestore(&sm->lock, flags); 127 return; 128 } else { 129 dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);