--- linux-2.6.25-gentoo-r5/drivers/net/wireless/iwlwifi/iwl-4965.c 2008-04-17 02:49:44.000000000 +0000 +++ linux-2.6.25-gentoo-r4/drivers/net/wireless/iwlwifi/iwl-4965.c 2008-06-13 20:10:20.000000000 +0000 @@ -3945,16 +3945,22 @@ static void iwl4965_rx_reply_rx(struct i } priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); stats.freq = ieee80211chan2mhz(stats.channel); /* Find max signal strength (dBm) among 3 antenna/receiver chains */ stats.ssi = iwl4965_calc_rssi(rx_start); + + /* ### Fix for monitor mode ### */ + if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { + iwl4965_handle_data_packet(priv, 1, include_phy, rxb, &stats); + return; + } /* Meaningful noise values are available only from beacon statistics, * which are gathered only when associated, and indicate noise * only for the associated network channel ... * Ignore these noise values while scanning (other channels) */ if (iwl4965_is_associated(priv) && !test_bit(STATUS_SCANNING, &priv->status)) { stats.noise = priv->last_rx_noise; --- linux-2.6.25-gentoo-r5/drivers/net/wireless/iwlwifi/iwl-4965.h 2008-04-17 02:49:44.000000000 +0000 +++ linux-2.6.25-gentoo-r4/drivers/net/wireless/iwlwifi/iwl-4965.h 2008-06-13 19:49:59.000000000 +0000 @@ -421,16 +421,17 @@ struct iwl4965_rx_queue { #define STATUS_IN_SUSPEND 10 #define STATUS_STATISTICS 11 #define STATUS_SCANNING 12 #define STATUS_SCAN_ABORTING 13 #define STATUS_SCAN_HW 14 #define STATUS_POWER_PMI 15 #define STATUS_FW_ERROR 16 #define STATUS_CONF_PENDING 17 +#define STATUS_RFMON_ON_PENDING 18 /* switching to monitor mode */ #define MAX_TID_COUNT 9 #define IWL_INVALID_RATE 0xFF #define IWL_INVALID_VALUE -1 #ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT_AGG --- linux-2.6.25-gentoo-r5/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-04-17 02:49:44.000000000 +0000 +++ linux-2.6.25-gentoo-r4/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-06-13 20:02:38.000000000 +0000 @@ -7524,16 +7524,29 @@ static int iwl4965_mac_config(struct iee priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); if (!iwl4965_is_ready(priv)) { IWL_DEBUG_MAC80211("leave - not ready\n"); ret = -EIO; goto out; } + + /* if Monitor mode was enabled via 'configure_filter', + * switch modes now + */ + if (test_bit(STATUS_RFMON_ON_PENDING, &priv->status)) { + clear_bit(STATUS_RFMON_ON_PENDING, &priv->status); + if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) { + IWL_ERROR("iwl4965_set_mode(IEEE80211_IF_TYPE_MNTR) failed\n"); + ret = -EIO; + goto out; + } + } + if (unlikely(!iwl4965_param_disable_hw_scan && test_bit(STATUS_SCANNING, &priv->status))) { IWL_DEBUG_MAC80211("leave - scanning\n"); set_bit(STATUS_CONF_PENDING, &priv->status); mutex_unlock(&priv->mutex); return 0; } @@ -7786,17 +7799,31 @@ static void iwl4965_configure_filter(str unsigned int changed_flags, unsigned int *total_flags, int mc_count, struct dev_addr_list *mc_list) { /* * XXX: dummy * see also iwl4965_connection_init_rx_config */ - *total_flags = 0; + /* ### Fix for monitor mode ### */ + struct iwl4965_priv *priv = hw->priv; + int new_flags = 0; + + if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + if (*total_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + IWL_DEBUG_MAC80211("Enter: type %d\n", IEEE80211_IF_TYPE_MNTR); + + set_bit(STATUS_RFMON_ON_PENDING, &priv->status); + new_flags |= (FIF_PROMISC_IN_BSS | + FIF_CONTROL | + FIF_OTHER_BSS); + } + } + *total_flags = new_flags; } static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n");