diff options
Diffstat (limited to 'drivers/net/wireless/ipw2x00')
-rw-r--r-- | drivers/net/wireless/ipw2x00/Kconfig | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2100.c | 155 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/ipw2200.c | 189 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/libipw.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/libipw_geo.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/libipw_module.c | 110 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/libipw_rx.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ipw2x00/libipw_wx.c | 1 |
8 files changed, 363 insertions, 116 deletions
diff --git a/drivers/net/wireless/ipw2x00/Kconfig b/drivers/net/wireless/ipw2x00/Kconfig index a8131384c6b9..2715b101aded 100644 --- a/drivers/net/wireless/ipw2x00/Kconfig +++ b/drivers/net/wireless/ipw2x00/Kconfig | |||
@@ -4,8 +4,10 @@ | |||
4 | 4 | ||
5 | config IPW2100 | 5 | config IPW2100 |
6 | tristate "Intel PRO/Wireless 2100 Network Connection" | 6 | tristate "Intel PRO/Wireless 2100 Network Connection" |
7 | depends on PCI && WLAN_80211 && CFG80211 | 7 | depends on PCI && CFG80211 |
8 | select WIRELESS_EXT | 8 | select WIRELESS_EXT |
9 | select WEXT_SPY | ||
10 | select WEXT_PRIV | ||
9 | select FW_LOADER | 11 | select FW_LOADER |
10 | select LIB80211 | 12 | select LIB80211 |
11 | select LIBIPW | 13 | select LIBIPW |
@@ -63,8 +65,10 @@ config IPW2100_DEBUG | |||
63 | 65 | ||
64 | config IPW2200 | 66 | config IPW2200 |
65 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" | 67 | tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection" |
66 | depends on PCI && WLAN_80211 && CFG80211 | 68 | depends on PCI && CFG80211 && CFG80211_WEXT |
67 | select WIRELESS_EXT | 69 | select WIRELESS_EXT |
70 | select WEXT_SPY | ||
71 | select WEXT_PRIV | ||
68 | select FW_LOADER | 72 | select FW_LOADER |
69 | select LIB80211 | 73 | select LIB80211 |
70 | select LIBIPW | 74 | select LIBIPW |
@@ -150,8 +154,9 @@ config IPW2200_DEBUG | |||
150 | 154 | ||
151 | config LIBIPW | 155 | config LIBIPW |
152 | tristate | 156 | tristate |
153 | depends on PCI && WLAN_80211 && CFG80211 | 157 | depends on PCI && CFG80211 |
154 | select WIRELESS_EXT | 158 | select WIRELESS_EXT |
159 | select WEXT_SPY | ||
155 | select CRYPTO | 160 | select CRYPTO |
156 | select CRYPTO_ARC4 | 161 | select CRYPTO_ARC4 |
157 | select CRYPTO_ECB | 162 | select CRYPTO_ECB |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 6e2fc0cb6f8a..9b72c45a7748 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -296,6 +296,33 @@ static const char *command_types[] = { | |||
296 | }; | 296 | }; |
297 | #endif | 297 | #endif |
298 | 298 | ||
299 | #define WEXT_USECHANNELS 1 | ||
300 | |||
301 | static const long ipw2100_frequencies[] = { | ||
302 | 2412, 2417, 2422, 2427, | ||
303 | 2432, 2437, 2442, 2447, | ||
304 | 2452, 2457, 2462, 2467, | ||
305 | 2472, 2484 | ||
306 | }; | ||
307 | |||
308 | #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) | ||
309 | |||
310 | static const long ipw2100_rates_11b[] = { | ||
311 | 1000000, | ||
312 | 2000000, | ||
313 | 5500000, | ||
314 | 11000000 | ||
315 | }; | ||
316 | |||
317 | static struct ieee80211_rate ipw2100_bg_rates[] = { | ||
318 | { .bitrate = 10 }, | ||
319 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
320 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
321 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
322 | }; | ||
323 | |||
324 | #define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) | ||
325 | |||
299 | /* Pre-decl until we get the code solid and then we can clean it up */ | 326 | /* Pre-decl until we get the code solid and then we can clean it up */ |
300 | static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); | 327 | static void ipw2100_tx_send_commands(struct ipw2100_priv *priv); |
301 | static void ipw2100_tx_send_data(struct ipw2100_priv *priv); | 328 | static void ipw2100_tx_send_data(struct ipw2100_priv *priv); |
@@ -551,7 +578,7 @@ static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord, | |||
551 | /* get number of entries */ | 578 | /* get number of entries */ |
552 | field_count = *(((u16 *) & field_info) + 1); | 579 | field_count = *(((u16 *) & field_info) + 1); |
553 | 580 | ||
554 | /* abort if no enought memory */ | 581 | /* abort if no enough memory */ |
555 | total_length = field_len * field_count; | 582 | total_length = field_len * field_count; |
556 | if (total_length > *len) { | 583 | if (total_length > *len) { |
557 | *len = total_length; | 584 | *len = total_length; |
@@ -1141,6 +1168,7 @@ static int rf_kill_active(struct ipw2100_priv *priv) | |||
1141 | int i; | 1168 | int i; |
1142 | 1169 | ||
1143 | if (!(priv->hw_features & HW_FEATURE_RFKILL)) { | 1170 | if (!(priv->hw_features & HW_FEATURE_RFKILL)) { |
1171 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1144 | priv->status &= ~STATUS_RF_KILL_HW; | 1172 | priv->status &= ~STATUS_RF_KILL_HW; |
1145 | return 0; | 1173 | return 0; |
1146 | } | 1174 | } |
@@ -1151,10 +1179,13 @@ static int rf_kill_active(struct ipw2100_priv *priv) | |||
1151 | value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1); | 1179 | value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1); |
1152 | } | 1180 | } |
1153 | 1181 | ||
1154 | if (value == 0) | 1182 | if (value == 0) { |
1183 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
1155 | priv->status |= STATUS_RF_KILL_HW; | 1184 | priv->status |= STATUS_RF_KILL_HW; |
1156 | else | 1185 | } else { |
1186 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false); | ||
1157 | priv->status &= ~STATUS_RF_KILL_HW; | 1187 | priv->status &= ~STATUS_RF_KILL_HW; |
1188 | } | ||
1158 | 1189 | ||
1159 | return (value == 0); | 1190 | return (value == 0); |
1160 | } | 1191 | } |
@@ -1814,13 +1845,6 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) | |||
1814 | return rc; | 1845 | return rc; |
1815 | } | 1846 | } |
1816 | 1847 | ||
1817 | /* Called by register_netdev() */ | ||
1818 | static int ipw2100_net_init(struct net_device *dev) | ||
1819 | { | ||
1820 | struct ipw2100_priv *priv = libipw_priv(dev); | ||
1821 | return ipw2100_up(priv, 1); | ||
1822 | } | ||
1823 | |||
1824 | static void ipw2100_down(struct ipw2100_priv *priv) | 1848 | static void ipw2100_down(struct ipw2100_priv *priv) |
1825 | { | 1849 | { |
1826 | unsigned long flags; | 1850 | unsigned long flags; |
@@ -1875,6 +1899,64 @@ static void ipw2100_down(struct ipw2100_priv *priv) | |||
1875 | netif_stop_queue(priv->net_dev); | 1899 | netif_stop_queue(priv->net_dev); |
1876 | } | 1900 | } |
1877 | 1901 | ||
1902 | /* Called by register_netdev() */ | ||
1903 | static int ipw2100_net_init(struct net_device *dev) | ||
1904 | { | ||
1905 | struct ipw2100_priv *priv = libipw_priv(dev); | ||
1906 | const struct libipw_geo *geo = libipw_get_geo(priv->ieee); | ||
1907 | struct wireless_dev *wdev = &priv->ieee->wdev; | ||
1908 | int ret; | ||
1909 | int i; | ||
1910 | |||
1911 | ret = ipw2100_up(priv, 1); | ||
1912 | if (ret) | ||
1913 | return ret; | ||
1914 | |||
1915 | memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN); | ||
1916 | |||
1917 | /* fill-out priv->ieee->bg_band */ | ||
1918 | if (geo->bg_channels) { | ||
1919 | struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band; | ||
1920 | |||
1921 | bg_band->band = IEEE80211_BAND_2GHZ; | ||
1922 | bg_band->n_channels = geo->bg_channels; | ||
1923 | bg_band->channels = | ||
1924 | kzalloc(geo->bg_channels * | ||
1925 | sizeof(struct ieee80211_channel), GFP_KERNEL); | ||
1926 | /* translate geo->bg to bg_band.channels */ | ||
1927 | for (i = 0; i < geo->bg_channels; i++) { | ||
1928 | bg_band->channels[i].band = IEEE80211_BAND_2GHZ; | ||
1929 | bg_band->channels[i].center_freq = geo->bg[i].freq; | ||
1930 | bg_band->channels[i].hw_value = geo->bg[i].channel; | ||
1931 | bg_band->channels[i].max_power = geo->bg[i].max_power; | ||
1932 | if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) | ||
1933 | bg_band->channels[i].flags |= | ||
1934 | IEEE80211_CHAN_PASSIVE_SCAN; | ||
1935 | if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) | ||
1936 | bg_band->channels[i].flags |= | ||
1937 | IEEE80211_CHAN_NO_IBSS; | ||
1938 | if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) | ||
1939 | bg_band->channels[i].flags |= | ||
1940 | IEEE80211_CHAN_RADAR; | ||
1941 | /* No equivalent for LIBIPW_CH_80211H_RULES, | ||
1942 | LIBIPW_CH_UNIFORM_SPREADING, or | ||
1943 | LIBIPW_CH_B_ONLY... */ | ||
1944 | } | ||
1945 | /* point at bitrate info */ | ||
1946 | bg_band->bitrates = ipw2100_bg_rates; | ||
1947 | bg_band->n_bitrates = RATE_COUNT; | ||
1948 | |||
1949 | wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band; | ||
1950 | } | ||
1951 | |||
1952 | set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); | ||
1953 | if (wiphy_register(wdev->wiphy)) { | ||
1954 | ipw2100_down(priv); | ||
1955 | return -EIO; | ||
1956 | } | ||
1957 | return 0; | ||
1958 | } | ||
1959 | |||
1878 | static void ipw2100_reset_adapter(struct work_struct *work) | 1960 | static void ipw2100_reset_adapter(struct work_struct *work) |
1879 | { | 1961 | { |
1880 | struct ipw2100_priv *priv = | 1962 | struct ipw2100_priv *priv = |
@@ -2090,6 +2172,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) | |||
2090 | priv->net_dev->name); | 2172 | priv->net_dev->name); |
2091 | 2173 | ||
2092 | /* RF_KILL is now enabled (else we wouldn't be here) */ | 2174 | /* RF_KILL is now enabled (else we wouldn't be here) */ |
2175 | wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true); | ||
2093 | priv->status |= STATUS_RF_KILL_HW; | 2176 | priv->status |= STATUS_RF_KILL_HW; |
2094 | 2177 | ||
2095 | /* Make sure the RF Kill check timer is running */ | 2178 | /* Make sure the RF Kill check timer is running */ |
@@ -3044,7 +3127,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv) | |||
3044 | IPW_MAX_BDS)) { | 3127 | IPW_MAX_BDS)) { |
3045 | /* TODO: Support merging buffers if more than | 3128 | /* TODO: Support merging buffers if more than |
3046 | * IPW_MAX_BDS are used */ | 3129 | * IPW_MAX_BDS are used */ |
3047 | IPW_DEBUG_INFO("%s: Maximum BD theshold exceeded. " | 3130 | IPW_DEBUG_INFO("%s: Maximum BD threshold exceeded. " |
3048 | "Increase fragmentation level.\n", | 3131 | "Increase fragmentation level.\n", |
3049 | priv->net_dev->name); | 3132 | priv->net_dev->name); |
3050 | } | 3133 | } |
@@ -6029,7 +6112,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6029 | struct ipw2100_priv *priv; | 6112 | struct ipw2100_priv *priv; |
6030 | struct net_device *dev; | 6113 | struct net_device *dev; |
6031 | 6114 | ||
6032 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv)); | 6115 | dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0); |
6033 | if (!dev) | 6116 | if (!dev) |
6034 | return NULL; | 6117 | return NULL; |
6035 | priv = libipw_priv(dev); | 6118 | priv = libipw_priv(dev); |
@@ -6342,7 +6425,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, | |||
6342 | sysfs_remove_group(&pci_dev->dev.kobj, | 6425 | sysfs_remove_group(&pci_dev->dev.kobj, |
6343 | &ipw2100_attribute_group); | 6426 | &ipw2100_attribute_group); |
6344 | 6427 | ||
6345 | free_ieee80211(dev); | 6428 | free_ieee80211(dev, 0); |
6346 | pci_set_drvdata(pci_dev, NULL); | 6429 | pci_set_drvdata(pci_dev, NULL); |
6347 | } | 6430 | } |
6348 | 6431 | ||
@@ -6400,7 +6483,10 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) | |||
6400 | if (dev->base_addr) | 6483 | if (dev->base_addr) |
6401 | iounmap((void __iomem *)dev->base_addr); | 6484 | iounmap((void __iomem *)dev->base_addr); |
6402 | 6485 | ||
6403 | free_ieee80211(dev); | 6486 | /* wiphy_unregister needs to be here, before free_ieee80211 */ |
6487 | wiphy_unregister(priv->ieee->wdev.wiphy); | ||
6488 | kfree(priv->ieee->bg_band.channels); | ||
6489 | free_ieee80211(dev, 0); | ||
6404 | } | 6490 | } |
6405 | 6491 | ||
6406 | pci_release_regions(pci_dev); | 6492 | pci_release_regions(pci_dev); |
@@ -6487,9 +6573,19 @@ static int ipw2100_resume(struct pci_dev *pci_dev) | |||
6487 | } | 6573 | } |
6488 | #endif | 6574 | #endif |
6489 | 6575 | ||
6576 | static void ipw2100_shutdown(struct pci_dev *pci_dev) | ||
6577 | { | ||
6578 | struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); | ||
6579 | |||
6580 | /* Take down the device; powers it off, etc. */ | ||
6581 | ipw2100_down(priv); | ||
6582 | |||
6583 | pci_disable_device(pci_dev); | ||
6584 | } | ||
6585 | |||
6490 | #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } | 6586 | #define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x } |
6491 | 6587 | ||
6492 | static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = { | 6588 | static DEFINE_PCI_DEVICE_TABLE(ipw2100_pci_id_table) = { |
6493 | IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ | 6589 | IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */ |
6494 | IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ | 6590 | IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */ |
6495 | IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ | 6591 | IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */ |
@@ -6550,6 +6646,7 @@ static struct pci_driver ipw2100_pci_driver = { | |||
6550 | .suspend = ipw2100_suspend, | 6646 | .suspend = ipw2100_suspend, |
6551 | .resume = ipw2100_resume, | 6647 | .resume = ipw2100_resume, |
6552 | #endif | 6648 | #endif |
6649 | .shutdown = ipw2100_shutdown, | ||
6553 | }; | 6650 | }; |
6554 | 6651 | ||
6555 | /** | 6652 | /** |
@@ -6601,26 +6698,6 @@ static void __exit ipw2100_exit(void) | |||
6601 | module_init(ipw2100_init); | 6698 | module_init(ipw2100_init); |
6602 | module_exit(ipw2100_exit); | 6699 | module_exit(ipw2100_exit); |
6603 | 6700 | ||
6604 | #define WEXT_USECHANNELS 1 | ||
6605 | |||
6606 | static const long ipw2100_frequencies[] = { | ||
6607 | 2412, 2417, 2422, 2427, | ||
6608 | 2432, 2437, 2442, 2447, | ||
6609 | 2452, 2457, 2462, 2467, | ||
6610 | 2472, 2484 | ||
6611 | }; | ||
6612 | |||
6613 | #define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) | ||
6614 | |||
6615 | static const long ipw2100_rates_11b[] = { | ||
6616 | 1000000, | ||
6617 | 2000000, | ||
6618 | 5500000, | ||
6619 | 11000000 | ||
6620 | }; | ||
6621 | |||
6622 | #define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b) | ||
6623 | |||
6624 | static int ipw2100_wx_get_name(struct net_device *dev, | 6701 | static int ipw2100_wx_get_name(struct net_device *dev, |
6625 | struct iw_request_info *info, | 6702 | struct iw_request_info *info, |
6626 | union iwreq_data *wrqu, char *extra) | 6703 | union iwreq_data *wrqu, char *extra) |
@@ -6820,7 +6897,7 @@ static int ipw2100_wx_get_range(struct net_device *dev, | |||
6820 | range->max_qual.updated = 7; /* Updated all three */ | 6897 | range->max_qual.updated = 7; /* Updated all three */ |
6821 | 6898 | ||
6822 | range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ | 6899 | range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ |
6823 | /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ | 6900 | /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ |
6824 | range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; | 6901 | range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM; |
6825 | range->avg_qual.noise = 0; | 6902 | range->avg_qual.noise = 0; |
6826 | range->avg_qual.updated = 7; /* Updated all three */ | 6903 | range->avg_qual.updated = 7; /* Updated all three */ |
@@ -8462,6 +8539,12 @@ static int ipw2100_get_firmware(struct ipw2100_priv *priv, | |||
8462 | return 0; | 8539 | return 0; |
8463 | } | 8540 | } |
8464 | 8541 | ||
8542 | MODULE_FIRMWARE(IPW2100_FW_NAME("-i")); | ||
8543 | #ifdef CONFIG_IPW2100_MONITOR | ||
8544 | MODULE_FIRMWARE(IPW2100_FW_NAME("-p")); | ||
8545 | #endif | ||
8546 | MODULE_FIRMWARE(IPW2100_FW_NAME("")); | ||
8547 | |||
8465 | static void ipw2100_release_firmware(struct ipw2100_priv *priv, | 8548 | static void ipw2100_release_firmware(struct ipw2100_priv *priv, |
8466 | struct ipw2100_fw *fw) | 8549 | struct ipw2100_fw *fw) |
8467 | { | 8550 | { |
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 | ||
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 1e334ff6bd52..a6d5e42647e4 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/ieee80211.h> | 31 | #include <linux/ieee80211.h> |
32 | 32 | ||
33 | #include <net/lib80211.h> | 33 | #include <net/lib80211.h> |
34 | #include <net/cfg80211.h> | ||
34 | 35 | ||
35 | #define LIBIPW_VERSION "git-1.1.13" | 36 | #define LIBIPW_VERSION "git-1.1.13" |
36 | 37 | ||
@@ -783,17 +784,20 @@ struct libipw_geo { | |||
783 | 784 | ||
784 | struct libipw_device { | 785 | struct libipw_device { |
785 | struct net_device *dev; | 786 | struct net_device *dev; |
787 | struct wireless_dev wdev; | ||
786 | struct libipw_security sec; | 788 | struct libipw_security sec; |
787 | 789 | ||
788 | /* Bookkeeping structures */ | 790 | /* Bookkeeping structures */ |
789 | struct libipw_stats ieee_stats; | 791 | struct libipw_stats ieee_stats; |
790 | 792 | ||
791 | struct libipw_geo geo; | 793 | struct libipw_geo geo; |
794 | struct ieee80211_supported_band bg_band; | ||
795 | struct ieee80211_supported_band a_band; | ||
792 | 796 | ||
793 | /* Probe / Beacon management */ | 797 | /* Probe / Beacon management */ |
794 | struct list_head network_free_list; | 798 | struct list_head network_free_list; |
795 | struct list_head network_list; | 799 | struct list_head network_list; |
796 | struct libipw_network *networks; | 800 | struct libipw_network *networks[MAX_NETWORK_COUNT]; |
797 | int scans; | 801 | int scans; |
798 | int scan_age; | 802 | int scan_age; |
799 | 803 | ||
@@ -1014,8 +1018,8 @@ static inline int libipw_is_cck_rate(u8 rate) | |||
1014 | } | 1018 | } |
1015 | 1019 | ||
1016 | /* ieee80211.c */ | 1020 | /* ieee80211.c */ |
1017 | extern void free_ieee80211(struct net_device *dev); | 1021 | extern void free_ieee80211(struct net_device *dev, int monitor); |
1018 | extern struct net_device *alloc_ieee80211(int sizeof_priv); | 1022 | extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor); |
1019 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); | 1023 | extern int libipw_change_mtu(struct net_device *dev, int new_mtu); |
1020 | 1024 | ||
1021 | extern void libipw_networks_age(struct libipw_device *ieee, | 1025 | extern void libipw_networks_age(struct libipw_device *ieee, |
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c index 65e8c175a4a0..c9fe3c99cb00 100644 --- a/drivers/net/wireless/ipw2x00/libipw_geo.c +++ b/drivers/net/wireless/ipw2x00/libipw_geo.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/netdevice.h> | 34 | #include <linux/netdevice.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/slab.h> | ||
38 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
39 | #include <linux/types.h> | 38 | #include <linux/types.h> |
40 | #include <linux/wireless.h> | 39 | #include <linux/wireless.h> |
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index eb2b60834c17..2fa55867bd8b 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c | |||
@@ -62,18 +62,22 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION); | |||
62 | MODULE_AUTHOR(DRV_COPYRIGHT); | 62 | MODULE_AUTHOR(DRV_COPYRIGHT); |
63 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
64 | 64 | ||
65 | struct cfg80211_ops libipw_config_ops = { }; | ||
66 | void *libipw_wiphy_privid = &libipw_wiphy_privid; | ||
67 | |||
65 | static int libipw_networks_allocate(struct libipw_device *ieee) | 68 | static int libipw_networks_allocate(struct libipw_device *ieee) |
66 | { | 69 | { |
67 | if (ieee->networks) | 70 | int i, j; |
68 | return 0; | 71 | |
69 | 72 | for (i = 0; i < MAX_NETWORK_COUNT; i++) { | |
70 | ieee->networks = | 73 | ieee->networks[i] = kzalloc(sizeof(struct libipw_network), |
71 | kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), | 74 | GFP_KERNEL); |
72 | GFP_KERNEL); | 75 | if (!ieee->networks[i]) { |
73 | if (!ieee->networks) { | 76 | LIBIPW_ERROR("Out of memory allocating beacons\n"); |
74 | printk(KERN_WARNING "%s: Out of memory allocating beacons\n", | 77 | for (j = 0; j < i; j++) |
75 | ieee->dev->name); | 78 | kfree(ieee->networks[j]); |
76 | return -ENOMEM; | 79 | return -ENOMEM; |
80 | } | ||
77 | } | 81 | } |
78 | 82 | ||
79 | return 0; | 83 | return 0; |
@@ -94,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee) | |||
94 | { | 98 | { |
95 | int i; | 99 | int i; |
96 | 100 | ||
97 | if (!ieee->networks) | 101 | for (i = 0; i < MAX_NETWORK_COUNT; i++) { |
98 | return; | 102 | if (ieee->networks[i]->ibss_dfs) |
99 | 103 | kfree(ieee->networks[i]->ibss_dfs); | |
100 | for (i = 0; i < MAX_NETWORK_COUNT; i++) | 104 | kfree(ieee->networks[i]); |
101 | if (ieee->networks[i].ibss_dfs) | 105 | } |
102 | kfree(ieee->networks[i].ibss_dfs); | ||
103 | |||
104 | kfree(ieee->networks); | ||
105 | ieee->networks = NULL; | ||
106 | } | 106 | } |
107 | 107 | ||
108 | void libipw_networks_age(struct libipw_device *ieee, | 108 | void libipw_networks_age(struct libipw_device *ieee, |
@@ -127,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee) | |||
127 | INIT_LIST_HEAD(&ieee->network_free_list); | 127 | INIT_LIST_HEAD(&ieee->network_free_list); |
128 | INIT_LIST_HEAD(&ieee->network_list); | 128 | INIT_LIST_HEAD(&ieee->network_list); |
129 | for (i = 0; i < MAX_NETWORK_COUNT; i++) | 129 | for (i = 0; i < MAX_NETWORK_COUNT; i++) |
130 | list_add_tail(&ieee->networks[i].list, | 130 | list_add_tail(&ieee->networks[i]->list, |
131 | &ieee->network_free_list); | 131 | &ieee->network_free_list); |
132 | } | 132 | } |
133 | 133 | ||
@@ -140,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu) | |||
140 | } | 140 | } |
141 | EXPORT_SYMBOL(libipw_change_mtu); | 141 | EXPORT_SYMBOL(libipw_change_mtu); |
142 | 142 | ||
143 | struct net_device *alloc_ieee80211(int sizeof_priv) | 143 | struct net_device *alloc_ieee80211(int sizeof_priv, int monitor) |
144 | { | 144 | { |
145 | struct libipw_device *ieee; | 145 | struct libipw_device *ieee; |
146 | struct net_device *dev; | 146 | struct net_device *dev; |
@@ -157,10 +157,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
157 | 157 | ||
158 | ieee->dev = dev; | 158 | ieee->dev = dev; |
159 | 159 | ||
160 | if (!monitor) { | ||
161 | ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0); | ||
162 | if (!ieee->wdev.wiphy) { | ||
163 | LIBIPW_ERROR("Unable to allocate wiphy.\n"); | ||
164 | goto failed_free_netdev; | ||
165 | } | ||
166 | |||
167 | ieee->dev->ieee80211_ptr = &ieee->wdev; | ||
168 | ieee->wdev.iftype = NL80211_IFTYPE_STATION; | ||
169 | |||
170 | /* Fill-out wiphy structure bits we know... Not enough info | ||
171 | here to call set_wiphy_dev or set MAC address or channel info | ||
172 | -- have to do that in ->ndo_init... */ | ||
173 | ieee->wdev.wiphy->privid = libipw_wiphy_privid; | ||
174 | |||
175 | ieee->wdev.wiphy->max_scan_ssids = 1; | ||
176 | ieee->wdev.wiphy->max_scan_ie_len = 0; | ||
177 | ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ||
178 | | BIT(NL80211_IFTYPE_ADHOC); | ||
179 | } | ||
180 | |||
160 | err = libipw_networks_allocate(ieee); | 181 | err = libipw_networks_allocate(ieee); |
161 | if (err) { | 182 | if (err) { |
162 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); | 183 | LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); |
163 | goto failed_free_netdev; | 184 | goto failed_free_wiphy; |
164 | } | 185 | } |
165 | libipw_networks_initialize(ieee); | 186 | libipw_networks_initialize(ieee); |
166 | 187 | ||
@@ -175,7 +196,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
175 | ieee->host_decrypt = 1; | 196 | ieee->host_decrypt = 1; |
176 | ieee->host_mc_decrypt = 1; | 197 | ieee->host_mc_decrypt = 1; |
177 | 198 | ||
178 | /* Host fragementation in Open mode. Default is enabled. | 199 | /* Host fragmentation in Open mode. Default is enabled. |
179 | * Note: host fragmentation is always enabled if host encryption | 200 | * Note: host fragmentation is always enabled if host encryption |
180 | * is enabled. For cards can do hardware encryption, they must do | 201 | * is enabled. For cards can do hardware encryption, they must do |
181 | * hardware fragmentation as well. So we don't need a variable | 202 | * hardware fragmentation as well. So we don't need a variable |
@@ -193,19 +214,27 @@ struct net_device *alloc_ieee80211(int sizeof_priv) | |||
193 | 214 | ||
194 | return dev; | 215 | return dev; |
195 | 216 | ||
217 | failed_free_wiphy: | ||
218 | if (!monitor) | ||
219 | wiphy_free(ieee->wdev.wiphy); | ||
196 | failed_free_netdev: | 220 | failed_free_netdev: |
197 | free_netdev(dev); | 221 | free_netdev(dev); |
198 | failed: | 222 | failed: |
199 | return NULL; | 223 | return NULL; |
200 | } | 224 | } |
201 | 225 | ||
202 | void free_ieee80211(struct net_device *dev) | 226 | void free_ieee80211(struct net_device *dev, int monitor) |
203 | { | 227 | { |
204 | struct libipw_device *ieee = netdev_priv(dev); | 228 | struct libipw_device *ieee = netdev_priv(dev); |
205 | 229 | ||
206 | lib80211_crypt_info_free(&ieee->crypt_info); | 230 | lib80211_crypt_info_free(&ieee->crypt_info); |
207 | 231 | ||
208 | libipw_networks_free(ieee); | 232 | libipw_networks_free(ieee); |
233 | |||
234 | /* free cfg80211 resources */ | ||
235 | if (!monitor) | ||
236 | wiphy_free(ieee->wdev.wiphy); | ||
237 | |||
209 | free_netdev(dev); | 238 | free_netdev(dev); |
210 | } | 239 | } |
211 | 240 | ||
@@ -216,17 +245,22 @@ u32 libipw_debug_level = 0; | |||
216 | EXPORT_SYMBOL_GPL(libipw_debug_level); | 245 | EXPORT_SYMBOL_GPL(libipw_debug_level); |
217 | static struct proc_dir_entry *libipw_proc = NULL; | 246 | static struct proc_dir_entry *libipw_proc = NULL; |
218 | 247 | ||
219 | static int show_debug_level(char *page, char **start, off_t offset, | 248 | static int debug_level_proc_show(struct seq_file *m, void *v) |
220 | int count, int *eof, void *data) | ||
221 | { | 249 | { |
222 | return snprintf(page, count, "0x%08X\n", libipw_debug_level); | 250 | seq_printf(m, "0x%08X\n", libipw_debug_level); |
251 | return 0; | ||
223 | } | 252 | } |
224 | 253 | ||
225 | static int store_debug_level(struct file *file, const char __user * buffer, | 254 | static int debug_level_proc_open(struct inode *inode, struct file *file) |
226 | unsigned long count, void *data) | 255 | { |
256 | return single_open(file, debug_level_proc_show, NULL); | ||
257 | } | ||
258 | |||
259 | static ssize_t debug_level_proc_write(struct file *file, | ||
260 | const char __user *buffer, size_t count, loff_t *pos) | ||
227 | { | 261 | { |
228 | char buf[] = "0x00000000\n"; | 262 | char buf[] = "0x00000000\n"; |
229 | unsigned long len = min((unsigned long)sizeof(buf) - 1, count); | 263 | size_t len = min(sizeof(buf) - 1, count); |
230 | unsigned long val; | 264 | unsigned long val; |
231 | 265 | ||
232 | if (copy_from_user(buf, buffer, len)) | 266 | if (copy_from_user(buf, buffer, len)) |
@@ -240,6 +274,15 @@ static int store_debug_level(struct file *file, const char __user * buffer, | |||
240 | 274 | ||
241 | return strnlen(buf, len); | 275 | return strnlen(buf, len); |
242 | } | 276 | } |
277 | |||
278 | static const struct file_operations debug_level_proc_fops = { | ||
279 | .owner = THIS_MODULE, | ||
280 | .open = debug_level_proc_open, | ||
281 | .read = seq_read, | ||
282 | .llseek = seq_lseek, | ||
283 | .release = single_release, | ||
284 | .write = debug_level_proc_write, | ||
285 | }; | ||
243 | #endif /* CONFIG_LIBIPW_DEBUG */ | 286 | #endif /* CONFIG_LIBIPW_DEBUG */ |
244 | 287 | ||
245 | static int __init libipw_init(void) | 288 | static int __init libipw_init(void) |
@@ -254,16 +297,13 @@ static int __init libipw_init(void) | |||
254 | " proc directory\n"); | 297 | " proc directory\n"); |
255 | return -EIO; | 298 | return -EIO; |
256 | } | 299 | } |
257 | e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, | 300 | e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, |
258 | libipw_proc); | 301 | &debug_level_proc_fops); |
259 | if (!e) { | 302 | if (!e) { |
260 | remove_proc_entry(DRV_NAME, init_net.proc_net); | 303 | remove_proc_entry(DRV_NAME, init_net.proc_net); |
261 | libipw_proc = NULL; | 304 | libipw_proc = NULL; |
262 | return -EIO; | 305 | return -EIO; |
263 | } | 306 | } |
264 | e->read_proc = show_debug_level; | ||
265 | e->write_proc = store_debug_level; | ||
266 | e->data = NULL; | ||
267 | #endif /* CONFIG_LIBIPW_DEBUG */ | 307 | #endif /* CONFIG_LIBIPW_DEBUG */ |
268 | 308 | ||
269 | printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); | 309 | printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); |
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c index 282b1f7ff1e9..39a34da52d52 100644 --- a/drivers/net/wireless/ipw2x00/libipw_rx.c +++ b/drivers/net/wireless/ipw2x00/libipw_rx.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/if_arp.h> | 18 | #include <linux/if_arp.h> |
19 | #include <linux/in6.h> | 19 | #include <linux/in6.h> |
20 | #include <linux/gfp.h> | ||
20 | #include <linux/in.h> | 21 | #include <linux/in.h> |
21 | #include <linux/ip.h> | 22 | #include <linux/ip.h> |
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
@@ -24,7 +25,6 @@ | |||
24 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
25 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
26 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
27 | #include <linux/slab.h> | ||
28 | #include <linux/tcp.h> | 28 | #include <linux/tcp.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/wireless.h> | 30 | #include <linux/wireless.h> |
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c index 4d89f66f53b2..3633c6682e49 100644 --- a/drivers/net/wireless/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/ipw2x00/libipw_wx.c | |||
@@ -31,6 +31,7 @@ | |||
31 | ******************************************************************************/ | 31 | ******************************************************************************/ |
32 | 32 | ||
33 | #include <linux/kmod.h> | 33 | #include <linux/kmod.h> |
34 | #include <linux/slab.h> | ||
34 | #include <linux/module.h> | 35 | #include <linux/module.h> |
35 | #include <linux/jiffies.h> | 36 | #include <linux/jiffies.h> |
36 | 37 | ||