|
@@ -789,107 +789,6 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-static void iwl_add_radiotap(struct iwl_priv *priv,
|
|
|
|
- struct sk_buff *skb,
|
|
|
|
- struct iwl_rx_phy_res *rx_start,
|
|
|
|
- struct ieee80211_rx_status *stats,
|
|
|
|
- u32 ampdu_status)
|
|
|
|
-{
|
|
|
|
- s8 signal = stats->signal;
|
|
|
|
- s8 noise = 0;
|
|
|
|
- int rate = stats->rate_idx;
|
|
|
|
- u64 tsf = stats->mactime;
|
|
|
|
- __le16 antenna;
|
|
|
|
- __le16 phy_flags_hw = rx_start->phy_flags;
|
|
|
|
- struct iwl4965_rt_rx_hdr {
|
|
|
|
- struct ieee80211_radiotap_header rt_hdr;
|
|
|
|
- __le64 rt_tsf; /* TSF */
|
|
|
|
- u8 rt_flags; /* radiotap packet flags */
|
|
|
|
- u8 rt_rate; /* rate in 500kb/s */
|
|
|
|
- __le16 rt_channelMHz; /* channel in MHz */
|
|
|
|
- __le16 rt_chbitmask; /* channel bitfield */
|
|
|
|
- s8 rt_dbmsignal; /* signal in dBm, kluged to signed */
|
|
|
|
- s8 rt_dbmnoise;
|
|
|
|
- u8 rt_antenna; /* antenna number */
|
|
|
|
- } __attribute__ ((packed)) *iwl4965_rt;
|
|
|
|
-
|
|
|
|
- /* TODO: We won't have enough headroom for HT frames. Fix it later. */
|
|
|
|
- if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
|
|
|
|
- if (net_ratelimit())
|
|
|
|
- printk(KERN_ERR "not enough headroom [%d] for "
|
|
|
|
- "radiotap head [%zd]\n",
|
|
|
|
- skb_headroom(skb), sizeof(*iwl4965_rt));
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* put radiotap header in front of 802.11 header and data */
|
|
|
|
- iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
|
|
|
|
-
|
|
|
|
- /* initialise radiotap header */
|
|
|
|
- iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
|
|
|
|
- iwl4965_rt->rt_hdr.it_pad = 0;
|
|
|
|
-
|
|
|
|
- /* total header + data */
|
|
|
|
- put_unaligned_le16(sizeof(*iwl4965_rt), &iwl4965_rt->rt_hdr.it_len);
|
|
|
|
-
|
|
|
|
- /* Indicate all the fields we add to the radiotap header */
|
|
|
|
- put_unaligned_le32((1 << IEEE80211_RADIOTAP_TSFT) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_FLAGS) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_RATE) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_CHANNEL) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
|
|
|
|
- (1 << IEEE80211_RADIOTAP_ANTENNA),
|
|
|
|
- &(iwl4965_rt->rt_hdr.it_present));
|
|
|
|
-
|
|
|
|
- /* Zero the flags, we'll add to them as we go */
|
|
|
|
- iwl4965_rt->rt_flags = 0;
|
|
|
|
-
|
|
|
|
- put_unaligned_le64(tsf, &iwl4965_rt->rt_tsf);
|
|
|
|
-
|
|
|
|
- iwl4965_rt->rt_dbmsignal = signal;
|
|
|
|
- iwl4965_rt->rt_dbmnoise = noise;
|
|
|
|
-
|
|
|
|
- /* Convert the channel frequency and set the flags */
|
|
|
|
- put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
|
|
|
|
- if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
|
|
|
|
- put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
|
|
|
|
- &iwl4965_rt->rt_chbitmask);
|
|
|
|
- else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
|
|
|
|
- put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
|
|
|
|
- &iwl4965_rt->rt_chbitmask);
|
|
|
|
- else /* 802.11g */
|
|
|
|
- put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
|
|
|
|
- &iwl4965_rt->rt_chbitmask);
|
|
|
|
-
|
|
|
|
- if (rate == -1)
|
|
|
|
- iwl4965_rt->rt_rate = 0;
|
|
|
|
- else
|
|
|
|
- iwl4965_rt->rt_rate = iwl_rates[rate].ieee;
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * "antenna number"
|
|
|
|
- *
|
|
|
|
- * It seems that the antenna field in the phy flags value
|
|
|
|
- * is actually a bitfield. This is undefined by radiotap,
|
|
|
|
- * it wants an actual antenna number but I always get "7"
|
|
|
|
- * for most legacy frames I receive indicating that the
|
|
|
|
- * same frame was received on all three RX chains.
|
|
|
|
- *
|
|
|
|
- * I think this field should be removed in favour of a
|
|
|
|
- * new 802.11n radiotap field "RX chains" that is defined
|
|
|
|
- * as a bitmask.
|
|
|
|
- */
|
|
|
|
- antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
|
|
|
|
- iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4;
|
|
|
|
-
|
|
|
|
- /* set the preamble flag if appropriate */
|
|
|
|
- if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
|
|
|
- iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
|
|
|
-
|
|
|
|
- stats->flag |= RX_FLAG_RADIOTAP;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
|
|
static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
|
|
{
|
|
{
|
|
/* 0 - mgmt, 1 - cnt, 2 - data */
|
|
/* 0 - mgmt, 1 - cnt, 2 - data */
|
|
@@ -1074,9 +973,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
|
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
|
|
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (priv->add_radiotap)
|
|
|
|
- iwl_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
|
|
|
|
-
|
|
|
|
iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
|
|
iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
|
|
ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
|
|
ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
|
|
priv->alloc_rxb_skb--;
|
|
priv->alloc_rxb_skb--;
|
|
@@ -1171,7 +1067,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
|
if (rx_status.band == IEEE80211_BAND_5GHZ)
|
|
if (rx_status.band == IEEE80211_BAND_5GHZ)
|
|
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
|
|
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
|
|
|
|
|
|
- rx_status.antenna = 0;
|
|
|
|
rx_status.flag = 0;
|
|
rx_status.flag = 0;
|
|
rx_status.flag |= RX_FLAG_TSFT;
|
|
rx_status.flag |= RX_FLAG_TSFT;
|
|
|
|
|
|
@@ -1250,6 +1145,26 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
|
rx_status.signal, rx_status.noise, rx_status.signal,
|
|
rx_status.signal, rx_status.noise, rx_status.signal,
|
|
(unsigned long long)rx_status.mactime);
|
|
(unsigned long long)rx_status.mactime);
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * "antenna number"
|
|
|
|
+ *
|
|
|
|
+ * It seems that the antenna field in the phy flags value
|
|
|
|
+ * is actually a bitfield. This is undefined by radiotap,
|
|
|
|
+ * it wants an actual antenna number but I always get "7"
|
|
|
|
+ * for most legacy frames I receive indicating that the
|
|
|
|
+ * same frame was received on all three RX chains.
|
|
|
|
+ *
|
|
|
|
+ * I think this field should be removed in favour of a
|
|
|
|
+ * new 802.11n radiotap field "RX chains" that is defined
|
|
|
|
+ * as a bitmask.
|
|
|
|
+ */
|
|
|
|
+ rx_status.antenna = le16_to_cpu(rx_start->phy_flags &
|
|
|
|
+ RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
|
|
|
|
+
|
|
|
|
+ /* set the preamble flag if appropriate */
|
|
|
|
+ if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
|
|
|
+ rx_status.flag |= RX_FLAG_SHORTPRE;
|
|
|
|
+
|
|
/* Take shortcut when only in monitor mode */
|
|
/* Take shortcut when only in monitor mode */
|
|
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
|
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
|
iwl_pass_packet_to_mac80211(priv, include_phy,
|
|
iwl_pass_packet_to_mac80211(priv, include_phy,
|