Skip to content

Commit

Permalink
iwlwifi: use generic mac80211 radiotap headers
Browse files Browse the repository at this point in the history
remove drivers own implementation of radiotap in favor of the generic one
provided by mac80211.

also remove priv->add_radiotap because it is not used any more.

Signed-off-by: Bruno Randolf <br1@einfach.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Aug 22, 2008
1 parent 9deb1ae commit 6f0a2c4
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 208 deletions.
104 changes: 7 additions & 97 deletions drivers/net/wireless/iwlwifi/iwl-3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,99 +531,6 @@ static int iwl3945_is_network_packet(struct iwl3945_priv *priv,
}
}

static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
struct sk_buff *skb,
struct iwl3945_rx_frame_hdr *rx_hdr,
struct ieee80211_rx_status *stats)
{
/* First cache any information we need before we overwrite
* the information provided in the skb from the hardware */
s8 signal = stats->signal;
s8 noise = 0;
int rate = stats->rate_idx;
u64 tsf = stats->mactime;
__le16 phy_flags_hw = rx_hdr->phy_flags, antenna;

struct iwl3945_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)) *iwl3945_rt;

if (skb_headroom(skb) < sizeof(*iwl3945_rt)) {
if (net_ratelimit())
printk(KERN_ERR "not enough headroom [%d] for "
"radiotap head [%zd]\n",
skb_headroom(skb), sizeof(*iwl3945_rt));
return;
}

/* put radiotap header in front of 802.11 header and data */
iwl3945_rt = (void *)skb_push(skb, sizeof(*iwl3945_rt));

/* initialise radiotap header */
iwl3945_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
iwl3945_rt->rt_hdr.it_pad = 0;

/* total header + data */
put_unaligned_le16(sizeof(*iwl3945_rt), &iwl3945_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),
&iwl3945_rt->rt_hdr.it_present);

/* Zero the flags, we'll add to them as we go */
iwl3945_rt->rt_flags = 0;

put_unaligned_le64(tsf, &iwl3945_rt->rt_tsf);

iwl3945_rt->rt_dbmsignal = signal;
iwl3945_rt->rt_dbmnoise = noise;

/* Convert the channel frequency and set the flags */
put_unaligned_le16(stats->freq, &iwl3945_rt->rt_channelMHz);
if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ,
&iwl3945_rt->rt_chbitmask);
else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ,
&iwl3945_rt->rt_chbitmask);
else /* 802.11g */
put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ,
&iwl3945_rt->rt_chbitmask);

if (rate == -1)
iwl3945_rt->rt_rate = 0;
else {
if (stats->band == IEEE80211_BAND_5GHZ)
rate += IWL_FIRST_OFDM_RATE;

iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee;
}

/* antenna number */
antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
iwl3945_rt->rt_antenna = le16_to_cpu(antenna) >> 4;

/* set the preamble flag if we have it */
if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
iwl3945_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;

stats->flag |= RX_FLAG_RADIOTAP;
}

static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
struct iwl3945_rx_mem_buffer *rxb,
struct ieee80211_rx_status *stats)
Expand Down Expand Up @@ -657,9 +564,6 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv,
iwl3945_set_decrypted_flag(priv, rxb->skb,
le32_to_cpu(rx_end->status), stats);

if (priv->add_radiotap)
iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats);

#ifdef CONFIG_IWL3945_LEDS
if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len;
Expand All @@ -684,7 +588,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
u8 network_packet;

rx_status.antenna = 0;
rx_status.flag = 0;
rx_status.mactime = le64_to_cpu(rx_end->timestamp);
rx_status.freq =
Expand All @@ -696,6 +599,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;

rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags &
RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;

/* set the preamble flag if appropriate */
if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
rx_status.flag |= RX_FLAG_SHORTPRE;

if ((unlikely(rx_stats->phy_count > 20))) {
IWL_DEBUG_DROP
("dsp size out of range [0,20]: "
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-3945.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,6 @@ struct iwl3945_priv {

enum ieee80211_band band;
int alloc_rxb_skb;
bool add_radiotap;

void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
struct iwl3945_rx_mem_buffer *rxb);
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -2790,8 +2790,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);

priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);

if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) {
IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n");
goto out;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,6 @@ struct iwl_priv {

enum ieee80211_band band;
int alloc_rxb_skb;
bool add_radiotap;

void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
Expand Down
125 changes: 20 additions & 105 deletions drivers/net/wireless/iwlwifi/iwl-rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,107 +789,6 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
}
#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)
{
/* 0 - mgmt, 1 - cnt, 2 - data */
Expand Down Expand Up @@ -1074,9 +973,6 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
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);
ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
priv->alloc_rxb_skb--;
Expand Down Expand Up @@ -1171,7 +1067,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;

rx_status.antenna = 0;
rx_status.flag = 0;
rx_status.flag |= RX_FLAG_TSFT;

Expand Down Expand Up @@ -1250,6 +1145,26 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
rx_status.signal, rx_status.noise, rx_status.signal,
(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 */
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
iwl_pass_packet_to_mac80211(priv, include_phy,
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -6650,8 +6650,6 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
mutex_lock(&priv->mutex);
IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);

priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);

if (!iwl3945_is_ready(priv)) {
IWL_DEBUG_MAC80211("leave - not ready\n");
ret = -EIO;
Expand Down

0 comments on commit 6f0a2c4

Please sign in to comment.