1 /******************************************************************************
5 * Copyright(c) 2008 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
24 * Contact Information:
25 * Tomas Winkler <tomas.winkler@intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *****************************************************************************/
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/version.h>
32 #include <net/mac80211.h>
34 struct iwl_priv; /* FIXME: remove */
35 #include "iwl-debug.h"
36 #include "iwl-eeprom.h"
39 #include "iwl-4965.h" /* FIXME: remove */
41 MODULE_DESCRIPTION("iwl core");
42 MODULE_VERSION(IWLWIFI_VERSION);
43 MODULE_AUTHOR(DRV_COPYRIGHT);
44 MODULE_LICENSE("GPL");
46 #ifdef CONFIG_IWLWIFI_DEBUG
48 EXPORT_SYMBOL(iwl_debug_level);
51 /* This function both allocates and initializes hw and priv. */
52 struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
53 struct ieee80211_ops *hw_ops)
55 struct iwl_priv *priv;
57 /* mac80211 allocates memory for this device instance, including
58 * space for this driver's private structure */
59 struct ieee80211_hw *hw =
60 ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
62 IWL_ERROR("Can not allocate network device\n");
72 EXPORT_SYMBOL(iwl_alloc_all);
75 * iwlcore_clear_stations_table - Clear the driver's station table
77 * NOTE: This does not clear or otherwise alter the device's station table.
79 void iwlcore_clear_stations_table(struct iwl_priv *priv)
83 spin_lock_irqsave(&priv->sta_lock, flags);
85 priv->num_stations = 0;
86 memset(priv->stations, 0, sizeof(priv->stations));
88 spin_unlock_irqrestore(&priv->sta_lock, flags);
90 EXPORT_SYMBOL(iwlcore_clear_stations_table);
92 void iwlcore_reset_qos(struct iwl_priv *priv)
101 spin_lock_irqsave(&priv->lock, flags);
102 priv->qos_data.qos_active = 0;
104 if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) {
105 if (priv->qos_data.qos_enable)
106 priv->qos_data.qos_active = 1;
107 if (!(priv->active_rate & 0xfff0)) {
111 } else if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
112 if (priv->qos_data.qos_enable)
113 priv->qos_data.qos_active = 1;
114 } else if (!(priv->staging_rxon.flags & RXON_FLG_SHORT_SLOT_MSK)) {
119 if (priv->qos_data.qos_active)
122 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
123 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
124 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
125 priv->qos_data.def_qos_parm.ac[0].edca_txop = 0;
126 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
128 if (priv->qos_data.qos_active) {
130 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
131 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
132 priv->qos_data.def_qos_parm.ac[i].aifsn = 7;
133 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
134 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
137 priv->qos_data.def_qos_parm.ac[i].cw_min =
138 cpu_to_le16((cw_min + 1) / 2 - 1);
139 priv->qos_data.def_qos_parm.ac[i].cw_max =
141 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
143 priv->qos_data.def_qos_parm.ac[i].edca_txop =
146 priv->qos_data.def_qos_parm.ac[i].edca_txop =
148 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
151 priv->qos_data.def_qos_parm.ac[i].cw_min =
152 cpu_to_le16((cw_min + 1) / 4 - 1);
153 priv->qos_data.def_qos_parm.ac[i].cw_max =
154 cpu_to_le16((cw_max + 1) / 2 - 1);
155 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
156 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
158 priv->qos_data.def_qos_parm.ac[i].edca_txop =
161 priv->qos_data.def_qos_parm.ac[i].edca_txop =
164 for (i = 1; i < 4; i++) {
165 priv->qos_data.def_qos_parm.ac[i].cw_min =
167 priv->qos_data.def_qos_parm.ac[i].cw_max =
169 priv->qos_data.def_qos_parm.ac[i].aifsn = aifs;
170 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
171 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
174 IWL_DEBUG_QOS("set QoS to default \n");
176 spin_unlock_irqrestore(&priv->lock, flags);
178 EXPORT_SYMBOL(iwlcore_reset_qos);
181 * iwlcore_set_rxon_channel - Set the phymode and channel values in staging RXON
182 * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
183 * @channel: Any channel valid for the requested phymode
185 * In addition to setting the staging RXON, priv->phymode is also set.
187 * NOTE: Does not commit to the hardware; it sets appropriate bit fields
188 * in the staging RXON flag structure based on the phymode
190 int iwlcore_set_rxon_channel(struct iwl_priv *priv,
191 enum ieee80211_band band,
194 if (!iwl_get_channel_info(priv, band, channel)) {
195 IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
200 if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
201 (priv->band == band))
204 priv->staging_rxon.channel = cpu_to_le16(channel);
205 if (band == IEEE80211_BAND_5GHZ)
206 priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
208 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
212 IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
216 EXPORT_SYMBOL(iwlcore_set_rxon_channel);
218 static void iwlcore_init_hw(struct iwl_priv *priv)
220 struct ieee80211_hw *hw = priv->hw;
221 hw->rate_control_algorithm = "iwl-4965-rs";
223 /* Tell mac80211 and its clients (e.g. Wireless Extensions)
224 * the range of signal quality values that we'll provide.
225 * Negative values for level/noise indicate that we'll provide dBm.
226 * For WE, at least, non-0 values here *enable* display of values
227 * in app (iwconfig). */
228 hw->max_rssi = -20; /* signal level, negative indicates dBm */
229 hw->max_noise = -20; /* noise level, negative indicates dBm */
230 hw->max_signal = 100; /* link quality indication (%) */
232 /* Tell mac80211 our Tx characteristics */
233 hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
235 /* Default value; 4 EDCA QOS priorities */
237 #ifdef CONFIG_IWL4965_HT
238 /* Enhanced value; more queues, to support 11n aggregation */
240 #endif /* CONFIG_IWL4965_HT */
243 int iwl_setup(struct iwl_priv *priv)
246 iwlcore_init_hw(priv);
247 ret = priv->cfg->ops->lib->init_drv(priv);
250 EXPORT_SYMBOL(iwl_setup);