diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 989 |
1 files changed, 221 insertions, 768 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..093b863ef904 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /****************************************************************************** | 1 | /****************************************************************************** |
2 | * | 2 | * |
3 | * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. |
4 | * | 4 | * |
5 | * Portions of this file are derived from the ipw3945 project, as well | 5 | * Portions of this file are derived from the ipw3945 project, as well |
6 | * as portions of the ieee80211 subsystem header files. | 6 | * as portions of the ieee80211 subsystem header files. |
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <asm/div64.h> | 47 | #include <asm/div64.h> |
48 | 48 | ||
49 | #include "iwl-3945-core.h" | ||
49 | #include "iwl-3945.h" | 50 | #include "iwl-3945.h" |
50 | #include "iwl-helpers.h" | 51 | #include "iwl-helpers.h" |
51 | 52 | ||
@@ -91,15 +92,10 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | |||
91 | #define VS | 92 | #define VS |
92 | #endif | 93 | #endif |
93 | 94 | ||
94 | #define IWLWIFI_VERSION "1.2.23k" VD VS | 95 | #define IWLWIFI_VERSION "1.2.26k" VD VS |
95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" | 96 | #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" |
96 | #define DRV_VERSION IWLWIFI_VERSION | 97 | #define DRV_VERSION IWLWIFI_VERSION |
97 | 98 | ||
98 | /* Change firmware file name, using "-" and incrementing number, | ||
99 | * *only* when uCode interface or architecture changes so that it | ||
100 | * is not compatible with earlier drivers. | ||
101 | * This number will also appear in << 8 position of 1st dword of uCode file */ | ||
102 | #define IWL3945_UCODE_API "-1" | ||
103 | 99 | ||
104 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | 100 | MODULE_DESCRIPTION(DRV_DESCRIPTION); |
105 | MODULE_VERSION(DRV_VERSION); | 101 | MODULE_VERSION(DRV_VERSION); |
@@ -116,16 +112,10 @@ static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
116 | return NULL; | 112 | return NULL; |
117 | } | 113 | } |
118 | 114 | ||
119 | static const struct ieee80211_hw_mode *iwl3945_get_hw_mode( | 115 | static const struct ieee80211_supported_band *iwl3945_get_band( |
120 | struct iwl3945_priv *priv, int mode) | 116 | struct iwl3945_priv *priv, enum ieee80211_band band) |
121 | { | 117 | { |
122 | int i; | 118 | return priv->hw->wiphy->bands[band]; |
123 | |||
124 | for (i = 0; i < 3; i++) | ||
125 | if (priv->modes[i].mode == mode) | ||
126 | return &priv->modes[i]; | ||
127 | |||
128 | return NULL; | ||
129 | } | 119 | } |
130 | 120 | ||
131 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) | 121 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) |
@@ -168,17 +158,6 @@ static const char *iwl3945_escape_essid(const char *essid, u8 essid_len) | |||
168 | return escaped; | 158 | return escaped; |
169 | } | 159 | } |
170 | 160 | ||
171 | static void iwl3945_print_hex_dump(int level, void *p, u32 len) | ||
172 | { | ||
173 | #ifdef CONFIG_IWL3945_DEBUG | ||
174 | if (!(iwl3945_debug_level & level)) | ||
175 | return; | ||
176 | |||
177 | print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
178 | p, len, 1); | ||
179 | #endif | ||
180 | } | ||
181 | |||
182 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | 161 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** |
183 | * DMA services | 162 | * DMA services |
184 | * | 163 | * |
@@ -204,7 +183,7 @@ static void iwl3945_print_hex_dump(int level, void *p, u32 len) | |||
204 | * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. | 183 | * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. |
205 | ***************************************************/ | 184 | ***************************************************/ |
206 | 185 | ||
207 | static int iwl3945_queue_space(const struct iwl3945_queue *q) | 186 | int iwl3945_queue_space(const struct iwl3945_queue *q) |
208 | { | 187 | { |
209 | int s = q->read_ptr - q->write_ptr; | 188 | int s = q->read_ptr - q->write_ptr; |
210 | 189 | ||
@@ -220,33 +199,14 @@ static int iwl3945_queue_space(const struct iwl3945_queue *q) | |||
220 | return s; | 199 | return s; |
221 | } | 200 | } |
222 | 201 | ||
223 | /** | 202 | int iwl3945_x2_queue_used(const struct iwl3945_queue *q, int i) |
224 | * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning | ||
225 | * @index -- current index | ||
226 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
227 | */ | ||
228 | static inline int iwl3945_queue_inc_wrap(int index, int n_bd) | ||
229 | { | ||
230 | return ++index & (n_bd - 1); | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * iwl3945_queue_dec_wrap - increment queue index, wrap back to end | ||
235 | * @index -- current index | ||
236 | * @n_bd -- total number of entries in queue (must be power of 2) | ||
237 | */ | ||
238 | static inline int iwl3945_queue_dec_wrap(int index, int n_bd) | ||
239 | { | ||
240 | return --index & (n_bd - 1); | ||
241 | } | ||
242 | |||
243 | static inline int x2_queue_used(const struct iwl3945_queue *q, int i) | ||
244 | { | 203 | { |
245 | return q->write_ptr > q->read_ptr ? | 204 | return q->write_ptr > q->read_ptr ? |
246 | (i >= q->read_ptr && i < q->write_ptr) : | 205 | (i >= q->read_ptr && i < q->write_ptr) : |
247 | !(i < q->read_ptr && i >= q->write_ptr); | 206 | !(i < q->read_ptr && i >= q->write_ptr); |
248 | } | 207 | } |
249 | 208 | ||
209 | |||
250 | static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) | 210 | static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) |
251 | { | 211 | { |
252 | /* This is for scan command, the big buffer at end of command array */ | 212 | /* This is for scan command, the big buffer at end of command array */ |
@@ -267,8 +227,8 @@ static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q | |||
267 | q->n_window = slots_num; | 227 | q->n_window = slots_num; |
268 | q->id = id; | 228 | q->id = id; |
269 | 229 | ||
270 | /* count must be power-of-two size, otherwise iwl3945_queue_inc_wrap | 230 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap |
271 | * and iwl3945_queue_dec_wrap are broken. */ | 231 | * and iwl_queue_dec_wrap are broken. */ |
272 | BUG_ON(!is_power_of_2(count)); | 232 | BUG_ON(!is_power_of_2(count)); |
273 | 233 | ||
274 | /* slots_num must be power-of-two size, otherwise | 234 | /* slots_num must be power-of-two size, otherwise |
@@ -368,7 +328,7 @@ int iwl3945_tx_queue_init(struct iwl3945_priv *priv, | |||
368 | txq->need_update = 0; | 328 | txq->need_update = 0; |
369 | 329 | ||
370 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | 330 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise |
371 | * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ | 331 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ |
372 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | 332 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); |
373 | 333 | ||
374 | /* Initialize queue high/low-water, head/tail indexes */ | 334 | /* Initialize queue high/low-water, head/tail indexes */ |
@@ -399,7 +359,7 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t | |||
399 | 359 | ||
400 | /* first, empty all BD's */ | 360 | /* first, empty all BD's */ |
401 | for (; q->write_ptr != q->read_ptr; | 361 | for (; q->write_ptr != q->read_ptr; |
402 | q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) | 362 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) |
403 | iwl3945_hw_txq_free_tfd(priv, txq); | 363 | iwl3945_hw_txq_free_tfd(priv, txq); |
404 | 364 | ||
405 | len = sizeof(struct iwl3945_cmd) * q->n_window; | 365 | len = sizeof(struct iwl3945_cmd) * q->n_window; |
@@ -547,7 +507,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
547 | station->sta.sta.sta_id = index; | 507 | station->sta.sta.sta_id = index; |
548 | station->sta.station_flags = 0; | 508 | station->sta.station_flags = 0; |
549 | 509 | ||
550 | if (priv->phymode == MODE_IEEE80211A) | 510 | if (priv->band == IEEE80211_BAND_5GHZ) |
551 | rate = IWL_RATE_6M_PLCP; | 511 | rate = IWL_RATE_6M_PLCP; |
552 | else | 512 | else |
553 | rate = IWL_RATE_1M_PLCP; | 513 | rate = IWL_RATE_1M_PLCP; |
@@ -738,7 +698,7 @@ static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_c | |||
738 | txq->need_update = 1; | 698 | txq->need_update = 1; |
739 | 699 | ||
740 | /* Increment and update queue's write index */ | 700 | /* Increment and update queue's write index */ |
741 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); | 701 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
742 | ret = iwl3945_tx_queue_update_write_ptr(priv, txq); | 702 | ret = iwl3945_tx_queue_update_write_ptr(priv, txq); |
743 | 703 | ||
744 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); | 704 | spin_unlock_irqrestore(&priv->hcmd_lock, flags); |
@@ -894,35 +854,37 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | |||
894 | 854 | ||
895 | /** | 855 | /** |
896 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON | 856 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON |
897 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz | 857 | * @band: 2.4 or 5 GHz band |
898 | * @channel: Any channel valid for the requested phymode | 858 | * @channel: Any channel valid for the requested band |
899 | 859 | ||
900 | * In addition to setting the staging RXON, priv->phymode is also set. | 860 | * In addition to setting the staging RXON, priv->band is also set. |
901 | * | 861 | * |
902 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 862 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
903 | * in the staging RXON flag structure based on the phymode | 863 | * in the staging RXON flag structure based on the band |
904 | */ | 864 | */ |
905 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel) | 865 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, |
866 | enum ieee80211_band band, | ||
867 | u16 channel) | ||
906 | { | 868 | { |
907 | if (!iwl3945_get_channel_info(priv, phymode, channel)) { | 869 | if (!iwl3945_get_channel_info(priv, band, channel)) { |
908 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 870 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
909 | channel, phymode); | 871 | channel, band); |
910 | return -EINVAL; | 872 | return -EINVAL; |
911 | } | 873 | } |
912 | 874 | ||
913 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 875 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
914 | (priv->phymode == phymode)) | 876 | (priv->band == band)) |
915 | return 0; | 877 | return 0; |
916 | 878 | ||
917 | priv->staging_rxon.channel = cpu_to_le16(channel); | 879 | priv->staging_rxon.channel = cpu_to_le16(channel); |
918 | if (phymode == MODE_IEEE80211A) | 880 | if (band == IEEE80211_BAND_5GHZ) |
919 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 881 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
920 | else | 882 | else |
921 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 883 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
922 | 884 | ||
923 | priv->phymode = phymode; | 885 | priv->band = band; |
924 | 886 | ||
925 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 887 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
926 | 888 | ||
927 | return 0; | 889 | return 0; |
928 | } | 890 | } |
@@ -1210,8 +1172,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1210 | return -EIO; | 1172 | return -EIO; |
1211 | } | 1173 | } |
1212 | 1174 | ||
1213 | /* Init the hardware's rate fallback order based on the | 1175 | /* Init the hardware's rate fallback order based on the band */ |
1214 | * phymode */ | ||
1215 | rc = iwl3945_init_hw_rate_table(priv); | 1176 | rc = iwl3945_init_hw_rate_table(priv); |
1216 | if (rc) { | 1177 | if (rc) { |
1217 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); | 1178 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); |
@@ -1635,151 +1596,6 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv) | |||
1635 | return 0; | 1596 | return 0; |
1636 | } | 1597 | } |
1637 | 1598 | ||
1638 | /****************************************************************************** | ||
1639 | * | ||
1640 | * Misc. internal state and helper functions | ||
1641 | * | ||
1642 | ******************************************************************************/ | ||
1643 | #ifdef CONFIG_IWL3945_DEBUG | ||
1644 | |||
1645 | /** | ||
1646 | * iwl3945_report_frame - dump frame to syslog during debug sessions | ||
1647 | * | ||
1648 | * You may hack this function to show different aspects of received frames, | ||
1649 | * including selective frame dumps. | ||
1650 | * group100 parameter selects whether to show 1 out of 100 good frames. | ||
1651 | */ | ||
1652 | void iwl3945_report_frame(struct iwl3945_priv *priv, | ||
1653 | struct iwl3945_rx_packet *pkt, | ||
1654 | struct ieee80211_hdr *header, int group100) | ||
1655 | { | ||
1656 | u32 to_us; | ||
1657 | u32 print_summary = 0; | ||
1658 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | ||
1659 | u32 hundred = 0; | ||
1660 | u32 dataframe = 0; | ||
1661 | u16 fc; | ||
1662 | u16 seq_ctl; | ||
1663 | u16 channel; | ||
1664 | u16 phy_flags; | ||
1665 | int rate_sym; | ||
1666 | u16 length; | ||
1667 | u16 status; | ||
1668 | u16 bcn_tmr; | ||
1669 | u32 tsf_low; | ||
1670 | u64 tsf; | ||
1671 | u8 rssi; | ||
1672 | u8 agc; | ||
1673 | u16 sig_avg; | ||
1674 | u16 noise_diff; | ||
1675 | struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); | ||
1676 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | ||
1677 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | ||
1678 | u8 *data = IWL_RX_DATA(pkt); | ||
1679 | |||
1680 | /* MAC header */ | ||
1681 | fc = le16_to_cpu(header->frame_control); | ||
1682 | seq_ctl = le16_to_cpu(header->seq_ctrl); | ||
1683 | |||
1684 | /* metadata */ | ||
1685 | channel = le16_to_cpu(rx_hdr->channel); | ||
1686 | phy_flags = le16_to_cpu(rx_hdr->phy_flags); | ||
1687 | rate_sym = rx_hdr->rate; | ||
1688 | length = le16_to_cpu(rx_hdr->len); | ||
1689 | |||
1690 | /* end-of-frame status and timestamp */ | ||
1691 | status = le32_to_cpu(rx_end->status); | ||
1692 | bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp); | ||
1693 | tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff; | ||
1694 | tsf = le64_to_cpu(rx_end->timestamp); | ||
1695 | |||
1696 | /* signal statistics */ | ||
1697 | rssi = rx_stats->rssi; | ||
1698 | agc = rx_stats->agc; | ||
1699 | sig_avg = le16_to_cpu(rx_stats->sig_avg); | ||
1700 | noise_diff = le16_to_cpu(rx_stats->noise_diff); | ||
1701 | |||
1702 | to_us = !compare_ether_addr(header->addr1, priv->mac_addr); | ||
1703 | |||
1704 | /* if data frame is to us and all is good, | ||
1705 | * (optionally) print summary for only 1 out of every 100 */ | ||
1706 | if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == | ||
1707 | (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | ||
1708 | dataframe = 1; | ||
1709 | if (!group100) | ||
1710 | print_summary = 1; /* print each frame */ | ||
1711 | else if (priv->framecnt_to_us < 100) { | ||
1712 | priv->framecnt_to_us++; | ||
1713 | print_summary = 0; | ||
1714 | } else { | ||
1715 | priv->framecnt_to_us = 0; | ||
1716 | print_summary = 1; | ||
1717 | hundred = 1; | ||
1718 | } | ||
1719 | } else { | ||
1720 | /* print summary for all other frames */ | ||
1721 | print_summary = 1; | ||
1722 | } | ||
1723 | |||
1724 | if (print_summary) { | ||
1725 | char *title; | ||
1726 | u32 rate; | ||
1727 | |||
1728 | if (hundred) | ||
1729 | title = "100Frames"; | ||
1730 | else if (fc & IEEE80211_FCTL_RETRY) | ||
1731 | title = "Retry"; | ||
1732 | else if (ieee80211_is_assoc_response(fc)) | ||
1733 | title = "AscRsp"; | ||
1734 | else if (ieee80211_is_reassoc_response(fc)) | ||
1735 | title = "RasRsp"; | ||
1736 | else if (ieee80211_is_probe_response(fc)) { | ||
1737 | title = "PrbRsp"; | ||
1738 | print_dump = 1; /* dump frame contents */ | ||
1739 | } else if (ieee80211_is_beacon(fc)) { | ||
1740 | title = "Beacon"; | ||
1741 | print_dump = 1; /* dump frame contents */ | ||
1742 | } else if (ieee80211_is_atim(fc)) | ||
1743 | title = "ATIM"; | ||
1744 | else if (ieee80211_is_auth(fc)) | ||
1745 | title = "Auth"; | ||
1746 | else if (ieee80211_is_deauth(fc)) | ||
1747 | title = "DeAuth"; | ||
1748 | else if (ieee80211_is_disassoc(fc)) | ||
1749 | title = "DisAssoc"; | ||
1750 | else | ||
1751 | title = "Frame"; | ||
1752 | |||
1753 | rate = iwl3945_rate_index_from_plcp(rate_sym); | ||
1754 | if (rate == -1) | ||
1755 | rate = 0; | ||
1756 | else | ||
1757 | rate = iwl3945_rates[rate].ieee / 2; | ||
1758 | |||
1759 | /* print frame summary. | ||
1760 | * MAC addresses show just the last byte (for brevity), | ||
1761 | * but you can hack it to show more, if you'd like to. */ | ||
1762 | if (dataframe) | ||
1763 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | ||
1764 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | ||
1765 | title, fc, header->addr1[5], | ||
1766 | length, rssi, channel, rate); | ||
1767 | else { | ||
1768 | /* src/dst addresses assume managed mode */ | ||
1769 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | ||
1770 | "src=0x%02x, rssi=%u, tim=%lu usec, " | ||
1771 | "phy=0x%02x, chnl=%d\n", | ||
1772 | title, fc, header->addr1[5], | ||
1773 | header->addr3[5], rssi, | ||
1774 | tsf_low - priv->scan_start_tsf, | ||
1775 | phy_flags, channel); | ||
1776 | } | ||
1777 | } | ||
1778 | if (print_dump) | ||
1779 | iwl3945_print_hex_dump(IWL_DL_RX, data, length); | ||
1780 | } | ||
1781 | #endif | ||
1782 | |||
1783 | static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv) | 1599 | static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv) |
1784 | { | 1600 | { |
1785 | if (priv->hw_setting.shared_virt) | 1601 | if (priv->hw_setting.shared_virt) |
@@ -1915,7 +1731,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv, | |||
1915 | /* | 1731 | /* |
1916 | * QoS support | 1732 | * QoS support |
1917 | */ | 1733 | */ |
1918 | #ifdef CONFIG_IWL3945_QOS | ||
1919 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, | 1734 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, |
1920 | struct iwl3945_qosparam_cmd *qos) | 1735 | struct iwl3945_qosparam_cmd *qos) |
1921 | { | 1736 | { |
@@ -2044,7 +1859,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) | |||
2044 | } | 1859 | } |
2045 | } | 1860 | } |
2046 | 1861 | ||
2047 | #endif /* CONFIG_IWL3945_QOS */ | ||
2048 | /* | 1862 | /* |
2049 | * Power management (not Tx power!) functions | 1863 | * Power management (not Tx power!) functions |
2050 | */ | 1864 | */ |
@@ -2249,34 +2063,6 @@ int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *h | |||
2249 | return 1; | 2063 | return 1; |
2250 | } | 2064 | } |
2251 | 2065 | ||
2252 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | ||
2253 | |||
2254 | static const char *iwl3945_get_tx_fail_reason(u32 status) | ||
2255 | { | ||
2256 | switch (status & TX_STATUS_MSK) { | ||
2257 | case TX_STATUS_SUCCESS: | ||
2258 | return "SUCCESS"; | ||
2259 | TX_STATUS_ENTRY(SHORT_LIMIT); | ||
2260 | TX_STATUS_ENTRY(LONG_LIMIT); | ||
2261 | TX_STATUS_ENTRY(FIFO_UNDERRUN); | ||
2262 | TX_STATUS_ENTRY(MGMNT_ABORT); | ||
2263 | TX_STATUS_ENTRY(NEXT_FRAG); | ||
2264 | TX_STATUS_ENTRY(LIFE_EXPIRE); | ||
2265 | TX_STATUS_ENTRY(DEST_PS); | ||
2266 | TX_STATUS_ENTRY(ABORTED); | ||
2267 | TX_STATUS_ENTRY(BT_RETRY); | ||
2268 | TX_STATUS_ENTRY(STA_INVALID); | ||
2269 | TX_STATUS_ENTRY(FRAG_DROPPED); | ||
2270 | TX_STATUS_ENTRY(TID_DISABLE); | ||
2271 | TX_STATUS_ENTRY(FRAME_FLUSHED); | ||
2272 | TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL); | ||
2273 | TX_STATUS_ENTRY(TX_LOCKED); | ||
2274 | TX_STATUS_ENTRY(NO_BEACON_ON_RADAR); | ||
2275 | } | ||
2276 | |||
2277 | return "UNKNOWN"; | ||
2278 | } | ||
2279 | |||
2280 | /** | 2066 | /** |
2281 | * iwl3945_scan_cancel - Cancel any currently executing HW scan | 2067 | * iwl3945_scan_cancel - Cancel any currently executing HW scan |
2282 | * | 2068 | * |
@@ -2461,9 +2247,10 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | |||
2461 | return 0; | 2247 | return 0; |
2462 | } | 2248 | } |
2463 | 2249 | ||
2464 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode) | 2250 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, |
2251 | enum ieee80211_band band) | ||
2465 | { | 2252 | { |
2466 | if (phymode == MODE_IEEE80211A) { | 2253 | if (band == IEEE80211_BAND_5GHZ) { |
2467 | priv->staging_rxon.flags &= | 2254 | priv->staging_rxon.flags &= |
2468 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2255 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2469 | | RXON_FLG_CCK_MSK); | 2256 | | RXON_FLG_CCK_MSK); |
@@ -2526,7 +2313,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2526 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2313 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2527 | #endif | 2314 | #endif |
2528 | 2315 | ||
2529 | ch_info = iwl3945_get_channel_info(priv, priv->phymode, | 2316 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2530 | le16_to_cpu(priv->staging_rxon.channel)); | 2317 | le16_to_cpu(priv->staging_rxon.channel)); |
2531 | 2318 | ||
2532 | if (!ch_info) | 2319 | if (!ch_info) |
@@ -2542,11 +2329,11 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2542 | 2329 | ||
2543 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2330 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2544 | if (is_channel_a_band(ch_info)) | 2331 | if (is_channel_a_band(ch_info)) |
2545 | priv->phymode = MODE_IEEE80211A; | 2332 | priv->band = IEEE80211_BAND_5GHZ; |
2546 | else | 2333 | else |
2547 | priv->phymode = MODE_IEEE80211G; | 2334 | priv->band = IEEE80211_BAND_2GHZ; |
2548 | 2335 | ||
2549 | iwl3945_set_flags_for_phymode(priv, priv->phymode); | 2336 | iwl3945_set_flags_for_phymode(priv, priv->band); |
2550 | 2337 | ||
2551 | priv->staging_rxon.ofdm_basic_rates = | 2338 | priv->staging_rxon.ofdm_basic_rates = |
2552 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2339 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2560,7 +2347,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2560 | const struct iwl3945_channel_info *ch_info; | 2347 | const struct iwl3945_channel_info *ch_info; |
2561 | 2348 | ||
2562 | ch_info = iwl3945_get_channel_info(priv, | 2349 | ch_info = iwl3945_get_channel_info(priv, |
2563 | priv->phymode, | 2350 | priv->band, |
2564 | le16_to_cpu(priv->staging_rxon.channel)); | 2351 | le16_to_cpu(priv->staging_rxon.channel)); |
2565 | 2352 | ||
2566 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2353 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2792,7 +2579,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2792 | goto drop_unlock; | 2579 | goto drop_unlock; |
2793 | } | 2580 | } |
2794 | 2581 | ||
2795 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2582 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2796 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2583 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2797 | goto drop_unlock; | 2584 | goto drop_unlock; |
2798 | } | 2585 | } |
@@ -2963,7 +2750,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2963 | ieee80211_get_hdrlen(fc)); | 2750 | ieee80211_get_hdrlen(fc)); |
2964 | 2751 | ||
2965 | /* Tell device the write index *just past* this latest filled TFD */ | 2752 | /* Tell device the write index *just past* this latest filled TFD */ |
2966 | q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); | 2753 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
2967 | rc = iwl3945_tx_queue_update_write_ptr(priv, txq); | 2754 | rc = iwl3945_tx_queue_update_write_ptr(priv, txq); |
2968 | spin_unlock_irqrestore(&priv->lock, flags); | 2755 | spin_unlock_irqrestore(&priv->lock, flags); |
2969 | 2756 | ||
@@ -2992,12 +2779,12 @@ drop: | |||
2992 | 2779 | ||
2993 | static void iwl3945_set_rate(struct iwl3945_priv *priv) | 2780 | static void iwl3945_set_rate(struct iwl3945_priv *priv) |
2994 | { | 2781 | { |
2995 | const struct ieee80211_hw_mode *hw = NULL; | 2782 | const struct ieee80211_supported_band *sband = NULL; |
2996 | struct ieee80211_rate *rate; | 2783 | struct ieee80211_rate *rate; |
2997 | int i; | 2784 | int i; |
2998 | 2785 | ||
2999 | hw = iwl3945_get_hw_mode(priv, priv->phymode); | 2786 | sband = iwl3945_get_band(priv, priv->band); |
3000 | if (!hw) { | 2787 | if (!sband) { |
3001 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 2788 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3002 | return; | 2789 | return; |
3003 | } | 2790 | } |
@@ -3005,24 +2792,17 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv) | |||
3005 | priv->active_rate = 0; | 2792 | priv->active_rate = 0; |
3006 | priv->active_rate_basic = 0; | 2793 | priv->active_rate_basic = 0; |
3007 | 2794 | ||
3008 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 2795 | IWL_DEBUG_RATE("Setting rates for %s GHz\n", |
3009 | hw->mode == MODE_IEEE80211A ? | 2796 | sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5"); |
3010 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 2797 | |
3011 | 2798 | for (i = 0; i < sband->n_bitrates; i++) { | |
3012 | for (i = 0; i < hw->num_rates; i++) { | 2799 | rate = &sband->bitrates[i]; |
3013 | rate = &(hw->rates[i]); | 2800 | if ((rate->hw_value < IWL_RATE_COUNT) && |
3014 | if ((rate->val < IWL_RATE_COUNT) && | 2801 | !(rate->flags & IEEE80211_CHAN_DISABLED)) { |
3015 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | 2802 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n", |
3016 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | 2803 | rate->hw_value, iwl3945_rates[rate->hw_value].plcp); |
3017 | rate->val, iwl3945_rates[rate->val].plcp, | 2804 | priv->active_rate |= (1 << rate->hw_value); |
3018 | (rate->flags & IEEE80211_RATE_BASIC) ? | 2805 | } |
3019 | "*" : ""); | ||
3020 | priv->active_rate |= (1 << rate->val); | ||
3021 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3022 | priv->active_rate_basic |= (1 << rate->val); | ||
3023 | } else | ||
3024 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3025 | rate->val, iwl3945_rates[rate->val].plcp); | ||
3026 | } | 2806 | } |
3027 | 2807 | ||
3028 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 2808 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3330,127 +3110,6 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv, | |||
3330 | } | 3110 | } |
3331 | #endif | 3111 | #endif |
3332 | 3112 | ||
3333 | static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv, | ||
3334 | struct iwl3945_tx_info *tx_sta) | ||
3335 | { | ||
3336 | |||
3337 | tx_sta->status.ack_signal = 0; | ||
3338 | tx_sta->status.excessive_retries = 0; | ||
3339 | tx_sta->status.queue_length = 0; | ||
3340 | tx_sta->status.queue_number = 0; | ||
3341 | |||
3342 | if (in_interrupt()) | ||
3343 | ieee80211_tx_status_irqsafe(priv->hw, | ||
3344 | tx_sta->skb[0], &(tx_sta->status)); | ||
3345 | else | ||
3346 | ieee80211_tx_status(priv->hw, | ||
3347 | tx_sta->skb[0], &(tx_sta->status)); | ||
3348 | |||
3349 | tx_sta->skb[0] = NULL; | ||
3350 | } | ||
3351 | |||
3352 | /** | ||
3353 | * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd | ||
3354 | * | ||
3355 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
3356 | * need to be reclaimed. As result, some free space forms. If there is | ||
3357 | * enough free space (> low mark), wake the stack that feeds us. | ||
3358 | */ | ||
3359 | static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index) | ||
3360 | { | ||
3361 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | ||
3362 | struct iwl3945_queue *q = &txq->q; | ||
3363 | int nfreed = 0; | ||
3364 | |||
3365 | if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) { | ||
3366 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | ||
3367 | "is out of range [0-%d] %d %d.\n", txq_id, | ||
3368 | index, q->n_bd, q->write_ptr, q->read_ptr); | ||
3369 | return 0; | ||
3370 | } | ||
3371 | |||
3372 | for (index = iwl3945_queue_inc_wrap(index, q->n_bd); | ||
3373 | q->read_ptr != index; | ||
3374 | q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
3375 | if (txq_id != IWL_CMD_QUEUE_NUM) { | ||
3376 | iwl3945_txstatus_to_ieee(priv, | ||
3377 | &(txq->txb[txq->q.read_ptr])); | ||
3378 | iwl3945_hw_txq_free_tfd(priv, txq); | ||
3379 | } else if (nfreed > 1) { | ||
3380 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | ||
3381 | q->write_ptr, q->read_ptr); | ||
3382 | queue_work(priv->workqueue, &priv->restart); | ||
3383 | } | ||
3384 | nfreed++; | ||
3385 | } | ||
3386 | |||
3387 | if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) && | ||
3388 | (txq_id != IWL_CMD_QUEUE_NUM) && | ||
3389 | priv->mac80211_registered) | ||
3390 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3391 | |||
3392 | |||
3393 | return nfreed; | ||
3394 | } | ||
3395 | |||
3396 | static int iwl3945_is_tx_success(u32 status) | ||
3397 | { | ||
3398 | return (status & 0xFF) == 0x1; | ||
3399 | } | ||
3400 | |||
3401 | /****************************************************************************** | ||
3402 | * | ||
3403 | * Generic RX handler implementations | ||
3404 | * | ||
3405 | ******************************************************************************/ | ||
3406 | /** | ||
3407 | * iwl3945_rx_reply_tx - Handle Tx response | ||
3408 | */ | ||
3409 | static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | ||
3410 | struct iwl3945_rx_mem_buffer *rxb) | ||
3411 | { | ||
3412 | struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; | ||
3413 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | ||
3414 | int txq_id = SEQ_TO_QUEUE(sequence); | ||
3415 | int index = SEQ_TO_INDEX(sequence); | ||
3416 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | ||
3417 | struct ieee80211_tx_status *tx_status; | ||
3418 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | ||
3419 | u32 status = le32_to_cpu(tx_resp->status); | ||
3420 | |||
3421 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { | ||
3422 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | ||
3423 | "is out of range [0-%d] %d %d\n", txq_id, | ||
3424 | index, txq->q.n_bd, txq->q.write_ptr, | ||
3425 | txq->q.read_ptr); | ||
3426 | return; | ||
3427 | } | ||
3428 | |||
3429 | tx_status = &(txq->txb[txq->q.read_ptr].status); | ||
3430 | |||
3431 | tx_status->retry_count = tx_resp->failure_frame; | ||
3432 | tx_status->queue_number = status; | ||
3433 | tx_status->queue_length = tx_resp->bt_kill_count; | ||
3434 | tx_status->queue_length |= tx_resp->failure_rts; | ||
3435 | |||
3436 | tx_status->flags = | ||
3437 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | ||
3438 | |||
3439 | tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate); | ||
3440 | |||
3441 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", | ||
3442 | txq_id, iwl3945_get_tx_fail_reason(status), status, | ||
3443 | tx_resp->rate, tx_resp->failure_frame); | ||
3444 | |||
3445 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | ||
3446 | if (index != -1) | ||
3447 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | ||
3448 | |||
3449 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | ||
3450 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | ||
3451 | } | ||
3452 | |||
3453 | |||
3454 | static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, | 3113 | static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, |
3455 | struct iwl3945_rx_mem_buffer *rxb) | 3114 | struct iwl3945_rx_mem_buffer *rxb) |
3456 | { | 3115 | { |
@@ -3797,13 +3456,44 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv) | |||
3797 | priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = | 3456 | priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = |
3798 | iwl3945_rx_scan_complete_notif; | 3457 | iwl3945_rx_scan_complete_notif; |
3799 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; | 3458 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; |
3800 | priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; | ||
3801 | 3459 | ||
3802 | /* Set up hardware specific Rx handlers */ | 3460 | /* Set up hardware specific Rx handlers */ |
3803 | iwl3945_hw_rx_handler_setup(priv); | 3461 | iwl3945_hw_rx_handler_setup(priv); |
3804 | } | 3462 | } |
3805 | 3463 | ||
3806 | /** | 3464 | /** |
3465 | * iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries | ||
3466 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
3467 | * need to be reclaimed. | ||
3468 | */ | ||
3469 | static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv, | ||
3470 | int txq_id, int index) | ||
3471 | { | ||
3472 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | ||
3473 | struct iwl3945_queue *q = &txq->q; | ||
3474 | int nfreed = 0; | ||
3475 | |||
3476 | if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) { | ||
3477 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | ||
3478 | "is out of range [0-%d] %d %d.\n", txq_id, | ||
3479 | index, q->n_bd, q->write_ptr, q->read_ptr); | ||
3480 | return; | ||
3481 | } | ||
3482 | |||
3483 | for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; | ||
3484 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
3485 | if (nfreed > 1) { | ||
3486 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | ||
3487 | q->write_ptr, q->read_ptr); | ||
3488 | queue_work(priv->workqueue, &priv->restart); | ||
3489 | break; | ||
3490 | } | ||
3491 | nfreed++; | ||
3492 | } | ||
3493 | } | ||
3494 | |||
3495 | |||
3496 | /** | ||
3807 | * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them | 3497 | * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them |
3808 | * @rxb: Rx buffer to reclaim | 3498 | * @rxb: Rx buffer to reclaim |
3809 | * | 3499 | * |
@@ -3822,12 +3512,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | |||
3822 | int cmd_index; | 3512 | int cmd_index; |
3823 | struct iwl3945_cmd *cmd; | 3513 | struct iwl3945_cmd *cmd; |
3824 | 3514 | ||
3825 | /* If a Tx command is being handled and it isn't in the actual | ||
3826 | * command queue then there a command routing bug has been introduced | ||
3827 | * in the queue management code. */ | ||
3828 | if (txq_id != IWL_CMD_QUEUE_NUM) | ||
3829 | IWL_ERROR("Error wrong command queue %d command id 0x%X\n", | ||
3830 | txq_id, pkt->hdr.cmd); | ||
3831 | BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); | 3515 | BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); |
3832 | 3516 | ||
3833 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); | 3517 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); |
@@ -3841,7 +3525,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, | |||
3841 | !cmd->meta.u.callback(priv, cmd, rxb->skb)) | 3525 | !cmd->meta.u.callback(priv, cmd, rxb->skb)) |
3842 | rxb->skb = NULL; | 3526 | rxb->skb = NULL; |
3843 | 3527 | ||
3844 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | 3528 | iwl3945_cmd_queue_reclaim(priv, txq_id, index); |
3845 | 3529 | ||
3846 | if (!(cmd->meta.flags & CMD_ASYNC)) { | 3530 | if (!(cmd->meta.flags & CMD_ASYNC)) { |
3847 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | 3531 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); |
@@ -4521,8 +4205,7 @@ static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) | |||
4521 | 4205 | ||
4522 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | 4206 | if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { |
4523 | IWL_ERROR("Start IWL Error Log Dump:\n"); | 4207 | IWL_ERROR("Start IWL Error Log Dump:\n"); |
4524 | IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n", | 4208 | IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count); |
4525 | priv->status, priv->config, count); | ||
4526 | } | 4209 | } |
4527 | 4210 | ||
4528 | IWL_ERROR("Desc Time asrtPC blink2 " | 4211 | IWL_ERROR("Desc Time asrtPC blink2 " |
@@ -4742,9 +4425,9 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4742 | * atomic, make sure that inta covers all the interrupts that | 4425 | * atomic, make sure that inta covers all the interrupts that |
4743 | * we've discovered, even if FH interrupt came in just after | 4426 | * we've discovered, even if FH interrupt came in just after |
4744 | * reading CSR_INT. */ | 4427 | * reading CSR_INT. */ |
4745 | if (inta_fh & CSR_FH_INT_RX_MASK) | 4428 | if (inta_fh & CSR39_FH_INT_RX_MASK) |
4746 | inta |= CSR_INT_BIT_FH_RX; | 4429 | inta |= CSR_INT_BIT_FH_RX; |
4747 | if (inta_fh & CSR_FH_INT_TX_MASK) | 4430 | if (inta_fh & CSR39_FH_INT_TX_MASK) |
4748 | inta |= CSR_INT_BIT_FH_TX; | 4431 | inta |= CSR_INT_BIT_FH_TX; |
4749 | 4432 | ||
4750 | /* Now service all interrupt bits discovered above. */ | 4433 | /* Now service all interrupt bits discovered above. */ |
@@ -4792,7 +4475,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4792 | /* Queue restart only if RF_KILL switch was set to "kill" | 4475 | /* Queue restart only if RF_KILL switch was set to "kill" |
4793 | * when we loaded driver, and is now set to "enable". | 4476 | * when we loaded driver, and is now set to "enable". |
4794 | * After we're Alive, RF_KILL gets handled by | 4477 | * After we're Alive, RF_KILL gets handled by |
4795 | * iwl_rx_card_state_notif() */ | 4478 | * iwl3945_rx_card_state_notif() */ |
4796 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 4479 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { |
4797 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 4480 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
4798 | queue_work(priv->workqueue, &priv->restart); | 4481 | queue_work(priv->workqueue, &priv->restart); |
@@ -5026,24 +4709,24 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban | |||
5026 | * Based on band and channel number. | 4709 | * Based on band and channel number. |
5027 | */ | 4710 | */ |
5028 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | 4711 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, |
5029 | int phymode, u16 channel) | 4712 | enum ieee80211_band band, u16 channel) |
5030 | { | 4713 | { |
5031 | int i; | 4714 | int i; |
5032 | 4715 | ||
5033 | switch (phymode) { | 4716 | switch (band) { |
5034 | case MODE_IEEE80211A: | 4717 | case IEEE80211_BAND_5GHZ: |
5035 | for (i = 14; i < priv->channel_count; i++) { | 4718 | for (i = 14; i < priv->channel_count; i++) { |
5036 | if (priv->channel_info[i].channel == channel) | 4719 | if (priv->channel_info[i].channel == channel) |
5037 | return &priv->channel_info[i]; | 4720 | return &priv->channel_info[i]; |
5038 | } | 4721 | } |
5039 | break; | 4722 | break; |
5040 | 4723 | ||
5041 | case MODE_IEEE80211B: | 4724 | case IEEE80211_BAND_2GHZ: |
5042 | case MODE_IEEE80211G: | ||
5043 | if (channel >= 1 && channel <= 14) | 4725 | if (channel >= 1 && channel <= 14) |
5044 | return &priv->channel_info[channel - 1]; | 4726 | return &priv->channel_info[channel - 1]; |
5045 | break; | 4727 | break; |
5046 | 4728 | case IEEE80211_NUM_BANDS: | |
4729 | WARN_ON(1); | ||
5047 | } | 4730 | } |
5048 | 4731 | ||
5049 | return NULL; | 4732 | return NULL; |
@@ -5106,8 +4789,8 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5106 | /* Loop through each band adding each of the channels */ | 4789 | /* Loop through each band adding each of the channels */ |
5107 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 4790 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5108 | ch_info->channel = eeprom_ch_index[ch]; | 4791 | ch_info->channel = eeprom_ch_index[ch]; |
5109 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 4792 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5110 | MODE_IEEE80211A; | 4793 | IEEE80211_BAND_5GHZ; |
5111 | 4794 | ||
5112 | /* permanently store EEPROM's channel regulatory flags | 4795 | /* permanently store EEPROM's channel regulatory flags |
5113 | * and max power in channel info database. */ | 4796 | * and max power in channel info database. */ |
@@ -5134,11 +4817,12 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5134 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | 4817 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; |
5135 | ch_info->min_power = 0; | 4818 | ch_info->min_power = 0; |
5136 | 4819 | ||
5137 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" | 4820 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x" |
5138 | " %ddBm): Ad-Hoc %ssupported\n", | 4821 | " %ddBm): Ad-Hoc %ssupported\n", |
5139 | ch_info->channel, | 4822 | ch_info->channel, |
5140 | is_channel_a_band(ch_info) ? | 4823 | is_channel_a_band(ch_info) ? |
5141 | "5.2" : "2.4", | 4824 | "5.2" : "2.4", |
4825 | CHECK_AND_PRINT(VALID), | ||
5142 | CHECK_AND_PRINT(IBSS), | 4826 | CHECK_AND_PRINT(IBSS), |
5143 | CHECK_AND_PRINT(ACTIVE), | 4827 | CHECK_AND_PRINT(ACTIVE), |
5144 | CHECK_AND_PRINT(RADAR), | 4828 | CHECK_AND_PRINT(RADAR), |
@@ -5203,18 +4887,20 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
5203 | #define IWL_PASSIVE_DWELL_BASE (100) | 4887 | #define IWL_PASSIVE_DWELL_BASE (100) |
5204 | #define IWL_CHANNEL_TUNE_TIME 5 | 4888 | #define IWL_CHANNEL_TUNE_TIME 5 |
5205 | 4889 | ||
5206 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode) | 4890 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, |
4891 | enum ieee80211_band band) | ||
5207 | { | 4892 | { |
5208 | if (phymode == MODE_IEEE80211A) | 4893 | if (band == IEEE80211_BAND_5GHZ) |
5209 | return IWL_ACTIVE_DWELL_TIME_52; | 4894 | return IWL_ACTIVE_DWELL_TIME_52; |
5210 | else | 4895 | else |
5211 | return IWL_ACTIVE_DWELL_TIME_24; | 4896 | return IWL_ACTIVE_DWELL_TIME_24; |
5212 | } | 4897 | } |
5213 | 4898 | ||
5214 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode) | 4899 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, |
4900 | enum ieee80211_band band) | ||
5215 | { | 4901 | { |
5216 | u16 active = iwl3945_get_active_dwell_time(priv, phymode); | 4902 | u16 active = iwl3945_get_active_dwell_time(priv, band); |
5217 | u16 passive = (phymode != MODE_IEEE80211A) ? | 4903 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
5218 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 4904 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5219 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 4905 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5220 | 4906 | ||
@@ -5234,28 +4920,29 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode | |||
5234 | return passive; | 4920 | return passive; |
5235 | } | 4921 | } |
5236 | 4922 | ||
5237 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | 4923 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, |
4924 | enum ieee80211_band band, | ||
5238 | u8 is_active, u8 direct_mask, | 4925 | u8 is_active, u8 direct_mask, |
5239 | struct iwl3945_scan_channel *scan_ch) | 4926 | struct iwl3945_scan_channel *scan_ch) |
5240 | { | 4927 | { |
5241 | const struct ieee80211_channel *channels = NULL; | 4928 | const struct ieee80211_channel *channels = NULL; |
5242 | const struct ieee80211_hw_mode *hw_mode; | 4929 | const struct ieee80211_supported_band *sband; |
5243 | const struct iwl3945_channel_info *ch_info; | 4930 | const struct iwl3945_channel_info *ch_info; |
5244 | u16 passive_dwell = 0; | 4931 | u16 passive_dwell = 0; |
5245 | u16 active_dwell = 0; | 4932 | u16 active_dwell = 0; |
5246 | int added, i; | 4933 | int added, i; |
5247 | 4934 | ||
5248 | hw_mode = iwl3945_get_hw_mode(priv, phymode); | 4935 | sband = iwl3945_get_band(priv, band); |
5249 | if (!hw_mode) | 4936 | if (!sband) |
5250 | return 0; | 4937 | return 0; |
5251 | 4938 | ||
5252 | channels = hw_mode->channels; | 4939 | channels = sband->channels; |
5253 | 4940 | ||
5254 | active_dwell = iwl3945_get_active_dwell_time(priv, phymode); | 4941 | active_dwell = iwl3945_get_active_dwell_time(priv, band); |
5255 | passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode); | 4942 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); |
5256 | 4943 | ||
5257 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 4944 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5258 | if (channels[i].chan == | 4945 | if (channels[i].hw_value == |
5259 | le16_to_cpu(priv->active_rxon.channel)) { | 4946 | le16_to_cpu(priv->active_rxon.channel)) { |
5260 | if (iwl3945_is_associated(priv)) { | 4947 | if (iwl3945_is_associated(priv)) { |
5261 | IWL_DEBUG_SCAN | 4948 | IWL_DEBUG_SCAN |
@@ -5266,9 +4953,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5266 | } else if (priv->only_active_channel) | 4953 | } else if (priv->only_active_channel) |
5267 | continue; | 4954 | continue; |
5268 | 4955 | ||
5269 | scan_ch->channel = channels[i].chan; | 4956 | scan_ch->channel = channels[i].hw_value; |
5270 | 4957 | ||
5271 | ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel); | 4958 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
5272 | if (!is_channel_valid(ch_info)) { | 4959 | if (!is_channel_valid(ch_info)) { |
5273 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4960 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
5274 | scan_ch->channel); | 4961 | scan_ch->channel); |
@@ -5276,7 +4963,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5276 | } | 4963 | } |
5277 | 4964 | ||
5278 | if (!is_active || is_channel_passive(ch_info) || | 4965 | if (!is_active || is_channel_passive(ch_info) || |
5279 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 4966 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5280 | scan_ch->type = 0; /* passive */ | 4967 | scan_ch->type = 0; /* passive */ |
5281 | else | 4968 | else |
5282 | scan_ch->type = 1; /* active */ | 4969 | scan_ch->type = 1; /* active */ |
@@ -5295,7 +4982,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5295 | /* scan_pwr_info->tpc.dsp_atten; */ | 4982 | /* scan_pwr_info->tpc.dsp_atten; */ |
5296 | 4983 | ||
5297 | /*scan_pwr_info->tpc.tx_gain; */ | 4984 | /*scan_pwr_info->tpc.tx_gain; */ |
5298 | if (phymode == MODE_IEEE80211A) | 4985 | if (band == IEEE80211_BAND_5GHZ) |
5299 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 4986 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5300 | else { | 4987 | else { |
5301 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 4988 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5319,41 +5006,23 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5319 | return added; | 5006 | return added; |
5320 | } | 5007 | } |
5321 | 5008 | ||
5322 | static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv) | ||
5323 | { | ||
5324 | int i, j; | ||
5325 | for (i = 0; i < 3; i++) { | ||
5326 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5327 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5328 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5329 | } | ||
5330 | } | ||
5331 | |||
5332 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | 5009 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, |
5333 | struct ieee80211_rate *rates) | 5010 | struct ieee80211_rate *rates) |
5334 | { | 5011 | { |
5335 | int i; | 5012 | int i; |
5336 | 5013 | ||
5337 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5014 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5338 | rates[i].rate = iwl3945_rates[i].ieee * 5; | 5015 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; |
5339 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5016 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5340 | rates[i].val2 = i; | 5017 | rates[i].hw_value_short = i; |
5341 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5018 | rates[i].flags = 0; |
5342 | /* Only OFDM have the bits-per-symbol set */ | 5019 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5343 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5344 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5345 | else { | ||
5346 | /* | 5020 | /* |
5347 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5021 | * If CCK != 1M then set short preamble rate flag. |
5348 | * which is CCK | PREAMBLE2 | ||
5349 | */ | 5022 | */ |
5350 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? | 5023 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? |
5351 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5024 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5352 | } | 5025 | } |
5353 | |||
5354 | /* Set up which ones are basic rates... */ | ||
5355 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5356 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5357 | } | 5026 | } |
5358 | } | 5027 | } |
5359 | 5028 | ||
@@ -5363,143 +5032,113 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
5363 | static int iwl3945_init_geos(struct iwl3945_priv *priv) | 5032 | static int iwl3945_init_geos(struct iwl3945_priv *priv) |
5364 | { | 5033 | { |
5365 | struct iwl3945_channel_info *ch; | 5034 | struct iwl3945_channel_info *ch; |
5366 | struct ieee80211_hw_mode *modes; | 5035 | struct ieee80211_supported_band *sband; |
5367 | struct ieee80211_channel *channels; | 5036 | struct ieee80211_channel *channels; |
5368 | struct ieee80211_channel *geo_ch; | 5037 | struct ieee80211_channel *geo_ch; |
5369 | struct ieee80211_rate *rates; | 5038 | struct ieee80211_rate *rates; |
5370 | int i = 0; | 5039 | int i = 0; |
5371 | enum { | ||
5372 | A = 0, | ||
5373 | B = 1, | ||
5374 | G = 2, | ||
5375 | }; | ||
5376 | int mode_count = 3; | ||
5377 | 5040 | ||
5378 | if (priv->modes) { | 5041 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5042 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5379 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5043 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5380 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5044 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5381 | return 0; | 5045 | return 0; |
5382 | } | 5046 | } |
5383 | 5047 | ||
5384 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5385 | GFP_KERNEL); | ||
5386 | if (!modes) | ||
5387 | return -ENOMEM; | ||
5388 | |||
5389 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5048 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5390 | priv->channel_count, GFP_KERNEL); | 5049 | priv->channel_count, GFP_KERNEL); |
5391 | if (!channels) { | 5050 | if (!channels) |
5392 | kfree(modes); | ||
5393 | return -ENOMEM; | 5051 | return -ENOMEM; |
5394 | } | ||
5395 | 5052 | ||
5396 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5053 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)), |
5397 | GFP_KERNEL); | 5054 | GFP_KERNEL); |
5398 | if (!rates) { | 5055 | if (!rates) { |
5399 | kfree(modes); | ||
5400 | kfree(channels); | 5056 | kfree(channels); |
5401 | return -ENOMEM; | 5057 | return -ENOMEM; |
5402 | } | 5058 | } |
5403 | 5059 | ||
5404 | /* 0 = 802.11a | ||
5405 | * 1 = 802.11b | ||
5406 | * 2 = 802.11g | ||
5407 | */ | ||
5408 | |||
5409 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5060 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5410 | modes[A].mode = MODE_IEEE80211A; | 5061 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; |
5411 | modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; | 5062 | sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; |
5412 | modes[A].rates = &rates[4]; | 5063 | /* just OFDM */ |
5413 | modes[A].num_rates = 8; /* just OFDM */ | 5064 | sband->bitrates = &rates[IWL_FIRST_OFDM_RATE]; |
5414 | modes[A].num_channels = 0; | 5065 | sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE; |
5415 | 5066 | ||
5416 | modes[B].mode = MODE_IEEE80211B; | 5067 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; |
5417 | modes[B].channels = channels; | 5068 | sband->channels = channels; |
5418 | modes[B].rates = rates; | 5069 | /* OFDM & CCK */ |
5419 | modes[B].num_rates = 4; /* just CCK */ | 5070 | sband->bitrates = rates; |
5420 | modes[B].num_channels = 0; | 5071 | sband->n_bitrates = IWL_RATE_COUNT; |
5421 | |||
5422 | modes[G].mode = MODE_IEEE80211G; | ||
5423 | modes[G].channels = channels; | ||
5424 | modes[G].rates = rates; | ||
5425 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5426 | modes[G].num_channels = 0; | ||
5427 | 5072 | ||
5428 | priv->ieee_channels = channels; | 5073 | priv->ieee_channels = channels; |
5429 | priv->ieee_rates = rates; | 5074 | priv->ieee_rates = rates; |
5430 | 5075 | ||
5431 | iwl3945_init_hw_rates(priv, rates); | 5076 | iwl3945_init_hw_rates(priv, rates); |
5432 | 5077 | ||
5433 | for (i = 0, geo_ch = channels; i < priv->channel_count; i++) { | 5078 | for (i = 0; i < priv->channel_count; i++) { |
5434 | ch = &priv->channel_info[i]; | 5079 | ch = &priv->channel_info[i]; |
5435 | 5080 | ||
5436 | if (!is_channel_valid(ch)) { | 5081 | /* FIXME: might be removed if scan is OK*/ |
5437 | IWL_DEBUG_INFO("Channel %d [%sGHz] is restricted -- " | 5082 | if (!is_channel_valid(ch)) |
5438 | "skipping.\n", | ||
5439 | ch->channel, is_channel_a_band(ch) ? | ||
5440 | "5.2" : "2.4"); | ||
5441 | continue; | 5083 | continue; |
5442 | } | ||
5443 | 5084 | ||
5444 | if (is_channel_a_band(ch)) | 5085 | if (is_channel_a_band(ch)) |
5445 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5086 | sband = &priv->bands[IEEE80211_BAND_5GHZ]; |
5446 | else { | 5087 | else |
5447 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5088 | sband = &priv->bands[IEEE80211_BAND_2GHZ]; |
5448 | modes[G].num_channels++; | ||
5449 | } | ||
5450 | 5089 | ||
5451 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5090 | geo_ch = &sband->channels[sband->n_channels++]; |
5452 | geo_ch->chan = ch->channel; | 5091 | |
5453 | geo_ch->power_level = ch->max_power_avg; | 5092 | geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel); |
5454 | geo_ch->antenna_max = 0xff; | 5093 | geo_ch->max_power = ch->max_power_avg; |
5094 | geo_ch->max_antenna_gain = 0xff; | ||
5095 | geo_ch->hw_value = ch->channel; | ||
5455 | 5096 | ||
5456 | if (is_channel_valid(ch)) { | 5097 | if (is_channel_valid(ch)) { |
5457 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5098 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5458 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5099 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5459 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5460 | 5100 | ||
5461 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5101 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5462 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5102 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5463 | 5103 | ||
5464 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5104 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5465 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5105 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5466 | 5106 | ||
5467 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5107 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5468 | priv->max_channel_txpower_limit = | 5108 | priv->max_channel_txpower_limit = |
5469 | ch->max_power_avg; | 5109 | ch->max_power_avg; |
5110 | } else { | ||
5111 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||
5470 | } | 5112 | } |
5471 | 5113 | ||
5472 | geo_ch->val = geo_ch->flag; | 5114 | /* Save flags for reg domain usage */ |
5115 | geo_ch->orig_flags = geo_ch->flags; | ||
5116 | |||
5117 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | ||
5118 | ch->channel, geo_ch->center_freq, | ||
5119 | is_channel_a_band(ch) ? "5.2" : "2.4", | ||
5120 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | ||
5121 | "restricted" : "valid", | ||
5122 | geo_ch->flags); | ||
5473 | } | 5123 | } |
5474 | 5124 | ||
5475 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5125 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
5126 | priv->cfg->sku & IWL_SKU_A) { | ||
5476 | printk(KERN_INFO DRV_NAME | 5127 | printk(KERN_INFO DRV_NAME |
5477 | ": Incorrectly detected BG card as ABG. Please send " | 5128 | ": Incorrectly detected BG card as ABG. Please send " |
5478 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5129 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
5479 | priv->pci_dev->device, priv->pci_dev->subsystem_device); | 5130 | priv->pci_dev->device, priv->pci_dev->subsystem_device); |
5480 | priv->is_abg = 0; | 5131 | priv->cfg->sku &= ~IWL_SKU_A; |
5481 | } | 5132 | } |
5482 | 5133 | ||
5483 | printk(KERN_INFO DRV_NAME | 5134 | printk(KERN_INFO DRV_NAME |
5484 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5135 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5485 | modes[G].num_channels, modes[A].num_channels); | 5136 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5486 | 5137 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5487 | /* | ||
5488 | * NOTE: We register these in preference of order -- the | ||
5489 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5490 | * a phymode based on rates or AP capabilities but seems to | ||
5491 | * configure it purely on if the channel being configured | ||
5492 | * is supported by a mode -- and the first match is taken | ||
5493 | */ | ||
5494 | 5138 | ||
5495 | if (modes[G].num_channels) | 5139 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5496 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5140 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5497 | if (modes[B].num_channels) | ||
5498 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5499 | if (modes[A].num_channels) | ||
5500 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5501 | 5141 | ||
5502 | priv->modes = modes; | ||
5503 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5142 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5504 | 5143 | ||
5505 | return 0; | 5144 | return 0; |
@@ -5510,7 +5149,6 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5510 | */ | 5149 | */ |
5511 | static void iwl3945_free_geos(struct iwl3945_priv *priv) | 5150 | static void iwl3945_free_geos(struct iwl3945_priv *priv) |
5512 | { | 5151 | { |
5513 | kfree(priv->modes); | ||
5514 | kfree(priv->ieee_channels); | 5152 | kfree(priv->ieee_channels); |
5515 | kfree(priv->ieee_rates); | 5153 | kfree(priv->ieee_rates); |
5516 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5154 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -5837,7 +5475,7 @@ static int iwl3945_read_ucode(struct iwl3945_priv *priv) | |||
5837 | int ret = 0; | 5475 | int ret = 0; |
5838 | const struct firmware *ucode_raw; | 5476 | const struct firmware *ucode_raw; |
5839 | /* firmware file name contains uCode/driver compatibility version */ | 5477 | /* firmware file name contains uCode/driver compatibility version */ |
5840 | const char *name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode"; | 5478 | const char *name = priv->cfg->fw_name; |
5841 | u8 *src; | 5479 | u8 *src; |
5842 | size_t len; | 5480 | size_t len; |
5843 | u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; | 5481 | u32 ver, inst_size, data_size, init_size, init_data_size, boot_size; |
@@ -6519,7 +6157,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6519 | struct iwl3945_scan_cmd *scan; | 6157 | struct iwl3945_scan_cmd *scan; |
6520 | struct ieee80211_conf *conf = NULL; | 6158 | struct ieee80211_conf *conf = NULL; |
6521 | u8 direct_mask; | 6159 | u8 direct_mask; |
6522 | int phymode; | 6160 | enum ieee80211_band band; |
6523 | 6161 | ||
6524 | conf = ieee80211_get_hw_conf(priv->hw); | 6162 | conf = ieee80211_get_hw_conf(priv->hw); |
6525 | 6163 | ||
@@ -6651,13 +6289,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6651 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6289 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6652 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6290 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6653 | scan->good_CRC_th = 0; | 6291 | scan->good_CRC_th = 0; |
6654 | phymode = MODE_IEEE80211G; | 6292 | band = IEEE80211_BAND_2GHZ; |
6655 | break; | 6293 | break; |
6656 | 6294 | ||
6657 | case 1: | 6295 | case 1: |
6658 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6296 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6659 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6297 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6660 | phymode = MODE_IEEE80211A; | 6298 | band = IEEE80211_BAND_5GHZ; |
6661 | break; | 6299 | break; |
6662 | 6300 | ||
6663 | default: | 6301 | default: |
@@ -6671,18 +6309,23 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6671 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | 6309 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) |
6672 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | 6310 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; |
6673 | 6311 | ||
6674 | if (direct_mask) | 6312 | if (direct_mask) { |
6675 | IWL_DEBUG_SCAN | 6313 | IWL_DEBUG_SCAN |
6676 | ("Initiating direct scan for %s.\n", | 6314 | ("Initiating direct scan for %s.\n", |
6677 | iwl3945_escape_essid(priv->essid, priv->essid_len)); | 6315 | iwl3945_escape_essid(priv->essid, priv->essid_len)); |
6678 | else | 6316 | scan->channel_count = |
6317 | iwl3945_get_channels_for_scan( | ||
6318 | priv, band, 1, /* active */ | ||
6319 | direct_mask, | ||
6320 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
6321 | } else { | ||
6679 | IWL_DEBUG_SCAN("Initiating indirect scan.\n"); | 6322 | IWL_DEBUG_SCAN("Initiating indirect scan.\n"); |
6680 | 6323 | scan->channel_count = | |
6681 | scan->channel_count = | 6324 | iwl3945_get_channels_for_scan( |
6682 | iwl3945_get_channels_for_scan( | 6325 | priv, band, 0, /* passive */ |
6683 | priv, phymode, 1, /* active */ | 6326 | direct_mask, |
6684 | direct_mask, | 6327 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6685 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6328 | } |
6686 | 6329 | ||
6687 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | 6330 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + |
6688 | scan->channel_count * sizeof(struct iwl3945_scan_channel); | 6331 | scan->channel_count * sizeof(struct iwl3945_scan_channel); |
@@ -6825,7 +6468,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6825 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); | 6468 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); |
6826 | iwl3945_add_station(priv, priv->bssid, 0, 0); | 6469 | iwl3945_add_station(priv, priv->bssid, 0, 0); |
6827 | iwl3945_sync_sta(priv, IWL_STA_ID, | 6470 | iwl3945_sync_sta(priv, IWL_STA_ID, |
6828 | (priv->phymode == MODE_IEEE80211A)? | 6471 | (priv->band == IEEE80211_BAND_5GHZ) ? |
6829 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 6472 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
6830 | CMD_ASYNC); | 6473 | CMD_ASYNC); |
6831 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); | 6474 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); |
@@ -6841,9 +6484,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6841 | 6484 | ||
6842 | iwl3945_sequence_reset(priv); | 6485 | iwl3945_sequence_reset(priv); |
6843 | 6486 | ||
6844 | #ifdef CONFIG_IWL3945_QOS | ||
6845 | iwl3945_activate_qos(priv, 0); | 6487 | iwl3945_activate_qos(priv, 0); |
6846 | #endif /* CONFIG_IWL3945_QOS */ | 6488 | |
6847 | /* we have just associated, don't start scan too early */ | 6489 | /* we have just associated, don't start scan too early */ |
6848 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 6490 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6849 | mutex_unlock(&priv->mutex); | 6491 | mutex_unlock(&priv->mutex); |
@@ -7020,7 +6662,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7020 | } | 6662 | } |
7021 | 6663 | ||
7022 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6664 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7023 | ctl->tx_rate); | 6665 | ctl->tx_rate->bitrate); |
7024 | 6666 | ||
7025 | if (iwl3945_tx_skb(priv, skb, ctl)) | 6667 | if (iwl3945_tx_skb(priv, skb, ctl)) |
7026 | dev_kfree_skb_any(skb); | 6668 | dev_kfree_skb_any(skb); |
@@ -7079,7 +6721,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7079 | int ret = 0; | 6721 | int ret = 0; |
7080 | 6722 | ||
7081 | mutex_lock(&priv->mutex); | 6723 | mutex_lock(&priv->mutex); |
7082 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 6724 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7083 | 6725 | ||
7084 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 6726 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7085 | 6727 | ||
@@ -7099,19 +6741,20 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7099 | 6741 | ||
7100 | spin_lock_irqsave(&priv->lock, flags); | 6742 | spin_lock_irqsave(&priv->lock, flags); |
7101 | 6743 | ||
7102 | ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel); | 6744 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
6745 | conf->channel->hw_value); | ||
7103 | if (!is_channel_valid(ch_info)) { | 6746 | if (!is_channel_valid(ch_info)) { |
7104 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 6747 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", |
7105 | conf->channel, conf->phymode); | 6748 | conf->channel->hw_value, conf->channel->band); |
7106 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 6749 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7107 | spin_unlock_irqrestore(&priv->lock, flags); | 6750 | spin_unlock_irqrestore(&priv->lock, flags); |
7108 | ret = -EINVAL; | 6751 | ret = -EINVAL; |
7109 | goto out; | 6752 | goto out; |
7110 | } | 6753 | } |
7111 | 6754 | ||
7112 | iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); | 6755 | iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value); |
7113 | 6756 | ||
7114 | iwl3945_set_flags_for_phymode(priv, conf->phymode); | 6757 | iwl3945_set_flags_for_phymode(priv, conf->channel->band); |
7115 | 6758 | ||
7116 | /* The list of supported rates and rate mask can be different | 6759 | /* The list of supported rates and rate mask can be different |
7117 | * for each phymode; since the phymode may have changed, reset | 6760 | * for each phymode; since the phymode may have changed, reset |
@@ -7225,6 +6868,12 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
7225 | if (conf == NULL) | 6868 | if (conf == NULL) |
7226 | return -EIO; | 6869 | return -EIO; |
7227 | 6870 | ||
6871 | if (priv->vif != vif) { | ||
6872 | IWL_DEBUG_MAC80211("leave - priv->vif != vif\n"); | ||
6873 | mutex_unlock(&priv->mutex); | ||
6874 | return 0; | ||
6875 | } | ||
6876 | |||
7228 | /* XXX: this MUST use conf->mac_addr */ | 6877 | /* XXX: this MUST use conf->mac_addr */ |
7229 | 6878 | ||
7230 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && | 6879 | if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) && |
@@ -7249,17 +6898,6 @@ static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, | |||
7249 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && | 6898 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) && |
7250 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { | 6899 | !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) { |
7251 | */ | 6900 | */ |
7252 | if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { | ||
7253 | IWL_DEBUG_MAC80211("leave - scanning\n"); | ||
7254 | mutex_unlock(&priv->mutex); | ||
7255 | return 0; | ||
7256 | } | ||
7257 | |||
7258 | if (priv->vif != vif) { | ||
7259 | IWL_DEBUG_MAC80211("leave - priv->vif != vif\n"); | ||
7260 | mutex_unlock(&priv->mutex); | ||
7261 | return 0; | ||
7262 | } | ||
7263 | 6901 | ||
7264 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | 6902 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { |
7265 | if (!conf->bssid) { | 6903 | if (!conf->bssid) { |
@@ -7487,10 +7125,8 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7487 | const struct ieee80211_tx_queue_params *params) | 7125 | const struct ieee80211_tx_queue_params *params) |
7488 | { | 7126 | { |
7489 | struct iwl3945_priv *priv = hw->priv; | 7127 | struct iwl3945_priv *priv = hw->priv; |
7490 | #ifdef CONFIG_IWL3945_QOS | ||
7491 | unsigned long flags; | 7128 | unsigned long flags; |
7492 | int q; | 7129 | int q; |
7493 | #endif /* CONFIG_IWL3945_QOS */ | ||
7494 | 7130 | ||
7495 | IWL_DEBUG_MAC80211("enter\n"); | 7131 | IWL_DEBUG_MAC80211("enter\n"); |
7496 | 7132 | ||
@@ -7504,7 +7140,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7504 | return 0; | 7140 | return 0; |
7505 | } | 7141 | } |
7506 | 7142 | ||
7507 | #ifdef CONFIG_IWL3945_QOS | ||
7508 | if (!priv->qos_data.qos_enable) { | 7143 | if (!priv->qos_data.qos_enable) { |
7509 | priv->qos_data.qos_active = 0; | 7144 | priv->qos_data.qos_active = 0; |
7510 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); | 7145 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); |
@@ -7518,7 +7153,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7518 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | 7153 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); |
7519 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | 7154 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; |
7520 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | 7155 | priv->qos_data.def_qos_parm.ac[q].edca_txop = |
7521 | cpu_to_le16((params->burst_time * 100)); | 7156 | cpu_to_le16((params->txop * 32)); |
7522 | 7157 | ||
7523 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 7158 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
7524 | priv->qos_data.qos_active = 1; | 7159 | priv->qos_data.qos_active = 1; |
@@ -7533,8 +7168,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7533 | 7168 | ||
7534 | mutex_unlock(&priv->mutex); | 7169 | mutex_unlock(&priv->mutex); |
7535 | 7170 | ||
7536 | #endif /*CONFIG_IWL3945_QOS */ | ||
7537 | |||
7538 | IWL_DEBUG_MAC80211("leave\n"); | 7171 | IWL_DEBUG_MAC80211("leave\n"); |
7539 | return 0; | 7172 | return 0; |
7540 | } | 7173 | } |
@@ -7599,9 +7232,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7599 | mutex_lock(&priv->mutex); | 7232 | mutex_lock(&priv->mutex); |
7600 | IWL_DEBUG_MAC80211("enter\n"); | 7233 | IWL_DEBUG_MAC80211("enter\n"); |
7601 | 7234 | ||
7602 | #ifdef CONFIG_IWL3945_QOS | ||
7603 | iwl3945_reset_qos(priv); | 7235 | iwl3945_reset_qos(priv); |
7604 | #endif | 7236 | |
7605 | cancel_delayed_work(&priv->post_associate); | 7237 | cancel_delayed_work(&priv->post_associate); |
7606 | 7238 | ||
7607 | spin_lock_irqsave(&priv->lock, flags); | 7239 | spin_lock_irqsave(&priv->lock, flags); |
@@ -7689,9 +7321,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7689 | IWL_DEBUG_MAC80211("leave\n"); | 7321 | IWL_DEBUG_MAC80211("leave\n"); |
7690 | spin_unlock_irqrestore(&priv->lock, flags); | 7322 | spin_unlock_irqrestore(&priv->lock, flags); |
7691 | 7323 | ||
7692 | #ifdef CONFIG_IWL3945_QOS | ||
7693 | iwl3945_reset_qos(priv); | 7324 | iwl3945_reset_qos(priv); |
7694 | #endif | ||
7695 | 7325 | ||
7696 | queue_work(priv->workqueue, &priv->post_associate.work); | 7326 | queue_work(priv->workqueue, &priv->post_associate.work); |
7697 | 7327 | ||
@@ -7892,65 +7522,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
7892 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 7522 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
7893 | store_filter_flags); | 7523 | store_filter_flags); |
7894 | 7524 | ||
7895 | static ssize_t show_tune(struct device *d, | ||
7896 | struct device_attribute *attr, char *buf) | ||
7897 | { | ||
7898 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7899 | |||
7900 | return sprintf(buf, "0x%04X\n", | ||
7901 | (priv->phymode << 8) | | ||
7902 | le16_to_cpu(priv->active_rxon.channel)); | ||
7903 | } | ||
7904 | |||
7905 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode); | ||
7906 | |||
7907 | static ssize_t store_tune(struct device *d, | ||
7908 | struct device_attribute *attr, | ||
7909 | const char *buf, size_t count) | ||
7910 | { | ||
7911 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7912 | char *p = (char *)buf; | ||
7913 | u16 tune = simple_strtoul(p, &p, 0); | ||
7914 | u8 phymode = (tune >> 8) & 0xff; | ||
7915 | u16 channel = tune & 0xff; | ||
7916 | |||
7917 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
7918 | |||
7919 | mutex_lock(&priv->mutex); | ||
7920 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
7921 | (priv->phymode != phymode)) { | ||
7922 | const struct iwl3945_channel_info *ch_info; | ||
7923 | |||
7924 | ch_info = iwl3945_get_channel_info(priv, phymode, channel); | ||
7925 | if (!ch_info) { | ||
7926 | IWL_WARNING("Requested invalid phymode/channel " | ||
7927 | "combination: %d %d\n", phymode, channel); | ||
7928 | mutex_unlock(&priv->mutex); | ||
7929 | return -EINVAL; | ||
7930 | } | ||
7931 | |||
7932 | /* Cancel any currently running scans... */ | ||
7933 | if (iwl3945_scan_cancel_timeout(priv, 100)) | ||
7934 | IWL_WARNING("Could not cancel scan.\n"); | ||
7935 | else { | ||
7936 | IWL_DEBUG_INFO("Committing phymode and " | ||
7937 | "rxon.channel = %d %d\n", | ||
7938 | phymode, channel); | ||
7939 | |||
7940 | iwl3945_set_rxon_channel(priv, phymode, channel); | ||
7941 | iwl3945_set_flags_for_phymode(priv, phymode); | ||
7942 | |||
7943 | iwl3945_set_rate(priv); | ||
7944 | iwl3945_commit_rxon(priv); | ||
7945 | } | ||
7946 | } | ||
7947 | mutex_unlock(&priv->mutex); | ||
7948 | |||
7949 | return count; | ||
7950 | } | ||
7951 | |||
7952 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
7953 | |||
7954 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 7525 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
7955 | 7526 | ||
7956 | static ssize_t show_measurement(struct device *d, | 7527 | static ssize_t show_measurement(struct device *d, |
@@ -8024,31 +7595,6 @@ static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, | |||
8024 | show_measurement, store_measurement); | 7595 | show_measurement, store_measurement); |
8025 | #endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */ | 7596 | #endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */ |
8026 | 7597 | ||
8027 | static ssize_t show_rate(struct device *d, | ||
8028 | struct device_attribute *attr, char *buf) | ||
8029 | { | ||
8030 | struct iwl3945_priv *priv = dev_get_drvdata(d); | ||
8031 | unsigned long flags; | ||
8032 | int i; | ||
8033 | |||
8034 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
8035 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) | ||
8036 | i = priv->stations[IWL_AP_ID].current_rate.s.rate; | ||
8037 | else | ||
8038 | i = priv->stations[IWL_STA_ID].current_rate.s.rate; | ||
8039 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
8040 | |||
8041 | i = iwl3945_rate_index_from_plcp(i); | ||
8042 | if (i == -1) | ||
8043 | return sprintf(buf, "0\n"); | ||
8044 | |||
8045 | return sprintf(buf, "%d%s\n", | ||
8046 | (iwl3945_rates[i].ieee >> 1), | ||
8047 | (iwl3945_rates[i].ieee & 0x1) ? ".5" : ""); | ||
8048 | } | ||
8049 | |||
8050 | static DEVICE_ATTR(rate, S_IRUSR, show_rate, NULL); | ||
8051 | |||
8052 | static ssize_t store_retry_rate(struct device *d, | 7598 | static ssize_t store_retry_rate(struct device *d, |
8053 | struct device_attribute *attr, | 7599 | struct device_attribute *attr, |
8054 | const char *buf, size_t count) | 7600 | const char *buf, size_t count) |
@@ -8165,73 +7711,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8165 | static ssize_t show_channels(struct device *d, | 7711 | static ssize_t show_channels(struct device *d, |
8166 | struct device_attribute *attr, char *buf) | 7712 | struct device_attribute *attr, char *buf) |
8167 | { | 7713 | { |
8168 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 7714 | /* all this shit doesn't belong into sysfs anyway */ |
8169 | int len = 0, i; | 7715 | return 0; |
8170 | struct ieee80211_channel *channels = NULL; | ||
8171 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8172 | int count = 0; | ||
8173 | |||
8174 | if (!iwl3945_is_ready(priv)) | ||
8175 | return -EAGAIN; | ||
8176 | |||
8177 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G); | ||
8178 | if (!hw_mode) | ||
8179 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B); | ||
8180 | if (hw_mode) { | ||
8181 | channels = hw_mode->channels; | ||
8182 | count = hw_mode->num_channels; | ||
8183 | } | ||
8184 | |||
8185 | len += | ||
8186 | sprintf(&buf[len], | ||
8187 | "Displaying %d channels in 2.4GHz band " | ||
8188 | "(802.11bg):\n", count); | ||
8189 | |||
8190 | for (i = 0; i < count; i++) | ||
8191 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8192 | channels[i].chan, | ||
8193 | channels[i].power_level, | ||
8194 | channels[i]. | ||
8195 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8196 | " (IEEE 802.11h required)" : "", | ||
8197 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8198 | || (channels[i]. | ||
8199 | flag & | ||
8200 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8201 | ", IBSS", | ||
8202 | channels[i]. | ||
8203 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8204 | "active/passive" : "passive only"); | ||
8205 | |||
8206 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A); | ||
8207 | if (hw_mode) { | ||
8208 | channels = hw_mode->channels; | ||
8209 | count = hw_mode->num_channels; | ||
8210 | } else { | ||
8211 | channels = NULL; | ||
8212 | count = 0; | ||
8213 | } | ||
8214 | |||
8215 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8216 | "(802.11a):\n", count); | ||
8217 | |||
8218 | for (i = 0; i < count; i++) | ||
8219 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8220 | channels[i].chan, | ||
8221 | channels[i].power_level, | ||
8222 | channels[i]. | ||
8223 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8224 | " (IEEE 802.11h required)" : "", | ||
8225 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8226 | || (channels[i]. | ||
8227 | flag & | ||
8228 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8229 | ", IBSS", | ||
8230 | channels[i]. | ||
8231 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8232 | "active/passive" : "passive only"); | ||
8233 | |||
8234 | return len; | ||
8235 | } | 7716 | } |
8236 | 7717 | ||
8237 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 7718 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8404,14 +7885,12 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
8404 | &dev_attr_measurement.attr, | 7885 | &dev_attr_measurement.attr, |
8405 | #endif | 7886 | #endif |
8406 | &dev_attr_power_level.attr, | 7887 | &dev_attr_power_level.attr, |
8407 | &dev_attr_rate.attr, | ||
8408 | &dev_attr_retry_rate.attr, | 7888 | &dev_attr_retry_rate.attr, |
8409 | &dev_attr_rf_kill.attr, | 7889 | &dev_attr_rf_kill.attr, |
8410 | &dev_attr_rs_window.attr, | 7890 | &dev_attr_rs_window.attr, |
8411 | &dev_attr_statistics.attr, | 7891 | &dev_attr_statistics.attr, |
8412 | &dev_attr_status.attr, | 7892 | &dev_attr_status.attr, |
8413 | &dev_attr_temperature.attr, | 7893 | &dev_attr_temperature.attr, |
8414 | &dev_attr_tune.attr, | ||
8415 | &dev_attr_tx_power.attr, | 7894 | &dev_attr_tx_power.attr, |
8416 | 7895 | ||
8417 | NULL | 7896 | NULL |
@@ -8444,9 +7923,9 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
8444 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 7923 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
8445 | { | 7924 | { |
8446 | int err = 0; | 7925 | int err = 0; |
8447 | u32 pci_id; | ||
8448 | struct iwl3945_priv *priv; | 7926 | struct iwl3945_priv *priv; |
8449 | struct ieee80211_hw *hw; | 7927 | struct ieee80211_hw *hw; |
7928 | struct iwl_3945_cfg *cfg = (struct iwl_3945_cfg *)(ent->driver_data); | ||
8450 | int i; | 7929 | int i; |
8451 | DECLARE_MAC_BUF(mac); | 7930 | DECLARE_MAC_BUF(mac); |
8452 | 7931 | ||
@@ -8482,6 +7961,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8482 | priv->hw = hw; | 7961 | priv->hw = hw; |
8483 | 7962 | ||
8484 | priv->pci_dev = pdev; | 7963 | priv->pci_dev = pdev; |
7964 | priv->cfg = cfg; | ||
8485 | 7965 | ||
8486 | /* Select antenna (may be helpful if only one antenna is connected) */ | 7966 | /* Select antenna (may be helpful if only one antenna is connected) */ |
8487 | priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; | 7967 | priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; |
@@ -8532,7 +8012,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8532 | priv->data_retry_limit = -1; | 8012 | priv->data_retry_limit = -1; |
8533 | priv->ieee_channels = NULL; | 8013 | priv->ieee_channels = NULL; |
8534 | priv->ieee_rates = NULL; | 8014 | priv->ieee_rates = NULL; |
8535 | priv->phymode = -1; | 8015 | priv->band = IEEE80211_BAND_2GHZ; |
8536 | 8016 | ||
8537 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8017 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
8538 | if (!err) | 8018 | if (!err) |
@@ -8571,32 +8051,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8571 | 8051 | ||
8572 | priv->iw_mode = IEEE80211_IF_TYPE_STA; | 8052 | priv->iw_mode = IEEE80211_IF_TYPE_STA; |
8573 | 8053 | ||
8574 | pci_id = | ||
8575 | (priv->pci_dev->device << 16) | priv->pci_dev->subsystem_device; | ||
8576 | |||
8577 | switch (pci_id) { | ||
8578 | case 0x42221005: /* 0x4222 0x8086 0x1005 is BG SKU */ | ||
8579 | case 0x42221034: /* 0x4222 0x8086 0x1034 is BG SKU */ | ||
8580 | case 0x42271014: /* 0x4227 0x8086 0x1014 is BG SKU */ | ||
8581 | case 0x42221044: /* 0x4222 0x8086 0x1044 is BG SKU */ | ||
8582 | priv->is_abg = 0; | ||
8583 | break; | ||
8584 | |||
8585 | /* | ||
8586 | * Rest are assumed ABG SKU -- if this is not the | ||
8587 | * case then the card will get the wrong 'Detected' | ||
8588 | * line in the kernel log however the code that | ||
8589 | * initializes the GEO table will detect no A-band | ||
8590 | * channels and remove the is_abg mask. | ||
8591 | */ | ||
8592 | default: | ||
8593 | priv->is_abg = 1; | ||
8594 | break; | ||
8595 | } | ||
8596 | |||
8597 | printk(KERN_INFO DRV_NAME | 8054 | printk(KERN_INFO DRV_NAME |
8598 | ": Detected Intel PRO/Wireless 3945%sBG Network Connection\n", | 8055 | ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name); |
8599 | priv->is_abg ? "A" : ""); | ||
8600 | 8056 | ||
8601 | /* Device-specific setup */ | 8057 | /* Device-specific setup */ |
8602 | if (iwl3945_hw_set_hw_setting(priv)) { | 8058 | if (iwl3945_hw_set_hw_setting(priv)) { |
@@ -8604,7 +8060,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8604 | goto out_iounmap; | 8060 | goto out_iounmap; |
8605 | } | 8061 | } |
8606 | 8062 | ||
8607 | #ifdef CONFIG_IWL3945_QOS | ||
8608 | if (iwl3945_param_qos_enable) | 8063 | if (iwl3945_param_qos_enable) |
8609 | priv->qos_data.qos_enable = 1; | 8064 | priv->qos_data.qos_enable = 1; |
8610 | 8065 | ||
@@ -8612,9 +8067,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8612 | 8067 | ||
8613 | priv->qos_data.qos_active = 0; | 8068 | priv->qos_data.qos_active = 0; |
8614 | priv->qos_data.qos_cap.val = 0; | 8069 | priv->qos_data.qos_cap.val = 0; |
8615 | #endif /* CONFIG_IWL3945_QOS */ | ||
8616 | 8070 | ||
8617 | iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8071 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
8618 | iwl3945_setup_deferred_work(priv); | 8072 | iwl3945_setup_deferred_work(priv); |
8619 | iwl3945_setup_rx_handlers(priv); | 8073 | iwl3945_setup_rx_handlers(priv); |
8620 | 8074 | ||
@@ -8665,7 +8119,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8665 | IWL_ERROR("initializing geos failed: %d\n", err); | 8119 | IWL_ERROR("initializing geos failed: %d\n", err); |
8666 | goto out_free_channel_map; | 8120 | goto out_free_channel_map; |
8667 | } | 8121 | } |
8668 | iwl3945_reset_channel_flag(priv); | ||
8669 | 8122 | ||
8670 | iwl3945_rate_control_register(priv->hw); | 8123 | iwl3945_rate_control_register(priv->hw); |
8671 | err = ieee80211_register_hw(priv->hw); | 8124 | err = ieee80211_register_hw(priv->hw); |