Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Fri, 26 Feb 2010 07:22:42 +0000 (23:22 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Feb 2010 07:22:42 +0000 (23:22 -0800)
13 files changed:
1  2 
Documentation/networking/ip-sysctl.txt
MAINTAINERS
drivers/net/e1000/e1000_main.c
drivers/net/sfc/mcdi.c
drivers/net/tc35815.c
drivers/net/usb/cdc_ether.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-tx.c
net/ipv4/devinet.c
net/ipv6/addrconf.c

index 2571a62d923e2bc630727d2695523caa41985ace,e87f3cdc8a6afc42c36f9469e7afac9b1ec74b82..8b72c88ba21391329300f0a1c25440b8520b28c1
@@@ -487,30 -487,6 +487,30 @@@ tcp_dma_copybreak - INTEGE
        and CONFIG_NET_DMA is enabled.
        Default: 4096
  
 +tcp_thin_linear_timeouts - BOOLEAN
 +      Enable dynamic triggering of linear timeouts for thin streams.
 +      If set, a check is performed upon retransmission by timeout to
 +      determine if the stream is thin (less than 4 packets in flight).
 +      As long as the stream is found to be thin, up to 6 linear
 +      timeouts may be performed before exponential backoff mode is
 +      initiated. This improves retransmission latency for
 +      non-aggressive thin streams, often found to be time-dependent.
 +      For more information on thin streams, see
 +      Documentation/networking/tcp-thin.txt
 +      Default: 0
 +
 +tcp_thin_dupack - BOOLEAN
 +      Enable dynamic triggering of retransmissions after one dupACK
 +      for thin streams. If set, a check is performed upon reception
 +      of a dupACK to determine if the stream is thin (less than 4
 +      packets in flight). As long as the stream is found to be thin,
 +      data is retransmitted on the first received dupACK. This
 +      improves retransmission latency for non-aggressive thin
 +      streams, often found to be time-dependent.
 +      For more information on thin streams, see
 +      Documentation/networking/tcp-thin.txt
 +      Default: 0
 +
  UDP variables:
  
  udp_mem - vector of 3 INTEGERs: min, pressure, max
@@@ -716,25 -692,6 +716,25 @@@ proxy_arp - BOOLEA
        conf/{all,interface}/proxy_arp is set to TRUE,
        it will be disabled otherwise
  
 +proxy_arp_pvlan - BOOLEAN
 +      Private VLAN proxy arp.
 +      Basically allow proxy arp replies back to the same interface
 +      (from which the ARP request/solicitation was received).
 +
 +      This is done to support (ethernet) switch features, like RFC
 +      3069, where the individual ports are NOT allowed to
 +      communicate with each other, but they are allowed to talk to
 +      the upstream router.  As described in RFC 3069, it is possible
 +      to allow these hosts to communicate through the upstream
 +      router by proxy_arp'ing. Don't need to be used together with
 +      proxy_arp.
 +
 +      This technology is known by different names:
 +        In RFC 3069 it is called VLAN Aggregation.
 +        Cisco and Allied Telesyn call it Private VLAN.
 +        Hewlett-Packard call it Source-Port filtering or port-isolation.
 +        Ericsson call it MAC-Forced Forwarding (RFC Draft).
 +
  shared_media - BOOLEAN
        Send(router) or accept(host) RFC1620 shared media redirects.
        Overrides ip_secure_redirects.
@@@ -876,18 -833,9 +876,18 @@@ arp_notify - BOOLEA
            or hardware address changes.
  
  arp_accept - BOOLEAN
 -      Define behavior when gratuitous arp replies are received:
 -      0 - drop gratuitous arp frames
 -      1 - accept gratuitous arp frames
 +      Define behavior for gratuitous ARP frames who's IP is not
 +      already present in the ARP table:
 +      0 - don't create new entries in the ARP table
 +      1 - create new entries in the ARP table
 +
 +      Both replies and requests type gratuitous arp will trigger the
 +      ARP table to be updated, if this setting is on.
 +
 +      If the ARP table already contains the IP address of the
 +      gratuitous arp frame, the arp table will be updated regardless
 +      if this setting is on or off.
 +
  
  app_solicit - INTEGER
        The maximum number of probes to send to the user space ARP daemon
@@@ -1126,10 -1074,10 +1126,10 @@@ regen_max_retry - INTEGE
        Default: 5
  
  max_addresses - INTEGER
-       Number of maximum addresses per interface.  0 disables limitation.
-       It is recommended not set too large value (or 0) because it would
-       be too easy way to crash kernel to allow to create too much of
-       autoconfigured addresses.
+       Maximum number of autoconfigured addresses per interface.  Setting
+       to zero disables the limitation.  It is not recommended to set this
+       value too large (or to zero) because it would be an easy way to
+       crash the kernel by allowing too many addresses to be created.
        Default: 16
  
  disable_ipv6 - BOOLEAN
diff --combined MAINTAINERS
index 9b0557a42a9a49db7467871817fecc540ab21430,318d2e41716846ef74f419c243774781d4fbe23b..2a479c7005b82187437a64b74c75fe16a361f0da
@@@ -1733,9 -1733,10 +1733,9 @@@ F:     include/linux/tfrc.
  F:    net/dccp/
  
  DECnet NETWORK LAYER
 -M:    Christine Caulfield <christine.caulfield@googlemail.com>
  W:    http://linux-decnet.sourceforge.net
  L:    linux-decnet-user@lists.sourceforge.net
 -S:    Maintained
 +S:    Orphan
  F:    Documentation/networking/decnet.txt
  F:    net/decnet/
  
@@@ -2372,12 -2373,6 +2372,12 @@@ F:    Documentation/isdn/README.gigase
  F:    drivers/isdn/gigaset/
  F:    include/linux/gigaset_dev.h
  
 +GRETH 10/100/1G Ethernet MAC device driver
 +M:    Kristoffer Glembo <kristoffer@gaisler.com>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/greth*
 +
  HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
  M:    Frank Seidel <frank@f-seidel.de>
  L:    lm-sensors@lm-sensors.org
@@@ -3495,9 -3490,9 +3495,9 @@@ S:      Maintaine
  F:    drivers/net/wireless/libertas/
  
  MARVELL MV643XX ETHERNET DRIVER
- M:    Lennert Buytenhek <buytenh@marvell.com>
+ M:    Lennert Buytenhek <buytenh@wantstofly.org>
  L:    netdev@vger.kernel.org
- S:    Supported
+ S:    Maintained
  F:    drivers/net/mv643xx_eth.*
  F:    include/linux/mv643xx.h
  
@@@ -4451,13 -4446,6 +4451,13 @@@ S:    Supporte
  F:    Documentation/networking/LICENSE.qla3xxx
  F:    drivers/net/qla3xxx.*
  
 +QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
 +M:    Amit Kumar Salecha <amit.salecha@qlogic.com>
 +M:    linux-driver@qlogic.com
 +L:    netdev@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/qlcnic/
 +
  QLOGIC QLGE 10Gb ETHERNET DRIVER
  M:    Ron Mercer <ron.mercer@qlogic.com>
  M:    linux-driver@qlogic.com
@@@ -4844,8 -4832,6 +4844,8 @@@ F:      drivers/scsi/be2iscsi
  SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
  M:    Sathya Perla <sathyap@serverengines.com>
  M:    Subbu Seetharaman <subbus@serverengines.com>
 +M:    Sarveshwar Bandi <sarveshwarb@serverengines.com>
 +M:    Ajit Khaparde <ajitk@serverengines.com>
  L:    netdev@vger.kernel.org
  W:    http://www.serverengines.com
  S:    Supported
@@@ -5811,15 -5797,6 +5811,15 @@@ S:    Maintaine
  F:    Documentation/filesystems/vfat.txt
  F:    fs/fat/
  
 +VIRTIO HOST (VHOST)
 +M:    "Michael S. Tsirkin" <mst@redhat.com>
 +L:    kvm@vger.kernel.org
 +L:    virtualization@lists.osdl.org
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/vhost/
 +F:    include/linux/vhost.h
 +
  VIA RHINE NETWORK DRIVER
  M:    Roger Luethi <rl@hellgate.ch>
  S:    Maintained
index 319c2b5281e9b5a292efce75dee6d50da270103c,765543663a4f29ada5fef9fe31032a476d306dda..8be6faee43e6e519519d015dd6c1d63a864d7b05
@@@ -42,7 -42,7 +42,7 @@@ static const char e1000_copyright[] = "
   * Macro expands to...
   *   {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
   */
 -static struct pci_device_id e1000_pci_tbl[] = {
 +static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
        INTEL_E1000_ETHERNET_DEVICE(0x1000),
        INTEL_E1000_ETHERNET_DEVICE(0x1001),
        INTEL_E1000_ETHERNET_DEVICE(0x1004),
@@@ -847,9 -847,6 +847,9 @@@ static int __devinit e1000_probe(struc
                goto err_pci_reg;
  
        pci_set_master(pdev);
 +      err = pci_save_state(pdev);
 +      if (err)
 +              goto err_alloc_etherdev;
  
        err = -ENOMEM;
        netdev = alloc_etherdev(sizeof(struct e1000_adapter));
@@@ -2130,7 -2127,7 +2130,7 @@@ static void e1000_set_rx_mode(struct ne
                        rctl |= E1000_RCTL_VFE;
        }
  
 -      if (netdev->uc.count > rar_entries - 1) {
 +      if (netdev_uc_count(netdev) > rar_entries - 1) {
                rctl |= E1000_RCTL_UPE;
        } else if (!(netdev->flags & IFF_PROMISC)) {
                rctl &= ~E1000_RCTL_UPE;
         */
        i = 1;
        if (use_uc)
 -              list_for_each_entry(ha, &netdev->uc.list, list) {
 +              netdev_for_each_uc_addr(ha, netdev) {
                        if (i == rar_entries)
                                break;
                        e1000_rar_set(hw, ha->addr, i++);
  
        WARN_ON(i == rar_entries);
  
 -      mc_ptr = netdev->mc_list;
 -
 -      for (; i < rar_entries; i++) {
 -              if (mc_ptr) {
 -                      e1000_rar_set(hw, mc_ptr->da_addr, i);
 -                      mc_ptr = mc_ptr->next;
 +      netdev_for_each_mc_addr(mc_ptr, netdev) {
 +              if (i == rar_entries) {
 +                      /* load any remaining addresses into the hash table */
 +                      u32 hash_reg, hash_bit, mta;
 +                      hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
 +                      hash_reg = (hash_value >> 5) & 0x7F;
 +                      hash_bit = hash_value & 0x1F;
 +                      mta = (1 << hash_bit);
 +                      mcarray[hash_reg] |= mta;
                } else {
 -                      E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
 -                      E1000_WRITE_FLUSH();
 -                      E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
 -                      E1000_WRITE_FLUSH();
 +                      e1000_rar_set(hw, mc_ptr->da_addr, i++);
                }
        }
  
 -      /* load any remaining addresses into the hash table */
 -
 -      for (; mc_ptr; mc_ptr = mc_ptr->next) {
 -              u32 hash_reg, hash_bit, mta;
 -              hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
 -              hash_reg = (hash_value >> 5) & 0x7F;
 -              hash_bit = hash_value & 0x1F;
 -              mta = (1 << hash_bit);
 -              mcarray[hash_reg] |= mta;
 +      for (; i < rar_entries; i++) {
 +              E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
 +              E1000_WRITE_FLUSH();
 +              E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
 +              E1000_WRITE_FLUSH();
        }
  
        /* write the hash table completely, write from bottom to avoid
@@@ -2245,7 -2246,7 +2245,7 @@@ static void e1000_82547_tx_fifo_stall(u
        }
  }
  
 -static bool e1000_has_link(struct e1000_adapter *adapter)
 +bool e1000_has_link(struct e1000_adapter *adapter)
  {
        struct e1000_hw *hw = &adapter->hw;
        bool link_active = false;
@@@ -4005,11 -4006,21 +4005,21 @@@ check_page
                        }
                }
  
-               if (!buffer_info->dma)
+               if (!buffer_info->dma) {
                        buffer_info->dma = pci_map_page(pdev,
                                                        buffer_info->page, 0,
                                                        buffer_info->length,
                                                        PCI_DMA_FROMDEVICE);
+                       if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+                               put_page(buffer_info->page);
+                               dev_kfree_skb(skb);
+                               buffer_info->page = NULL;
+                               buffer_info->skb = NULL;
+                               buffer_info->dma = 0;
+                               adapter->alloc_rx_buff_failed++;
+                               break; /* while !buffer_info->skb */
+                       }
+               }
  
                rx_desc = E1000_RX_DESC(*rx_ring, i);
                rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@@ -4100,6 -4111,13 +4110,13 @@@ map_skb
                                                  skb->data,
                                                  buffer_info->length,
                                                  PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+                       dev_kfree_skb(skb);
+                       buffer_info->skb = NULL;
+                       buffer_info->dma = 0;
+                       adapter->alloc_rx_buff_failed++;
+                       break; /* while !buffer_info->skb */
+               }
  
                /*
                 * XXX if it was allocated cleanly it will never map to a
@@@ -4595,7 -4613,6 +4612,7 @@@ static int e1000_resume(struct pci_dev 
  
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
 +      pci_save_state(pdev);
  
        if (adapter->need_ioport)
                err = pci_enable_device(pdev);
diff --combined drivers/net/sfc/mcdi.c
index 86610db2cff53768eaa6791c602cc592af158112,f66b3da6ddffbecc236a7d2e6a83506bb0b71a34..c48669c774141965c2f12cbe2f1d9749e5642ea9
@@@ -127,7 -127,7 +127,7 @@@ static int efx_mcdi_poll(struct efx_ni
        efx_dword_t reg;
  
        /* Check for a reboot atomically with respect to efx_mcdi_copyout() */
-       rc = efx_mcdi_poll_reboot(efx);
+       rc = -efx_mcdi_poll_reboot(efx);
        if (rc)
                goto out;
  
@@@ -896,73 -896,29 +896,73 @@@ fail
        return rc;
  }
  
 -int efx_mcdi_handle_assertion(struct efx_nic *efx)
 +static int efx_mcdi_nvram_test(struct efx_nic *efx, unsigned int type)
  {
 -      union {
 -              u8 asserts[MC_CMD_GET_ASSERTS_IN_LEN];
 -              u8 reboot[MC_CMD_REBOOT_IN_LEN];
 -      } inbuf;
 -      u8 assertion[MC_CMD_GET_ASSERTS_OUT_LEN];
 +      u8 inbuf[MC_CMD_NVRAM_TEST_IN_LEN];
 +      u8 outbuf[MC_CMD_NVRAM_TEST_OUT_LEN];
 +      int rc;
 +
 +      MCDI_SET_DWORD(inbuf, NVRAM_TEST_IN_TYPE, type);
 +
 +      rc = efx_mcdi_rpc(efx, MC_CMD_NVRAM_TEST, inbuf, sizeof(inbuf),
 +                        outbuf, sizeof(outbuf), NULL);
 +      if (rc)
 +              return rc;
 +
 +      switch (MCDI_DWORD(outbuf, NVRAM_TEST_OUT_RESULT)) {
 +      case MC_CMD_NVRAM_TEST_PASS:
 +      case MC_CMD_NVRAM_TEST_NOTSUPP:
 +              return 0;
 +      default:
 +              return -EIO;
 +      }
 +}
 +
 +int efx_mcdi_nvram_test_all(struct efx_nic *efx)
 +{
 +      u32 nvram_types;
 +      unsigned int type;
 +      int rc;
 +
 +      rc = efx_mcdi_nvram_types(efx, &nvram_types);
 +      if (rc)
 +              return rc;
 +
 +      type = 0;
 +      while (nvram_types != 0) {
 +              if (nvram_types & 1) {
 +                      rc = efx_mcdi_nvram_test(efx, type);
 +                      if (rc)
 +                              return rc;
 +              }
 +              type++;
 +              nvram_types >>= 1;
 +      }
 +
 +      return 0;
 +}
 +
 +static int efx_mcdi_read_assertion(struct efx_nic *efx)
 +{
 +      u8 inbuf[MC_CMD_GET_ASSERTS_IN_LEN];
 +      u8 outbuf[MC_CMD_GET_ASSERTS_OUT_LEN];
        unsigned int flags, index, ofst;
        const char *reason;
        size_t outlen;
        int retry;
        int rc;
  
 -      /* Check if the MC is in the assertion handler, retrying twice. Once
 +      /* Attempt to read any stored assertion state before we reboot
 +       * the mcfw out of the assertion handler. Retry twice, once
         * because a boot-time assertion might cause this command to fail
         * with EINTR. And once again because GET_ASSERTS can race with
         * MC_CMD_REBOOT running on the other port. */
        retry = 2;
        do {
 -              MCDI_SET_DWORD(inbuf.asserts, GET_ASSERTS_IN_CLEAR, 0);
 +              MCDI_SET_DWORD(inbuf, GET_ASSERTS_IN_CLEAR, 1);
                rc = efx_mcdi_rpc(efx, MC_CMD_GET_ASSERTS,
 -                                inbuf.asserts, MC_CMD_GET_ASSERTS_IN_LEN,
 -                                assertion, sizeof(assertion), &outlen);
 +                                inbuf, MC_CMD_GET_ASSERTS_IN_LEN,
 +                                outbuf, sizeof(outbuf), &outlen);
        } while ((rc == -EINTR || rc == -EIO) && retry-- > 0);
  
        if (rc)
        if (outlen < MC_CMD_GET_ASSERTS_OUT_LEN)
                return -EINVAL;
  
 -      flags = MCDI_DWORD(assertion, GET_ASSERTS_OUT_GLOBAL_FLAGS);
 +      /* Print out any recorded assertion state */
 +      flags = MCDI_DWORD(outbuf, GET_ASSERTS_OUT_GLOBAL_FLAGS);
        if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
                return 0;
  
 -      /* Reset the hardware atomically such that only one port with succeed.
 -       * This command will succeed if a reboot is no longer required (because
 -       * the other port did it first), but fail with EIO if it succeeds.
 -       */
 -      BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
 -      MCDI_SET_DWORD(inbuf.reboot, REBOOT_IN_FLAGS,
 -                     MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
 -      efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf.reboot, MC_CMD_REBOOT_IN_LEN,
 -                   NULL, 0, NULL);
 -
 -      /* Print out the assertion */
        reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
                ? "system-level assertion"
                : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
                ? "watchdog reset"
                : "unknown assertion";
        EFX_ERR(efx, "MCPU %s at PC = 0x%.8x in thread 0x%.8x\n", reason,
 -              MCDI_DWORD(assertion, GET_ASSERTS_OUT_SAVED_PC_OFFS),
 -              MCDI_DWORD(assertion, GET_ASSERTS_OUT_THREAD_OFFS));
 +              MCDI_DWORD(outbuf, GET_ASSERTS_OUT_SAVED_PC_OFFS),
 +              MCDI_DWORD(outbuf, GET_ASSERTS_OUT_THREAD_OFFS));
  
        /* Print out the registers */
        ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
        for (index = 1; index < 32; index++) {
                EFX_ERR(efx, "R%.2d (?): 0x%.8x\n", index,
 -                      MCDI_DWORD2(assertion, ofst));
 +                      MCDI_DWORD2(outbuf, ofst));
                ofst += sizeof(efx_dword_t);
        }
  
        return 0;
  }
  
 +static void efx_mcdi_exit_assertion(struct efx_nic *efx)
 +{
 +      u8 inbuf[MC_CMD_REBOOT_IN_LEN];
 +
 +      /* Atomically reboot the mcfw out of the assertion handler */
 +      BUILD_BUG_ON(MC_CMD_REBOOT_OUT_LEN != 0);
 +      MCDI_SET_DWORD(inbuf, REBOOT_IN_FLAGS,
 +                     MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
 +      efx_mcdi_rpc(efx, MC_CMD_REBOOT, inbuf, MC_CMD_REBOOT_IN_LEN,
 +                   NULL, 0, NULL);
 +}
 +
 +int efx_mcdi_handle_assertion(struct efx_nic *efx)
 +{
 +      int rc;
 +
 +      rc = efx_mcdi_read_assertion(efx);
 +      if (rc)
 +              return rc;
 +
 +      efx_mcdi_exit_assertion(efx);
 +
 +      return 0;
 +}
 +
  void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode)
  {
        u8 inbuf[MC_CMD_SET_ID_LED_IN_LEN];
diff --combined drivers/net/tc35815.c
index d838d4015c63f2e8412aff48c9af13085bdb3b7e,d71c1976072e7bcbda5739748a9d92bf67b44d17..a2c635ecdab857a3b710c1fa9c3d8a9aba99ea5b
@@@ -65,7 -65,7 +65,7 @@@ static const struct 
        { "TOSHIBA TC35815/TX4939" },
  };
  
 -static const struct pci_device_id tc35815_pci_tbl[] = {
 +static DEFINE_PCI_DEVICE_TABLE(tc35815_pci_tbl) = {
        {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815CF), .driver_data = TC35815CF },
        {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_NWU), .driver_data = TC35815_NWU },
        {PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939), .driver_data = TC35815_TX4939 },
@@@ -1437,7 -1437,6 +1437,6 @@@ static int tc35815_do_interrupt(struct 
                /* Transmit complete. */
                lp->lstats.tx_ints++;
                tc35815_txdone(dev);
-               netif_wake_queue(dev);
                if (ret < 0)
                        ret = 0;
        }
@@@ -1941,18 -1940,18 +1940,18 @@@ tc35815_set_multicast_list(struct net_d
                /* Enable promiscuous mode */
                tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc | CAM_StationAcc, &tr->CAM_Ctl);
        } else if ((dev->flags & IFF_ALLMULTI) ||
 -                dev->mc_count > CAM_ENTRY_MAX - 3) {
 +                netdev_mc_count(dev) > CAM_ENTRY_MAX - 3) {
                /* CAM 0, 1, 20 are reserved. */
                /* Disable promiscuous mode, use normal mode. */
                tc_writel(CAM_CompEn | CAM_BroadAcc | CAM_GroupAcc, &tr->CAM_Ctl);
 -      } else if (dev->mc_count) {
 +      } else if (!netdev_mc_empty(dev)) {
                struct dev_mc_list *cur_addr = dev->mc_list;
                int i;
                int ena_bits = CAM_Ena_Bit(CAM_ENTRY_SOURCE);
  
                tc_writel(0, &tr->CAM_Ctl);
                /* Walk the address list, and load the filter */
 -              for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
 +              for (i = 0; i < netdev_mc_count(dev); i++, cur_addr = cur_addr->next) {
                        if (!cur_addr)
                                break;
                        /* entry 0,1 is reserved. */
index 3486e8ca039ad2df60f47eebd411951c3507397f,5f3b9eaeb04fbc76ea1a721931d331ebe6e4ccd1..c8cdb7f30adc05b0bba34d767dc29447c6d613c9
@@@ -339,10 -339,10 +339,10 @@@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind)
  
  static void dumpspeed(struct usbnet *dev, __le32 *speeds)
  {
 -      if (netif_msg_timer(dev))
 -              devinfo(dev, "link speeds: %u kbps up, %u kbps down",
 -                      __le32_to_cpu(speeds[0]) / 1000,
 -              __le32_to_cpu(speeds[1]) / 1000);
 +      netif_info(dev, timer, dev->net,
 +                 "link speeds: %u kbps up, %u kbps down\n",
 +                 __le32_to_cpu(speeds[0]) / 1000,
 +                 __le32_to_cpu(speeds[1]) / 1000);
  }
  
  static void cdc_status(struct usbnet *dev, struct urb *urb)
        event = urb->transfer_buffer;
        switch (event->bNotificationType) {
        case USB_CDC_NOTIFY_NETWORK_CONNECTION:
 -              if (netif_msg_timer(dev))
 -                      devdbg(dev, "CDC: carrier %s",
 -                                      event->wValue ? "on" : "off");
 +              netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
 +                        event->wValue ? "on" : "off");
                if (event->wValue)
                        netif_carrier_on(dev->net);
                else
                        netif_carrier_off(dev->net);
                break;
        case USB_CDC_NOTIFY_SPEED_CHANGE:       /* tx/rx rates */
 -              if (netif_msg_timer(dev))
 -                      devdbg(dev, "CDC: speed change (len %d)",
 -                                      urb->actual_length);
 +              netif_dbg(dev, timer, dev->net, "CDC: speed change (len %d)\n",
 +                        urb->actual_length);
                if (urb->actual_length != (sizeof *event + 8))
                        set_bit(EVENT_STS_SPLIT, &dev->flags);
                else
         * but there are no standard formats for the response data.
         */
        default:
 -              deverr(dev, "CDC: unexpected notification %02x!",
 -                               event->bNotificationType);
 +              netdev_err(dev->net, "CDC: unexpected notification %02x!\n",
 +                         event->bNotificationType);
                break;
        }
  }
@@@ -581,6 -583,11 +581,11 @@@ static const struct usb_device_id        produ
        USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
                        USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
        .driver_info = (unsigned long) &mbm_info,
+ }, {
+       /* Ericsson C3607w ver 2 */
+       USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long) &mbm_info,
  }, {
        /* Toshiba F3507g */
        USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
index aebe8c51d3e18d308e25de8b36ba60d92280009c,31462813bac0c798bf0749fe35d3265edbdf85f1..b07874f7da7ff1876de6affdaf01139151ce5686
@@@ -1,6 -1,6 +1,6 @@@
  /******************************************************************************
   *
 - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of version 2 of the GNU General Public License as
@@@ -2008,7 -2008,7 +2008,7 @@@ static void iwl4965_rx_reply_tx(struct 
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
                                           "%d index %d\n", scd_ssn , index);
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                       priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
  
                        if (priv->mac80211_registered &&
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@@ -2206,10 -2206,9 +2206,10 @@@ static struct iwl_lib_ops iwl4965_lib 
                .temperature = iwl4965_temperature_calib,
                .set_ct_kill = iwl4965_set_ct_threshold,
        },
 +      .add_bcast_station = iwl_add_bcast_station,
  };
  
 -static struct iwl_ops iwl4965_ops = {
 +static const struct iwl_ops iwl4965_ops = {
        .ucode = &iwl4965_ucode,
        .lib = &iwl4965_lib,
        .hcmd = &iwl4965_hcmd,
@@@ -2240,7 -2239,7 +2240,7 @@@ struct iwl_cfg iwl4965_agn_cfg = 
        .broken_powersave = true,
        .led_compensation = 61,
        .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
 -      .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
  };
  
  /* Module firmware */
index f3d662c8cbcf320fb1b1f8d5f0f087f7ad460bb8,cffaae772d513169a356c3aa28e76a692c2b656d..2cf92a51f041d0eeac7b88361707ac7fc5d93c13
@@@ -1,6 -1,6 +1,6 @@@
  /******************************************************************************
   *
 - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of version 2 of the GNU General Public License as
@@@ -179,24 -179,14 +179,24 @@@ static void iwl5000_gain_computation(st
                        data->delta_gain_code[i] = 0;
                        continue;
                }
 -              delta_g = (1000 * ((s32)average_noise[default_chain] -
 +
 +              delta_g = (priv->cfg->chain_noise_scale *
 +                      ((s32)average_noise[default_chain] -
                        (s32)average_noise[i])) / 1500;
 +
                /* bound gain by 2 bits value max, 3rd bit is sign */
                data->delta_gain_code[i] =
                        min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
  
                if (delta_g < 0)
 -                      /* set negative sign */
 +                      /*
 +                       * set negative sign ...
 +                       * note to Intel developers:  This is uCode API format,
 +                       *   not the format of any internal device registers.
 +                       *   Do not change this format for e.g. 6050 or similar
 +                       *   devices.  Change format only if more resolution
 +                       *   (i.e. more than 2 bits magnitude) is needed.
 +                       */
                        data->delta_gain_code[i] |= (1 << 2);
        }
  
