#include <asm/div64.h>
#include "iwl-eeprom.h"
-#include "iwl-core.h"
#include "iwl-4965.h"
+#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
}
-/*************** DRIVER STATUS FUNCTIONS *****/
-
-static inline int iwl4965_is_ready(struct iwl_priv *priv)
-{
- /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are
- * set but EXIT_PENDING is not */
- return test_bit(STATUS_READY, &priv->status) &&
- test_bit(STATUS_GEO_CONFIGURED, &priv->status) &&
- !test_bit(STATUS_EXIT_PENDING, &priv->status);
-}
-
-static inline int iwl4965_is_alive(struct iwl_priv *priv)
-{
- return test_bit(STATUS_ALIVE, &priv->status);
-}
-
-static inline int iwl4965_is_init(struct iwl_priv *priv)
-{
- return test_bit(STATUS_INIT, &priv->status);
-}
-
-static inline int iwl4965_is_rfkill(struct iwl_priv *priv)
-{
- return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
- test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
-static inline int iwl4965_is_ready_rf(struct iwl_priv *priv)
-{
- if (iwl4965_is_rfkill(priv))
- return 0;
-
- return iwl4965_is_ready(priv);
-}
/*************** HOST COMMAND QUEUE FUNCTIONS *****/
BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
!(cmd->meta.flags & CMD_SIZE_HUGE));
- if (iwl4965_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_INFO("Not sending command - RF KILL");
return -EIO;
}
DECLARE_MAC_BUF(mac);
int rc = 0;
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -1;
/* always get timestamp with Rx frame */
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (iwl4965_is_associated(priv) &&
+ if (iwl_is_associated(priv) &&
(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) {
IWL_DEBUG_INFO("Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
/* If we have set the ASSOC_MSK and we are in BSS mode then
* add the IWL_AP_ID to the station rate table */
- if (iwl4965_is_associated(priv) &&
+ if (iwl_is_associated(priv) &&
(priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
== IWL_INVALID_STATION) {
const u8 *dest, int left)
{
- if (!iwl4965_is_associated(priv) || !priv->ibss_beacon ||
+ if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
(priv->iw_mode != IEEE80211_IF_TYPE_AP)))
return 0;
spin_unlock_irqrestore(&priv->lock, flags);
- if (force || iwl4965_is_associated(priv)) {
+ if (force || iwl_is_associated(priv)) {
IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
priv->qos_data.qos_active,
priv->qos_data.def_qos_parm.qos_flags);
conf = ieee80211_get_hw_conf(priv->hw);
spin_lock_irqsave(&priv->lock, flags);
- priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp1);
- priv->rxon_timing.timestamp.dw[0] = cpu_to_le32(priv->timestamp0);
+ priv->rxon_timing.timestamp.dw[1] = cpu_to_le32(priv->timestamp >> 32);
+ priv->rxon_timing.timestamp.dw[0] =
+ cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
- tsf = priv->timestamp1;
- tsf = ((tsf << 32) | priv->timestamp0);
+ tsf = priv->timestamp;
beacon_int = priv->beacon_int;
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
return -EIO;
}
iwlcore_clear_stations_table(priv);
/* dont commit rxon if rf-kill is on*/
- if (!iwl4965_is_ready_rf(priv))
+ if (!iwl_is_ready_rf(priv))
return -EAGAIN;
cancel_delayed_work(&priv->scan_check);
int rc;
spin_lock_irqsave(&priv->lock, flags);
- if (iwl4965_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_DROP("Dropping - RF KILL\n");
goto drop_unlock;
}
/* drop all data frame if we are not associated */
if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
- (!iwl4965_is_associated(priv) ||
+ (!iwl_is_associated(priv) ||
((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
!priv->assoc_station_added)) {
- IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n");
+ IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n");
goto drop_unlock;
}
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
-static void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
+void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio)
{
unsigned long flags;
iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_SW_BIT_RFKILL);
spin_unlock_irqrestore(&priv->lock, flags);
- iwl4965_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0);
+ /* call the host command only if no hw rf-kill set */
+ if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
+ iwl4965_send_card_state(priv,
+ CARD_STATE_CMD_DISABLE,
+ 0);
set_bit(STATUS_RF_KILL_SW, &priv->status);
+
+ /* make sure mac80211 stop sending Tx frame */
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
}
return;
}
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
- if (iwl4965_is_associated(priv))
+ if (iwl_is_associated(priv))
add_time =
iwl4965_usecs_to_beacons(
le64_to_cpu(params->start_time) - priv->last_tsf,
cmd.len = sizeof(spectrum);
spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
- if (iwl4965_is_associated(priv))
+ if (iwl_is_associated(priv))
spectrum.start_time =
iwl4965_add_beacon_time(priv->last_beacon_time,
add_time,
agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
- agg->bitmap);
+ (unsigned long long)agg->bitmap);
if (bitmap)
agg->wait_for_ba = 1;
iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
}
+/* call this function to flush any scheduled tasklet */
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
+{
+ /* wait to make sure we flush pedding tasklet*/
+ synchronize_irq(priv->pci_dev->irq);
+ tasklet_kill(&priv->irq_tasklet);
+}
+
static inline void iwl4965_disable_interrupts(struct iwl_priv *priv)
{
clear_bit(STATUS_INT_ENABLED, &priv->status);
IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS,
"Restarting adapter due to uCode error.\n");
- if (iwl4965_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
memcpy(&priv->recovery_rxon, &priv->active_rxon,
sizeof(priv->recovery_rxon));
priv->error_recovering = 1;
}
/* Re-enable all interrupts */
- iwl4965_enable_interrupts(priv);
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl4965_enable_interrupts(priv);
#ifdef CONFIG_IWLWIFI_DEBUG
if (iwl_debug_level & (IWL_DL_ISR)) {
none:
/* re-enable interrupts here since we don't have anything to service. */
- iwl4965_enable_interrupts(priv);
+ /* only Re-enable if diabled by irq */
+ if (test_bit(STATUS_INT_ENABLED, &priv->status))
+ iwl4965_enable_interrupts(priv);
spin_unlock(&priv->lock);
return IRQ_NONE;
}
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
- if (iwl4965_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
/* If we're associated, we clamp the maximum passive
* dwell time to be 98% of the beacon interval (minus
* 2 * channel tune time) */
passive_dwell = iwl4965_get_passive_dwell_time(priv, band);
for (i = 0, added = 0; i < sband->n_channels; i++) {
+ if (channels[i].flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
if (ieee80211_frequency_to_channel(channels[i].center_freq) ==
le16_to_cpu(priv->active_rxon.channel)) {
- if (iwl4965_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
IWL_DEBUG_SCAN
("Skipping current channel %d\n",
le16_to_cpu(priv->active_rxon.channel));
/* Clear out the uCode error bit if it is set */
clear_bit(STATUS_FW_ERROR, &priv->status);
- if (iwl4965_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
return;
ieee80211_start_queues(priv->hw);
iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode));
- if (iwl4965_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
struct iwl4965_rxon_cmd *active_rxon =
(struct iwl4965_rxon_cmd *)(&priv->active_rxon);
iwl4965_rf_kill_ct_config(priv);
+ iwl_leds_register(priv);
+
IWL_DEBUG_INFO("ALIVE processing complete.\n");
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- iwl_leds_register(priv);
-
if (priv->error_recovering)
iwl4965_error_recovery(priv);
iwlcore_low_level_notify(priv, IWLCORE_START_EVT);
+ ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC);
return;
restart:
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
/* tell the device to stop sending interrupts */
+ spin_lock_irqsave(&priv->lock, flags);
iwl4965_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_synchronize_irq(priv);
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl4965_init() then
* clear all bits but the RF Kill and SUSPEND bits and return */
- if (!iwl4965_is_init(priv)) {
+ if (!iwl_is_init(priv)) {
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
test_bit(STATUS_RF_KILL_SW, &priv->status) <<
if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
IWL_WARNING("Radio disabled by SW RF kill (module "
"parameter)\n");
+ iwl_rfkill_set_hw_state(priv);
return -ENODEV;
}
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
+ iwl_rfkill_set_hw_state(priv);
IWL_WARNING("Radio disabled by HW RF Kill switch\n");
return -ENODEV;
}
}
+ iwl_rfkill_set_hw_state(priv);
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
rc = iwl4965_hw_nic_init(priv);
mutex_lock(&priv->mutex);
- if (!iwl4965_is_rfkill(priv)) {
+ if (!iwl_is_rfkill(priv)) {
IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL,
"HW and/or SW RF Kill no longer active, restarting "
"device\n");
if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
queue_work(priv->workqueue, &priv->restart);
} else {
+ /* make sure mac80211 stop sending Tx frame */
+ if (priv->mac80211_registered)
+ ieee80211_stop_queues(priv->hw);
if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
IWL_DEBUG_RF_KILL("Can not turn radio back on - "
"Kill switch must be turned off for "
"wireless networking to work.\n");
}
+ iwl_rfkill_set_hw_state(priv);
+
mutex_unlock(&priv->mutex);
}
mutex_lock(&priv->mutex);
- if (!iwl4965_is_ready(priv)) {
+ if (!iwl_is_ready(priv)) {
IWL_WARNING("request scan called when driver not ready.\n");
goto done;
}
goto done;
}
- if (iwl4965_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n");
goto done;
}
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
- if (iwl4965_is_associated(priv)) {
+ if (iwl_is_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
memcpy(scan->direct_scan[0].ssid,
priv->direct_ssid, priv->direct_ssid_len);
direct_mask = 1;
- } else if (!iwl4965_is_associated(priv) && priv->essid_len) {
+ } else if (!iwl_is_associated(priv) && priv->essid_len) {
scan->direct_scan[0].id = WLAN_EID_SSID;
scan->direct_scan[0].len = priv->essid_len;
memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
- if (!iwl4965_is_ready(priv))
+ if (!iwl_is_ready(priv))
return;
mutex_lock(&priv->mutex);
priv->is_open = 0;
- if (iwl4965_is_ready_rf(priv)) {
+ if (iwl_is_ready_rf(priv)) {
/* stop mac, cancel any scan request and clear
* RXON_FILTER_ASSOC_MSK BIT
*/
memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
}
- if (iwl4965_is_ready(priv))
+ if (iwl_is_ready(priv))
iwl4965_set_mode(priv, conf->type);
mutex_unlock(&priv->mutex);
priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
- if (!iwl4965_is_ready(priv)) {
+ if (!iwl_is_ready(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
ret = -EIO;
goto out;
}
#endif
- iwl4965_radio_kill_sw(priv, !conf->radio_enabled);
+ if (priv->cfg->ops->lib->radio_kill_sw)
+ priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled);
if (!conf->radio_enabled) {
IWL_DEBUG_MAC80211("leave - radio disabled\n");
goto out;
}
- if (iwl4965_is_rfkill(priv)) {
+ if (iwl_is_rfkill(priv)) {
IWL_DEBUG_MAC80211("leave - RF kill\n");
ret = -EIO;
goto out;
return 0;
}
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
priv->ibss_beacon = conf->beacon;
}
- if (iwl4965_is_rfkill(priv))
+ if (iwl_is_rfkill(priv))
goto done;
if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
mutex_lock(&priv->mutex);
- if (iwl4965_is_ready_rf(priv)) {
+ if (iwl_is_ready_rf(priv)) {
iwl4965_scan_cancel_timeout(priv, 100);
cancel_delayed_work(&priv->post_associate);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
}
+
+#ifdef CONFIG_IWL4965_HT
+static void iwl4965_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf;
+ struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf;
+ struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+
+ IWL_DEBUG_MAC80211("enter: \n");
+
+ iwl_conf->is_ht = bss_conf->assoc_ht;
+
+ if (!iwl_conf->is_ht)
+ return;
+
+ priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+ iwl_conf->sgf |= 0x1;
+ if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+ iwl_conf->sgf |= 0x2;
+
+ iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+ iwl_conf->max_amsdu_size =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
+ iwl_conf->supported_chan_width =
+ !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
+ iwl_conf->extension_chan_offset =
+ ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+ /* If no above or below channel supplied disable FAT channel */
+ if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
+ iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
+ iwl_conf->supported_chan_width = 0;
+
+ iwl_conf->tx_mimo_ps_mode =
+ (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
+ memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
+
+ iwl_conf->control_channel = ht_bss_conf->primary_channel;
+ iwl_conf->tx_chan_width =
+ !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
+ iwl_conf->ht_protection =
+ ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
+ iwl_conf->non_GF_STA_present =
+ !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
+
+ IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel);
+ IWL_DEBUG_MAC80211("leave\n");
+}
+#else
+static inline void iwl4965_ht_conf(struct iwl_priv *priv,
+ struct ieee80211_bss_conf *bss_conf)
+{
+}
+#endif
+
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
{
struct iwl_priv *priv = hw->priv;
+ IWL_DEBUG_MAC80211("changes = 0x%X\n", changes);
+
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+ IWL_DEBUG_MAC80211("ERP_PREAMBLE %d\n",
+ bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+ IWL_DEBUG_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
}
+ if (changes & BSS_CHANGED_HT) {
+ IWL_DEBUG_MAC80211("HT %d\n", bss_conf->assoc_ht);
+ iwl4965_ht_conf(priv, bss_conf);
+ iwl4965_set_rxon_chain(priv);
+ }
+
if (changes & BSS_CHANGED_ASSOC) {
- /*
- * TODO:
- * do stuff instead of sniffing assoc resp
- */
+ IWL_DEBUG_MAC80211("ASSOC %d\n", bss_conf->assoc);
+ if (bss_conf->assoc) {
+ priv->assoc_id = bss_conf->aid;
+ priv->beacon_int = bss_conf->beacon_int;
+ priv->timestamp = bss_conf->timestamp;
+ priv->assoc_capability = bss_conf->assoc_capability;
+ priv->next_scan_jiffies = jiffies +
+ IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+ queue_work(priv->workqueue, &priv->post_associate.work);
+ } else {
+ priv->assoc_id = 0;
+ IWL_DEBUG_MAC80211("DISASSOC %d\n", bss_conf->assoc);
+ }
+ } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+ IWL_DEBUG_MAC80211("Associated Changes %d\n", changes);
+ iwl4965_send_rxon_assoc(priv);
}
- if (iwl4965_is_associated(priv))
- iwl4965_send_rxon_assoc(priv);
}
static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
mutex_lock(&priv->mutex);
spin_lock_irqsave(&priv->lock, flags);
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
rc = -EIO;
IWL_DEBUG_MAC80211("leave - not ready or exit pending\n");
goto out_unlock;
/* FIXME: need to differenciate between static and dynamic key
* in the level of mac80211 */
- static_key = !iwl4965_is_associated(priv);
+ static_key = !iwl_is_associated(priv);
if (!static_key) {
sta_id = iwl4965_hw_find_station(priv, addr);
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
return -EIO;
}
mutex_lock(&priv->mutex);
if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
iwl4965_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl4965_is_associated(priv))
+ else if (priv->assoc_id && iwl_is_associated(priv))
iwl4965_activate_qos(priv, 0);
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
return -EIO;
}
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
- priv->call_post_assoc_from_beacon = 0;
priv->assoc_station_added = 0;
/* new association get rid of ibss beacon skb */
priv->ibss_beacon = NULL;
priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp1 = 0;
- priv->timestamp0 = 0;
+ priv->timestamp = 0;
if ((priv->iw_mode == IEEE80211_IF_TYPE_STA))
priv->beacon_int = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
mutex_unlock(&priv->mutex);
return;
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter\n");
- if (!iwl4965_is_ready_rf(priv)) {
+ if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_MAC80211("leave - RF not ready\n");
mutex_unlock(&priv->mutex);
return -EIO;
return 0;
}
-#ifdef CONFIG_IWL4965_HT
-
-static void iwl4965_ht_info_fill(struct ieee80211_conf *conf,
- struct iwl_priv *priv)
-{
- struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
- struct ieee80211_ht_info *ht_conf = &conf->ht_conf;
- struct ieee80211_ht_bss_info *ht_bss_conf = &conf->ht_bss_conf;
-
- IWL_DEBUG_MAC80211("enter: \n");
-
- if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) {
- iwl_conf->is_ht = 0;
- return;
- }
-
- iwl_conf->is_ht = 1;
- priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
-
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
- iwl_conf->sgf |= 0x1;
- if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
- iwl_conf->sgf |= 0x2;
-
- iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
- iwl_conf->max_amsdu_size =
- !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
- iwl_conf->supported_chan_width =
- !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
- iwl_conf->extension_chan_offset =
- ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
- /* If no above or below channel supplied disable FAT channel */
- if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
- iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
- iwl_conf->supported_chan_width = 0;
-
- iwl_conf->tx_mimo_ps_mode =
- (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
- memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
-
- iwl_conf->control_channel = ht_bss_conf->primary_channel;
- iwl_conf->tx_chan_width =
- !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
- iwl_conf->ht_protection =
- ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION;
- iwl_conf->non_GF_STA_present =
- !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT);
-
- IWL_DEBUG_MAC80211("control channel %d\n",
- iwl_conf->control_channel);
- IWL_DEBUG_MAC80211("leave\n");
-}
-
-static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211("enter: \n");
-
- iwl4965_ht_info_fill(conf, priv);
- iwl4965_set_rxon_chain(priv);
-
- if (priv && priv->assoc_id &&
- (priv->iw_mode == IEEE80211_IF_TYPE_STA)) {
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- if (priv->beacon_int)
- queue_work(priv->workqueue, &priv->post_associate.work);
- else
- priv->call_post_assoc_from_beacon = 1;
- spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- IWL_DEBUG_MAC80211("leave:\n");
- return 0;
-}
-
-#endif /*CONFIG_IWL4965_HT*/
-
/*****************************************************************************
*
* sysfs attributes
#endif /* CONFIG_IWLWIFI_DEBUG */
-static ssize_t show_rf_kill(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- /*
- * 0 - RF kill not enabled
- * 1 - SW based RF kill active (sysfs)
- * 2 - HW based RF kill active
- * 3 - Both HW and SW based RF kill active
- */
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) |
- (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0);
-
- return sprintf(buf, "%i\n", val);
-}
-
-static ssize_t store_rf_kill(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
-
- mutex_lock(&priv->mutex);
- iwl4965_radio_kill_sw(priv, buf[0] == '1');
- mutex_unlock(&priv->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv));
mode = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
- if (!iwl4965_is_ready(priv)) {
+ if (!iwl_is_ready(priv)) {
rc = -EAGAIN;
goto out;
}
u8 *data = (u8 *) & priv->statistics;
int rc = 0;
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
mutex_lock(&priv->mutex);
{
struct iwl_priv *priv = dev_get_drvdata(d);
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "%d\n", priv->antenna);
struct device_attribute *attr, char *buf)
{
struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
- if (!iwl4965_is_alive(priv))
+ if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
}
#endif
&dev_attr_power_level.attr,
&dev_attr_retry_rate.attr,
- &dev_attr_rf_kill.attr,
&dev_attr_rs_window.attr,
&dev_attr_statistics.attr,
&dev_attr_status.attr,
.beacon_update = iwl4965_mac_beacon_update,
.bss_info_changed = iwl4965_bss_info_changed,
#ifdef CONFIG_IWL4965_HT
- .conf_ht = iwl4965_mac_conf_ht,
.ampdu_action = iwl4965_mac_ampdu_action,
#endif /* CONFIG_IWL4965_HT */
.hw_scan = iwl4965_mac_hw_scan
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+ unsigned long flags;
DECLARE_MAC_BUF(mac);
/************************
/********************
* 8. Setup services
********************/
+ spin_lock_irqsave(&priv->lock, flags);
iwl4965_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group);
if (err) {
struct iwl_priv *priv = pci_get_drvdata(pdev);
struct list_head *p, *q;
int i;
+ unsigned long flags;
if (!priv)
return;
IWL_DEBUG_INFO("*** UNLOAD DRIVER ***\n");
+ if (priv->mac80211_registered) {
+ ieee80211_unregister_hw(priv->hw);
+ priv->mac80211_registered = 0;
+ }
+
set_bit(STATUS_EXIT_PENDING, &priv->status);
iwl4965_down(priv);
+ /* make sure we flush any pending irq or
+ * tasklet for the driver
+ */
+ spin_lock_irqsave(&priv->lock, flags);
+ iwl4965_disable_interrupts(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ iwl_synchronize_irq(priv);
+
/* Free MAC hash list for ADHOC */
for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
iwl4965_unset_hw_setting(priv);
iwlcore_clear_stations_table(priv);
- if (priv->mac80211_registered) {
- ieee80211_unregister_hw(priv->hw);
- iwl4965_rate_control_unregister(priv->hw);
- }
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
int ret;
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
+
+ ret = iwl4965_rate_control_register();
+ if (ret) {
+ IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
+ return ret;
+ }
+
ret = pci_register_driver(&iwl4965_driver);
if (ret) {
IWL_ERROR("Unable to initialize PCI module\n");
- return ret;
+ goto error_register;
}
#ifdef CONFIG_IWLWIFI_DEBUG
ret = driver_create_file(&iwl4965_driver.driver, &driver_attr_debug_level);
if (ret) {
IWL_ERROR("Unable to create driver sysfs file\n");
- pci_unregister_driver(&iwl4965_driver);
- return ret;
+ goto error_debug;
}
#endif
return ret;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+error_debug:
+ pci_unregister_driver(&iwl4965_driver);
+#endif
+error_register:
+ iwl4965_rate_control_unregister();
+ return ret;
}
static void __exit iwl4965_exit(void)
driver_remove_file(&iwl4965_driver.driver, &driver_attr_debug_level);
#endif
pci_unregister_driver(&iwl4965_driver);
+ iwl4965_rate_control_unregister();
}
module_exit(iwl4965_exit);