Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
authorDavid S. Miller <davem@davemloft.net>
Sun, 11 Apr 2010 09:44:30 +0000 (02:44 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 11 Apr 2010 09:44:30 +0000 (02:44 -0700)
15 files changed:
1  2 
drivers/net/myri10ge/myri10ge.c
drivers/net/qlcnic/qlcnic_hw.c
drivers/net/r6040.c
drivers/net/stmmac/stmmac_main.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/vhost/vhost.c
include/net/x25.h
net/ipv4/udp.c
net/ipv6/udp.c
net/mac80211/mesh.c
net/mac80211/rx.c
net/x25/af_x25.c
net/x25/x25_in.c

@@@ -64,6 -64,7 +64,7 @@@
  #include <linux/moduleparam.h>
  #include <linux/io.h>
  #include <linux/log2.h>
+ #include <linux/slab.h>
  #include <net/checksum.h>
  #include <net/ip.h>
  #include <net/tcp.h>
@@@ -1689,7 -1690,7 +1690,7 @@@ myri10ge_set_pauseparam(struct net_devi
        if (pause->tx_pause != mgp->pause)
                return myri10ge_change_pause(mgp, pause->tx_pause);
        if (pause->rx_pause != mgp->pause)
 -              return myri10ge_change_pause(mgp, pause->tx_pause);
 +              return myri10ge_change_pause(mgp, pause->rx_pause);
        if (pause->autoneg != 0)
                return -EINVAL;
        return 0;
@@@ -24,6 -24,7 +24,7 @@@
  
  #include "qlcnic.h"
  
+ #include <linux/slab.h>
  #include <net/ip.h>
  
  #define MASK(n) ((1ULL<<(n))-1)
@@@ -430,9 -431,6 +431,9 @@@ void qlcnic_set_multi(struct net_devic
        u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        u32 mode = VPORT_MISS_MODE_DROP;
  
 +      if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
 +              return;
 +
        qlcnic_nic_add_mac(adapter, adapter->mac_addr);
        qlcnic_nic_add_mac(adapter, bcast_addr);
  
diff --combined drivers/net/r6040.c
@@@ -29,7 -29,6 +29,6 @@@
  #include <linux/timer.h>
  #include <linux/errno.h>
  #include <linux/ioport.h>
- #include <linux/slab.h>
  #include <linux/interrupt.h>
  #include <linux/pci.h>
  #include <linux/netdevice.h>
  #define RX_DESC_SIZE  (RX_DCNT * sizeof(struct r6040_descriptor))
  #define TX_DESC_SIZE  (TX_DCNT * sizeof(struct r6040_descriptor))
  #define MBCR_DEFAULT  0x012A  /* MAC Bus Control Register */
 -#define MCAST_MAX     4       /* Max number multicast addresses to filter */
 +#define MCAST_MAX     3       /* Max number multicast addresses to filter */
  
  /* Descriptor status */
  #define DSC_OWNER_MAC 0x8000  /* MAC is the owner of this descriptor */
@@@ -983,6 -982,9 +982,6 @@@ static void r6040_multicast_list(struc
                        crc >>= 26;
                        hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
                }
 -              /* Write the index of the hash table */
 -              for (i = 0; i < 4; i++)
 -                      iowrite16(hash_table[i] << 14, ioaddr + MCR1);
                /* Fill the MAC hash tables with their values */
                iowrite16(hash_table[0], ioaddr + MAR0);
                iowrite16(hash_table[1], ioaddr + MAR1);
                        iowrite16(adrp[1], ioaddr + MID_1M + 8 * i);
                        iowrite16(adrp[2], ioaddr + MID_1H + 8 * i);
                } else {
 -                      iowrite16(0xffff, ioaddr + MID_0L + 8 * i);
 -                      iowrite16(0xffff, ioaddr + MID_0M + 8 * i);
 -                      iowrite16(0xffff, ioaddr + MID_0H + 8 * i);
 +                      iowrite16(0xffff, ioaddr + MID_1L + 8 * i);
 +                      iowrite16(0xffff, ioaddr + MID_1M + 8 * i);
 +                      iowrite16(0xffff, ioaddr + MID_1H + 8 * i);
                }
                i++;
        }
@@@ -44,6 -44,7 +44,7 @@@
  #include <linux/phy.h>
  #include <linux/if_vlan.h>
  #include <linux/dma-mapping.h>
+ #include <linux/slab.h>
  #include "stmmac.h"
  
  #define STMMAC_RESOURCE_NAME  "stmmaceth"
@@@ -1685,7 -1686,7 +1686,7 @@@ static int stmmac_dvr_probe(struct plat
        }
        pr_info("done!\n");
  
 -      if (!request_mem_region(res->start, (res->end - res->start),
 +      if (!request_mem_region(res->start, resource_size(res),
                                pdev->name)) {
                pr_err("%s: ERROR: memory allocation failed"
                       "cannot get the I/O addr 0x%x\n",
                goto out;
        }
  
 -      addr = ioremap(res->start, (res->end - res->start));
 +      addr = ioremap(res->start, resource_size(res));
        if (!addr) {
 -              pr_err("%s: ERROR: memory mapping failed \n", __func__);
 +              pr_err("%s: ERROR: memory mapping failed\n", __func__);
                ret = -ENOMEM;
                goto out;
        }
  out:
        if (ret < 0) {
                platform_set_drvdata(pdev, NULL);
 -              release_mem_region(res->start, (res->end - res->start));
 +              release_mem_region(res->start, resource_size(res));
                if (addr != NULL)
                        iounmap(addr);
        }
@@@ -1812,7 -1813,7 +1813,7 @@@ static int stmmac_dvr_remove(struct pla
  
        iounmap((void *)ndev->base_addr);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      release_mem_region(res->start, (res->end - res->start));
 +      release_mem_region(res->start, resource_size(res));
  
        free_netdev(ndev);
  
@@@ -26,6 -26,7 +26,7 @@@
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/skbuff.h>
+ #include <linux/slab.h>
  #include <linux/wireless.h>
  #include <net/mac80211.h>
  
@@@ -345,17 -346,6 +346,17 @@@ static inline int get_num_of_ant_from_r
               !!(rate_n_flags & RATE_MCS_ANT_C_MSK);
  }
  
 +/*
 + * Static function to get the expected throughput from an iwl_scale_tbl_info
 + * that wraps a NULL pointer check
 + */
 +static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
 +{
 +      if (tbl->expected_tpt)
 +              return tbl->expected_tpt[rs_index];
 +      return 0;
 +}
 +
  /**
   * rs_collect_tx_data - Update the success/failure sliding window
   *
   * at this rate.  window->data contains the bitmask of successful
   * packets.
   */
 -static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
 -                            int scale_index, s32 tpt, int attempts,
 -                            int successes)
 +static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
 +                            int scale_index, int attempts, int successes)
  {
        struct iwl_rate_scale_data *window = NULL;
        static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
 -      s32 fail_count;
 +      s32 fail_count, tpt;
  
        if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
                return -EINVAL;
  
        /* Select window for current tx bit rate */
 -      window = &(windows[scale_index]);
 +      window = &(tbl->win[scale_index]);
 +
 +      /* Get expected throughput */
 +      tpt = get_expected_tpt(tbl, scale_index);
  
        /*
         * Keep track of only the latest 62 tx frame attempts in this rate's
@@@ -751,6 -739,16 +752,6 @@@ static bool table_type_matches(struct i
        return (a->lq_type == b->lq_type) && (a->ant_type == b->ant_type) &&
                (a->is_SGI == b->is_SGI);
  }
 -/*
 - * Static function to get the expected throughput from an iwl_scale_tbl_info
 - * that wraps a NULL pointer check
 - */
 -static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
 -{
 -      if (tbl->expected_tpt)
 -              return tbl->expected_tpt[rs_index];
 -      return 0;
 -}
  
  /*
   * mac80211 sends us Tx status
@@@ -767,10 -765,12 +768,10 @@@ static void rs_tx_status(void *priv_r, 
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl_priv *priv = (struct iwl_priv *)priv_r;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 -      struct iwl_rate_scale_data *window = NULL;
        enum mac80211_rate_control_flags mac_flags;
        u32 tx_rate;
        struct iwl_scale_tbl_info tbl_type;
 -      struct iwl_scale_tbl_info *curr_tbl, *other_tbl;
 -      s32 tpt = 0;
 +      struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
  
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
  
                IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n");
                return;
        }
 -      window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
  
        /*
         * Updating the frame history depends on whether packets were
                tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
                rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type,
                                &rs_index);
 -              tpt = get_expected_tpt(curr_tbl, rs_index);
 -              rs_collect_tx_data(window, rs_index, tpt,
 +              rs_collect_tx_data(curr_tbl, rs_index,
                                   info->status.ampdu_ack_len,
                                   info->status.ampdu_ack_map);
  
                         * table as active/search.
                         */
                        if (table_type_matches(&tbl_type, curr_tbl))
 -                              tpt = get_expected_tpt(curr_tbl, rs_index);
 +                              tmp_tbl = curr_tbl;
                        else if (table_type_matches(&tbl_type, other_tbl))
 -                              tpt = get_expected_tpt(other_tbl, rs_index);
 +                              tmp_tbl = other_tbl;
                        else
                                continue;
 -
 -                      /* Constants mean 1 transmission, 0 successes */
 -                      if (i < retries)
 -                              rs_collect_tx_data(window, rs_index, tpt, 1,
 -                                              0);
 -                      else
 -                              rs_collect_tx_data(window, rs_index, tpt, 1,
 -                                              legacy_success);
 +                      rs_collect_tx_data(tmp_tbl, rs_index, 1,
 +                                         i < retries ? 0 : legacy_success);
                }
  
                /* Update success/fail counts if not searching for new mode */
@@@ -30,6 -30,7 +30,7 @@@
  #include <linux/module.h>
  #include <linux/etherdevice.h>
  #include <linux/sched.h>
+ #include <linux/slab.h>
  #include <net/mac80211.h>
  
  #include "iwl-eeprom.h"
@@@ -307,13 -308,10 +308,13 @@@ int iwl_hw_nic_init(struct iwl_priv *pr
  
        spin_unlock_irqrestore(&priv->lock, flags);
  
 -      /* Allocate and init all Tx and Command queues */
 -      ret = iwl_txq_ctx_reset(priv);
 -      if (ret)
 -              return ret;
 +      /* Allocate or reset and init all Tx and Command queues */
 +      if (!priv->txq) {
 +              ret = iwl_txq_ctx_alloc(priv);
 +              if (ret)
 +                      return ret;
 +      } else
 +              iwl_txq_ctx_reset(priv);
  
        set_bit(STATUS_INIT, &priv->status);
  
@@@ -29,6 -29,7 +29,7 @@@
  
  #include <linux/etherdevice.h>
  #include <linux/sched.h>
+ #include <linux/slab.h>
  #include <net/mac80211.h>
  #include "iwl-eeprom.h"
  #include "iwl-dev.h"
@@@ -193,34 -194,10 +194,34 @@@ void iwl_cmd_queue_free(struct iwl_pri
        struct iwl_queue *q = &txq->q;
        struct device *dev = &priv->pci_dev->dev;
        int i;
 +      bool huge = false;
  
        if (q->n_bd == 0)
                return;
  
 +      for (; q->read_ptr != q->write_ptr;
 +           q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
 +              /* we have no way to tell if it is a huge cmd ATM */
 +              i = get_cmd_index(q, q->read_ptr, 0);
 +
 +              if (txq->meta[i].flags & CMD_SIZE_HUGE) {
 +                      huge = true;
 +                      continue;
 +              }
 +
 +              pci_unmap_single(priv->pci_dev,
 +                               pci_unmap_addr(&txq->meta[i], mapping),
 +                               pci_unmap_len(&txq->meta[i], len),
 +                               PCI_DMA_BIDIRECTIONAL);
 +      }
 +      if (huge) {
 +              i = q->n_window;
 +              pci_unmap_single(priv->pci_dev,
 +                               pci_unmap_addr(&txq->meta[i], mapping),
 +                               pci_unmap_len(&txq->meta[i], len),
 +                               PCI_DMA_BIDIRECTIONAL);
 +      }
 +
        /* De-alloc array of command/tx buffers */
        for (i = 0; i <= TFD_CMD_SLOTS; i++)
                kfree(txq->cmd[i]);
@@@ -433,26 -410,6 +434,26 @@@ out_free_arrays
  }
  EXPORT_SYMBOL(iwl_tx_queue_init);
  
 +void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 +                      int slots_num, u32 txq_id)
 +{
 +      int actual_slots = slots_num;
 +
 +      if (txq_id == IWL_CMD_QUEUE_NUM)
 +              actual_slots++;
 +
 +      memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
 +
 +      txq->need_update = 0;
 +
 +      /* Initialize queue's high/low-water marks, and head/tail indexes */
 +      iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
 +
 +      /* Tell device where to find queue */
 +      priv->cfg->ops->lib->txq_init(priv, txq);
 +}
 +EXPORT_SYMBOL(iwl_tx_queue_reset);
 +
  /**
   * iwl_hw_txq_ctx_free - Free TXQ Context
   *
@@@ -464,7 -421,8 +465,7 @@@ void iwl_hw_txq_ctx_free(struct iwl_pri
  
        /* Tx queues */
        if (priv->txq) {
 -              for (txq_id = 0; txq_id < priv->hw_params.max_txq_num;
 -                   txq_id++)
 +              for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
                        if (txq_id == IWL_CMD_QUEUE_NUM)
                                iwl_cmd_queue_free(priv);
                        else
  EXPORT_SYMBOL(iwl_hw_txq_ctx_free);
  
  /**
 - * iwl_txq_ctx_reset - Reset TX queue context
 - * Destroys all DMA structures and initialize them again
 + * iwl_txq_ctx_alloc - allocate TX queue context
 + * Allocate all Tx DMA structures and initialize them
   *
   * @param priv
   * @return error code
   */
 -int iwl_txq_ctx_reset(struct iwl_priv *priv)
 +int iwl_txq_ctx_alloc(struct iwl_priv *priv)
  {
 -      int ret = 0;
 +      int ret;
        int txq_id, slots_num;
        unsigned long flags;
  
        return ret;
  }
  
 +void iwl_txq_ctx_reset(struct iwl_priv *priv)
 +{
 +      int txq_id, slots_num;
 +      unsigned long flags;
 +
 +      spin_lock_irqsave(&priv->lock, flags);
 +
 +      /* Turn off all Tx DMA fifos */
 +      priv->cfg->ops->lib->txq_set_sched(priv, 0);
 +
 +      /* Tell NIC where to find the "keep warm" buffer */
 +      iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
 +
 +      spin_unlock_irqrestore(&priv->lock, flags);
 +
 +      /* Alloc and init all Tx queues, including the command queue (#4) */
 +      for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
 +              slots_num = txq_id == IWL_CMD_QUEUE_NUM ?
 +                          TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
 +              iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
 +      }
 +}
 +
  /**
 - * iwl_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory
 + * iwl_txq_ctx_stop - Stop all Tx DMA channels
   */
  void iwl_txq_ctx_stop(struct iwl_priv *priv)
  {
                                    1000);
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 -
 -      /* Deallocate memory for all Tx queues */
 -      iwl_hw_txq_ctx_free(priv);
  }
  EXPORT_SYMBOL(iwl_txq_ctx_stop);
  
@@@ -1112,14 -1050,6 +1113,14 @@@ int iwl_enqueue_hcmd(struct iwl_priv *p
  
        spin_lock_irqsave(&priv->hcmd_lock, flags);
  
 +      /* If this is a huge cmd, mark the huge flag also on the meta.flags
 +       * of the _original_ cmd. This is used for DMA mapping clean up.
 +       */
 +      if (cmd->flags & CMD_SIZE_HUGE) {
 +              idx = get_cmd_index(q, q->write_ptr, 0);
 +              txq->meta[idx].flags = CMD_SIZE_HUGE;
 +      }
 +
        idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
        out_cmd = txq->cmd[idx];
        out_meta = &txq->meta[idx];
@@@ -1297,7 -1227,6 +1298,7 @@@ void iwl_tx_cmd_complete(struct iwl_pri
        bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
        struct iwl_device_cmd *cmd;
        struct iwl_cmd_meta *meta;
 +      struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
  
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
                return;
        }
  
 -      cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
 -      cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
 -      meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
 +      /* If this is a huge cmd, clear the huge flag on the meta.flags
 +       * of the _original_ cmd. So that iwl_cmd_queue_free won't unmap
 +       * the DMA buffer for the scan (huge) command.
 +       */
 +      if (huge) {
 +              cmd_index = get_cmd_index(&txq->q, index, 0);
 +              txq->meta[cmd_index].flags = 0;
 +      }
 +      cmd_index = get_cmd_index(&txq->q, index, huge);
 +      cmd = txq->cmd[cmd_index];
 +      meta = &txq->meta[cmd_index];
  
        pci_unmap_single(priv->pci_dev,
                         pci_unmap_addr(meta, mapping),
                               get_cmd_string(cmd->hdr.cmd));
                wake_up_interruptible(&priv->wait_command_queue);
        }
 +      meta->flags = 0;
  }
  EXPORT_SYMBOL(iwl_tx_cmd_complete);
  
