aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2007-12-19 22:27:32 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:07:53 -0500
commit12342c475f5de17071eaf24ea2938ba8dfe285f2 (patch)
treea2cdfd191069397e093f2410009092e7e96c9325 /drivers/net/wireless/iwlwifi/iwl4965-base.c
parent7e94041ca17685cf12c658b8edc008dd0bdb00c7 (diff)
iwlwifi: proper monitor support
This patch changes the iwlwifi driver to properly support monitor interfaces after the filter flags change. The patch is originally created by Johannes Berg for iwl4965. I fixed some of the comments and created a similar patch for iwl3945. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c90
1 files changed, 2 insertions, 88 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 14a1124e6ef4..07089754b544 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -41,7 +41,6 @@
41#include <linux/etherdevice.h> 41#include <linux/etherdevice.h>
42#include <linux/if_arp.h> 42#include <linux/if_arp.h>
43 43
44#include <net/ieee80211_radiotap.h>
45#include <net/mac80211.h> 44#include <net/mac80211.h>
46 45
47#include <asm/div64.h> 46#include <asm/div64.h>
@@ -3247,93 +3246,6 @@ void iwl4965_set_decrypted_flag(struct iwl4965_priv *priv, struct sk_buff *skb,
3247 } 3246 }
3248} 3247}
3249 3248
3250void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv,
3251 struct iwl4965_rx_mem_buffer *rxb,
3252 void *data, short len,
3253 struct ieee80211_rx_status *stats,
3254 u16 phy_flags)
3255{
3256 struct iwl4965_rt_rx_hdr *iwl4965_rt;
3257
3258 /* First cache any information we need before we overwrite
3259 * the information provided in the skb from the hardware */
3260 s8 signal = stats->ssi;
3261 s8 noise = 0;
3262 int rate = stats->rate;
3263 u64 tsf = stats->mactime;
3264 __le16 phy_flags_hw = cpu_to_le16(phy_flags);
3265
3266 /* We received data from the HW, so stop the watchdog */
3267 if (len > priv->hw_setting.rx_buf_size - sizeof(*iwl4965_rt)) {
3268 IWL_DEBUG_DROP("Dropping too large packet in monitor\n");
3269 return;
3270 }
3271
3272 /* copy the frame data to write after where the radiotap header goes */
3273 iwl4965_rt = (void *)rxb->skb->data;
3274 memmove(iwl4965_rt->payload, data, len);
3275
3276 iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
3277 iwl4965_rt->rt_hdr.it_pad = 0; /* always good to zero */
3278
3279 /* total header + data */
3280 iwl4965_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl4965_rt));
3281
3282 /* Set the size of the skb to the size of the frame */
3283 skb_put(rxb->skb, sizeof(*iwl4965_rt) + len);
3284
3285 /* Big bitfield of all the fields we provide in radiotap */
3286 iwl4965_rt->rt_hdr.it_present =
3287 cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
3288 (1 << IEEE80211_RADIOTAP_FLAGS) |
3289 (1 << IEEE80211_RADIOTAP_RATE) |
3290 (1 << IEEE80211_RADIOTAP_CHANNEL) |
3291 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
3292 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
3293 (1 << IEEE80211_RADIOTAP_ANTENNA));
3294
3295 /* Zero the flags, we'll add to them as we go */
3296 iwl4965_rt->rt_flags = 0;
3297
3298 iwl4965_rt->rt_tsf = cpu_to_le64(tsf);
3299
3300 /* Convert to dBm */
3301 iwl4965_rt->rt_dbmsignal = signal;
3302 iwl4965_rt->rt_dbmnoise = noise;
3303
3304 /* Convert the channel frequency and set the flags */
3305 iwl4965_rt->rt_channelMHz = cpu_to_le16(stats->freq);
3306 if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
3307 iwl4965_rt->rt_chbitmask =
3308 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
3309 else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
3310 iwl4965_rt->rt_chbitmask =
3311 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
3312 else /* 802.11g */
3313 iwl4965_rt->rt_chbitmask =
3314 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ));
3315
3316 rate = iwl4965_rate_index_from_plcp(rate);
3317 if (rate == -1)
3318 iwl4965_rt->rt_rate = 0;
3319 else
3320 iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee;
3321
3322 /* antenna number */
3323 iwl4965_rt->rt_antenna =
3324 le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
3325
3326 /* set the preamble flag if we have it */
3327 if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
3328 iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3329
3330 IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
3331
3332 stats->flag |= RX_FLAG_RADIOTAP;
3333 ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
3334 rxb->skb = NULL;
3335}
3336
3337 3249
3338#define IWL_PACKET_RETRY_TIME HZ 3250#define IWL_PACKET_RETRY_TIME HZ
3339 3251
@@ -7556,6 +7468,8 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
7556 mutex_lock(&priv->mutex); 7468 mutex_lock(&priv->mutex);
7557 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); 7469 IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
7558 7470
7471 priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
7472
7559 if (!iwl4965_is_ready(priv)) { 7473 if (!iwl4965_is_ready(priv)) {
7560 IWL_DEBUG_MAC80211("leave - not ready\n"); 7474 IWL_DEBUG_MAC80211("leave - not ready\n");
7561 ret = -EIO; 7475 ret = -EIO;