aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2200.c
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-08-24 22:25:16 -0400
committerJames Ketrenos <jketreno@linux.intel.com>2005-11-07 18:49:50 -0500
commitea2b26e0a0264650e13acac8e66d315bb818897c (patch)
treea2045d043ca6e09722d23518170900c1cc4dcc6d /drivers/net/wireless/ipw2200.c
parenta1e695adca76f5729224242e4f2f9f6ceb6863d1 (diff)
Catch ipw2200 up to equivelancy with v1.0.1
This commit contains the following fixes: Fixed #559: iwconfig rate support (thanks to Florian Hackenberger) Improved link signal quality calculation (thanks to Bill Moss) Fixed a problem with sensitivity threshold during association Added iwpriv for turning forcing long preamble support: % iwpriv eth1 set_preamble 1|0 Fixed #542 and #377 support for short preamble Fixed locked BSSID reporting channel number (thanks to Pedro Ramalhais) Fixed type-o with scan watchdog timeout message (thanks to Pedro Ramalhais) Changed logic for displaying get_mode output so the code is easier to follow (thanks to Pedro Ramalhais) Added initial support for WPA (thanks to Yi Zhu) -- tested with wpa_supplicant (either tip w/ ipw driver, or with -Dipw2100) with both CCMP and TKIP Fixed problem with CCMP not working due to uninitialized 802.11 header fields (thanks to Pedro Ramalhais) Bug references are to defects stored on http://bughost.org Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r--drivers/net/wireless/ipw2200.c1496
1 files changed, 1133 insertions, 363 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32afe82..ddbee3edcd8c 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
32 32
33#include "ipw2200.h" 33#include "ipw2200.h"
34 34
35#define IPW2200_VERSION "1.0.0" 35#define IPW2200_VERSION "1.0.1"
36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" 36#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"
37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 37#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
38#define DRV_VERSION IPW2200_VERSION 38#define DRV_VERSION IPW2200_VERSION
@@ -44,7 +44,6 @@ MODULE_LICENSE("GPL");
44 44
45static int debug = 0; 45static int debug = 0;
46static int channel = 0; 46static int channel = 0;
47static char *ifname;
48static int mode = 0; 47static int mode = 0;
49 48
50static u32 ipw_debug_level; 49static u32 ipw_debug_level;
@@ -289,32 +288,33 @@ static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
289{ 288{
290 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 289 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
291 u32 dif_len = addr - aligned_addr; 290 u32 dif_len = addr - aligned_addr;
292 u32 aligned_len;
293 u32 i; 291 u32 i;
294 292
295 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 293 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
296 294
295 if (num <= 0) {
296 return;
297 }
298
297 /* Read the first nibble byte by byte */ 299 /* Read the first nibble byte by byte */
298 if (unlikely(dif_len)) { 300 if (unlikely(dif_len)) {
299 /* Start reading at aligned_addr + dif_len */
300 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 301 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
301 for (i = dif_len; i < 4; i++, buf++) 302 /* Start reading at aligned_addr + dif_len */
302 *buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i); 303 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
303 num -= dif_len; 304 *buf++ = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
304 aligned_addr += 4; 305 aligned_addr += 4;
305 } 306 }
306 307
307 /* Read DWs through autoinc register */
308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 308 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
309 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 309 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
310 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4) 310 *(u32 *) buf = _ipw_read32(priv, CX2_AUTOINC_DATA);
311 *(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
312 311
313 /* Copy the last nibble */ 312 /* Copy the last nibble */
314 dif_len = num - aligned_len; 313 if (unlikely(num)) {
315 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 314 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
316 for (i = 0; i < dif_len; i++, buf++) 315 for (i = 0; num > 0; i++, num--)
317 *buf = ipw_read8(priv, CX2_INDIRECT_DATA + i); 316 *buf++ = ipw_read8(priv, CX2_INDIRECT_DATA + i);
317 }
318} 318}
319 319
320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf, 320static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
@@ -322,32 +322,33 @@ static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
322{ 322{
323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK; 323 u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
324 u32 dif_len = addr - aligned_addr; 324 u32 dif_len = addr - aligned_addr;
325 u32 aligned_len;
326 u32 i; 325 u32 i;
327 326
328 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num); 327 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
329 328
329 if (num <= 0) {
330 return;
331 }
332
330 /* Write the first nibble byte by byte */ 333 /* Write the first nibble byte by byte */
331 if (unlikely(dif_len)) { 334 if (unlikely(dif_len)) {
332 /* Start writing at aligned_addr + dif_len */
333 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 335 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
334 for (i = dif_len; i < 4; i++, buf++) 336 /* Start reading at aligned_addr + dif_len */
337 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
335 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 338 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
336 num -= dif_len;
337 aligned_addr += 4; 339 aligned_addr += 4;
338 } 340 }
339 341
340 /* Write DWs through autoinc register */
341 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr); 342 _ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
342 aligned_len = num & CX2_INDIRECT_ADDR_MASK; 343 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
343 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf); 344 _ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
345 345
346 /* Copy the last nibble */ 346 /* Copy the last nibble */
347 dif_len = num - aligned_len; 347 if (unlikely(num)) {
348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr); 348 _ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
349 for (i = 0; i < dif_len; i++, buf++) 349 for (i = 0; num > 0; i++, num--, buf++)
350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf); 350 _ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
351 }
351} 352}
352 353
353static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf, 354static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -945,7 +946,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
945static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) 946static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
946{ 947{
947 if ((disable_radio ? 1 : 0) == 948 if ((disable_radio ? 1 : 0) ==
948 (priv->status & STATUS_RF_KILL_SW ? 1 : 0)) 949 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
949 return 0; 950 return 0;
950 951
951 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", 952 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
@@ -987,6 +988,17 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
987 988
988static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); 989static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
989 990
991static void notify_wx_assoc_event(struct ipw_priv *priv)
992{
993 union iwreq_data wrqu;
994 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
995 if (priv->status & STATUS_ASSOCIATED)
996 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
997 else
998 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
999 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1000}
1001
990static void ipw_irq_tasklet(struct ipw_priv *priv) 1002static void ipw_irq_tasklet(struct ipw_priv *priv)
991{ 1003{
992 u32 inta, inta_mask, handled = 0; 1004 u32 inta, inta_mask, handled = 0;
@@ -1071,6 +1083,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
1071 wake_up_interruptible(&priv->wait_command_queue); 1083 wake_up_interruptible(&priv->wait_command_queue);
1072 netif_carrier_off(priv->net_dev); 1084 netif_carrier_off(priv->net_dev);
1073 netif_stop_queue(priv->net_dev); 1085 netif_stop_queue(priv->net_dev);
1086 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1087 notify_wx_assoc_event(priv);
1074 cancel_delayed_work(&priv->request_scan); 1088 cancel_delayed_work(&priv->request_scan);
1075 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); 1089 queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
1076 handled |= CX2_INTA_BIT_RF_KILL_DONE; 1090 handled |= CX2_INTA_BIT_RF_KILL_DONE;
@@ -1162,7 +1176,7 @@ static char *get_cmd_string(u8 cmd)
1162 return "UNKNOWN"; 1176 return "UNKNOWN";
1163 } 1177 }
1164} 1178}
1165#endif /* CONFIG_IPW_DEBUG */ 1179#endif
1166 1180
1167#define HOST_COMPLETE_TIMEOUT HZ 1181#define HOST_COMPLETE_TIMEOUT HZ
1168static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) 1182static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
@@ -2445,10 +2459,10 @@ static int ipw_load(struct ipw_priv *priv)
2445 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss")); 2459 rc = ipw_get_fw(priv, &firmware, IPW_FW_NAME("ibss"));
2446 break; 2460 break;
2447 2461
2448#ifdef CONFIG_IPW_PROMISC 2462#ifdef CONFIG_IPW_MONITOR
2449 case IW_MODE_MONITOR: 2463 case IW_MODE_MONITOR:
2450 rc = ipw_get_fw(priv, &ucode, 2464 rc = ipw_get_fw(priv, &ucode,
2451 IPW_FW_NAME("ibss_ucode")); 2465 IPW_FW_NAME("sniffer_ucode"));
2452 if (rc) 2466 if (rc)
2453 goto error; 2467 goto error;
2454 2468
@@ -2929,17 +2943,6 @@ static void ipw_disassociate(void *data)
2929 ipw_send_disassociate(data, 0); 2943 ipw_send_disassociate(data, 0);
2930} 2944}
2931 2945
2932static void notify_wx_assoc_event(struct ipw_priv *priv)
2933{
2934 union iwreq_data wrqu;
2935 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2936 if (priv->status & STATUS_ASSOCIATED)
2937 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
2938 else
2939 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
2940 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
2941}
2942
2943struct ipw_status_code { 2946struct ipw_status_code {
2944 u16 status; 2947 u16 status;
2945 const char *reason; 2948 const char *reason;
@@ -2997,7 +3000,7 @@ static const char *ipw_get_status_code(u16 status)
2997{ 3000{
2998 int i; 3001 int i;
2999 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++) 3002 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)
3000 if (ipw_status_codes[i].status == status) 3003 if (ipw_status_codes[i].status == (status & 0xff))
3001 return ipw_status_codes[i].reason; 3004 return ipw_status_codes[i].reason;
3002 return "Unknown status value."; 3005 return "Unknown status value.";
3003} 3006}
@@ -3076,18 +3079,30 @@ static inline u32 ipw_get_max_rate(struct ipw_priv *priv)
3076 while (i && !(mask & i)) 3079 while (i && !(mask & i))
3077 i >>= 1; 3080 i >>= 1;
3078 switch (i) { 3081 switch (i) {
3079 case IEEE80211_CCK_RATE_1MB_MASK: return 1000000; 3082 case IEEE80211_CCK_RATE_1MB_MASK:
3080 case IEEE80211_CCK_RATE_2MB_MASK: return 2000000; 3083 return 1000000;
3081 case IEEE80211_CCK_RATE_5MB_MASK: return 5500000; 3084 case IEEE80211_CCK_RATE_2MB_MASK:
3082 case IEEE80211_OFDM_RATE_6MB_MASK: return 6000000; 3085 return 2000000;
3083 case IEEE80211_OFDM_RATE_9MB_MASK: return 9000000; 3086 case IEEE80211_CCK_RATE_5MB_MASK:
3084 case IEEE80211_CCK_RATE_11MB_MASK: return 11000000; 3087 return 5500000;
3085 case IEEE80211_OFDM_RATE_12MB_MASK: return 12000000; 3088 case IEEE80211_OFDM_RATE_6MB_MASK:
3086 case IEEE80211_OFDM_RATE_18MB_MASK: return 18000000; 3089 return 6000000;
3087 case IEEE80211_OFDM_RATE_24MB_MASK: return 24000000; 3090 case IEEE80211_OFDM_RATE_9MB_MASK:
3088 case IEEE80211_OFDM_RATE_36MB_MASK: return 36000000; 3091 return 9000000;
3089 case IEEE80211_OFDM_RATE_48MB_MASK: return 48000000; 3092 case IEEE80211_CCK_RATE_11MB_MASK:
3090 case IEEE80211_OFDM_RATE_54MB_MASK: return 54000000; 3093 return 11000000;
3094 case IEEE80211_OFDM_RATE_12MB_MASK:
3095 return 12000000;
3096 case IEEE80211_OFDM_RATE_18MB_MASK:
3097 return 18000000;
3098 case IEEE80211_OFDM_RATE_24MB_MASK:
3099 return 24000000;
3100 case IEEE80211_OFDM_RATE_36MB_MASK:
3101 return 36000000;
3102 case IEEE80211_OFDM_RATE_48MB_MASK:
3103 return 48000000;
3104 case IEEE80211_OFDM_RATE_54MB_MASK:
3105 return 54000000;
3091 } 3106 }
3092 3107
3093 if (priv->ieee->mode == IEEE_B) 3108 if (priv->ieee->mode == IEEE_B)
@@ -3115,24 +3130,36 @@ static u32 ipw_get_current_rate(struct ipw_priv *priv)
3115 return ipw_get_max_rate(priv); 3130 return ipw_get_max_rate(priv);
3116 3131
3117 switch (rate) { 3132 switch (rate) {
3118 case IPW_TX_RATE_1MB: return 1000000; 3133 case IPW_TX_RATE_1MB:
3119 case IPW_TX_RATE_2MB: return 2000000; 3134 return 1000000;
3120 case IPW_TX_RATE_5MB: return 5500000; 3135 case IPW_TX_RATE_2MB:
3121 case IPW_TX_RATE_6MB: return 6000000; 3136 return 2000000;
3122 case IPW_TX_RATE_9MB: return 9000000; 3137 case IPW_TX_RATE_5MB:
3123 case IPW_TX_RATE_11MB: return 11000000; 3138 return 5500000;
3124 case IPW_TX_RATE_12MB: return 12000000; 3139 case IPW_TX_RATE_6MB:
3125 case IPW_TX_RATE_18MB: return 18000000; 3140 return 6000000;
3126 case IPW_TX_RATE_24MB: return 24000000; 3141 case IPW_TX_RATE_9MB:
3127 case IPW_TX_RATE_36MB: return 36000000; 3142 return 9000000;
3128 case IPW_TX_RATE_48MB: return 48000000; 3143 case IPW_TX_RATE_11MB:
3129 case IPW_TX_RATE_54MB: return 54000000; 3144 return 11000000;
3145 case IPW_TX_RATE_12MB:
3146 return 12000000;
3147 case IPW_TX_RATE_18MB:
3148 return 18000000;
3149 case IPW_TX_RATE_24MB:
3150 return 24000000;
3151 case IPW_TX_RATE_36MB:
3152 return 36000000;
3153 case IPW_TX_RATE_48MB:
3154 return 48000000;
3155 case IPW_TX_RATE_54MB:
3156 return 54000000;
3130 } 3157 }
3131 3158
3132 return 0; 3159 return 0;
3133} 3160}
3134 3161
3135#define PERFECT_RSSI (-50) 3162#define PERFECT_RSSI (-20)
3136#define WORST_RSSI (-85) 3163#define WORST_RSSI (-85)
3137#define IPW_STATS_INTERVAL (2 * HZ) 3164#define IPW_STATS_INTERVAL (2 * HZ)
3138static void ipw_gather_stats(struct ipw_priv *priv) 3165static void ipw_gather_stats(struct ipw_priv *priv)
@@ -3145,6 +3172,7 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3145 s16 rssi; 3172 s16 rssi;
3146 u32 beacon_quality, signal_quality, tx_quality, rx_quality, 3173 u32 beacon_quality, signal_quality, tx_quality, rx_quality,
3147 rate_quality; 3174 rate_quality;
3175 u32 max_rate;
3148 3176
3149 if (!(priv->status & STATUS_ASSOCIATED)) { 3177 if (!(priv->status & STATUS_ASSOCIATED)) {
3150 priv->quality = 0; 3178 priv->quality = 0;
@@ -3201,7 +3229,8 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3201 beacon_quality, missed_beacons_percent); 3229 beacon_quality, missed_beacons_percent);
3202 3230
3203 priv->last_rate = ipw_get_current_rate(priv); 3231 priv->last_rate = ipw_get_current_rate(priv);
3204 rate_quality = priv->last_rate * 40 / priv->last_rate + 60; 3232 max_rate = ipw_get_max_rate(priv);
3233 rate_quality = priv->last_rate * 40 / max_rate + 60;
3205 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n", 3234 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",
3206 rate_quality, priv->last_rate / 1000000); 3235 rate_quality, priv->last_rate / 1000000);
3207 3236
@@ -3226,9 +3255,16 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3226 signal_quality = 100; 3255 signal_quality = 100;
3227 else if (rssi < WORST_RSSI) 3256 else if (rssi < WORST_RSSI)
3228 signal_quality = 0; 3257 signal_quality = 0;
3229 else 3258 else /* qual = 100a^2 - 15ab + 62b^2 / a^2 */
3230 signal_quality = (rssi - WORST_RSSI) * 100 / 3259 signal_quality =
3231 (PERFECT_RSSI - WORST_RSSI); 3260 (100 *
3261 (PERFECT_RSSI - WORST_RSSI) *
3262 (PERFECT_RSSI - WORST_RSSI) -
3263 (PERFECT_RSSI - rssi) *
3264 (15 * (PERFECT_RSSI - WORST_RSSI) +
3265 62 * (PERFECT_RSSI - rssi))) /
3266 ((PERFECT_RSSI - WORST_RSSI) * (PERFECT_RSSI - WORST_RSSI));
3267
3232 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 3268 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
3233 signal_quality, rssi); 3269 signal_quality, rssi);
3234 3270
@@ -3257,6 +3293,62 @@ static void ipw_gather_stats(struct ipw_priv *priv)
3257 IPW_STATS_INTERVAL); 3293 IPW_STATS_INTERVAL);
3258} 3294}
3259 3295
3296static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
3297 int missed_count)
3298{
3299 priv->notif_missed_beacons = missed_count;
3300
3301 if (missed_count > priv->missed_beacon_threshold &&
3302 priv->status & STATUS_ASSOCIATED) {
3303 /* If associated and we've hit the missed
3304 * beacon threshold, disassociate, turn
3305 * off roaming, and abort any active scans */
3306 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3307 IPW_DL_STATE,
3308 "Missed beacon: %d - disassociate\n", missed_count);
3309 priv->status &= ~STATUS_ROAMING;
3310 if (priv->status & STATUS_SCANNING)
3311 queue_work(priv->workqueue, &priv->abort_scan);
3312 queue_work(priv->workqueue, &priv->disassociate);
3313 return;
3314 }
3315
3316 if (priv->status & STATUS_ROAMING) {
3317 /* If we are currently roaming, then just
3318 * print a debug statement... */
3319 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3320 "Missed beacon: %d - roam in progress\n",
3321 missed_count);
3322 return;
3323 }
3324
3325 if (missed_count > priv->roaming_threshold) {
3326 /* If we are not already roaming, set the ROAM
3327 * bit in the status and kick off a scan */
3328 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3329 "Missed beacon: %d - initiate "
3330 "roaming\n", missed_count);
3331 if (!(priv->status & STATUS_ROAMING)) {
3332 priv->status |= STATUS_ROAMING;
3333 if (!(priv->status & STATUS_SCANNING))
3334 queue_work(priv->workqueue,
3335 &priv->request_scan);
3336 }
3337 return;
3338 }
3339
3340 if (priv->status & STATUS_SCANNING) {
3341 /* Stop scan to keep fw from getting
3342 * stuck (only if we aren't roaming --
3343 * otherwise we'll never scan more than 2 or 3
3344 * channels..) */
3345 queue_work(priv->workqueue, &priv->abort_scan);
3346 }
3347
3348 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);
3349
3350}
3351
3260/** 3352/**
3261 * Handle host notification packet. 3353 * Handle host notification packet.
3262 * Called from interrupt routine 3354 * Called from interrupt routine
@@ -3383,6 +3475,24 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3383 } 3475 }
3384 3476
3385 case CMAS_INIT:{ 3477 case CMAS_INIT:{
3478 if (priv->status & STATUS_AUTH) {
3479 struct
3480 ieee80211_assoc_response
3481 *resp;
3482 resp =
3483 (struct
3484 ieee80211_assoc_response
3485 *)&notif->u.raw;
3486 IPW_DEBUG(IPW_DL_NOTIF |
3487 IPW_DL_STATE |
3488 IPW_DL_ASSOC,
3489 "association failed (0x%04X): %s\n",
3490 ntohs(resp->status),
3491 ipw_get_status_code
3492 (ntohs
3493 (resp->status)));
3494 }
3495
3386 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | 3496 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |
3387 IPW_DL_ASSOC, 3497 IPW_DL_ASSOC,
3388 "disassociated: '%s' " MAC_FMT 3498 "disassociated: '%s' " MAC_FMT
@@ -3629,36 +3739,8 @@ static inline void ipw_rx_notification(struct ipw_priv *priv,
3629 break; 3739 break;
3630 } 3740 }
3631 3741
3632 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING) { 3742 if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING)
3633 if (priv->status & STATUS_SCANNING) { 3743 ipw_handle_missed_beacon(priv, x->number);
3634 /* Stop scan to keep fw from getting
3635 * stuck... */
3636 queue_work(priv->workqueue,
3637 &priv->abort_scan);
3638 }
3639
3640 if (x->number > priv->missed_beacon_threshold &&
3641 priv->status & STATUS_ASSOCIATED) {
3642 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
3643 IPW_DL_STATE,
3644 "Missed beacon: %d - disassociate\n",
3645 x->number);
3646 queue_work(priv->workqueue,
3647 &priv->disassociate);
3648 } else if (x->number > priv->roaming_threshold) {
3649 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
3650 "Missed beacon: %d - initiate "
3651 "roaming\n", x->number);
3652 queue_work(priv->workqueue,
3653 &priv->roam);
3654 } else {
3655 IPW_DEBUG_NOTIF("Missed beacon: %d\n",
3656 x->number);
3657 }
3658
3659 priv->notif_missed_beacons = x->number;
3660
3661 }
3662 3744
3663 break; 3745 break;
3664 } 3746 }
@@ -4137,6 +4219,13 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4137 for (i = 0; i < num_rates; i++) { 4219 for (i = 0; i < num_rates; i++) {
4138 if (!ipw_is_rate_in_mask 4220 if (!ipw_is_rate_in_mask
4139 (priv, network->mode, network->rates[i])) { 4221 (priv, network->mode, network->rates[i])) {
4222 if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
4223 IPW_DEBUG_SCAN
4224 ("Basic rate %02X masked: 0x%08X\n",
4225 network->rates[i], priv->rates_mask);
4226 return 0;
4227 }
4228
4140 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 4229 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4141 network->rates[i], priv->rates_mask); 4230 network->rates[i], priv->rates_mask);
4142 continue; 4231 continue;
@@ -4150,6 +4239,13 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4150 for (i = 0; i < num_rates; i++) { 4239 for (i = 0; i < num_rates; i++) {
4151 if (!ipw_is_rate_in_mask 4240 if (!ipw_is_rate_in_mask
4152 (priv, network->mode, network->rates_ex[i])) { 4241 (priv, network->mode, network->rates_ex[i])) {
4242 if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
4243 IPW_DEBUG_SCAN
4244 ("Basic rate %02X masked: 0x%08X\n",
4245 network->rates_ex[i], priv->rates_mask);
4246 return 0;
4247 }
4248
4153 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n", 4249 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
4154 network->rates_ex[i], priv->rates_mask); 4250 network->rates_ex[i], priv->rates_mask);
4155 continue; 4251 continue;
@@ -4159,7 +4255,7 @@ static int ipw_compatible_rates(struct ipw_priv *priv,
4159 network->rates_ex[i]; 4255 network->rates_ex[i];
4160 } 4256 }
4161 4257
4162 return rates->num_rates; 4258 return 1;
4163} 4259}
4164 4260
4165static inline void ipw_copy_rates(struct ipw_supported_rates *dest, 4261static inline void ipw_copy_rates(struct ipw_supported_rates *dest,
@@ -4322,7 +4418,7 @@ static int ipw_best_network(struct ipw_priv *priv,
4322 /* If this network has already had an association attempt within the 4418 /* If this network has already had an association attempt within the
4323 * last 3 seconds, do not try and associate again... */ 4419 * last 3 seconds, do not try and associate again... */
4324 if (network->last_associate && 4420 if (network->last_associate &&
4325 time_after(network->last_associate + (HZ * 5UL), jiffies)) { 4421 time_after(network->last_associate + (HZ * 3UL), jiffies)) {
4326 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 4422 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4327 "because of storming (%lu since last " 4423 "because of storming (%lu since last "
4328 "assoc attempt).\n", 4424 "assoc attempt).\n",
@@ -4334,7 +4430,7 @@ static int ipw_best_network(struct ipw_priv *priv,
4334 4430
4335 /* Now go through and see if the requested network is valid... */ 4431 /* Now go through and see if the requested network is valid... */
4336 if (priv->ieee->scan_age != 0 && 4432 if (priv->ieee->scan_age != 0 &&
4337 jiffies - network->last_scanned > priv->ieee->scan_age) { 4433 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
4338 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 4434 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4339 "because of age: %lums.\n", 4435 "because of age: %lums.\n",
4340 escape_essid(network->ssid, network->ssid_len), 4436 escape_essid(network->ssid, network->ssid_len),
@@ -4386,7 +4482,17 @@ static int ipw_best_network(struct ipw_priv *priv,
4386 return 0; 4482 return 0;
4387 } 4483 }
4388 4484
4389 ipw_compatible_rates(priv, network, &rates); 4485 /* Ensure that the rates supported by the driver are compatible with
4486 * this AP, including verification of basic rates (mandatory) */
4487 if (!ipw_compatible_rates(priv, network, &rates)) {
4488 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4489 "because configured rate mask excludes "
4490 "AP mandatory rate.\n",
4491 escape_essid(network->ssid, network->ssid_len),
4492 MAC_ARG(network->bssid));
4493 return 0;
4494 }
4495
4390 if (rates.num_rates == 0) { 4496 if (rates.num_rates == 0) {
4391 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded " 4497 IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
4392 "because of no compatible rates.\n", 4498 "because of no compatible rates.\n",
@@ -4448,6 +4554,8 @@ static void ipw_adhoc_create(struct ipw_priv *priv,
4448 memcpy(network->ssid, priv->essid, priv->essid_len); 4554 memcpy(network->ssid, priv->essid, priv->essid_len);
4449 memset(&network->stats, 0, sizeof(network->stats)); 4555 memset(&network->stats, 0, sizeof(network->stats));
4450 network->capability = WLAN_CAPABILITY_IBSS; 4556 network->capability = WLAN_CAPABILITY_IBSS;
4557 if (!(priv->config & CFG_PREAMBLE_LONG))
4558 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;
4451 if (priv->capability & CAP_PRIVACY_ON) 4559 if (priv->capability & CAP_PRIVACY_ON)
4452 network->capability |= WLAN_CAPABILITY_PRIVACY; 4560 network->capability |= WLAN_CAPABILITY_PRIVACY;
4453 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH); 4561 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);
@@ -4530,7 +4638,8 @@ static void ipw_debug_config(struct ipw_priv *priv)
4530 else 4638 else
4531 IPW_DEBUG_INFO("ESSID unlocked.\n"); 4639 IPW_DEBUG_INFO("ESSID unlocked.\n");
4532 if (priv->config & CFG_STATIC_BSSID) 4640 if (priv->config & CFG_STATIC_BSSID)
4533 IPW_DEBUG_INFO("BSSID locked to %d\n", priv->channel); 4641 IPW_DEBUG_INFO("BSSID locked to " MAC_FMT "\n",
4642 MAC_ARG(priv->bssid));
4534 else 4643 else
4535 IPW_DEBUG_INFO("BSSID unlocked.\n"); 4644 IPW_DEBUG_INFO("BSSID unlocked.\n");
4536 if (priv->capability & CAP_PRIVACY_ON) 4645 if (priv->capability & CAP_PRIVACY_ON)
@@ -4561,6 +4670,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4561 /* IEEE_A */ 4670 /* IEEE_A */
4562 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) { 4671 if (priv->rates_mask & ~IEEE80211_OFDM_RATES_MASK) {
4563 /* Invalid fixed rate mask */ 4672 /* Invalid fixed rate mask */
4673 IPW_DEBUG_WX
4674 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4564 fr.tx_rates = 0; 4675 fr.tx_rates = 0;
4565 break; 4676 break;
4566 } 4677 }
@@ -4573,6 +4684,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4573 if (network->mode == IEEE_B) { 4684 if (network->mode == IEEE_B) {
4574 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 4685 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) {
4575 /* Invalid fixed rate mask */ 4686 /* Invalid fixed rate mask */
4687 IPW_DEBUG_WX
4688 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4576 fr.tx_rates = 0; 4689 fr.tx_rates = 0;
4577 } 4690 }
4578 break; 4691 break;
@@ -4582,6 +4695,8 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4582 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 4695 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK |
4583 IEEE80211_OFDM_RATES_MASK)) { 4696 IEEE80211_OFDM_RATES_MASK)) {
4584 /* Invalid fixed rate mask */ 4697 /* Invalid fixed rate mask */
4698 IPW_DEBUG_WX
4699 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
4585 fr.tx_rates = 0; 4700 fr.tx_rates = 0;
4586 break; 4701 break;
4587 } 4702 }
@@ -4609,6 +4724,597 @@ static inline void ipw_set_fixed_rate(struct ipw_priv *priv,
4609 ipw_write_reg32(priv, reg, *(u32 *) & fr); 4724 ipw_write_reg32(priv, reg, *(u32 *) & fr);
4610} 4725}
4611 4726
4727static void ipw_abort_scan(struct ipw_priv *priv)
4728{
4729 int err;
4730
4731 if (priv->status & STATUS_SCAN_ABORTING) {
4732 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
4733 return;
4734 }
4735 priv->status |= STATUS_SCAN_ABORTING;
4736
4737 err = ipw_send_scan_abort(priv);
4738 if (err)
4739 IPW_DEBUG_HC("Request to abort scan failed.\n");
4740}
4741
4742static int ipw_request_scan(struct ipw_priv *priv)
4743{
4744 struct ipw_scan_request_ext scan;
4745 int channel_index = 0;
4746 int i, err, scan_type;
4747
4748 if (priv->status & STATUS_EXIT_PENDING) {
4749 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n");
4750 priv->status |= STATUS_SCAN_PENDING;
4751 return 0;
4752 }
4753
4754 if (priv->status & STATUS_SCANNING) {
4755 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
4756 priv->status |= STATUS_SCAN_PENDING;
4757 ipw_abort_scan(priv);
4758 return 0;
4759 }
4760
4761 if (priv->status & STATUS_SCAN_ABORTING) {
4762 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
4763 priv->status |= STATUS_SCAN_PENDING;
4764 return 0;
4765 }
4766
4767 if (priv->status & STATUS_RF_KILL_MASK) {
4768 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
4769 priv->status |= STATUS_SCAN_PENDING;
4770 return 0;
4771 }
4772
4773 memset(&scan, 0, sizeof(scan));
4774
4775 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20;
4776 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20;
4777 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
4778
4779 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
4780
4781#ifdef CONFIG_IPW_MONITOR
4782 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4783 u8 band = 0, channel = priv->channel;
4784
4785 if (is_valid_channel(IEEE_A, channel))
4786 band = (u8) (IPW_A_MODE << 6) | 1;
4787
4788 if (is_valid_channel(IEEE_B | IEEE_G, channel))
4789 band = (u8) (IPW_B_MODE << 6) | 1;
4790
4791 if (band == 0) {
4792 band = (u8) (IPW_B_MODE << 6) | 1;
4793 channel = 9;
4794 }
4795
4796 scan.channels_list[channel_index++] = band;
4797 scan.channels_list[channel_index] = channel;
4798 ipw_set_scan_type(&scan, channel_index,
4799 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
4800
4801 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 2000;
4802 } else {
4803#endif /* CONFIG_IPW_MONITOR */
4804 /* If we are roaming, then make this a directed scan for the current
4805 * network. Otherwise, ensure that every other scan is a fast
4806 * channel hop scan */
4807 if ((priv->status & STATUS_ROAMING)
4808 || (!(priv->status & STATUS_ASSOCIATED)
4809 && (priv->config & CFG_STATIC_ESSID)
4810 && (scan.full_scan_index % 2))) {
4811 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
4812 if (err) {
4813 IPW_DEBUG_HC
4814 ("Attempt to send SSID command failed.\n");
4815 return err;
4816 }
4817
4818 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
4819 } else {
4820 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
4821 }
4822
4823 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
4824 int start = channel_index;
4825 for (i = 0; i < MAX_A_CHANNELS; i++) {
4826 if (band_a_active_channel[i] == 0)
4827 break;
4828 if ((priv->status & STATUS_ASSOCIATED) &&
4829 band_a_active_channel[i] == priv->channel)
4830 continue;
4831 channel_index++;
4832 scan.channels_list[channel_index] =
4833 band_a_active_channel[i];
4834 ipw_set_scan_type(&scan, channel_index,
4835 scan_type);
4836 }
4837
4838 if (start != channel_index) {
4839 scan.channels_list[start] =
4840 (u8) (IPW_A_MODE << 6) | (channel_index -
4841 start);
4842 channel_index++;
4843 }
4844 }
4845
4846 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
4847 int start = channel_index;
4848 for (i = 0; i < MAX_B_CHANNELS; i++) {
4849 if (band_b_active_channel[i] == 0)
4850 break;
4851 if ((priv->status & STATUS_ASSOCIATED) &&
4852 band_b_active_channel[i] == priv->channel)
4853 continue;
4854 channel_index++;
4855 scan.channels_list[channel_index] =
4856 band_b_active_channel[i];
4857 ipw_set_scan_type(&scan, channel_index,
4858 scan_type);
4859 }
4860
4861 if (start != channel_index) {
4862 scan.channels_list[start] =
4863 (u8) (IPW_B_MODE << 6) | (channel_index -
4864 start);
4865 }
4866 }
4867#ifdef CONFIG_IPW_MONITOR
4868 }
4869#endif
4870
4871 err = ipw_send_scan_request_ext(priv, &scan);
4872 if (err) {
4873 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
4874 return -EIO;
4875 }
4876
4877 priv->status |= STATUS_SCANNING;
4878 priv->status &= ~STATUS_SCAN_PENDING;
4879
4880 return 0;
4881}
4882
4883/* Support for wpa_supplicant. Will be replaced with WEXT once
4884 * they get WPA support. */
4885#ifdef CONFIG_IEEE80211_WPA
4886
4887/* following definitions must match definitions in driver_ipw.c */
4888
4889#define IPW_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
4890
4891#define IPW_CMD_SET_WPA_PARAM 1
4892#define IPW_CMD_SET_WPA_IE 2
4893#define IPW_CMD_SET_ENCRYPTION 3
4894#define IPW_CMD_MLME 4
4895
4896#define IPW_PARAM_WPA_ENABLED 1
4897#define IPW_PARAM_TKIP_COUNTERMEASURES 2
4898#define IPW_PARAM_DROP_UNENCRYPTED 3
4899#define IPW_PARAM_PRIVACY_INVOKED 4
4900#define IPW_PARAM_AUTH_ALGS 5
4901#define IPW_PARAM_IEEE_802_1X 6
4902
4903#define IPW_MLME_STA_DEAUTH 1
4904#define IPW_MLME_STA_DISASSOC 2
4905
4906#define IPW_CRYPT_ERR_UNKNOWN_ALG 2
4907#define IPW_CRYPT_ERR_UNKNOWN_ADDR 3
4908#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED 4
4909#define IPW_CRYPT_ERR_KEY_SET_FAILED 5
4910#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED 6
4911#define IPW_CRYPT_ERR_CARD_CONF_FAILED 7
4912
4913#define IPW_CRYPT_ALG_NAME_LEN 16
4914
4915struct ipw_param {
4916 u32 cmd;
4917 u8 sta_addr[ETH_ALEN];
4918 union {
4919 struct {
4920 u8 name;
4921 u32 value;
4922 } wpa_param;
4923 struct {
4924 u32 len;
4925 u8 *data;
4926 } wpa_ie;
4927 struct {
4928 int command;
4929 int reason_code;
4930 } mlme;
4931 struct {
4932 u8 alg[IPW_CRYPT_ALG_NAME_LEN];
4933 u8 set_tx;
4934 u32 err;
4935 u8 idx;
4936 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
4937 u16 key_len;
4938 u8 key[0];
4939 } crypt;
4940
4941 } u;
4942};
4943
4944/* end of driver_ipw.c code */
4945
4946static int ipw_wpa_enable(struct ipw_priv *priv, int value)
4947{
4948 struct ieee80211_device *ieee = priv->ieee;
4949 struct ieee80211_security sec = {
4950 .flags = SEC_LEVEL | SEC_ENABLED,
4951 };
4952 int ret = 0;
4953
4954 ieee->wpa_enabled = value;
4955
4956 if (value) {
4957 sec.level = SEC_LEVEL_3;
4958 sec.enabled = 1;
4959 } else {
4960 sec.level = SEC_LEVEL_0;
4961 sec.enabled = 0;
4962 }
4963
4964 if (ieee->set_security)
4965 ieee->set_security(ieee->dev, &sec);
4966 else
4967 ret = -EOPNOTSUPP;
4968
4969 return ret;
4970}
4971
4972#define AUTH_ALG_OPEN_SYSTEM 0x1
4973#define AUTH_ALG_SHARED_KEY 0x2
4974
4975static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
4976{
4977 struct ieee80211_device *ieee = priv->ieee;
4978 struct ieee80211_security sec = {
4979 .flags = SEC_AUTH_MODE,
4980 };
4981 int ret = 0;
4982
4983 if (value & AUTH_ALG_SHARED_KEY) {
4984 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
4985 ieee->open_wep = 0;
4986 } else {
4987 sec.auth_mode = WLAN_AUTH_OPEN;
4988 ieee->open_wep = 1;
4989 }
4990
4991 if (ieee->set_security)
4992 ieee->set_security(ieee->dev, &sec);
4993 else
4994 ret = -EOPNOTSUPP;
4995
4996 return ret;
4997}
4998
4999static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5000{
5001 struct ipw_priv *priv = ieee80211_priv(dev);
5002 int ret = 0;
5003
5004 switch (name) {
5005 case IPW_PARAM_WPA_ENABLED:
5006 ret = ipw_wpa_enable(priv, value);
5007 break;
5008
5009 case IPW_PARAM_TKIP_COUNTERMEASURES:
5010 priv->ieee->tkip_countermeasures = value;
5011 break;
5012
5013 case IPW_PARAM_DROP_UNENCRYPTED:
5014 priv->ieee->drop_unencrypted = value;
5015 break;
5016
5017 case IPW_PARAM_PRIVACY_INVOKED:
5018 priv->ieee->privacy_invoked = value;
5019 break;
5020
5021 case IPW_PARAM_AUTH_ALGS:
5022 ret = ipw_wpa_set_auth_algs(priv, value);
5023 break;
5024
5025 case IPW_PARAM_IEEE_802_1X:
5026 priv->ieee->ieee802_1x = value;
5027 break;
5028
5029 default:
5030 IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name);
5031 ret = -EOPNOTSUPP;
5032 }
5033
5034 return ret;
5035}
5036
5037static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
5038{
5039 struct ipw_priv *priv = ieee80211_priv(dev);
5040 int ret = 0;
5041
5042 switch (command) {
5043 case IPW_MLME_STA_DEAUTH:
5044 // silently ignore
5045 break;
5046
5047 case IPW_MLME_STA_DISASSOC:
5048 ipw_disassociate(priv);
5049 break;
5050
5051 default:
5052 IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command);
5053 ret = -EOPNOTSUPP;
5054 }
5055
5056 return ret;
5057}
5058
5059static int ipw_set_rsn_capa(struct ipw_priv *priv,
5060 char *capabilities, int length)
5061{
5062 struct host_cmd cmd = {
5063 .cmd = IPW_CMD_RSN_CAPABILITIES,
5064 .len = length,
5065 };
5066
5067 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
5068
5069 memcpy(&cmd.param, capabilities, length);
5070 if (ipw_send_cmd(priv, &cmd)) {
5071 IPW_ERROR("failed to send HOST_CMD_RSN_CAPABILITIES command\n");
5072 return -1;
5073 }
5074 return 0;
5075}
5076
5077void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie, int wpa_ie_len)
5078{
5079 /* make sure WPA is enabled */
5080 ipw_wpa_enable(priv, 1);
5081
5082 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))
5083 ipw_disassociate(priv);
5084}
5085
5086static int ipw_wpa_set_wpa_ie(struct net_device *dev,
5087 struct ipw_param *param, int plen)
5088{
5089 struct ipw_priv *priv = ieee80211_priv(dev);
5090 struct ieee80211_device *ieee = priv->ieee;
5091 u8 *buf;
5092
5093 if (!ieee->wpa_enabled)
5094 return -EOPNOTSUPP;
5095
5096 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5097 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
5098 return -EINVAL;
5099
5100 if (param->u.wpa_ie.len) {
5101 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5102 if (buf == NULL)
5103 return -ENOMEM;
5104
5105 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5106 kfree(ieee->wpa_ie);
5107 ieee->wpa_ie = buf;
5108 ieee->wpa_ie_len = param->u.wpa_ie.len;
5109 } else {
5110 kfree(ieee->wpa_ie);
5111 ieee->wpa_ie = NULL;
5112 ieee->wpa_ie_len = 0;
5113 }
5114
5115 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5116 return 0;
5117}
5118
5119/* implementation borrowed from hostap driver */
5120
5121static int ipw_wpa_set_encryption(struct net_device *dev,
5122 struct ipw_param *param, int param_len)
5123{
5124 int ret = 0;
5125 struct ipw_priv *priv = ieee80211_priv(dev);
5126 struct ieee80211_device *ieee = priv->ieee;
5127 struct ieee80211_crypto_ops *ops;
5128 struct ieee80211_crypt_data **crypt;
5129
5130 struct ieee80211_security sec = {
5131 .flags = 0,
5132 };
5133
5134 param->u.crypt.err = 0;
5135 param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0';
5136
5137 if (param_len !=
5138 (int)((char *)param->u.crypt.key - (char *)param) +
5139 param->u.crypt.key_len) {
5140 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
5141 param->u.crypt.key_len);
5142 return -EINVAL;
5143 }
5144 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
5145 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
5146 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
5147 if (param->u.crypt.idx >= WEP_KEYS)
5148 return -EINVAL;
5149 crypt = &ieee->crypt[param->u.crypt.idx];
5150 } else {
5151 return -EINVAL;
5152 }
5153
5154 if (strcmp(param->u.crypt.alg, "none") == 0) {
5155 if (crypt) {
5156 sec.enabled = 0;
5157 sec.level = SEC_LEVEL_0;
5158 sec.flags |= SEC_ENABLED | SEC_LEVEL;
5159 ieee80211_crypt_delayed_deinit(ieee, crypt);
5160 }
5161 goto done;
5162 }
5163 sec.enabled = 1;
5164 sec.flags |= SEC_ENABLED;
5165
5166 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5167 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
5168 request_module("ieee80211_crypt_wep");
5169 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5170 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
5171 request_module("ieee80211_crypt_tkip");
5172 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5173 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
5174 request_module("ieee80211_crypt_ccmp");
5175 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
5176 }
5177 if (ops == NULL) {
5178 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
5179 dev->name, param->u.crypt.alg);
5180 param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG;
5181 ret = -EINVAL;
5182 goto done;
5183 }
5184
5185 if (*crypt == NULL || (*crypt)->ops != ops) {
5186 struct ieee80211_crypt_data *new_crypt;
5187
5188 ieee80211_crypt_delayed_deinit(ieee, crypt);
5189
5190 new_crypt = (struct ieee80211_crypt_data *)
5191 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
5192 if (new_crypt == NULL) {
5193 ret = -ENOMEM;
5194 goto done;
5195 }
5196 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
5197 new_crypt->ops = ops;
5198 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
5199 new_crypt->priv =
5200 new_crypt->ops->init(param->u.crypt.idx);
5201
5202 if (new_crypt->priv == NULL) {
5203 kfree(new_crypt);
5204 param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;
5205 ret = -EINVAL;
5206 goto done;
5207 }
5208
5209 *crypt = new_crypt;
5210 }
5211
5212 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
5213 (*crypt)->ops->set_key(param->u.crypt.key,
5214 param->u.crypt.key_len, param->u.crypt.seq,
5215 (*crypt)->priv) < 0) {
5216 IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
5217 param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;
5218 ret = -EINVAL;
5219 goto done;
5220 }
5221
5222 if (param->u.crypt.set_tx) {
5223 ieee->tx_keyidx = param->u.crypt.idx;
5224 sec.active_key = param->u.crypt.idx;
5225 sec.flags |= SEC_ACTIVE_KEY;
5226 }
5227
5228 if (ops->name != NULL) {
5229 if (strcmp(ops->name, "WEP") == 0) {
5230 memcpy(sec.keys[param->u.crypt.idx],
5231 param->u.crypt.key, param->u.crypt.key_len);
5232 sec.key_sizes[param->u.crypt.idx] =
5233 param->u.crypt.key_len;
5234 sec.flags |= (1 << param->u.crypt.idx);
5235 sec.flags |= SEC_LEVEL;
5236 sec.level = SEC_LEVEL_1;
5237 } else if (strcmp(ops->name, "TKIP") == 0) {
5238 sec.flags |= SEC_LEVEL;
5239 sec.level = SEC_LEVEL_2;
5240 } else if (strcmp(ops->name, "CCMP") == 0) {
5241 sec.flags |= SEC_LEVEL;
5242 sec.level = SEC_LEVEL_3;
5243 }
5244 }
5245 done:
5246 if (ieee->set_security)
5247 ieee->set_security(ieee->dev, &sec);
5248
5249 /* Do not reset port if card is in Managed mode since resetting will
5250 * generate new IEEE 802.11 authentication which may end up in looping
5251 * with IEEE 802.1X. If your hardware requires a reset after WEP
5252 * configuration (for example... Prism2), implement the reset_port in
5253 * the callbacks structures used to initialize the 802.11 stack. */
5254 if (ieee->reset_on_keychange &&
5255 ieee->iw_mode != IW_MODE_INFRA &&
5256 ieee->reset_port && ieee->reset_port(dev)) {
5257 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
5258 param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
5259 return -EINVAL;
5260 }
5261
5262 return ret;
5263}
5264
5265static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
5266{
5267 struct ipw_param *param;
5268 int ret = 0;
5269
5270 IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
5271
5272 if (p->length < sizeof(struct ipw_param) || !p->pointer)
5273 return -EINVAL;
5274
5275 param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);
5276 if (param == NULL)
5277 return -ENOMEM;
5278
5279 if (copy_from_user(param, p->pointer, p->length)) {
5280 kfree(param);
5281 return -EFAULT;
5282 }
5283
5284 switch (param->cmd) {
5285
5286 case IPW_CMD_SET_WPA_PARAM:
5287 ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,
5288 param->u.wpa_param.value);
5289 break;
5290
5291 case IPW_CMD_SET_WPA_IE:
5292 ret = ipw_wpa_set_wpa_ie(dev, param, p->length);
5293 break;
5294
5295 case IPW_CMD_SET_ENCRYPTION:
5296 ret = ipw_wpa_set_encryption(dev, param, p->length);
5297 break;
5298
5299 case IPW_CMD_MLME:
5300 ret = ipw_wpa_mlme(dev, param->u.mlme.command,
5301 param->u.mlme.reason_code);
5302 break;
5303
5304 default:
5305 IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",
5306 dev->name, param->cmd);
5307 ret = -EOPNOTSUPP;
5308 }
5309
5310 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
5311 ret = -EFAULT;
5312
5313 kfree(param);
5314 return ret;
5315}
5316#endif /* CONFIG_IEEE80211_WPA */
5317
4612static int ipw_associate_network(struct ipw_priv *priv, 5318static int ipw_associate_network(struct ipw_priv *priv,
4613 struct ieee80211_network *network, 5319 struct ieee80211_network *network,
4614 struct ipw_supported_rates *rates, int roaming) 5320 struct ipw_supported_rates *rates, int roaming)
@@ -4640,6 +5346,14 @@ static int ipw_associate_network(struct ipw_priv *priv,
4640 if (priv->capability & CAP_PRIVACY_ON) 5346 if (priv->capability & CAP_PRIVACY_ON)
4641 ipw_send_wep_keys(priv); 5347 ipw_send_wep_keys(priv);
4642 5348
5349#ifdef CONFIG_IEEE80211_WPA
5350 if (priv->ieee->wpa_enabled) {
5351 priv->assoc_request.policy_support = 0x02; /* RSN active */
5352 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
5353 priv->ieee->wpa_ie_len);
5354 }
5355#endif
5356
4643 /* 5357 /*
4644 * It is valid for our ieee device to support multiple modes, but 5358 * It is valid for our ieee device to support multiple modes, but
4645 * when it comes to associating to a given network we have to choose 5359 * when it comes to associating to a given network we have to choose
@@ -4652,13 +5366,29 @@ static int ipw_associate_network(struct ipw_priv *priv,
4652 else if (network->mode & priv->ieee->mode & IEEE_B) 5366 else if (network->mode & priv->ieee->mode & IEEE_B)
4653 priv->assoc_request.ieee_mode = IPW_B_MODE; 5367 priv->assoc_request.ieee_mode = IPW_B_MODE;
4654 5368
5369 priv->assoc_request.capability = network->capability;
5370 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
5371 && !(priv->config & CFG_PREAMBLE_LONG)) {
5372 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;
5373 } else {
5374 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;
5375
5376 /* Clear the short preamble if we won't be supporting it */
5377 priv->assoc_request.capability &=
5378 ~WLAN_CAPABILITY_SHORT_PREAMBLE;
5379 }
5380
4655 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, " 5381 IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
4656 "802.11%c [%d], enc=%s%s%s%c%c\n", 5382 "802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
4657 roaming ? "Rea" : "A", 5383 roaming ? "Rea" : "A",
4658 escape_essid(priv->essid, priv->essid_len), 5384 escape_essid(priv->essid, priv->essid_len),
4659 network->channel, 5385 network->channel,
4660 ipw_modes[priv->assoc_request.ieee_mode], 5386 ipw_modes[priv->assoc_request.ieee_mode],
4661 rates->num_rates, 5387 rates->num_rates,
5388 (priv->assoc_request.preamble_length ==
5389 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",
5390 network->capability &
5391 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",
4662 priv->capability & CAP_PRIVACY_ON ? "on " : "off", 5392 priv->capability & CAP_PRIVACY_ON ? "on " : "off",
4663 priv->capability & CAP_PRIVACY_ON ? 5393 priv->capability & CAP_PRIVACY_ON ?
4664 (priv->capability & CAP_SHARED_KEY ? "(shared)" : 5394 (priv->capability & CAP_SHARED_KEY ? "(shared)" :
@@ -4693,7 +5423,6 @@ static int ipw_associate_network(struct ipw_priv *priv,
4693 priv->assoc_request.atim_window = 0; 5423 priv->assoc_request.atim_window = 0;
4694 } 5424 }
4695 5425
4696 priv->assoc_request.capability = network->capability;
4697 priv->assoc_request.listen_interval = network->listen_interval; 5426 priv->assoc_request.listen_interval = network->listen_interval;
4698 5427
4699 err = ipw_send_ssid(priv, priv->essid, priv->essid_len); 5428 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
@@ -4717,7 +5446,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
4717 } 5446 }
4718 5447
4719 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi); 5448 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);
4720 err = ipw_set_sensitivity(priv, network->stats.rssi); 5449 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);
4721 if (err) { 5450 if (err) {
4722 IPW_DEBUG_HC("Attempt to send associate command failed.\n"); 5451 IPW_DEBUG_HC("Attempt to send associate command failed.\n");
4723 return err; 5452 return err;
@@ -4899,6 +5628,32 @@ static inline void ipw_handle_data_packet(struct ipw_priv *priv,
4899 rxb->skb = NULL; 5628 rxb->skb = NULL;
4900} 5629}
4901 5630
5631static inline int is_network_packet(struct ipw_priv *priv,
5632 struct ieee80211_hdr_4addr *header)
5633{
5634 /* Filter incoming packets to determine if they are targetted toward
5635 * this network, discarding packets coming from ourselves */
5636 switch (priv->ieee->iw_mode) {
5637 case IW_MODE_ADHOC:
5638 if (is_broadcast_ether_addr(header->addr1) ||
5639 is_multicast_ether_addr(header->addr1))
5640 return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
5641 else
5642 return memcmp(header->addr1, priv->net_dev->dev_addr,
5643 ETH_ALEN);
5644 break;
5645 case IW_MODE_INFRA:
5646 if (is_broadcast_ether_addr(header->addr3) ||
5647 is_multicast_ether_addr(header->addr3))
5648 return !memcmp(header->addr1, priv->bssid, ETH_ALEN);
5649 else
5650 return memcmp(header->addr3, priv->net_dev->dev_addr,
5651 ETH_ALEN);
5652 break;
5653 }
5654 return 1;
5655}
5656
4902/* 5657/*
4903 * Main entry function for recieving a packet with 80211 headers. This 5658 * Main entry function for recieving a packet with 80211 headers. This
4904 * should be called when ever the FW has notified us that there is a new 5659 * should be called when ever the FW has notified us that there is a new
@@ -4962,7 +5717,7 @@ static void ipw_rx(struct ipw_priv *priv)
4962 5717
4963 priv->rx_packets++; 5718 priv->rx_packets++;
4964 5719
4965#ifdef CONFIG_IPW_PROMISC 5720#ifdef CONFIG_IPW_MONITOR
4966 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 5721 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
4967 ipw_handle_data_packet(priv, rxb, 5722 ipw_handle_data_packet(priv, rxb,
4968 &stats); 5723 &stats);
@@ -4979,35 +5734,9 @@ static void ipw_rx(struct ipw_priv *priv)
4979 * correctly -- we should probably use the 5734 * correctly -- we should probably use the
4980 * frame control of the packet and disregard 5735 * frame control of the packet and disregard
4981 * the current iw_mode */ 5736 * the current iw_mode */
4982 switch (priv->ieee->iw_mode) {
4983 case IW_MODE_ADHOC:
4984 network_packet =
4985 !memcmp(header->addr1,
4986 priv->net_dev->dev_addr,
4987 ETH_ALEN) ||
4988 !memcmp(header->addr3,
4989 priv->bssid, ETH_ALEN) ||
4990 is_broadcast_ether_addr(header->
4991 addr1)
4992 || is_multicast_ether_addr(header->
4993 addr1);
4994 break;
4995
4996 case IW_MODE_INFRA:
4997 default:
4998 network_packet =
4999 !memcmp(header->addr3,
5000 priv->bssid, ETH_ALEN) ||
5001 !memcmp(header->addr1,
5002 priv->net_dev->dev_addr,
5003 ETH_ALEN) ||
5004 is_broadcast_ether_addr(header->
5005 addr1)
5006 || is_multicast_ether_addr(header->
5007 addr1);
5008 break;
5009 }
5010 5737
5738 network_packet =
5739 is_network_packet(priv, header);
5011 if (network_packet && priv->assoc_network) { 5740 if (network_packet && priv->assoc_network) {
5012 priv->assoc_network->stats.rssi = 5741 priv->assoc_network->stats.rssi =
5013 stats.rssi; 5742 stats.rssi;
@@ -5108,130 +5837,6 @@ static void ipw_rx(struct ipw_priv *priv)
5108 ipw_rx_queue_restock(priv); 5837 ipw_rx_queue_restock(priv);
5109} 5838}
5110 5839
5111static void ipw_abort_scan(struct ipw_priv *priv)
5112{
5113 int err;
5114
5115 if (priv->status & STATUS_SCAN_ABORTING) {
5116 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");
5117 return;
5118 }
5119 priv->status |= STATUS_SCAN_ABORTING;
5120
5121 err = ipw_send_scan_abort(priv);
5122 if (err)
5123 IPW_DEBUG_HC("Request to abort scan failed.\n");
5124}
5125
5126static int ipw_request_scan(struct ipw_priv *priv)
5127{
5128 struct ipw_scan_request_ext scan;
5129 int channel_index = 0;
5130 int i, err, scan_type;
5131
5132 if (priv->status & STATUS_EXIT_PENDING) {
5133 IPW_DEBUG_SCAN("Aborting scan due to device shutdown\n");
5134 priv->status |= STATUS_SCAN_PENDING;
5135 return 0;
5136 }
5137
5138 if (priv->status & STATUS_SCANNING) {
5139 IPW_DEBUG_HC("Concurrent scan requested. Aborting first.\n");
5140 priv->status |= STATUS_SCAN_PENDING;
5141 ipw_abort_scan(priv);
5142 return 0;
5143 }
5144
5145 if (priv->status & STATUS_SCAN_ABORTING) {
5146 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");
5147 priv->status |= STATUS_SCAN_PENDING;
5148 return 0;
5149 }
5150
5151 if (priv->status & STATUS_RF_KILL_MASK) {
5152 IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n");
5153 priv->status |= STATUS_SCAN_PENDING;
5154 return 0;
5155 }
5156
5157 memset(&scan, 0, sizeof(scan));
5158
5159 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20;
5160 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20;
5161 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
5162
5163 scan.full_scan_index = ieee80211_get_scans(priv->ieee);
5164 /* If we are roaming, then make this a directed scan for the current
5165 * network. Otherwise, ensure that every other scan is a fast
5166 * channel hop scan */
5167 if ((priv->status & STATUS_ROAMING)
5168 || (!(priv->status & STATUS_ASSOCIATED)
5169 && (priv->config & CFG_STATIC_ESSID)
5170 && (scan.full_scan_index % 2))) {
5171 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
5172 if (err) {
5173 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");
5174 return err;
5175 }
5176
5177 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;
5178 } else {
5179 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;
5180 }
5181
5182 if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
5183 int start = channel_index;
5184 for (i = 0; i < MAX_A_CHANNELS; i++) {
5185 if (band_a_active_channel[i] == 0)
5186 break;
5187 if ((priv->status & STATUS_ASSOCIATED) &&
5188 band_a_active_channel[i] == priv->channel)
5189 continue;
5190 channel_index++;
5191 scan.channels_list[channel_index] =
5192 band_a_active_channel[i];
5193 ipw_set_scan_type(&scan, channel_index, scan_type);
5194 }
5195
5196 if (start != channel_index) {
5197 scan.channels_list[start] = (u8) (IPW_A_MODE << 6) |
5198 (channel_index - start);
5199 channel_index++;
5200 }
5201 }
5202
5203 if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
5204 int start = channel_index;
5205 for (i = 0; i < MAX_B_CHANNELS; i++) {
5206 if (band_b_active_channel[i] == 0)
5207 break;
5208 if ((priv->status & STATUS_ASSOCIATED) &&
5209 band_b_active_channel[i] == priv->channel)
5210 continue;
5211 channel_index++;
5212 scan.channels_list[channel_index] =
5213 band_b_active_channel[i];
5214 ipw_set_scan_type(&scan, channel_index, scan_type);
5215 }
5216
5217 if (start != channel_index) {
5218 scan.channels_list[start] = (u8) (IPW_B_MODE << 6) |
5219 (channel_index - start);
5220 }
5221 }
5222
5223 err = ipw_send_scan_request_ext(priv, &scan);
5224 if (err) {
5225 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);
5226 return -EIO;
5227 }
5228
5229 priv->status |= STATUS_SCANNING;
5230 priv->status &= ~STATUS_SCAN_PENDING;
5231
5232 return 0;
5233}
5234
5235/* 5840/*
5236 * This file defines the Wireless Extension handlers. It does not 5841 * This file defines the Wireless Extension handlers. It does not
5237 * define any methods of hardware manipulation and relies on the 5842 * define any methods of hardware manipulation and relies on the
@@ -5357,7 +5962,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
5357 return 0; 5962 return 0;
5358 5963
5359 switch (wrqu->mode) { 5964 switch (wrqu->mode) {
5360#ifdef CONFIG_IPW_PROMISC 5965#ifdef CONFIG_IPW_MONITOR
5361 case IW_MODE_MONITOR: 5966 case IW_MODE_MONITOR:
5362#endif 5967#endif
5363 case IW_MODE_ADHOC: 5968 case IW_MODE_ADHOC:
@@ -5370,13 +5975,13 @@ static int ipw_wx_set_mode(struct net_device *dev,
5370 return -EINVAL; 5975 return -EINVAL;
5371 } 5976 }
5372 5977
5373#ifdef CONFIG_IPW_PROMISC 5978#ifdef CONFIG_IPW_MONITOR
5374 if (priv->ieee->iw_mode == IW_MODE_MONITOR) 5979 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5375 priv->net_dev->type = ARPHRD_ETHER; 5980 priv->net_dev->type = ARPHRD_ETHER;
5376 5981
5377 if (wrqu->mode == IW_MODE_MONITOR) 5982 if (wrqu->mode == IW_MODE_MONITOR)
5378 priv->net_dev->type = ARPHRD_IEEE80211; 5983 priv->net_dev->type = ARPHRD_IEEE80211;
5379#endif /* CONFIG_IPW_PROMISC */ 5984#endif /* CONFIG_IPW_MONITOR */
5380 5985
5381#ifdef CONFIG_PM 5986#ifdef CONFIG_PM
5382 /* Free the existing firmware and reset the fw_loaded 5987 /* Free the existing firmware and reset the fw_loaded
@@ -5680,8 +6285,111 @@ static int ipw_wx_set_rate(struct net_device *dev,
5680 struct iw_request_info *info, 6285 struct iw_request_info *info,
5681 union iwreq_data *wrqu, char *extra) 6286 union iwreq_data *wrqu, char *extra)
5682{ 6287{
5683 IPW_DEBUG_WX("0x%p, 0x%p, 0x%p\n", dev, info, wrqu); 6288 /* TODO: We should use semaphores or locks for access to priv */
5684 return -EOPNOTSUPP; 6289 struct ipw_priv *priv = ieee80211_priv(dev);
6290 u32 target_rate = wrqu->bitrate.value;
6291 u32 fixed, mask;
6292
6293 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */
6294 /* value = X, fixed = 1 means only rate X */
6295 /* value = X, fixed = 0 means all rates lower equal X */
6296
6297 if (target_rate == -1) {
6298 fixed = 0;
6299 mask = IEEE80211_DEFAULT_RATES_MASK;
6300 /* Now we should reassociate */
6301 goto apply;
6302 }
6303
6304 mask = 0;
6305 fixed = wrqu->bitrate.fixed;
6306
6307 if (target_rate == 1000000 || !fixed)
6308 mask |= IEEE80211_CCK_RATE_1MB_MASK;
6309 if (target_rate == 1000000)
6310 goto apply;
6311
6312 if (target_rate == 2000000 || !fixed)
6313 mask |= IEEE80211_CCK_RATE_2MB_MASK;
6314 if (target_rate == 2000000)
6315 goto apply;
6316
6317 if (target_rate == 5500000 || !fixed)
6318 mask |= IEEE80211_CCK_RATE_5MB_MASK;
6319 if (target_rate == 5500000)
6320 goto apply;
6321
6322 if (target_rate == 6000000 || !fixed)
6323 mask |= IEEE80211_OFDM_RATE_6MB_MASK;
6324 if (target_rate == 6000000)
6325 goto apply;
6326
6327 if (target_rate == 9000000 || !fixed)
6328 mask |= IEEE80211_OFDM_RATE_9MB_MASK;
6329 if (target_rate == 9000000)
6330 goto apply;
6331
6332 if (target_rate == 11000000 || !fixed)
6333 mask |= IEEE80211_CCK_RATE_11MB_MASK;
6334 if (target_rate == 11000000)
6335 goto apply;
6336
6337 if (target_rate == 12000000 || !fixed)
6338 mask |= IEEE80211_OFDM_RATE_12MB_MASK;
6339 if (target_rate == 12000000)
6340 goto apply;
6341
6342 if (target_rate == 18000000 || !fixed)
6343 mask |= IEEE80211_OFDM_RATE_18MB_MASK;
6344 if (target_rate == 18000000)
6345 goto apply;
6346
6347 if (target_rate == 24000000 || !fixed)
6348 mask |= IEEE80211_OFDM_RATE_24MB_MASK;
6349 if (target_rate == 24000000)
6350 goto apply;
6351
6352 if (target_rate == 36000000 || !fixed)
6353 mask |= IEEE80211_OFDM_RATE_36MB_MASK;
6354 if (target_rate == 36000000)
6355 goto apply;
6356
6357 if (target_rate == 48000000 || !fixed)
6358 mask |= IEEE80211_OFDM_RATE_48MB_MASK;
6359 if (target_rate == 48000000)
6360 goto apply;
6361
6362 if (target_rate == 54000000 || !fixed)
6363 mask |= IEEE80211_OFDM_RATE_54MB_MASK;
6364 if (target_rate == 54000000)
6365 goto apply;
6366
6367 IPW_DEBUG_WX("invalid rate specified, returning error\n");
6368 return -EINVAL;
6369
6370 apply:
6371 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
6372 mask, fixed ? "fixed" : "sub-rates");
6373
6374 if (mask == IEEE80211_DEFAULT_RATES_MASK)
6375 priv->config &= ~CFG_FIXED_RATE;
6376 else
6377 priv->config |= CFG_FIXED_RATE;
6378
6379 if (priv->rates_mask != mask) {
6380 priv->rates_mask = mask;
6381 /* If we are already associated or are currently trying to
6382 * associate, disassociate and try again */
6383 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
6384 IPW_DEBUG_ASSOC("Disassociating due to RATE change.\n");
6385 ipw_disassociate(priv);
6386 }
6387 } else {
6388 /* We are not yet associated, so kick one off... */
6389 ipw_associate(priv);
6390 }
6391
6392 return 0;
5685} 6393}
5686 6394
5687static int ipw_wx_get_rate(struct net_device *dev, 6395static int ipw_wx_get_rate(struct net_device *dev,
@@ -5888,7 +6596,6 @@ static int ipw_wx_set_power(struct net_device *dev,
5888 IPW_DEBUG_WX("failed setting power mode.\n"); 6596 IPW_DEBUG_WX("failed setting power mode.\n");
5889 return err; 6597 return err;
5890 } 6598 }
5891
5892 IPW_DEBUG_WX("SET Power Management Mode -> off\n"); 6599 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
5893 6600
5894 return 0; 6601 return 0;
@@ -6069,37 +6776,30 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6069{ 6776{
6070 struct ipw_priv *priv = ieee80211_priv(dev); 6777 struct ipw_priv *priv = ieee80211_priv(dev);
6071 6778
6072 switch (priv->ieee->freq_band) { 6779 switch (priv->ieee->mode) {
6073 case IEEE80211_24GHZ_BAND: 6780 case IEEE_A:
6074 switch (priv->ieee->modulation) {
6075 case IEEE80211_CCK_MODULATION:
6076 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6077 break;
6078 case IEEE80211_OFDM_MODULATION:
6079 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6080 break;
6081 default:
6082 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6083 break;
6084 }
6085 break;
6086
6087 case IEEE80211_52GHZ_BAND:
6088 strncpy(extra, "802.11a (1)", MAX_WX_STRING); 6781 strncpy(extra, "802.11a (1)", MAX_WX_STRING);
6089 break; 6782 break;
6090 6783 case IEEE_B:
6091 default: /* Mixed Band */ 6784 strncpy(extra, "802.11b (2)", MAX_WX_STRING);
6092 switch (priv->ieee->modulation) { 6785 break;
6093 case IEEE80211_CCK_MODULATION: 6786 case IEEE_A | IEEE_B:
6094 strncpy(extra, "802.11ab (3)", MAX_WX_STRING); 6787 strncpy(extra, "802.11ab (3)", MAX_WX_STRING);
6095 break; 6788 break;
6096 case IEEE80211_OFDM_MODULATION: 6789 case IEEE_G:
6097 strncpy(extra, "802.11ag (5)", MAX_WX_STRING); 6790 strncpy(extra, "802.11g (4)", MAX_WX_STRING);
6098 break; 6791 break;
6099 default: 6792 case IEEE_A | IEEE_G:
6100 strncpy(extra, "802.11abg (7)", MAX_WX_STRING); 6793 strncpy(extra, "802.11ag (5)", MAX_WX_STRING);
6101 break; 6794 break;
6102 } 6795 case IEEE_B | IEEE_G:
6796 strncpy(extra, "802.11bg (6)", MAX_WX_STRING);
6797 break;
6798 case IEEE_A | IEEE_B | IEEE_G:
6799 strncpy(extra, "802.11abg (7)", MAX_WX_STRING);
6800 break;
6801 default:
6802 strncpy(extra, "unknown", MAX_WX_STRING);
6103 break; 6803 break;
6104 } 6804 }
6105 6805
@@ -6110,8 +6810,55 @@ static int ipw_wx_get_wireless_mode(struct net_device *dev,
6110 return 0; 6810 return 0;
6111} 6811}
6112 6812
6113#ifdef CONFIG_IPW_PROMISC 6813static int ipw_wx_set_preamble(struct net_device *dev,
6114static int ipw_wx_set_promisc(struct net_device *dev, 6814 struct iw_request_info *info,
6815 union iwreq_data *wrqu, char *extra)
6816{
6817 struct ipw_priv *priv = ieee80211_priv(dev);
6818 int mode = *(int *)extra;
6819
6820 /* Switching from SHORT -> LONG requires a disassociation */
6821 if (mode == 1) {
6822 if (!(priv->config & CFG_PREAMBLE_LONG)) {
6823 priv->config |= CFG_PREAMBLE_LONG;
6824 if (priv->status &
6825 (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
6826 IPW_DEBUG_ASSOC
6827 ("Disassociating due to preamble "
6828 "change.\n");
6829 ipw_disassociate(priv);
6830 }
6831 }
6832 goto done;
6833 }
6834
6835 if (mode == 0) {
6836 priv->config &= ~CFG_PREAMBLE_LONG;
6837 goto done;
6838 }
6839
6840 return -EINVAL;
6841
6842 done:
6843 return 0;
6844}
6845
6846static int ipw_wx_get_preamble(struct net_device *dev,
6847 struct iw_request_info *info,
6848 union iwreq_data *wrqu, char *extra)
6849{
6850 struct ipw_priv *priv = ieee80211_priv(dev);
6851
6852 if (priv->config & CFG_PREAMBLE_LONG)
6853 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
6854 else
6855 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
6856
6857 return 0;
6858}
6859
6860#ifdef CONFIG_IPW_MONITOR
6861static int ipw_wx_set_monitor(struct net_device *dev,
6115 struct iw_request_info *info, 6862 struct iw_request_info *info,
6116 union iwreq_data *wrqu, char *extra) 6863 union iwreq_data *wrqu, char *extra)
6117{ 6864{
@@ -6119,7 +6866,7 @@ static int ipw_wx_set_promisc(struct net_device *dev,
6119 int *parms = (int *)extra; 6866 int *parms = (int *)extra;
6120 int enable = (parms[0] > 0); 6867 int enable = (parms[0] > 0);
6121 6868
6122 IPW_DEBUG_WX("SET PROMISC: %d %d\n", enable, parms[1]); 6869 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
6123 if (enable) { 6870 if (enable) {
6124 if (priv->ieee->iw_mode != IW_MODE_MONITOR) { 6871 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
6125 priv->net_dev->type = ARPHRD_IEEE80211; 6872 priv->net_dev->type = ARPHRD_IEEE80211;
@@ -6145,47 +6892,49 @@ static int ipw_wx_reset(struct net_device *dev,
6145 ipw_adapter_restart(priv); 6892 ipw_adapter_restart(priv);
6146 return 0; 6893 return 0;
6147} 6894}
6148#endif // CONFIG_IPW_PROMISC 6895#endif // CONFIG_IPW_MONITOR
6149 6896
6150/* Rebase the WE IOCTLs to zero for the handler array */ 6897/* Rebase the WE IOCTLs to zero for the handler array */
6151#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 6898#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
6152static iw_handler ipw_wx_handlers[] = { 6899static iw_handler ipw_wx_handlers[] = {
6153 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 6900 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
6154 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 6901 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
6155 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 6902 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
6156 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 6903 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
6157 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 6904 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode,
6158 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 6905 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range,
6159 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 6906 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap,
6160 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 6907 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap,
6161 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 6908 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan,
6162 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 6909 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan,
6163 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 6910 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid,
6164 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 6911 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid,
6165 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 6912 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick,
6166 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 6913 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick,
6167 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 6914 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate,
6168 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 6915 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate,
6169 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 6916 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts,
6170 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 6917 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts,
6171 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 6918 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag,
6172 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 6919 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag,
6173 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 6920 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow,
6174 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 6921 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow,
6175 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 6922 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry,
6176 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 6923 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry,
6177 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 6924 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode,
6178 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 6925 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
6179 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 6926 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
6180 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 6927 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
6181}; 6928};
6182 6929
6183#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV 6930#define IPW_PRIV_SET_POWER SIOCIWFIRSTPRIV
6184#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1 6931#define IPW_PRIV_GET_POWER SIOCIWFIRSTPRIV+1
6185#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2 6932#define IPW_PRIV_SET_MODE SIOCIWFIRSTPRIV+2
6186#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3 6933#define IPW_PRIV_GET_MODE SIOCIWFIRSTPRIV+3
6187#define IPW_PRIV_SET_PROMISC SIOCIWFIRSTPRIV+4 6934#define IPW_PRIV_SET_PREAMBLE SIOCIWFIRSTPRIV+4
6188#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+5 6935#define IPW_PRIV_GET_PREAMBLE SIOCIWFIRSTPRIV+5
6936#define IPW_PRIV_SET_MONITOR SIOCIWFIRSTPRIV+6
6937#define IPW_PRIV_RESET SIOCIWFIRSTPRIV+7
6189 6938
6190static struct iw_priv_args ipw_priv_args[] = { 6939static struct iw_priv_args ipw_priv_args[] = {
6191 { 6940 {
@@ -6204,14 +6953,22 @@ static struct iw_priv_args ipw_priv_args[] = {
6204 .cmd = IPW_PRIV_GET_MODE, 6953 .cmd = IPW_PRIV_GET_MODE,
6205 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, 6954 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
6206 .name = "get_mode"}, 6955 .name = "get_mode"},
6207#ifdef CONFIG_IPW_PROMISC
6208 { 6956 {
6209 IPW_PRIV_SET_PROMISC, 6957 .cmd = IPW_PRIV_SET_PREAMBLE,
6958 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6959 .name = "set_preamble"},
6960 {
6961 .cmd = IPW_PRIV_GET_PREAMBLE,
6962 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,
6963 .name = "get_preamble"},
6964#ifdef CONFIG_IPW_MONITOR
6965 {
6966 IPW_PRIV_SET_MONITOR,
6210 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"}, 6967 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},
6211 { 6968 {
6212 IPW_PRIV_RESET, 6969 IPW_PRIV_RESET,
6213 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"}, 6970 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},
6214#endif /* CONFIG_IPW_PROMISC */ 6971#endif /* CONFIG_IPW_MONITOR */
6215}; 6972};
6216 6973
6217static iw_handler ipw_priv_handler[] = { 6974static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +6976,21 @@ static iw_handler ipw_priv_handler[] = {
6219 ipw_wx_get_powermode, 6976 ipw_wx_get_powermode,
6220 ipw_wx_set_wireless_mode, 6977 ipw_wx_set_wireless_mode,
6221 ipw_wx_get_wireless_mode, 6978 ipw_wx_get_wireless_mode,
6222#ifdef CONFIG_IPW_PROMISC 6979 ipw_wx_set_preamble,
6223 ipw_wx_set_promisc, 6980 ipw_wx_get_preamble,
6981#ifdef CONFIG_IPW_MONITOR
6982 ipw_wx_set_monitor,
6224 ipw_wx_reset, 6983 ipw_wx_reset,
6225#endif 6984#endif
6226}; 6985};
6227 6986
6228static struct iw_handler_def ipw_wx_handler_def = { 6987static struct iw_handler_def ipw_wx_handler_def = {
6229 .standard = ipw_wx_handlers, 6988 .standard = ipw_wx_handlers,
6230 .num_standard = ARRAY_SIZE(ipw_wx_handlers), 6989 .num_standard = ARRAY_SIZE(ipw_wx_handlers),
6231 .num_private = ARRAY_SIZE(ipw_priv_handler), 6990 .num_private = ARRAY_SIZE(ipw_priv_handler),
6232 .num_private_args = ARRAY_SIZE(ipw_priv_args), 6991 .num_private_args = ARRAY_SIZE(ipw_priv_args),
6233 .private = ipw_priv_handler, 6992 .private = ipw_priv_handler,
6234 .private_args = ipw_priv_args, 6993 .private_args = ipw_priv_args,
6235}; 6994};
6236 6995
6237/* 6996/*
@@ -6246,7 +7005,7 @@ static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)
6246 7005
6247 wstats = &priv->wstats; 7006 wstats = &priv->wstats;
6248 7007
6249 /* if hw is disabled, then ipw2100_get_ordinal() can't be called. 7008 /* if hw is disabled, then ipw_get_ordinal() can't be called.
6250 * ipw2100_wx_wireless_stats seems to be called before fw is 7009 * ipw2100_wx_wireless_stats seems to be called before fw is
6251 * initialized. STATUS_ASSOCIATED will only be set if the hw is up 7010 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
6252 * and associated; if not associcated, the values are all meaningless 7011 * and associated; if not associcated, the values are all meaningless
@@ -6384,8 +7143,8 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
6384 else 7143 else
6385 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM; 7144 tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM;
6386 7145
6387 if (priv->config & CFG_PREAMBLE) 7146 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
6388 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL; 7147 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
6389 7148
6390 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len); 7149 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
6391 7150
@@ -6568,11 +7327,11 @@ static int ipw_ethtool_set_eeprom(struct net_device *dev,
6568} 7327}
6569 7328
6570static struct ethtool_ops ipw_ethtool_ops = { 7329static struct ethtool_ops ipw_ethtool_ops = {
6571 .get_link = ipw_ethtool_get_link, 7330 .get_link = ipw_ethtool_get_link,
6572 .get_drvinfo = ipw_ethtool_get_drvinfo, 7331 .get_drvinfo = ipw_ethtool_get_drvinfo,
6573 .get_eeprom_len = ipw_ethtool_get_eeprom_len, 7332 .get_eeprom_len = ipw_ethtool_get_eeprom_len,
6574 .get_eeprom = ipw_ethtool_get_eeprom, 7333 .get_eeprom = ipw_ethtool_get_eeprom,
6575 .set_eeprom = ipw_ethtool_set_eeprom, 7334 .set_eeprom = ipw_ethtool_set_eeprom,
6576}; 7335};
6577 7336
6578static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) 7337static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6918,6 +7677,25 @@ static void ipw_down(struct ipw_priv *priv)
6918 ipw_stop_nic(priv); 7677 ipw_stop_nic(priv);
6919} 7678}
6920 7679
7680static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
7681{
7682#ifdef CONFIG_IEEE80211_WPA
7683 struct iwreq *wrq = (struct iwreq *)rq;
7684 int ret = -1;
7685 switch (cmd) {
7686 case IPW_IOCTL_WPA_SUPPLICANT:
7687 ret = ipw_wpa_supplicant(dev, &wrq->u.data);
7688 return ret;
7689
7690 default:
7691 return -EOPNOTSUPP;
7692 }
7693
7694#endif /* CONFIG_IEEE80211_WPA */
7695
7696 return -EOPNOTSUPP;
7697}
7698
6921/* Called by register_netdev() */ 7699/* Called by register_netdev() */
6922static int ipw_net_init(struct net_device *dev) 7700static int ipw_net_init(struct net_device *dev)
6923{ 7701{
@@ -7065,9 +7843,6 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7065 } 7843 }
7066 7844
7067 /* Initialize module parameter values here */ 7845 /* Initialize module parameter values here */
7068 if (ifname)
7069 strncpy(net_dev->name, ifname, IFNAMSIZ);
7070
7071 if (associate) 7846 if (associate)
7072 priv->config |= CFG_ASSOCIATE; 7847 priv->config |= CFG_ASSOCIATE;
7073 else 7848 else
@@ -7095,7 +7870,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7095 case 1: 7870 case 1:
7096 priv->ieee->iw_mode = IW_MODE_ADHOC; 7871 priv->ieee->iw_mode = IW_MODE_ADHOC;
7097 break; 7872 break;
7098#ifdef CONFIG_IPW_PROMISC 7873#ifdef CONFIG_IPW_MONITOR
7099 case 2: 7874 case 2:
7100 priv->ieee->iw_mode = IW_MODE_MONITOR; 7875 priv->ieee->iw_mode = IW_MODE_MONITOR;
7101 break; 7876 break;
@@ -7164,6 +7939,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
7164 net_dev->open = ipw_net_open; 7939 net_dev->open = ipw_net_open;
7165 net_dev->stop = ipw_net_stop; 7940 net_dev->stop = ipw_net_stop;
7166 net_dev->init = ipw_net_init; 7941 net_dev->init = ipw_net_init;
7942 net_dev->do_ioctl = ipw_ioctl;
7167 net_dev->get_stats = ipw_net_get_stats; 7943 net_dev->get_stats = ipw_net_get_stats;
7168 net_dev->set_multicast_list = ipw_net_set_multicast_list; 7944 net_dev->set_multicast_list = ipw_net_set_multicast_list;
7169 net_dev->set_mac_address = ipw_net_set_mac_address; 7945 net_dev->set_mac_address = ipw_net_set_mac_address;
@@ -7287,13 +8063,10 @@ static int ipw_pci_resume(struct pci_dev *pdev)
7287 8063
7288 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name); 8064 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
7289 8065
7290 pci_set_power_state(pdev, 0); 8066 pci_set_power_state(pdev, PCI_D0);
7291 pci_enable_device(pdev); 8067 pci_enable_device(pdev);
7292#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
7293 pci_restore_state(pdev, priv->pm_state);
7294#else
7295 pci_restore_state(pdev); 8068 pci_restore_state(pdev);
7296#endif 8069
7297 /* 8070 /*
7298 * Suspend/Resume resets the PCI configuration space, so we have to 8071 * Suspend/Resume resets the PCI configuration space, so we have to
7299 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries 8072 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7371,10 +8144,7 @@ MODULE_PARM_DESC(debug, "debug output mask");
7371module_param(channel, int, 0444); 8144module_param(channel, int, 0444);
7372MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 8145MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
7373 8146
7374module_param(ifname, charp, 0444); 8147#ifdef CONFIG_IPW_MONITOR
7375MODULE_PARM_DESC(ifname, "network device name (default eth%d)");
7376
7377#ifdef CONFIG_IPW_PROMISC
7378module_param(mode, int, 0444); 8148module_param(mode, int, 0444);
7379MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 8149MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
7380#else 8150#else