diff options
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 450 |
1 files changed, 188 insertions, 262 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index ed37141319ea..9dce522526c5 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | 2 | ||
3 | Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. | 3 | Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. |
4 | 4 | ||
5 | 802.11 status code portion of this file from ethereal-0.10.6: | 5 | 802.11 status code portion of this file from ethereal-0.10.6: |
6 | Copyright 2000, Axis Communications AB | 6 | Copyright 2000, Axis Communications AB |
@@ -33,9 +33,9 @@ | |||
33 | #include "ipw2200.h" | 33 | #include "ipw2200.h" |
34 | #include <linux/version.h> | 34 | #include <linux/version.h> |
35 | 35 | ||
36 | #define IPW2200_VERSION "git-1.0.10" | 36 | #define IPW2200_VERSION "git-1.1.1" |
37 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" | 37 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" |
38 | #define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" | 38 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" |
39 | #define DRV_VERSION IPW2200_VERSION | 39 | #define DRV_VERSION IPW2200_VERSION |
40 | 40 | ||
41 | #define ETH_P_80211_STATS (ETH_P_80211_RAW + 1) | 41 | #define ETH_P_80211_STATS (ETH_P_80211_RAW + 1) |
@@ -153,12 +153,6 @@ static int init_supported_rates(struct ipw_priv *priv, | |||
153 | static void ipw_set_hwcrypto_keys(struct ipw_priv *); | 153 | static void ipw_set_hwcrypto_keys(struct ipw_priv *); |
154 | static void ipw_send_wep_keys(struct ipw_priv *, int); | 154 | static void ipw_send_wep_keys(struct ipw_priv *, int); |
155 | 155 | ||
156 | static int ipw_is_valid_channel(struct ieee80211_device *, u8); | ||
157 | static int ipw_channel_to_index(struct ieee80211_device *, u8); | ||
158 | static u8 ipw_freq_to_channel(struct ieee80211_device *, u32); | ||
159 | static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *); | ||
160 | static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *); | ||
161 | |||
162 | static int snprint_line(char *buf, size_t count, | 156 | static int snprint_line(char *buf, size_t count, |
163 | const u8 * data, u32 len, u32 ofs) | 157 | const u8 * data, u32 len, u32 ofs) |
164 | { | 158 | { |
@@ -1654,7 +1648,7 @@ static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr, | |||
1654 | break; | 1648 | break; |
1655 | } | 1649 | } |
1656 | 1650 | ||
1657 | if (ipw_is_valid_channel(priv->ieee, channel)) | 1651 | if (ieee80211_is_valid_channel(priv->ieee, channel)) |
1658 | priv->speed_scan[pos++] = channel; | 1652 | priv->speed_scan[pos++] = channel; |
1659 | else | 1653 | else |
1660 | IPW_WARNING("Skipping invalid channel request: %d\n", | 1654 | IPW_WARNING("Skipping invalid channel request: %d\n", |
@@ -1802,9 +1796,9 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
1802 | } | 1796 | } |
1803 | 1797 | ||
1804 | if (inta & IPW_INTA_BIT_FATAL_ERROR) { | 1798 | if (inta & IPW_INTA_BIT_FATAL_ERROR) { |
1805 | IPW_ERROR("Firmware error detected. Restarting.\n"); | 1799 | IPW_WARNING("Firmware error detected. Restarting.\n"); |
1806 | if (priv->error) { | 1800 | if (priv->error) { |
1807 | IPW_ERROR("Sysfs 'error' log already exists.\n"); | 1801 | IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); |
1808 | #ifdef CONFIG_IPW2200_DEBUG | 1802 | #ifdef CONFIG_IPW2200_DEBUG |
1809 | if (ipw_debug_level & IPW_DL_FW_ERRORS) { | 1803 | if (ipw_debug_level & IPW_DL_FW_ERRORS) { |
1810 | struct ipw_fw_error *error = | 1804 | struct ipw_fw_error *error = |
@@ -1817,10 +1811,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
1817 | } else { | 1811 | } else { |
1818 | priv->error = ipw_alloc_error_log(priv); | 1812 | priv->error = ipw_alloc_error_log(priv); |
1819 | if (priv->error) | 1813 | if (priv->error) |
1820 | IPW_ERROR("Sysfs 'error' log captured.\n"); | 1814 | IPW_DEBUG_FW("Sysfs 'error' log captured.\n"); |
1821 | else | 1815 | else |
1822 | IPW_ERROR("Error allocating sysfs 'error' " | 1816 | IPW_DEBUG_FW("Error allocating sysfs 'error' " |
1823 | "log.\n"); | 1817 | "log.\n"); |
1824 | #ifdef CONFIG_IPW2200_DEBUG | 1818 | #ifdef CONFIG_IPW2200_DEBUG |
1825 | if (ipw_debug_level & IPW_DL_FW_ERRORS) | 1819 | if (ipw_debug_level & IPW_DL_FW_ERRORS) |
1826 | ipw_dump_error_log(priv, priv->error); | 1820 | ipw_dump_error_log(priv, priv->error); |
@@ -2222,7 +2216,7 @@ static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power) | |||
2222 | 2216 | ||
2223 | static int ipw_set_tx_power(struct ipw_priv *priv) | 2217 | static int ipw_set_tx_power(struct ipw_priv *priv) |
2224 | { | 2218 | { |
2225 | const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); | 2219 | const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); |
2226 | struct ipw_tx_power tx_power; | 2220 | struct ipw_tx_power tx_power; |
2227 | s8 max_power; | 2221 | s8 max_power; |
2228 | int i; | 2222 | int i; |
@@ -2835,33 +2829,11 @@ static void ipw_arc_release(struct ipw_priv *priv) | |||
2835 | mdelay(5); | 2829 | mdelay(5); |
2836 | } | 2830 | } |
2837 | 2831 | ||
2838 | struct fw_header { | ||
2839 | u32 version; | ||
2840 | u32 mode; | ||
2841 | }; | ||
2842 | |||
2843 | struct fw_chunk { | 2832 | struct fw_chunk { |
2844 | u32 address; | 2833 | u32 address; |
2845 | u32 length; | 2834 | u32 length; |
2846 | }; | 2835 | }; |
2847 | 2836 | ||
2848 | #define IPW_FW_MAJOR_VERSION 2 | ||
2849 | #define IPW_FW_MINOR_VERSION 4 | ||
2850 | |||
2851 | #define IPW_FW_MINOR(x) ((x & 0xff) >> 8) | ||
2852 | #define IPW_FW_MAJOR(x) (x & 0xff) | ||
2853 | |||
2854 | #define IPW_FW_VERSION ((IPW_FW_MINOR_VERSION << 8) | IPW_FW_MAJOR_VERSION) | ||
2855 | |||
2856 | #define IPW_FW_PREFIX "ipw-" __stringify(IPW_FW_MAJOR_VERSION) \ | ||
2857 | "." __stringify(IPW_FW_MINOR_VERSION) "-" | ||
2858 | |||
2859 | #if IPW_FW_MAJOR_VERSION >= 2 && IPW_FW_MINOR_VERSION > 0 | ||
2860 | #define IPW_FW_NAME(x) IPW_FW_PREFIX "" x ".fw" | ||
2861 | #else | ||
2862 | #define IPW_FW_NAME(x) "ipw2200_" x ".fw" | ||
2863 | #endif | ||
2864 | |||
2865 | static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) | 2837 | static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len) |
2866 | { | 2838 | { |
2867 | int rc = 0, i, addr; | 2839 | int rc = 0, i, addr; |
@@ -3130,33 +3102,47 @@ static int ipw_reset_nic(struct ipw_priv *priv) | |||
3130 | return rc; | 3102 | return rc; |
3131 | } | 3103 | } |
3132 | 3104 | ||
3105 | |||
3106 | struct ipw_fw { | ||
3107 | u32 ver; | ||
3108 | u32 boot_size; | ||
3109 | u32 ucode_size; | ||
3110 | u32 fw_size; | ||
3111 | u8 data[0]; | ||
3112 | }; | ||
3113 | |||
3133 | static int ipw_get_fw(struct ipw_priv *priv, | 3114 | static int ipw_get_fw(struct ipw_priv *priv, |
3134 | const struct firmware **fw, const char *name) | 3115 | const struct firmware **raw, const char *name) |
3135 | { | 3116 | { |
3136 | struct fw_header *header; | 3117 | struct ipw_fw *fw; |
3137 | int rc; | 3118 | int rc; |
3138 | 3119 | ||
3139 | /* ask firmware_class module to get the boot firmware off disk */ | 3120 | /* ask firmware_class module to get the boot firmware off disk */ |
3140 | rc = request_firmware(fw, name, &priv->pci_dev->dev); | 3121 | rc = request_firmware(raw, name, &priv->pci_dev->dev); |
3141 | if (rc < 0) { | 3122 | if (rc < 0) { |
3142 | IPW_ERROR("%s load failed: Reason %d\n", name, rc); | 3123 | IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc); |
3143 | return rc; | 3124 | return rc; |
3144 | } | 3125 | } |
3145 | 3126 | ||
3146 | header = (struct fw_header *)(*fw)->data; | 3127 | if ((*raw)->size < sizeof(*fw)) { |
3147 | if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) { | 3128 | IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size); |
3148 | IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n", | ||
3149 | name, | ||
3150 | IPW_FW_MAJOR(le32_to_cpu(header->version)), | ||
3151 | IPW_FW_MAJOR_VERSION); | ||
3152 | return -EINVAL; | 3129 | return -EINVAL; |
3153 | } | 3130 | } |
3154 | 3131 | ||
3155 | IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n", | 3132 | fw = (void *)(*raw)->data; |
3133 | |||
3134 | if ((*raw)->size < sizeof(*fw) + | ||
3135 | fw->boot_size + fw->ucode_size + fw->fw_size) { | ||
3136 | IPW_ERROR("%s is too small or corrupt (%zd)\n", | ||
3137 | name, (*raw)->size); | ||
3138 | return -EINVAL; | ||
3139 | } | ||
3140 | |||
3141 | IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n", | ||
3156 | name, | 3142 | name, |
3157 | IPW_FW_MAJOR(le32_to_cpu(header->version)), | 3143 | le32_to_cpu(fw->ver) >> 16, |
3158 | IPW_FW_MINOR(le32_to_cpu(header->version)), | 3144 | le32_to_cpu(fw->ver) & 0xff, |
3159 | (*fw)->size - sizeof(struct fw_header)); | 3145 | (*raw)->size - sizeof(*fw)); |
3160 | return 0; | 3146 | return 0; |
3161 | } | 3147 | } |
3162 | 3148 | ||
@@ -3196,17 +3182,13 @@ static void ipw_rx_queue_reset(struct ipw_priv *priv, | |||
3196 | 3182 | ||
3197 | #ifdef CONFIG_PM | 3183 | #ifdef CONFIG_PM |
3198 | static int fw_loaded = 0; | 3184 | static int fw_loaded = 0; |
3199 | static const struct firmware *bootfw = NULL; | 3185 | static const struct firmware *raw = NULL; |
3200 | static const struct firmware *firmware = NULL; | ||
3201 | static const struct firmware *ucode = NULL; | ||
3202 | 3186 | ||
3203 | static void free_firmware(void) | 3187 | static void free_firmware(void) |
3204 | { | 3188 | { |
3205 | if (fw_loaded) { | 3189 | if (fw_loaded) { |
3206 | release_firmware(bootfw); | 3190 | release_firmware(raw); |
3207 | release_firmware(ucode); | 3191 | raw = NULL; |
3208 | release_firmware(firmware); | ||
3209 | bootfw = ucode = firmware = NULL; | ||
3210 | fw_loaded = 0; | 3192 | fw_loaded = 0; |
3211 | } | 3193 | } |
3212 | } | 3194 | } |
@@ -3217,32 +3199,46 @@ static void free_firmware(void) | |||
3217 | static int ipw_load(struct ipw_priv *priv) | 3199 | static int ipw_load(struct ipw_priv *priv) |
3218 | { | 3200 | { |
3219 | #ifndef CONFIG_PM | 3201 | #ifndef CONFIG_PM |
3220 | const struct firmware *bootfw = NULL; | 3202 | const struct firmware *raw = NULL; |
3221 | const struct firmware *firmware = NULL; | ||
3222 | const struct firmware *ucode = NULL; | ||
3223 | #endif | 3203 | #endif |
3224 | char *ucode_name; | 3204 | struct ipw_fw *fw; |
3225 | char *fw_name; | 3205 | u8 *boot_img, *ucode_img, *fw_img; |
3206 | u8 *name = NULL; | ||
3226 | int rc = 0, retries = 3; | 3207 | int rc = 0, retries = 3; |
3227 | 3208 | ||
3228 | switch (priv->ieee->iw_mode) { | 3209 | switch (priv->ieee->iw_mode) { |
3229 | case IW_MODE_ADHOC: | 3210 | case IW_MODE_ADHOC: |
3230 | ucode_name = IPW_FW_NAME("ibss_ucode"); | 3211 | name = "ipw2200-ibss.fw"; |
3231 | fw_name = IPW_FW_NAME("ibss"); | ||
3232 | break; | 3212 | break; |
3233 | #ifdef CONFIG_IPW2200_MONITOR | 3213 | #ifdef CONFIG_IPW2200_MONITOR |
3234 | case IW_MODE_MONITOR: | 3214 | case IW_MODE_MONITOR: |
3235 | ucode_name = IPW_FW_NAME("sniffer_ucode"); | 3215 | name = "ipw2200-sniffer.fw"; |
3236 | fw_name = IPW_FW_NAME("sniffer"); | ||
3237 | break; | 3216 | break; |
3238 | #endif | 3217 | #endif |
3239 | case IW_MODE_INFRA: | 3218 | case IW_MODE_INFRA: |
3240 | ucode_name = IPW_FW_NAME("bss_ucode"); | 3219 | name = "ipw2200-bss.fw"; |
3241 | fw_name = IPW_FW_NAME("bss"); | ||
3242 | break; | 3220 | break; |
3243 | default: | 3221 | } |
3222 | |||
3223 | if (!name) { | ||
3244 | rc = -EINVAL; | 3224 | rc = -EINVAL; |
3225 | goto error; | ||
3226 | } | ||
3227 | |||
3228 | #ifdef CONFIG_PM | ||
3229 | if (!fw_loaded) { | ||
3230 | #endif | ||
3231 | rc = ipw_get_fw(priv, &raw, name); | ||
3232 | if (rc < 0) | ||
3233 | goto error; | ||
3234 | #ifdef CONFIG_PM | ||
3245 | } | 3235 | } |
3236 | #endif | ||
3237 | |||
3238 | fw = (void *)raw->data; | ||
3239 | boot_img = &fw->data[0]; | ||
3240 | ucode_img = &fw->data[fw->boot_size]; | ||
3241 | fw_img = &fw->data[fw->boot_size + fw->ucode_size]; | ||
3246 | 3242 | ||
3247 | if (rc < 0) | 3243 | if (rc < 0) |
3248 | goto error; | 3244 | goto error; |
@@ -3275,18 +3271,8 @@ static int ipw_load(struct ipw_priv *priv) | |||
3275 | ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, | 3271 | ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND, |
3276 | IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); | 3272 | IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND); |
3277 | 3273 | ||
3278 | #ifdef CONFIG_PM | ||
3279 | if (!fw_loaded) { | ||
3280 | #endif | ||
3281 | rc = ipw_get_fw(priv, &bootfw, IPW_FW_NAME("boot")); | ||
3282 | if (rc < 0) | ||
3283 | goto error; | ||
3284 | #ifdef CONFIG_PM | ||
3285 | } | ||
3286 | #endif | ||
3287 | /* DMA the initial boot firmware into the device */ | 3274 | /* DMA the initial boot firmware into the device */ |
3288 | rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header), | 3275 | rc = ipw_load_firmware(priv, boot_img, fw->boot_size); |
3289 | bootfw->size - sizeof(struct fw_header)); | ||
3290 | if (rc < 0) { | 3276 | if (rc < 0) { |
3291 | IPW_ERROR("Unable to load boot firmware: %d\n", rc); | 3277 | IPW_ERROR("Unable to load boot firmware: %d\n", rc); |
3292 | goto error; | 3278 | goto error; |
@@ -3307,19 +3293,8 @@ static int ipw_load(struct ipw_priv *priv) | |||
3307 | /* ack fw init done interrupt */ | 3293 | /* ack fw init done interrupt */ |
3308 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); | 3294 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE); |
3309 | 3295 | ||
3310 | #ifdef CONFIG_PM | ||
3311 | if (!fw_loaded) { | ||
3312 | #endif | ||
3313 | rc = ipw_get_fw(priv, &ucode, ucode_name); | ||
3314 | if (rc < 0) | ||
3315 | goto error; | ||
3316 | #ifdef CONFIG_PM | ||
3317 | } | ||
3318 | #endif | ||
3319 | |||
3320 | /* DMA the ucode into the device */ | 3296 | /* DMA the ucode into the device */ |
3321 | rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header), | 3297 | rc = ipw_load_ucode(priv, ucode_img, fw->ucode_size); |
3322 | ucode->size - sizeof(struct fw_header)); | ||
3323 | if (rc < 0) { | 3298 | if (rc < 0) { |
3324 | IPW_ERROR("Unable to load ucode: %d\n", rc); | 3299 | IPW_ERROR("Unable to load ucode: %d\n", rc); |
3325 | goto error; | 3300 | goto error; |
@@ -3328,20 +3303,8 @@ static int ipw_load(struct ipw_priv *priv) | |||
3328 | /* stop nic */ | 3303 | /* stop nic */ |
3329 | ipw_stop_nic(priv); | 3304 | ipw_stop_nic(priv); |
3330 | 3305 | ||
3331 | #ifdef CONFIG_PM | ||
3332 | if (!fw_loaded) { | ||
3333 | #endif | ||
3334 | rc = ipw_get_fw(priv, &firmware, fw_name); | ||
3335 | if (rc < 0) | ||
3336 | goto error; | ||
3337 | #ifdef CONFIG_PM | ||
3338 | } | ||
3339 | #endif | ||
3340 | |||
3341 | /* DMA bss firmware into the device */ | 3306 | /* DMA bss firmware into the device */ |
3342 | rc = ipw_load_firmware(priv, firmware->data + | 3307 | rc = ipw_load_firmware(priv, fw_img, fw->fw_size); |
3343 | sizeof(struct fw_header), | ||
3344 | firmware->size - sizeof(struct fw_header)); | ||
3345 | if (rc < 0) { | 3308 | if (rc < 0) { |
3346 | IPW_ERROR("Unable to load firmware: %d\n", rc); | 3309 | IPW_ERROR("Unable to load firmware: %d\n", rc); |
3347 | goto error; | 3310 | goto error; |
@@ -3406,9 +3369,7 @@ static int ipw_load(struct ipw_priv *priv) | |||
3406 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL); | 3369 | ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL); |
3407 | 3370 | ||
3408 | #ifndef CONFIG_PM | 3371 | #ifndef CONFIG_PM |
3409 | release_firmware(bootfw); | 3372 | release_firmware(raw); |
3410 | release_firmware(ucode); | ||
3411 | release_firmware(firmware); | ||
3412 | #endif | 3373 | #endif |
3413 | return 0; | 3374 | return 0; |
3414 | 3375 | ||
@@ -3418,15 +3379,11 @@ static int ipw_load(struct ipw_priv *priv) | |||
3418 | priv->rxq = NULL; | 3379 | priv->rxq = NULL; |
3419 | } | 3380 | } |
3420 | ipw_tx_queue_free(priv); | 3381 | ipw_tx_queue_free(priv); |
3421 | if (bootfw) | 3382 | if (raw) |
3422 | release_firmware(bootfw); | 3383 | release_firmware(raw); |
3423 | if (ucode) | ||
3424 | release_firmware(ucode); | ||
3425 | if (firmware) | ||
3426 | release_firmware(firmware); | ||
3427 | #ifdef CONFIG_PM | 3384 | #ifdef CONFIG_PM |
3428 | fw_loaded = 0; | 3385 | fw_loaded = 0; |
3429 | bootfw = ucode = firmware = NULL; | 3386 | raw = NULL; |
3430 | #endif | 3387 | #endif |
3431 | 3388 | ||
3432 | return rc; | 3389 | return rc; |
@@ -4547,10 +4504,9 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4547 | 4504 | ||
4548 | if (notif->size == sizeof(*x)) { | 4505 | if (notif->size == sizeof(*x)) { |
4549 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, | 4506 | IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE, |
4550 | "link deterioration: '%s' " MAC_FMT | 4507 | "link deterioration: type %d, cnt %d\n", |
4551 | " \n", escape_essid(priv->essid, | 4508 | x->silence_notification_type, |
4552 | priv->essid_len), | 4509 | x->silence_count); |
4553 | MAC_ARG(priv->bssid)); | ||
4554 | memcpy(&priv->last_link_deterioration, x, | 4510 | memcpy(&priv->last_link_deterioration, x, |
4555 | sizeof(*x)); | 4511 | sizeof(*x)); |
4556 | } else { | 4512 | } else { |
@@ -5533,15 +5489,6 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5533 | return 0; | 5489 | return 0; |
5534 | } | 5490 | } |
5535 | 5491 | ||
5536 | if (priv->ieee->wpa_enabled && | ||
5537 | network->wpa_ie_len == 0 && network->rsn_ie_len == 0) { | ||
5538 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " | ||
5539 | "because of WPA capability mismatch.\n", | ||
5540 | escape_essid(network->ssid, network->ssid_len), | ||
5541 | MAC_ARG(network->bssid)); | ||
5542 | return 0; | ||
5543 | } | ||
5544 | |||
5545 | if ((priv->config & CFG_STATIC_BSSID) && | 5492 | if ((priv->config & CFG_STATIC_BSSID) && |
5546 | memcmp(network->bssid, priv->bssid, ETH_ALEN)) { | 5493 | memcmp(network->bssid, priv->bssid, ETH_ALEN)) { |
5547 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " | 5494 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " |
@@ -5562,7 +5509,7 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5562 | } | 5509 | } |
5563 | 5510 | ||
5564 | /* Filter out invalid channel in current GEO */ | 5511 | /* Filter out invalid channel in current GEO */ |
5565 | if (!ipw_is_valid_channel(priv->ieee, network->channel)) { | 5512 | if (!ieee80211_is_valid_channel(priv->ieee, network->channel)) { |
5566 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " | 5513 | IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " |
5567 | "because of invalid channel in current GEO\n", | 5514 | "because of invalid channel in current GEO\n", |
5568 | escape_essid(network->ssid, network->ssid_len), | 5515 | escape_essid(network->ssid, network->ssid_len), |
@@ -5607,7 +5554,7 @@ static int ipw_best_network(struct ipw_priv *priv, | |||
5607 | static void ipw_adhoc_create(struct ipw_priv *priv, | 5554 | static void ipw_adhoc_create(struct ipw_priv *priv, |
5608 | struct ieee80211_network *network) | 5555 | struct ieee80211_network *network) |
5609 | { | 5556 | { |
5610 | const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); | 5557 | const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); |
5611 | int i; | 5558 | int i; |
5612 | 5559 | ||
5613 | /* | 5560 | /* |
@@ -5622,10 +5569,10 @@ static void ipw_adhoc_create(struct ipw_priv *priv, | |||
5622 | * FW fatal error. | 5569 | * FW fatal error. |
5623 | * | 5570 | * |
5624 | */ | 5571 | */ |
5625 | switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { | 5572 | switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { |
5626 | case IEEE80211_52GHZ_BAND: | 5573 | case IEEE80211_52GHZ_BAND: |
5627 | network->mode = IEEE_A; | 5574 | network->mode = IEEE_A; |
5628 | i = ipw_channel_to_index(priv->ieee, priv->channel); | 5575 | i = ieee80211_channel_to_index(priv->ieee, priv->channel); |
5629 | if (i == -1) | 5576 | if (i == -1) |
5630 | BUG(); | 5577 | BUG(); |
5631 | if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { | 5578 | if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) { |
@@ -5639,7 +5586,7 @@ static void ipw_adhoc_create(struct ipw_priv *priv, | |||
5639 | network->mode = IEEE_G; | 5586 | network->mode = IEEE_G; |
5640 | else | 5587 | else |
5641 | network->mode = IEEE_B; | 5588 | network->mode = IEEE_B; |
5642 | i = ipw_channel_to_index(priv->ieee, priv->channel); | 5589 | i = ieee80211_channel_to_index(priv->ieee, priv->channel); |
5643 | if (i == -1) | 5590 | if (i == -1) |
5644 | BUG(); | 5591 | BUG(); |
5645 | if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { | 5592 | if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) { |
@@ -5963,7 +5910,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
5963 | const struct ieee80211_geo *geo; | 5910 | const struct ieee80211_geo *geo; |
5964 | int i; | 5911 | int i; |
5965 | 5912 | ||
5966 | geo = ipw_get_geo(priv->ieee); | 5913 | geo = ieee80211_get_geo(priv->ieee); |
5967 | 5914 | ||
5968 | if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { | 5915 | if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) { |
5969 | int start = channel_index; | 5916 | int start = channel_index; |
@@ -6023,7 +5970,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
6023 | channel_index++; | 5970 | channel_index++; |
6024 | scan->channels_list[channel_index] = channel; | 5971 | scan->channels_list[channel_index] = channel; |
6025 | index = | 5972 | index = |
6026 | ipw_channel_to_index(priv->ieee, channel); | 5973 | ieee80211_channel_to_index(priv->ieee, channel); |
6027 | ipw_set_scan_type(scan, channel_index, | 5974 | ipw_set_scan_type(scan, channel_index, |
6028 | geo->bg[index]. | 5975 | geo->bg[index]. |
6029 | flags & | 5976 | flags & |
@@ -6105,7 +6052,7 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
6105 | u8 channel; | 6052 | u8 channel; |
6106 | u8 band = 0; | 6053 | u8 band = 0; |
6107 | 6054 | ||
6108 | switch (ipw_is_valid_channel(priv->ieee, priv->channel)) { | 6055 | switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { |
6109 | case IEEE80211_52GHZ_BAND: | 6056 | case IEEE80211_52GHZ_BAND: |
6110 | band = (u8) (IPW_A_MODE << 6) | 1; | 6057 | band = (u8) (IPW_A_MODE << 6) | 1; |
6111 | channel = priv->channel; | 6058 | channel = priv->channel; |
@@ -6568,7 +6515,7 @@ static int ipw_wx_set_mlme(struct net_device *dev, | |||
6568 | * get the modulation type of the current network or | 6515 | * get the modulation type of the current network or |
6569 | * the card current mode | 6516 | * the card current mode |
6570 | */ | 6517 | */ |
6571 | u8 ipw_qos_current_mode(struct ipw_priv * priv) | 6518 | static u8 ipw_qos_current_mode(struct ipw_priv * priv) |
6572 | { | 6519 | { |
6573 | u8 mode = 0; | 6520 | u8 mode = 0; |
6574 | 6521 | ||
@@ -7815,12 +7762,10 @@ static void ipw_rx(struct ipw_priv *priv) | |||
7815 | 7762 | ||
7816 | while (i != r) { | 7763 | while (i != r) { |
7817 | rxb = priv->rxq->queue[i]; | 7764 | rxb = priv->rxq->queue[i]; |
7818 | #ifdef CONFIG_IPW2200_DEBUG | ||
7819 | if (unlikely(rxb == NULL)) { | 7765 | if (unlikely(rxb == NULL)) { |
7820 | printk(KERN_CRIT "Queue not allocated!\n"); | 7766 | printk(KERN_CRIT "Queue not allocated!\n"); |
7821 | break; | 7767 | break; |
7822 | } | 7768 | } |
7823 | #endif | ||
7824 | priv->rxq->queue[i] = NULL; | 7769 | priv->rxq->queue[i] = NULL; |
7825 | 7770 | ||
7826 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, | 7771 | pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, |
@@ -7839,7 +7784,8 @@ static void ipw_rx(struct ipw_priv *priv) | |||
7839 | le16_to_cpu(pkt->u.frame.rssi_dbm) - | 7784 | le16_to_cpu(pkt->u.frame.rssi_dbm) - |
7840 | IPW_RSSI_TO_DBM, | 7785 | IPW_RSSI_TO_DBM, |
7841 | .signal = | 7786 | .signal = |
7842 | le16_to_cpu(pkt->u.frame.signal), | 7787 | le16_to_cpu(pkt->u.frame.rssi_dbm) - |
7788 | IPW_RSSI_TO_DBM + 0x100, | ||
7843 | .noise = | 7789 | .noise = |
7844 | le16_to_cpu(pkt->u.frame.noise), | 7790 | le16_to_cpu(pkt->u.frame.noise), |
7845 | .rate = pkt->u.frame.rate, | 7791 | .rate = pkt->u.frame.rate, |
@@ -7903,7 +7849,8 @@ static void ipw_rx(struct ipw_priv *priv) | |||
7903 | le16_to_cpu(pkt->u.frame.length)); | 7849 | le16_to_cpu(pkt->u.frame.length)); |
7904 | 7850 | ||
7905 | if (le16_to_cpu(pkt->u.frame.length) < | 7851 | if (le16_to_cpu(pkt->u.frame.length) < |
7906 | frame_hdr_len(header)) { | 7852 | ieee80211_get_hdrlen(le16_to_cpu( |
7853 | header->frame_ctl))) { | ||
7907 | IPW_DEBUG_DROP | 7854 | IPW_DEBUG_DROP |
7908 | ("Received packet is too small. " | 7855 | ("Received packet is too small. " |
7909 | "Dropping.\n"); | 7856 | "Dropping.\n"); |
@@ -7993,7 +7940,14 @@ static void ipw_rx(struct ipw_priv *priv) | |||
7993 | #define DEFAULT_SHORT_RETRY_LIMIT 7U | 7940 | #define DEFAULT_SHORT_RETRY_LIMIT 7U |
7994 | #define DEFAULT_LONG_RETRY_LIMIT 4U | 7941 | #define DEFAULT_LONG_RETRY_LIMIT 4U |
7995 | 7942 | ||
7996 | static int ipw_sw_reset(struct ipw_priv *priv, int init) | 7943 | /** |
7944 | * ipw_sw_reset | ||
7945 | * @option: options to control different reset behaviour | ||
7946 | * 0 = reset everything except the 'disable' module_param | ||
7947 | * 1 = reset everything and print out driver info (for probe only) | ||
7948 | * 2 = reset everything | ||
7949 | */ | ||
7950 | static int ipw_sw_reset(struct ipw_priv *priv, int option) | ||
7997 | { | 7951 | { |
7998 | int band, modulation; | 7952 | int band, modulation; |
7999 | int old_mode = priv->ieee->iw_mode; | 7953 | int old_mode = priv->ieee->iw_mode; |
@@ -8020,7 +7974,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init) | |||
8020 | priv->essid_len = 0; | 7974 | priv->essid_len = 0; |
8021 | memset(priv->essid, 0, IW_ESSID_MAX_SIZE); | 7975 | memset(priv->essid, 0, IW_ESSID_MAX_SIZE); |
8022 | 7976 | ||
8023 | if (disable) { | 7977 | if (disable && option) { |
8024 | priv->status |= STATUS_RF_KILL_SW; | 7978 | priv->status |= STATUS_RF_KILL_SW; |
8025 | IPW_DEBUG_INFO("Radio disabled.\n"); | 7979 | IPW_DEBUG_INFO("Radio disabled.\n"); |
8026 | } | 7980 | } |
@@ -8072,7 +8026,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init) | |||
8072 | 8026 | ||
8073 | if ((priv->pci_dev->device == 0x4223) || | 8027 | if ((priv->pci_dev->device == 0x4223) || |
8074 | (priv->pci_dev->device == 0x4224)) { | 8028 | (priv->pci_dev->device == 0x4224)) { |
8075 | if (init) | 8029 | if (option == 1) |
8076 | printk(KERN_INFO DRV_NAME | 8030 | printk(KERN_INFO DRV_NAME |
8077 | ": Detected Intel PRO/Wireless 2915ABG Network " | 8031 | ": Detected Intel PRO/Wireless 2915ABG Network " |
8078 | "Connection\n"); | 8032 | "Connection\n"); |
@@ -8083,7 +8037,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int init) | |||
8083 | priv->adapter = IPW_2915ABG; | 8037 | priv->adapter = IPW_2915ABG; |
8084 | priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; | 8038 | priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B; |
8085 | } else { | 8039 | } else { |
8086 | if (init) | 8040 | if (option == 1) |
8087 | printk(KERN_INFO DRV_NAME | 8041 | printk(KERN_INFO DRV_NAME |
8088 | ": Detected Intel PRO/Wireless 2200BG Network " | 8042 | ": Detected Intel PRO/Wireless 2200BG Network " |
8089 | "Connection\n"); | 8043 | "Connection\n"); |
@@ -8200,7 +8154,7 @@ static int ipw_wx_set_freq(struct net_device *dev, | |||
8200 | union iwreq_data *wrqu, char *extra) | 8154 | union iwreq_data *wrqu, char *extra) |
8201 | { | 8155 | { |
8202 | struct ipw_priv *priv = ieee80211_priv(dev); | 8156 | struct ipw_priv *priv = ieee80211_priv(dev); |
8203 | const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); | 8157 | const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); |
8204 | struct iw_freq *fwrq = &wrqu->freq; | 8158 | struct iw_freq *fwrq = &wrqu->freq; |
8205 | int ret = 0, i; | 8159 | int ret = 0, i; |
8206 | u8 channel, flags; | 8160 | u8 channel, flags; |
@@ -8215,17 +8169,17 @@ static int ipw_wx_set_freq(struct net_device *dev, | |||
8215 | } | 8169 | } |
8216 | /* if setting by freq convert to channel */ | 8170 | /* if setting by freq convert to channel */ |
8217 | if (fwrq->e == 1) { | 8171 | if (fwrq->e == 1) { |
8218 | channel = ipw_freq_to_channel(priv->ieee, fwrq->m); | 8172 | channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m); |
8219 | if (channel == 0) | 8173 | if (channel == 0) |
8220 | return -EINVAL; | 8174 | return -EINVAL; |
8221 | } else | 8175 | } else |
8222 | channel = fwrq->m; | 8176 | channel = fwrq->m; |
8223 | 8177 | ||
8224 | if (!(band = ipw_is_valid_channel(priv->ieee, channel))) | 8178 | if (!(band = ieee80211_is_valid_channel(priv->ieee, channel))) |
8225 | return -EINVAL; | 8179 | return -EINVAL; |
8226 | 8180 | ||
8227 | if (priv->ieee->iw_mode == IW_MODE_ADHOC) { | 8181 | if (priv->ieee->iw_mode == IW_MODE_ADHOC) { |
8228 | i = ipw_channel_to_index(priv->ieee, channel); | 8182 | i = ieee80211_channel_to_index(priv->ieee, channel); |
8229 | if (i == -1) | 8183 | if (i == -1) |
8230 | return -EINVAL; | 8184 | return -EINVAL; |
8231 | 8185 | ||
@@ -8353,7 +8307,7 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
8353 | { | 8307 | { |
8354 | struct ipw_priv *priv = ieee80211_priv(dev); | 8308 | struct ipw_priv *priv = ieee80211_priv(dev); |
8355 | struct iw_range *range = (struct iw_range *)extra; | 8309 | struct iw_range *range = (struct iw_range *)extra; |
8356 | const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee); | 8310 | const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee); |
8357 | int i = 0, j; | 8311 | int i = 0, j; |
8358 | 8312 | ||
8359 | wrqu->data.length = sizeof(*range); | 8313 | wrqu->data.length = sizeof(*range); |
@@ -8365,7 +8319,7 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
8365 | range->max_qual.qual = 100; | 8319 | range->max_qual.qual = 100; |
8366 | /* TODO: Find real max RSSI and stick here */ | 8320 | /* TODO: Find real max RSSI and stick here */ |
8367 | range->max_qual.level = 0; | 8321 | range->max_qual.level = 0; |
8368 | range->max_qual.noise = priv->ieee->worst_rssi + 0x100; | 8322 | range->max_qual.noise = 0; |
8369 | range->max_qual.updated = 7; /* Updated all three */ | 8323 | range->max_qual.updated = 7; /* Updated all three */ |
8370 | 8324 | ||
8371 | range->avg_qual.qual = 70; | 8325 | range->avg_qual.qual = 70; |
@@ -8395,20 +8349,28 @@ static int ipw_wx_get_range(struct net_device *dev, | |||
8395 | 8349 | ||
8396 | i = 0; | 8350 | i = 0; |
8397 | if (priv->ieee->mode & (IEEE_B | IEEE_G)) { | 8351 | if (priv->ieee->mode & (IEEE_B | IEEE_G)) { |
8398 | for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; | 8352 | for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) { |
8399 | i++, j++) { | 8353 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC) && |
8354 | (geo->bg[j].flags & IEEE80211_CH_PASSIVE_ONLY)) | ||
8355 | continue; | ||
8356 | |||
8400 | range->freq[i].i = geo->bg[j].channel; | 8357 | range->freq[i].i = geo->bg[j].channel; |
8401 | range->freq[i].m = geo->bg[j].freq * 100000; | 8358 | range->freq[i].m = geo->bg[j].freq * 100000; |
8402 | range->freq[i].e = 1; | 8359 | range->freq[i].e = 1; |
8360 | i++; | ||
8403 | } | 8361 | } |
8404 | } | 8362 | } |
8405 | 8363 | ||
8406 | if (priv->ieee->mode & IEEE_A) { | 8364 | if (priv->ieee->mode & IEEE_A) { |
8407 | for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; | 8365 | for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) { |
8408 | i++, j++) { | 8366 | if ((priv->ieee->iw_mode == IW_MODE_ADHOC) && |
8367 | (geo->a[j].flags & IEEE80211_CH_PASSIVE_ONLY)) | ||
8368 | continue; | ||
8369 | |||
8409 | range->freq[i].i = geo->a[j].channel; | 8370 | range->freq[i].i = geo->a[j].channel; |
8410 | range->freq[i].m = geo->a[j].freq * 100000; | 8371 | range->freq[i].m = geo->a[j].freq * 100000; |
8411 | range->freq[i].e = 1; | 8372 | range->freq[i].e = 1; |
8373 | i++; | ||
8412 | } | 8374 | } |
8413 | } | 8375 | } |
8414 | 8376 | ||
@@ -8609,6 +8571,52 @@ static int ipw_wx_get_nick(struct net_device *dev, | |||
8609 | return 0; | 8571 | return 0; |
8610 | } | 8572 | } |
8611 | 8573 | ||
8574 | static int ipw_wx_set_sens(struct net_device *dev, | ||
8575 | struct iw_request_info *info, | ||
8576 | union iwreq_data *wrqu, char *extra) | ||
8577 | { | ||
8578 | struct ipw_priv *priv = ieee80211_priv(dev); | ||
8579 | int err = 0; | ||
8580 | |||
8581 | IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value); | ||
8582 | IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value); | ||
8583 | mutex_lock(&priv->mutex); | ||
8584 | |||
8585 | if (wrqu->sens.fixed == 0) | ||
8586 | { | ||
8587 | priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT; | ||
8588 | priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT; | ||
8589 | goto out; | ||
8590 | } | ||
8591 | if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) || | ||
8592 | (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) { | ||
8593 | err = -EINVAL; | ||
8594 | goto out; | ||
8595 | } | ||
8596 | |||
8597 | priv->roaming_threshold = wrqu->sens.value; | ||
8598 | priv->disassociate_threshold = 3*wrqu->sens.value; | ||
8599 | out: | ||
8600 | mutex_unlock(&priv->mutex); | ||
8601 | return err; | ||
8602 | } | ||
8603 | |||
8604 | static int ipw_wx_get_sens(struct net_device *dev, | ||
8605 | struct iw_request_info *info, | ||
8606 | union iwreq_data *wrqu, char *extra) | ||
8607 | { | ||
8608 | struct ipw_priv *priv = ieee80211_priv(dev); | ||
8609 | mutex_lock(&priv->mutex); | ||
8610 | wrqu->sens.fixed = 1; | ||
8611 | wrqu->sens.value = priv->roaming_threshold; | ||
8612 | mutex_unlock(&priv->mutex); | ||
8613 | |||
8614 | IPW_DEBUG_WX("GET roaming threshold -> %s %d \n", | ||
8615 | wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value); | ||
8616 | |||
8617 | return 0; | ||
8618 | } | ||
8619 | |||
8612 | static int ipw_wx_set_rate(struct net_device *dev, | 8620 | static int ipw_wx_set_rate(struct net_device *dev, |
8613 | struct iw_request_info *info, | 8621 | struct iw_request_info *info, |
8614 | union iwreq_data *wrqu, char *extra) | 8622 | union iwreq_data *wrqu, char *extra) |
@@ -9395,7 +9403,7 @@ static int ipw_wx_sw_reset(struct net_device *dev, | |||
9395 | 9403 | ||
9396 | mutex_lock(&priv->mutex); | 9404 | mutex_lock(&priv->mutex); |
9397 | 9405 | ||
9398 | ret = ipw_sw_reset(priv, 0); | 9406 | ret = ipw_sw_reset(priv, 2); |
9399 | if (!ret) { | 9407 | if (!ret) { |
9400 | free_firmware(); | 9408 | free_firmware(); |
9401 | ipw_adapter_restart(priv); | 9409 | ipw_adapter_restart(priv); |
@@ -9430,6 +9438,8 @@ static iw_handler ipw_wx_handlers[] = { | |||
9430 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, | 9438 | IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, |
9431 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, | 9439 | IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, |
9432 | IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, | 9440 | IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, |
9441 | IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens, | ||
9442 | IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens, | ||
9433 | IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, | 9443 | IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, |
9434 | IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, | 9444 | IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, |
9435 | IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, | 9445 | IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, |
@@ -9575,7 +9585,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev) | |||
9575 | wstats->qual.level = average_value(&priv->average_rssi); | 9585 | wstats->qual.level = average_value(&priv->average_rssi); |
9576 | wstats->qual.noise = average_value(&priv->average_noise); | 9586 | wstats->qual.noise = average_value(&priv->average_noise); |
9577 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | | 9587 | wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | |
9578 | IW_QUAL_NOISE_UPDATED; | 9588 | IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM; |
9579 | 9589 | ||
9580 | wstats->miss.beacon = average_value(&priv->average_missed_beacons); | 9590 | wstats->miss.beacon = average_value(&priv->average_missed_beacons); |
9581 | wstats->discard.retries = priv->last_tx_failures; | 9591 | wstats->discard.retries = priv->last_tx_failures; |
@@ -9601,12 +9611,13 @@ static void init_sys_config(struct ipw_sys_config *sys_config) | |||
9601 | sys_config->disable_unicast_decryption = 1; | 9611 | sys_config->disable_unicast_decryption = 1; |
9602 | sys_config->exclude_multicast_unencrypted = 0; | 9612 | sys_config->exclude_multicast_unencrypted = 0; |
9603 | sys_config->disable_multicast_decryption = 1; | 9613 | sys_config->disable_multicast_decryption = 1; |
9604 | sys_config->antenna_diversity = CFG_SYS_ANTENNA_BOTH; | 9614 | sys_config->antenna_diversity = CFG_SYS_ANTENNA_SLOW_DIV; |
9605 | sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ | 9615 | sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */ |
9606 | sys_config->dot11g_auto_detection = 0; | 9616 | sys_config->dot11g_auto_detection = 0; |
9607 | sys_config->enable_cts_to_self = 0; | 9617 | sys_config->enable_cts_to_self = 0; |
9608 | sys_config->bt_coexist_collision_thr = 0; | 9618 | sys_config->bt_coexist_collision_thr = 0; |
9609 | sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 | 9619 | sys_config->pass_noise_stats_to_host = 1; //1 -- fix for 256 |
9620 | sys_config->silence_threshold = 0x1e; | ||
9610 | } | 9621 | } |
9611 | 9622 | ||
9612 | static int ipw_net_open(struct net_device *dev) | 9623 | static int ipw_net_open(struct net_device *dev) |
@@ -9654,11 +9665,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9654 | u16 remaining_bytes; | 9665 | u16 remaining_bytes; |
9655 | int fc; | 9666 | int fc; |
9656 | 9667 | ||
9657 | /* If there isn't room in the queue, we return busy and let the | ||
9658 | * network stack requeue the packet for us */ | ||
9659 | if (ipw_queue_space(q) < q->high_mark) | ||
9660 | return NETDEV_TX_BUSY; | ||
9661 | |||
9662 | switch (priv->ieee->iw_mode) { | 9668 | switch (priv->ieee->iw_mode) { |
9663 | case IW_MODE_ADHOC: | 9669 | case IW_MODE_ADHOC: |
9664 | hdr_len = IEEE80211_3ADDR_LEN; | 9670 | hdr_len = IEEE80211_3ADDR_LEN; |
@@ -9824,6 +9830,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9824 | q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); | 9830 | q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); |
9825 | ipw_write32(priv, q->reg_w, q->first_empty); | 9831 | ipw_write32(priv, q->reg_w, q->first_empty); |
9826 | 9832 | ||
9833 | if (ipw_queue_space(q) < q->high_mark) | ||
9834 | netif_stop_queue(priv->net_dev); | ||
9835 | |||
9827 | return NETDEV_TX_OK; | 9836 | return NETDEV_TX_OK; |
9828 | 9837 | ||
9829 | drop: | 9838 | drop: |
@@ -9963,9 +9972,8 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev, | |||
9963 | return -EINVAL; | 9972 | return -EINVAL; |
9964 | mutex_lock(&p->mutex); | 9973 | mutex_lock(&p->mutex); |
9965 | memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); | 9974 | memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len); |
9966 | for (i = IPW_EEPROM_DATA; | 9975 | for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++) |
9967 | i < IPW_EEPROM_DATA + IPW_EEPROM_IMAGE_SIZE; i++) | 9976 | ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]); |
9968 | ipw_write8(p, i, p->eeprom[i]); | ||
9969 | mutex_unlock(&p->mutex); | 9977 | mutex_unlock(&p->mutex); |
9970 | return 0; | 9978 | return 0; |
9971 | } | 9979 | } |
@@ -10370,6 +10378,9 @@ static int ipw_config(struct ipw_priv *priv) | |||
10370 | * not intended for resale of the above mentioned Intel adapters has | 10378 | * not intended for resale of the above mentioned Intel adapters has |
10371 | * not been tested. | 10379 | * not been tested. |
10372 | * | 10380 | * |
10381 | * Remember to update the table in README.ipw2200 when changing this | ||
10382 | * table. | ||
10383 | * | ||
10373 | */ | 10384 | */ |
10374 | static const struct ieee80211_geo ipw_geos[] = { | 10385 | static const struct ieee80211_geo ipw_geos[] = { |
10375 | { /* Restricted */ | 10386 | { /* Restricted */ |
@@ -10617,96 +10628,6 @@ static const struct ieee80211_geo ipw_geos[] = { | |||
10617 | } | 10628 | } |
10618 | }; | 10629 | }; |
10619 | 10630 | ||
10620 | /* GEO code borrowed from ieee80211_geo.c */ | ||
10621 | static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel) | ||
10622 | { | ||
10623 | int i; | ||
10624 | |||
10625 | /* Driver needs to initialize the geography map before using | ||
10626 | * these helper functions */ | ||
10627 | BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); | ||
10628 | |||
10629 | if (ieee->freq_band & IEEE80211_24GHZ_BAND) | ||
10630 | for (i = 0; i < ieee->geo.bg_channels; i++) | ||
10631 | /* NOTE: If G mode is currently supported but | ||
10632 | * this is a B only channel, we don't see it | ||
10633 | * as valid. */ | ||
10634 | if ((ieee->geo.bg[i].channel == channel) && | ||
10635 | (!(ieee->mode & IEEE_G) || | ||
10636 | !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY))) | ||
10637 | return IEEE80211_24GHZ_BAND; | ||
10638 | |||
10639 | if (ieee->freq_band & IEEE80211_52GHZ_BAND) | ||
10640 | for (i = 0; i < ieee->geo.a_channels; i++) | ||
10641 | if (ieee->geo.a[i].channel == channel) | ||
10642 | return IEEE80211_52GHZ_BAND; | ||
10643 | |||
10644 | return 0; | ||
10645 | } | ||
10646 | |||
10647 | static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel) | ||
10648 | { | ||
10649 | int i; | ||
10650 | |||
10651 | /* Driver needs to initialize the geography map before using | ||
10652 | * these helper functions */ | ||
10653 | BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); | ||
10654 | |||
10655 | if (ieee->freq_band & IEEE80211_24GHZ_BAND) | ||
10656 | for (i = 0; i < ieee->geo.bg_channels; i++) | ||
10657 | if (ieee->geo.bg[i].channel == channel) | ||
10658 | return i; | ||
10659 | |||
10660 | if (ieee->freq_band & IEEE80211_52GHZ_BAND) | ||
10661 | for (i = 0; i < ieee->geo.a_channels; i++) | ||
10662 | if (ieee->geo.a[i].channel == channel) | ||
10663 | return i; | ||
10664 | |||
10665 | return -1; | ||
10666 | } | ||
10667 | |||
10668 | static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq) | ||
10669 | { | ||
10670 | int i; | ||
10671 | |||
10672 | /* Driver needs to initialize the geography map before using | ||
10673 | * these helper functions */ | ||
10674 | BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0); | ||
10675 | |||
10676 | freq /= 100000; | ||
10677 | |||
10678 | if (ieee->freq_band & IEEE80211_24GHZ_BAND) | ||
10679 | for (i = 0; i < ieee->geo.bg_channels; i++) | ||
10680 | if (ieee->geo.bg[i].freq == freq) | ||
10681 | return ieee->geo.bg[i].channel; | ||
10682 | |||
10683 | if (ieee->freq_band & IEEE80211_52GHZ_BAND) | ||
10684 | for (i = 0; i < ieee->geo.a_channels; i++) | ||
10685 | if (ieee->geo.a[i].freq == freq) | ||
10686 | return ieee->geo.a[i].channel; | ||
10687 | |||
10688 | return 0; | ||
10689 | } | ||
10690 | |||
10691 | static int ipw_set_geo(struct ieee80211_device *ieee, | ||
10692 | const struct ieee80211_geo *geo) | ||
10693 | { | ||
10694 | memcpy(ieee->geo.name, geo->name, 3); | ||
10695 | ieee->geo.name[3] = '\0'; | ||
10696 | ieee->geo.bg_channels = geo->bg_channels; | ||
10697 | ieee->geo.a_channels = geo->a_channels; | ||
10698 | memcpy(ieee->geo.bg, geo->bg, geo->bg_channels * | ||
10699 | sizeof(struct ieee80211_channel)); | ||
10700 | memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * | ||
10701 | sizeof(struct ieee80211_channel)); | ||
10702 | return 0; | ||
10703 | } | ||
10704 | |||
10705 | static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee) | ||
10706 | { | ||
10707 | return &ieee->geo; | ||
10708 | } | ||
10709 | |||
10710 | #define MAX_HW_RESTARTS 5 | 10631 | #define MAX_HW_RESTARTS 5 |
10711 | static int ipw_up(struct ipw_priv *priv) | 10632 | static int ipw_up(struct ipw_priv *priv) |
10712 | { | 10633 | { |
@@ -10753,14 +10674,11 @@ static int ipw_up(struct ipw_priv *priv) | |||
10753 | priv->eeprom[EEPROM_COUNTRY_CODE + 2]); | 10674 | priv->eeprom[EEPROM_COUNTRY_CODE + 2]); |
10754 | j = 0; | 10675 | j = 0; |
10755 | } | 10676 | } |
10756 | if (ipw_set_geo(priv->ieee, &ipw_geos[j])) { | 10677 | if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) { |
10757 | IPW_WARNING("Could not set geography."); | 10678 | IPW_WARNING("Could not set geography."); |
10758 | return 0; | 10679 | return 0; |
10759 | } | 10680 | } |
10760 | 10681 | ||
10761 | IPW_DEBUG_INFO("Geography %03d [%s] detected.\n", | ||
10762 | j, priv->ieee->geo.name); | ||
10763 | |||
10764 | if (priv->status & STATUS_RF_KILL_SW) { | 10682 | if (priv->status & STATUS_RF_KILL_SW) { |
10765 | IPW_WARNING("Radio disabled by module parameter.\n"); | 10683 | IPW_WARNING("Radio disabled by module parameter.\n"); |
10766 | return 0; | 10684 | return 0; |
@@ -11081,6 +10999,12 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
11081 | IPW_ERROR("failed to register network device\n"); | 10999 | IPW_ERROR("failed to register network device\n"); |
11082 | goto out_remove_sysfs; | 11000 | goto out_remove_sysfs; |
11083 | } | 11001 | } |
11002 | |||
11003 | printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg " | ||
11004 | "channels, %d 802.11a channels)\n", | ||
11005 | priv->ieee->geo.name, priv->ieee->geo.bg_channels, | ||
11006 | priv->ieee->geo.a_channels); | ||
11007 | |||
11084 | return 0; | 11008 | return 0; |
11085 | 11009 | ||
11086 | out_remove_sysfs: | 11010 | out_remove_sysfs: |
@@ -11271,8 +11195,10 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); | |||
11271 | module_param(led, int, 0444); | 11195 | module_param(led, int, 0444); |
11272 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); | 11196 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); |
11273 | 11197 | ||
11198 | #ifdef CONFIG_IPW2200_DEBUG | ||
11274 | module_param(debug, int, 0444); | 11199 | module_param(debug, int, 0444); |
11275 | MODULE_PARM_DESC(debug, "debug output mask"); | 11200 | MODULE_PARM_DESC(debug, "debug output mask"); |
11201 | #endif | ||
11276 | 11202 | ||
11277 | module_param(channel, int, 0444); | 11203 | module_param(channel, int, 0444); |
11278 | MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); | 11204 | MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); |