@@@ -273,8 -263,8 +273,8 @@@ static struct iwl_sensitivity_ranges iw
  
        .auto_corr_max_ofdm = 120,
        .auto_corr_max_ofdm_mrc = 210,
 -      .auto_corr_max_ofdm_x1 = 155,
 -      .auto_corr_max_ofdm_mrc_x1 = 290,
 +      .auto_corr_max_ofdm_x1 = 120,
 +      .auto_corr_max_ofdm_mrc_x1 = 240,
  
        .auto_corr_min_cck = 125,
        .auto_corr_max_cck = 200,
@@@ -422,14 -412,12 +422,14 @@@ static void iwl5000_rx_calib_complete(s
  /*
   * ucode
   */
 -static int iwl5000_load_section(struct iwl_priv *priv,
 -                              struct fw_desc *image,
 -                              u32 dst_addr)
 +static int iwl5000_load_section(struct iwl_priv *priv, const char *name,
 +                              struct fw_desc *image, u32 dst_addr)
  {
        dma_addr_t phy_addr = image->p_addr;
        u32 byte_cnt = image->len;
 +      int ret;
 +
 +      priv->ucode_write_complete = 0;
  
        iwl_write_direct32(priv,
                FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
  
 -      return 0;
 -}
 -
 -static int iwl5000_load_given_ucode(struct iwl_priv *priv,
 -              struct fw_desc *inst_image,
 -              struct fw_desc *data_image)
 -{
 -      int ret = 0;
 -
 -      ret = iwl5000_load_section(priv, inst_image,
 -                                 IWL50_RTC_INST_LOWER_BOUND);
 -      if (ret)
 -              return ret;
 -
 -      IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n");
 +      IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name);
        ret = wait_event_interruptible_timeout(priv->wait_command_queue,
                                        priv->ucode_write_complete, 5 * HZ);
        if (ret == -ERESTARTSYS) {
 -              IWL_ERR(priv, "Could not load the INST uCode section due "
 -                      "to interrupt\n");
 +              IWL_ERR(priv, "Could not load the %s uCode section due "
 +                      "to interrupt\n", name);
                return ret;
        }
        if (!ret) {
 -              IWL_ERR(priv, "Could not load the INST uCode section\n");
 +              IWL_ERR(priv, "Could not load the %s uCode section\n",
 +                      name);
                return -ETIMEDOUT;
        }
  
 -      priv->ucode_write_complete = 0;
 -
 -      ret = iwl5000_load_section(
 -              priv, data_image, IWL50_RTC_DATA_LOWER_BOUND);
 -      if (ret)
 -              return ret;
 +      return 0;
 +}
  
 -      IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n");
 +static int iwl5000_load_given_ucode(struct iwl_priv *priv,
 +              struct fw_desc *inst_image,
 +              struct fw_desc *data_image)
 +{
 +      int ret = 0;
  
 -      ret = wait_event_interruptible_timeout(priv->wait_command_queue,
 -                              priv->ucode_write_complete, 5 * HZ);
 -      if (ret == -ERESTARTSYS) {
 -              IWL_ERR(priv, "Could not load the INST uCode section due "
 -                      "to interrupt\n");
 +      ret = iwl5000_load_section(priv, "INST", inst_image,
 +                                 IWL50_RTC_INST_LOWER_BOUND);
 +      if (ret)
                return ret;
 -      } else if (!ret) {
 -              IWL_ERR(priv, "Could not load the DATA uCode section\n");
 -              return -ETIMEDOUT;
 -      } else
 -              ret = 0;
 -
 -      priv->ucode_write_complete = 0;
  
 -      return ret;
 +      return iwl5000_load_section(priv, "DATA", data_image,
 +                                  IWL50_RTC_DATA_LOWER_BOUND);
  }
  
  int iwl5000_load_ucode(struct iwl_priv *priv)
@@@ -772,7 -781,7 +772,7 @@@ void iwl5000_txq_update_byte_cnt_tbl(st
  
        scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
  
 -      if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
 +      if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
                scd_bc_tbl[txq_id].
                        tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
  }
@@@ -791,12 -800,12 +791,12 @@@ void iwl5000_txq_inval_byte_cnt_tbl(str
        if (txq_id != IWL_CMD_QUEUE_NUM)
                sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
  
 -      bc_ent =  cpu_to_le16(1 | (sta_id << 12));
 +      bc_ent = cpu_to_le16(1 | (sta_id << 12));
        scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
  
 -      if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP)
 +      if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
                scd_bc_tbl[txq_id].
 -                      tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] =  bc_ent;
 +                      tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
  }
  
  static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
