summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-03-10 20:13:26 -0800
committerJohn W. Linville <linville@tuxdriver.com>2011-03-11 14:15:55 -0500
commit266af4c745952e9bebf687dd68af58df553cb59d (patch)
treeb3bbe8ac763395a4dfcfdd2b46948c9963dbfa46 /drivers/net/wireless/iwlwifi/iwl-scan.c
parent808118cb41dfe12a1ac0e35515ac4d91b170bdf9 (diff)
iwlagn: support off-channel TX
Add support to iwlagn for off-channel TX. The microcode API for this is a bit strange in that it uses a hacked-up scan command, so the scan code needs to change quite a bit to accomodate that and be able to send it out. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index faa6d34cb65..3a4d9e6b042 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -101,7 +101,7 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
ieee80211_scan_completed(priv->hw, aborted);
}
- priv->is_internal_short_scan = false;
+ priv->scan_type = IWL_SCAN_NORMAL;
priv->scan_vif = NULL;
priv->scan_request = NULL;
}
@@ -339,10 +339,10 @@ void iwl_init_scan_params(struct iwl_priv *priv)
priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = ant_idx;
}
-static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
- struct ieee80211_vif *vif,
- bool internal,
- enum ieee80211_band band)
+int __must_check iwl_scan_initiate(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
+ enum iwl_scan_type scan_type,
+ enum ieee80211_band band)
{
int ret;
@@ -370,17 +370,19 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
}
IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
- internal ? "internal short " : "");
+ scan_type == IWL_SCAN_NORMAL ? "" :
+ scan_type == IWL_SCAN_OFFCH_TX ? "offchan TX " :
+ "internal short ");
set_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = internal;
+ priv->scan_type = scan_type;
priv->scan_start = jiffies;
priv->scan_band = band;
ret = priv->cfg->ops->utils->request_scan(priv, vif);
if (ret) {
clear_bit(STATUS_SCANNING, &priv->status);
- priv->is_internal_short_scan = false;
+ priv->scan_type = IWL_SCAN_NORMAL;
return ret;
}
@@ -405,7 +407,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (test_bit(STATUS_SCANNING, &priv->status) &&
- !priv->is_internal_short_scan) {
+ priv->scan_type != IWL_SCAN_NORMAL) {
IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
ret = -EAGAIN;
goto out_unlock;
@@ -419,11 +421,11 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
* If an internal scan is in progress, just set
* up the scan_request as per above.
*/
- if (priv->is_internal_short_scan) {
+ if (priv->scan_type != IWL_SCAN_NORMAL) {
IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
ret = 0;
} else
- ret = iwl_scan_initiate(priv, vif, false,
+ ret = iwl_scan_initiate(priv, vif, IWL_SCAN_NORMAL,
req->channels[0]->band);
IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -452,7 +454,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
mutex_lock(&priv->mutex);
- if (priv->is_internal_short_scan == true) {
+ if (priv->scan_type == IWL_SCAN_RADIO_RESET) {
IWL_DEBUG_SCAN(priv, "Internal scan already in progress\n");
goto unlock;
}
@@ -462,7 +464,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
goto unlock;
}
- if (iwl_scan_initiate(priv, NULL, true, priv->band))
+ if (iwl_scan_initiate(priv, NULL, IWL_SCAN_RADIO_RESET, priv->band))
IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
unlock:
mutex_unlock(&priv->mutex);
@@ -549,8 +551,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
container_of(work, struct iwl_priv, scan_completed);
bool aborted;
- IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
- priv->is_internal_short_scan ? "internal short " : "");
+ IWL_DEBUG_SCAN(priv, "Completed scan.\n");
cancel_delayed_work(&priv->scan_check);
@@ -565,7 +566,13 @@ static void iwl_bg_scan_completed(struct work_struct *work)
goto out_settings;
}
- if (priv->is_internal_short_scan && !aborted) {
+ if (priv->scan_type == IWL_SCAN_OFFCH_TX && priv->_agn.offchan_tx_skb) {
+ ieee80211_tx_status_irqsafe(priv->hw,
+ priv->_agn.offchan_tx_skb);
+ priv->_agn.offchan_tx_skb = NULL;
+ }
+
+ if (priv->scan_type != IWL_SCAN_NORMAL && !aborted) {
int err;
/* Check if mac80211 requested scan during our internal scan */
@@ -573,7 +580,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
goto out_complete;
/* If so request a new scan */
- err = iwl_scan_initiate(priv, priv->scan_vif, false,
+ err = iwl_scan_initiate(priv, priv->scan_vif, IWL_SCAN_NORMAL,
priv->scan_request->channels[0]->band);
if (err) {
IWL_DEBUG_SCAN(priv,