diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ipw2x00/ipw2200.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ipw2x00/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2200.c | 189 |
1 files changed, 152 insertions, 37 deletions
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index a6ca536e44f8..8d72e3d19586 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -31,6 +31,7 @@ | |||
31 | ******************************************************************************/ | 31 | ******************************************************************************/ |
32 | 32 | ||
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/slab.h> | ||
34 | #include "ipw2200.h" | 35 | #include "ipw2200.h" |
35 | 36 | ||
36 | 37 | ||
@@ -81,6 +82,11 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
81 | MODULE_VERSION(DRV_VERSION); | 82 | MODULE_VERSION(DRV_VERSION); |
82 | MODULE_AUTHOR(DRV_COPYRIGHT); | 83 | MODULE_AUTHOR(DRV_COPYRIGHT); |
83 | MODULE_LICENSE("GPL"); | 84 | MODULE_LICENSE("GPL"); |
85 | MODULE_FIRMWARE("ipw2200-ibss.fw"); | ||
86 | #ifdef CONFIG_IPW2200_MONITOR | ||
87 | MODULE_FIRMWARE("ipw2200-sniffer.fw"); | ||
88 | #endif | ||
89 | MODULE_FIRMWARE("ipw2200-bss.fw"); | ||
84 | 90 | ||
85 | static int cmdlog = 0; | 91 | static int cmdlog = 0; |
86 | static int debug = 0; | 92 | static int debug = 0; |
@@ -104,6 +110,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH; | |||
104 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ | 110 | static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ |
105 | #endif | 111 | #endif |
106 | 112 | ||
113 | static struct ieee80211_rate ipw2200_rates[] = { | ||
114 | { .bitrate = 10 }, | ||
115 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
116 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
117 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
118 | { .bitrate = 60 }, | ||
119 | { .bitrate = 90 }, | ||
120 | { .bitrate = 120 }, | ||
121 | { .bitrate = 180 }, | ||
122 | { .bitrate = 240 }, | ||
123 | { .bitrate = 360 }, | ||
124 | { .bitrate = 480 }, | ||
125 | { .bitrate = 540 } | ||
126 | }; | ||
127 | |||
128 | #define ipw2200_a_rates (ipw2200_rates + 4) | ||
129 | #define ipw2200_num_a_rates 8 | ||
130 | #define ipw2200_bg_rates (ipw2200_rates + 0) | ||
131 | #define ipw2200_num_bg_rates 12 | ||
107 | 132 | ||
108 | #ifdef CONFIG_IPW2200_QOS | 133 | #ifdef CONFIG_IPW2200_QOS |
109 | static int qos_enable = 0; | 134 | static int qos_enable = 0; |
@@ -768,7 +793,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len) | |||
768 | /* get number of entries */ | 793 | /* get number of entries */ |
769 | field_count = *(((u16 *) & field_info) + 1); | 794 | field_count = *(((u16 *) & field_info) + 1); |
770 | 795 | ||
771 | /* abort if not enought memory */ | 796 | /* abort if not enough memory */ |
772 | total_len = field_len * field_count; | 797 | total_len = field_len * field_count; |
773 | if (total_len > *len) { | 798 | if (total_len > *len) { |
774 | *len = total_len; | 799 | *len = total_len; |
@@ -1734,10 +1759,13 @@ static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO, | |||
1734 | 1759 | ||
1735 | static int rf_kill_active(struct ipw_priv *priv) | 1760 | static int rf_kill_active(struct ipw_priv *priv) |
1736 | { | 1761 | { |
1737 | if (0 == (ipw_read32(priv, 0x30) & 0x10000)) | 1762 | if (0 == (ipw_read32(priv, 0x30) & 0x10000)) { |
1738 | priv->status |= STATUS_RF_KILL_HW; | 1763 | priv->status |= STATUS_RF_KILL_HW; |
1739 | else | 1764 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); |
1765 | } else { | ||
1740 | priv->status &= ~STATUS_RF_KILL_HW; | 1766 | priv->status &= ~STATUS_RF_KILL_HW; |
1767 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1768 | } | ||
1741 | 1769 | ||
1742 | return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; | 1770 | return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; |
1743 | } | 1771 | } |
@@ -2020,6 +2048,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
2020 | if (inta & IPW_INTA_BIT_RF_KILL_DONE) { | 2048 | if (inta & IPW_INTA_BIT_RF_KILL_DONE) { |
2021 | IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); | 2049 | IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); |
2022 | priv->status |= STATUS_RF_KILL_HW; | 2050 | priv->status |= STATUS_RF_KILL_HW; |
2051 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
2023 | wake_up_interruptible(&priv->wait_command_queue); | 2052 | wake_up_interruptible(&priv->wait_command_queue); |
2024 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2053 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
2025 | cancel_delayed_work(&priv->request_scan); | 2054 | cancel_delayed_work(&priv->request_scan); |
@@ -3149,14 +3178,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) | |||
3149 | int total_nr = 0; | 3178 | int total_nr = 0; |
3150 | int i; | 3179 | int i; |
3151 | struct pci_pool *pool; | 3180 | struct pci_pool *pool; |
3152 | u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; | 3181 | void **virts; |
3153 | dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; | 3182 | dma_addr_t *phys; |
3154 | 3183 | ||
3155 | IPW_DEBUG_TRACE("<< : \n"); | 3184 | IPW_DEBUG_TRACE("<< : \n"); |
3156 | 3185 | ||
3186 | virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL, | ||
3187 | GFP_KERNEL); | ||
3188 | if (!virts) | ||
3189 | return -ENOMEM; | ||
3190 | |||
3191 | phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL, | ||
3192 | GFP_KERNEL); | ||
3193 | if (!phys) { | ||
3194 | kfree(virts); | ||
3195 | return -ENOMEM; | ||
3196 | } | ||
3157 | pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); | 3197 | pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); |
3158 | if (!pool) { | 3198 | if (!pool) { |
3159 | IPW_ERROR("pci_pool_create failed\n"); | 3199 | IPW_ERROR("pci_pool_create failed\n"); |
3200 | kfree(phys); | ||
3201 | kfree(virts); | ||
3160 | return -ENOMEM; | 3202 | return -ENOMEM; |
3161 | } | 3203 | } |
3162 | 3204 | ||
@@ -3226,6 +3268,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) | |||
3226 | pci_pool_free(pool, virts[i], phys[i]); | 3268 | pci_pool_free(pool, virts[i], phys[i]); |
3227 | 3269 | ||
3228 | pci_pool_destroy(pool); | 3270 | pci_pool_destroy(pool); |
3271 | kfree(phys); | ||
3272 | kfree(virts); | ||
3229 | 3273 | ||
3230 | return ret; | 3274 | return ret; |
3231 | } | 3275 | } |
@@ -7732,7 +7776,7 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv, | |||
7732 | case SEC_LEVEL_0: | 7776 | case SEC_LEVEL_0: |
7733 | break; | 7777 | break; |
7734 | default: | 7778 | default: |
7735 | printk(KERN_ERR "Unknow security level %d\n", | 7779 | printk(KERN_ERR "Unknown security level %d\n", |
7736 | priv->ieee->sec.level); | 7780 | priv->ieee->sec.level); |
7737 | break; | 7781 | break; |
7738 | } | 7782 | } |
@@ -8655,24 +8699,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option) | |||
8655 | * | 8699 | * |
8656 | */ | 8700 | */ |
8657 | 8701 | ||
8658 | static int ipw_wx_get_name(struct net_device *dev, | ||
8659 | struct iw_request_info *info, | ||
8660 | union iwreq_data *wrqu, char *extra) | ||
8661 | { | ||
8662 | struct ipw_priv *priv = libipw_priv(dev); | ||
8663 | mutex_lock(&priv->mutex); | ||
8664 | if (priv->status & STATUS_RF_KILL_MASK) | ||
8665 | strcpy(wrqu->name, "radio off"); | ||
8666 | else if (!(priv->status & STATUS_ASSOCIATED)) | ||
8667 | strcpy(wrqu->name, "unassociated"); | ||
8668 | else | ||
8669 | snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c", | ||
8670 | ipw_modes[priv->assoc_request.ieee_mode]); | ||
8671 | IPW_DEBUG_WX("Name: %s\n", wrqu->name); | ||
8672 | mutex_unlock(&priv->mutex); | ||
8673 | return 0; | ||
8674 | } | ||
8675 | |||
8676 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) | 8702 | static int ipw_set_channel(struct ipw_priv *priv, u8 channel) |
8677 | { | 8703 | { |
8678 | if (channel == 0) { | 8704 | if (channel == 0) { |
@@ -8916,7 +8942,7 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
8916 | range->max_qual.updated = 7; /* Updated all three */ | 8942 | range->max_qual.updated = 7; /* Updated all three */ |
8917 | 8943 | ||
8918 | range->avg_qual.qual = 70; | 8944 | range->avg_qual.qual = 70; |
8919 | /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ | 8945 | /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ |
8920 | range->avg_qual.level = 0; /* FIXME to real average level */ | 8946 | range->avg_qual.level = 0; /* FIXME to real average level */ |
8921 | range->avg_qual.noise = 0; | 8947 | range->avg_qual.noise = 0; |
8922 | range->avg_qual.updated = 7; /* Updated all three */ | 8948 | range->avg_qual.updated = 7; /* Updated all three */ |
@@ -9972,7 +9998,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, | |||
9972 | /* Rebase the WE IOCTLs to zero for the handler array */ | 9998 | /* Rebase the WE IOCTLs to zero for the handler array */ |
9973 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] | 9999 | #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] |
9974 | static iw_handler ipw_wx_handlers[] = { | 10000 | static iw_handler ipw_wx_handlers[] = { |
9975 | IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, | 10001 | IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, |
9976 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, | 10002 | IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, |
9977 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, | 10003 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, |
9978 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, | 10004 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, |
@@ -10289,7 +10315,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb, | |||
10289 | case SEC_LEVEL_0: | 10315 | case SEC_LEVEL_0: |
10290 | break; | 10316 | break; |
10291 | default: | 10317 | default: |
10292 | printk(KERN_ERR "Unknow security level %d\n", | 10318 | printk(KERN_ERR "Unknown security level %d\n", |
10293 | priv->ieee->sec.level); | 10319 | priv->ieee->sec.level); |
10294 | break; | 10320 | break; |
10295 | } | 10321 | } |
@@ -11275,6 +11301,7 @@ static int ipw_up(struct ipw_priv *priv) | |||
11275 | if (!(priv->config & CFG_CUSTOM_MAC)) | 11301 | if (!(priv->config & CFG_CUSTOM_MAC)) |
11276 | eeprom_parse_mac(priv, priv->mac_addr); | 11302 | eeprom_parse_mac(priv, priv->mac_addr); |
11277 | memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); | 11303 | memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); |
11304 | memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); | ||
11278 | 11305 | ||
11279 | for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { | 11306 | for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { |
11280 | if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], | 11307 | if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], |
@@ -11416,20 +11443,104 @@ static void ipw_bg_down(struct work_struct *work) | |||
11416 | /* Called by register_netdev() */ | 11443 | /* Called by register_netdev() */ |
11417 | static int ipw_net_init(struct net_device *dev) | 11444 | static int ipw_net_init(struct net_device *dev) |
11418 | { | 11445 | { |
11446 | int i, rc = 0; | ||
11419 | struct ipw_priv *priv = libipw_priv(dev); | 11447 | struct ipw_priv *priv = libipw_priv(dev); |
11448 | const struct libipw_geo *geo = libipw_get_geo(priv->ieee); | ||
11449 | struct wireless_dev *wdev = &priv->ieee->wdev; | ||
11420 | mutex_lock(&priv->mutex); | 11450 | mutex_lock(&priv->mutex); |
11421 | 11451 | ||
11422 | if (ipw_up(priv)) { | 11452 | if (ipw_up(priv)) { |
11423 | mutex_unlock(&priv->mutex); | 11453 | rc = -EIO; |
11424 | return -EIO; | 11454 | goto out; |
11455 | } | ||
11456 | |||
11457 | memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); | ||
11458 | |||
11459 | /* fill-out priv->ieee->bg_band */ | ||
11460 | if (geo->bg_channels) { | ||
11461 | struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; | ||
11462 | |||
11463 | bg_band->band = IEEE80211_BAND_2GHZ; | ||
11464 | bg_band->n_channels = geo->bg_channels; | ||
11465 | bg_band->channels = | ||
11466 | kzalloc(geo->bg_channels * | ||
11467 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11468 | /* translate geo->bg to bg_band.channels */ | ||
11469 | for (i = 0; i < geo->bg_channels; i++) { | ||
11470 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11471 | bg_band->channels[i].center_freq = geo->bg[i].freq; | ||
11472 | bg_band->channels[i].hw_value = geo->bg[i].channel; | ||
11473 | bg_band->channels[i].max_power = geo->bg[i].max_power; | ||
11474 | if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11475 | bg_band->channels[i].flags |= | ||
11476 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11477 | if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) | ||
11478 | bg_band->channels[i].flags |= | ||
11479 | IEEE80211_CHAN_NO_IBSS; | ||
11480 | if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11481 | bg_band->channels[i].flags |= | ||
11482 | IEEE80211_CHAN_RADAR; | ||
11483 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11484 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11485 | LIBIPW_CH_B_ONLY... */ | ||
11486 | } | ||
11487 | /* point at bitrate info */ | ||
11488 | bg_band->bitrates = ipw2200_bg_rates; | ||
11489 | bg_band->n_bitrates = ipw2200_num_bg_rates; | ||
11490 | |||
11491 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; | ||
11492 | } | ||
11493 | |||
11494 | /* fill-out priv->ieee->a_band */ | ||
11495 | if (geo->a_channels) { | ||
11496 | struct ieee80211_supported_band *a_band = &priv->ieee->a_band; | ||
11497 | |||
11498 | a_band->band = IEEE80211_BAND_5GHZ; | ||
11499 | a_band->n_channels = geo->a_channels; | ||
11500 | a_band->channels = | ||
11501 | kzalloc(geo->a_channels * | ||
11502 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
11503 | /* translate geo->bg to a_band.channels */ | ||
11504 | for (i = 0; i < geo->a_channels; i++) { | ||
11505 | a_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
11506 | a_band->channels[i].center_freq = geo->a[i].freq; | ||
11507 | a_band->channels[i].hw_value = geo->a[i].channel; | ||
11508 | a_band->channels[i].max_power = geo->a[i].max_power; | ||
11509 | if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
11510 | a_band->channels[i].flags |= | ||
11511 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
11512 | if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) | ||
11513 | a_band->channels[i].flags |= | ||
11514 | IEEE80211_CHAN_NO_IBSS; | ||
11515 | if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
11516 | a_band->channels[i].flags |= | ||
11517 | IEEE80211_CHAN_RADAR; | ||
11518 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
11519 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
11520 | LIBIPW_CH_B_ONLY... */ | ||
11521 | } | ||
11522 | /* point at bitrate info */ | ||
11523 | a_band->bitrates = ipw2200_a_rates; | ||
11524 | a_band->n_bitrates = ipw2200_num_a_rates; | ||
11525 | |||
11526 | wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band; | ||
11425 | } | 11527 | } |
11426 | 11528 | ||
11529 | set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); | ||
11530 | |||
11531 | /* With that information in place, we can now register the wiphy... */ | ||
11532 | if (wiphy_register(wdev->wiphy)) { | ||
11533 | rc = -EIO; | ||
11534 | goto out; | ||
11535 | } | ||
11536 | |||
11537 | out: | ||
11427 | mutex_unlock(&priv->mutex); | 11538 | mutex_unlock(&priv->mutex); |
11428 | return 0; | 11539 | return rc; |
11429 | } | 11540 | } |
11430 | 11541 | ||
11431 | /* PCI driver stuff */ | 11542 | /* PCI driver stuff */ |
11432 | static struct pci_device_id card_ids[] = { | 11543 | static DEFINE_PCI_DEVICE_TABLE(card_ids) = { |
11433 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0}, | 11544 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0}, |
11434 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0}, | 11545 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0}, |
11435 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0}, | 11546 | {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0}, |
@@ -11556,7 +11667,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11556 | if (priv->prom_net_dev) | 11667 | if (priv->prom_net_dev) |
11557 | return -EPERM; | 11668 | return -EPERM; |
11558 | 11669 | ||
11559 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); | 11670 | priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1); |
11560 | if (priv->prom_net_dev == NULL) | 11671 | if (priv->prom_net_dev == NULL) |
11561 | return -ENOMEM; | 11672 | return -ENOMEM; |
11562 | 11673 | ||
@@ -11575,7 +11686,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv) | |||
11575 | 11686 | ||
11576 | rc = register_netdev(priv->prom_net_dev); | 11687 | rc = register_netdev(priv->prom_net_dev); |
11577 | if (rc) { | 11688 | if (rc) { |
11578 | free_ieee80211(priv->prom_net_dev); | 11689 | free_ieee80211(priv->prom_net_dev, 1); |
11579 | priv->prom_net_dev = NULL; | 11690 | priv->prom_net_dev = NULL; |
11580 | return rc; | 11691 | return rc; |
11581 | } | 11692 | } |
@@ -11589,7 +11700,7 @@ static void ipw_prom_free(struct ipw_priv *priv) | |||
11589 | return; | 11700 | return; |
11590 | 11701 | ||
11591 | unregister_netdev(priv->prom_net_dev); | 11702 | unregister_netdev(priv->prom_net_dev); |
11592 | free_ieee80211(priv->prom_net_dev); | 11703 | free_ieee80211(priv->prom_net_dev, 1); |
11593 | 11704 | ||
11594 | priv->prom_net_dev = NULL; | 11705 | priv->prom_net_dev = NULL; |
11595 | } | 11706 | } |
@@ -11617,7 +11728,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11617 | struct ipw_priv *priv; | 11728 | struct ipw_priv *priv; |
11618 | int i; | 11729 | int i; |
11619 | 11730 | ||
11620 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); | 11731 | net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0); |
11621 | if (net_dev == NULL) { | 11732 | if (net_dev == NULL) { |
11622 | err = -ENOMEM; | 11733 | err = -ENOMEM; |
11623 | goto out; | 11734 | goto out; |
@@ -11765,7 +11876,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev, | |||
11765 | pci_disable_device(pdev); | 11876 | pci_disable_device(pdev); |
11766 | pci_set_drvdata(pdev, NULL); | 11877 | pci_set_drvdata(pdev, NULL); |
11767 | out_free_ieee80211: | 11878 | out_free_ieee80211: |
11768 | free_ieee80211(priv->net_dev); | 11879 | free_ieee80211(priv->net_dev, 0); |
11769 | out: | 11880 | out: |
11770 | return err; | 11881 | return err; |
11771 | } | 11882 | } |
@@ -11832,7 +11943,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11832 | pci_release_regions(pdev); | 11943 | pci_release_regions(pdev); |
11833 | pci_disable_device(pdev); | 11944 | pci_disable_device(pdev); |
11834 | pci_set_drvdata(pdev, NULL); | 11945 | pci_set_drvdata(pdev, NULL); |
11835 | free_ieee80211(priv->net_dev); | 11946 | /* wiphy_unregister needs to be here, before free_ieee80211 */ |
11947 | wiphy_unregister(priv->ieee->wdev.wiphy); | ||
11948 | kfree(priv->ieee->a_band.channels); | ||
11949 | kfree(priv->ieee->bg_band.channels); | ||
11950 | free_ieee80211(priv->net_dev, 0); | ||
11836 | free_firmware(); | 11951 | free_firmware(); |
11837 | } | 11952 | } |
11838 | 11953 | ||