Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 214649
b: refs/heads/master
c: 3eecce5
h: refs/heads/master
i:
  214647: d92a82d
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed Sep 14, 2010
1 parent 23d805a commit af8f71f
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 188 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b5be3efc34294cc34e305903df6a388950e8d1f3
refs/heads/master: 3eecce527c7434dfd16517ce08b49632c8a26717
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-3945.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);

/* scanning */
void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);

/* Requires full declaration of iwl_priv before including */
#include "iwl-io.h"
Expand Down
88 changes: 21 additions & 67 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}

void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
Expand All @@ -1170,57 +1170,20 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
int chan_mod;
u8 active_chains;
u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
int ret;

lockdep_assert_held(&priv->mutex);

if (vif)
ctx = iwl_rxon_ctx_from_vif(vif);

cancel_delayed_work(&priv->scan_check);

if (!iwl_is_ready(priv)) {
IWL_WARN(priv, "request scan called when driver not ready.\n");
goto done;
}

/* Make sure the scan wasn't canceled before this queued work
* was given the chance to run... */
if (!test_bit(STATUS_SCANNING, &priv->status))
goto done;

/* This should never be called or scheduled if there is currently
* a scan active in the hardware. */
if (test_bit(STATUS_SCAN_HW, &priv->status)) {
IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
"Ignoring second request.\n");
goto done;
}

if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
goto done;
}

if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n");
goto done;
}

if (iwl_is_rfkill(priv)) {
IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
goto done;
}

if (!test_bit(STATUS_READY, &priv->status)) {
IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n");
goto done;
}

if (!priv->scan_cmd) {
priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
IWL_MAX_SCAN_SIZE, GFP_KERNEL);
if (!priv->scan_cmd) {
IWL_DEBUG_SCAN(priv,
"fail to allocate memory for scan\n");
goto done;
return -ENOMEM;
}
}
scan = priv->scan_cmd;
Expand Down Expand Up @@ -1327,8 +1290,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_GOOD_CRC_TH_NEVER;
break;
default:
IWL_WARN(priv, "Invalid scan band count\n");
goto done;
IWL_WARN(priv, "Invalid scan band\n");
return -EIO;
}

band = priv->scan_band;
Expand Down Expand Up @@ -1408,38 +1371,29 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
}
if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
goto done;
return -EIO;
}

cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl_scan_channel);
cmd.data = scan;
scan->len = cpu_to_le16(cmd.len);

set_bit(STATUS_SCAN_HW, &priv->status);

if (priv->cfg->ops->hcmd->set_pan_params &&
priv->cfg->ops->hcmd->set_pan_params(priv))
goto done;
if (priv->cfg->ops->hcmd->set_pan_params) {
ret = priv->cfg->ops->hcmd->set_pan_params(priv);
if (ret)
return ret;
}

if (iwl_send_cmd_sync(priv, &cmd))
goto done;
set_bit(STATUS_SCAN_HW, &priv->status);
ret = iwl_send_cmd_sync(priv, &cmd);
if (ret) {
clear_bit(STATUS_SCAN_HW, &priv->status);
if (priv->cfg->ops->hcmd->set_pan_params)
priv->cfg->ops->hcmd->set_pan_params(priv);
}

queue_delayed_work(priv->workqueue, &priv->scan_check,
IWL_SCAN_CHECK_WATCHDOG);

return;

done:
/* Cannot perform scan. Make sure we clear scanning
* bits from status so next scan request can be performed.
* If we don't clear scanning status bit here all next scan
* will fail
*/
clear_bit(STATUS_SCAN_HW, &priv->status);
clear_bit(STATUS_SCANNING, &priv->status);
/* inform mac80211 scan aborted */
queue_work(priv->workqueue, &priv->scan_completed);
return ret;
}

int iwlagn_manage_ibss_station(struct iwl_priv *priv,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ void iwl_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);

/* scan */
void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);

/* station mgmt */
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ struct iwl_hcmd_utils_ops {
__le16 fc, __le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
};

struct iwl_apm_ops {
Expand Down
127 changes: 74 additions & 53 deletions trunk/drivers/net/wireless/iwlwifi/iwl-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,19 +324,68 @@ void iwl_init_scan_params(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_init_scan_params);

static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
struct ieee80211_vif *vif,
bool internal,
enum nl80211_band band)
{
int ret;

lockdep_assert_held(&priv->mutex);

IWL_DEBUG_INFO(priv, "Starting scan...\n");
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
return -EOPNOTSUPP;

cancel_delayed_work(&priv->scan_check);

if (!iwl_is_ready(priv)) {
IWL_WARN(priv, "request scan called when driver not ready.\n");
return -EIO;
}

if (test_bit(STATUS_SCAN_HW, &priv->status)) {
IWL_DEBUG_INFO(priv,
"Multiple concurrent scan requests in parallel.\n");
return -EBUSY;
}

if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
return -EIO;
}

