Commit 0869aea0 authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: remove RX_FLAG_RADIOTAP

While there may be a case for a driver adding its
own bits of radiotap information, none currently
does. Also, drivers would have to copy the code
to generate the radiotap bits that now mac80211
generates. If some driver in the future needs to
add some driver-specific information I'd expect
that to be in a radiotap vendor namespace and we
can add a different way of passing such data up
and having mac80211 include it.

Additionally, rename IEEE80211_CONF_RADIOTAP to
IEEE80211_CONF_MONITOR since it's still used by
b43(legacy) to obtain per-frame timestamps.

The purpose of this patch is to simplify the RX
code in mac80211 to make it easier to add paged
skb support.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 6a86b9c7
...@@ -3573,7 +3573,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) ...@@ -3573,7 +3573,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
if (conf->channel->hw_value != phy->channel) if (conf->channel->hw_value != phy->channel)
b43_switch_channel(dev, conf->channel->hw_value); b43_switch_channel(dev, conf->channel->hw_value);
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
/* Adjust the desired TX power level. */ /* Adjust the desired TX power level. */
if (conf->power_level != 0) { if (conf->power_level != 0) {
......
...@@ -2676,7 +2676,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2676,7 +2676,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
if (conf->channel->hw_value != phy->channel) if (conf->channel->hw_value != phy->channel)
b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
/* Adjust the desired TX power level. */ /* Adjust the desired TX power level. */
if (conf->power_level != 0) { if (conf->power_level != 0) {
......
...@@ -494,7 +494,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) ...@@ -494,7 +494,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_MMIC_ERROR: Michael MIC error was reported on this frame. * @RX_FLAG_MMIC_ERROR: Michael MIC error was reported on this frame.
* Use together with %RX_FLAG_MMIC_STRIPPED. * Use together with %RX_FLAG_MMIC_STRIPPED.
* @RX_FLAG_DECRYPTED: This frame was decrypted in hardware. * @RX_FLAG_DECRYPTED: This frame was decrypted in hardware.
* @RX_FLAG_RADIOTAP: This frame starts with a radiotap header.
* @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame, * @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame,
* verification has been done by the hardware. * verification has been done by the hardware.
* @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame. * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame.
...@@ -515,7 +514,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) ...@@ -515,7 +514,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
enum mac80211_rx_flags { enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = 1<<0, RX_FLAG_MMIC_ERROR = 1<<0,
RX_FLAG_DECRYPTED = 1<<1, RX_FLAG_DECRYPTED = 1<<1,
RX_FLAG_RADIOTAP = 1<<2,
RX_FLAG_MMIC_STRIPPED = 1<<3, RX_FLAG_MMIC_STRIPPED = 1<<3,
RX_FLAG_IV_STRIPPED = 1<<4, RX_FLAG_IV_STRIPPED = 1<<4,
RX_FLAG_FAILED_FCS_CRC = 1<<5, RX_FLAG_FAILED_FCS_CRC = 1<<5,
...@@ -565,7 +563,9 @@ struct ieee80211_rx_status { ...@@ -565,7 +563,9 @@ struct ieee80211_rx_status {
* *
* Flags to define PHY configuration options * Flags to define PHY configuration options
* *
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) * @IEEE80211_CONF_MONITOR: there's a monitor interface present -- use this
* to determine for example whether to calculate timestamps for packets
* or not, do not use instead of filter flags!
* @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only) * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only)
* @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set
* the driver should be prepared to handle configuration requests but * the driver should be prepared to handle configuration requests but
...@@ -574,7 +574,7 @@ struct ieee80211_rx_status { ...@@ -574,7 +574,7 @@ struct ieee80211_rx_status {
* it can also be unset in that case when monitor interfaces are active. * it can also be unset in that case when monitor interfaces are active.
*/ */
enum ieee80211_conf_flags { enum ieee80211_conf_flags {
IEEE80211_CONF_RADIOTAP = (1<<0), IEEE80211_CONF_MONITOR = (1<<0),
IEEE80211_CONF_PS = (1<<1), IEEE80211_CONF_PS = (1<<1),
IEEE80211_CONF_IDLE = (1<<2), IEEE80211_CONF_IDLE = (1<<2),
}; };
...@@ -584,7 +584,7 @@ enum ieee80211_conf_flags { ...@@ -584,7 +584,7 @@ enum ieee80211_conf_flags {
* enum ieee80211_conf_changed - denotes which configuration changed * enum ieee80211_conf_changed - denotes which configuration changed
* *
* @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
* @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed * @IEEE80211_CONF_CHANGE_MONITOR: the monitor flag changed
* @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
* @IEEE80211_CONF_CHANGE_POWER: the TX power changed * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
* @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
...@@ -593,7 +593,7 @@ enum ieee80211_conf_flags { ...@@ -593,7 +593,7 @@ enum ieee80211_conf_flags {
*/ */
enum ieee80211_conf_changed { enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), IEEE80211_CONF_CHANGE_MONITOR = BIT(3),
IEEE80211_CONF_CHANGE_PS = BIT(4), IEEE80211_CONF_CHANGE_PS = BIT(4),
IEEE80211_CONF_CHANGE_POWER = BIT(5), IEEE80211_CONF_CHANGE_POWER = BIT(5),
IEEE80211_CONF_CHANGE_CHANNEL = BIT(6), IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
...@@ -1661,8 +1661,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw); ...@@ -1661,8 +1661,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
* ieee80211_rx - receive frame * ieee80211_rx - receive frame
* *
* Use this function to hand received frames to mac80211. The receive * Use this function to hand received frames to mac80211. The receive
* buffer in @skb must start with an IEEE 802.11 header or a radiotap * buffer in @skb must start with an IEEE 802.11 header.
* header if %RX_FLAG_RADIOTAP is set in the @status flags.
* *
* This function may not be called in IRQ context. Calls to this function * This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls to * for a single hardware must be synchronized against each other. Calls to
......
...@@ -214,8 +214,8 @@ static int ieee80211_open(struct net_device *dev) ...@@ -214,8 +214,8 @@ static int ieee80211_open(struct net_device *dev)
/* must be before the call to ieee80211_configure_filter */ /* must be before the call to ieee80211_configure_filter */
local->monitors++; local->monitors++;
if (local->monitors == 1) { if (local->monitors == 1) {
local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
} }
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
...@@ -435,8 +435,8 @@ static int ieee80211_stop(struct net_device *dev) ...@@ -435,8 +435,8 @@ static int ieee80211_stop(struct net_device *dev)
local->monitors--; local->monitors--;
if (local->monitors == 0) { if (local->monitors == 0) {
local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
} }
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
......
...@@ -39,11 +39,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, ...@@ -39,11 +39,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
* only useful for monitoring. * only useful for monitoring.
*/ */
static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
struct sk_buff *skb, struct sk_buff *skb)
int rtap_len)
{ {
skb_pull(skb, rtap_len);
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) {
if (likely(skb->len > FCS_LEN)) if (likely(skb->len > FCS_LEN))
skb_trim(skb, skb->len - FCS_LEN); skb_trim(skb, skb->len - FCS_LEN);
...@@ -59,15 +56,14 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, ...@@ -59,15 +56,14 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
} }
static inline int should_drop_frame(struct sk_buff *skb, static inline int should_drop_frame(struct sk_buff *skb,
int present_fcs_len, int present_fcs_len)
int radiotap_len)
{ {
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
return 1; return 1;
if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) if (unlikely(skb->len < 16 + present_fcs_len))
return 1; return 1;
if (ieee80211_is_ctl(hdr->frame_control) && if (ieee80211_is_ctl(hdr->frame_control) &&
!ieee80211_is_pspoll(hdr->frame_control) && !ieee80211_is_pspoll(hdr->frame_control) &&
...@@ -225,7 +221,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -225,7 +221,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
struct sk_buff *skb, *skb2; struct sk_buff *skb, *skb2;
struct net_device *prev_dev = NULL; struct net_device *prev_dev = NULL;
int present_fcs_len = 0; int present_fcs_len = 0;
int rtap_len = 0;
/* /*
* First, we may need to make a copy of the skb because * First, we may need to make a copy of the skb because
...@@ -235,25 +230,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -235,25 +230,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
* We don't need to, of course, if we aren't going to return * We don't need to, of course, if we aren't going to return
* the SKB because it has a bad FCS/PLCP checksum. * the SKB because it has a bad FCS/PLCP checksum.
*/ */
if (status->flag & RX_FLAG_RADIOTAP)
rtap_len = ieee80211_get_radiotap_len(origskb->data); /* room for the radiotap header based on driver features */
else needed_headroom = ieee80211_rx_radiotap_len(local, status);
/* room for the radiotap header based on driver features */
needed_headroom = ieee80211_rx_radiotap_len(local, status);
if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
present_fcs_len = FCS_LEN; present_fcs_len = FCS_LEN;
if (!local->monitors) { if (!local->monitors) {
if (should_drop_frame(origskb, present_fcs_len, rtap_len)) { if (should_drop_frame(origskb, present_fcs_len)) {
dev_kfree_skb(origskb); dev_kfree_skb(origskb);
return NULL; return NULL;
} }
return remove_monitor_info(local, origskb, rtap_len); return remove_monitor_info(local, origskb);
} }
if (should_drop_frame(origskb, present_fcs_len, rtap_len)) { if (should_drop_frame(origskb, present_fcs_len)) {
/* only need to expand headroom if necessary */ /* only need to expand headroom if necessary */
skb = origskb; skb = origskb;
origskb = NULL; origskb = NULL;
...@@ -277,16 +270,14 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -277,16 +270,14 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
*/ */
skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC);
origskb = remove_monitor_info(local, origskb, rtap_len); origskb = remove_monitor_info(local, origskb);
if (!skb) if (!skb)
return origskb; return origskb;
} }
/* if necessary, prepend radiotap information */ /* prepend radiotap information */
if (!(status->flag & RX_FLAG_RADIOTAP)) ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
ieee80211_add_rx_radiotap_header(local, skb, rate,
needed_headroom);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment