We currently forbid injecting packets in monitor mode for iwl3945, but it's done in an unsafe way, that can result in various issues. This patch enables injecting packets in monitor mode. The patch is also available as an attachment in case Gmail decides to corrupt it. John, please apply to 2.6.27. You might also want to apply it to 2.6.26, but it's not tested there. Signed-off-by: Gábor Stefanik <netrolller.3d@xxxxxxxxx> --- diff -ru8p compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c --- compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-06-04 06:10:49.000000000 +0200 +++ compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-06-04 22:34:32.000000000 +0200 @@ -2532,16 +2532,19 @@ static int iwl3945_get_sta_id(struct iwl return sta_id; IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", print_mac(mac, hdr->addr1)); iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; } + /* If we are in monitor mode, use BCAST */ + case IEEE80211_IF_TYPE_MNTR: + return priv->hw_setting.bcast_sta_id; default: IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); return priv->hw_setting.bcast_sta_id; } } /* * start REPLY_TX command process @@ -2571,21 +2574,16 @@ static int iwl3945_tx_skb(struct iwl3945 int rc; spin_lock_irqsave(&priv->lock, flags); if (iwl3945_is_rfkill(priv)) { IWL_DEBUG_DROP("Dropping - RF KILL\n"); goto drop_unlock; } - if (!priv->vif) { - IWL_DEBUG_DROP("Dropping - !priv->vif\n"); - goto drop_unlock; - } - if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { IWL_ERROR("ERROR: No TX rate available.\n"); goto drop_unlock; } unicast = !is_multicast_ether_addr(hdr->addr1); id = 0; @@ -2595,24 +2593,16 @@ static int iwl3945_tx_skb(struct iwl3945 if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); else if (ieee80211_is_assoc_request(fc)) IWL_DEBUG_TX("Sending ASSOC frame\n"); else if (ieee80211_is_reassoc_request(fc)) IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - /* drop all data frame if we are not associated */ - if ((!iwl3945_is_associated(priv) || - ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && - ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { - IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); - goto drop_unlock; - } - spin_unlock_irqrestore(&priv->lock, flags); hdr_len = ieee80211_get_hdrlen(fc); /* Find (or create) index into station table for destination station */ sta_id = iwl3945_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { DECLARE_MAC_BUF(mac); @@ -6334,17 +6324,17 @@ static void iwl3945_bg_request_scan(stru IWL_WARNING("Invalid scan band count\n"); goto done; } /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) - scan->filter_flags = RXON_FILTER_PROMISC_MSK; + scan->filter_flags |= RXON_FILTER_PROMISC_MSK | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; if (direct_mask) scan->channel_count = iwl3945_get_channels_for_scan( priv, band, 1, /* active */ direct_mask, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); else @@ -6660,38 +6650,33 @@ static void iwl3945_mac_stop(struct ieee * RXON_FILTER_ASSOC_MSK BIT */ mutex_lock(&priv->mutex); iwl3945_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); mutex_unlock(&priv->mutex); } iwl3945_down(priv); flush_workqueue(priv->workqueue); free_irq(priv->pci_dev->irq, priv); pci_disable_msi(priv->pci_dev); pci_save_state(priv->pci_dev); pci_disable_device(priv->pci_dev); IWL_DEBUG_MAC80211("leave\n"); } static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); - if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { - IWL_DEBUG_MAC80211("leave - monitor\n"); - return -1; - } - IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwl3945_tx_skb(priv, skb)) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211("leave\n"); return 0;
diff -ru8p compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c --- compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-06-04 06:10:49.000000000 +0200 +++ compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-06-04 22:34:32.000000000 +0200 @@ -2532,16 +2532,19 @@ static int iwl3945_get_sta_id(struct iwl return sta_id; IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", print_mac(mac, hdr->addr1)); iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; } + /* If we are in monitor mode, use BCAST */ + case IEEE80211_IF_TYPE_MNTR: + return priv->hw_setting.bcast_sta_id; default: IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); return priv->hw_setting.bcast_sta_id; } } /* * start REPLY_TX command process @@ -2571,21 +2574,16 @@ static int iwl3945_tx_skb(struct iwl3945 int rc; spin_lock_irqsave(&priv->lock, flags); if (iwl3945_is_rfkill(priv)) { IWL_DEBUG_DROP("Dropping - RF KILL\n"); goto drop_unlock; } - if (!priv->vif) { - IWL_DEBUG_DROP("Dropping - !priv->vif\n"); - goto drop_unlock; - } - if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) { IWL_ERROR("ERROR: No TX rate available.\n"); goto drop_unlock; } unicast = !is_multicast_ether_addr(hdr->addr1); id = 0; @@ -2595,24 +2593,16 @@ static int iwl3945_tx_skb(struct iwl3945 if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); else if (ieee80211_is_assoc_request(fc)) IWL_DEBUG_TX("Sending ASSOC frame\n"); else if (ieee80211_is_reassoc_request(fc)) IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - /* drop all data frame if we are not associated */ - if ((!iwl3945_is_associated(priv) || - ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && - ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { - IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); - goto drop_unlock; - } - spin_unlock_irqrestore(&priv->lock, flags); hdr_len = ieee80211_get_hdrlen(fc); /* Find (or create) index into station table for destination station */ sta_id = iwl3945_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { DECLARE_MAC_BUF(mac); @@ -6334,17 +6324,17 @@ static void iwl3945_bg_request_scan(stru IWL_WARNING("Invalid scan band count\n"); goto done; } /* select Rx antennas */ scan->flags |= iwl3945_get_antenna_flags(priv); if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) - scan->filter_flags = RXON_FILTER_PROMISC_MSK; + scan->filter_flags |= RXON_FILTER_PROMISC_MSK | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK; if (direct_mask) scan->channel_count = iwl3945_get_channels_for_scan( priv, band, 1, /* active */ direct_mask, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); else @@ -6660,38 +6650,33 @@ static void iwl3945_mac_stop(struct ieee * RXON_FILTER_ASSOC_MSK BIT */ mutex_lock(&priv->mutex); iwl3945_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); mutex_unlock(&priv->mutex); } iwl3945_down(priv); flush_workqueue(priv->workqueue); free_irq(priv->pci_dev->irq, priv); pci_disable_msi(priv->pci_dev); pci_save_state(priv->pci_dev); pci_disable_device(priv->pci_dev); IWL_DEBUG_MAC80211("leave\n"); } static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); - if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { - IWL_DEBUG_MAC80211("leave - monitor\n"); - return -1; - } - IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwl3945_tx_skb(priv, skb)) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211("leave\n"); return 0;