diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 829 |
1 files changed, 422 insertions, 407 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6027e1119c3f..d15a2c997954 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/version.h> | ||
33 | #include <linux/init.h> | 32 | #include <linux/init.h> |
34 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
35 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
@@ -102,16 +101,6 @@ MODULE_VERSION(DRV_VERSION); | |||
102 | MODULE_AUTHOR(DRV_COPYRIGHT); | 101 | MODULE_AUTHOR(DRV_COPYRIGHT); |
103 | MODULE_LICENSE("GPL"); | 102 | MODULE_LICENSE("GPL"); |
104 | 103 | ||
105 | static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | ||
106 | { | ||
107 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
108 | int hdr_len = ieee80211_get_hdrlen(fc); | ||
109 | |||
110 | if ((fc & 0x00cc) == (IEEE80211_STYPE_QOS_DATA | IEEE80211_FTYPE_DATA)) | ||
111 | return (__le16 *) ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN); | ||
112 | return NULL; | ||
113 | } | ||
114 | |||
115 | static const struct ieee80211_supported_band *iwl3945_get_band( | 104 | static const struct ieee80211_supported_band *iwl3945_get_band( |
116 | struct iwl3945_priv *priv, enum ieee80211_band band) | 105 | struct iwl3945_priv *priv, enum ieee80211_band band) |
117 | { | 106 | { |
@@ -285,10 +274,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, | |||
285 | return 0; | 274 | return 0; |
286 | 275 | ||
287 | error: | 276 | error: |
288 | if (txq->txb) { | 277 | kfree(txq->txb); |
289 | kfree(txq->txb); | 278 | txq->txb = NULL; |
290 | txq->txb = NULL; | ||
291 | } | ||
292 | 279 | ||
293 | return -ENOMEM; | 280 | return -ENOMEM; |
294 | } | 281 | } |
@@ -375,10 +362,8 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t | |||
375 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | 362 | txq->q.n_bd, txq->bd, txq->q.dma_addr); |
376 | 363 | ||
377 | /* De-alloc array of per-TFD driver data */ | 364 | /* De-alloc array of per-TFD driver data */ |
378 | if (txq->txb) { | 365 | kfree(txq->txb); |
379 | kfree(txq->txb); | 366 | txq->txb = NULL; |
380 | txq->txb = NULL; | ||
381 | } | ||
382 | 367 | ||
383 | /* 0-fill queue descriptor structure */ | 368 | /* 0-fill queue descriptor structure */ |
384 | memset(txq, 0, sizeof(*txq)); | 369 | memset(txq, 0, sizeof(*txq)); |
@@ -547,10 +532,20 @@ static inline int iwl3945_is_init(struct iwl3945_priv *priv) | |||
547 | return test_bit(STATUS_INIT, &priv->status); | 532 | return test_bit(STATUS_INIT, &priv->status); |
548 | } | 533 | } |
549 | 534 | ||
535 | static inline int iwl3945_is_rfkill_sw(struct iwl3945_priv *priv) | ||
536 | { | ||
537 | return test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
538 | } | ||
539 | |||
540 | static inline int iwl3945_is_rfkill_hw(struct iwl3945_priv *priv) | ||
541 | { | ||
542 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | ||
543 | } | ||
544 | |||
550 | static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) | 545 | static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) |
551 | { | 546 | { |
552 | return test_bit(STATUS_RF_KILL_HW, &priv->status) || | 547 | return iwl3945_is_rfkill_hw(priv) || |
553 | test_bit(STATUS_RF_KILL_SW, &priv->status); | 548 | iwl3945_is_rfkill_sw(priv); |
554 | } | 549 | } |
555 | 550 | ||
556 | static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) | 551 | static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) |
@@ -980,7 +975,7 @@ static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) | |||
980 | { | 975 | { |
981 | 976 | ||
982 | /* These items are only settable from the full RXON command */ | 977 | /* These items are only settable from the full RXON command */ |
983 | if (!(priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) || | 978 | if (!(iwl3945_is_associated(priv)) || |
984 | compare_ether_addr(priv->staging_rxon.bssid_addr, | 979 | compare_ether_addr(priv->staging_rxon.bssid_addr, |
985 | priv->active_rxon.bssid_addr) || | 980 | priv->active_rxon.bssid_addr) || |
986 | compare_ether_addr(priv->staging_rxon.node_addr, | 981 | compare_ether_addr(priv->staging_rxon.node_addr, |
@@ -1165,7 +1160,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1165 | /* If we have set the ASSOC_MSK and we are in BSS mode then | 1160 | /* If we have set the ASSOC_MSK and we are in BSS mode then |
1166 | * add the IWL_AP_ID to the station rate table */ | 1161 | * add the IWL_AP_ID to the station rate table */ |
1167 | if (iwl3945_is_associated(priv) && | 1162 | if (iwl3945_is_associated(priv) && |
1168 | (priv->iw_mode == IEEE80211_IF_TYPE_STA)) | 1163 | (priv->iw_mode == NL80211_IFTYPE_STATION)) |
1169 | if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0) | 1164 | if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0) |
1170 | == IWL_INVALID_STATION) { | 1165 | == IWL_INVALID_STATION) { |
1171 | IWL_ERROR("Error adding AP address for transmit.\n"); | 1166 | IWL_ERROR("Error adding AP address for transmit.\n"); |
@@ -1452,8 +1447,8 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, | |||
1452 | { | 1447 | { |
1453 | 1448 | ||
1454 | if (!iwl3945_is_associated(priv) || !priv->ibss_beacon || | 1449 | if (!iwl3945_is_associated(priv) || !priv->ibss_beacon || |
1455 | ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) && | 1450 | ((priv->iw_mode != NL80211_IFTYPE_ADHOC) && |
1456 | (priv->iw_mode != IEEE80211_IF_TYPE_AP))) | 1451 | (priv->iw_mode != NL80211_IFTYPE_AP))) |
1457 | return 0; | 1452 | return 0; |
1458 | 1453 | ||
1459 | if (priv->ibss_beacon->len > left) | 1454 | if (priv->ibss_beacon->len > left) |
@@ -1562,7 +1557,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) | |||
1562 | BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); | 1557 | BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); |
1563 | 1558 | ||
1564 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { | 1559 | if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { |
1565 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); | 1560 | IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp); |
1566 | return -ENOENT; | 1561 | return -ENOENT; |
1567 | } | 1562 | } |
1568 | 1563 | ||
@@ -1587,7 +1582,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) | |||
1587 | } | 1582 | } |
1588 | 1583 | ||
1589 | if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { | 1584 | if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) { |
1590 | IWL_ERROR("Time out reading EEPROM[%d]", addr); | 1585 | IWL_ERROR("Time out reading EEPROM[%d]\n", addr); |
1591 | return -ETIMEDOUT; | 1586 | return -ETIMEDOUT; |
1592 | } | 1587 | } |
1593 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); | 1588 | e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); |
@@ -1751,14 +1746,14 @@ static void iwl3945_reset_qos(struct iwl3945_priv *priv) | |||
1751 | spin_lock_irqsave(&priv->lock, flags); | 1746 | spin_lock_irqsave(&priv->lock, flags); |
1752 | priv->qos_data.qos_active = 0; | 1747 | priv->qos_data.qos_active = 0; |
1753 | 1748 | ||
1754 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) { | 1749 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) { |
1755 | if (priv->qos_data.qos_enable) | 1750 | if (priv->qos_data.qos_enable) |
1756 | priv->qos_data.qos_active = 1; | 1751 | priv->qos_data.qos_active = 1; |
1757 | if (!(priv->active_rate & 0xfff0)) { | 1752 | if (!(priv->active_rate & 0xfff0)) { |
1758 | cw_min = 31; | 1753 | cw_min = 31; |
1759 | is_legacy = 1; | 1754 | is_legacy = 1; |
1760 | } | 1755 | } |
1761 | } else if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 1756 | } else if (priv->iw_mode == NL80211_IFTYPE_AP) { |
1762 | if (priv->qos_data.qos_enable) | 1757 | if (priv->qos_data.qos_enable) |
1763 | priv->qos_data.qos_active = 1; | 1758 | priv->qos_data.qos_active = 1; |
1764 | } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) { | 1759 | } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) { |
@@ -2035,36 +2030,6 @@ static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) | |||
2035 | return rc; | 2030 | return rc; |
2036 | } | 2031 | } |
2037 | 2032 | ||
2038 | int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) | ||
2039 | { | ||
2040 | /* Filter incoming packets to determine if they are targeted toward | ||
2041 | * this network, discarding packets coming from ourselves */ | ||
2042 | switch (priv->iw_mode) { | ||
2043 | case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */ | ||
2044 | /* packets from our adapter are dropped (echo) */ | ||
2045 | if (!compare_ether_addr(header->addr2, priv->mac_addr)) | ||
2046 | return 0; | ||
2047 | /* {broad,multi}cast packets to our IBSS go through */ | ||
2048 | if (is_multicast_ether_addr(header->addr1)) | ||
2049 | return !compare_ether_addr(header->addr3, priv->bssid); | ||
2050 | /* packets to our adapter go through */ | ||
2051 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
2052 | case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */ | ||
2053 | /* packets from our adapter are dropped (echo) */ | ||
2054 | if (!compare_ether_addr(header->addr3, priv->mac_addr)) | ||
2055 | return 0; | ||
2056 | /* {broad,multi}cast packets to our BSS go through */ | ||
2057 | if (is_multicast_ether_addr(header->addr1)) | ||
2058 | return !compare_ether_addr(header->addr2, priv->bssid); | ||
2059 | /* packets to our adapter go through */ | ||
2060 | return !compare_ether_addr(header->addr1, priv->mac_addr); | ||
2061 | default: | ||
2062 | return 1; | ||
2063 | } | ||
2064 | |||
2065 | return 1; | ||
2066 | } | ||
2067 | |||
2068 | /** | 2033 | /** |
2069 | * iwl3945_scan_cancel - Cancel any currently executing HW scan | 2034 | * iwl3945_scan_cancel - Cancel any currently executing HW scan |
2070 | * | 2035 | * |
@@ -2117,20 +2082,6 @@ static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long | |||
2117 | return ret; | 2082 | return ret; |
2118 | } | 2083 | } |
2119 | 2084 | ||
2120 | static void iwl3945_sequence_reset(struct iwl3945_priv *priv) | ||
2121 | { | ||
2122 | /* Reset ieee stats */ | ||
2123 | |||
2124 | /* We don't reset the net_device_stats (ieee->stats) on | ||
2125 | * re-association */ | ||
2126 | |||
2127 | priv->last_seq_num = -1; | ||
2128 | priv->last_frag_num = -1; | ||
2129 | priv->last_packet_time = 0; | ||
2130 | |||
2131 | iwl3945_scan_cancel(priv); | ||
2132 | } | ||
2133 | |||
2134 | #define MAX_UCODE_BEACON_INTERVAL 1024 | 2085 | #define MAX_UCODE_BEACON_INTERVAL 1024 |
2135 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) | 2086 | #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) |
2136 | 2087 | ||
@@ -2169,7 +2120,7 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) | |||
2169 | beacon_int = priv->beacon_int; | 2120 | beacon_int = priv->beacon_int; |
2170 | spin_unlock_irqrestore(&priv->lock, flags); | 2121 | spin_unlock_irqrestore(&priv->lock, flags); |
2171 | 2122 | ||
2172 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { | 2123 | if (priv->iw_mode == NL80211_IFTYPE_STATION) { |
2173 | if (beacon_int == 0) { | 2124 | if (beacon_int == 0) { |
2174 | priv->rxon_timing.beacon_interval = cpu_to_le16(100); | 2125 | priv->rxon_timing.beacon_interval = cpu_to_le16(100); |
2175 | priv->rxon_timing.beacon_init_val = cpu_to_le32(102400); | 2126 | priv->rxon_timing.beacon_init_val = cpu_to_le32(102400); |
@@ -2205,7 +2156,7 @@ static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) | |||
2205 | 2156 | ||
2206 | static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | 2157 | static int iwl3945_scan_initiate(struct iwl3945_priv *priv) |
2207 | { | 2158 | { |
2208 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 2159 | if (priv->iw_mode == NL80211_IFTYPE_AP) { |
2209 | IWL_ERROR("APs don't scan.\n"); | 2160 | IWL_ERROR("APs don't scan.\n"); |
2210 | return 0; | 2161 | return 0; |
2211 | } | 2162 | } |
@@ -2267,7 +2218,7 @@ static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, | |||
2267 | else | 2218 | else |
2268 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 2219 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
2269 | 2220 | ||
2270 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 2221 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
2271 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 2222 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
2272 | 2223 | ||
2273 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 2224 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
@@ -2286,23 +2237,23 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2286 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); | 2237 | memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); |
2287 | 2238 | ||
2288 | switch (priv->iw_mode) { | 2239 | switch (priv->iw_mode) { |
2289 | case IEEE80211_IF_TYPE_AP: | 2240 | case NL80211_IFTYPE_AP: |
2290 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; | 2241 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; |
2291 | break; | 2242 | break; |
2292 | 2243 | ||
2293 | case IEEE80211_IF_TYPE_STA: | 2244 | case NL80211_IFTYPE_STATION: |
2294 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; | 2245 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; |
2295 | priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; | 2246 | priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; |
2296 | break; | 2247 | break; |
2297 | 2248 | ||
2298 | case IEEE80211_IF_TYPE_IBSS: | 2249 | case NL80211_IFTYPE_ADHOC: |
2299 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; | 2250 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; |
2300 | priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; | 2251 | priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; |
2301 | priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | | 2252 | priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | |
2302 | RXON_FILTER_ACCEPT_GRP_MSK; | 2253 | RXON_FILTER_ACCEPT_GRP_MSK; |
2303 | break; | 2254 | break; |
2304 | 2255 | ||
2305 | case IEEE80211_IF_TYPE_MNTR: | 2256 | case NL80211_IFTYPE_MONITOR: |
2306 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER; | 2257 | priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER; |
2307 | priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK | | 2258 | priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK | |
2308 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; | 2259 | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; |
@@ -2322,7 +2273,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2322 | #endif | 2273 | #endif |
2323 | 2274 | ||
2324 | ch_info = iwl3945_get_channel_info(priv, priv->band, | 2275 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2325 | le16_to_cpu(priv->staging_rxon.channel)); | 2276 | le16_to_cpu(priv->active_rxon.channel)); |
2326 | 2277 | ||
2327 | if (!ch_info) | 2278 | if (!ch_info) |
2328 | ch_info = &priv->channel_info[0]; | 2279 | ch_info = &priv->channel_info[0]; |
@@ -2331,7 +2282,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2331 | * in some case A channels are all non IBSS | 2282 | * in some case A channels are all non IBSS |
2332 | * in this case force B/G channel | 2283 | * in this case force B/G channel |
2333 | */ | 2284 | */ |
2334 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2285 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && |
2335 | !(is_channel_ibss(ch_info))) | 2286 | !(is_channel_ibss(ch_info))) |
2336 | ch_info = &priv->channel_info[0]; | 2287 | ch_info = &priv->channel_info[0]; |
2337 | 2288 | ||
@@ -2351,7 +2302,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2351 | 2302 | ||
2352 | static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | 2303 | static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) |
2353 | { | 2304 | { |
2354 | if (mode == IEEE80211_IF_TYPE_IBSS) { | 2305 | if (mode == NL80211_IFTYPE_ADHOC) { |
2355 | const struct iwl3945_channel_info *ch_info; | 2306 | const struct iwl3945_channel_info *ch_info; |
2356 | 2307 | ||
2357 | ch_info = iwl3945_get_channel_info(priv, | 2308 | ch_info = iwl3945_get_channel_info(priv, |
@@ -2389,12 +2340,13 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2389 | } | 2340 | } |
2390 | 2341 | ||
2391 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | 2342 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, |
2392 | struct ieee80211_tx_control *ctl, | 2343 | struct ieee80211_tx_info *info, |
2393 | struct iwl3945_cmd *cmd, | 2344 | struct iwl3945_cmd *cmd, |
2394 | struct sk_buff *skb_frag, | 2345 | struct sk_buff *skb_frag, |
2395 | int last_frag) | 2346 | int last_frag) |
2396 | { | 2347 | { |
2397 | struct iwl3945_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo; | 2348 | struct iwl3945_hw_key *keyinfo = |
2349 | &priv->stations[info->control.hw_key->hw_key_idx].keyinfo; | ||
2398 | 2350 | ||
2399 | switch (keyinfo->alg) { | 2351 | switch (keyinfo->alg) { |
2400 | case ALG_CCMP: | 2352 | case ALG_CCMP: |
@@ -2417,7 +2369,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | |||
2417 | 2369 | ||
2418 | case ALG_WEP: | 2370 | case ALG_WEP: |
2419 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP | | 2371 | cmd->cmd.tx.sec_ctl = TX_CMD_SEC_WEP | |
2420 | (ctl->key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; | 2372 | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; |
2421 | 2373 | ||
2422 | if (keyinfo->keylen == 13) | 2374 | if (keyinfo->keylen == 13) |
2423 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; | 2375 | cmd->cmd.tx.sec_ctl |= TX_CMD_SEC_KEY128; |
@@ -2425,7 +2377,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | |||
2425 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen); | 2377 | memcpy(&cmd->cmd.tx.key[3], keyinfo->key, keyinfo->keylen); |
2426 | 2378 | ||
2427 | IWL_DEBUG_TX("Configuring packet for WEP encryption " | 2379 | IWL_DEBUG_TX("Configuring packet for WEP encryption " |
2428 | "with key %d\n", ctl->key_idx); | 2380 | "with key %d\n", info->control.hw_key->hw_key_idx); |
2429 | break; | 2381 | break; |
2430 | 2382 | ||
2431 | default: | 2383 | default: |
@@ -2439,20 +2391,19 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, | |||
2439 | */ | 2391 | */ |
2440 | static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | 2392 | static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, |
2441 | struct iwl3945_cmd *cmd, | 2393 | struct iwl3945_cmd *cmd, |
2442 | struct ieee80211_tx_control *ctrl, | 2394 | struct ieee80211_tx_info *info, |
2443 | struct ieee80211_hdr *hdr, | 2395 | struct ieee80211_hdr *hdr, |
2444 | int is_unicast, u8 std_id) | 2396 | int is_unicast, u8 std_id) |
2445 | { | 2397 | { |
2446 | __le16 *qc; | 2398 | __le16 fc = hdr->frame_control; |
2447 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
2448 | __le32 tx_flags = cmd->cmd.tx.tx_flags; | 2399 | __le32 tx_flags = cmd->cmd.tx.tx_flags; |
2449 | 2400 | ||
2450 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 2401 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2451 | if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) { | 2402 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
2452 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 2403 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
2453 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) | 2404 | if (ieee80211_is_mgmt(fc)) |
2454 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 2405 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
2455 | if (ieee80211_is_probe_response(fc) && | 2406 | if (ieee80211_is_probe_resp(fc) && |
2456 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) | 2407 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) |
2457 | tx_flags |= TX_CMD_FLG_TSF_MSK; | 2408 | tx_flags |= TX_CMD_FLG_TSF_MSK; |
2458 | } else { | 2409 | } else { |
@@ -2461,20 +2412,21 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2461 | } | 2412 | } |
2462 | 2413 | ||
2463 | cmd->cmd.tx.sta_id = std_id; | 2414 | cmd->cmd.tx.sta_id = std_id; |
2464 | if (ieee80211_get_morefrag(hdr)) | 2415 | if (ieee80211_has_morefrags(fc)) |
2465 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 2416 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
2466 | 2417 | ||
2467 | qc = ieee80211_get_qos_ctrl(hdr); | 2418 | if (ieee80211_is_data_qos(fc)) { |
2468 | if (qc) { | 2419 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
2469 | cmd->cmd.tx.tid_tspec = (u8) (le16_to_cpu(*qc) & 0xf); | 2420 | cmd->cmd.tx.tid_tspec = qc[0] & 0xf; |
2470 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | 2421 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; |
2471 | } else | 2422 | } else { |
2472 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 2423 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
2424 | } | ||
2473 | 2425 | ||
2474 | if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 2426 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { |
2475 | tx_flags |= TX_CMD_FLG_RTS_MSK; | 2427 | tx_flags |= TX_CMD_FLG_RTS_MSK; |
2476 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | 2428 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; |
2477 | } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | 2429 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { |
2478 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 2430 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
2479 | tx_flags |= TX_CMD_FLG_CTS_MSK; | 2431 | tx_flags |= TX_CMD_FLG_CTS_MSK; |
2480 | } | 2432 | } |
@@ -2483,9 +2435,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2483 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | 2435 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; |
2484 | 2436 | ||
2485 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | 2437 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); |
2486 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 2438 | if (ieee80211_is_mgmt(fc)) { |
2487 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || | 2439 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) |
2488 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) | ||
2489 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); | 2440 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); |
2490 | else | 2441 | else |
2491 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); | 2442 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); |
@@ -2518,11 +2469,11 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2518 | 2469 | ||
2519 | /* If we are a client station in a BSS network, use the special | 2470 | /* If we are a client station in a BSS network, use the special |
2520 | * AP station entry (that's the only station we communicate with) */ | 2471 | * AP station entry (that's the only station we communicate with) */ |
2521 | case IEEE80211_IF_TYPE_STA: | 2472 | case NL80211_IFTYPE_STATION: |
2522 | return IWL_AP_ID; | 2473 | return IWL_AP_ID; |
2523 | 2474 | ||
2524 | /* If we are an AP, then find the station, or use BCAST */ | 2475 | /* If we are an AP, then find the station, or use BCAST */ |
2525 | case IEEE80211_IF_TYPE_AP: | 2476 | case NL80211_IFTYPE_AP: |
2526 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); | 2477 | sta_id = iwl3945_hw_find_station(priv, hdr->addr1); |
2527 | if (sta_id != IWL_INVALID_STATION) | 2478 | if (sta_id != IWL_INVALID_STATION) |
2528 | return sta_id; | 2479 | return sta_id; |
@@ -2530,7 +2481,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2530 | 2481 | ||
2531 | /* If this frame is going out to an IBSS network, find the station, | 2482 | /* If this frame is going out to an IBSS network, find the station, |
2532 | * or create a new station table entry */ | 2483 | * or create a new station table entry */ |
2533 | case IEEE80211_IF_TYPE_IBSS: { | 2484 | case NL80211_IFTYPE_ADHOC: { |
2534 | DECLARE_MAC_BUF(mac); | 2485 | DECLARE_MAC_BUF(mac); |
2535 | 2486 | ||
2536 | /* Create new station table entry */ | 2487 | /* Create new station table entry */ |
@@ -2549,8 +2500,13 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2549 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); | 2500 | iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); |
2550 | return priv->hw_setting.bcast_sta_id; | 2501 | return priv->hw_setting.bcast_sta_id; |
2551 | } | 2502 | } |
2503 | /* If we are in monitor mode, use BCAST. This is required for | ||
2504 | * packet injection. */ | ||
2505 | case NL80211_IFTYPE_MONITOR: | ||
2506 | return priv->hw_setting.bcast_sta_id; | ||
2507 | |||
2552 | default: | 2508 | default: |
2553 | IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); | 2509 | IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode); |
2554 | return priv->hw_setting.bcast_sta_id; | 2510 | return priv->hw_setting.bcast_sta_id; |
2555 | } | 2511 | } |
2556 | } | 2512 | } |
@@ -2558,25 +2514,27 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2558 | /* | 2514 | /* |
2559 | * start REPLY_TX command process | 2515 | * start REPLY_TX command process |
2560 | */ | 2516 | */ |
2561 | static int iwl3945_tx_skb(struct iwl3945_priv *priv, | 2517 | static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) |
2562 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | ||
2563 | { | 2518 | { |
2564 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2519 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2520 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2565 | struct iwl3945_tfd_frame *tfd; | 2521 | struct iwl3945_tfd_frame *tfd; |
2566 | u32 *control_flags; | 2522 | u32 *control_flags; |
2567 | int txq_id = ctl->queue; | 2523 | int txq_id = skb_get_queue_mapping(skb); |
2568 | struct iwl3945_tx_queue *txq = NULL; | 2524 | struct iwl3945_tx_queue *txq = NULL; |
2569 | struct iwl3945_queue *q = NULL; | 2525 | struct iwl3945_queue *q = NULL; |
2570 | dma_addr_t phys_addr; | 2526 | dma_addr_t phys_addr; |
2571 | dma_addr_t txcmd_phys; | 2527 | dma_addr_t txcmd_phys; |
2572 | struct iwl3945_cmd *out_cmd = NULL; | 2528 | struct iwl3945_cmd *out_cmd = NULL; |
2573 | u16 len, idx, len_org; | 2529 | u16 len, idx, len_org, hdr_len; |
2574 | u8 id, hdr_len, unicast; | 2530 | u8 id; |
2531 | u8 unicast; | ||
2575 | u8 sta_id; | 2532 | u8 sta_id; |
2533 | u8 tid = 0; | ||
2576 | u16 seq_number = 0; | 2534 | u16 seq_number = 0; |
2577 | u16 fc; | 2535 | __le16 fc; |
2578 | __le16 *qc; | ||
2579 | u8 wait_write_ptr = 0; | 2536 | u8 wait_write_ptr = 0; |
2537 | u8 *qc = NULL; | ||
2580 | unsigned long flags; | 2538 | unsigned long flags; |
2581 | int rc; | 2539 | int rc; |
2582 | 2540 | ||
@@ -2586,12 +2544,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2586 | goto drop_unlock; | 2544 | goto drop_unlock; |
2587 | } | 2545 | } |
2588 | 2546 | ||
2589 | if (!priv->vif) { | 2547 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2590 | IWL_DEBUG_DROP("Dropping - !priv->vif\n"); | ||
2591 | goto drop_unlock; | ||
2592 | } | ||
2593 | |||
2594 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { | ||
2595 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2548 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2596 | goto drop_unlock; | 2549 | goto drop_unlock; |
2597 | } | 2550 | } |
@@ -2599,28 +2552,29 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2599 | unicast = !is_multicast_ether_addr(hdr->addr1); | 2552 | unicast = !is_multicast_ether_addr(hdr->addr1); |
2600 | id = 0; | 2553 | id = 0; |
2601 | 2554 | ||
2602 | fc = le16_to_cpu(hdr->frame_control); | 2555 | fc = hdr->frame_control; |
2603 | 2556 | ||
2604 | #ifdef CONFIG_IWL3945_DEBUG | 2557 | #ifdef CONFIG_IWL3945_DEBUG |
2605 | if (ieee80211_is_auth(fc)) | 2558 | if (ieee80211_is_auth(fc)) |
2606 | IWL_DEBUG_TX("Sending AUTH frame\n"); | 2559 | IWL_DEBUG_TX("Sending AUTH frame\n"); |
2607 | else if (ieee80211_is_assoc_request(fc)) | 2560 | else if (ieee80211_is_assoc_req(fc)) |
2608 | IWL_DEBUG_TX("Sending ASSOC frame\n"); | 2561 | IWL_DEBUG_TX("Sending ASSOC frame\n"); |
2609 | else if (ieee80211_is_reassoc_request(fc)) | 2562 | else if (ieee80211_is_reassoc_req(fc)) |
2610 | IWL_DEBUG_TX("Sending REASSOC frame\n"); | 2563 | IWL_DEBUG_TX("Sending REASSOC frame\n"); |
2611 | #endif | 2564 | #endif |
2612 | 2565 | ||
2613 | /* drop all data frame if we are not associated */ | 2566 | /* drop all data frame if we are not associated */ |
2614 | if ((!iwl3945_is_associated(priv) || | 2567 | if (ieee80211_is_data(fc) && |
2615 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && | 2568 | (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */ |
2616 | ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { | 2569 | (!iwl3945_is_associated(priv) || |
2570 | ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) { | ||
2617 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); | 2571 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); |
2618 | goto drop_unlock; | 2572 | goto drop_unlock; |
2619 | } | 2573 | } |
2620 | 2574 | ||
2621 | spin_unlock_irqrestore(&priv->lock, flags); | 2575 | spin_unlock_irqrestore(&priv->lock, flags); |
2622 | 2576 | ||
2623 | hdr_len = ieee80211_get_hdrlen(fc); | 2577 | hdr_len = ieee80211_hdrlen(fc); |
2624 | 2578 | ||
2625 | /* Find (or create) index into station table for destination station */ | 2579 | /* Find (or create) index into station table for destination station */ |
2626 | sta_id = iwl3945_get_sta_id(priv, hdr); | 2580 | sta_id = iwl3945_get_sta_id(priv, hdr); |
@@ -2634,9 +2588,9 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2634 | 2588 | ||
2635 | IWL_DEBUG_RATE("station Id %d\n", sta_id); | 2589 | IWL_DEBUG_RATE("station Id %d\n", sta_id); |
2636 | 2590 | ||
2637 | qc = ieee80211_get_qos_ctrl(hdr); | 2591 | if (ieee80211_is_data_qos(fc)) { |
2638 | if (qc) { | 2592 | qc = ieee80211_get_qos_ctl(hdr); |
2639 | u8 tid = (u8)(le16_to_cpu(*qc) & 0xf); | 2593 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
2640 | seq_number = priv->stations[sta_id].tid[tid].seq_number & | 2594 | seq_number = priv->stations[sta_id].tid[tid].seq_number & |
2641 | IEEE80211_SCTL_SEQ; | 2595 | IEEE80211_SCTL_SEQ; |
2642 | hdr->seq_ctrl = cpu_to_le16(seq_number) | | 2596 | hdr->seq_ctrl = cpu_to_le16(seq_number) | |
@@ -2660,8 +2614,6 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2660 | /* Set up driver data for this TFD */ | 2614 | /* Set up driver data for this TFD */ |
2661 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); | 2615 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); |
2662 | txq->txb[q->write_ptr].skb[0] = skb; | 2616 | txq->txb[q->write_ptr].skb[0] = skb; |
2663 | memcpy(&(txq->txb[q->write_ptr].status.control), | ||
2664 | ctl, sizeof(struct ieee80211_tx_control)); | ||
2665 | 2617 | ||
2666 | /* Init first empty entry in queue's array of Tx/cmd buffers */ | 2618 | /* Init first empty entry in queue's array of Tx/cmd buffers */ |
2667 | out_cmd = &txq->cmd[idx]; | 2619 | out_cmd = &txq->cmd[idx]; |
@@ -2710,8 +2662,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2710 | * first entry */ | 2662 | * first entry */ |
2711 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 2663 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
2712 | 2664 | ||
2713 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 2665 | if (info->control.hw_key) |
2714 | iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); | 2666 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); |
2715 | 2667 | ||
2716 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 2668 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
2717 | * if any (802.11 null frames have no payload). */ | 2669 | * if any (802.11 null frames have no payload). */ |
@@ -2736,20 +2688,18 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2736 | out_cmd->cmd.tx.len = cpu_to_le16(len); | 2688 | out_cmd->cmd.tx.len = cpu_to_le16(len); |
2737 | 2689 | ||
2738 | /* TODO need this for burst mode later on */ | 2690 | /* TODO need this for burst mode later on */ |
2739 | iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); | 2691 | iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, unicast, sta_id); |
2740 | 2692 | ||
2741 | /* set is_hcca to 0; it probably will never be implemented */ | 2693 | /* set is_hcca to 0; it probably will never be implemented */ |
2742 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); | 2694 | iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0); |
2743 | 2695 | ||
2744 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 2696 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
2745 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 2697 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
2746 | 2698 | ||
2747 | if (!ieee80211_get_morefrag(hdr)) { | 2699 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
2748 | txq->need_update = 1; | 2700 | txq->need_update = 1; |
2749 | if (qc) { | 2701 | if (qc) |
2750 | u8 tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
2751 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | 2702 | priv->stations[sta_id].tid[tid].seq_number = seq_number; |
2752 | } | ||
2753 | } else { | 2703 | } else { |
2754 | wait_write_ptr = 1; | 2704 | wait_write_ptr = 1; |
2755 | txq->need_update = 0; | 2705 | txq->need_update = 0; |
@@ -2759,7 +2709,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2759 | sizeof(out_cmd->cmd.tx)); | 2709 | sizeof(out_cmd->cmd.tx)); |
2760 | 2710 | ||
2761 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 2711 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, |
2762 | ieee80211_get_hdrlen(fc)); | 2712 | ieee80211_hdrlen(fc)); |
2763 | 2713 | ||
2764 | /* Tell device the write index *just past* this latest filled TFD */ | 2714 | /* Tell device the write index *just past* this latest filled TFD */ |
2765 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 2715 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -2778,7 +2728,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2778 | spin_unlock_irqrestore(&priv->lock, flags); | 2728 | spin_unlock_irqrestore(&priv->lock, flags); |
2779 | } | 2729 | } |
2780 | 2730 | ||
2781 | ieee80211_stop_queue(priv->hw, ctl->queue); | 2731 | ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb)); |
2782 | } | 2732 | } |
2783 | 2733 | ||
2784 | return 0; | 2734 | return 0; |
@@ -2856,7 +2806,7 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2856 | if (disable_radio) { | 2806 | if (disable_radio) { |
2857 | iwl3945_scan_cancel(priv); | 2807 | iwl3945_scan_cancel(priv); |
2858 | /* FIXME: This is a workaround for AP */ | 2808 | /* FIXME: This is a workaround for AP */ |
2859 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | 2809 | if (priv->iw_mode != NL80211_IFTYPE_AP) { |
2860 | spin_lock_irqsave(&priv->lock, flags); | 2810 | spin_lock_irqsave(&priv->lock, flags); |
2861 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, | 2811 | iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, |
2862 | CSR_UCODE_SW_BIT_RFKILL); | 2812 | CSR_UCODE_SW_BIT_RFKILL); |
@@ -2888,7 +2838,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2888 | return; | 2838 | return; |
2889 | } | 2839 | } |
2890 | 2840 | ||
2891 | queue_work(priv->workqueue, &priv->restart); | 2841 | if (priv->is_open) |
2842 | queue_work(priv->workqueue, &priv->restart); | ||
2892 | return; | 2843 | return; |
2893 | } | 2844 | } |
2894 | 2845 | ||
@@ -2924,72 +2875,6 @@ void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, | |||
2924 | } | 2875 | } |
2925 | } | 2876 | } |
2926 | 2877 | ||
2927 | #define IWL_PACKET_RETRY_TIME HZ | ||
2928 | |||
2929 | int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) | ||
2930 | { | ||
2931 | u16 sc = le16_to_cpu(header->seq_ctrl); | ||
2932 | u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; | ||
2933 | u16 frag = sc & IEEE80211_SCTL_FRAG; | ||
2934 | u16 *last_seq, *last_frag; | ||
2935 | unsigned long *last_time; | ||
2936 | |||
2937 | switch (priv->iw_mode) { | ||
2938 | case IEEE80211_IF_TYPE_IBSS:{ | ||
2939 | struct list_head *p; | ||
2940 | struct iwl3945_ibss_seq *entry = NULL; | ||
2941 | u8 *mac = header->addr2; | ||
2942 | int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); | ||
2943 | |||
2944 | __list_for_each(p, &priv->ibss_mac_hash[index]) { | ||
2945 | entry = list_entry(p, struct iwl3945_ibss_seq, list); | ||
2946 | if (!compare_ether_addr(entry->mac, mac)) | ||
2947 | break; | ||
2948 | } | ||
2949 | if (p == &priv->ibss_mac_hash[index]) { | ||
2950 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | ||
2951 | if (!entry) { | ||
2952 | IWL_ERROR("Cannot malloc new mac entry\n"); | ||
2953 | return 0; | ||
2954 | } | ||
2955 | memcpy(entry->mac, mac, ETH_ALEN); | ||
2956 | entry->seq_num = seq; | ||
2957 | entry->frag_num = frag; | ||
2958 | entry->packet_time = jiffies; | ||
2959 | list_add(&entry->list, &priv->ibss_mac_hash[index]); | ||
2960 | return 0; | ||
2961 | } | ||
2962 | last_seq = &entry->seq_num; | ||
2963 | last_frag = &entry->frag_num; | ||
2964 | last_time = &entry->packet_time; | ||
2965 | break; | ||
2966 | } | ||
2967 | case IEEE80211_IF_TYPE_STA: | ||
2968 | last_seq = &priv->last_seq_num; | ||
2969 | last_frag = &priv->last_frag_num; | ||
2970 | last_time = &priv->last_packet_time; | ||
2971 | break; | ||
2972 | default: | ||
2973 | return 0; | ||
2974 | } | ||
2975 | if ((*last_seq == seq) && | ||
2976 | time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) { | ||
2977 | if (*last_frag == frag) | ||
2978 | goto drop; | ||
2979 | if (*last_frag + 1 != frag) | ||
2980 | /* out-of-order fragment */ | ||
2981 | goto drop; | ||
2982 | } else | ||
2983 | *last_seq = seq; | ||
2984 | |||
2985 | *last_frag = frag; | ||
2986 | *last_time = jiffies; | ||
2987 | return 0; | ||
2988 | |||
2989 | drop: | ||
2990 | return 1; | ||
2991 | } | ||
2992 | |||
2993 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 2878 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
2994 | 2879 | ||
2995 | #include "iwl-spectrum.h" | 2880 | #include "iwl-spectrum.h" |
@@ -3241,7 +3126,7 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) | |||
3241 | struct sk_buff *beacon; | 3126 | struct sk_buff *beacon; |
3242 | 3127 | ||
3243 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ | 3128 | /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ |
3244 | beacon = ieee80211_beacon_get(priv->hw, priv->vif, NULL); | 3129 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); |
3245 | 3130 | ||
3246 | if (!beacon) { | 3131 | if (!beacon) { |
3247 | IWL_ERROR("update beacon failed\n"); | 3132 | IWL_ERROR("update beacon failed\n"); |
@@ -3276,7 +3161,7 @@ static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv, | |||
3276 | le32_to_cpu(beacon->low_tsf), rate); | 3161 | le32_to_cpu(beacon->low_tsf), rate); |
3277 | #endif | 3162 | #endif |
3278 | 3163 | ||
3279 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 3164 | if ((priv->iw_mode == NL80211_IFTYPE_AP) && |
3280 | (!test_bit(STATUS_EXIT_PENDING, &priv->status))) | 3165 | (!test_bit(STATUS_EXIT_PENDING, &priv->status))) |
3281 | queue_work(priv->workqueue, &priv->beacon_update); | 3166 | queue_work(priv->workqueue, &priv->beacon_update); |
3282 | } | 3167 | } |
@@ -3922,7 +3807,7 @@ int iwl3945_calc_db_from_ratio(int sig_ratio) | |||
3922 | /* 100:1 or higher, divide by 10 and use table, | 3807 | /* 100:1 or higher, divide by 10 and use table, |
3923 | * add 20 dB to make up for divide by 10 */ | 3808 | * add 20 dB to make up for divide by 10 */ |
3924 | if (sig_ratio >= 100) | 3809 | if (sig_ratio >= 100) |
3925 | return (20 + (int)ratio2dB[sig_ratio/10]); | 3810 | return 20 + (int)ratio2dB[sig_ratio/10]; |
3926 | 3811 | ||
3927 | /* We shouldn't see this */ | 3812 | /* We shouldn't see this */ |
3928 | if (sig_ratio < 1) | 3813 | if (sig_ratio < 1) |
@@ -4848,7 +4733,7 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
4848 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | 4733 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; |
4849 | ch_info->min_power = 0; | 4734 | ch_info->min_power = 0; |
4850 | 4735 | ||
4851 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x" | 4736 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" |
4852 | " %ddBm): Ad-Hoc %ssupported\n", | 4737 | " %ddBm): Ad-Hoc %ssupported\n", |
4853 | ch_info->channel, | 4738 | ch_info->channel, |
4854 | is_channel_a_band(ch_info) ? | 4739 | is_channel_a_band(ch_info) ? |
@@ -4858,7 +4743,6 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
4858 | CHECK_AND_PRINT(ACTIVE), | 4743 | CHECK_AND_PRINT(ACTIVE), |
4859 | CHECK_AND_PRINT(RADAR), | 4744 | CHECK_AND_PRINT(RADAR), |
4860 | CHECK_AND_PRINT(WIDE), | 4745 | CHECK_AND_PRINT(WIDE), |
4861 | CHECK_AND_PRINT(NARROW), | ||
4862 | CHECK_AND_PRINT(DFS), | 4746 | CHECK_AND_PRINT(DFS), |
4863 | eeprom_ch_info[ch].flags, | 4747 | eeprom_ch_info[ch].flags, |
4864 | eeprom_ch_info[ch].max_power_avg, | 4748 | eeprom_ch_info[ch].max_power_avg, |
@@ -4898,8 +4782,11 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
4898 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | 4782 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after |
4899 | * sending probe req. This should be set long enough to hear probe responses | 4783 | * sending probe req. This should be set long enough to hear probe responses |
4900 | * from more than one AP. */ | 4784 | * from more than one AP. */ |
4901 | #define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ | 4785 | #define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */ |
4902 | #define IWL_ACTIVE_DWELL_TIME_52 (10) | 4786 | #define IWL_ACTIVE_DWELL_TIME_52 (20) |
4787 | |||
4788 | #define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3) | ||
4789 | #define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2) | ||
4903 | 4790 | ||
4904 | /* For faster active scanning, scan will move to the next channel if fewer than | 4791 | /* For faster active scanning, scan will move to the next channel if fewer than |
4905 | * PLCP_QUIET_THRESH packets are heard on this channel within | 4792 | * PLCP_QUIET_THRESH packets are heard on this channel within |
@@ -4908,7 +4795,7 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
4908 | * no other traffic). | 4795 | * no other traffic). |
4909 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | 4796 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ |
4910 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | 4797 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ |
4911 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ | 4798 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */ |
4912 | 4799 | ||
4913 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | 4800 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. |
4914 | * Must be set longer than active dwell time. | 4801 | * Must be set longer than active dwell time. |
@@ -4918,19 +4805,23 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
4918 | #define IWL_PASSIVE_DWELL_BASE (100) | 4805 | #define IWL_PASSIVE_DWELL_BASE (100) |
4919 | #define IWL_CHANNEL_TUNE_TIME 5 | 4806 | #define IWL_CHANNEL_TUNE_TIME 5 |
4920 | 4807 | ||
4808 | #define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1)))) | ||
4809 | |||
4921 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, | 4810 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, |
4922 | enum ieee80211_band band) | 4811 | enum ieee80211_band band, |
4812 | u8 n_probes) | ||
4923 | { | 4813 | { |
4924 | if (band == IEEE80211_BAND_5GHZ) | 4814 | if (band == IEEE80211_BAND_5GHZ) |
4925 | return IWL_ACTIVE_DWELL_TIME_52; | 4815 | return IWL_ACTIVE_DWELL_TIME_52 + |
4816 | IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1); | ||
4926 | else | 4817 | else |
4927 | return IWL_ACTIVE_DWELL_TIME_24; | 4818 | return IWL_ACTIVE_DWELL_TIME_24 + |
4819 | IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1); | ||
4928 | } | 4820 | } |
4929 | 4821 | ||
4930 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, | 4822 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, |
4931 | enum ieee80211_band band) | 4823 | enum ieee80211_band band) |
4932 | { | 4824 | { |
4933 | u16 active = iwl3945_get_active_dwell_time(priv, band); | ||
4934 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? | 4825 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
4935 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 4826 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
4936 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 4827 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
@@ -4945,15 +4836,12 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, | |||
4945 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | 4836 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; |
4946 | } | 4837 | } |
4947 | 4838 | ||
4948 | if (passive <= active) | ||
4949 | passive = active + 1; | ||
4950 | |||
4951 | return passive; | 4839 | return passive; |
4952 | } | 4840 | } |
4953 | 4841 | ||
4954 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | 4842 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, |
4955 | enum ieee80211_band band, | 4843 | enum ieee80211_band band, |
4956 | u8 is_active, u8 direct_mask, | 4844 | u8 is_active, u8 n_probes, |
4957 | struct iwl3945_scan_channel *scan_ch) | 4845 | struct iwl3945_scan_channel *scan_ch) |
4958 | { | 4846 | { |
4959 | const struct ieee80211_channel *channels = NULL; | 4847 | const struct ieee80211_channel *channels = NULL; |
@@ -4969,9 +4857,12 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4969 | 4857 | ||
4970 | channels = sband->channels; | 4858 | channels = sband->channels; |
4971 | 4859 | ||
4972 | active_dwell = iwl3945_get_active_dwell_time(priv, band); | 4860 | active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes); |
4973 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); | 4861 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); |
4974 | 4862 | ||
4863 | if (passive_dwell <= active_dwell) | ||
4864 | passive_dwell = active_dwell + 1; | ||
4865 | |||
4975 | for (i = 0, added = 0; i < sband->n_channels; i++) { | 4866 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
4976 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | 4867 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) |
4977 | continue; | 4868 | continue; |
@@ -4991,11 +4882,8 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4991 | else | 4882 | else |
4992 | scan_ch->type = 1; /* active */ | 4883 | scan_ch->type = 1; /* active */ |
4993 | 4884 | ||
4994 | if (scan_ch->type & 1) | 4885 | if ((scan_ch->type & 1) && n_probes) |
4995 | scan_ch->type |= (direct_mask << 1); | 4886 | scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes); |
4996 | |||
4997 | if (is_channel_narrow(ch_info)) | ||
4998 | scan_ch->type |= (1 << 7); | ||
4999 | 4887 | ||
5000 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | 4888 | scan_ch->active_dwell = cpu_to_le16(active_dwell); |
5001 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | 4889 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); |
@@ -5201,7 +5089,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv) | |||
5201 | * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, | 5089 | * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, |
5202 | * looking at all data. | 5090 | * looking at all data. |
5203 | */ | 5091 | */ |
5204 | static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len) | 5092 | static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len) |
5205 | { | 5093 | { |
5206 | u32 val; | 5094 | u32 val; |
5207 | u32 save_len = len; | 5095 | u32 save_len = len; |
@@ -5350,7 +5238,7 @@ static int iwl3945_verify_bsm(struct iwl3945_priv *priv) | |||
5350 | val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG); | 5238 | val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG); |
5351 | for (reg = BSM_SRAM_LOWER_BOUND; | 5239 | for (reg = BSM_SRAM_LOWER_BOUND; |
5352 | reg < BSM_SRAM_LOWER_BOUND + len; | 5240 | reg < BSM_SRAM_LOWER_BOUND + len; |
5353 | reg += sizeof(u32), image ++) { | 5241 | reg += sizeof(u32), image++) { |
5354 | val = iwl3945_read_prph(priv, reg); | 5242 | val = iwl3945_read_prph(priv, reg); |
5355 | if (val != le32_to_cpu(*image)) { | 5243 | if (val != le32_to_cpu(*image)) { |
5356 | IWL_ERROR("BSM uCode verification failed at " | 5244 | IWL_ERROR("BSM uCode verification failed at " |
@@ -5843,7 +5731,7 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5843 | if (iwl3945_is_rfkill(priv)) | 5731 | if (iwl3945_is_rfkill(priv)) |
5844 | return; | 5732 | return; |
5845 | 5733 | ||
5846 | ieee80211_start_queues(priv->hw); | 5734 | ieee80211_wake_queues(priv->hw); |
5847 | 5735 | ||
5848 | priv->active_rate = priv->rates_mask; | 5736 | priv->active_rate = priv->rates_mask; |
5849 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 5737 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
@@ -5869,9 +5757,6 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv) | |||
5869 | /* Configure the adapter for unassociated operation */ | 5757 | /* Configure the adapter for unassociated operation */ |
5870 | iwl3945_commit_rxon(priv); | 5758 | iwl3945_commit_rxon(priv); |
5871 | 5759 | ||
5872 | /* At this point, the NIC is initialized and operational */ | ||
5873 | priv->notif_missed_beacons = 0; | ||
5874 | |||
5875 | iwl3945_reg_txpower_periodic(priv); | 5760 | iwl3945_reg_txpower_periodic(priv); |
5876 | 5761 | ||
5877 | iwl3945_led_register(priv); | 5762 | iwl3945_led_register(priv); |
@@ -5938,7 +5823,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5938 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 5823 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
5939 | STATUS_GEO_CONFIGURED | | 5824 | STATUS_GEO_CONFIGURED | |
5940 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5825 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5941 | STATUS_IN_SUSPEND; | 5826 | STATUS_IN_SUSPEND | |
5827 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5828 | STATUS_EXIT_PENDING; | ||
5942 | goto exit; | 5829 | goto exit; |
5943 | } | 5830 | } |
5944 | 5831 | ||
@@ -5953,7 +5840,9 @@ static void __iwl3945_down(struct iwl3945_priv *priv) | |||
5953 | test_bit(STATUS_IN_SUSPEND, &priv->status) << | 5840 | test_bit(STATUS_IN_SUSPEND, &priv->status) << |
5954 | STATUS_IN_SUSPEND | | 5841 | STATUS_IN_SUSPEND | |
5955 | test_bit(STATUS_FW_ERROR, &priv->status) << | 5842 | test_bit(STATUS_FW_ERROR, &priv->status) << |
5956 | STATUS_FW_ERROR; | 5843 | STATUS_FW_ERROR | |
5844 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||
5845 | STATUS_EXIT_PENDING; | ||
5957 | 5846 | ||
5958 | spin_lock_irqsave(&priv->lock, flags); | 5847 | spin_lock_irqsave(&priv->lock, flags); |
5959 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 5848 | iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
@@ -6085,6 +5974,7 @@ static int __iwl3945_up(struct iwl3945_priv *priv) | |||
6085 | 5974 | ||
6086 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 5975 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
6087 | __iwl3945_down(priv); | 5976 | __iwl3945_down(priv); |
5977 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||
6088 | 5978 | ||
6089 | /* tried to restart and config the device for as long as our | 5979 | /* tried to restart and config the device for as long as our |
6090 | * patience could withstand */ | 5980 | * patience could withstand */ |
@@ -6152,6 +6042,26 @@ static void iwl3945_bg_rf_kill(struct work_struct *work) | |||
6152 | "Kill switch must be turned off for " | 6042 | "Kill switch must be turned off for " |
6153 | "wireless networking to work.\n"); | 6043 | "wireless networking to work.\n"); |
6154 | } | 6044 | } |
6045 | |||
6046 | mutex_unlock(&priv->mutex); | ||
6047 | iwl3945_rfkill_set_hw_state(priv); | ||
6048 | } | ||
6049 | |||
6050 | static void iwl3945_bg_set_monitor(struct work_struct *work) | ||
6051 | { | ||
6052 | struct iwl3945_priv *priv = container_of(work, | ||
6053 | struct iwl3945_priv, set_monitor); | ||
6054 | |||
6055 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | ||
6056 | |||
6057 | mutex_lock(&priv->mutex); | ||
6058 | |||
6059 | if (!iwl3945_is_ready(priv)) | ||
6060 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
6061 | else | ||
6062 | if (iwl3945_set_mode(priv, NL80211_IFTYPE_MONITOR) != 0) | ||
6063 | IWL_ERROR("iwl3945_set_mode() failed\n"); | ||
6064 | |||
6155 | mutex_unlock(&priv->mutex); | 6065 | mutex_unlock(&priv->mutex); |
6156 | } | 6066 | } |
6157 | 6067 | ||
@@ -6190,7 +6100,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6190 | int rc = 0; | 6100 | int rc = 0; |
6191 | struct iwl3945_scan_cmd *scan; | 6101 | struct iwl3945_scan_cmd *scan; |
6192 | struct ieee80211_conf *conf = NULL; | 6102 | struct ieee80211_conf *conf = NULL; |
6193 | u8 direct_mask; | 6103 | u8 n_probes = 2; |
6194 | enum ieee80211_band band; | 6104 | enum ieee80211_band band; |
6195 | 6105 | ||
6196 | conf = ieee80211_get_hw_conf(priv->hw); | 6106 | conf = ieee80211_get_hw_conf(priv->hw); |
@@ -6298,7 +6208,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6298 | scan->direct_scan[0].len = priv->direct_ssid_len; | 6208 | scan->direct_scan[0].len = priv->direct_ssid_len; |
6299 | memcpy(scan->direct_scan[0].ssid, | 6209 | memcpy(scan->direct_scan[0].ssid, |
6300 | priv->direct_ssid, priv->direct_ssid_len); | 6210 | priv->direct_ssid, priv->direct_ssid_len); |
6301 | direct_mask = 1; | 6211 | n_probes++; |
6302 | } else if (!iwl3945_is_associated(priv) && priv->essid_len) { | 6212 | } else if (!iwl3945_is_associated(priv) && priv->essid_len) { |
6303 | IWL_DEBUG_SCAN | 6213 | IWL_DEBUG_SCAN |
6304 | ("Kicking off one direct scan for '%s' when not associated\n", | 6214 | ("Kicking off one direct scan for '%s' when not associated\n", |
@@ -6306,11 +6216,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6306 | scan->direct_scan[0].id = WLAN_EID_SSID; | 6216 | scan->direct_scan[0].id = WLAN_EID_SSID; |
6307 | scan->direct_scan[0].len = priv->essid_len; | 6217 | scan->direct_scan[0].len = priv->essid_len; |
6308 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | 6218 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); |
6309 | direct_mask = 1; | 6219 | n_probes++; |
6310 | } else { | 6220 | } else |
6311 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); | 6221 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); |
6312 | direct_mask = 0; | ||
6313 | } | ||
6314 | 6222 | ||
6315 | /* We don't build a direct scan probe request; the uCode will do | 6223 | /* We don't build a direct scan probe request; the uCode will do |
6316 | * that based on the direct_mask added to each channel entry */ | 6224 | * that based on the direct_mask added to each channel entry */ |
@@ -6340,21 +6248,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6340 | /* select Rx antennas */ | 6248 | /* select Rx antennas */ |
6341 | scan->flags |= iwl3945_get_antenna_flags(priv); | 6249 | scan->flags |= iwl3945_get_antenna_flags(priv); |
6342 | 6250 | ||
6343 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | 6251 | if (priv->iw_mode == NL80211_IFTYPE_MONITOR) |
6344 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 6252 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
6345 | 6253 | ||
6346 | if (direct_mask) | 6254 | scan->channel_count = |
6347 | scan->channel_count = | 6255 | iwl3945_get_channels_for_scan(priv, band, 1, /* active */ |
6348 | iwl3945_get_channels_for_scan( | 6256 | n_probes, |
6349 | priv, band, 1, /* active */ | 6257 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6350 | direct_mask, | ||
6351 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
6352 | else | ||
6353 | scan->channel_count = | ||
6354 | iwl3945_get_channels_for_scan( | ||
6355 | priv, band, 0, /* passive */ | ||
6356 | direct_mask, | ||
6357 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
6358 | 6258 | ||
6359 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 6259 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
6360 | scan->channel_count * sizeof(struct iwl3945_scan_channel); | 6260 | scan->channel_count * sizeof(struct iwl3945_scan_channel); |
@@ -6388,6 +6288,7 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
6388 | mutex_lock(&priv->mutex); | 6288 | mutex_lock(&priv->mutex); |
6389 | __iwl3945_up(priv); | 6289 | __iwl3945_up(priv); |
6390 | mutex_unlock(&priv->mutex); | 6290 | mutex_unlock(&priv->mutex); |
6291 | iwl3945_rfkill_set_hw_state(priv); | ||
6391 | } | 6292 | } |
6392 | 6293 | ||
6393 | static void iwl3945_bg_restart(struct work_struct *data) | 6294 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -6416,17 +6317,14 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
6416 | 6317 | ||
6417 | #define IWL_DELAY_NEXT_SCAN (HZ*2) | 6318 | #define IWL_DELAY_NEXT_SCAN (HZ*2) |
6418 | 6319 | ||
6419 | static void iwl3945_bg_post_associate(struct work_struct *data) | 6320 | static void iwl3945_post_associate(struct iwl3945_priv *priv) |
6420 | { | 6321 | { |
6421 | struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, | ||
6422 | post_associate.work); | ||
6423 | |||
6424 | int rc = 0; | 6322 | int rc = 0; |
6425 | struct ieee80211_conf *conf = NULL; | 6323 | struct ieee80211_conf *conf = NULL; |
6426 | DECLARE_MAC_BUF(mac); | 6324 | DECLARE_MAC_BUF(mac); |
6427 | 6325 | ||
6428 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 6326 | if (priv->iw_mode == NL80211_IFTYPE_AP) { |
6429 | IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__); | 6327 | IWL_ERROR("%s Should not be called in AP mode\n", __func__); |
6430 | return; | 6328 | return; |
6431 | } | 6329 | } |
6432 | 6330 | ||
@@ -6438,12 +6336,9 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6438 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 6336 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
6439 | return; | 6337 | return; |
6440 | 6338 | ||
6441 | mutex_lock(&priv->mutex); | 6339 | if (!priv->vif || !priv->is_open) |
6442 | |||
6443 | if (!priv->vif || !priv->is_open) { | ||
6444 | mutex_unlock(&priv->mutex); | ||
6445 | return; | 6340 | return; |
6446 | } | 6341 | |
6447 | iwl3945_scan_cancel_timeout(priv, 200); | 6342 | iwl3945_scan_cancel_timeout(priv, 200); |
6448 | 6343 | ||
6449 | conf = ieee80211_get_hw_conf(priv->hw); | 6344 | conf = ieee80211_get_hw_conf(priv->hw); |
@@ -6477,7 +6372,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6477 | else | 6372 | else |
6478 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 6373 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
6479 | 6374 | ||
6480 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 6375 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
6481 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 6376 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
6482 | 6377 | ||
6483 | } | 6378 | } |
@@ -6485,11 +6380,11 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6485 | iwl3945_commit_rxon(priv); | 6380 | iwl3945_commit_rxon(priv); |
6486 | 6381 | ||
6487 | switch (priv->iw_mode) { | 6382 | switch (priv->iw_mode) { |
6488 | case IEEE80211_IF_TYPE_STA: | 6383 | case NL80211_IFTYPE_STATION: |
6489 | iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); | 6384 | iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); |
6490 | break; | 6385 | break; |
6491 | 6386 | ||
6492 | case IEEE80211_IF_TYPE_IBSS: | 6387 | case NL80211_IFTYPE_ADHOC: |
6493 | 6388 | ||
6494 | /* clear out the station table */ | 6389 | /* clear out the station table */ |
6495 | iwl3945_clear_stations_table(priv); | 6390 | iwl3945_clear_stations_table(priv); |
@@ -6507,17 +6402,14 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6507 | 6402 | ||
6508 | default: | 6403 | default: |
6509 | IWL_ERROR("%s Should not be called in %d mode\n", | 6404 | IWL_ERROR("%s Should not be called in %d mode\n", |
6510 | __FUNCTION__, priv->iw_mode); | 6405 | __func__, priv->iw_mode); |
6511 | break; | 6406 | break; |
6512 | } | 6407 | } |
6513 | 6408 | ||
6514 | iwl3945_sequence_reset(priv); | ||
6515 | |||
6516 | iwl3945_activate_qos(priv, 0); | 6409 | iwl3945_activate_qos(priv, 0); |
6517 | 6410 | ||
6518 | /* we have just associated, don't start scan too early */ | 6411 | /* we have just associated, don't start scan too early */ |
6519 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 6412 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6520 | mutex_unlock(&priv->mutex); | ||
6521 | } | 6413 | } |
6522 | 6414 | ||
6523 | static void iwl3945_bg_abort_scan(struct work_struct *work) | 6415 | static void iwl3945_bg_abort_scan(struct work_struct *work) |
@@ -6608,6 +6500,8 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
6608 | 6500 | ||
6609 | mutex_unlock(&priv->mutex); | 6501 | mutex_unlock(&priv->mutex); |
6610 | 6502 | ||
6503 | iwl3945_rfkill_set_hw_state(priv); | ||
6504 | |||
6611 | if (ret) | 6505 | if (ret) |
6612 | goto out_release_irq; | 6506 | goto out_release_irq; |
6613 | 6507 | ||
@@ -6663,7 +6557,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) | |||
6663 | */ | 6557 | */ |
6664 | mutex_lock(&priv->mutex); | 6558 | mutex_lock(&priv->mutex); |
6665 | iwl3945_scan_cancel_timeout(priv, 100); | 6559 | iwl3945_scan_cancel_timeout(priv, 100); |
6666 | cancel_delayed_work(&priv->post_associate); | ||
6667 | mutex_unlock(&priv->mutex); | 6560 | mutex_unlock(&priv->mutex); |
6668 | } | 6561 | } |
6669 | 6562 | ||
@@ -6678,23 +6571,16 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) | |||
6678 | IWL_DEBUG_MAC80211("leave\n"); | 6571 | IWL_DEBUG_MAC80211("leave\n"); |
6679 | } | 6572 | } |
6680 | 6573 | ||
6681 | static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | 6574 | static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
6682 | struct ieee80211_tx_control *ctl) | ||
6683 | { | 6575 | { |
6684 | struct iwl3945_priv *priv = hw->priv; | 6576 | struct iwl3945_priv *priv = hw->priv; |
6685 | 6577 | ||
6686 | IWL_DEBUG_MAC80211("enter\n"); | 6578 | IWL_DEBUG_MAC80211("enter\n"); |
6687 | 6579 | ||
6688 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | ||
6689 | IWL_DEBUG_MAC80211("leave - monitor\n"); | ||
6690 | dev_kfree_skb_any(skb); | ||
6691 | return 0; | ||
6692 | } | ||
6693 | |||
6694 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6580 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
6695 | ctl->tx_rate->bitrate); | 6581 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); |
6696 | 6582 | ||
6697 | if (iwl3945_tx_skb(priv, skb, ctl)) | 6583 | if (iwl3945_tx_skb(priv, skb)) |
6698 | dev_kfree_skb_any(skb); | 6584 | dev_kfree_skb_any(skb); |
6699 | 6585 | ||
6700 | IWL_DEBUG_MAC80211("leave\n"); | 6586 | IWL_DEBUG_MAC80211("leave\n"); |
@@ -6753,8 +6639,6 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
6753 | mutex_lock(&priv->mutex); | 6639 | mutex_lock(&priv->mutex); |
6754 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); | 6640 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
6755 | 6641 | ||
6756 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | ||
6757 | |||
6758 | if (!iwl3945_is_ready(priv)) { | 6642 | if (!iwl3945_is_ready(priv)) { |
6759 | IWL_DEBUG_MAC80211("leave - not ready\n"); | 6643 | IWL_DEBUG_MAC80211("leave - not ready\n"); |
6760 | ret = -EIO; | 6644 | ret = -EIO; |
@@ -6837,7 +6721,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6837 | return; | 6721 | return; |
6838 | 6722 | ||
6839 | /* The following should be done only at AP bring up */ | 6723 | /* The following should be done only at AP bring up */ |
6840 | if ((priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) == 0) { | 6724 | if (!(iwl3945_is_associated(priv))) { |
6841 | 6725 | ||
6842 | /* RXON - unassoc (to set timing command) */ | 6726 | /* RXON - unassoc (to set timing command) */ |
6843 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 6727 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
@@ -6870,7 +6754,7 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6870 | priv->staging_rxon.flags &= | 6754 | priv->staging_rxon.flags &= |
6871 | ~RXON_FLG_SHORT_SLOT_MSK; | 6755 | ~RXON_FLG_SHORT_SLOT_MSK; |
6872 | 6756 | ||
6873 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 6757 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC) |
6874 | priv->staging_rxon.flags &= | 6758 | priv->staging_rxon.flags &= |
6875 | ~RXON_FLG_SHORT_SLOT_MSK; | 6759 | ~RXON_FLG_SHORT_SLOT_MSK; |
6876 | } | 6760 | } |
@@ -6886,6 +6770,9 @@ static void iwl3945_config_ap(struct iwl3945_priv *priv) | |||
6886 | * clear sta table, add BCAST sta... */ | 6770 | * clear sta table, add BCAST sta... */ |
6887 | } | 6771 | } |
6888 | 6772 | ||
6773 | /* temporary */ | ||
6774 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
6775 | |||
6889 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | 6776 | static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, |
6890 | struct ieee80211_vif *vif, | 6777 | struct ieee80211_vif *vif, |
6891 | struct ieee80211_if_conf *conf) | 6778 | struct ieee80211_if_conf *conf) |
@@ -6903,10 +6790,21 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6903 | return 0; | 6790 | return 0; |
6904 | } | 6791 | } |
6905 | 6792 | ||
6793 | /* handle this temporarily here */ | ||
6794 | if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | ||
6795 | conf->changed & IEEE80211_IFCC_BEACON) { | ||
6796 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | ||
6797 | if (!beacon) | ||
6798 | return -ENOMEM; | ||
6799 | rc = iwl3945_mac_beacon_update(hw, beacon); | ||
6800 | if (rc) | ||
6801 | return rc; | ||
6802 | } | ||
6803 | |||
6906 | /* XXX: this MUST use conf->mac_addr */ | 6804 | /* XXX: this MUST use conf->mac_addr */ |
6907 | 6805 | ||
6908 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 6806 | if ((priv->iw_mode == NL80211_IFTYPE_AP) && |
6909 | (!conf->beacon || !conf->ssid_len)) { | 6807 | (!conf->ssid_len)) { |
6910 | IWL_DEBUG_MAC80211 | 6808 | IWL_DEBUG_MAC80211 |
6911 | ("Leaving in AP mode because HostAPD is not ready.\n"); | 6809 | ("Leaving in AP mode because HostAPD is not ready.\n"); |
6912 | return 0; | 6810 | return 0; |
@@ -6928,7 +6826,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6928 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { | 6826 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { |
6929 | */ | 6827 | */ |
6930 | 6828 | ||
6931 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 6829 | if (priv->iw_mode == NL80211_IFTYPE_AP) { |
6932 | if (!conf->bssid) { | 6830 | if (!conf->bssid) { |
6933 | conf->bssid = priv->mac_addr; | 6831 | conf->bssid = priv->mac_addr; |
6934 | memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); | 6832 | memcpy(priv->bssid, priv->mac_addr, ETH_ALEN); |
@@ -6938,7 +6836,7 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6938 | if (priv->ibss_beacon) | 6836 | if (priv->ibss_beacon) |
6939 | dev_kfree_skb(priv->ibss_beacon); | 6837 | dev_kfree_skb(priv->ibss_beacon); |
6940 | 6838 | ||
6941 | priv->ibss_beacon = conf->beacon; | 6839 | priv->ibss_beacon = ieee80211_beacon_get(hw, vif); |
6942 | } | 6840 | } |
6943 | 6841 | ||
6944 | if (iwl3945_is_rfkill(priv)) | 6842 | if (iwl3945_is_rfkill(priv)) |
@@ -6963,11 +6861,11 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
6963 | * to verify) - jpk */ | 6861 | * to verify) - jpk */ |
6964 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); | 6862 | memcpy(priv->bssid, conf->bssid, ETH_ALEN); |
6965 | 6863 | ||
6966 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | 6864 | if (priv->iw_mode == NL80211_IFTYPE_AP) |
6967 | iwl3945_config_ap(priv); | 6865 | iwl3945_config_ap(priv); |
6968 | else { | 6866 | else { |
6969 | rc = iwl3945_commit_rxon(priv); | 6867 | rc = iwl3945_commit_rxon(priv); |
6970 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) | 6868 | if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc) |
6971 | iwl3945_add_station(priv, | 6869 | iwl3945_add_station(priv, |
6972 | priv->active_rxon.bssid_addr, 1, 0); | 6870 | priv->active_rxon.bssid_addr, 1, 0); |
6973 | } | 6871 | } |
@@ -6999,11 +6897,18 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, | |||
6999 | unsigned int *total_flags, | 6897 | unsigned int *total_flags, |
7000 | int mc_count, struct dev_addr_list *mc_list) | 6898 | int mc_count, struct dev_addr_list *mc_list) |
7001 | { | 6899 | { |
7002 | /* | 6900 | struct iwl3945_priv *priv = hw->priv; |
7003 | * XXX: dummy | 6901 | |
7004 | * see also iwl3945_connection_init_rx_config | 6902 | if (changed_flags & (*total_flags) & FIF_OTHER_BSS) { |
7005 | */ | 6903 | IWL_DEBUG_MAC80211("Enter: type %d (0x%x, 0x%x)\n", |
7006 | *total_flags = 0; | 6904 | NL80211_IFTYPE_MONITOR, |
6905 | changed_flags, *total_flags); | ||
6906 | /* queue work 'cuz mac80211 is holding a lock which | ||
6907 | * prevents us from issuing (synchronous) f/w cmds */ | ||
6908 | queue_work(priv->workqueue, &priv->set_monitor); | ||
6909 | } | ||
6910 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | | ||
6911 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
7007 | } | 6912 | } |
7008 | 6913 | ||
7009 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | 6914 | static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -7017,7 +6922,6 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | |||
7017 | 6922 | ||
7018 | if (iwl3945_is_ready_rf(priv)) { | 6923 | if (iwl3945_is_ready_rf(priv)) { |
7019 | iwl3945_scan_cancel_timeout(priv, 100); | 6924 | iwl3945_scan_cancel_timeout(priv, 100); |
7020 | cancel_delayed_work(&priv->post_associate); | ||
7021 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 6925 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
7022 | iwl3945_commit_rxon(priv); | 6926 | iwl3945_commit_rxon(priv); |
7023 | } | 6927 | } |
@@ -7032,6 +6936,63 @@ static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, | |||
7032 | IWL_DEBUG_MAC80211("leave\n"); | 6936 | IWL_DEBUG_MAC80211("leave\n"); |
7033 | } | 6937 | } |
7034 | 6938 | ||
6939 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | ||
6940 | |||
6941 | static void iwl3945_bss_info_changed(struct ieee80211_hw *hw, | ||
6942 | struct ieee80211_vif *vif, | ||
6943 | struct ieee80211_bss_conf *bss_conf, | ||
6944 | u32 changes) | ||
6945 | { | ||
6946 | struct iwl3945_priv *priv = hw->priv; | ||
6947 | |||
6948 | IWL_DEBUG_MAC80211("changes = 0x%X\n", changes); | ||
6949 | |||
6950 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
6951 | IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n", | ||
6952 | bss_conf->use_short_preamble); | ||
6953 | if (bss_conf->use_short_preamble) | ||
6954 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | ||
6955 | else | ||
6956 | priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; | ||
6957 | } | ||
6958 | |||
6959 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | ||
6960 | IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot); | ||
6961 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) | ||
6962 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | ||
6963 | else | ||
6964 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | ||
6965 | } | ||
6966 | |||
6967 | if (changes & BSS_CHANGED_ASSOC) { | ||
6968 | IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc); | ||
6969 | /* This should never happen as this function should | ||
6970 | * never be called from interrupt context. */ | ||
6971 | if (WARN_ON_ONCE(in_interrupt())) | ||
6972 | return; | ||
6973 | if (bss_conf->assoc) { | ||
6974 | priv->assoc_id = bss_conf->aid; | ||
6975 | priv->beacon_int = bss_conf->beacon_int; | ||
6976 | priv->timestamp0 = bss_conf->timestamp & 0xFFFFFFFF; | ||
6977 | priv->timestamp1 = (bss_conf->timestamp >> 32) & | ||
6978 | 0xFFFFFFFF; | ||
6979 | priv->assoc_capability = bss_conf->assoc_capability; | ||
6980 | priv->next_scan_jiffies = jiffies + | ||
6981 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | ||
6982 | mutex_lock(&priv->mutex); | ||
6983 | iwl3945_post_associate(priv); | ||
6984 | mutex_unlock(&priv->mutex); | ||
6985 | } else { | ||
6986 | priv->assoc_id = 0; | ||
6987 | IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc); | ||
6988 | } | ||
6989 | } else if (changes && iwl3945_is_associated(priv) && priv->assoc_id) { | ||
6990 | IWL_DEBUG_MAC80211("Associated Changes %d\n", changes); | ||
6991 | iwl3945_send_rxon_assoc(priv); | ||
6992 | } | ||
6993 | |||
6994 | } | ||
6995 | |||
7035 | static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | 6996 | static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) |
7036 | { | 6997 | { |
7037 | int rc = 0; | 6998 | int rc = 0; |
@@ -7049,7 +7010,7 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
7049 | goto out_unlock; | 7010 | goto out_unlock; |
7050 | } | 7011 | } |
7051 | 7012 | ||
7052 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { /* APs don't scan */ | 7013 | if (priv->iw_mode == NL80211_IFTYPE_AP) { /* APs don't scan */ |
7053 | rc = -EIO; | 7014 | rc = -EIO; |
7054 | IWL_ERROR("ERROR: APs don't scan\n"); | 7015 | IWL_ERROR("ERROR: APs don't scan\n"); |
7055 | goto out_unlock; | 7016 | goto out_unlock; |
@@ -7061,9 +7022,10 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
7061 | rc = -EAGAIN; | 7022 | rc = -EAGAIN; |
7062 | goto out_unlock; | 7023 | goto out_unlock; |
7063 | } | 7024 | } |
7064 | /* if we just finished scan ask for delay */ | 7025 | /* if we just finished scan ask for delay for a broadcast scan */ |
7065 | if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + | 7026 | if ((len == 0) && priv->last_scan_jiffies && |
7066 | IWL_DELAY_NEXT_SCAN, jiffies)) { | 7027 | time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, |
7028 | jiffies)) { | ||
7067 | rc = -EAGAIN; | 7029 | rc = -EAGAIN; |
7068 | goto out_unlock; | 7030 | goto out_unlock; |
7069 | } | 7031 | } |
@@ -7150,7 +7112,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
7150 | return rc; | 7112 | return rc; |
7151 | } | 7113 | } |
7152 | 7114 | ||
7153 | static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | 7115 | static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, |
7154 | const struct ieee80211_tx_queue_params *params) | 7116 | const struct ieee80211_tx_queue_params *params) |
7155 | { | 7117 | { |
7156 | struct iwl3945_priv *priv = hw->priv; | 7118 | struct iwl3945_priv *priv = hw->priv; |
@@ -7190,7 +7152,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7190 | spin_unlock_irqrestore(&priv->lock, flags); | 7152 | spin_unlock_irqrestore(&priv->lock, flags); |
7191 | 7153 | ||
7192 | mutex_lock(&priv->mutex); | 7154 | mutex_lock(&priv->mutex); |
7193 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) | 7155 | if (priv->iw_mode == NL80211_IFTYPE_AP) |
7194 | iwl3945_activate_qos(priv, 1); | 7156 | iwl3945_activate_qos(priv, 1); |
7195 | else if (priv->assoc_id && iwl3945_is_associated(priv)) | 7157 | else if (priv->assoc_id && iwl3945_is_associated(priv)) |
7196 | iwl3945_activate_qos(priv, 0); | 7158 | iwl3945_activate_qos(priv, 0); |
@@ -7224,9 +7186,9 @@ static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, | |||
7224 | q = &txq->q; | 7186 | q = &txq->q; |
7225 | avail = iwl3945_queue_space(q); | 7187 | avail = iwl3945_queue_space(q); |
7226 | 7188 | ||
7227 | stats->data[i].len = q->n_window - avail; | 7189 | stats[i].len = q->n_window - avail; |
7228 | stats->data[i].limit = q->n_window - q->high_mark; | 7190 | stats[i].limit = q->n_window - q->high_mark; |
7229 | stats->data[i].count = q->n_window; | 7191 | stats[i].count = q->n_window; |
7230 | 7192 | ||
7231 | } | 7193 | } |
7232 | spin_unlock_irqrestore(&priv->lock, flags); | 7194 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -7263,8 +7225,6 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7263 | 7225 | ||
7264 | iwl3945_reset_qos(priv); | 7226 | iwl3945_reset_qos(priv); |
7265 | 7227 | ||
7266 | cancel_delayed_work(&priv->post_associate); | ||
7267 | |||
7268 | spin_lock_irqsave(&priv->lock, flags); | 7228 | spin_lock_irqsave(&priv->lock, flags); |
7269 | priv->assoc_id = 0; | 7229 | priv->assoc_id = 0; |
7270 | priv->assoc_capability = 0; | 7230 | priv->assoc_capability = 0; |
@@ -7279,7 +7239,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7279 | priv->beacon_int = priv->hw->conf.beacon_int; | 7239 | priv->beacon_int = priv->hw->conf.beacon_int; |
7280 | priv->timestamp1 = 0; | 7240 | priv->timestamp1 = 0; |
7281 | priv->timestamp0 = 0; | 7241 | priv->timestamp0 = 0; |
7282 | if ((priv->iw_mode == IEEE80211_IF_TYPE_STA)) | 7242 | if ((priv->iw_mode == NL80211_IFTYPE_STATION)) |
7283 | priv->beacon_int = 0; | 7243 | priv->beacon_int = 0; |
7284 | 7244 | ||
7285 | spin_unlock_irqrestore(&priv->lock, flags); | 7245 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -7293,14 +7253,14 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7293 | /* we are restarting association process | 7253 | /* we are restarting association process |
7294 | * clear RXON_FILTER_ASSOC_MSK bit | 7254 | * clear RXON_FILTER_ASSOC_MSK bit |
7295 | */ | 7255 | */ |
7296 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | 7256 | if (priv->iw_mode != NL80211_IFTYPE_AP) { |
7297 | iwl3945_scan_cancel_timeout(priv, 100); | 7257 | iwl3945_scan_cancel_timeout(priv, 100); |
7298 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 7258 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
7299 | iwl3945_commit_rxon(priv); | 7259 | iwl3945_commit_rxon(priv); |
7300 | } | 7260 | } |
7301 | 7261 | ||
7302 | /* Per mac80211.h: This is only used in IBSS mode... */ | 7262 | /* Per mac80211.h: This is only used in IBSS mode... */ |
7303 | if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { | 7263 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { |
7304 | 7264 | ||
7305 | IWL_DEBUG_MAC80211("leave - not in IBSS\n"); | 7265 | IWL_DEBUG_MAC80211("leave - not in IBSS\n"); |
7306 | mutex_unlock(&priv->mutex); | 7266 | mutex_unlock(&priv->mutex); |
@@ -7315,8 +7275,7 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7315 | 7275 | ||
7316 | } | 7276 | } |
7317 | 7277 | ||
7318 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 7278 | static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
7319 | struct ieee80211_tx_control *control) | ||
7320 | { | 7279 | { |
7321 | struct iwl3945_priv *priv = hw->priv; | 7280 | struct iwl3945_priv *priv = hw->priv; |
7322 | unsigned long flags; | 7281 | unsigned long flags; |
@@ -7330,7 +7289,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7330 | return -EIO; | 7289 | return -EIO; |
7331 | } | 7290 | } |
7332 | 7291 | ||
7333 | if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) { | 7292 | if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { |
7334 | IWL_DEBUG_MAC80211("leave - not IBSS\n"); | 7293 | IWL_DEBUG_MAC80211("leave - not IBSS\n"); |
7335 | mutex_unlock(&priv->mutex); | 7294 | mutex_unlock(&priv->mutex); |
7336 | return -EIO; | 7295 | return -EIO; |
@@ -7350,7 +7309,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7350 | 7309 | ||
7351 | iwl3945_reset_qos(priv); | 7310 | iwl3945_reset_qos(priv); |
7352 | 7311 | ||
7353 | queue_work(priv->workqueue, &priv->post_associate.work); | 7312 | iwl3945_post_associate(priv); |
7354 | 7313 | ||
7355 | mutex_unlock(&priv->mutex); | 7314 | mutex_unlock(&priv->mutex); |
7356 | 7315 | ||
@@ -7398,37 +7357,6 @@ static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, | |||
7398 | 7357 | ||
7399 | #endif /* CONFIG_IWL3945_DEBUG */ | 7358 | #endif /* CONFIG_IWL3945_DEBUG */ |
7400 | 7359 | ||
7401 | static ssize_t show_rf_kill(struct device *d, | ||
7402 | struct device_attribute *attr, char *buf) | ||
7403 | { | ||
7404 | /* | ||
7405 | * 0 - RF kill not enabled | ||
7406 | * 1 - SW based RF kill active (sysfs) | ||
7407 | * 2 - HW based RF kill active | ||
7408 | * 3 - Both HW and SW based RF kill active | ||
7409 | */ | ||
7410 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7411 | int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | | ||
7412 | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); | ||
7413 | |||
7414 | return sprintf(buf, "%i\n", val); | ||
7415 | } | ||
7416 | |||
7417 | static ssize_t store_rf_kill(struct device *d, | ||
7418 | struct device_attribute *attr, | ||
7419 | const char *buf, size_t count) | ||
7420 | { | ||
7421 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7422 | |||
7423 | mutex_lock(&priv->mutex); | ||
7424 | iwl3945_radio_kill_sw(priv, buf[0] == '1'); | ||
7425 | mutex_unlock(&priv->mutex); | ||
7426 | |||
7427 | return count; | ||
7428 | } | ||
7429 | |||
7430 | static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); | ||
7431 | |||
7432 | static ssize_t show_temperature(struct device *d, | 7360 | static ssize_t show_temperature(struct device *d, |
7433 | struct device_attribute *attr, char *buf) | 7361 | struct device_attribute *attr, char *buf) |
7434 | { | 7362 | { |
@@ -7442,15 +7370,6 @@ static ssize_t show_temperature(struct device *d, | |||
7442 | 7370 | ||
7443 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | 7371 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); |
7444 | 7372 | ||
7445 | static ssize_t show_rs_window(struct device *d, | ||
7446 | struct device_attribute *attr, | ||
7447 | char *buf) | ||
7448 | { | ||
7449 | struct iwl3945_priv *priv = d->driver_data; | ||
7450 | return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID); | ||
7451 | } | ||
7452 | static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL); | ||
7453 | |||
7454 | static ssize_t show_tx_power(struct device *d, | 7373 | static ssize_t show_tx_power(struct device *d, |
7455 | struct device_attribute *attr, char *buf) | 7374 | struct device_attribute *attr, char *buf) |
7456 | { | 7375 | { |
@@ -7557,7 +7476,7 @@ static ssize_t show_measurement(struct device *d, | |||
7557 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 7476 | struct iwl3945_priv *priv = dev_get_drvdata(d); |
7558 | struct iwl3945_spectrum_notification measure_report; | 7477 | struct iwl3945_spectrum_notification measure_report; |
7559 | u32 size = sizeof(measure_report), len = 0, ofs = 0; | 7478 | u32 size = sizeof(measure_report), len = 0, ofs = 0; |
7560 | u8 *data = (u8 *) & measure_report; | 7479 | u8 *data = (u8 *)&measure_report; |
7561 | unsigned long flags; | 7480 | unsigned long flags; |
7562 | 7481 | ||
7563 | spin_lock_irqsave(&priv->lock, flags); | 7482 | spin_lock_irqsave(&priv->lock, flags); |
@@ -7728,7 +7647,7 @@ static ssize_t show_power_level(struct device *d, | |||
7728 | else | 7647 | else |
7729 | p += sprintf(p, " \n"); | 7648 | p += sprintf(p, " \n"); |
7730 | 7649 | ||
7731 | return (p - buf + 1); | 7650 | return p - buf + 1; |
7732 | 7651 | ||
7733 | } | 7652 | } |
7734 | 7653 | ||
@@ -7750,7 +7669,7 @@ static ssize_t show_statistics(struct device *d, | |||
7750 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 7669 | struct iwl3945_priv *priv = dev_get_drvdata(d); |
7751 | u32 size = sizeof(struct iwl3945_notif_statistics); | 7670 | u32 size = sizeof(struct iwl3945_notif_statistics); |
7752 | u32 len = 0, ofs = 0; | 7671 | u32 len = 0, ofs = 0; |
7753 | u8 *data = (u8 *) & priv->statistics; | 7672 | u8 *data = (u8 *)&priv->statistics; |
7754 | int rc = 0; | 7673 | int rc = 0; |
7755 | 7674 | ||
7756 | if (!iwl3945_is_alive(priv)) | 7675 | if (!iwl3945_is_alive(priv)) |
@@ -7879,7 +7798,7 @@ static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) | |||
7879 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); | 7798 | INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); |
7880 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); | 7799 | INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); |
7881 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 7800 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
7882 | INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate); | 7801 | INIT_WORK(&priv->set_monitor, iwl3945_bg_set_monitor); |
7883 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 7802 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
7884 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 7803 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
7885 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); | 7804 | INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); |
@@ -7897,7 +7816,6 @@ static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv) | |||
7897 | cancel_delayed_work_sync(&priv->init_alive_start); | 7816 | cancel_delayed_work_sync(&priv->init_alive_start); |
7898 | cancel_delayed_work(&priv->scan_check); | 7817 | cancel_delayed_work(&priv->scan_check); |
7899 | cancel_delayed_work(&priv->alive_start); | 7818 | cancel_delayed_work(&priv->alive_start); |
7900 | cancel_delayed_work(&priv->post_associate); | ||
7901 | cancel_work_sync(&priv->beacon_update); | 7819 | cancel_work_sync(&priv->beacon_update); |
7902 | } | 7820 | } |
7903 | 7821 | ||
@@ -7913,8 +7831,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
7913 | #endif | 7831 | #endif |
7914 | &dev_attr_power_level.attr, | 7832 | &dev_attr_power_level.attr, |
7915 | &dev_attr_retry_rate.attr, | 7833 | &dev_attr_retry_rate.attr, |
7916 | &dev_attr_rf_kill.attr, | ||
7917 | &dev_attr_rs_window.attr, | ||
7918 | &dev_attr_statistics.attr, | 7834 | &dev_attr_statistics.attr, |
7919 | &dev_attr_status.attr, | 7835 | &dev_attr_status.attr, |
7920 | &dev_attr_temperature.attr, | 7836 | &dev_attr_temperature.attr, |
@@ -7943,7 +7859,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
7943 | .conf_tx = iwl3945_mac_conf_tx, | 7859 | .conf_tx = iwl3945_mac_conf_tx, |
7944 | .get_tsf = iwl3945_mac_get_tsf, | 7860 | .get_tsf = iwl3945_mac_get_tsf, |
7945 | .reset_tsf = iwl3945_mac_reset_tsf, | 7861 | .reset_tsf = iwl3945_mac_reset_tsf, |
7946 | .beacon_update = iwl3945_mac_beacon_update, | 7862 | .bss_info_changed = iwl3945_bss_info_changed, |
7947 | .hw_scan = iwl3945_mac_hw_scan | 7863 | .hw_scan = iwl3945_mac_hw_scan |
7948 | }; | 7864 | }; |
7949 | 7865 | ||
@@ -7953,7 +7869,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7953 | struct iwl3945_priv *priv; | 7869 | struct iwl3945_priv *priv; |
7954 | struct ieee80211_hw *hw; | 7870 | struct ieee80211_hw *hw; |
7955 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); | 7871 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); |
7956 | int i; | ||
7957 | unsigned long flags; | 7872 | unsigned long flags; |
7958 | DECLARE_MAC_BUF(mac); | 7873 | DECLARE_MAC_BUF(mac); |
7959 | 7874 | ||
@@ -7983,6 +7898,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
7983 | SET_IEEE80211_DEV(hw, &pdev->dev); | 7898 | SET_IEEE80211_DEV(hw, &pdev->dev); |
7984 | 7899 | ||
7985 | hw->rate_control_algorithm = "iwl-3945-rs"; | 7900 | hw->rate_control_algorithm = "iwl-3945-rs"; |
7901 | hw->sta_data_size = sizeof(struct iwl3945_sta_priv); | ||
7986 | 7902 | ||
7987 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); | 7903 | IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); |
7988 | priv = hw->priv; | 7904 | priv = hw->priv; |
@@ -8001,17 +7917,14 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8001 | 7917 | ||
8002 | priv->ibss_beacon = NULL; | 7918 | priv->ibss_beacon = NULL; |
8003 | 7919 | ||
8004 | /* Tell mac80211 and its clients (e.g. Wireless Extensions) | 7920 | /* Tell mac80211 our characteristics */ |
8005 | * the range of signal quality values that we'll provide. | 7921 | hw->flags = IEEE80211_HW_SIGNAL_DBM | |
8006 | * Negative values for level/noise indicate that we'll provide dBm. | 7922 | IEEE80211_HW_NOISE_DBM; |
8007 | * For WE, at least, non-0 values here *enable* display of values | ||
8008 | * in app (iwconfig). */ | ||
8009 | hw->max_rssi = -20; /* signal level, negative indicates dBm */ | ||
8010 | hw->max_noise = -20; /* noise level, negative indicates dBm */ | ||
8011 | hw->max_signal = 100; /* link quality indication (%) */ | ||
8012 | 7923 | ||
8013 | /* Tell mac80211 our Tx characteristics */ | 7924 | hw->wiphy->interface_modes = |
8014 | hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; | 7925 | BIT(NL80211_IFTYPE_AP) | |
7926 | BIT(NL80211_IFTYPE_STATION) | | ||
7927 | BIT(NL80211_IFTYPE_ADHOC); | ||
8015 | 7928 | ||
8016 | /* 4 EDCA QOS priorities */ | 7929 | /* 4 EDCA QOS priorities */ |
8017 | hw->queues = 4; | 7930 | hw->queues = 4; |
@@ -8021,9 +7934,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8021 | spin_lock_init(&priv->sta_lock); | 7934 | spin_lock_init(&priv->sta_lock); |
8022 | spin_lock_init(&priv->hcmd_lock); | 7935 | spin_lock_init(&priv->hcmd_lock); |
8023 | 7936 | ||
8024 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) | ||
8025 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | ||
8026 | |||
8027 | INIT_LIST_HEAD(&priv->free_frames); | 7937 | INIT_LIST_HEAD(&priv->free_frames); |
8028 | 7938 | ||
8029 | mutex_init(&priv->mutex); | 7939 | mutex_init(&priv->mutex); |
@@ -8077,7 +7987,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8077 | IWL_DEBUG_INFO("Radio disabled.\n"); | 7987 | IWL_DEBUG_INFO("Radio disabled.\n"); |
8078 | } | 7988 | } |
8079 | 7989 | ||
8080 | priv->iw_mode = IEEE80211_IF_TYPE_STA; | 7990 | priv->iw_mode = NL80211_IFTYPE_STATION; |
8081 | 7991 | ||
8082 | printk(KERN_INFO DRV_NAME | 7992 | printk(KERN_INFO DRV_NAME |
8083 | ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); | 7993 | ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); |
@@ -8117,16 +8027,16 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8117 | 8027 | ||
8118 | /* nic init */ | 8028 | /* nic init */ |
8119 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 8029 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
8120 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); | 8030 | CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); |
8121 | 8031 | ||
8122 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 8032 | iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
8123 | err = iwl3945_poll_bit(priv, CSR_GP_CNTRL, | 8033 | err = iwl3945_poll_bit(priv, CSR_GP_CNTRL, |
8124 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, | 8034 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, |
8125 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); | 8035 | CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); |
8126 | if (err < 0) { | 8036 | if (err < 0) { |
8127 | IWL_DEBUG_INFO("Failed to init the card\n"); | 8037 | IWL_DEBUG_INFO("Failed to init the card\n"); |
8128 | goto out_remove_sysfs; | 8038 | goto out_remove_sysfs; |
8129 | } | 8039 | } |
8130 | /* Read the EEPROM */ | 8040 | /* Read the EEPROM */ |
8131 | err = iwl3945_eeprom_init(priv); | 8041 | err = iwl3945_eeprom_init(priv); |
8132 | if (err) { | 8042 | if (err) { |
@@ -8161,6 +8071,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8161 | pci_save_state(pdev); | 8071 | pci_save_state(pdev); |
8162 | pci_disable_device(pdev); | 8072 | pci_disable_device(pdev); |
8163 | 8073 | ||
8074 | err = iwl3945_rfkill_init(priv); | ||
8075 | if (err) | ||
8076 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
8077 | "Ignoring error: %d\n", err); | ||
8078 | |||
8164 | return 0; | 8079 | return 0; |
8165 | 8080 | ||
8166 | out_free_geos: | 8081 | out_free_geos: |
@@ -8191,8 +8106,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8191 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | 8106 | static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) |
8192 | { | 8107 | { |
8193 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); | 8108 | struct iwl3945_priv *priv = pci_get_drvdata(pdev); |
8194 | struct list_head *p, *q; | ||
8195 | int i; | ||
8196 | unsigned long flags; | 8109 | unsigned long flags; |
8197 | 8110 | ||
8198 | if (!priv) | 8111 | if (!priv) |
@@ -8213,16 +8126,9 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8213 | 8126 | ||
8214 | iwl_synchronize_irq(priv); | 8127 | iwl_synchronize_irq(priv); |
8215 | 8128 | ||
8216 | /* Free MAC hash list for ADHOC */ | ||
8217 | for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { | ||
8218 | list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { | ||
8219 | list_del(p); | ||
8220 | kfree(list_entry(p, struct iwl3945_ibss_seq, list)); | ||
8221 | } | ||
8222 | } | ||
8223 | |||
8224 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 8129 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
8225 | 8130 | ||
8131 | iwl3945_rfkill_unregister(priv); | ||
8226 | iwl3945_dealloc_ucode_pci(priv); | 8132 | iwl3945_dealloc_ucode_pci(priv); |
8227 | 8133 | ||
8228 | if (priv->rxq.bd) | 8134 | if (priv->rxq.bd) |
@@ -8232,9 +8138,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8232 | iwl3945_unset_hw_setting(priv); | 8138 | iwl3945_unset_hw_setting(priv); |
8233 | iwl3945_clear_stations_table(priv); | 8139 | iwl3945_clear_stations_table(priv); |
8234 | 8140 | ||
8235 | if (priv->mac80211_registered) { | 8141 | if (priv->mac80211_registered) |
8236 | ieee80211_unregister_hw(priv->hw); | 8142 | ieee80211_unregister_hw(priv->hw); |
8237 | } | ||
8238 | 8143 | ||
8239 | /*netif_stop_queue(dev); */ | 8144 | /*netif_stop_queue(dev); */ |
8240 | flush_workqueue(priv->workqueue); | 8145 | flush_workqueue(priv->workqueue); |
@@ -8252,7 +8157,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
8252 | 8157 | ||
8253 | iwl3945_free_channel_map(priv); | 8158 | iwl3945_free_channel_map(priv); |
8254 | iwl3945_free_geos(priv); | 8159 | iwl3945_free_geos(priv); |
8255 | 8160 | kfree(priv->scan); | |
8256 | if (priv->ibss_beacon) | 8161 | if (priv->ibss_beacon) |
8257 | dev_kfree_skb(priv->ibss_beacon); | 8162 | dev_kfree_skb(priv->ibss_beacon); |
8258 | 8163 | ||
@@ -8291,6 +8196,114 @@ static int iwl3945_pci_resume(struct pci_dev *pdev) | |||
8291 | 8196 | ||
8292 | #endif /* CONFIG_PM */ | 8197 | #endif /* CONFIG_PM */ |
8293 | 8198 | ||
8199 | /*************** RFKILL FUNCTIONS **********/ | ||
8200 | #ifdef CONFIG_IWL3945_RFKILL | ||
8201 | /* software rf-kill from user */ | ||
8202 | static int iwl3945_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
8203 | { | ||
8204 | struct iwl3945_priv *priv = data; | ||
8205 | int err = 0; | ||
8206 | |||
8207 | if (!priv->rfkill) | ||
8208 | return 0; | ||
8209 | |||
8210 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
8211 | return 0; | ||
8212 | |||
8213 | IWL_DEBUG_RF_KILL("we recieved soft RFKILL set to state %d\n", state); | ||
8214 | mutex_lock(&priv->mutex); | ||
8215 | |||
8216 | switch (state) { | ||
8217 | case RFKILL_STATE_UNBLOCKED: | ||
8218 | if (iwl3945_is_rfkill_hw(priv)) { | ||
8219 | err = -EBUSY; | ||
8220 | goto out_unlock; | ||
8221 | } | ||
8222 | iwl3945_radio_kill_sw(priv, 0); | ||
8223 | break; | ||
8224 | case RFKILL_STATE_SOFT_BLOCKED: | ||
8225 | iwl3945_radio_kill_sw(priv, 1); | ||
8226 | break; | ||
8227 | default: | ||
8228 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); | ||
8229 | break; | ||
8230 | } | ||
8231 | out_unlock: | ||
8232 | mutex_unlock(&priv->mutex); | ||
8233 | |||
8234 | return err; | ||
8235 | } | ||
8236 | |||
8237 | int iwl3945_rfkill_init(struct iwl3945_priv *priv) | ||
8238 | { | ||
8239 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
8240 | int ret = 0; | ||
8241 | |||
8242 | BUG_ON(device == NULL); | ||
8243 | |||
8244 | IWL_DEBUG_RF_KILL("Initializing RFKILL.\n"); | ||
8245 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
8246 | if (!priv->rfkill) { | ||
8247 | IWL_ERROR("Unable to allocate rfkill device.\n"); | ||
8248 | ret = -ENOMEM; | ||
8249 | goto error; | ||
8250 | } | ||
8251 | |||
8252 | priv->rfkill->name = priv->cfg->name; | ||
8253 | priv->rfkill->data = priv; | ||
8254 | priv->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
8255 | priv->rfkill->toggle_radio = iwl3945_rfkill_soft_rf_kill; | ||
8256 | priv->rfkill->user_claim_unsupported = 1; | ||
8257 | |||
8258 | priv->rfkill->dev.class->suspend = NULL; | ||
8259 | priv->rfkill->dev.class->resume = NULL; | ||
8260 | |||
8261 | ret = rfkill_register(priv->rfkill); | ||
8262 | if (ret) { | ||
8263 | IWL_ERROR("Unable to register rfkill: %d\n", ret); | ||
8264 | goto freed_rfkill; | ||
8265 | } | ||
8266 | |||
8267 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8268 | return ret; | ||
8269 | |||
8270 | freed_rfkill: | ||
8271 | if (priv->rfkill != NULL) | ||
8272 | rfkill_free(priv->rfkill); | ||
8273 | priv->rfkill = NULL; | ||
8274 | |||
8275 | error: | ||
8276 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | ||
8277 | return ret; | ||
8278 | } | ||
8279 | |||
8280 | void iwl3945_rfkill_unregister(struct iwl3945_priv *priv) | ||
8281 | { | ||
8282 | if (priv->rfkill) | ||
8283 | rfkill_unregister(priv->rfkill); | ||
8284 | |||
8285 | priv->rfkill = NULL; | ||
8286 | } | ||
8287 | |||
8288 | /* set rf-kill to the right state. */ | ||
8289 | void iwl3945_rfkill_set_hw_state(struct iwl3945_priv *priv) | ||
8290 | { | ||
8291 | |||
8292 | if (!priv->rfkill) | ||
8293 | return; | ||
8294 | |||
8295 | if (iwl3945_is_rfkill_hw(priv)) { | ||
8296 | rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); | ||
8297 | return; | ||
8298 | } | ||
8299 | |||
8300 | if (!iwl3945_is_rfkill_sw(priv)) | ||
8301 | rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); | ||
8302 | else | ||
8303 | rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); | ||
8304 | } | ||
8305 | #endif | ||
8306 | |||
8294 | /***************************************************************************** | 8307 | /***************************************************************************** |
8295 | * | 8308 | * |
8296 | * driver and module entry point | 8309 | * driver and module entry point |
@@ -8354,6 +8367,8 @@ static void __exit iwl3945_exit(void) | |||
8354 | iwl3945_rate_control_unregister(); | 8367 | iwl3945_rate_control_unregister(); |
8355 | } | 8368 | } |
8356 | 8369 | ||
8370 | MODULE_FIRMWARE("iwlwifi-3945" IWL3945_UCODE_API ".ucode"); | ||
8371 | |||
8357 | module_param_named(antenna, iwl3945_param_antenna, int, 0444); | 8372 | module_param_named(antenna, iwl3945_param_antenna, int, 0444); |
8358 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); | 8373 | MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); |
8359 | module_param_named(disable, iwl3945_param_disable, int, 0444); | 8374 | module_param_named(disable, iwl3945_param_disable, int, 0444); |