diff --combined drivers/vhost/vhost.c
@@@ -22,6 -22,7 +22,7 @@@
  #include <linux/poll.h>
  #include <linux/file.h>
  #include <linux/highmem.h>
+ #include <linux/slab.h>
  
  #include <linux/net.h>
  #include <linux/if_packet.h>
@@@ -235,10 -236,6 +236,10 @@@ static int vq_memory_access_ok(void __u
                               int log_all)
  {
        int i;
 +
 +        if (!mem)
 +                return 0;
 +
        for (i = 0; i < mem->nregions; ++i) {
                struct vhost_memory_region *m = mem->regions + i;
                unsigned long a = m->userspace_addr;
diff --combined include/net/x25.h
@@@ -10,6 -10,7 +10,7 @@@
  #ifndef _X25_H
  #define _X25_H 
  #include <linux/x25.h>
+ #include <linux/slab.h>
  #include <net/sock.h>
  
  #define       X25_ADDR_LEN                    16
@@@ -182,10 -183,6 +183,10 @@@ extern int  sysctl_x25_clear_request_ti
  extern int  sysctl_x25_ack_holdback_timeout;
  extern int  sysctl_x25_forward;
  
 +extern int x25_parse_address_block(struct sk_buff *skb,
 +              struct x25_address *called_addr,
 +              struct x25_address *calling_addr);
 +
  extern int  x25_addr_ntoa(unsigned char *, struct x25_address *,
                          struct x25_address *);
  extern int  x25_addr_aton(unsigned char *, struct x25_address *,
diff --combined net/ipv4/udp.c
@@@ -95,6 -95,7 +95,7 @@@
  #include <linux/mm.h>
  #include <linux/inet.h>
  #include <linux/netdevice.h>
+ #include <linux/slab.h>
  #include <net/tcp_states.h>
  #include <linux/skbuff.h>
  #include <linux/proc_fs.h>
@@@ -471,8 -472,8 +472,8 @@@ static struct sock *__udp4_lib_lookup(s
                        if (hslot->count < hslot2->count)
                                goto begin;
  
 -                      result = udp4_lib_lookup2(net, INADDR_ANY, sport,
 -                                                daddr, hnum, dif,
 +                      result = udp4_lib_lookup2(net, saddr, sport,
 +                                                INADDR_ANY, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
diff --combined net/ipv6/udp.c
@@@ -34,6 -34,7 +34,7 @@@
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/skbuff.h>
+ #include <linux/slab.h>
  #include <asm/uaccess.h>
  
  #include <net/ndisc.h>
@@@ -258,8 -259,8 +259,8 @@@ static struct sock *__udp6_lib_lookup(s
                        if (hslot->count < hslot2->count)
                                goto begin;
  
 -                      result = udp6_lib_lookup2(net, &in6addr_any, sport,
 -                                                daddr, hnum, dif,
 +                      result = udp6_lib_lookup2(net, saddr, sport,
 +                                                &in6addr_any, hnum, dif,
                                                  hslot2, slot2);
                }
                rcu_read_unlock();
diff --combined net/mac80211/mesh.c
@@@ -8,6 -8,7 +8,7 @@@
   * published by the Free Software Foundation.
   */
  
+ #include <linux/slab.h>
  #include <asm/unaligned.h>
  #include "ieee80211_i.h"
  #include "mesh.h"
@@@ -749,6 -750,9 +750,6 @@@ ieee80211_mesh_rx_mgmt(struct ieee80211
  
        switch (fc & IEEE80211_FCTL_STYPE) {
        case IEEE80211_STYPE_ACTION:
 -              if (skb->len < IEEE80211_MIN_ACTION_SIZE)
 -                      return RX_DROP_MONITOR;
 -              /* fall through */
        case IEEE80211_STYPE_PROBE_RESP:
        case IEEE80211_STYPE_BEACON:
                skb_queue_tail(&ifmsh->skb_queue, skb);
diff --combined net/mac80211/rx.c
@@@ -10,6 -10,7 +10,7 @@@
   */
  
  #include <linux/jiffies.h>
+ #include <linux/slab.h>
  #include <linux/kernel.h>
  #include <linux/skbuff.h>
  #include <linux/netdevice.h>
@@@ -1973,11 -1974,6 +1974,11 @@@ ieee80211_rx_h_action(struct ieee80211_
                        goto handled;
                }
                break;
 +      case MESH_PLINK_CATEGORY:
 +      case MESH_PATH_SEL_CATEGORY:
 +              if (ieee80211_vif_is_mesh(&sdata->vif))
 +                      return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
 +              break;
        }
  
        /*
diff --combined net/x25/af_x25.c
@@@ -47,6 -47,7 +47,7 @@@
  #include <linux/netdevice.h>
  #include <linux/if_arp.h>
  #include <linux/skbuff.h>
+ #include <linux/slab.h>
  #include <net/sock.h>
  #include <net/tcp_states.h>
  #include <asm/uaccess.h>
@@@ -82,41 -83,6 +83,41 @@@ struct compat_x25_subscrip_struct 
  };
  #endif
  
 +
 +int x25_parse_address_block(struct sk_buff *skb,
 +              struct x25_address *called_addr,
 +              struct x25_address *calling_addr)
 +{
 +      unsigned char len;
 +      int needed;
 +      int rc;
 +
 +      if (skb->len < 1) {
 +              /* packet has no address block */
 +              rc = 0;
 +              goto empty;
 +      }
 +
 +      len = *skb->data;
 +      needed = 1 + (len >> 4) + (len & 0x0f);
 +
 +      if (skb->len < needed) {
 +              /* packet is too short to hold the addresses it claims
 +                 to hold */
 +              rc = -1;
 +              goto empty;
 +      }
 +
 +      return x25_addr_ntoa(skb->data, called_addr, calling_addr);
 +
 +empty:
 +      *called_addr->x25_addr = 0;
 +      *calling_addr->x25_addr = 0;
 +
 +      return rc;
 +}
 +
 +
  int x25_addr_ntoa(unsigned char *p, struct x25_address *called_addr,
                  struct x25_address *calling_addr)
  {
@@@ -588,8 -554,7 +589,8 @@@ static int x25_create(struct net *net, 
        x25->facilities.winsize_out = X25_DEFAULT_WINDOW_SIZE;
        x25->facilities.pacsize_in  = X25_DEFAULT_PACKET_SIZE;
        x25->facilities.pacsize_out = X25_DEFAULT_PACKET_SIZE;
 -      x25->facilities.throughput  = X25_DEFAULT_THROUGHPUT;
 +      x25->facilities.throughput  = 0;        /* by default don't negotiate
 +                                                 throughput */
        x25->facilities.reverse     = X25_DEFAULT_REVERSE;
        x25->dte_facilities.calling_len = 0;
        x25->dte_facilities.called_len = 0;
@@@ -957,26 -922,16 +958,26 @@@ int x25_rx_call_request(struct sk_buff 
        /*
         *      Extract the X.25 addresses and convert them to ASCII strings,
         *      and remove them.
 +       *
 +       *      Address block is mandatory in call request packets
         */
 -      addr_len = x25_addr_ntoa(skb->data, &source_addr, &dest_addr);
 +      addr_len = x25_parse_address_block(skb, &source_addr, &dest_addr);
 +      if (addr_len <= 0)
 +              goto out_clear_request;
        skb_pull(skb, addr_len);
  
        /*
         *      Get the length of the facilities, skip past them for the moment
         *      get the call user data because this is needed to determine
         *      the correct listener
 +       *
 +       *      Facilities length is mandatory in call request packets
         */
 +      if (skb->len < 1)
 +              goto out_clear_request;
        len = skb->data[0] + 1;
 +      if (skb->len < len)
 +              goto out_clear_request;
        skb_pull(skb,len);
  
        /*
@@@ -1460,20 -1415,9 +1461,20 @@@ static int x25_ioctl(struct socket *soc
                        if (facilities.winsize_in < 1 ||
                            facilities.winsize_in > 127)
                                break;
 -                      if (facilities.throughput < 0x03 ||
 -                          facilities.throughput > 0xDD)
 -                              break;
 +                      if (facilities.throughput) {
 +                              int out = facilities.throughput & 0xf0;
 +                              int in  = facilities.throughput & 0x0f;
 +                              if (!out)
 +                                      facilities.throughput |=
 +                                              X25_DEFAULT_THROUGHPUT << 4;
 +                              else if (out < 0x30 || out > 0xD0)
 +                                      break;
 +                              if (!in)
 +                                      facilities.throughput |=
 +                                              X25_DEFAULT_THROUGHPUT;
 +                              else if (in < 0x03 || in > 0x0D)
 +                                      break;
 +                      }
                        if (facilities.reverse &&
                                (facilities.reverse & 0x81) != 0x81)
                                break;
diff --combined net/x25/x25_in.c
@@@ -23,6 -23,7 +23,7 @@@
   *                                      i-frames.
   */
  
+ #include <linux/slab.h>
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/string.h>
@@@ -89,7 -90,6 +90,7 @@@ static int x25_queue_rx_frame(struct so
  static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
  {
        struct x25_address source_addr, dest_addr;
 +      int len;
  
        switch (frametype) {
                case X25_CALL_ACCEPTED: {
                         *      Parse the data in the frame.
                         */
                        skb_pull(skb, X25_STD_MIN_LEN);
 -                      skb_pull(skb, x25_addr_ntoa(skb->data, &source_addr, &dest_addr));
 -                      skb_pull(skb,
 -                               x25_parse_facilities(skb, &x25->facilities,
 +
 +                      len = x25_parse_address_block(skb, &source_addr,
 +                                              &dest_addr);
 +                      if (len > 0)
 +                              skb_pull(skb, len);
 +
 +                      len = x25_parse_facilities(skb, &x25->facilities,
                                                &x25->dte_facilities,
 -                                              &x25->vc_facil_mask));
 +                                              &x25->vc_facil_mask);
 +                      if (len > 0)
 +                              skb_pull(skb, len);
                        /*
                         *      Copy any Call User Data.
                         */