Search Linux Wireless

Re: [PATCH] iwl4965: remove useless network and duplicate checking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 22, 2008 at 12:03 PM, Johannes Berg
<johannes@xxxxxxxxxxxxxxxx> wrote:
> The iwlwifi drivers go to great lengths to avoid passing packets to
> mac80211 they think shouldn't go there, while mac80211 can (of course!)
> handle them very well.
>
> Especially in the case of duplicate packets this is interesting
> because it's such a performance hog (especially for IBSS networks)
> while mac80211 does that work on the side without much effort.
>
> This patch removes all that and leaves only what is absolutely
> necessary for the hardware.
>
> Signed-off-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
> ---
> Unless I made a mistake, obviously.
>
> Of course, it would be good to use the 20 descriptors per skb
> to be able to fill the performance gap again...
>
> Somebody should port this to iwl3945 too.
>
>  drivers/net/wireless/iwlwifi/iwl-4965.c     |   81 +++++-------------
>  drivers/net/wireless/iwlwifi/iwl-core.c     |    4
>  drivers/net/wireless/iwlwifi/iwl-dev.h      |   19 ----
>  drivers/net/wireless/iwlwifi/iwl4965-base.c |  122 ----------------------------
>  4 files changed, 27 insertions(+), 199 deletions(-)
>
> --- everything.orig/drivers/net/wireless/iwlwifi/iwl-4965.c     2008-05-22 10:37:41.000000000 +0200
> +++ everything/drivers/net/wireless/iwlwifi/iwl-4965.c  2008-05-22 10:42:41.000000000 +0200
> @@ -2456,10 +2456,10 @@ static u32 iwl4965_translate_rx_status(s
>        return decrypt_out;
>  }
>
> -static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
> -                                      int include_phy,
> -                                      struct iwl_rx_mem_buffer *rxb,
> -                                      struct ieee80211_rx_status *stats)
> +static void iwl4965_pass_packet_to_mac80211(struct iwl_priv *priv,
> +                                           int include_phy,
> +                                           struct iwl_rx_mem_buffer *rxb,
> +                                           struct ieee80211_rx_status *stats)
>  {
>        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
>        struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
> @@ -2498,12 +2498,6 @@ static void iwl4965_handle_data_packet(s
>                rx_start->byte_count = amsdu->byte_count;
>                rx_end = (__le32 *) (((u8 *) hdr) + len);
>        }
> -       /* In monitor mode allow 802.11 ACk frames (10 bytes) */
> -       if (len > priv->hw_params.max_pkt_size ||
> -           len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) {
> -               IWL_WARNING("byte count out of range [16,4K] : %d\n", len);
> -               return;
> -       }
>
>        ampdu_status = le32_to_cpu(*rx_end);
>        skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32);
> @@ -2762,6 +2756,21 @@ static inline void iwl4965_dbg_report_fr
>  }
>  #endif
>
> +/* This is necessary only for a number of statistics, see the user. */
> +static int iwl4965_is_network_packet(struct iwl_priv *priv,
> +                                    struct ieee80211_hdr *header)
> +{
> +       switch (priv->iw_mode) {
> +       case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source    | BSSID */
> +               /* packets to our IBSS update information */
> +               return !compare_ether_addr(header->addr3, priv->bssid);
> +       case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
> +               /* packets to our BSS update information */
> +               return !compare_ether_addr(header->addr2, priv->bssid);
> +       default:
> +               return 1;
> +       }
> +}
>
>
>  /* Called for REPLY_RX (legacy ABG frames), or
> @@ -2873,8 +2882,9 @@ static void iwl4965_rx_reply_rx(struct i
>                              (unsigned long long)rx_status.mactime);
>
>
> +       /* Take shortcut when only in monitor mode */
>        if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
> -               iwl4965_handle_data_packet(priv, 1, include_phy,
> +               iwl4965_pass_packet_to_mac80211(priv, include_phy,
>                                                 rxb, &rx_status);
>                return;
>        }
> @@ -2889,54 +2899,15 @@ static void iwl4965_rx_reply_rx(struct i
>        fc = le16_to_cpu(header->frame_control);
>        switch (fc & IEEE80211_FCTL_FTYPE) {
>        case IEEE80211_FTYPE_MGMT:
> +       case IEEE80211_FTYPE_DATA:
>                if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
> -                       iwl4965_update_ps_mode(priv, fc  & IEEE80211_FCTL_PM,
> -                                               header->addr2);
> -               iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
> -               break;
> -
> -       case IEEE80211_FTYPE_CTL:
> -#ifdef CONFIG_IWL4965_HT
> -               switch (fc & IEEE80211_FCTL_STYPE) {
> -               case IEEE80211_STYPE_BACK_REQ:
> -                       IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
> -                       iwl4965_handle_data_packet(priv, 0, include_phy,
> -                                               rxb, &rx_status);
> -                       break;
> -               default:
> -                       break;
> -               }
> -#endif
> -               break;
> -
> -       case IEEE80211_FTYPE_DATA: {
> -               DECLARE_MAC_BUF(mac1);
> -               DECLARE_MAC_BUF(mac2);
> -               DECLARE_MAC_BUF(mac3);
> -
> -               if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
> -                       iwl4965_update_ps_mode(priv, fc  & IEEE80211_FCTL_PM,
> +                       iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
>                                                header->addr2);
> -
> -               if (unlikely(!network_packet))
> -                       IWL_DEBUG_DROP("Dropping (non network): "
> -                                      "%s, %s, %s\n",
> -                                      print_mac(mac1, header->addr1),
> -                                      print_mac(mac2, header->addr2),
> -                                      print_mac(mac3, header->addr3));
> -               else if (unlikely(iwl4965_is_duplicate_packet(priv, header)))
> -                       IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
> -                                      print_mac(mac1, header->addr1),
> -                                      print_mac(mac2, header->addr2),
> -                                      print_mac(mac3, header->addr3));
> -               else
> -                       iwl4965_handle_data_packet(priv, 1, include_phy, rxb,
> -                                                  &rx_status);
> -               break;
> -       }
> +               /* fall through */
>        default:
> +               iwl4965_pass_packet_to_mac80211(priv, include_phy, rxb,
> +                                               &rx_status);
>                break;
> -
>        }
>  }
>
> --- everything.orig/drivers/net/wireless/iwlwifi/iwl-dev.h      2008-05-22 10:37:41.000000000 +0200
> +++ everything/drivers/net/wireless/iwlwifi/iwl-dev.h   2008-05-22 10:37:42.000000000 +0200
> @@ -532,8 +532,6 @@ struct iwl4965_ucode {
>        u8 data[0];             /* data in same order as "size" elements */
>  };
>
> -#define IWL_IBSS_MAC_HASH_SIZE 32
> -
>  struct iwl4965_ibss_seq {
>        u8 mac[ETH_ALEN];
>        u16 seq_num;
> @@ -633,16 +631,7 @@ extern int iwl_send_add_sta(struct iwl_p
>                            struct iwl_addsta_cmd *sta, u8 flags);
>  u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
>                         u8 flags, struct ieee80211_ht_info *ht_info);
> -extern int iwl4965_is_network_packet(struct iwl_priv *priv,
> -                                struct ieee80211_hdr *header);
>  extern int iwl4965_power_init_handle(struct iwl_priv *priv);
> -extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv,
> -                                          struct iwl_rx_mem_buffer *rxb,
> -                                          void *data, short len,
> -                                          struct ieee80211_rx_status *stats,
> -                                          u16 phy_flags);
> -extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,
> -                                      struct ieee80211_hdr *header);
>  extern int iwl4965_calc_db_from_ratio(int sig_ratio);
>  extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
>  extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
> @@ -1129,14 +1118,6 @@ struct iwl_priv {
>        u32 last_beacon_time;
>        u64 last_tsf;
>
> -       /* Duplicate packet detection */
> -       u16 last_seq_num;
> -       u16 last_frag_num;
> -       unsigned long last_packet_time;
> -
> -       /* Hash table for finding stations in IBSS network */
> -       struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
> -
>        /* eeprom */
>        u8 *eeprom;
>        struct iwl_eeprom_calib_info *calib_info;
> --- everything.orig/drivers/net/wireless/iwlwifi/iwl4965-base.c 2008-05-22 10:37:40.000000000 +0200
> +++ everything/drivers/net/wireless/iwlwifi/iwl4965-base.c      2008-05-22 10:42:27.000000000 +0200
> @@ -927,36 +927,6 @@ static void iwl4965_activate_qos(struct
>        }
>  }
>
> -int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
> -{
> -       /* Filter incoming packets to determine if they are targeted toward
> -        * this network, discarding packets coming from ourselves */
> -       switch (priv->iw_mode) {
> -       case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source    | BSSID */
> -               /* packets from our adapter are dropped (echo) */
> -               if (!compare_ether_addr(header->addr2, priv->mac_addr))
> -                       return 0;
> -               /* {broad,multi}cast packets to our IBSS go through */
> -               if (is_multicast_ether_addr(header->addr1))
> -                       return !compare_ether_addr(header->addr3, priv->bssid);
> -               /* packets to our adapter go through */
> -               return !compare_ether_addr(header->addr1, priv->mac_addr);
> -       case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
> -               /* packets from our adapter are dropped (echo) */
> -               if (!compare_ether_addr(header->addr3, priv->mac_addr))
> -                       return 0;
> -               /* {broad,multi}cast packets to our BSS go through */
> -               if (is_multicast_ether_addr(header->addr1))
> -                       return !compare_ether_addr(header->addr2, priv->bssid);
> -               /* packets to our adapter go through */
> -               return !compare_ether_addr(header->addr1, priv->mac_addr);
> -       default:
> -               break;
> -       }
> -
> -       return 1;
> -}
> -
>  #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
>
>  static const char *iwl4965_get_tx_fail_reason(u32 status)
> @@ -1037,20 +1007,6 @@ static int iwl4965_scan_cancel_timeout(s
>        return ret;
>  }
>
> -static void iwl4965_sequence_reset(struct iwl_priv *priv)
> -{
> -       /* Reset ieee stats */
> -
> -       /* We don't reset the net_device_stats (ieee->stats) on
> -        * re-association */
> -
> -       priv->last_seq_num = -1;
> -       priv->last_frag_num = -1;
> -       priv->last_packet_time = 0;
> -
> -       iwl4965_scan_cancel(priv);
> -}
> -
>  #define MAX_UCODE_BEACON_INTERVAL      4096
>  #define INTEL_CONN_LISTEN_INTERVAL     __constant_cpu_to_le16(0xA)
>
> @@ -1404,72 +1360,6 @@ void iwl4965_radio_kill_sw(struct iwl_pr
>        return;
>  }
>
> -#define IWL_PACKET_RETRY_TIME HZ
> -
> -int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
> -{
> -       u16 sc = le16_to_cpu(header->seq_ctrl);
> -       u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
> -       u16 frag = sc & IEEE80211_SCTL_FRAG;
> -       u16 *last_seq, *last_frag;
> -       unsigned long *last_time;
> -
> -       switch (priv->iw_mode) {
> -       case IEEE80211_IF_TYPE_IBSS:{
> -               struct list_head *p;
> -               struct iwl4965_ibss_seq *entry = NULL;
> -               u8 *mac = header->addr2;
> -               int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
> -
> -               __list_for_each(p, &priv->ibss_mac_hash[index]) {
> -                       entry = list_entry(p, struct iwl4965_ibss_seq, list);
> -                       if (!compare_ether_addr(entry->mac, mac))
> -                               break;
> -               }
> -               if (p == &priv->ibss_mac_hash[index]) {
> -                       entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
> -                       if (!entry) {
> -                               IWL_ERROR("Cannot malloc new mac entry\n");
> -                               return 0;
> -                       }
> -                       memcpy(entry->mac, mac, ETH_ALEN);
> -                       entry->seq_num = seq;
> -                       entry->frag_num = frag;
> -                       entry->packet_time = jiffies;
> -                       list_add(&entry->list, &priv->ibss_mac_hash[index]);
> -                       return 0;
> -               }
> -               last_seq = &entry->seq_num;
> -               last_frag = &entry->frag_num;
> -               last_time = &entry->packet_time;
> -               break;
> -       }
> -       case IEEE80211_IF_TYPE_STA:
> -               last_seq = &priv->last_seq_num;
> -               last_frag = &priv->last_frag_num;
> -               last_time = &priv->last_packet_time;
> -               break;
> -       default:
> -               return 0;
> -       }
> -       if ((*last_seq == seq) &&
> -           time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
> -               if (*last_frag == frag)
> -                       goto drop;
> -               if (*last_frag + 1 != frag)
> -                       /* out-of-order fragment */
> -                       goto drop;
> -       } else
> -               *last_seq = seq;
> -
> -       *last_frag = frag;
> -       *last_time = jiffies;
> -       return 0;
> -
> - drop:
> -       return 1;
> -}
> -
>  #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
>
>  #include "iwl-spectrum.h"
> @@ -4074,7 +3964,7 @@ static void iwl4965_post_associate(struc
>                break;
>        }
>
> -       iwl4965_sequence_reset(priv);
> +       iwl4965_scan_cancel(priv);
>
>        /* Enable Rx differential gain and sensitivity calibrations */
>        iwl_chain_noise_reset(priv);
> @@ -5835,8 +5725,6 @@ static int iwl4965_pci_probe(struct pci_
>  static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
>  {
>        struct iwl_priv *priv = pci_get_drvdata(pdev);
> -       struct list_head *p, *q;
> -       int i;
>        unsigned long flags;
>
>        if (!priv)
> @@ -5862,14 +5750,6 @@ static void __devexit iwl4965_pci_remove
>
>        iwl_synchronize_irq(priv);
>
> -       /* Free MAC hash list for ADHOC */
> -       for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) {
> -               list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
> -                       list_del(p);
> -                       kfree(list_entry(p, struct iwl4965_ibss_seq, list));
> -               }
> -       }
> -
>        iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT);
>        iwl_dbgfs_unregister(priv);
>        sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
> --- everything.orig/drivers/net/wireless/iwlwifi/iwl-core.c     2008-05-22 10:37:40.000000000 +0200
> +++ everything/drivers/net/wireless/iwlwifi/iwl-core.c  2008-05-22 10:42:27.000000000 +0200
> @@ -801,7 +801,6 @@ EXPORT_SYMBOL(iwl_setup_mac);
>  int iwl_init_drv(struct iwl_priv *priv)
>  {
>        int ret;
> -       int i;
>
>        priv->retry_rate = 1;
>        priv->ibss_beacon = NULL;
> @@ -812,9 +811,6 @@ int iwl_init_drv(struct iwl_priv *priv)
>        spin_lock_init(&priv->hcmd_lock);
>        spin_lock_init(&priv->lq_mngr.lock);
>
> -       for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++)
> -               INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
> -
>        INIT_LIST_HEAD(&priv->free_frames);
>
>        mutex_init(&priv->mutex);
>

Looks good to me. let me just repost it rebased over our latest code.

Thanks
Tomas
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux