Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 214652
b: refs/heads/master
c: cd44600
h: refs/heads/master
v: v3
  • Loading branch information
Stanislaw Gruszka authored and John W. Linville committed Sep 14, 2010
1 parent ed7a7ea commit 4c8acd5
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 65 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: d745d472afcbc6354ebfee008123894a7f37e97e
refs/heads/master: cd44600fdd89832c0bc898189270a81be0db01cd
131 changes: 67 additions & 64 deletions trunk/drivers/net/wireless/iwlwifi/iwl-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,83 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5

static int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret;
struct iwl_rx_packet *pkt;
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_ABORT_CMD,
.flags = CMD_WANT_SKB,
};

/* Exit instantly with error when device is not ready
* to receive scan abort command or it does not perform
* hardware scan currently */
if (!test_bit(STATUS_READY, &priv->status) ||
!test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
!test_bit(STATUS_SCAN_HW, &priv->status) ||
test_bit(STATUS_FW_ERROR, &priv->status) ||
test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EIO;

/**
* iwl_scan_cancel - Cancel any currently executing HW scan
*
* NOTE: priv->mutex is not required before calling this function
*/
int iwl_scan_cancel(struct iwl_priv *priv)
{
if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
clear_bit(STATUS_SCANNING, &priv->status);
return 0;
ret = iwl_send_cmd_sync(priv, &cmd);
if (ret)
return ret;

pkt = (struct iwl_rx_packet *)cmd.reply_page;
if (pkt->u.status != CAN_ABORT_STATUS) {
/* The scan abort will return 1 for success or
* 2 for "failure". A failure condition can be
* due to simply not being in an active scan which
* can occur if we send the scan abort before we
* the microcode has notified us that a scan is
* completed. */
IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
ret = -EIO;
}

if (test_bit(STATUS_SCANNING, &priv->status)) {
if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
schedule_work(&priv->abort_scan);
iwl_free_pages(priv, cmd.reply_page);
return ret;
}

} else
IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
static void iwl_do_scan_abort(struct iwl_priv *priv)
{
int ret;

return test_bit(STATUS_SCANNING, &priv->status);
lockdep_assert_held(&priv->mutex);

if (!test_bit(STATUS_SCANNING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
return;
}

if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
return;
}

ret = iwl_send_scan_abort(priv);
if (ret) {
IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret);
clear_bit(STATUS_SCANNING, &priv->status);
clear_bit(STATUS_SCAN_HW, &priv->status);
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
ieee80211_scan_completed(priv->hw, true);
} else
IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
}

/**
* iwl_scan_cancel - Cancel any currently executing HW scan
*/
int iwl_scan_cancel(struct iwl_priv *priv)
{
IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
schedule_work(&priv->abort_scan);
return 0;
}
EXPORT_SYMBOL(iwl_scan_cancel);

/**
* iwl_scan_cancel_timeout - Cancel any currently executing HW scan
* @ms: amount of time to wait (in milliseconds) for scan to abort
Expand All @@ -108,47 +157,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
}
EXPORT_SYMBOL(iwl_scan_cancel_timeout);

static int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rx_packet *pkt;
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_ABORT_CMD,
.flags = CMD_WANT_SKB,
};

/* If there isn't a scan actively going on in the hardware
* then we are in between scan bands and not actually
* actively scanning, so don't send the abort command */
if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
return 0;
}

ret = iwl_send_cmd_sync(priv, &cmd);
if (ret) {
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
return ret;
}

pkt = (struct iwl_rx_packet *)cmd.reply_page;
if (pkt->u.status != CAN_ABORT_STATUS) {
/* The scan abort will return 1 for success or
* 2 for "failure". A failure condition can be
* due to simply not being in an active scan which
* can occur if we send the scan abort before we
* the microcode has notified us that a scan is
* completed. */
IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
clear_bit(STATUS_SCAN_HW, &priv->status);
}

iwl_free_pages(priv, cmd.reply_page);

return ret;
}

/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
Expand Down Expand Up @@ -527,15 +535,10 @@ static void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);

if (!test_bit(STATUS_READY, &priv->status) ||
!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
return;

cancel_delayed_work(&priv->scan_check);

mutex_lock(&priv->mutex);
if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
iwl_send_scan_abort(priv);
iwl_do_scan_abort(priv);
mutex_unlock(&priv->mutex);
}

Expand Down

0 comments on commit 4c8acd5

Please sign in to comment.