@@@ -1116,7 -1125,7 +1116,7 @@@ static void iwl5000_rx_reply_tx(struct 
                                        scd_ssn , index, txq_id, txq->swq_id);
  
                        freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-                       priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+                       iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
  
                        if (priv->mac80211_registered &&
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
                                   tx_resp->failure_frame);
  
                freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-               if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-                       priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+               iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
  
                if (priv->mac80211_registered &&
                    (iwl_queue_space(&txq->q) > txq->q.low_mark))
                        iwl_wake_queue(priv, txq_id);
        }
  
-       if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-               iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+       iwl_txq_check_empty(priv, sta_id, tid, txq_id);
  
        if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
                IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
@@@ -1457,8 -1464,6 +1455,8 @@@ struct iwl_lib_ops iwl5000_lib = 
        .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
 +      .dump_csr = iwl_dump_csr,
 +      .dump_fh = iwl_dump_fh,
        .load_ucode = iwl5000_load_ucode,
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
                .temperature = iwl5000_temperature,
                .set_ct_kill = iwl5000_set_ct_threshold,
         },
 +      .add_bcast_station = iwl_add_bcast_station,
  };
  
  static struct iwl_lib_ops iwl5150_lib = {
        .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
        .dump_nic_event_log = iwl_dump_nic_event_log,
        .dump_nic_error_log = iwl_dump_nic_error_log,
 +      .dump_csr = iwl_dump_csr,
        .load_ucode = iwl5000_load_ucode,
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
                .temperature = iwl5150_temperature,
                .set_ct_kill = iwl5150_set_ct_threshold,
         },
 +      .add_bcast_station = iwl_add_bcast_station,
  };
  
 -static struct iwl_ops iwl5000_ops = {
 +static const struct iwl_ops iwl5000_ops = {
        .ucode = &iwl5000_ucode,
        .lib = &iwl5000_lib,
        .hcmd = &iwl5000_hcmd,
        .led = &iwlagn_led_ops,
  };
  
 -static struct iwl_ops iwl5150_ops = {
 +static const struct iwl_ops iwl5150_ops = {
        .ucode = &iwl5000_ucode,
        .lib = &iwl5150_lib,
        .hcmd = &iwl5000_hcmd,
@@@ -1596,8 -1598,7 +1594,8 @@@ struct iwl_cfg iwl5300_agn_cfg = 
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 -      .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5100_bgn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5100_abg_cfg = {
        .use_bsm = false,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5100_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 -      .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5350_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 -      .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5150_agn_cfg = {
        .led_compensation = 51,
        .use_rts_for_ht = true, /* use rts/cts protection */
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 -      .sm_ps_mode = WLAN_HT_CAP_SM_PS_DISABLED,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  struct iwl_cfg iwl5150_abg_cfg = {
        .use_bsm = false,
        .led_compensation = 51,
        .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 +      .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 +      .chain_noise_scale = 1000,
  };
  
  MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
index d390eef2efe5996364d8f820ce1b4bdfab33947d,f36f804804fc2d0a54f3a3e260324738e776bbef..728410083cb826229d56850ccee62b6eaa67eab5
@@@ -2,7 -2,7 +2,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -47,26 -47,6 +47,26 @@@ MODULE_VERSION(IWLWIFI_VERSION)
  MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
  MODULE_LICENSE("GPL");
  
 +/*
 + * set bt_coex_active to true, uCode will do kill/defer
 + * every time the priority line is asserted (BT is sending signals on the
 + * priority line in the PCIx).
 + * set bt_coex_active to false, uCode will ignore the BT activity and
 + * perform the normal operation
 + *
 + * User might experience transmit issue on some platform due to WiFi/BT
 + * co-exist problem. The possible behaviors are:
 + *   Able to scan and finding all the available AP
 + *   Not able to associate with any AP
 + * On those platforms, WiFi communication can be restored by set
 + * "bt_coex_active" module parameter to "false"
 + *
 + * default: bt_coex_active = true (BT_COEX_ENABLE)
 + */
 +static bool bt_coex_active = true;
 +module_param(bt_coex_active, bool, S_IRUGO);
 +MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n");
 +
  static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
        {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
         0, COEX_UNASSOC_IDLE_FLAGS},
@@@ -277,8 -257,8 +277,8 @@@ int iwl_hw_nic_init(struct iwl_priv *pr
        spin_lock_irqsave(&priv->lock, flags);
        priv->cfg->ops->lib->apm_ops.init(priv);
  
 -      /* Set interrupt coalescing timer to 512 usecs */
 -      iwl_write8(priv, CSR_INT_COALESCING, 512 / 32);
 +      /* Set interrupt coalescing calibration timer to default (512 usecs) */
 +      iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
  
        spin_unlock_irqrestore(&priv->lock, flags);
  
@@@ -470,6 -450,8 +470,6 @@@ static void iwlcore_init_ht_hw_capab(co
        if (priv->cfg->ht_greenfield_support)
                ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
        ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
 -      ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
 -                           (priv->cfg->sm_ps_mode << 2));
        max_bit_rate = MAX_BIT_RATE_20_MHZ;
        if (priv->hw_params.ht40_channel & BIT(band)) {
                ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@@ -654,7 -636,7 +654,7 @@@ EXPORT_SYMBOL(iwlcore_rts_tx_cmd_flag)
  
  static bool is_single_rx_stream(struct iwl_priv *priv)
  {
 -      return !priv->current_ht_config.is_ht ||
 +      return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
               priv->current_ht_config.single_chain_sufficient;
  }
  
@@@ -1021,18 -1003,28 +1021,18 @@@ static int iwl_get_active_rx_chain_coun
   */
  static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
  {
 -      int idle_cnt = active_cnt;
 -      bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
 -
 -      /* # Rx chains when idling and maybe trying to save power */
 -      switch (priv->cfg->sm_ps_mode) {
 -      case WLAN_HT_CAP_SM_PS_STATIC:
 -              idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
 -              break;
 -      case WLAN_HT_CAP_SM_PS_DYNAMIC:
 -              idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
 -                      IWL_NUM_IDLE_CHAINS_SINGLE;
 -              break;
 -      case WLAN_HT_CAP_SM_PS_DISABLED:
 -              break;
 -      case WLAN_HT_CAP_SM_PS_INVALID:
 +      /* # Rx chains when idling, depending on SMPS mode */
 +      switch (priv->current_ht_config.smps) {
 +      case IEEE80211_SMPS_STATIC:
 +      case IEEE80211_SMPS_DYNAMIC:
 +              return IWL_NUM_IDLE_CHAINS_SINGLE;
 +      case IEEE80211_SMPS_OFF:
 +              return active_cnt;
        default:
 -              IWL_ERR(priv, "invalid sm_ps mode %u\n",
 -                      priv->cfg->sm_ps_mode);
 -              WARN_ON(1);
 -              break;
 +              WARN(1, "invalid SMPS mode %d",
 +                   priv->current_ht_config.smps);
 +              return active_cnt;
        }
 -      return idle_cnt;
  }
  
  /* up to 4 chains */
@@@ -1371,11 -1363,7 +1371,11 @@@ void iwl_irq_handle_error(struct iwl_pr
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
  
        priv->cfg->ops->lib->dump_nic_error_log(priv);
 -      priv->cfg->ops->lib->dump_nic_event_log(priv, false);
 +      if (priv->cfg->ops->lib->dump_csr)
 +              priv->cfg->ops->lib->dump_csr(priv);
 +      if (priv->cfg->ops->lib->dump_fh)
 +              priv->cfg->ops->lib->dump_fh(priv, NULL, false);
 +      priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
  #ifdef CONFIG_IWLWIFI_DEBUG
        if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
                iwl_print_rx_config_cmd(priv);
@@@ -1825,16 -1813,6 +1825,16 @@@ irqreturn_t iwl_isr_ict(int irq, void *
        if (val == 0xffffffff)
                val = 0;
  
 +      /*
 +       * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit
 +       * (bit 15 before shifting it to 31) to clear when using interrupt
 +       * coalescing. fortunately, bits 18 and 19 stay set when this happens
 +       * so we use them to decide on the real state of the Rx bit.
 +       * In order words, bit 15 is set if bit 18 or bit 19 are set.
 +       */
 +      if (val & 0xC0000)
 +              val |= 0x8000;
 +
        inta = (0xff & val) | ((0xff00 & val) << 16);
        IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
                        inta, inta_mask, val);
@@@ -1997,20 -1975,13 +1997,20 @@@ EXPORT_SYMBOL(iwl_isr_legacy)
  int iwl_send_bt_config(struct iwl_priv *priv)
  {
        struct iwl_bt_cmd bt_cmd = {
 -              .flags = BT_COEX_MODE_4W,
                .lead_time = BT_LEAD_TIME_DEF,
                .max_kill = BT_MAX_KILL_DEF,
                .kill_ack_mask = 0,
                .kill_cts_mask = 0,
        };
  
 +      if (!bt_coex_active)
 +              bt_cmd.flags = BT_COEX_DISABLE;
 +      else
 +              bt_cmd.flags = BT_COEX_ENABLE;
 +
 +      IWL_DEBUG_INFO(priv, "BT coex %s\n",
 +              (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active");
 +
        return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
                                sizeof(struct iwl_bt_cmd), &bt_cmd);
  }
@@@ -2628,43 -2599,44 +2628,43 @@@ int iwl_set_mode(struct iwl_priv *priv
  EXPORT_SYMBOL(iwl_set_mode);
  
  int iwl_mac_add_interface(struct ieee80211_hw *hw,
 -                               struct ieee80211_if_init_conf *conf)
 +                               struct ieee80211_vif *vif)
  {
        struct iwl_priv *priv = hw->priv;
 -      unsigned long flags;
 +      int err = 0;
  
 -      IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
 +      IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type);
 +
 +      mutex_lock(&priv->mutex);
  
        if (priv->vif) {
                IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
 -              return -EOPNOTSUPP;
 +              err = -EOPNOTSUPP;
 +              goto out;
        }
  
 -      spin_lock_irqsave(&priv->lock, flags);
 -      priv->vif = conf->vif;
 -      priv->iw_mode = conf->type;
 -
 -      spin_unlock_irqrestore(&priv->lock, flags);
 +      priv->vif = vif;
 +      priv->iw_mode = vif->type;
  
 -      mutex_lock(&priv->mutex);
 -
 -      if (conf->mac_addr) {
 -              IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
 -              memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
 +      if (vif->addr) {
 +              IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr);
 +              memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
        }
  
 -      if (iwl_set_mode(priv, conf->type) == -EAGAIN)
 +      if (iwl_set_mode(priv, vif->type) == -EAGAIN)
                /* we are not ready, will run again when ready */
                set_bit(STATUS_MODE_PENDING, &priv->status);
  
 + out:
        mutex_unlock(&priv->mutex);
  
        IWL_DEBUG_MAC80211(priv, "leave\n");
 -      return 0;
 +      return err;
  }
  EXPORT_SYMBOL(iwl_mac_add_interface);
  
  void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 -                                   struct ieee80211_if_init_conf *conf)
 +                                   struct ieee80211_vif *vif)
  {
        struct iwl_priv *priv = hw->priv;
  
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwlcore_commit_rxon(priv);
        }
 -      if (priv->vif == conf->vif) {
 +      if (priv->vif == vif) {
                priv->vif = NULL;
                memset(priv->bssid, 0, ETH_ALEN);
        }
@@@ -2717,21 -2689,6 +2717,21 @@@ int iwl_mac_config(struct ieee80211_hw 
                IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
        }
  
 +      if (changed & (IEEE80211_CONF_CHANGE_SMPS |
 +                     IEEE80211_CONF_CHANGE_CHANNEL)) {
 +              /* mac80211 uses static for non-HT which is what we want */
 +              priv->current_ht_config.smps = conf->smps_mode;
 +
 +              /*
 +               * Recalculate chain counts.
 +               *
 +               * If monitor mode is enabled then mac80211 will
 +               * set up the SM PS mode to OFF if an HT channel is
 +               * configured.
 +               */
 +              if (priv->cfg->ops->hcmd->set_rxon_chain)
 +                      priv->cfg->ops->hcmd->set_rxon_chain(priv);
 +      }
  
        /* during scanning mac80211 will delay channel setting until
         * scan finish with changed = 0
                if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
                        priv->staging_rxon.flags = 0;
  
-               iwl_set_rxon_ht(priv, ht_conf);
                iwl_set_rxon_channel(priv, conf->channel);
+               iwl_set_rxon_ht(priv, ht_conf);
  
                iwl_set_flags_for_band(priv, conf->channel->band);
                spin_unlock_irqrestore(&priv->lock, flags);
                iwl_set_tx_power(priv, conf->power_level, false);
        }
  
 -      /* call to ensure that 4965 rx_chain is set properly in monitor mode */
 -      if (priv->cfg->ops->hcmd->set_rxon_chain)
 -              priv->cfg->ops->hcmd->set_rxon_chain(priv);
 -
        if (!iwl_is_ready(priv)) {
                IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
                goto out;
@@@ -2851,6 -2812,42 +2851,6 @@@ out
  }
  EXPORT_SYMBOL(iwl_mac_config);
  
 -int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
 -                       struct ieee80211_tx_queue_stats *stats)
 -{
 -      struct iwl_priv *priv = hw->priv;
 -      int i, avail;
 -      struct iwl_tx_queue *txq;
 -      struct iwl_queue *q;
 -      unsigned long flags;
 -
 -      IWL_DEBUG_MAC80211(priv, "enter\n");
 -
 -      if (!iwl_is_ready_rf(priv)) {
 -              IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
 -              return -EIO;
 -      }
 -
 -      spin_lock_irqsave(&priv->lock, flags);
 -
 -      for (i = 0; i < AC_NUM; i++) {
 -              txq = &priv->txq[i];
 -              q = &txq->q;
 -              avail = iwl_queue_space(q);
 -
 -              stats[i].len = q->n_window - avail;
 -              stats[i].limit = q->n_window - q->high_mark;
 -              stats[i].count = q->n_window;
 -
 -      }
 -      spin_unlock_irqrestore(&priv->lock, flags);
 -
 -      IWL_DEBUG_MAC80211(priv, "leave\n");
 -
 -      return 0;
 -}
 -EXPORT_SYMBOL(iwl_mac_get_tx_stats);
 -
  void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
  {
        struct iwl_priv *priv = hw->priv;
@@@ -3200,164 -3197,6 +3200,164 @@@ void iwl_update_stats(struct iwl_priv *
  EXPORT_SYMBOL(iwl_update_stats);
  #endif
  
 +const static char *get_csr_string(int cmd)
 +{
 +      switch (cmd) {
 +              IWL_CMD(CSR_HW_IF_CONFIG_REG);
 +              IWL_CMD(CSR_INT_COALESCING);
 +              IWL_CMD(CSR_INT);
 +              IWL_CMD(CSR_INT_MASK);
 +              IWL_CMD(CSR_FH_INT_STATUS);
 +              IWL_CMD(CSR_GPIO_IN);
 +              IWL_CMD(CSR_RESET);
 +              IWL_CMD(CSR_GP_CNTRL);
 +              IWL_CMD(CSR_HW_REV);
 +              IWL_CMD(CSR_EEPROM_REG);
 +              IWL_CMD(CSR_EEPROM_GP);
 +              IWL_CMD(CSR_OTP_GP_REG);
 +              IWL_CMD(CSR_GIO_REG);
 +              IWL_CMD(CSR_GP_UCODE_REG);
 +              IWL_CMD(CSR_GP_DRIVER_REG);
 +              IWL_CMD(CSR_UCODE_DRV_GP1);
 +              IWL_CMD(CSR_UCODE_DRV_GP2);
 +              IWL_CMD(CSR_LED_REG);
 +              IWL_CMD(CSR_DRAM_INT_TBL_REG);
 +              IWL_CMD(CSR_GIO_CHICKEN_BITS);
 +              IWL_CMD(CSR_ANA_PLL_CFG);
 +              IWL_CMD(CSR_HW_REV_WA_REG);
 +              IWL_CMD(CSR_DBG_HPET_MEM_REG);
 +      default:
 +              return "UNKNOWN";
 +
 +      }
 +}
 +
 +void iwl_dump_csr(struct iwl_priv *priv)
 +{
 +      int i;
 +      u32 csr_tbl[] = {
 +              CSR_HW_IF_CONFIG_REG,
 +              CSR_INT_COALESCING,
 +              CSR_INT,
 +              CSR_INT_MASK,
 +              CSR_FH_INT_STATUS,
 +              CSR_GPIO_IN,
 +              CSR_RESET,
 +              CSR_GP_CNTRL,
 +              CSR_HW_REV,
 +              CSR_EEPROM_REG,
 +              CSR_EEPROM_GP,
 +              CSR_OTP_GP_REG,
 +              CSR_GIO_REG,
 +              CSR_GP_UCODE_REG,
 +              CSR_GP_DRIVER_REG,
 +              CSR_UCODE_DRV_GP1,
 +              CSR_UCODE_DRV_GP2,
 +              CSR_LED_REG,
 +              CSR_DRAM_INT_TBL_REG,
 +              CSR_GIO_CHICKEN_BITS,
 +              CSR_ANA_PLL_CFG,
 +              CSR_HW_REV_WA_REG,
 +              CSR_DBG_HPET_MEM_REG
 +      };
 +      IWL_ERR(priv, "CSR values:\n");
 +      IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
 +              "CSR_INT_PERIODIC_REG)\n");
 +      for (i = 0; i <  ARRAY_SIZE(csr_tbl); i++) {
 +              IWL_ERR(priv, "  %25s: 0X%08x\n",
 +                      get_csr_string(csr_tbl[i]),
 +                      iwl_read32(priv, csr_tbl[i]));
 +      }
 +}
 +EXPORT_SYMBOL(iwl_dump_csr);
 +
 +const static char *get_fh_string(int cmd)
 +{
 +      switch (cmd) {
 +              IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
 +              IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
 +              IWL_CMD(FH_RSCSR_CHNL0_WPTR);
 +              IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
 +              IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
 +              IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
 +              IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
 +              IWL_CMD(FH_TSSR_TX_STATUS_REG);
 +              IWL_CMD(FH_TSSR_TX_ERROR_REG);
 +      default:
 +              return "UNKNOWN";
 +
 +      }
 +}
 +
 +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
 +{
 +      int i;
 +#ifdef CONFIG_IWLWIFI_DEBUG
 +      int pos = 0;
 +      size_t bufsz = 0;
 +#endif
 +      u32 fh_tbl[] = {
 +              FH_RSCSR_CHNL0_STTS_WPTR_REG,
 +              FH_RSCSR_CHNL0_RBDCB_BASE_REG,
 +              FH_RSCSR_CHNL0_WPTR,
 +              FH_MEM_RCSR_CHNL0_CONFIG_REG,
 +              FH_MEM_RSSR_SHARED_CTRL_REG,
 +              FH_MEM_RSSR_RX_STATUS_REG,
 +              FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
 +              FH_TSSR_TX_STATUS_REG,
 +              FH_TSSR_TX_ERROR_REG
 +      };
 +#ifdef CONFIG_IWLWIFI_DEBUG
 +      if (display) {
 +              bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
 +              *buf = kmalloc(bufsz, GFP_KERNEL);
 +              if (!*buf)
 +                      return -ENOMEM;
 +              pos += scnprintf(*buf + pos, bufsz - pos,
 +                              "FH register values:\n");
 +              for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
 +                      pos += scnprintf(*buf + pos, bufsz - pos,
 +                              "  %34s: 0X%08x\n",
 +                              get_fh_string(fh_tbl[i]),
 +                              iwl_read_direct32(priv, fh_tbl[i]));
 +              }
 +              return pos;
 +      }
 +#endif
 +      IWL_ERR(priv, "FH register values:\n");
 +      for (i = 0; i <  ARRAY_SIZE(fh_tbl); i++) {
 +              IWL_ERR(priv, "  %34s: 0X%08x\n",
 +                      get_fh_string(fh_tbl[i]),
 +                      iwl_read_direct32(priv, fh_tbl[i]));
 +      }
 +      return 0;
 +}
 +EXPORT_SYMBOL(iwl_dump_fh);
 +
 +void iwl_force_rf_reset(struct iwl_priv *priv)
 +{
 +      if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 +              return;
 +
 +      if (!iwl_is_associated(priv)) {
 +              IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
 +              return;
 +      }
 +      /*
 +       * There is no easy and better way to force reset the radio,
 +       * the only known method is switching channel which will force to
 +       * reset and tune the radio.
 +       * Use internal short scan (single channel) operation to should
 +       * achieve this objective.
 +       * Driver should reset the radio when number of consecutive missed
 +       * beacon, or any other uCode error condition detected.
 +       */
 +      IWL_DEBUG_INFO(priv, "perform radio reset.\n");
 +      iwl_internal_short_hw_scan(priv);
 +      return;
 +}
 +EXPORT_SYMBOL(iwl_force_rf_reset);
 +
  #ifdef CONFIG_PM
  
  int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
index 8f0c564e68b0d3a485a0226425a44edd01f468ae,b69e972671b2c156b208d3615b7370a55e79c252..1b0701b876c34cd37a5d5b7bacef688768e30bc1
@@@ -5,7 -5,7 +5,7 @@@
   *
   * GPL LICENSE SUMMARY
   *
 - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of version 2 of the GNU General Public License as
@@@ -30,7 -30,7 +30,7 @@@
   *
   * BSD LICENSE
   *
 - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
@@@ -63,6 -63,8 +63,6 @@@
  #ifndef __iwl_core_h__
  #define __iwl_core_h__
  
 -#include <generated/utsrelease.h>
 -
  /************************
   * forward declarations *
   ************************/
@@@ -70,8 -72,8 +70,8 @@@ struct iwl_host_cmd
  struct iwl_cmd;
  
  
 -#define IWLWIFI_VERSION UTS_RELEASE "-k"
 -#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
 +#define IWLWIFI_VERSION "in-tree:"
 +#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation"
  #define DRV_AUTHOR     "<ilw@linux.intel.com>"
  
  #define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@@ -167,11 -169,8 +167,11 @@@ struct iwl_lib_ops 
        int (*is_valid_rtc_data_addr)(u32 addr);
        /* 1st ucode load */
        int (*load_ucode)(struct iwl_priv *priv);
 -      void (*dump_nic_event_log)(struct iwl_priv *priv, bool full_log);
 +      int (*dump_nic_event_log)(struct iwl_priv *priv,
 +                                bool full_log, char **buf, bool display);
        void (*dump_nic_error_log)(struct iwl_priv *priv);
 +      void (*dump_csr)(struct iwl_priv *priv);
 +      int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display);
        int (*set_channel_switch)(struct iwl_priv *priv, u16 channel);
        /* power management */
        struct iwl_apm_ops apm_ops;
  
        /* temperature */
        struct iwl_temp_ops temp_ops;
 +      /* station management */
 +      void (*add_bcast_station)(struct iwl_priv *priv);
  };
  
  struct iwl_led_ops {
@@@ -233,9 -230,8 +233,9 @@@ struct iwl_mod_params 
   * @chain_noise_num_beacons: number of beacons used to compute chain noise
   * @adv_thermal_throttle: support advance thermal throttle
   * @support_ct_kill_exit: support ct kill exit condition
 - * @sm_ps_mode: spatial multiplexing power save mode
   * @support_wimax_coexist: support wimax/wifi co-exist
 + * @plcp_delta_threshold: plcp error rate threshold used to trigger
 + *    radio tuning when there is a high receiving plcp error rate
   *
   * We enable the driver to be backward compatible wrt API version. The
   * driver specifies which APIs it supports (with @ucode_api_max being the
@@@ -291,9 -287,8 +291,9 @@@ struct iwl_cfg 
        const bool supports_idle;
        bool adv_thermal_throttle;
        bool support_ct_kill_exit;
 -      u8 sm_ps_mode;
        const bool support_wimax_coexist;
 +      u8 plcp_delta_threshold;
 +      s32 chain_noise_scale;
  };
  
  /***************************
@@@ -337,11 -332,13 +337,11 @@@ int iwl_mac_beacon_update(struct ieee80
  int iwl_commit_rxon(struct iwl_priv *priv);
  int iwl_set_mode(struct iwl_priv *priv, int mode);
  int iwl_mac_add_interface(struct ieee80211_hw *hw,
 -                               struct ieee80211_if_init_conf *conf);
 +                        struct ieee80211_vif *vif);
  void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 -                               struct ieee80211_if_init_conf *conf);
 +                            struct ieee80211_vif *vif);
  int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
  void iwl_config_ap(struct iwl_priv *priv);
 -int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
 -                       struct ieee80211_tx_queue_stats *stats);
  void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
  int iwl_alloc_txq_mem(struct iwl_priv *priv);
  void iwl_free_txq_mem(struct iwl_priv *priv);
@@@ -428,8 -425,6 +428,8 @@@ int iwl_tx_queue_reclaim(struct iwl_pri
  /* Handlers */
  void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
                               struct iwl_rx_mem_buffer *rxb);
 +void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
 +                                        struct iwl_rx_mem_buffer *rxb);
  void iwl_rx_statistics(struct iwl_priv *priv,
                              struct iwl_rx_mem_buffer *rxb);
  void iwl_reply_statistics(struct iwl_priv *priv,
@@@ -451,6 -446,8 +451,8 @@@ void iwl_hw_txq_ctx_free(struct iwl_pri
  int iwl_hw_tx_queue_init(struct iwl_priv *priv,
                         struct iwl_tx_queue *txq);
  int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+                           int sta_id, int tid, int freed);
  int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
                      int slots_num, u32 txq_id);
  void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
@@@ -500,8 -497,6 +502,8 @@@ void iwl_init_scan_params(struct iwl_pr
  int iwl_scan_cancel(struct iwl_priv *priv);
  int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
  int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
 +int iwl_internal_short_hw_scan(struct iwl_priv *priv);
 +void iwl_force_rf_reset(struct iwl_priv *priv);
  u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
                       const u8 *ie, int ie_len, int left);
  void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
@@@ -532,6 -527,14 +534,6 @@@ int iwl_send_calib_results(struct iwl_p
  int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
  void iwl_calib_free_results(struct iwl_priv *priv);
  
 -/*******************************************************************************
 - * Spectrum Measureemtns in  iwl-spectrum.c
 - ******************************************************************************/
 -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
 -void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
 -#else
 -static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
 -#endif
  /*****************************************************
   *   S e n d i n g     H o s t     C o m m a n d s   *
   *****************************************************/
@@@ -580,10 -583,7 +582,10 @@@ int iwl_pci_resume(struct pci_dev *pdev
  *  Error Handling Debugging
  ******************************************************/
  void iwl_dump_nic_error_log(struct iwl_priv *priv);
 -void iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log);
 +int iwl_dump_nic_event_log(struct iwl_priv *priv,
 +                         bool full_log, char **buf, bool display);
 +void iwl_dump_csr(struct iwl_priv *priv);
 +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
  #ifdef CONFIG_IWLWIFI_DEBUG
  void iwl_print_rx_config_cmd(struct iwl_priv *priv);
  #else
index d365d13e32917e6b2c13218c6fa79ceb059fc014,8f407156285768cc992d1f28d1a92d467a97c4a2..6eff3d4d061672e097724a68493e95020a22354d
@@@ -1,6 -1,6 +1,6 @@@
  /******************************************************************************
   *
 - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
 + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
   *
   * Portions of this file are derived from the ipw3945 project, as well
   * as portions of the ieee80211 subsystem header files.
@@@ -120,6 -120,20 +120,20 @@@ int iwl_txq_update_write_ptr(struct iwl
  EXPORT_SYMBOL(iwl_txq_update_write_ptr);
  
  
+ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+                           int sta_id, int tid, int freed)
+ {
+       if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
+               priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+       else {
+               IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+                       priv->stations[sta_id].tid[tid].tfds_in_queue,
+                       freed);
+               priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
+       }
+ }
+ EXPORT_SYMBOL(iwl_free_tfds_in_queue);
  /**
   * iwl_tx_queue_free - Deallocate DMA queue.
   * @txq: Transmit queue to deallocate.
@@@ -1131,6 -1145,7 +1145,7 @@@ int iwl_tx_queue_reclaim(struct iwl_pri
        struct iwl_queue *q = &txq->q;
        struct iwl_tx_info *tx_info;
        int nfreed = 0;
+       struct ieee80211_hdr *hdr;
  
        if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
                IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
  
                tx_info = &txq->txb[txq->q.read_ptr];
                iwl_tx_status(priv, tx_info->skb[0]);
+               hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
+               if (hdr && ieee80211_is_data_qos(hdr->frame_control))
+                       nfreed++;
                tx_info->skb[0] = NULL;
  
                if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
                        priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
  
                priv->cfg->ops->lib->txq_free_tfd(priv, txq);
-               nfreed++;
        }
        return nfreed;
  }
@@@ -1559,7 -1577,7 +1577,7 @@@ void iwl_rx_reply_compressed_ba(struct 
        if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
                /* calculate mac80211 ampdu sw queue to wake */
                int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
-               priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+               iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
  
                if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
                    priv->mac80211_registered &&
diff --combined net/ipv4/devinet.c
index 014982b61564937f7f55295ac960188491468491,26dec2be96152aa88b3b8893f1fe175a9eb8a418..51ca946e339268b58181870695906e1f29257d85
  
  static struct ipv4_devconf ipv4_devconf = {
        .data = {
 -              [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
 +              [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
        },
  };
  
  static struct ipv4_devconf ipv4_devconf_dflt = {
        .data = {
 -              [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
 -              [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
 -              [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
 +              [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
 +              [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
 +              [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
        },
  };
  
@@@ -1317,14 -1317,19 +1317,19 @@@ static int devinet_sysctl_forward(ctl_t
  {
        int *valp = ctl->data;
        int val = *valp;
+       loff_t pos = *ppos;
        int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
  
        if (write && *valp != val) {
                struct net *net = ctl->extra2;
  
                if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
-                       if (!rtnl_trylock())
+                       if (!rtnl_trylock()) {
+                               /* Restore the original values before restarting */
+                               *valp = val;
+                               *ppos = pos;
                                return restart_syscall();
+                       }
                        if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
                                inet_forward_change(net);
                        } else if (*valp) {
@@@ -1360,7 -1365,7 +1365,7 @@@ int ipv4_doint_and_flush(ctl_table *ctl
        { \
                .procname       = name, \
                .data           = ipv4_devconf.data + \
 -                                NET_IPV4_CONF_ ## attr - 1, \
 +                                IPV4_DEVCONF_ ## attr - 1, \
                .maxlen         = sizeof(int), \
                .mode           = mval, \
                .proc_handler   = proc, \
  
  static struct devinet_sysctl_table {
        struct ctl_table_header *sysctl_header;
 -      struct ctl_table devinet_vars[__NET_IPV4_CONF_MAX];
 +      struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
        char *dev_name;
  } devinet_sysctl = {
        .devinet_vars = {
                DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
                DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
                DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
 +              DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
  
                DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
                DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
@@@ -1487,7 -1491,8 +1492,7 @@@ static void __devinet_sysctl_unregister
  
  static void devinet_sysctl_register(struct in_device *idev)
  {
 -      neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4,
 -                      NET_IPV4_NEIGH, "ipv4", NULL);
 +      neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL);
        __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
                                        &idev->cnf);
  }
@@@ -1502,7 -1507,7 +1507,7 @@@ static struct ctl_table ctl_forward_ent
        {
                .procname       = "ip_forward",
                .data           = &ipv4_devconf.data[
 -                                      NET_IPV4_CONF_FORWARDING - 1],
 +                                      IPV4_DEVCONF_FORWARDING - 1],
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = devinet_sysctl_forward,
@@@ -1546,7 -1551,7 +1551,7 @@@ static __net_init int devinet_init_net(
                if (tbl == NULL)
                        goto err_alloc_ctl;
  
 -              tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1];
 +              tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
                tbl[0].extra1 = all;
                tbl[0].extra2 = net;
  #endif
diff --combined net/ipv6/addrconf.c
index b0d4a4b23db53a97a95aeb7610c26328f6c555bc,143791da062c5118656f826033bb673435ab09f2..1b327f15e7e7ae7960ca8321875375673b67e385
@@@ -278,31 -278,31 +278,31 @@@ static void addrconf_mod_timer(struct i
  
  static int snmp6_alloc_dev(struct inet6_dev *idev)
  {
 -      if (snmp_mib_init((void **)idev->stats.ipv6,
 +      if (snmp_mib_init((void __percpu **)idev->stats.ipv6,
                          sizeof(struct ipstats_mib)) < 0)
                goto err_ip;
 -      if (snmp_mib_init((void **)idev->stats.icmpv6,
 +      if (snmp_mib_init((void __percpu **)idev->stats.icmpv6,
                          sizeof(struct icmpv6_mib)) < 0)
                goto err_icmp;
 -      if (snmp_mib_init((void **)idev->stats.icmpv6msg,
 +      if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg,
                          sizeof(struct icmpv6msg_mib)) < 0)
                goto err_icmpmsg;
  
        return 0;
  
  err_icmpmsg:
 -      snmp_mib_free((void **)idev->stats.icmpv6);
 +      snmp_mib_free((void __percpu **)idev->stats.icmpv6);
  err_icmp:
 -      snmp_mib_free((void **)idev->stats.ipv6);
 +      snmp_mib_free((void __percpu **)idev->stats.ipv6);
  err_ip:
        return -ENOMEM;
  }
  
  static void snmp6_free_dev(struct inet6_dev *idev)
  {
 -      snmp_mib_free((void **)idev->stats.icmpv6msg);
 -      snmp_mib_free((void **)idev->stats.icmpv6);
 -      snmp_mib_free((void **)idev->stats.ipv6);
 +      snmp_mib_free((void __percpu **)idev->stats.icmpv6msg);
 +      snmp_mib_free((void __percpu **)idev->stats.icmpv6);
 +      snmp_mib_free((void __percpu **)idev->stats.ipv6);
  }
  
  /* Nobody refers to this device, we may destroy it. */
@@@ -502,8 -502,11 +502,11 @@@ static int addrconf_fixup_forwarding(st
        if (p == &net->ipv6.devconf_dflt->forwarding)
                return 0;
  
-       if (!rtnl_trylock())
+       if (!rtnl_trylock()) {
+               /* Restore the original values before restarting */
+               *p = old;
                return restart_syscall();
+       }
  
        if (p == &net->ipv6.devconf_all->forwarding) {
                __s32 newf = net->ipv6.devconf_all->forwarding;
@@@ -2646,8 -2649,7 +2649,8 @@@ static int addrconf_ifdown(struct net_d
  
                write_lock_bh(&addrconf_hash_lock);
                while ((ifa = *bifa) != NULL) {
 -                      if (ifa->idev == idev) {
 +                      if (ifa->idev == idev &&
 +                          (how || !(ifa->flags&IFA_F_PERMANENT))) {
                                *bifa = ifa->lst_next;
                                ifa->lst_next = NULL;
                                addrconf_del_timer(ifa);
                write_lock_bh(&idev->lock);
        }
  #endif
 -      while ((ifa = idev->addr_list) != NULL) {
 -              idev->addr_list = ifa->if_next;
 -              ifa->if_next = NULL;
 -              ifa->dead = 1;
 -              addrconf_del_timer(ifa);
 -              write_unlock_bh(&idev->lock);
 +      bifa = &idev->addr_list;
 +      while ((ifa = *bifa) != NULL) {
 +              if (how == 0 && (ifa->flags&IFA_F_PERMANENT)) {
 +                      /* Retain permanent address on admin down */
 +                      bifa = &ifa->if_next;
 +
 +                      /* Restart DAD if needed when link comes back up */
 +                      if ( !((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
 +                             idev->cnf.accept_dad <= 0 ||
 +                             (ifa->flags & IFA_F_NODAD)))
 +                              ifa->flags |= IFA_F_TENTATIVE;
 +              } else {
 +                      *bifa = ifa->if_next;
 +                      ifa->if_next = NULL;
  
 -              __ipv6_ifa_notify(RTM_DELADDR, ifa);
 -              atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
 -              in6_ifa_put(ifa);
 +                      ifa->dead = 1;
 +                      write_unlock_bh(&idev->lock);
  
 -              write_lock_bh(&idev->lock);
 +                      __ipv6_ifa_notify(RTM_DELADDR, ifa);
 +                      atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
 +                      in6_ifa_put(ifa);
 +
 +                      write_lock_bh(&idev->lock);
 +              }
        }
        write_unlock_bh(&idev->lock);
  
@@@ -2802,14 -2792,14 +2805,14 @@@ static void addrconf_dad_start(struct i
        read_lock_bh(&idev->lock);
        if (ifp->dead)
                goto out;
 -      spin_lock_bh(&ifp->lock);
  
 +      spin_lock(&ifp->lock);
        if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) ||
            idev->cnf.accept_dad < 1 ||
            !(ifp->flags&IFA_F_TENTATIVE) ||
            ifp->flags & IFA_F_NODAD) {
                ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
 -              spin_unlock_bh(&ifp->lock);
 +              spin_unlock(&ifp->lock);
                read_unlock_bh(&idev->lock);
  
                addrconf_dad_completed(ifp);
        }
  
        if (!(idev->if_flags & IF_READY)) {
 -              spin_unlock_bh(&ifp->lock);
 +              spin_unlock(&ifp->lock);
                read_unlock_bh(&idev->lock);
                /*
                 * If the device is not ready:
                ip6_ins_rt(ifp->rt);
  
        addrconf_dad_kick(ifp);
 -      spin_unlock_bh(&ifp->lock);
 +      spin_unlock(&ifp->lock);
  out:
        read_unlock_bh(&idev->lock);
  }
@@@ -2853,15 -2843,14 +2856,15 @@@ static void addrconf_dad_timer(unsigne
                read_unlock_bh(&idev->lock);
                goto out;
        }
 -      spin_lock_bh(&ifp->lock);
 +
 +      spin_lock(&ifp->lock);
        if (ifp->probes == 0) {
                /*
                 * DAD was successful
                 */
  
                ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
 -              spin_unlock_bh(&ifp->lock);
 +              spin_unlock(&ifp->lock);
                read_unlock_bh(&idev->lock);
  
                addrconf_dad_completed(ifp);
  
        ifp->probes--;
        addrconf_mod_timer(ifp, AC_DAD, ifp->idev->nd_parms->retrans_time);
 -      spin_unlock_bh(&ifp->lock);
 +      spin_unlock(&ifp->lock);
        read_unlock_bh(&idev->lock);
  
        /* send a neighbour solicitation for our addr */
@@@ -2919,12 -2908,12 +2922,12 @@@ static void addrconf_dad_run(struct ine
  
        read_lock_bh(&idev->lock);
        for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
 -              spin_lock_bh(&ifp->lock);
 +              spin_lock(&ifp->lock);
                if (!(ifp->flags & IFA_F_TENTATIVE)) {
 -                      spin_unlock_bh(&ifp->lock);
 +                      spin_unlock(&ifp->lock);
                        continue;
                }
 -              spin_unlock_bh(&ifp->lock);
 +              spin_unlock(&ifp->lock);
                addrconf_dad_kick(ifp);
        }
        read_unlock_bh(&idev->lock);
@@@ -3041,14 -3030,14 +3044,14 @@@ static const struct file_operations if6
        .release        = seq_release_net,
  };
  
 -static int if6_proc_net_init(struct net *net)
 +static int __net_init if6_proc_net_init(struct net *net)
  {
        if (!proc_net_fops_create(net, "if_inet6", S_IRUGO, &if6_fops))
                return -ENOMEM;
        return 0;
  }
  
 -static void if6_proc_net_exit(struct net *net)
 +static void __net_exit if6_proc_net_exit(struct net *net)
  {
         proc_net_remove(net, "if_inet6");
  }
@@@ -3766,8 -3755,8 +3769,8 @@@ static inline size_t inet6_if_nlmsg_siz
                 );
  }
  
 -static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items,
 -                                    int bytes)
 +static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
 +                                    int items, int bytes)
  {
        int i;
        int pad = bytes - sizeof(u64) * items;
@@@ -3786,10 -3775,10 +3789,10 @@@ static void snmp6_fill_stats(u64 *stats
  {
        switch(attrtype) {
        case IFLA_INET6_STATS:
 -              __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
 +              __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
                break;
        case IFLA_INET6_ICMP6STATS:
 -              __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
 +              __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
                break;
        }
  }
@@@ -4042,12 -4031,15 +4045,15 @@@ int addrconf_sysctl_forward(ctl_table *
  {
        int *valp = ctl->data;
        int val = *valp;
+       loff_t pos = *ppos;
        int ret;
  
        ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
  
        if (write)
                ret = addrconf_fixup_forwarding(ctl, valp, val);
+       if (ret)
+               *ppos = pos;
        return ret;
  }
  
@@@ -4089,8 -4081,11 +4095,11 @@@ static int addrconf_disable_ipv6(struc
        if (p == &net->ipv6.devconf_dflt->disable_ipv6)
                return 0;
  
-       if (!rtnl_trylock())
+       if (!rtnl_trylock()) {
+               /* Restore the original values before restarting */
+               *p = old;
                return restart_syscall();
+       }
  
        if (p == &net->ipv6.devconf_all->disable_ipv6) {
                __s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@@ -4109,12 -4104,15 +4118,15 @@@ int addrconf_sysctl_disable(ctl_table *
  {
        int *valp = ctl->data;
        int val = *valp;
+       loff_t pos = *ppos;
        int ret;
  
        ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
  
        if (write)
                ret = addrconf_disable_ipv6(ctl, valp, val);
+       if (ret)
+               *ppos = pos;
        return ret;
  }
  
@@@ -4416,7 -4414,8 +4428,7 @@@ static void __addrconf_sysctl_unregiste
  
  static void addrconf_sysctl_register(struct inet6_dev *idev)
  {
 -      neigh_sysctl_register(idev->dev, idev->nd_parms, NET_IPV6,
 -                            NET_IPV6_NEIGH, "ipv6",
 +      neigh_sysctl_register(idev->dev, idev->nd_parms, "ipv6",
                              &ndisc_ifinfo_sysctl_change);
        __addrconf_sysctl_register(dev_net(idev->dev), idev->dev->name,
                                        idev, &idev->cnf);
@@@ -4431,7 -4430,7 +4443,7 @@@ static void addrconf_sysctl_unregister(
  
  #endif
  
 -static int addrconf_init_net(struct net *net)
 +static int __net_init addrconf_init_net(struct net *net)
  {
        int err;
        struct ipv6_devconf *all, *dflt;
@@@ -4480,7 -4479,7 +4492,7 @@@ err_alloc_all
        return err;
  }
  
 -static void addrconf_exit_net(struct net *net)
 +static void __net_exit addrconf_exit_net(struct net *net)
  {
  #ifdef CONFIG_SYSCTL
        __addrconf_sysctl_unregister(net->ipv6.devconf_dflt);