diff options
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 215 |
1 files changed, 124 insertions, 91 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index a72f3e1e991b..f29ec0ebed2f 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -70,7 +70,7 @@ | |||
70 | #define VQ | 70 | #define VQ |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #define IPW2200_VERSION "1.1.2" VK VD VM VP VR VQ | 73 | #define IPW2200_VERSION "1.1.4" VK VD VM VP VR VQ |
74 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" | 74 | #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver" |
75 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" | 75 | #define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" |
76 | #define DRV_VERSION IPW2200_VERSION | 76 | #define DRV_VERSION IPW2200_VERSION |
@@ -83,9 +83,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT); | |||
83 | MODULE_LICENSE("GPL"); | 83 | MODULE_LICENSE("GPL"); |
84 | 84 | ||
85 | static int cmdlog = 0; | 85 | static int cmdlog = 0; |
86 | #ifdef CONFIG_IPW2200_DEBUG | ||
87 | static int debug = 0; | 86 | static int debug = 0; |
88 | #endif | ||
89 | static int channel = 0; | 87 | static int channel = 0; |
90 | static int mode = 0; | 88 | static int mode = 0; |
91 | 89 | ||
@@ -567,7 +565,6 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) | |||
567 | spin_unlock_irqrestore(&priv->irq_lock, flags); | 565 | spin_unlock_irqrestore(&priv->irq_lock, flags); |
568 | } | 566 | } |
569 | 567 | ||
570 | #ifdef CONFIG_IPW2200_DEBUG | ||
571 | static char *ipw_error_desc(u32 val) | 568 | static char *ipw_error_desc(u32 val) |
572 | { | 569 | { |
573 | switch (val) { | 570 | switch (val) { |
@@ -634,7 +631,6 @@ static void ipw_dump_error_log(struct ipw_priv *priv, | |||
634 | error->log[i].time, | 631 | error->log[i].time, |
635 | error->log[i].data, error->log[i].event); | 632 | error->log[i].data, error->log[i].event); |
636 | } | 633 | } |
637 | #endif | ||
638 | 634 | ||
639 | static inline int ipw_is_init(struct ipw_priv *priv) | 635 | static inline int ipw_is_init(struct ipw_priv *priv) |
640 | { | 636 | { |
@@ -1435,9 +1431,7 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, | |||
1435 | const char *buf, size_t count) | 1431 | const char *buf, size_t count) |
1436 | { | 1432 | { |
1437 | struct ipw_priv *priv = dev_get_drvdata(d); | 1433 | struct ipw_priv *priv = dev_get_drvdata(d); |
1438 | #ifdef CONFIG_IPW2200_DEBUG | ||
1439 | struct net_device *dev = priv->net_dev; | 1434 | struct net_device *dev = priv->net_dev; |
1440 | #endif | ||
1441 | char buffer[] = "00000000"; | 1435 | char buffer[] = "00000000"; |
1442 | unsigned long len = | 1436 | unsigned long len = |
1443 | (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; | 1437 | (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1; |
@@ -1958,14 +1952,12 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
1958 | IPW_WARNING("Firmware error detected. Restarting.\n"); | 1952 | IPW_WARNING("Firmware error detected. Restarting.\n"); |
1959 | if (priv->error) { | 1953 | if (priv->error) { |
1960 | IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); | 1954 | IPW_DEBUG_FW("Sysfs 'error' log already exists.\n"); |
1961 | #ifdef CONFIG_IPW2200_DEBUG | ||
1962 | if (ipw_debug_level & IPW_DL_FW_ERRORS) { | 1955 | if (ipw_debug_level & IPW_DL_FW_ERRORS) { |
1963 | struct ipw_fw_error *error = | 1956 | struct ipw_fw_error *error = |
1964 | ipw_alloc_error_log(priv); | 1957 | ipw_alloc_error_log(priv); |
1965 | ipw_dump_error_log(priv, error); | 1958 | ipw_dump_error_log(priv, error); |
1966 | kfree(error); | 1959 | kfree(error); |
1967 | } | 1960 | } |
1968 | #endif | ||
1969 | } else { | 1961 | } else { |
1970 | priv->error = ipw_alloc_error_log(priv); | 1962 | priv->error = ipw_alloc_error_log(priv); |
1971 | if (priv->error) | 1963 | if (priv->error) |
@@ -1973,10 +1965,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
1973 | else | 1965 | else |
1974 | IPW_DEBUG_FW("Error allocating sysfs 'error' " | 1966 | IPW_DEBUG_FW("Error allocating sysfs 'error' " |
1975 | "log.\n"); | 1967 | "log.\n"); |
1976 | #ifdef CONFIG_IPW2200_DEBUG | ||
1977 | if (ipw_debug_level & IPW_DL_FW_ERRORS) | 1968 | if (ipw_debug_level & IPW_DL_FW_ERRORS) |
1978 | ipw_dump_error_log(priv, priv->error); | 1969 | ipw_dump_error_log(priv, priv->error); |
1979 | #endif | ||
1980 | } | 1970 | } |
1981 | 1971 | ||
1982 | /* XXX: If hardware encryption is for WPA/WPA2, | 1972 | /* XXX: If hardware encryption is for WPA/WPA2, |
@@ -2287,7 +2277,7 @@ static int ipw_send_scan_abort(struct ipw_priv *priv) | |||
2287 | static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) | 2277 | static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens) |
2288 | { | 2278 | { |
2289 | struct ipw_sensitivity_calib calib = { | 2279 | struct ipw_sensitivity_calib calib = { |
2290 | .beacon_rssi_raw = sens, | 2280 | .beacon_rssi_raw = cpu_to_le16(sens), |
2291 | }; | 2281 | }; |
2292 | 2282 | ||
2293 | return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), | 2283 | return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib), |
@@ -2353,6 +2343,7 @@ static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off) | |||
2353 | return -1; | 2343 | return -1; |
2354 | } | 2344 | } |
2355 | 2345 | ||
2346 | phy_off = cpu_to_le32(phy_off); | ||
2356 | return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), | 2347 | return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(phy_off), |
2357 | &phy_off); | 2348 | &phy_off); |
2358 | } | 2349 | } |
@@ -2414,7 +2405,7 @@ static int ipw_set_tx_power(struct ipw_priv *priv) | |||
2414 | static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) | 2405 | static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) |
2415 | { | 2406 | { |
2416 | struct ipw_rts_threshold rts_threshold = { | 2407 | struct ipw_rts_threshold rts_threshold = { |
2417 | .rts_threshold = rts, | 2408 | .rts_threshold = cpu_to_le16(rts), |
2418 | }; | 2409 | }; |
2419 | 2410 | ||
2420 | if (!priv) { | 2411 | if (!priv) { |
@@ -2429,7 +2420,7 @@ static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts) | |||
2429 | static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) | 2420 | static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag) |
2430 | { | 2421 | { |
2431 | struct ipw_frag_threshold frag_threshold = { | 2422 | struct ipw_frag_threshold frag_threshold = { |
2432 | .frag_threshold = frag, | 2423 | .frag_threshold = cpu_to_le16(frag), |
2433 | }; | 2424 | }; |
2434 | 2425 | ||
2435 | if (!priv) { | 2426 | if (!priv) { |
@@ -2464,6 +2455,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode) | |||
2464 | break; | 2455 | break; |
2465 | } | 2456 | } |
2466 | 2457 | ||
2458 | param = cpu_to_le32(mode); | ||
2467 | return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), | 2459 | return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param), |
2468 | ¶m); | 2460 | ¶m); |
2469 | } | 2461 | } |
@@ -3915,7 +3907,6 @@ static const struct ipw_status_code ipw_status_codes[] = { | |||
3915 | {0x2E, "Cipher suite is rejected per security policy"}, | 3907 | {0x2E, "Cipher suite is rejected per security policy"}, |
3916 | }; | 3908 | }; |
3917 | 3909 | ||
3918 | #ifdef CONFIG_IPW2200_DEBUG | ||
3919 | static const char *ipw_get_status_code(u16 status) | 3910 | static const char *ipw_get_status_code(u16 status) |
3920 | { | 3911 | { |
3921 | int i; | 3912 | int i; |
@@ -3924,7 +3915,6 @@ static const char *ipw_get_status_code(u16 status) | |||
3924 | return ipw_status_codes[i].reason; | 3915 | return ipw_status_codes[i].reason; |
3925 | return "Unknown status value."; | 3916 | return "Unknown status value."; |
3926 | } | 3917 | } |
3927 | #endif | ||
3928 | 3918 | ||
3929 | static void inline average_init(struct average *avg) | 3919 | static void inline average_init(struct average *avg) |
3930 | { | 3920 | { |
@@ -4394,7 +4384,6 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4394 | if (priv-> | 4384 | if (priv-> |
4395 | status & (STATUS_ASSOCIATED | | 4385 | status & (STATUS_ASSOCIATED | |
4396 | STATUS_AUTH)) { | 4386 | STATUS_AUTH)) { |
4397 | #ifdef CONFIG_IPW2200_DEBUG | ||
4398 | struct notif_authenticate *auth | 4387 | struct notif_authenticate *auth |
4399 | = ¬if->u.auth; | 4388 | = ¬if->u.auth; |
4400 | IPW_DEBUG(IPW_DL_NOTIF | | 4389 | IPW_DEBUG(IPW_DL_NOTIF | |
@@ -4412,7 +4401,6 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4412 | ipw_get_status_code | 4401 | ipw_get_status_code |
4413 | (ntohs | 4402 | (ntohs |
4414 | (auth->status))); | 4403 | (auth->status))); |
4415 | #endif | ||
4416 | 4404 | ||
4417 | priv->status &= | 4405 | priv->status &= |
4418 | ~(STATUS_ASSOCIATING | | 4406 | ~(STATUS_ASSOCIATING | |
@@ -5055,7 +5043,6 @@ static void ipw_rx_queue_replenish(void *data) | |||
5055 | } | 5043 | } |
5056 | list_del(element); | 5044 | list_del(element); |
5057 | 5045 | ||
5058 | rxb->rxb = (struct ipw_rx_buffer *)rxb->skb->data; | ||
5059 | rxb->dma_addr = | 5046 | rxb->dma_addr = |
5060 | pci_map_single(priv->pci_dev, rxb->skb->data, | 5047 | pci_map_single(priv->pci_dev, rxb->skb->data, |
5061 | IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); | 5048 | IPW_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); |
@@ -5834,8 +5821,8 @@ static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index) | |||
5834 | key.station_index = 0; /* always 0 for BSS */ | 5821 | key.station_index = 0; /* always 0 for BSS */ |
5835 | key.flags = 0; | 5822 | key.flags = 0; |
5836 | /* 0 for new key; previous value of counter (after fatal error) */ | 5823 | /* 0 for new key; previous value of counter (after fatal error) */ |
5837 | key.tx_counter[0] = 0; | 5824 | key.tx_counter[0] = cpu_to_le32(0); |
5838 | key.tx_counter[1] = 0; | 5825 | key.tx_counter[1] = cpu_to_le32(0); |
5839 | 5826 | ||
5840 | ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); | 5827 | ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key); |
5841 | } | 5828 | } |
@@ -5969,7 +5956,6 @@ static void ipw_bg_adhoc_check(void *data) | |||
5969 | mutex_unlock(&priv->mutex); | 5956 | mutex_unlock(&priv->mutex); |
5970 | } | 5957 | } |
5971 | 5958 | ||
5972 | #ifdef CONFIG_IPW2200_DEBUG | ||
5973 | static void ipw_debug_config(struct ipw_priv *priv) | 5959 | static void ipw_debug_config(struct ipw_priv *priv) |
5974 | { | 5960 | { |
5975 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " | 5961 | IPW_DEBUG_INFO("Scan completed, no valid APs matched " |
@@ -5994,9 +5980,6 @@ static void ipw_debug_config(struct ipw_priv *priv) | |||
5994 | IPW_DEBUG_INFO("PRIVACY off\n"); | 5980 | IPW_DEBUG_INFO("PRIVACY off\n"); |
5995 | IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask); | 5981 | IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask); |
5996 | } | 5982 | } |
5997 | #else | ||
5998 | #define ipw_debug_config(x) do {} while (0) | ||
5999 | #endif | ||
6000 | 5983 | ||
6001 | static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode) | 5984 | static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode) |
6002 | { | 5985 | { |
@@ -6184,7 +6167,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
6184 | } | 6167 | } |
6185 | } | 6168 | } |
6186 | 6169 | ||
6187 | static int ipw_request_scan(struct ipw_priv *priv) | 6170 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type) |
6188 | { | 6171 | { |
6189 | struct ipw_scan_request_ext scan; | 6172 | struct ipw_scan_request_ext scan; |
6190 | int err = 0, scan_type; | 6173 | int err = 0, scan_type; |
@@ -6215,19 +6198,29 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
6215 | } | 6198 | } |
6216 | 6199 | ||
6217 | memset(&scan, 0, sizeof(scan)); | 6200 | memset(&scan, 0, sizeof(scan)); |
6201 | scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); | ||
6218 | 6202 | ||
6219 | if (priv->config & CFG_SPEED_SCAN) | 6203 | if (type == IW_SCAN_TYPE_PASSIVE) { |
6204 | IPW_DEBUG_WX("use passive scanning\n"); | ||
6205 | scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN; | ||
6206 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = | ||
6207 | cpu_to_le16(120); | ||
6208 | ipw_add_scan_channels(priv, &scan, scan_type); | ||
6209 | goto send_request; | ||
6210 | } | ||
6211 | |||
6212 | /* Use active scan by default. */ | ||
6213 | if (priv->config & CFG_SPEED_SCAN) | ||
6220 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | 6214 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = |
6221 | cpu_to_le16(30); | 6215 | cpu_to_le16(30); |
6222 | else | 6216 | else |
6223 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | 6217 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = |
6224 | cpu_to_le16(20); | 6218 | cpu_to_le16(20); |
6225 | 6219 | ||
6226 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = | 6220 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = |
6227 | cpu_to_le16(20); | 6221 | cpu_to_le16(20); |
6228 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | ||
6229 | 6222 | ||
6230 | scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); | 6223 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); |
6231 | 6224 | ||
6232 | #ifdef CONFIG_IPW2200_MONITOR | 6225 | #ifdef CONFIG_IPW2200_MONITOR |
6233 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 6226 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
@@ -6264,7 +6257,7 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
6264 | * | 6257 | * |
6265 | * TODO: Move SPEED SCAN support to all modes and bands */ | 6258 | * TODO: Move SPEED SCAN support to all modes and bands */ |
6266 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = | 6259 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = |
6267 | cpu_to_le16(2000); | 6260 | cpu_to_le16(2000); |
6268 | } else { | 6261 | } else { |
6269 | #endif /* CONFIG_IPW2200_MONITOR */ | 6262 | #endif /* CONFIG_IPW2200_MONITOR */ |
6270 | /* If we are roaming, then make this a directed scan for the | 6263 | /* If we are roaming, then make this a directed scan for the |
@@ -6290,6 +6283,7 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
6290 | } | 6283 | } |
6291 | #endif | 6284 | #endif |
6292 | 6285 | ||
6286 | send_request: | ||
6293 | err = ipw_send_scan_request_ext(priv, &scan); | 6287 | err = ipw_send_scan_request_ext(priv, &scan); |
6294 | if (err) { | 6288 | if (err) { |
6295 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); | 6289 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); |
@@ -6300,11 +6294,19 @@ static int ipw_request_scan(struct ipw_priv *priv) | |||
6300 | priv->status &= ~STATUS_SCAN_PENDING; | 6294 | priv->status &= ~STATUS_SCAN_PENDING; |
6301 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 6295 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
6302 | IPW_SCAN_CHECK_WATCHDOG); | 6296 | IPW_SCAN_CHECK_WATCHDOG); |
6303 | done: | 6297 | done: |
6304 | mutex_unlock(&priv->mutex); | 6298 | mutex_unlock(&priv->mutex); |
6305 | return err; | 6299 | return err; |
6306 | } | 6300 | } |
6307 | 6301 | ||
6302 | static int ipw_request_passive_scan(struct ipw_priv *priv) { | ||
6303 | return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | ||
6304 | } | ||
6305 | |||
6306 | static int ipw_request_scan(struct ipw_priv *priv) { | ||
6307 | return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | ||
6308 | } | ||
6309 | |||
6308 | static void ipw_bg_abort_scan(void *data) | 6310 | static void ipw_bg_abort_scan(void *data) |
6309 | { | 6311 | { |
6310 | struct ipw_priv *priv = data; | 6312 | struct ipw_priv *priv = data; |
@@ -6790,7 +6792,7 @@ static int ipw_qos_activate(struct ipw_priv *priv, | |||
6790 | burst_duration = ipw_qos_get_burst_duration(priv); | 6792 | burst_duration = ipw_qos_get_burst_duration(priv); |
6791 | for (i = 0; i < QOS_QUEUE_NUM; i++) | 6793 | for (i = 0; i < QOS_QUEUE_NUM; i++) |
6792 | qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] = | 6794 | qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] = |
6793 | (u16) burst_duration; | 6795 | (u16)burst_duration; |
6794 | } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) { | 6796 | } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) { |
6795 | if (type == IEEE_B) { | 6797 | if (type == IEEE_B) { |
6796 | IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n", | 6798 | IPW_DEBUG_QOS("QoS activate IBSS nework mode %d\n", |
@@ -6822,11 +6824,20 @@ static int ipw_qos_activate(struct ipw_priv *priv, | |||
6822 | burst_duration = ipw_qos_get_burst_duration(priv); | 6824 | burst_duration = ipw_qos_get_burst_duration(priv); |
6823 | for (i = 0; i < QOS_QUEUE_NUM; i++) | 6825 | for (i = 0; i < QOS_QUEUE_NUM; i++) |
6824 | qos_parameters[QOS_PARAM_SET_ACTIVE]. | 6826 | qos_parameters[QOS_PARAM_SET_ACTIVE]. |
6825 | tx_op_limit[i] = (u16) burst_duration; | 6827 | tx_op_limit[i] = (u16)burst_duration; |
6826 | } | 6828 | } |
6827 | } | 6829 | } |
6828 | 6830 | ||
6829 | IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); | 6831 | IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n"); |
6832 | for (i = 0; i < 3; i++) { | ||
6833 | int j; | ||
6834 | for (j = 0; j < QOS_QUEUE_NUM; j++) { | ||
6835 | qos_parameters[i].cw_min[j] = cpu_to_le16(qos_parameters[i].cw_min[j]); | ||
6836 | qos_parameters[i].cw_max[j] = cpu_to_le16(qos_parameters[i].cw_max[j]); | ||
6837 | qos_parameters[i].tx_op_limit[j] = cpu_to_le16(qos_parameters[i].tx_op_limit[j]); | ||
6838 | } | ||
6839 | } | ||
6840 | |||
6830 | err = ipw_send_qos_params_command(priv, | 6841 | err = ipw_send_qos_params_command(priv, |
6831 | (struct ieee80211_qos_parameters *) | 6842 | (struct ieee80211_qos_parameters *) |
6832 | &(qos_parameters[0])); | 6843 | &(qos_parameters[0])); |
@@ -7065,7 +7076,7 @@ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, | |||
7065 | 7076 | ||
7066 | if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) { | 7077 | if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) { |
7067 | tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; | 7078 | tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; |
7068 | tfd->tfd.tfd_26.mchdr.qos_ctrl |= CTRL_QOS_NO_ACK; | 7079 | tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK); |
7069 | } | 7080 | } |
7070 | return 0; | 7081 | return 0; |
7071 | } | 7082 | } |
@@ -7646,7 +7657,6 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, | |||
7646 | /* Big bitfield of all the fields we provide in radiotap */ | 7657 | /* Big bitfield of all the fields we provide in radiotap */ |
7647 | ipw_rt->rt_hdr.it_present = | 7658 | ipw_rt->rt_hdr.it_present = |
7648 | ((1 << IEEE80211_RADIOTAP_FLAGS) | | 7659 | ((1 << IEEE80211_RADIOTAP_FLAGS) | |
7649 | (1 << IEEE80211_RADIOTAP_TSFT) | | ||
7650 | (1 << IEEE80211_RADIOTAP_RATE) | | 7660 | (1 << IEEE80211_RADIOTAP_RATE) | |
7651 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 7661 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
7652 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | 7662 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | |
@@ -7655,6 +7665,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, | |||
7655 | 7665 | ||
7656 | /* Zero the flags, we'll add to them as we go */ | 7666 | /* Zero the flags, we'll add to them as we go */ |
7657 | ipw_rt->rt_flags = 0; | 7667 | ipw_rt->rt_flags = 0; |
7668 | ipw_rt->rt_tsf = 0ULL; | ||
7658 | 7669 | ||
7659 | /* Convert signal to DBM */ | 7670 | /* Convert signal to DBM */ |
7660 | ipw_rt->rt_dbmsignal = antsignal; | 7671 | ipw_rt->rt_dbmsignal = antsignal; |
@@ -7773,7 +7784,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
7773 | s8 noise = frame->noise; | 7784 | s8 noise = frame->noise; |
7774 | u8 rate = frame->rate; | 7785 | u8 rate = frame->rate; |
7775 | short len = le16_to_cpu(pkt->u.frame.length); | 7786 | short len = le16_to_cpu(pkt->u.frame.length); |
7776 | u64 tsf = 0; | ||
7777 | struct sk_buff *skb; | 7787 | struct sk_buff *skb; |
7778 | int hdr_only = 0; | 7788 | int hdr_only = 0; |
7779 | u16 filter = priv->prom_priv->filter; | 7789 | u16 filter = priv->prom_priv->filter; |
@@ -7808,17 +7818,17 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
7808 | } | 7818 | } |
7809 | 7819 | ||
7810 | hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE; | 7820 | hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE; |
7811 | if (ieee80211_is_management(hdr->frame_ctl)) { | 7821 | if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) { |
7812 | if (filter & IPW_PROM_NO_MGMT) | 7822 | if (filter & IPW_PROM_NO_MGMT) |
7813 | return; | 7823 | return; |
7814 | if (filter & IPW_PROM_MGMT_HEADER_ONLY) | 7824 | if (filter & IPW_PROM_MGMT_HEADER_ONLY) |
7815 | hdr_only = 1; | 7825 | hdr_only = 1; |
7816 | } else if (ieee80211_is_control(hdr->frame_ctl)) { | 7826 | } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) { |
7817 | if (filter & IPW_PROM_NO_CTL) | 7827 | if (filter & IPW_PROM_NO_CTL) |
7818 | return; | 7828 | return; |
7819 | if (filter & IPW_PROM_CTL_HEADER_ONLY) | 7829 | if (filter & IPW_PROM_CTL_HEADER_ONLY) |
7820 | hdr_only = 1; | 7830 | hdr_only = 1; |
7821 | } else if (ieee80211_is_data(hdr->frame_ctl)) { | 7831 | } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) { |
7822 | if (filter & IPW_PROM_NO_DATA) | 7832 | if (filter & IPW_PROM_NO_DATA) |
7823 | return; | 7833 | return; |
7824 | if (filter & IPW_PROM_DATA_HEADER_ONLY) | 7834 | if (filter & IPW_PROM_DATA_HEADER_ONLY) |
@@ -7836,7 +7846,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
7836 | ipw_rt = (void *)skb->data; | 7846 | ipw_rt = (void *)skb->data; |
7837 | 7847 | ||
7838 | if (hdr_only) | 7848 | if (hdr_only) |
7839 | len = ieee80211_get_hdrlen(hdr->frame_ctl); | 7849 | len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); |
7840 | 7850 | ||
7841 | memcpy(ipw_rt->payload, hdr, len); | 7851 | memcpy(ipw_rt->payload, hdr, len); |
7842 | 7852 | ||
@@ -7859,7 +7869,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
7859 | /* Big bitfield of all the fields we provide in radiotap */ | 7869 | /* Big bitfield of all the fields we provide in radiotap */ |
7860 | ipw_rt->rt_hdr.it_present = | 7870 | ipw_rt->rt_hdr.it_present = |
7861 | ((1 << IEEE80211_RADIOTAP_FLAGS) | | 7871 | ((1 << IEEE80211_RADIOTAP_FLAGS) | |
7862 | (1 << IEEE80211_RADIOTAP_TSFT) | | ||
7863 | (1 << IEEE80211_RADIOTAP_RATE) | | 7872 | (1 << IEEE80211_RADIOTAP_RATE) | |
7864 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | 7873 | (1 << IEEE80211_RADIOTAP_CHANNEL) | |
7865 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | 7874 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | |
@@ -7868,8 +7877,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, | |||
7868 | 7877 | ||
7869 | /* Zero the flags, we'll add to them as we go */ | 7878 | /* Zero the flags, we'll add to them as we go */ |
7870 | ipw_rt->rt_flags = 0; | 7879 | ipw_rt->rt_flags = 0; |
7871 | 7880 | ipw_rt->rt_tsf = 0ULL; | |
7872 | ipw_rt->rt_tsf = tsf; | ||
7873 | 7881 | ||
7874 | /* Convert to DBM */ | 7882 | /* Convert to DBM */ |
7875 | ipw_rt->rt_dbmsignal = signal; | 7883 | ipw_rt->rt_dbmsignal = signal; |
@@ -8142,8 +8150,7 @@ static void ipw_rx(struct ipw_priv *priv) | |||
8142 | switch (pkt->header.message_type) { | 8150 | switch (pkt->header.message_type) { |
8143 | case RX_FRAME_TYPE: /* 802.11 frame */ { | 8151 | case RX_FRAME_TYPE: /* 802.11 frame */ { |
8144 | struct ieee80211_rx_stats stats = { | 8152 | struct ieee80211_rx_stats stats = { |
8145 | .rssi = | 8153 | .rssi = pkt->u.frame.rssi_dbm - |
8146 | le16_to_cpu(pkt->u.frame.rssi_dbm) - | ||
8147 | IPW_RSSI_TO_DBM, | 8154 | IPW_RSSI_TO_DBM, |
8148 | .signal = | 8155 | .signal = |
8149 | le16_to_cpu(pkt->u.frame.rssi_dbm) - | 8156 | le16_to_cpu(pkt->u.frame.rssi_dbm) - |
@@ -8578,9 +8585,26 @@ static int ipw_wx_get_freq(struct net_device *dev, | |||
8578 | * configured CHANNEL then return that; otherwise return ANY */ | 8585 | * configured CHANNEL then return that; otherwise return ANY */ |
8579 | mutex_lock(&priv->mutex); | 8586 | mutex_lock(&priv->mutex); |
8580 | if (priv->config & CFG_STATIC_CHANNEL || | 8587 | if (priv->config & CFG_STATIC_CHANNEL || |
8581 | priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) | 8588 | priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) { |
8582 | wrqu->freq.m = priv->channel; | 8589 | int i; |
8583 | else | 8590 | |
8591 | i = ieee80211_channel_to_index(priv->ieee, priv->channel); | ||
8592 | BUG_ON(i == -1); | ||
8593 | wrqu->freq.e = 1; | ||
8594 | |||
8595 | switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) { | ||
8596 | case IEEE80211_52GHZ_BAND: | ||
8597 | wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000; | ||
8598 | break; | ||
8599 | |||
8600 | case IEEE80211_24GHZ_BAND: | ||
8601 | wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000; | ||
8602 | break; | ||
8603 | |||
8604 | default: | ||
8605 | BUG(); | ||
8606 | } | ||
8607 | } else | ||
8584 | wrqu->freq.m = 0; | 8608 | wrqu->freq.m = 0; |
8585 | 8609 | ||
8586 | mutex_unlock(&priv->mutex); | 8610 | mutex_unlock(&priv->mutex); |
@@ -8836,42 +8860,38 @@ static int ipw_wx_set_essid(struct net_device *dev, | |||
8836 | union iwreq_data *wrqu, char *extra) | 8860 | union iwreq_data *wrqu, char *extra) |
8837 | { | 8861 | { |
8838 | struct ipw_priv *priv = ieee80211_priv(dev); | 8862 | struct ipw_priv *priv = ieee80211_priv(dev); |
8839 | char *essid = ""; /* ANY */ | 8863 | int length; |
8840 | int length = 0; | 8864 | |
8841 | mutex_lock(&priv->mutex); | 8865 | mutex_lock(&priv->mutex); |
8842 | if (wrqu->essid.flags && wrqu->essid.length) { | ||
8843 | length = wrqu->essid.length - 1; | ||
8844 | essid = extra; | ||
8845 | } | ||
8846 | if (length == 0) { | ||
8847 | IPW_DEBUG_WX("Setting ESSID to ANY\n"); | ||
8848 | if ((priv->config & CFG_STATIC_ESSID) && | ||
8849 | !(priv->status & (STATUS_ASSOCIATED | | ||
8850 | STATUS_ASSOCIATING))) { | ||
8851 | IPW_DEBUG_ASSOC("Attempting to associate with new " | ||
8852 | "parameters.\n"); | ||
8853 | priv->config &= ~CFG_STATIC_ESSID; | ||
8854 | ipw_associate(priv); | ||
8855 | } | ||
8856 | mutex_unlock(&priv->mutex); | ||
8857 | return 0; | ||
8858 | } | ||
8859 | 8866 | ||
8860 | length = min(length, IW_ESSID_MAX_SIZE); | 8867 | if (!wrqu->essid.flags) |
8868 | { | ||
8869 | IPW_DEBUG_WX("Setting ESSID to ANY\n"); | ||
8870 | ipw_disassociate(priv); | ||
8871 | priv->config &= ~CFG_STATIC_ESSID; | ||
8872 | ipw_associate(priv); | ||
8873 | mutex_unlock(&priv->mutex); | ||
8874 | return 0; | ||
8875 | } | ||
8876 | |||
8877 | length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE); | ||
8878 | if (!extra[length - 1]) | ||
8879 | length--; | ||
8861 | 8880 | ||
8862 | priv->config |= CFG_STATIC_ESSID; | 8881 | priv->config |= CFG_STATIC_ESSID; |
8863 | 8882 | ||
8864 | if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) { | 8883 | if (priv->essid_len == length && !memcmp(priv->essid, extra, length) |
8884 | && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) { | ||
8865 | IPW_DEBUG_WX("ESSID set to current ESSID.\n"); | 8885 | IPW_DEBUG_WX("ESSID set to current ESSID.\n"); |
8866 | mutex_unlock(&priv->mutex); | 8886 | mutex_unlock(&priv->mutex); |
8867 | return 0; | 8887 | return 0; |
8868 | } | 8888 | } |
8869 | 8889 | ||
8870 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length), | 8890 | IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(extra, length), |
8871 | length); | 8891 | length); |
8872 | 8892 | ||
8873 | priv->essid_len = length; | 8893 | priv->essid_len = length; |
8874 | memcpy(priv->essid, essid, priv->essid_len); | 8894 | memcpy(priv->essid, extra, priv->essid_len); |
8875 | 8895 | ||
8876 | /* Network configuration changed -- force [re]association */ | 8896 | /* Network configuration changed -- force [re]association */ |
8877 | IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n"); | 8897 | IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n"); |
@@ -9252,7 +9272,7 @@ static int ipw_wx_set_retry(struct net_device *dev, | |||
9252 | if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) | 9272 | if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) |
9253 | return 0; | 9273 | return 0; |
9254 | 9274 | ||
9255 | if (wrqu->retry.value < 0 || wrqu->retry.value > 255) | 9275 | if (wrqu->retry.value < 0 || wrqu->retry.value >= 255) |
9256 | return -EINVAL; | 9276 | return -EINVAL; |
9257 | 9277 | ||
9258 | mutex_lock(&priv->mutex); | 9278 | mutex_lock(&priv->mutex); |
@@ -9375,15 +9395,19 @@ static int ipw_wx_set_scan(struct net_device *dev, | |||
9375 | union iwreq_data *wrqu, char *extra) | 9395 | union iwreq_data *wrqu, char *extra) |
9376 | { | 9396 | { |
9377 | struct ipw_priv *priv = ieee80211_priv(dev); | 9397 | struct ipw_priv *priv = ieee80211_priv(dev); |
9378 | struct iw_scan_req *req = NULL; | 9398 | struct iw_scan_req *req = (struct iw_scan_req *)extra; |
9379 | if (wrqu->data.length | 9399 | |
9380 | && wrqu->data.length == sizeof(struct iw_scan_req)) { | 9400 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { |
9381 | req = (struct iw_scan_req *)extra; | ||
9382 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 9401 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
9383 | ipw_request_direct_scan(priv, req->essid, | 9402 | ipw_request_direct_scan(priv, req->essid, |
9384 | req->essid_len); | 9403 | req->essid_len); |
9385 | return 0; | 9404 | return 0; |
9386 | } | 9405 | } |
9406 | if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { | ||
9407 | queue_work(priv->workqueue, | ||
9408 | &priv->request_passive_scan); | ||
9409 | return 0; | ||
9410 | } | ||
9387 | } | 9411 | } |
9388 | 9412 | ||
9389 | IPW_DEBUG_WX("Start scan\n"); | 9413 | IPW_DEBUG_WX("Start scan\n"); |
@@ -10092,7 +10116,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
10092 | switch (priv->ieee->sec.level) { | 10116 | switch (priv->ieee->sec.level) { |
10093 | case SEC_LEVEL_3: | 10117 | case SEC_LEVEL_3: |
10094 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= | 10118 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= |
10095 | IEEE80211_FCTL_PROTECTED; | 10119 | cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
10096 | /* XXX: ACK flag must be set for CCMP even if it | 10120 | /* XXX: ACK flag must be set for CCMP even if it |
10097 | * is a multicast/broadcast packet, because CCMP | 10121 | * is a multicast/broadcast packet, because CCMP |
10098 | * group communication encrypted by GTK is | 10122 | * group communication encrypted by GTK is |
@@ -10107,14 +10131,14 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
10107 | break; | 10131 | break; |
10108 | case SEC_LEVEL_2: | 10132 | case SEC_LEVEL_2: |
10109 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= | 10133 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= |
10110 | IEEE80211_FCTL_PROTECTED; | 10134 | cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
10111 | tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP; | 10135 | tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP; |
10112 | tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP; | 10136 | tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP; |
10113 | tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE; | 10137 | tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE; |
10114 | break; | 10138 | break; |
10115 | case SEC_LEVEL_1: | 10139 | case SEC_LEVEL_1: |
10116 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= | 10140 | tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |= |
10117 | IEEE80211_FCTL_PROTECTED; | 10141 | cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
10118 | tfd->u.data.key_index = priv->ieee->tx_keyidx; | 10142 | tfd->u.data.key_index = priv->ieee->tx_keyidx; |
10119 | if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= | 10143 | if (priv->ieee->sec.key_sizes[priv->ieee->tx_keyidx] <= |
10120 | 40) | 10144 | 40) |
@@ -10246,17 +10270,17 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, | |||
10246 | 10270 | ||
10247 | /* Filtering of fragment chains is done agains the first fragment */ | 10271 | /* Filtering of fragment chains is done agains the first fragment */ |
10248 | hdr = (void *)txb->fragments[0]->data; | 10272 | hdr = (void *)txb->fragments[0]->data; |
10249 | if (ieee80211_is_management(hdr->frame_ctl)) { | 10273 | if (ieee80211_is_management(le16_to_cpu(hdr->frame_ctl))) { |
10250 | if (filter & IPW_PROM_NO_MGMT) | 10274 | if (filter & IPW_PROM_NO_MGMT) |
10251 | return; | 10275 | return; |
10252 | if (filter & IPW_PROM_MGMT_HEADER_ONLY) | 10276 | if (filter & IPW_PROM_MGMT_HEADER_ONLY) |
10253 | hdr_only = 1; | 10277 | hdr_only = 1; |
10254 | } else if (ieee80211_is_control(hdr->frame_ctl)) { | 10278 | } else if (ieee80211_is_control(le16_to_cpu(hdr->frame_ctl))) { |
10255 | if (filter & IPW_PROM_NO_CTL) | 10279 | if (filter & IPW_PROM_NO_CTL) |
10256 | return; | 10280 | return; |
10257 | if (filter & IPW_PROM_CTL_HEADER_ONLY) | 10281 | if (filter & IPW_PROM_CTL_HEADER_ONLY) |
10258 | hdr_only = 1; | 10282 | hdr_only = 1; |
10259 | } else if (ieee80211_is_data(hdr->frame_ctl)) { | 10283 | } else if (ieee80211_is_data(le16_to_cpu(hdr->frame_ctl))) { |
10260 | if (filter & IPW_PROM_NO_DATA) | 10284 | if (filter & IPW_PROM_NO_DATA) |
10261 | return; | 10285 | return; |
10262 | if (filter & IPW_PROM_DATA_HEADER_ONLY) | 10286 | if (filter & IPW_PROM_DATA_HEADER_ONLY) |
@@ -10271,7 +10295,7 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, | |||
10271 | 10295 | ||
10272 | if (hdr_only) { | 10296 | if (hdr_only) { |
10273 | hdr = (void *)src->data; | 10297 | hdr = (void *)src->data; |
10274 | len = ieee80211_get_hdrlen(hdr->frame_ctl); | 10298 | len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); |
10275 | } else | 10299 | } else |
10276 | len = src->len; | 10300 | len = src->len; |
10277 | 10301 | ||
@@ -10615,6 +10639,8 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) | |||
10615 | INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); | 10639 | INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); |
10616 | INIT_WORK(&priv->request_scan, | 10640 | INIT_WORK(&priv->request_scan, |
10617 | (void (*)(void *))ipw_request_scan, priv); | 10641 | (void (*)(void *))ipw_request_scan, priv); |
10642 | INIT_WORK(&priv->request_passive_scan, | ||
10643 | (void (*)(void *))ipw_request_passive_scan, priv); | ||
10618 | INIT_WORK(&priv->gather_stats, | 10644 | INIT_WORK(&priv->gather_stats, |
10619 | (void (*)(void *))ipw_bg_gather_stats, priv); | 10645 | (void (*)(void *))ipw_bg_gather_stats, priv); |
10620 | INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); | 10646 | INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); |
@@ -11467,9 +11493,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
11467 | 11493 | ||
11468 | priv->net_dev = net_dev; | 11494 | priv->net_dev = net_dev; |
11469 | priv->pci_dev = pdev; | 11495 | priv->pci_dev = pdev; |
11470 | #ifdef CONFIG_IPW2200_DEBUG | ||
11471 | ipw_debug_level = debug; | 11496 | ipw_debug_level = debug; |
11472 | #endif | ||
11473 | spin_lock_init(&priv->irq_lock); | 11497 | spin_lock_init(&priv->irq_lock); |
11474 | spin_lock_init(&priv->lock); | 11498 | spin_lock_init(&priv->lock); |
11475 | for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) | 11499 | for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) |
@@ -11734,6 +11758,16 @@ static int ipw_pci_resume(struct pci_dev *pdev) | |||
11734 | } | 11758 | } |
11735 | #endif | 11759 | #endif |
11736 | 11760 | ||
11761 | static void ipw_pci_shutdown(struct pci_dev *pdev) | ||
11762 | { | ||
11763 | struct ipw_priv *priv = pci_get_drvdata(pdev); | ||
11764 | |||
11765 | /* Take down the device; powers it off, etc. */ | ||
11766 | ipw_down(priv); | ||
11767 | |||
11768 | pci_disable_device(pdev); | ||
11769 | } | ||
11770 | |||
11737 | /* driver initialization stuff */ | 11771 | /* driver initialization stuff */ |
11738 | static struct pci_driver ipw_driver = { | 11772 | static struct pci_driver ipw_driver = { |
11739 | .name = DRV_NAME, | 11773 | .name = DRV_NAME, |
@@ -11744,6 +11778,7 @@ static struct pci_driver ipw_driver = { | |||
11744 | .suspend = ipw_pci_suspend, | 11778 | .suspend = ipw_pci_suspend, |
11745 | .resume = ipw_pci_resume, | 11779 | .resume = ipw_pci_resume, |
11746 | #endif | 11780 | #endif |
11781 | .shutdown = ipw_pci_shutdown, | ||
11747 | }; | 11782 | }; |
11748 | 11783 | ||
11749 | static int __init ipw_init(void) | 11784 | static int __init ipw_init(void) |
@@ -11787,10 +11822,8 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); | |||
11787 | module_param(led, int, 0444); | 11822 | module_param(led, int, 0444); |
11788 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); | 11823 | MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n"); |
11789 | 11824 | ||
11790 | #ifdef CONFIG_IPW2200_DEBUG | ||
11791 | module_param(debug, int, 0444); | 11825 | module_param(debug, int, 0444); |
11792 | MODULE_PARM_DESC(debug, "debug output mask"); | 11826 | MODULE_PARM_DESC(debug, "debug output mask"); |
11793 | #endif | ||
11794 | 11827 | ||
11795 | module_param(channel, int, 0444); | 11828 | module_param(channel, int, 0444); |
11796 | MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); | 11829 | MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); |