|
@@ -791,47 +791,6 @@ static int iwl3945_send_bt_config(struct iwl_priv *priv)
|
|
|
sizeof(bt_cmd), &bt_cmd);
|
|
|
}
|
|
|
|
|
|
-static int iwl3945_send_scan_abort(struct iwl_priv *priv)
|
|
|
-{
|
|
|
- int rc = 0;
|
|
|
- struct iwl_rx_packet *res;
|
|
|
- struct iwl_host_cmd cmd = {
|
|
|
- .id = REPLY_SCAN_ABORT_CMD,
|
|
|
- .meta.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;
|
|
|
- }
|
|
|
-
|
|
|
- rc = iwl_send_cmd_sync(priv, &cmd);
|
|
|
- if (rc) {
|
|
|
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
|
|
|
- return rc;
|
|
|
- }
|
|
|
-
|
|
|
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
|
|
|
- if (res->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("SCAN_ABORT returned %d.\n", res->u.status);
|
|
|
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
|
|
|
- clear_bit(STATUS_SCAN_HW, &priv->status);
|
|
|
- }
|
|
|
-
|
|
|
- dev_kfree_skb_any(cmd.meta.u.skb);
|
|
|
-
|
|
|
- return rc;
|
|
|
-}
|
|
|
-
|
|
|
static int iwl3945_add_sta_sync_callback(struct iwl_priv *priv,
|
|
|
struct iwl_cmd *cmd, struct sk_buff *skb)
|
|
|
{
|
|
@@ -1168,115 +1127,6 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
|
|
|
priv->shared_phys);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
|
|
|
- *
|
|
|
- * return : set the bit for each supported rate insert in ie
|
|
|
- */
|
|
|
-static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
|
|
|
- u16 basic_rate, int *left)
|
|
|
-{
|
|
|
- u16 ret_rates = 0, bit;
|
|
|
- int i;
|
|
|
- u8 *cnt = ie;
|
|
|
- u8 *rates = ie + 1;
|
|
|
-
|
|
|
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
|
|
|
- if (bit & supported_rate) {
|
|
|
- ret_rates |= bit;
|
|
|
- rates[*cnt] = iwl3945_rates[i].ieee |
|
|
|
- ((bit & basic_rate) ? 0x80 : 0x00);
|
|
|
- (*cnt)++;
|
|
|
- (*left)--;
|
|
|
- if ((*left <= 0) ||
|
|
|
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return ret_rates;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
|
|
|
- */
|
|
|
-static u16 iwl3945_fill_probe_req(struct iwl_priv *priv,
|
|
|
- struct ieee80211_mgmt *frame,
|
|
|
- int left)
|
|
|
-{
|
|
|
- int len = 0;
|
|
|
- u8 *pos = NULL;
|
|
|
- u16 active_rates, ret_rates, cck_rates;
|
|
|
-
|
|
|
- /* Make sure there is enough space for the probe request,
|
|
|
- * two mandatory IEs and the data */
|
|
|
- left -= 24;
|
|
|
- if (left < 0)
|
|
|
- return 0;
|
|
|
- len += 24;
|
|
|
-
|
|
|
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
|
|
|
- memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
|
|
|
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
|
|
|
- memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
|
|
|
- frame->seq_ctrl = 0;
|
|
|
-
|
|
|
- /* fill in our indirect SSID IE */
|
|
|
- /* ...next IE... */
|
|
|
-
|
|
|
- left -= 2;
|
|
|
- if (left < 0)
|
|
|
- return 0;
|
|
|
- len += 2;
|
|
|
- pos = &(frame->u.probe_req.variable[0]);
|
|
|
- *pos++ = WLAN_EID_SSID;
|
|
|
- *pos++ = 0;
|
|
|
-
|
|
|
- /* fill in supported rate */
|
|
|
- /* ...next IE... */
|
|
|
- left -= 2;
|
|
|
- if (left < 0)
|
|
|
- return 0;
|
|
|
-
|
|
|
- /* ... fill it in... */
|
|
|
- *pos++ = WLAN_EID_SUPP_RATES;
|
|
|
- *pos = 0;
|
|
|
-
|
|
|
- priv->active_rate = priv->rates_mask;
|
|
|
- active_rates = priv->active_rate;
|
|
|
- priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
|
|
|
-
|
|
|
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
|
|
|
- ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
|
|
|
- priv->active_rate_basic, &left);
|
|
|
- active_rates &= ~ret_rates;
|
|
|
-
|
|
|
- ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
|
|
|
- priv->active_rate_basic, &left);
|
|
|
- active_rates &= ~ret_rates;
|
|
|
-
|
|
|
- len += 2 + *pos;
|
|
|
- pos += (*pos) + 1;
|
|
|
- if (active_rates == 0)
|
|
|
- goto fill_end;
|
|
|
-
|
|
|
- /* fill in supported extended rate */
|
|
|
- /* ...next IE... */
|
|
|
- left -= 2;
|
|
|
- if (left < 0)
|
|
|
- return 0;
|
|
|
- /* ... fill it in... */
|
|
|
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
|
|
|
- *pos = 0;
|
|
|
- iwl3945_supported_rate_to_ie(pos, active_rates,
|
|
|
- priv->active_rate_basic, &left);
|
|
|
- if (*pos > 0)
|
|
|
- len += 2 + *pos;
|
|
|
-
|
|
|
- fill_end:
|
|
|
- return (u16)len;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* QoS support
|
|
|
*/
|
|
@@ -3955,66 +3805,6 @@ static void iwl3945_free_channel_map(struct iwl_priv *priv)
|
|
|
priv->channel_count = 0;
|
|
|
}
|
|
|
|
|
|
-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
|
|
|
- * sending probe req. This should be set long enough to hear probe responses
|
|
|
- * from more than one AP. */
|
|
|
-#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
|
|
|
-#define IWL_ACTIVE_DWELL_TIME_52 (20)
|
|
|
-
|
|
|
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
|
|
|
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
|
|
|
-
|
|
|
-/* For faster active scanning, scan will move to the next channel if fewer than
|
|
|
- * PLCP_QUIET_THRESH packets are heard on this channel within
|
|
|
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
|
|
|
- * time if it's a quiet channel (nothing responded to our probe, and there's
|
|
|
- * no other traffic).
|
|
|
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
|
|
|
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
|
|
|
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
|
|
|
-
|
|
|
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
|
|
|
- * Must be set longer than active dwell time.
|
|
|
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
|
|
|
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
|
|
|
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
|
|
|
-#define IWL_PASSIVE_DWELL_BASE (100)
|
|
|
-#define IWL_CHANNEL_TUNE_TIME 5
|
|
|
-
|
|
|
-#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
|
|
|
-
|
|
|
-static inline u16 iwl3945_get_active_dwell_time(struct iwl_priv *priv,
|
|
|
- enum ieee80211_band band,
|
|
|
- u8 n_probes)
|
|
|
-{
|
|
|
- if (band == IEEE80211_BAND_5GHZ)
|
|
|
- return IWL_ACTIVE_DWELL_TIME_52 +
|
|
|
- IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
|
|
|
- else
|
|
|
- return IWL_ACTIVE_DWELL_TIME_24 +
|
|
|
- IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
|
|
|
-}
|
|
|
-
|
|
|
-static u16 iwl3945_get_passive_dwell_time(struct iwl_priv *priv,
|
|
|
- enum ieee80211_band band)
|
|
|
-{
|
|
|
- u16 passive = (band == IEEE80211_BAND_2GHZ) ?
|
|
|
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
|
|
|
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
|
|
|
-
|
|
|
- if (iwl3945_is_associated(priv)) {
|
|
|
- /* If we're associated, we clamp the maximum passive
|
|
|
- * dwell time to be 98% of the beacon interval (minus
|
|
|
- * 2 * channel tune time) */
|
|
|
- passive = priv->beacon_int;
|
|
|
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
|
|
|
- passive = IWL_PASSIVE_DWELL_BASE;
|
|
|
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
|
|
|
- }
|
|
|
-
|
|
|
- return passive;
|
|
|
-}
|
|
|
-
|
|
|
static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
|
|
|
enum ieee80211_band band,
|
|
|
u8 is_active, u8 n_probes,
|
|
@@ -4033,8 +3823,8 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
|
|
|
|
|
|
channels = sband->channels;
|
|
|
|
|
|
- active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
|
|
|
- passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
|
|
|
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
|
|
|
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);
|
|
|
|
|
|
if (passive_dwell <= active_dwell)
|
|
|
passive_dwell = active_dwell + 1;
|
|
@@ -5135,28 +4925,6 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
|
|
|
}
|
|
|
|
|
|
#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
|
|
|
-
|
|
|
-static void iwl3945_bg_scan_check(struct work_struct *data)
|
|
|
-{
|
|
|
- struct iwl_priv *priv =
|
|
|
- container_of(data, struct iwl_priv, scan_check.work);
|
|
|
-
|
|
|
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
|
|
- return;
|
|
|
-
|
|
|
- mutex_lock(&priv->mutex);
|
|
|
- if (test_bit(STATUS_SCANNING, &priv->status) ||
|
|
|
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
|
|
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
|
|
|
- "Scan completion watchdog resetting adapter (%dms)\n",
|
|
|
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
|
|
|
-
|
|
|
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
|
|
|
- iwl3945_send_scan_abort(priv);
|
|
|
- }
|
|
|
- mutex_unlock(&priv->mutex);
|
|
|
-}
|
|
|
-
|
|
|
static void iwl3945_bg_request_scan(struct work_struct *data)
|
|
|
{
|
|
|
struct iwl_priv *priv =
|
|
@@ -5284,9 +5052,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
|
|
|
|
|
/* We don't build a direct scan probe request; the uCode will do
|
|
|
* that based on the direct_mask added to each channel entry */
|
|
|
- scan->tx_cmd.len = cpu_to_le16(
|
|
|
- iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
|
|
|
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
|
|
|
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
|
|
|
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
|
|
|
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
|
@@ -5307,6 +5072,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ scan->tx_cmd.len = cpu_to_le16(
|
|
|
+ iwl_fill_probe_req(priv, band,
|
|
|
+ (struct ieee80211_mgmt *)scan->data,
|
|
|
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
|
|
|
+
|
|
|
/* select Rx antennas */
|
|
|
scan->flags |= iwl3945_get_antenna_flags(priv);
|
|
|
|
|
@@ -5482,45 +5252,8 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
|
|
|
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
|
|
|
}
|
|
|
|
|
|
-static void iwl3945_bg_abort_scan(struct work_struct *work)
|
|
|
-{
|
|
|
- struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
|
|
|
-
|
|
|
- if (!iwl_is_ready(priv))
|
|
|
- return;
|
|
|
-
|
|
|
- mutex_lock(&priv->mutex);
|
|
|
-
|
|
|
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
|
|
|
- iwl3945_send_scan_abort(priv);
|
|
|
-
|
|
|
- mutex_unlock(&priv->mutex);
|
|
|
-}
|
|
|
-
|
|
|
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
|
|
|
|
|
|
-static void iwl3945_bg_scan_completed(struct work_struct *work)
|
|
|
-{
|
|
|
- struct iwl_priv *priv =
|
|
|
- container_of(work, struct iwl_priv, scan_completed);
|
|
|
-
|
|
|
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
|
|
|
-
|
|
|
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
|
|
- return;
|
|
|
-
|
|
|
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
|
|
|
- iwl3945_mac_config(priv->hw, 0);
|
|
|
-
|
|
|
- ieee80211_scan_completed(priv->hw);
|
|
|
-
|
|
|
- /* Since setting the TXPOWER may have been deferred while
|
|
|
- * performing the scan, fire one off */
|
|
|
- mutex_lock(&priv->mutex);
|
|
|
- priv->cfg->ops->lib->send_tx_power(priv);
|
|
|
- mutex_unlock(&priv->mutex);
|
|
|
-}
|
|
|
-
|
|
|
/*****************************************************************************
|
|
|
*
|
|
|
* mac80211 entry point functions
|
|
@@ -6821,15 +6554,15 @@ 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->scan_completed, iwl3945_bg_scan_completed);
|
|
|
- INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
|
|
|
- INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
|
|
|
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);
|
|
|
- INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
|
|
|
INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
|
|
|
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
|
|
|
+ INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
|
|
|
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
|
|
|
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
|
|
|
|
|
|
iwl3945_hw_setup_deferred_work(priv);
|
|
|
|