iwlwifi: proper monitor support
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl3945-base.c
index c366ad55f70e4e2b7c464e5b19e31b43cf7f3b2b..40b69182e4dc03e0af6127551428741c2e5ad2e0 100644 (file)
@@ -1497,16 +1497,6 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv,
        return priv->ibss_beacon->len;
 }
 
-static int iwl3945_rate_index_from_plcp(int plcp)
-{
-       int i = 0;
-
-       for (i = 0; i < IWL_RATE_COUNT; i++)
-               if (iwl3945_rates[i].plcp == plcp)
-                       return i;
-       return -1;
-}
-
 static u8 iwl3945_rate_get_lowest_plcp(int rate_mask)
 {
        u8 i;
@@ -3121,94 +3111,6 @@ void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb,
        }
 }
 
-void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv,
-                                   struct iwl3945_rx_mem_buffer *rxb,
-                                   void *data, short len,
-                                   struct ieee80211_rx_status *stats,
-                                   u16 phy_flags)
-{
-       struct iwl3945_rt_rx_hdr *iwl3945_rt;
-
-       /* First cache any information we need before we overwrite
-        * the information provided in the skb from the hardware */
-       s8 signal = stats->ssi;
-       s8 noise = 0;
-       int rate = stats->rate;
-       u64 tsf = stats->mactime;
-       __le16 phy_flags_hw = cpu_to_le16(phy_flags);
-
-       /* We received data from the HW, so stop the watchdog */
-       if (len > IWL_RX_BUF_SIZE - sizeof(*iwl3945_rt)) {
-               IWL_DEBUG_DROP("Dropping too large packet in monitor\n");
-               return;
-       }
-
-       /* copy the frame data to write after where the radiotap header goes */
-       iwl3945_rt = (void *)rxb->skb->data;
-       memmove(iwl3945_rt->payload, data, len);
-
-       iwl3945_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
-       iwl3945_rt->rt_hdr.it_pad = 0; /* always good to zero */
-
-       /* total header + data */
-       iwl3945_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl3945_rt));
-
-       /* Set the size of the skb to the size of the frame */
-       skb_put(rxb->skb, sizeof(*iwl3945_rt) + len);
-
-       /* Big bitfield of all the fields we provide in radiotap */
-       iwl3945_rt->rt_hdr.it_present =
-           cpu_to_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));
-
-       /* Zero the flags, we'll add to them as we go */
-       iwl3945_rt->rt_flags = 0;
-
-       iwl3945_rt->rt_tsf = cpu_to_le64(tsf);
-
-       /* Convert to dBm */
-       iwl3945_rt->rt_dbmsignal = signal;
-       iwl3945_rt->rt_dbmnoise = noise;
-
-       /* Convert the channel frequency and set the flags */
-       iwl3945_rt->rt_channelMHz = cpu_to_le16(stats->freq);
-       if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
-               iwl3945_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
-       else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
-               iwl3945_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
-       else    /* 802.11g */
-               iwl3945_rt->rt_chbitmask =
-                   cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ));
-
-       rate = iwl3945_rate_index_from_plcp(rate);
-       if (rate == -1)
-               iwl3945_rt->rt_rate = 0;
-       else
-               iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee;
-
-       /* antenna number */
-       iwl3945_rt->rt_antenna =
-               le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 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;
-
-       IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
-
-       stats->flag |= RX_FLAG_RADIOTAP;
-       ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
-       rxb->skb = NULL;
-}
-
-
 #define IWL_PACKET_RETRY_TIME HZ
 
 int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header)
@@ -4147,6 +4049,15 @@ static void iwl3945_rx_allocate(struct iwl3945_priv *priv)
                         * more buffers it will schedule replenish */
                        break;
                }
+
+               /* If radiotap head is required, reserve some headroom here.
+                * The physical head count is a variable rx_stats->phy_count.
+                * We reserve 4 bytes here. Plus these extra bytes, the
+                * headroom of the physical head should be enough for the
+                * radiotap head that iwl3945 supported. See iwl3945_rt.
+                */
+               skb_reserve(rxb->skb, 4);
+
                priv->alloc_rxb_skb++;
                list_del(element);
 
@@ -7114,6 +7025,8 @@ 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);
 
+       priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
+
        if (!iwl3945_is_ready(priv)) {
                IWL_DEBUG_MAC80211("leave - not ready\n");
                ret = -EIO;
This page took 0.025206 seconds and 5 git commands to generate.