diff options
author | Zhu Yi <yi.zhu@intel.com> | 2007-12-19 22:27:32 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:53 -0500 |
commit | 12342c475f5de17071eaf24ea2938ba8dfe285f2 (patch) | |
tree | a2cdfd191069397e093f2410009092e7e96c9325 /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | 7e94041ca17685cf12c658b8edc008dd0bdb00c7 (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.c | 90 |
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 | ||
3250 | void 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; |