if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
return -EBUSY;
}

if (iwl_is_rfkill(priv)) {
IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
return -EIO;
}

if (!test_bit(STATUS_READY, &priv->status)) {
IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n");
return -EBUSY;
}

IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
internal ? "internal short " : "");

set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = false;
priv->is_internal_short_scan = internal;
priv->scan_start = jiffies;
priv->scan_band = band;

if (WARN_ON(!priv->cfg->ops->utils->request_scan))
return -EOPNOTSUPP;
ret = priv->cfg->ops->utils->request_scan(priv, vif);
if (ret) {
clear_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = false;
return ret;
}

priv->cfg->ops->utils->request_scan(priv, vif);
queue_delayed_work(priv->workqueue, &priv->scan_check,
IWL_SCAN_CHECK_WATCHDOG);

return 0;
}
Expand All @@ -355,27 +404,14 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,

mutex_lock(&priv->mutex);

if (!iwl_is_ready_rf(priv)) {
ret = -EIO;
IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
goto out_unlock;
}

if (test_bit(STATUS_SCANNING, &priv->status) &&
!priv->is_internal_short_scan) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
ret = -EAGAIN;
goto out_unlock;
}

if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
ret = -EAGAIN;
goto out_unlock;
}

/* mac80211 will only ask for one band at a time */
priv->scan_band = req->channels[0]->band;
priv->scan_request = req;
priv->scan_vif = vif;

Expand All @@ -386,7 +422,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
if (priv->is_internal_short_scan)
ret = 0;
else
ret = iwl_scan_initiate(priv, vif);
ret = iwl_scan_initiate(priv, vif, false,
req->channels[0]->band);

IWL_DEBUG_MAC80211(priv, "leave\n");

Expand Down Expand Up @@ -418,31 +455,13 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
goto unlock;
}

if (!iwl_is_ready_rf(priv)) {
IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
goto unlock;
}

if (test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
goto unlock;
}

if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
goto unlock;
}

priv->scan_band = priv->band;

IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
set_bit(STATUS_SCANNING, &priv->status);
priv->is_internal_short_scan = true;

if (WARN_ON(!priv->cfg->ops->utils->request_scan))
goto unlock;

priv->cfg->ops->utils->request_scan(priv, NULL);
if (iwl_scan_initiate(priv, NULL, true, priv->band))
IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
unlock:
mutex_unlock(&priv->mutex);
}
Expand Down Expand Up @@ -536,7 +555,6 @@ static void iwl_bg_scan_completed(struct work_struct *work)
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
bool internal = false;
bool scan_completed = false;
struct iwl_rxon_context *ctx;

IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
Expand All @@ -549,16 +567,27 @@ static void iwl_bg_scan_completed(struct work_struct *work)
IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
internal = true;
} else if (priv->scan_request) {
scan_completed = true;
priv->scan_request = NULL;
priv->scan_vif = NULL;
ieee80211_scan_completed(priv->hw, false);
}

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
goto out;

if (internal && priv->scan_request)
iwl_scan_initiate(priv, priv->scan_vif);
if (internal && priv->scan_request) {
int err = iwl_scan_initiate(priv, priv->scan_vif, false,
priv->scan_request->channels[0]->band);

if (err) {
IWL_DEBUG_SCAN(priv,
"failed to initiate pending scan: %d\n", err);
priv->scan_request = NULL;
priv->scan_vif = NULL;
ieee80211_scan_completed(priv->hw, true);
} else
goto out;
}

/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
Expand All @@ -571,19 +600,11 @@ static void iwl_bg_scan_completed(struct work_struct *work)
for_each_context(priv, ctx)
iwlcore_commit_rxon(priv, ctx);

out:
if (priv->cfg->ops->hcmd->set_pan_params)
priv->cfg->ops->hcmd->set_pan_params(priv);

out:
mutex_unlock(&priv->mutex);

/*
* Do not hold mutex here since this will cause mac80211 to call
* into driver again into functions that will attempt to take
* mutex.
*/
if (scan_completed)
ieee80211_scan_completed(priv->hw, false);
}

void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
Expand Down
Loading

0 comments on commit af8f71f

Please sign in to comment.