summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c1455
1 files changed, 206 insertions, 1249 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index ff4d0e41d7c..cb9bd4c8f25 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -95,188 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
/* the rest are 0 by default */
};
-/*************** STATION TABLE MANAGEMENT ****
- * mac80211 should be examined to determine if sta_info is duplicating
- * the functionality provided here
- */
-
-/**************************************************************/
-#if 0 /* temporary disable till we add real remove station */
-/**
- * iwl3945_remove_station - Remove driver's knowledge of station.
- *
- * NOTE: This does not remove station from device's station table.
- */
-static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
-{
- int index = IWL_INVALID_STATION;
- int i;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
- if (priv->stations_39[i].used &&
- !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (unlikely(index == IWL_INVALID_STATION))
- goto out;
-
- if (priv->stations_39[index].used) {
- priv->stations_39[index].used = 0;
- priv->num_stations--;
- }
-
- BUG_ON(priv->num_stations < 0);
-
-out:
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return 0;
-}
-#endif
-
-/**
- * iwl3945_clear_stations_table - Clear the driver's station table
- *
- * NOTE: This does not clear or otherwise alter the device's station table.
- */
-static void iwl3945_clear_stations_table(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
-
- priv->num_stations = 0;
- memset(priv->stations_39, 0, sizeof(priv->stations_39));
-
- spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-
-/**
- * iwl3945_add_station - Add station to station tables in driver and device
- */
-u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
-{
- int i;
- int index = IWL_INVALID_STATION;
- struct iwl3945_station_entry *station;
- unsigned long flags_spin;
- u8 rate;
-
- spin_lock_irqsave(&priv->sta_lock, flags_spin);
- if (is_ap)
- index = IWL_AP_ID;
- else if (is_broadcast_ether_addr(addr))
- index = priv->hw_params.bcast_sta_id;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
- if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
- addr)) {
- index = i;
- break;
- }
-
- if (!priv->stations_39[i].used &&
- index == IWL_INVALID_STATION)
- index = i;
- }
-
- /* These two conditions has the same outcome but keep them separate
- since they have different meaning */
- if (unlikely(index == IWL_INVALID_STATION)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
- if (priv->stations_39[index].used &&
- !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
- return index;
- }
-
- IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
- station = &priv->stations_39[index];
- station->used = 1;
- priv->num_stations++;
-
- /* Set up the REPLY_ADD_STA command to send to device */
- memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
- memcpy(station->sta.sta.addr, addr, ETH_ALEN);
- station->sta.mode = 0;
- station->sta.sta.sta_id = index;
- station->sta.station_flags = 0;
-
- if (priv->band == IEEE80211_BAND_5GHZ)
- rate = IWL_RATE_6M_PLCP;
- else
- rate = IWL_RATE_1M_PLCP;
-
- /* Turn on both antennas for the station... */
- station->sta.rate_n_flags =
- iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
-
- spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-
- /* Add station to device's station table */
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&station->sta, flags);
- return index;
-
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
-{
- int rc = 0;
- struct iwl_rx_packet *res = NULL;
- struct iwl3945_rxon_assoc_cmd rxon_assoc;
- struct iwl_host_cmd cmd = {
- .id = REPLY_RXON_ASSOC,
- .len = sizeof(rxon_assoc),
- .meta.flags = CMD_WANT_SKB,
- .data = &rxon_assoc,
- };
- const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
- const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
-
- if ((rxon1->flags == rxon2->flags) &&
- (rxon1->filter_flags == rxon2->filter_flags) &&
- (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
- (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
- IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
- return 0;
- }
-
- rxon_assoc.flags = priv->staging_rxon.flags;
- rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
- rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
- rxon_assoc.reserved = 0;
-
- rc = iwl_send_cmd_sync(priv, &cmd);
- if (rc)
- return rc;
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
- rc = -EIO;
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
/**
* iwl3945_get_antenna_flags - Get antenna flags for RXON command
* @priv: eeprom and antenna fields are used to determine antenna flags
@@ -314,150 +132,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
return 0; /* "diversity" is default if error */
}
-/**
- * iwl3945_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data. This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
-{
- /* cast away the const for active_rxon in this function */
- struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
- struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
- int rc = 0;
- bool new_assoc =
- !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
-
- if (!iwl_is_alive(priv))
- return -1;
-
- /* always get timestamp with Rx frame */
- staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
-
- /* select antenna */
- staging_rxon->flags &=
- ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
- staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
-
- rc = iwl_check_rxon_cmd(priv);
- if (rc) {
- IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
- return -EINVAL;
- }
-
- /* If we don't need to send a full RXON, we can use
- * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
- * and other flags for the current radio configuration. */
- if (!iwl_full_rxon_required(priv)) {
- rc = iwl3945_send_rxon_assoc(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting RXON_ASSOC "
- "configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- return 0;
- }
-
- /* If we are currently associated and the new config requires
- * 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 (iwl_is_associated(priv) && new_assoc) {
- IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
- active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- active_rxon->reserved4 = 0;
- active_rxon->reserved5 = 0;
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- &priv->active_rxon);
-
- /* If the mask clearing failed then we set
- * active_rxon back to what it was previously */
- if (rc) {
- active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
- IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
- "configuration (%d).\n", rc);
- return rc;
- }
- }
-
- IWL_DEBUG_INFO(priv, "Sending RXON\n"
- "* with%s RXON_FILTER_ASSOC_MSK\n"
- "* channel = %d\n"
- "* bssid = %pM\n",
- (new_assoc ? "" : "out"),
- le16_to_cpu(staging_rxon->channel),
- staging_rxon->bssid_addr);
-
- /*
- * reserved4 and 5 could have been filled by the iwlcore code.
- * Let's clear them before pushing to the 3945.
- */
- staging_rxon->reserved4 = 0;
- staging_rxon->reserved5 = 0;
-
- iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
-
- /* Apply the new configuration */
- rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
- sizeof(struct iwl3945_rxon_cmd),
- staging_rxon);
- if (rc) {
- IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
- return rc;
- }
-
- memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
- iwl3945_clear_stations_table(priv);
-
- /* If we issue a new RXON command which required a tune then we must
- * send a new TXPOWER command or we won't be able to Tx any frames */
- rc = priv->cfg->ops->lib->send_tx_power(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
- return rc;
- }
-
- /* Add the broadcast address so we can send broadcast frames */
- if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
- IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
- return -EIO;
- }
-
- /* 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 (iwl_is_associated(priv) &&
- (priv->iw_mode == NL80211_IFTYPE_STATION))
- if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
- 1, 0)
- == IWL_INVALID_STATION) {
- IWL_ERR(priv, "Error adding AP address for transmit\n");
- return -EIO;
- }
-
- /* Init the hardware's rate fallback order based on the band */
- rc = iwl3945_init_hw_rate_table(priv);
- if (rc) {
- IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
- return -EIO;
- }
-
- return 0;
-}
-
static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
@@ -477,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
key_flags &= ~STA_KEY_FLG_INVALID;
spin_lock_irqsave(&priv->sta_lock, flags);
- priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
- priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
- memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
+ priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+ priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+ memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
keyconf->keylen);
- memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+ memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
keyconf->keylen);
- if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+ if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
== STA_KEY_FLG_NO_ENC)
- priv->stations_39[sta_id].sta.key.key_offset =
+ priv->stations[sta_id].sta.key.key_offset =
iwl_get_free_ucode_key_index(priv);
/* else, we are overriding an existing key => no need to allocated room
* in uCode. */
- WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+ WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
"no space for a new key");
- priv->stations_39[sta_id].sta.key.key_flags = key_flags;
- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ priv->stations[sta_id].sta.key.key_flags = key_flags;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
- ret = iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
+ ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -528,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
unsigned long flags;
spin_lock_irqsave(&priv->sta_lock, flags);
- memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
- memset(&priv->stations_39[sta_id].sta.key, 0,
+ memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
+ memset(&priv->stations[sta_id].sta.key, 0,
sizeof(struct iwl4965_keyinfo));
- priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
- priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
- priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+ priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+ priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+ priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
spin_unlock_irqrestore(&priv->sta_lock, flags);
IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
- iwl_send_add_sta(priv,
- (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
+ iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
return 0;
}
@@ -739,7 +411,8 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.atim_window = 0;
} else {
priv->rxon_timing.beacon_interval =
- iwl3945_adjust_beacon_interval(conf->beacon_int);
+ iwl3945_adjust_beacon_interval(
+ priv->vif->bss_conf.beacon_int);
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
@@ -758,35 +431,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
le16_to_cpu(priv->rxon_timing.atim_window));
}
-static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
-{
- if (mode == NL80211_IFTYPE_ADHOC) {
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv,
- priv->band,
- le16_to_cpu(priv->staging_rxon.channel));
-
- if (!ch_info || !is_channel_ibss(ch_info)) {
- IWL_ERR(priv, "channel %d not IBSS channel\n",
- le16_to_cpu(priv->staging_rxon.channel));
- return -EINVAL;
- }
- }
-
- iwl_connection_init_rx_config(priv, mode);
-
- iwl3945_clear_stations_table(priv);
-
- /* don't commit rxon if rf-kill is on*/
- if (!iwl_is_ready_rf(priv))
- return -EAGAIN;
-
- iwl3945_commit_rxon(priv);
-
- return 0;
-}
-
static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
struct ieee80211_tx_info *info,
struct iwl_cmd *cmd,
@@ -794,8 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
int sta_id)
{
struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
- struct iwl3945_hw_key *keyinfo =
- &priv->stations_39[sta_id].keyinfo;
+ struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
switch (keyinfo->alg) {
case ALG_CCMP:
@@ -893,64 +536,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
tx->next_frame_len = 0;
}
-/**
- * iwl3945_get_sta_id - Find station's index within station table
- */
-static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
- int sta_id;
- u16 fc = le16_to_cpu(hdr->frame_control);
-
- /* If this frame is broadcast or management, use broadcast station id */
- if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
- is_multicast_ether_addr(hdr->addr1))
- return priv->hw_params.bcast_sta_id;
-
- switch (priv->iw_mode) {
-
- /* If we are a client station in a BSS network, use the special
- * AP station entry (that's the only station we communicate with) */
- case NL80211_IFTYPE_STATION:
- return IWL_AP_ID;
-
- /* If we are an AP, then find the station, or use BCAST */
- case NL80211_IFTYPE_AP:
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
- return priv->hw_params.bcast_sta_id;
-
- /* If this frame is going out to an IBSS network, find the station,
- * or create a new station table entry */
- case NL80211_IFTYPE_ADHOC: {
- /* Create new station table entry */
- sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
-
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
- "Defaulting to broadcast...\n",
- hdr->addr1);
- iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_params.bcast_sta_id;
- }
- /* If we are in monitor mode, use BCAST. This is required for
- * packet injection. */
- case NL80211_IFTYPE_MONITOR:
- return priv->hw_params.bcast_sta_id;
-
- default:
- IWL_WARN(priv, "Unknown mode of operation: %d\n",
- priv->iw_mode);
- return priv->hw_params.bcast_sta_id;
- }
-}
-
/*
* start REPLY_TX command process
*/
@@ -1004,7 +589,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* drop all data frame if we are not associated */
if (ieee80211_is_data(fc) &&
- (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
+ (!iwl_is_monitor_mode(priv)) && /* packet injection */
(!iwl_is_associated(priv) ||
((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
@@ -1016,7 +601,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find (or create) index into station table for destination station */
- sta_id = iwl3945_get_sta_id(priv, hdr);
+ sta_id = iwl_get_sta_id(priv, hdr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -1028,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
- seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
+ seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
hdr->seq_ctrl = cpu_to_le16(seq_number) |
(hdr->seq_ctrl &
@@ -1088,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
- priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+ priv->stations[sta_id].tid[tid].seq_number = seq_number;
} else {
wait_write_ptr = 1;
txq->need_update = 0;
@@ -1424,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
clear_bit(STATUS_RF_KILL_HW, &priv->status);
- if (flags & SW_CARD_DISABLED)
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- else
- clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
iwl_scan_cancel(priv);
if ((test_bit(STATUS_RF_KILL_HW, &status) !=
- test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
- (test_bit(STATUS_RF_KILL_SW, &status) !=
- test_bit(STATUS_RF_KILL_SW, &priv->status)))
- queue_work(priv->workqueue, &priv->rf_kill);
+ test_bit(STATUS_RF_KILL_HW, &priv->status)))
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
else
wake_up_interruptible(&priv->wait_command_queue);
}
@@ -1591,7 +1170,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
/* If we've added more space for the firmware to place data, tell it.
* Increment device's write pointer in multiples of 8. */
- if ((write != (rxq->write & ~0x7))
+ if ((rxq->write_actual != (rxq->write & ~0x7))
|| (abs(rxq->write - rxq->read) > 7)) {
spin_lock_irqsave(&rxq->lock, flags);
rxq->need_update = 1;
@@ -1612,21 +1191,30 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
* Also restock the Rx queue via iwl3945_rx_queue_restock.
* This is called as a scheduled work item (except for during initialization)
*/
-static void iwl3945_rx_allocate(struct iwl_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
{
struct iwl_rx_queue *rxq = &priv->rxq;
struct list_head *element;
struct iwl_rx_mem_buffer *rxb;
unsigned long flags;
- spin_lock_irqsave(&rxq->lock, flags);
- while (!list_empty(&rxq->rx_used)) {
+
+ while (1) {
+ spin_lock_irqsave(&rxq->lock, flags);
+
+ if (list_empty(&rxq->rx_used)) {
+ spin_unlock_irqrestore(&rxq->lock, flags);
+ return;
+ }
+
element = rxq->rx_used.next;
rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+ list_del(element);
+ spin_unlock_irqrestore(&rxq->lock, flags);
/* Alloc a new receive buffer */
rxb->skb =
alloc_skb(priv->hw_params.rx_buf_size,
- __GFP_NOWARN | GFP_ATOMIC);
+ priority);
if (!rxb->skb) {
if (net_ratelimit())
IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1644,18 +1232,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
*/
skb_reserve(rxb->skb, 4);
- priv->alloc_rxb_skb++;
- list_del(element);
-
/* Get physical address of RB/SKB */
rxb->real_dma_addr = pci_map_single(priv->pci_dev,
rxb->skb->data,
priv->hw_params.rx_buf_size,
PCI_DMA_FROMDEVICE);
+
+ spin_lock_irqsave(&rxq->lock, flags);
list_add_tail(&rxb->list, &rxq->rx_free);
+ priv->alloc_rxb_skb++;
rxq->free_count++;
+ spin_unlock_irqrestore(&rxq->lock, flags);
}
- spin_unlock_irqrestore(&rxq->lock, flags);
}
void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1685,33 +1273,30 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
* not restocked the Rx queue with fresh buffers */
rxq->read = rxq->write = 0;
rxq->free_count = 0;
+ rxq->write_actual = 0;
spin_unlock_irqrestore(&rxq->lock, flags);
}
-/*
- * this should be called while priv->lock is locked
- */
-static void __iwl3945_rx_replenish(void *data)
-{
- struct iwl_priv *priv = data;
-
- iwl3945_rx_allocate(priv);
- iwl3945_rx_queue_restock(priv);
-}
-
-
void iwl3945_rx_replenish(void *data)
{
struct iwl_priv *priv = data;
unsigned long flags;
- iwl3945_rx_allocate(priv);
+ iwl3945_rx_allocate(priv, GFP_KERNEL);
spin_lock_irqsave(&priv->lock, flags);
iwl3945_rx_queue_restock(priv);
spin_unlock_irqrestore(&priv->lock, flags);
}
+static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
+{
+ iwl3945_rx_allocate(priv, GFP_ATOMIC);
+
+ iwl3945_rx_queue_restock(priv);
+}
+
+
/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
* If an SKB has been detached, the POOL needs to have its SKB set to NULL
* This free routine walks the list of POOL entries and if SKB is set to
@@ -1834,13 +1419,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
unsigned long flags;
u8 fill_rx = 0;
u32 count = 8;
+ int total_empty = 0;
/* uCode's read index (stored in shared DRAM) indicates the last Rx
* buffer that the driver may process (last buffer filled by ucode). */
r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
i = rxq->read;
- if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+ /* calculate total frames need to be restock after handling RX */
+ total_empty = r - priv->rxq.write_actual;
+ if (total_empty < 0)
+ total_empty += RX_QUEUE_SIZE;
+
+ if (total_empty > (RX_QUEUE_SIZE / 2))
fill_rx = 1;
/* Rx interrupt, but nothing sent from uCode */
if (i == r)
@@ -1879,6 +1470,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
"r = %d, i = %d, %s, 0x%02x\n", r, i,
get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+ priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
} else {
/* No handling needed */
IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
@@ -1916,7 +1508,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
count++;
if (count >= 8) {
priv->rxq.read = i;
- __iwl3945_rx_replenish(priv);
+ iwl3945_rx_replenish_now(priv);
count = 0;
}
}
@@ -1924,7 +1516,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
/* Backtrack one entry */
priv->rxq.read = i;
- iwl3945_rx_queue_restock(priv);
+ if (fill_rx)
+ iwl3945_rx_replenish_now(priv);
+ else
+ iwl3945_rx_queue_restock(priv);
}
/* call this function to flush any scheduled tasklet */
@@ -1963,7 +1558,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
u32 i;
u32 desc, time, count, base, data1;
u32 blink1, blink2, ilink1, ilink2;
- int rc;
base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
@@ -1972,11 +1566,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
return;
}
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
count = iwl_read_targ_mem(priv, base);
@@ -2011,8 +1600,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
ilink1, ilink2, data1);
}
- iwl_release_nic_access(priv);
-
}
#define EVENT_START_OFFSET (6 * sizeof(u32))
@@ -2020,7 +1607,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
/**
* iwl3945_print_event_log - Dump error event log to syslog
*
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
*/
static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
u32 num_events, u32 mode)
@@ -2063,7 +1649,6 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
{
- int rc;
u32 base; /* SRAM byte address of event log header */
u32 capacity; /* event log capacity in # entries */
u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
@@ -2077,12 +1662,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
return;
}
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read from adapter at this time.\n");
- return;
- }
-
/* event log header */
capacity = iwl_read_targ_mem(priv, base);
mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -2094,7 +1673,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
/* bail out if nothing in log */
if (size == 0) {
IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
- iwl_release_nic_access(priv);
return;
}
@@ -2110,24 +1688,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
/* (then/else) start at top of log */
iwl3945_print_event_log(priv, 0, next_entry, mode);
- iwl_release_nic_access(priv);
-}
-
-static void iwl3945_error_recovery(struct iwl_priv *priv)
-{
- unsigned long flags;
-
- memcpy(&priv->staging_rxon, &priv->recovery_rxon,
- sizeof(priv->staging_rxon));
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
-
- iwl3945_add_station(priv, priv->bssid, 1, 0);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
- priv->error_recovering = 0;
- spin_unlock_irqrestore(&priv->lock, flags);
}
static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2178,6 +1738,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
/* Tell the device to stop sending interrupts */
iwl_disable_interrupts(priv);
+ priv->isr_stats.hw++;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_HW_ERR;
@@ -2190,13 +1751,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
- if (inta & CSR_INT_BIT_SCD)
+ if (inta & CSR_INT_BIT_SCD) {
IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
"the frame/frames.\n");
+ priv->isr_stats.sch++;
+ }
/* Alive notification via Rx interrupt will do the real work */
- if (inta & CSR_INT_BIT_ALIVE)
+ if (inta & CSR_INT_BIT_ALIVE) {
IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+ priv->isr_stats.alive++;
+ }
}
#endif
/* Safely ignore these bits for debug checks below */
@@ -2206,6 +1771,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
if (inta & CSR_INT_BIT_SW_ERR) {
IWL_ERR(priv, "Microcode SW error detected. "
"Restarting 0x%X.\n", inta);
+ priv->isr_stats.sw++;
+ priv->isr_stats.sw_err = inta;
iwl_irq_handle_error(priv);
handled |= CSR_INT_BIT_SW_ERR;
}
@@ -2221,6 +1788,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
iwl_txq_update_write_ptr(priv, &priv->txq[4]);
iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+ priv->isr_stats.wakeup++;
handled |= CSR_INT_BIT_WAKEUP;
}
@@ -2229,27 +1797,28 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
* notifications from uCode come through here*/
if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
iwl3945_rx_handle(priv);
+ priv->isr_stats.rx++;
handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
}
if (inta & CSR_INT_BIT_FH_TX) {
IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+ priv->isr_stats.tx++;
iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_direct32(priv, FH39_TCSR_CREDIT
- (FH39_SRVC_CHNL), 0x0);
- iwl_release_nic_access(priv);
- }
+ iwl_write_direct32(priv, FH39_TCSR_CREDIT
+ (FH39_SRVC_CHNL), 0x0);
handled |= CSR_INT_BIT_FH_TX;
}
- if (inta & ~handled)
+ if (inta & ~handled) {
IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+ priv->isr_stats.unhandled++;
+ }
- if (inta & ~CSR_INI_SET_MASK) {
+ if (inta & ~priv->inta_mask) {
IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
- inta & ~CSR_INI_SET_MASK);
+ inta & ~priv->inta_mask);
IWL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
}
@@ -2413,10 +1982,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
IWL39_RTC_INST_LOWER_BOUND);
@@ -2437,7 +2002,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
}
}
- iwl_release_nic_access(priv);
if (!errcnt)
IWL_DEBUG_INFO(priv,
@@ -2461,10 +2025,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- return rc;
-
for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
/* read data comes through single port, auto-incr addr */
/* NOTE: Use the debugless read so we don't flood kernel log
@@ -2485,8 +2045,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
}
}
- iwl_release_nic_access(priv);
-
return rc;
}
@@ -2810,20 +2368,11 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
{
dma_addr_t pinst;
dma_addr_t pdata;
- int rc = 0;
- unsigned long flags;
/* bits 31:0 for 3945 */
pinst = priv->ucode_code.p_addr;
pdata = priv->ucode_data_backup.p_addr;
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
/* Tell bootstrap uCode where to find image to load */
iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
@@ -2835,13 +2384,9 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
priv->ucode_code.len | BSM_DRAM_INST_LOAD);
- iwl_release_nic_access(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
- return rc;
+ return 0;
}
/**
@@ -2887,11 +2432,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
-
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
- struct sk_buff *skb);
-
/**
* iwl3945_alive_start - called after REPLY_ALIVE notification received
* from protocol/runtime uCode (initialization uCode's
@@ -2899,7 +2439,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
*/
static void iwl3945_alive_start(struct iwl_priv *priv)
{
- int rc = 0;
int thermal_spin = 0;
u32 rfkill;
@@ -2922,17 +2461,10 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
goto restart;
}
- iwl3945_clear_stations_table(priv);
-
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
- return;
- }
+ iwl_clear_stations_table(priv);
rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
- iwl_release_nic_access(priv);
if (rfkill & 0x1) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -2952,9 +2484,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(STATUS_ALIVE, &priv->status);
- /* Clear out the uCode error bit if it is set */
- clear_bit(STATUS_FW_ERROR, &priv->status);
-
if (iwl_is_rfkill(priv))
return;
@@ -2969,8 +2498,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
struct iwl3945_rxon_cmd *active_rxon =
(struct iwl3945_rxon_cmd *)(&priv->active_rxon);
- memcpy(&priv->staging_rxon, &priv->active_rxon,
- sizeof(priv->staging_rxon));
+ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
@@ -2981,7 +2509,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
iwl_send_bt_config(priv);
/* Configure the adapter for unassociated operation */
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
iwl3945_reg_txpower_periodic(priv);
@@ -2991,17 +2519,17 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
set_bit(STATUS_READY, &priv->status);
wake_up_interruptible(&priv->wait_command_queue);
- if (priv->error_recovering)
- iwl3945_error_recovery(priv);
-
/* reassociate for ADHOC mode */
if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
priv->vif);
if (beacon)
- iwl3945_mac_beacon_update(priv->hw, beacon);
+ iwl_mac_beacon_update(priv->hw, beacon);
}
+ if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+ iwl_set_mode(priv, priv->iw_mode);
+
return;
restart:
@@ -3024,7 +2552,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);
iwl3945_led_unregister(priv);
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -3047,31 +2575,23 @@ static void __iwl3945_down(struct iwl_priv *priv)
ieee80211_stop_queues(priv->hw);
/* If we have not previously called iwl3945_init() then
- * clear all bits but the RF Kill and SUSPEND bits and return */
+ * clear all bits but the RF Kill bits and return */
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) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
STATUS_EXIT_PENDING;
goto exit;
}
- /* ...otherwise clear out all the status bits but the RF Kill and
- * SUSPEND bits and continue taking the NIC down. */
+ /* ...otherwise clear out all the status bits but the RF Kill
+ * bit and continue taking the NIC down. */
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
STATUS_RF_KILL_HW |
- test_bit(STATUS_RF_KILL_SW, &priv->status) <<
- STATUS_RF_KILL_SW |
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
STATUS_GEO_CONFIGURED |
- test_bit(STATUS_IN_SUSPEND, &priv->status) <<
- STATUS_IN_SUSPEND |
test_bit(STATUS_FW_ERROR, &priv->status) <<
STATUS_FW_ERROR |
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -3085,17 +2605,12 @@ static void __iwl3945_down(struct iwl_priv *priv)
iwl3945_hw_txq_ctx_stop(priv);
iwl3945_hw_rxq_stop(priv);
- spin_lock_irqsave(&priv->lock, flags);
- if (!iwl_grab_nic_access(priv)) {
- iwl_write_prph(priv, APMG_CLK_DIS_REG,
- APMG_CLK_VAL_DMA_CLK_RQT);
- iwl_release_nic_access(priv);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
+ iwl_write_prph(priv, APMG_CLK_DIS_REG,
+ APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);
- if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+ if (exit_pending)
priv->cfg->ops->lib->apm_ops.stop(priv);
else
priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -3131,12 +2646,6 @@ static int __iwl3945_up(struct iwl_priv *priv)
return -EIO;
}
- if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
- IWL_WARN(priv, "Radio disabled by SW RF kill (module "
- "parameter)\n");
- return -ENODEV;
- }
-
if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
IWL_ERR(priv, "ucode not available for device bring up\n");
return -EIO;
@@ -3148,10 +2657,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else {
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
- IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
- return -ENODEV;
- }
+ IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
+ return -ENODEV;
}
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@@ -3187,7 +2694,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
for (i = 0; i < MAX_HW_RESTARTS; i++) {
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
@@ -3255,15 +2762,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, rfkill_poll.work);
- unsigned long status = priv->status;
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
clear_bit(STATUS_RF_KILL_HW, &priv->status);
else
set_bit(STATUS_RF_KILL_HW, &priv->status);
- if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
- queue_work(priv->workqueue, &priv->rf_kill);
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
round_jiffies_relative(2 * HZ));
@@ -3283,9 +2789,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
int rc = 0;
struct iwl3945_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
- u8 n_probes = 2;
+ u8 n_probes = 0;
enum ieee80211_band band;
- DECLARE_SSID_BUF(ssid);
+ bool is_active = false;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -3386,18 +2892,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
scan_suspend_time, interval);
}
- /* We should add the ability for user to lock to PASSIVE ONLY */
- if (priv->one_direct_scan) {
- IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
- print_ssid(ssid, priv->direct_ssid,
- priv->direct_ssid_len));
- scan->direct_scan[0].id = WLAN_EID_SSID;
- scan->direct_scan[0].len = priv->direct_ssid_len;
- memcpy(scan->direct_scan[0].ssid,
- priv->direct_ssid, priv->direct_ssid_len);
- n_probes++;
+ if (priv->scan_request->n_ssids) {
+ int i, p = 0;
+ IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+ for (i = 0; i < priv->scan_request->n_ssids; i++) {
+ /* always does wildcard anyway */
+ if (!priv->scan_request->ssids[i].ssid_len)
+ continue;
+ scan->direct_scan[p].id = WLAN_EID_SSID;
+ scan->direct_scan[p].len =
+ priv->scan_request->ssids[i].ssid_len;
+ memcpy(scan->direct_scan[p].ssid,
+ priv->scan_request->ssids[i].ssid,
+ priv->scan_request->ssids[i].ssid_len);
+ n_probes++;
+ p++;
+ }
+ is_active = true;
} else
- IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
+ IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n");
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
@@ -3414,7 +2927,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
band = IEEE80211_BAND_2GHZ;
} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
- scan->good_CRC_th = IWL_GOOD_CRC_TH;
+ /*
+ * If active scaning is requested but a certain channel
+ * is marked passive, we can do active scanning if we
+ * detect transmissions.
+ */
+ scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
band = IEEE80211_BAND_5GHZ;
} else {
IWL_WARN(priv, "Invalid scan band count\n");
@@ -3422,19 +2940,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
}
scan->tx_cmd.len = cpu_to_le16(
- iwl_fill_probe_req(priv, band,
- (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+ iwl_fill_probe_req(priv,
+ (struct ieee80211_mgmt *)scan->data,
+ priv->scan_request->ie,
+ priv->scan_request->ie_len,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);
- if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+ if (iwl_is_monitor_mode(priv))
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
scan->channel_count =
- iwl3945_get_channels_for_scan(priv, band, 1, /* active */
- n_probes,
+ iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
if (scan->channel_count == 0) {
@@ -3482,7 +3001,6 @@ static void iwl3945_bg_up(struct work_struct *data)
mutex_lock(&priv->mutex);
__iwl3945_up(priv);
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
}
static void iwl3945_bg_restart(struct work_struct *data)
@@ -3492,8 +3010,17 @@ static void iwl3945_bg_restart(struct work_struct *data)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;
- iwl3945_down(priv);
- queue_work(priv->workqueue, &priv->up);
+ if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+ mutex_lock(&priv->mutex);
+ priv->vif = NULL;
+ priv->is_open = 0;
+ mutex_unlock(&priv->mutex);
+ iwl3945_down(priv);
+ ieee80211_restart_hw(priv->hw);
+ } else {
+ iwl3945_down(priv);
+ queue_work(priv->workqueue, &priv->up);
+ }
}
static void iwl3945_bg_rx_replenish(struct work_struct *data)
@@ -3511,7 +3038,7 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
#define IWL_DELAY_NEXT_SCAN (HZ*2)
-static void iwl3945_post_associate(struct iwl_priv *priv)
+void iwl3945_post_associate(struct iwl_priv *priv)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
@@ -3536,7 +3063,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
conf = ieee80211_get_hw_conf(priv->hw);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
iwl3945_setup_rxon_timing(priv);
@@ -3569,7 +3096,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
}
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
@@ -3579,7 +3106,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
case NL80211_IFTYPE_ADHOC:
priv->assoc_id = 1;
- iwl3945_add_station(priv, priv->bssid, 0, 0);
+ iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
iwl3945_sync_sta(priv, IWL_STA_ID,
(priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3601,8 +3128,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -3621,7 +3146,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
/* we should be verifying the device is ready to be opened */
mutex_lock(&priv->mutex);
- memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
@@ -3638,16 +3162,11 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
mutex_unlock(&priv->mutex);
- iwl_rfkill_set_hw_state(priv);
-
if (ret)
goto out_release_irq;
IWL_DEBUG_INFO(priv, "Start UP work.\n");
- if (test_bit(STATUS_IN_SUSPEND, &priv->status))
- return 0;
-
/* Wait for START_ALIVE from ucode. Otherwise callbacks from
* mac80211 will not be run successfully. */
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -3726,144 +3245,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}
-static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
- if (priv->vif) {
- IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
- return -EOPNOTSUPP;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->vif = conf->vif;
- priv->iw_mode = conf->type;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
-
- if (conf->mac_addr) {
- IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
- memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
- }
-
- if (iwl_is_ready(priv))
- iwl3945_set_mode(priv, conf->type);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-/**
- * iwl3945_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
- struct iwl_priv *priv = hw->priv;
- const struct iwl_channel_info *ch_info;
- struct ieee80211_conf *conf = &hw->conf;
- unsigned long flags;
- int ret = 0;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
- conf->channel->hw_value);
-
- if (!iwl_is_ready(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- ret = -EIO;
- goto out;
- }
-
- if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
- test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
- set_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return 0;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- ch_info = iwl_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
- if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN(priv,
- "Channel %d [%d] is INVALID for this band.\n",
- conf->channel->hw_value, conf->channel->band);
- IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
- spin_unlock_irqrestore(&priv->lock, flags);
- ret = -EINVAL;
- goto out;
- }
-
- iwl_set_rxon_channel(priv, conf->channel);
-
- iwl_set_flags_for_band(priv, conf->channel->band);
-
- /* The list of supported rates and rate mask can be different
- * for each phymode; since the phymode may have changed, reset
- * the rate mask to what mac80211 lists */
- iwl_set_rate(priv);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
- if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
- iwl3945_hw_channel_switch(priv, conf->channel);
- goto out;
- }
-#endif
-
- if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
- if (conf->radio_enabled &&
- iwl_radio_kill_sw_enable_radio(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
- "waiting for uCode\n");
- goto out;
- }
-
- if (!conf->radio_enabled) {
- iwl_radio_kill_sw_disable_radio(priv);
- IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
- goto out;
- }
- }
-
- if (iwl_is_rfkill(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
- ret = -EIO;
- goto out;
- }
-
- iwl_set_rate(priv);
-
- if (memcmp(&priv->active_rxon,
- &priv->staging_rxon, sizeof(priv->staging_rxon)))
- iwl3945_commit_rxon(priv);
- else
- IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-out:
- clear_bit(STATUS_CONF_PENDING, &priv->status);
- mutex_unlock(&priv->mutex);
- return ret;
-}
-
-static void iwl3945_config_ap(struct iwl_priv *priv)
+void iwl3945_config_ap(struct iwl_priv *priv)
{
int rc = 0;
@@ -3875,7 +3257,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
/* RXON - unassoc (to set timing command) */
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
/* RXON Timing */
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
@@ -3911,8 +3293,8 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
}
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
+ iwlcore_commit_rxon(priv);
+ iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
}
iwl3945_send_beacon_cmd(priv);
@@ -3921,189 +3303,6 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
* clear sta table, add BCAST sta... */
}
-static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
- int rc;
-
- if (conf == NULL)
- return -EIO;
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
- return 0;
- }
-
- /* handle this temporarily here */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
- conf->changed & IEEE80211_IFCC_BEACON) {
- struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
- if (!beacon)
- return -ENOMEM;
- mutex_lock(&priv->mutex);
- rc = iwl3945_mac_beacon_update(hw, beacon);
- mutex_unlock(&priv->mutex);
- if (rc)
- return rc;
- }
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
-
- mutex_lock(&priv->mutex);
-
- if (conf->bssid)
- IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
- !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
- if (priv->iw_mode == NL80211_IFTYPE_AP) {
- if (!conf->bssid) {
- conf->bssid = priv->mac_addr;
- memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
- IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
- conf->bssid);
- }
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
- }
-
- if (iwl_is_rfkill(priv))
- goto done;
-
- if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
- !is_multicast_ether_addr(conf->bssid)) {
- /* If there is currently a HW scan going on in the background
- * then we need to cancel it else the RXON below will fail. */
- if (iwl_scan_cancel_timeout(priv, 100)) {
- IWL_WARN(priv, "Aborted scan still in progress "
- "after 100ms\n");
- IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
- mutex_unlock(&priv->mutex);
- return -EAGAIN;
- }
- memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
- /* TODO: Audit driver for usage of these members and see
- * if mac80211 deprecates them (priv->bssid looks like it
- * shouldn't be there, but I haven't scanned the IBSS code
- * to verify) - jpk */
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl3945_config_ap(priv);
- else {
- rc = iwl3945_commit_rxon(priv);
- if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
- iwl3945_add_station(priv,
- priv->active_rxon.bssid_addr, 1, 0);
- }
-
- } else {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- done:
- IWL_DEBUG_MAC80211(priv, "leave\n");
- mutex_unlock(&priv->mutex);
-
- return 0;
-}
-
-static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- mutex_lock(&priv->mutex);
-
- if (iwl_is_ready_rf(priv)) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
- if (priv->vif == conf->vif) {
- priv->vif = NULL;
- memset(priv->bssid, 0, ETH_ALEN);
- }
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-
-static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *bss_conf,
- u32 changes)
-{
- struct iwl_priv *priv = hw->priv;
-
- IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
- if (changes & BSS_CHANGED_ERP_PREAMBLE) {
- IWL_DEBUG_MAC80211(priv, "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
- priv->staging_rxon.flags &=
- ~RXON_FLG_SHORT_PREAMBLE_MSK;
- }
-
- if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- IWL_DEBUG_MAC80211(priv, "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_ASSOC) {
- IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
- /* This should never happen as this function should
- * never be called from interrupt context. */
- if (WARN_ON_ONCE(in_interrupt()))
- return;
- 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->power_data.dtim_period = bss_conf->dtim_period;
- priv->next_scan_jiffies = jiffies +
- IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
- mutex_lock(&priv->mutex);
- iwl3945_post_associate(priv);
- mutex_unlock(&priv->mutex);
- } else {
- priv->assoc_id = 0;
- IWL_DEBUG_MAC80211(priv,
- "DISASSOC %d\n", bss_conf->assoc);
- }
- } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
- IWL_DEBUG_MAC80211(priv,
- "Associated Changes %d\n", changes);
- iwl3945_send_rxon_assoc(priv);
- }
-
-}
-
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -4126,7 +3325,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
static_key = !iwl_is_associated(priv);
if (!static_key) {
- sta_id = iwl3945_hw_find_station(priv, addr);
+ sta_id = iwl_find_station(priv, addr);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
addr);
@@ -4162,185 +3361,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return ret;
}
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
- const struct ieee80211_tx_queue_params *params)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- int q;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (queue >= AC_NUM) {
- IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
- return 0;
- }
-
- q = AC_NUM - 1 - queue;
-
- spin_lock_irqsave(&priv->lock, flags);
-
- priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
- priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
- priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->txop * 32));
-
- priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
- priv->qos_data.qos_active = 1;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- mutex_lock(&priv->mutex);
- if (priv->iw_mode == NL80211_IFTYPE_AP)
- iwl_activate_qos(priv, 1);
- else if (priv->assoc_id && iwl_is_associated(priv))
- iwl_activate_qos(priv, 0);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- return 0;
-}
-
-static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
- struct ieee80211_tx_queue_stats *stats)
-{
- struct iwl_priv *priv = hw->priv;
- int i, avail;
- struct iwl_tx_queue *txq;
- struct iwl_queue *q;
- unsigned long flags;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- for (i = 0; i < AC_NUM; i++) {
- txq = &priv->txq[i];
- q = &txq->q;
- avail = iwl_queue_space(q);
-
- stats[i].len = q->n_window - avail;
- stats[i].limit = q->n_window - q->high_mark;
- stats[i].count = q->n_window;
-
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
- return 0;
-}
-
-static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
-
- mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- iwl_reset_qos(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;
-
- /* new association get rid of ibss beacon skb */
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = NULL;
-
- priv->beacon_int = priv->hw->conf.beacon_int;
- priv->timestamp = 0;
- if ((priv->iw_mode == NL80211_IFTYPE_STATION))
- priv->beacon_int = 0;
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- if (priv->iw_mode != NL80211_IFTYPE_AP) {
- iwl_scan_cancel_timeout(priv, 100);
- priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- iwl3945_commit_rxon(priv);
- }
-
- /* Per mac80211.h: This is only used in IBSS mode... */
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
- IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
- mutex_unlock(&priv->mutex);
- return;
- }
-
- iwl_set_rate(priv);
-
- mutex_unlock(&priv->mutex);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct iwl_priv *priv = hw->priv;
- unsigned long flags;
- __le64 timestamp;
-
- IWL_DEBUG_MAC80211(priv, "enter\n");
-
- if (!iwl_is_ready_rf(priv)) {
- IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
- return -EIO;
- }
-
- if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
- IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
- return -EIO;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- if (priv->ibss_beacon)
- dev_kfree_skb(priv->ibss_beacon);
-
- priv->ibss_beacon = skb;
-
- priv->assoc_id = 0;
- timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
- priv->timestamp = le64_to_cpu(timestamp);
-
- IWL_DEBUG_MAC80211(priv, "leave\n");
- spin_unlock_irqrestore(&priv->lock, flags);
-
- iwl_reset_qos(priv);
-
- iwl3945_post_associate(priv);
-
-
- return 0;
-}
-
/*****************************************************************************
*
* sysfs attributes
@@ -4359,7 +3379,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
static ssize_t show_debug_level(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%08X\n", priv->debug_level);
}
@@ -4367,7 +3387,7 @@ static ssize_t store_debug_level(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
unsigned long val;
int ret;
@@ -4388,7 +3408,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
@@ -4401,7 +3421,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
}
@@ -4409,7 +3429,7 @@ static ssize_t store_tx_power(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
u32 val;
@@ -4427,7 +3447,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
static ssize_t show_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
}
@@ -4436,7 +3456,7 @@ static ssize_t store_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4448,7 +3468,7 @@ static ssize_t store_flags(struct device *d,
IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
flags);
priv->staging_rxon.flags = cpu_to_le32(flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4461,7 +3481,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
static ssize_t show_filter_flags(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
return sprintf(buf, "0x%04X\n",
le32_to_cpu(priv->active_rxon.filter_flags));
@@ -4471,7 +3491,7 @@ static ssize_t store_filter_flags(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&priv->mutex);
@@ -4484,7 +3504,7 @@ static ssize_t store_filter_flags(struct device *d,
"0x%04X\n", filter_flags);
priv->staging_rxon.filter_flags =
cpu_to_le32(filter_flags);
- iwl3945_commit_rxon(priv);
+ iwlcore_commit_rxon(priv);
}
}
mutex_unlock(&priv->mutex);
@@ -4624,26 +3644,11 @@ static ssize_t show_power_level(struct device *d,
{
struct iwl_priv *priv = dev_get_drvdata(d);
int mode = priv->power_data.user_power_setting;
- int system = priv->power_data.system_power_setting;
int level = priv->power_data.power_mode;
char *p = buf;
- switch (system) {
- case IWL_POWER_SYS_AUTO:
- p += sprintf(p, "SYSTEM:auto");
- break;
- case IWL_POWER_SYS_AC:
- p += sprintf(p, "SYSTEM:ac");
- break;
- case IWL_POWER_SYS_BATTERY:
- p += sprintf(p, "SYSTEM:battery");
- break;
- }
-
- p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
- "fixed" : "auto");
- p += sprintf(p, "\tINDEX:%d", level);
- p += sprintf(p, "\n");
+ p += sprintf(p, "INDEX:%d\t", level);
+ p += sprintf(p, "USER:%d\n", mode);
return p - buf + 1;
}
@@ -4756,7 +3761,7 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
static ssize_t show_status(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+ struct iwl_priv *priv = dev_get_drvdata(d);
if (!iwl_is_alive(priv))
return -EAGAIN;
return sprintf(buf, "0x%08x\n", (int)priv->status);
@@ -4768,10 +3773,11 @@ static ssize_t dump_error_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_error_log(priv);
return strnlen(buf, count);
}
@@ -4782,10 +3788,11 @@ static ssize_t dump_event_log(struct device *d,
struct device_attribute *attr,
const char *buf, size_t count)
{
+ struct iwl_priv *priv = dev_get_drvdata(d);
char *p = (char *)buf;
if (p[0] == '1')
- iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+ iwl3945_dump_nic_event_log(priv);
return strnlen(buf, count);
}
@@ -4807,7 +3814,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
@@ -4864,16 +3870,15 @@ static struct ieee80211_ops iwl3945_hw_ops = {
.tx = iwl3945_mac_tx,
.start = iwl3945_mac_start,
.stop = iwl3945_mac_stop,
- .add_interface = iwl3945_mac_add_interface,
- .remove_interface = iwl3945_mac_remove_interface,
- .config = iwl3945_mac_config,
- .config_interface = iwl3945_mac_config_interface,
+ .add_interface = iwl_mac_add_interface,
+ .remove_interface = iwl_mac_remove_interface,
+ .config = iwl_mac_config,
.configure_filter = iwl_configure_filter,
.set_key = iwl3945_mac_set_key,
- .get_tx_stats = iwl3945_mac_get_tx_stats,
- .conf_tx = iwl3945_mac_conf_tx,
- .reset_tsf = iwl3945_mac_reset_tsf,
- .bss_info_changed = iwl3945_bss_info_changed,
+ .get_tx_stats = iwl_mac_get_tx_stats,
+ .conf_tx = iwl_mac_conf_tx,
+ .reset_tsf = iwl_mac_reset_tsf,
+ .bss_info_changed = iwl_bss_info_changed,
.hw_scan = iwl_mac_hw_scan
};
@@ -4886,7 +3891,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->ibss_beacon = NULL;
spin_lock_init(&priv->lock);
- spin_lock_init(&priv->power_data.lock);
spin_lock_init(&priv->sta_lock);
spin_lock_init(&priv->hcmd_lock);
@@ -4895,7 +3899,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
/* Clear the driver's (not device's) station table */
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
priv->data_retry_limit = -1;
priv->ieee_channels = NULL;
@@ -4966,13 +3970,13 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
hw->wiphy->custom_regulatory = true;
- hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+ hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
+ /* we create the 802.11 header and a zero-length SSID element */
+ hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
- hw->conf.beacon_int = 100;
-
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->bands[IEEE80211_BAND_2GHZ];
@@ -5037,6 +4041,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
priv->cfg = cfg;
priv->pci_dev = pdev;
+ priv->inta_mask = CSR_INI_SET_MASK;
#ifdef CONFIG_IWLWIFI_DEBUG
priv->debug_level = iwl3945_mod_params.debug;
@@ -5083,6 +4088,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
+ /* this spin lock will be used in apm_ops.init and EEPROM access
+ * we should init now
+ */
+ spin_lock_init(&priv->reg_lock);
+
/* amp init */
err = priv->cfg->ops->lib->apm_ops.init(priv);
if (err < 0) {
@@ -5128,20 +4138,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
priv->cfg->name);
- /***********************************
- * 7. Initialize Module Parameters
- * **********************************/
-
- /* Initialize module parameter values here */
- /* Disable radio (SW RF KILL) via parameter when loading driver */
- if (iwl3945_mod_params.disable) {
- set_bit(STATUS_RF_KILL_SW, &priv->status);
- IWL_DEBUG_INFO(priv, "Radio disabled.\n");
- }
-
-
/***********************
- * 8. Setup Services
+ * 7. Setup Services
* ********************/
spin_lock_irqsave(&priv->lock, flags);
@@ -5150,8 +4148,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
pci_enable_msi(priv->pci_dev);
- err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
- DRV_NAME, priv);
+ err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+ IRQF_SHARED, DRV_NAME, priv);
if (err) {
IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
goto out_disable_msi;
@@ -5169,7 +4167,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
iwl3945_setup_rx_handlers(priv);
/*********************************
- * 9. Setup and Register mac80211
+ * 8. Setup and Register mac80211
* *******************************/
iwl_enable_interrupts(priv);
@@ -5178,12 +4176,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if (err)
goto out_remove_sysfs;
- err = iwl_rfkill_init(priv);
+ err = iwl_dbgfs_register(priv, DRV_NAME);
if (err)
- IWL_ERR(priv, "Unable to initialize RFKILL system. "
- "Ignoring error: %d\n", err);
- else
- iwl_rfkill_set_hw_state(priv);
+ IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
/* Start monitoring the killswitch */
queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
@@ -5228,6 +4223,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
+ iwl_dbgfs_unregister(priv);
+
set_bit(STATUS_EXIT_PENDING, &priv->status);
if (priv->mac80211_registered) {
@@ -5248,7 +4245,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
- iwl_rfkill_unregister(priv);
cancel_delayed_work_sync(&priv->rfkill_poll);
iwl3945_dealloc_ucode_pci(priv);
@@ -5258,7 +4254,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_hw_txq_ctx_free(priv);
iwl3945_unset_hw_params(priv);
- iwl3945_clear_stations_table(priv);
+ iwl_clear_stations_table(priv);
/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
@@ -5286,43 +4282,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
ieee80211_free_hw(priv->hw);
}
-#ifdef CONFIG_PM
-
-static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
-
- if (priv->is_open) {
- set_bit(STATUS_IN_SUSPEND, &priv->status);
- iwl3945_mac_stop(priv->hw);
- priv->is_open = 1;
- }
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- return 0;
-}
-
-static int iwl3945_pci_resume(struct pci_dev *pdev)
-{
- struct iwl_priv *priv = pci_get_drvdata(pdev);
- int ret;
-
- pci_set_power_state(pdev, PCI_D0);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
- pci_restore_state(pdev);
-
- if (priv->is_open)
- iwl3945_mac_start(priv->hw);
-
- clear_bit(STATUS_IN_SUSPEND, &priv->status);
- return 0;
-}
-
-#endif /* CONFIG_PM */
/*****************************************************************************
*
@@ -5336,8 +4295,8 @@ static struct pci_driver iwl3945_driver = {
.probe = iwl3945_pci_probe,
.remove = __devexit_p(iwl3945_pci_remove),
#ifdef CONFIG_PM
- .suspend = iwl3945_pci_suspend,
- .resume = iwl3945_pci_resume,
+ .suspend = iwl_pci_suspend,
+ .resume = iwl_pci_resume,
#endif
};
@@ -5378,8 +4337,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
MODULE_PARM_DESC(swcrypto,
"using software crypto (default 1 [software])\n");