OSDN Git Service

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Tue, 17 May 2011 21:33:11 +0000 (17:33 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 17 May 2011 21:33:11 +0000 (17:33 -0400)
Conflicts:
drivers/net/vmxnet3/vmxnet3_ethtool.c
net/core/dev.c

16 files changed:
1  2 
drivers/net/bonding/bond_3ad.h
drivers/net/ehea/ehea_main.c
drivers/net/sfc/nic.c
drivers/net/sfc/nic.h
drivers/net/sfc/siena.c
drivers/net/vmxnet3/vmxnet3_ethtool.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlegacy/iwl-core.c
drivers/net/wireless/iwlegacy/iwl-dev.h
drivers/net/wireless/libertas/cmd.c
net/bridge/br_netfilter.c
net/core/dev.c
net/core/ethtool.c
net/mac80211/tx.c
net/netfilter/ipvs/ip_vs_ctl.c
net/socket.c

@@@ -39,7 -39,7 +39,7 @@@
  
  typedef struct mac_addr {
        u8 mac_addr_value[ETH_ALEN];
- } mac_addr_t;
+ } __packed mac_addr_t;
  
  enum {
        BOND_AD_STABLE = 0,
@@@ -134,12 -134,12 +134,12 @@@ typedef struct lacpdu 
        u8 tlv_type_terminator;      // = terminator
        u8 terminator_length;        // = 0
        u8 reserved_50[50];          // = 0
- } lacpdu_t;
+ } __packed lacpdu_t;
  
  typedef struct lacpdu_header {
        struct ethhdr hdr;
        struct lacpdu lacpdu;
- } lacpdu_header_t;
+ } __packed lacpdu_header_t;
  
  // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
  typedef struct bond_marker {
        u8 tlv_type_terminator;      //  = 0x00
        u8 terminator_length;        //  = 0x00
        u8 reserved_90[90];          //  = 0
- } bond_marker_t;
+ } __packed bond_marker_t;
  
  typedef struct bond_marker_header {
        struct ethhdr hdr;
        struct bond_marker marker;
- } bond_marker_header_t;
+ } __packed bond_marker_header_t;
  
  #pragma pack()
  
@@@ -258,6 -258,7 +258,6 @@@ struct ad_bond_info 
                                 * requested
                                 */
        struct timer_list ad_timer;
 -      struct packet_type ad_pkt_type;
  };
  
  struct ad_slave_info {
@@@ -279,8 -280,7 +279,8 @@@ void bond_3ad_adapter_duplex_changed(st
  void bond_3ad_handle_link_change(struct slave *slave, char link);
  int  bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
  int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
 -int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
 +void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
 +                        struct slave *slave);
  int bond_3ad_set_carrier(struct bonding *bond);
  #endif //__BOND_3AD_H__
  
@@@ -2688,9 -2688,6 +2688,6 @@@ static int ehea_open(struct net_device 
                netif_start_queue(dev);
        }
  
-       init_waitqueue_head(&port->swqe_avail_wq);
-       init_waitqueue_head(&port->restart_wq);
        mutex_unlock(&port->port_lock);
  
        return ret;
@@@ -3265,12 -3262,10 +3262,12 @@@ struct ehea_port *ehea_setup_single_por
        dev->netdev_ops = &ehea_netdev_ops;
        ehea_set_ethtool_ops(dev);
  
 +      dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
 +                    | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO;
        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
                      | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
                      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
 -                    | NETIF_F_LLTX;
 +                    | NETIF_F_LLTX | NETIF_F_RXCSUM;
        dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
  
        if (use_lro)
  
        INIT_WORK(&port->reset_task, ehea_reset_port);
  
+       init_waitqueue_head(&port->swqe_avail_wq);
+       init_waitqueue_head(&port->restart_wq);
        ret = register_netdev(dev);
        if (ret) {
                pr_err("register_netdev failed. ret=%d\n", ret);
diff --combined drivers/net/sfc/nic.c
@@@ -852,6 -852,7 +852,6 @@@ efx_handle_rx_event(struct efx_channel 
        unsigned expected_ptr;
        bool rx_ev_pkt_ok, discard = false, checksummed;
        struct efx_rx_queue *rx_queue;
 -      struct efx_nic *efx = channel->efx;
  
        /* Basic packet information */
        rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT);
                 * UDP/IP, then we can rely on the hardware checksum.
                 */
                checksummed =
 -                      likely(efx->rx_checksum_enabled) &&
 -                      (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
 -                       rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP);
 +                      rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
 +                      rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP;
        } else {
                efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard);
                checksummed = false;
@@@ -1935,6 -1937,13 +1935,13 @@@ void efx_nic_get_regs(struct efx_nic *e
  
                size = min_t(size_t, table->step, 16);
  
+               if (table->offset >= efx->type->mem_map_size) {
+                       /* No longer mapped; return dummy data */
+                       memcpy(buf, "\xde\xc0\xad\xde", 4);
+                       buf += table->rows * size;
+                       continue;
+               }
                for (i = 0; i < table->rows; i++) {
                        switch (table->step) {
                        case 4: /* 32-bit register or SRAM */
diff --combined drivers/net/sfc/nic.h
@@@ -143,16 -143,18 +143,18 @@@ static inline struct falcon_board *falc
  /**
   * struct siena_nic_data - Siena NIC state
   * @mcdi: Management-Controller-to-Driver Interface
+  * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable.
   * @wol_filter_id: Wake-on-LAN packet filter id
   */
  struct siena_nic_data {
        struct efx_mcdi_iface mcdi;
+       void __iomem *mcdi_smem;
        int wol_filter_id;
  };
  
 -extern struct efx_nic_type falcon_a1_nic_type;
 -extern struct efx_nic_type falcon_b0_nic_type;
 -extern struct efx_nic_type siena_a0_nic_type;
 +extern const struct efx_nic_type falcon_a1_nic_type;
 +extern const struct efx_nic_type falcon_b0_nic_type;
 +extern const struct efx_nic_type siena_a0_nic_type;
  
  /**************************************************************************
   *
diff --combined drivers/net/sfc/siena.c
@@@ -220,12 -220,26 +220,26 @@@ static int siena_probe_nic(struct efx_n
        efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
        efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
  
+       /* Initialise MCDI */
+       nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys +
+                                             FR_CZ_MC_TREG_SMEM,
+                                             FR_CZ_MC_TREG_SMEM_STEP *
+                                             FR_CZ_MC_TREG_SMEM_ROWS);
+       if (!nic_data->mcdi_smem) {
+               netif_err(efx, probe, efx->net_dev,
+                         "could not map MCDI at %llx+%x\n",
+                         (unsigned long long)efx->membase_phys +
+                         FR_CZ_MC_TREG_SMEM,
+                         FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS);
+               rc = -ENOMEM;
+               goto fail1;
+       }
        efx_mcdi_init(efx);
  
        /* Recover from a failed assertion before probing */
        rc = efx_mcdi_handle_assertion(efx);
        if (rc)
-               goto fail1;
+               goto fail2;
  
        /* Let the BMC know that the driver is now in charge of link and
         * filter settings. We must do this before we reset the NIC */
@@@ -280,6 -294,7 +294,7 @@@ fail4
  fail3:
        efx_mcdi_drv_attach(efx, false, NULL);
  fail2:
+       iounmap(nic_data->mcdi_smem);
  fail1:
        kfree(efx->nic_data);
        return rc;
@@@ -359,6 -374,8 +374,8 @@@ static int siena_init_nic(struct efx_ni
  
  static void siena_remove_nic(struct efx_nic *efx)
  {
+       struct siena_nic_data *nic_data = efx->nic_data;
        efx_nic_free_buffer(efx, &efx->irq_status);
  
        siena_reset_hw(efx, RESET_TYPE_ALL);
                efx_mcdi_drv_attach(efx, false, NULL);
  
        /* Tear down the private nic state */
-       kfree(efx->nic_data);
+       iounmap(nic_data->mcdi_smem);
+       kfree(nic_data);
        efx->nic_data = NULL;
  }
  
@@@ -581,7 -599,7 +599,7 @@@ static void siena_init_wol(struct efx_n
   **************************************************************************
   */
  
 -struct efx_nic_type siena_a0_nic_type = {
 +const struct efx_nic_type siena_a0_nic_type = {
        .probe = siena_probe_nic,
        .remove = siena_remove_nic,
        .init = siena_init_nic,
        .default_mac_ops = &efx_mcdi_mac_operations,
  
        .revision = EFX_REV_SIENA_A0,
-       .mem_map_size = (FR_CZ_MC_TREG_SMEM +
-                        FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS),
+       .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */
        .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL,
        .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL,
        .buf_tbl_base = FR_BZ_BUF_FULL_TBL,
@@@ -33,6 -33,40 +33,6 @@@ struct vmxnet3_stat_desc 
  };
  
  
 -static u32
 -vmxnet3_get_rx_csum(struct net_device *netdev)
 -{
 -      struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 -      return adapter->rxcsum;
 -}
 -
 -
 -static int
 -vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
 -{
 -      struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 -      unsigned long flags;
 -
 -      if (adapter->rxcsum != val) {
 -              adapter->rxcsum = val;
 -              if (netif_running(netdev)) {
 -                      if (val)
 -                              adapter->shared->devRead.misc.uptFeatures |=
 -                              UPT1_F_RXCSUM;
 -                      else
 -                              adapter->shared->devRead.misc.uptFeatures &=
 -                              ~UPT1_F_RXCSUM;
 -
 -                      spin_lock_irqsave(&adapter->cmd_lock, flags);
 -                      VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 -                                             VMXNET3_CMD_UPDATE_FEATURE);
 -                      spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 -              }
 -      }
 -      return 0;
 -}
 -
 -
  /* per tq stats maintained by the device */
  static const struct vmxnet3_stat_desc
  vmxnet3_tq_dev_stats[] = {
@@@ -262,27 -296,31 +262,28 @@@ vmxnet3_get_strings(struct net_device *
        }
  }
  
 -static int
 -vmxnet3_set_flags(struct net_device *netdev, u32 data)
 +int vmxnet3_set_features(struct net_device *netdev, u32 features)
  {
        struct vmxnet3_adapter *adapter = netdev_priv(netdev);
 -      u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
 -      u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
        unsigned long flags;
 +      u32 changed = features ^ netdev->features;
  
 -      if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
 -              return -EINVAL;
 -
 -      if (lro_requested ^ lro_present) {
 -              /* toggle the LRO feature*/
 -              netdev->features ^= NETIF_F_LRO;
 -
 -              /* Update private LRO flag */
 -              adapter->lro = lro_requested;
 +      if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) {
 +              if (features & NETIF_F_RXCSUM)
 +                      adapter->shared->devRead.misc.uptFeatures |=
 +                      UPT1_F_RXCSUM;
 +              else
 +                      adapter->shared->devRead.misc.uptFeatures &=
 +                      ~UPT1_F_RXCSUM;
  
 -              if (lro_requested)
+               /* update harware LRO capability accordingly */
 +              if (features & NETIF_F_LRO)
                        adapter->shared->devRead.misc.uptFeatures |=
                                                        UPT1_F_LRO;
                else
                        adapter->shared->devRead.misc.uptFeatures &=
                                                        ~UPT1_F_LRO;
 +
                spin_lock_irqsave(&adapter->cmd_lock, flags);
                VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
                                       VMXNET3_CMD_UPDATE_FEATURE);
@@@ -424,10 -462,10 +425,10 @@@ vmxnet3_get_settings(struct net_device 
        ecmd->transceiver = XCVR_INTERNAL;
  
        if (adapter->link_speed) {
 -              ecmd->speed = adapter->link_speed;
 +              ethtool_cmd_speed_set(ecmd, adapter->link_speed);
                ecmd->duplex = DUPLEX_FULL;
        } else {
 -              ecmd->speed = -1;
 +              ethtool_cmd_speed_set(ecmd, -1);
                ecmd->duplex = -1;
        }
        return 0;
@@@ -619,7 -657,17 +620,7 @@@ static struct ethtool_ops vmxnet3_ethto
        .get_wol           = vmxnet3_get_wol,
        .set_wol           = vmxnet3_set_wol,
        .get_link          = ethtool_op_get_link,
 -      .get_rx_csum       = vmxnet3_get_rx_csum,
 -      .set_rx_csum       = vmxnet3_set_rx_csum,
 -      .get_tx_csum       = ethtool_op_get_tx_csum,
 -      .set_tx_csum       = ethtool_op_set_tx_hw_csum,
 -      .get_sg            = ethtool_op_get_sg,
 -      .set_sg            = ethtool_op_set_sg,
 -      .get_tso           = ethtool_op_get_tso,
 -      .set_tso           = ethtool_op_set_tso,
        .get_strings       = vmxnet3_get_strings,
 -      .get_flags         = ethtool_op_get_flags,
 -      .set_flags         = vmxnet3_set_flags,
        .get_sset_count    = vmxnet3_get_sset_count,
        .get_ethtool_stats = vmxnet3_get_ethtool_stats,
        .get_ringparam     = vmxnet3_get_ringparam,
@@@ -299,7 -299,7 +299,7 @@@ int ath_set_channel(struct ath_softc *s
  
        if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
                if (sc->sc_flags & SC_OP_BEACONS)
 -                      ath_beacon_config(sc, NULL);
 +                      ath_set_beacon(sc);
                ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
                ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
                ath_start_ani(common);
@@@ -624,43 -624,6 +624,43 @@@ out
        ath9k_ps_restore(sc);
  }
  
 +static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
 +{
 +      static int count;
 +      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 +
 +      if (pll_sqsum >= 0x40000) {
 +              count++;
 +              if (count == 3) {
 +                      /* Rx is hung for more than 500ms. Reset it */
 +                      ath_dbg(common, ATH_DBG_RESET,
 +                              "Possible RX hang, resetting");
 +                      ath_reset(sc, true);
 +                      count = 0;
 +              }
 +      } else
 +              count = 0;
 +}
 +
 +void ath_hw_pll_work(struct work_struct *work)
 +{
 +      struct ath_softc *sc = container_of(work, struct ath_softc,
 +                                          hw_pll_work.work);
 +      u32 pll_sqsum;
 +
 +      if (AR_SREV_9485(sc->sc_ah)) {
 +
 +              ath9k_ps_wakeup(sc);
 +              pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
 +              ath9k_ps_restore(sc);
 +
 +              ath_hw_pll_rx_hang_check(sc, pll_sqsum);
 +
 +              ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
 +      }
 +}
 +
 +
  void ath9k_tasklet(unsigned long data)
  {
        struct ath_softc *sc = (struct ath_softc *)data;
            !ath9k_hw_check_alive(ah))
                ieee80211_queue_work(sc->hw, &sc->hw_check_work);
  
 +      if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
 +              /*
 +               * TSF sync does not look correct; remain awake to sync with
 +               * the next Beacon.
 +               */
 +              ath_dbg(common, ATH_DBG_PS,
 +                      "TSFOOR - Sync with next Beacon\n");
 +              sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
 +                              PS_TSFOOR_SYNC;
 +      }
 +
        if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
                rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
                          ATH9K_INT_RXORN);
                        ath_tx_tasklet(sc);
        }
  
 -      if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
 -              /*
 -               * TSF sync does not look correct; remain awake to sync with
 -               * the next Beacon.
 -               */
 -              ath_dbg(common, ATH_DBG_PS,
 -                      "TSFOOR - Sync with next Beacon\n");
 -              sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
 -      }
 -
        if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
                if (status & ATH9K_INT_GENTIMER)
                        ath_gen_timer_isr(sc->sc_ah);
@@@ -866,6 -828,48 +866,6 @@@ chip_reset
  #undef SCHED_INTR
  }
  
 -static void ath9k_bss_assoc_info(struct ath_softc *sc,
 -                               struct ieee80211_hw *hw,
 -                               struct ieee80211_vif *vif,
 -                               struct ieee80211_bss_conf *bss_conf)
 -{
 -      struct ath_hw *ah = sc->sc_ah;
 -      struct ath_common *common = ath9k_hw_common(ah);
 -
 -      if (bss_conf->assoc) {
 -              ath_dbg(common, ATH_DBG_CONFIG,
 -                      "Bss Info ASSOC %d, bssid: %pM\n",
 -                      bss_conf->aid, common->curbssid);
 -
 -              /* New association, store aid */
 -              common->curaid = bss_conf->aid;
 -              ath9k_hw_write_associd(ah);
 -
 -              /*
 -               * Request a re-configuration of Beacon related timers
 -               * on the receipt of the first Beacon frame (i.e.,
 -               * after time sync with the AP).
 -               */
 -              sc->ps_flags |= PS_BEACON_SYNC;
 -
 -              /* Configure the beacon */
 -              ath_beacon_config(sc, vif);
 -
 -              /* Reset rssi stats */
 -              sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 -              sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 -
 -              sc->sc_flags |= SC_OP_ANI_RUN;
 -              ath_start_ani(common);
 -      } else {
 -              ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
 -              common->curaid = 0;
 -              /* Stop ANI */
 -              sc->sc_flags &= ~SC_OP_ANI_RUN;
 -              del_timer_sync(&common->ani.timer);
 -      }
 -}
 -
  void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
  {
        struct ath_hw *ah = sc->sc_ah;
                goto out;
        }
        if (sc->sc_flags & SC_OP_BEACONS)
 -              ath_beacon_config(sc, NULL);    /* restart beacons */
 +              ath_set_beacon(sc);     /* restart beacons */
  
        /* Re-Enable  interrupts */
        ath9k_hw_set_interrupts(ah, ah->imask);
@@@ -1002,7 -1006,7 +1002,7 @@@ int ath_reset(struct ath_softc *sc, boo
                               sc->config.txpowlimit, &sc->curtxpow);
  
        if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
 -              ath_beacon_config(sc, NULL);    /* restart beacons */
 +              ath_set_beacon(sc);     /* restart beacons */
  
        ath9k_hw_set_interrupts(ah, ah->imask);
  
@@@ -1385,9 -1389,7 +1385,9 @@@ static void ath9k_calculate_summary_sta
                ath9k_hw_set_tsfadjust(ah, 0);
                sc->sc_flags &= ~SC_OP_TSF_RESET;
  
 -              if (iter_data.nwds + iter_data.nmeshes)
 +              if (iter_data.nmeshes)
 +                      ah->opmode = NL80211_IFTYPE_MESH_POINT;
 +              else if (iter_data.nwds)
                        ah->opmode = NL80211_IFTYPE_AP;
                else if (iter_data.nadhocs)
                        ah->opmode = NL80211_IFTYPE_ADHOC;
  
        /* Set up ANI */
        if ((iter_data.naps + iter_data.nadhocs) > 0) {
 +              sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
                sc->sc_flags |= SC_OP_ANI_RUN;
                ath_start_ani(common);
        } else {
@@@ -1451,6 -1452,7 +1451,6 @@@ static int ath9k_add_interface(struct i
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
 -      struct ath_vif *avp = (void *)vif->drv_priv;
        int ret = 0;
  
        ath9k_ps_wakeup(sc);
                }
        }
  
 -      if ((vif->type == NL80211_IFTYPE_ADHOC) &&
 -          sc->nvifs > 0) {
 +      if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
 +          ((vif->type == NL80211_IFTYPE_ADHOC) &&
 +           sc->nvifs > 0)) {
                ath_err(common, "Cannot create ADHOC interface when other"
                        " interfaces already exist.\n");
                ret = -EINVAL;
        ath_dbg(common, ATH_DBG_CONFIG,
                "Attach a VIF of type: %d\n", vif->type);
  
 -      /* Set the VIF opmode */
 -      avp->av_opmode = vif->type;
 -      avp->av_bslot = -1;
 -
        sc->nvifs++;
  
        ath9k_do_vif_add_setup(hw, vif);
@@@ -1777,68 -1782,23 +1777,68 @@@ static int ath9k_sta_add(struct ieee802
                         struct ieee80211_sta *sta)
  {
        struct ath_softc *sc = hw->priv;
 +      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 +      struct ath_node *an = (struct ath_node *) sta->drv_priv;
 +      struct ieee80211_key_conf ps_key = { };
  
        ath_node_attach(sc, sta);
  
 +      if (vif->type != NL80211_IFTYPE_AP &&
 +          vif->type != NL80211_IFTYPE_AP_VLAN)
 +              return 0;
 +
 +      an->ps_key = ath_key_config(common, vif, sta, &ps_key);
 +
        return 0;
  }
  
 +static void ath9k_del_ps_key(struct ath_softc *sc,
 +                           struct ieee80211_vif *vif,
 +                           struct ieee80211_sta *sta)
 +{
 +      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 +      struct ath_node *an = (struct ath_node *) sta->drv_priv;
 +      struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };
 +
 +      if (!an->ps_key)
 +          return;
 +
 +      ath_key_delete(common, &ps_key);
 +}
 +
  static int ath9k_sta_remove(struct ieee80211_hw *hw,
                            struct ieee80211_vif *vif,
                            struct ieee80211_sta *sta)
  {
        struct ath_softc *sc = hw->priv;
  
 +      ath9k_del_ps_key(sc, vif, sta);
        ath_node_detach(sc, sta);
  
        return 0;
  }
  
 +static void ath9k_sta_notify(struct ieee80211_hw *hw,
 +                       struct ieee80211_vif *vif,
 +                       enum sta_notify_cmd cmd,
 +                       struct ieee80211_sta *sta)
 +{
 +      struct ath_softc *sc = hw->priv;
 +      struct ath_node *an = (struct ath_node *) sta->drv_priv;
 +
 +      switch (cmd) {
 +      case STA_NOTIFY_SLEEP:
 +              an->sleeping = true;
 +              if (ath_tx_aggr_sleep(sc, an))
 +                      ieee80211_sta_set_tim(sta);
 +              break;
 +      case STA_NOTIFY_AWAKE:
 +              an->sleeping = false;
 +              ath_tx_aggr_wakeup(sc, an);
 +              break;
 +      }
 +}
 +
  static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
                         const struct ieee80211_tx_queue_params *params)
  {
@@@ -1895,29 -1855,12 +1895,29 @@@ static int ath9k_set_key(struct ieee802
        if (ath9k_modparam_nohwcrypt)
                return -ENOSPC;
  
 +      if (vif->type == NL80211_IFTYPE_ADHOC &&
 +          (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
 +           key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
 +          !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
 +              /*
 +               * For now, disable hw crypto for the RSN IBSS group keys. This
 +               * could be optimized in the future to use a modified key cache
 +               * design to support per-STA RX GTK, but until that gets
 +               * implemented, use of software crypto for group addressed
 +               * frames is a acceptable to allow RSN IBSS to be used.
 +               */
 +              return -EOPNOTSUPP;
 +      }
 +
        mutex_lock(&sc->mutex);
        ath9k_ps_wakeup(sc);
        ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
  
        switch (cmd) {
        case SET_KEY:
 +              if (sta)
 +                      ath9k_del_ps_key(sc, vif, sta);
 +
                ret = ath_key_config(common, vif, sta, key);
                if (ret >= 0) {
                        key->hw_key_idx = ret;
  
        return ret;
  }
 +static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 +{
 +      struct ath_softc *sc = data;
 +      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 +      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 +      struct ath_vif *avp = (void *)vif->drv_priv;
 +
 +      switch (sc->sc_ah->opmode) {
 +      case NL80211_IFTYPE_ADHOC:
 +              /* There can be only one vif available */
 +              memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
 +              common->curaid = bss_conf->aid;
 +              ath9k_hw_write_associd(sc->sc_ah);
 +              /* configure beacon */
 +              if (bss_conf->enable_beacon)
 +                      ath_beacon_config(sc, vif);
 +              break;
 +      case NL80211_IFTYPE_STATION:
 +              /*
 +               * Skip iteration if primary station vif's bss info
 +               * was not changed
 +               */
 +              if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
 +                      break;
 +
 +              if (bss_conf->assoc) {
 +                      sc->sc_flags |= SC_OP_PRIM_STA_VIF;
 +                      avp->primary_sta_vif = true;
 +                      memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
 +                      common->curaid = bss_conf->aid;
 +                      ath9k_hw_write_associd(sc->sc_ah);
 +                      ath_dbg(common, ATH_DBG_CONFIG,
 +                              "Bss Info ASSOC %d, bssid: %pM\n",
 +                              bss_conf->aid, common->curbssid);
 +                      ath_beacon_config(sc, vif);
 +                      /*
 +                       * Request a re-configuration of Beacon related timers
 +                       * on the receipt of the first Beacon frame (i.e.,
 +                       * after time sync with the AP).
 +                       */
 +                      sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
 +                      /* Reset rssi stats */
 +                      sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 +                      sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 +
 +                      sc->sc_flags |= SC_OP_ANI_RUN;
 +                      ath_start_ani(common);
 +              }
 +              break;
 +      default:
 +              break;
 +      }
 +}
 +
 +static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
 +{
 +      struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 +      struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 +      struct ath_vif *avp = (void *)vif->drv_priv;
 +
 +      /* Reconfigure bss info */
 +      if (avp->primary_sta_vif && !bss_conf->assoc) {
 +              ath_dbg(common, ATH_DBG_CONFIG,
 +                      "Bss Info DISASSOC %d, bssid %pM\n",
 +                      common->curaid, common->curbssid);
 +              sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
 +              avp->primary_sta_vif = false;
 +              memset(common->curbssid, 0, ETH_ALEN);
 +              common->curaid = 0;
 +      }
 +
 +      ieee80211_iterate_active_interfaces_atomic(
 +                      sc->hw, ath9k_bss_iter, sc);
 +
 +      /*
 +       * None of station vifs are associated.
 +       * Clear bssid & aid
 +       */
 +      if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
 +          !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
 +              ath9k_hw_write_associd(sc->sc_ah);
 +              /* Stop ANI */
 +              sc->sc_flags &= ~SC_OP_ANI_RUN;
 +              del_timer_sync(&common->ani.timer);
 +      }
 +}
  
  static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
                                   struct ieee80211_vif *vif,
                                   u32 changed)
  {
        struct ath_softc *sc = hw->priv;
 -      struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_vif *avp = (void *)vif->drv_priv;
        mutex_lock(&sc->mutex);
  
        if (changed & BSS_CHANGED_BSSID) {
 -              /* Set BSSID */
 -              memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
 -              memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
 -              common->curaid = 0;
 -              ath9k_hw_write_associd(ah);
 -
 -              /* Set aggregation protection mode parameters */
 -              sc->config.ath_aggr_prot = 0;
 +              ath9k_config_bss(sc, vif);
  
                ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
                        common->curbssid, common->curaid);
 -
 -              /* need to reconfigure the beacon */
 -              sc->sc_flags &= ~SC_OP_BEACONS ;
        }
  
        /* Enable transmission of beacons (AP, IBSS, MESH) */
        }
  
        if (changed & BSS_CHANGED_BEACON_INT) {
 -              cur_conf->beacon_interval = bss_conf->beacon_int;
                /*
                 * In case of AP mode, the HW TSF has to be reset
                 * when the beacon interval changes.
                        if (!error)
                                ath_beacon_config(sc, vif);
                        ath9k_set_beaconing_status(sc, true);
 -              } else {
 +              } else
                        ath_beacon_config(sc, vif);
 -              }
        }
  
        if (changed & BSS_CHANGED_ERP_PREAMBLE) {
                        sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
        }
  
 -      if (changed & BSS_CHANGED_ASSOC) {
 -              ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
 -                      bss_conf->assoc);
 -              ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
 -      }
 -
        mutex_unlock(&sc->mutex);
        ath9k_ps_restore(sc);
  }
@@@ -2265,18 -2141,27 +2265,26 @@@ static void ath9k_set_coverage_class(st
  static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
  {
        struct ath_softc *sc = hw->priv;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_common *common = ath9k_hw_common(ah);
        int timeout = 200; /* ms */
        int i, j;
 +      bool drain_txq;
  
 -      ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
 -
        cancel_delayed_work_sync(&sc->tx_complete_work);
  
+       if (sc->sc_flags & SC_OP_INVALID) {
+               ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
+               mutex_unlock(&sc->mutex);
+               return;
+       }
        if (drop)
                timeout = 1;
  
        for (j = 0; j < timeout; j++) {
 -              int npend = 0;
 +              bool npend = false;
  
                if (j)
                        usleep_range(1000, 2000);
                        if (!ATH_TXQ_SETUP(sc, i))
                                continue;
  
 -                      npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
 +                      npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
 +
 +                      if (npend)
 +                              break;
                }
  
                if (!npend)
                    goto out;
        }
  
 -      if (!ath_drain_all_txq(sc, false))
 +      ath9k_ps_wakeup(sc);
 +      spin_lock_bh(&sc->sc_pcu_lock);
 +      drain_txq = ath_drain_all_txq(sc, false);
 +      spin_unlock_bh(&sc->sc_pcu_lock);
 +      if (!drain_txq)
                ath_reset(sc, false);
 -
 +      ath9k_ps_restore(sc);
        ieee80211_wake_queues(hw);
  
  out:
        ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
        mutex_unlock(&sc->mutex);
 -      ath9k_ps_restore(sc);
 +}
 +
 +static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
 +{
 +      struct ath_softc *sc = hw->priv;
 +      int i;
 +
 +      for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
 +              if (!ATH_TXQ_SETUP(sc, i))
 +                      continue;
 +
 +              if (ath9k_has_pending_frames(sc, &sc->tx.txq[i]))
 +                      return true;
 +      }
 +      return false;
  }
  
  struct ieee80211_ops ath9k_ops = {
        .configure_filter   = ath9k_configure_filter,
        .sta_add            = ath9k_sta_add,
        .sta_remove         = ath9k_sta_remove,
 +      .sta_notify         = ath9k_sta_notify,
        .conf_tx            = ath9k_conf_tx,
        .bss_info_changed   = ath9k_bss_info_changed,
        .set_key            = ath9k_set_key,
        .rfkill_poll        = ath9k_rfkill_poll_state,
        .set_coverage_class = ath9k_set_coverage_class,
        .flush              = ath9k_flush,
 +      .tx_frames_pending  = ath9k_tx_frames_pending,
  };
@@@ -211,7 -211,10 +211,7 @@@ int iwl_legacy_init_geos(struct iwl_pri
                if (!iwl_legacy_is_channel_valid(ch))
                        continue;
  
 -              if (iwl_legacy_is_channel_a_band(ch))
 -                      sband =  &priv->bands[IEEE80211_BAND_5GHZ];
 -              else
 -                      sband =  &priv->bands[IEEE80211_BAND_2GHZ];
 +              sband = &priv->bands[ch->band];
  
                geo_ch = &sband->channels[sband->n_channels++];
  
@@@ -2114,9 -2117,10 +2114,9 @@@ int iwl_legacy_mac_config(struct ieee80
        IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
                                        channel->hw_value, changed);
  
 -      if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
 -                      test_bit(STATUS_SCANNING, &priv->status))) {
 +      if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
                scan_active = 1;
 -              IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
 +              IWL_DEBUG_MAC80211(priv, "scan active\n");
        }
  
        if (changed & (IEEE80211_CONF_CHANGE_SMPS |
                        goto set_ch_out;
                }
  
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+                   !iwl_legacy_is_channel_ibss(ch_info)) {
+                       IWL_DEBUG_MAC80211(priv, "leave - not IBSS channel\n");
+                       ret = -EINVAL;
+                       goto set_ch_out;
+               }
                spin_lock_irqsave(&priv->lock, flags);
  
                for_each_context(priv, ctx) {
@@@ -2429,13 -2440,11 +2436,13 @@@ void iwl_legacy_mac_bss_info_changed(st
  
        IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
  
 -      if (!iwl_legacy_is_alive(priv))
 -              return;
 -
        mutex_lock(&priv->mutex);
  
 +      if (!iwl_legacy_is_alive(priv)) {
 +              mutex_unlock(&priv->mutex);
 +              return;
 +      }
 +
        if (changes & BSS_CHANGED_QOS) {
                unsigned long flags;
  
@@@ -2644,7 -2653,7 +2651,7 @@@ unplugged
  
  none:
        /* re-enable interrupts here since we don't have anything to service. */
 -      /* only Re-enable if diabled by irq */
 +      /* only Re-enable if disabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
                iwl_legacy_enable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
@@@ -134,7 -134,7 +134,7 @@@ struct iwl_queue 
                                * space more than this */
        int high_mark;         /* high watermark, stop queue if free
                                * space less than this */
 -} __packed;
 +};
  
  /* One for each TFD */
  struct iwl_tx_info {
@@@ -290,7 -290,6 +290,7 @@@ enum 
        CMD_SIZE_HUGE = (1 << 0),
        CMD_ASYNC = (1 << 1),
        CMD_WANT_SKB = (1 << 2),
 +      CMD_MAPPED = (1 << 3),
  };
  
  #define DEF_CMD_PAYLOAD_SIZE 320
@@@ -1077,6 -1076,7 +1077,6 @@@ struct iwl_priv 
        spinlock_t hcmd_lock;   /* protect hcmd */
        spinlock_t reg_lock;    /* protect hw register access */
        struct mutex mutex;
 -      struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
  
        /* basic pci-network driver stuff */
        struct pci_dev *pci_dev;
@@@ -1411,6 -1411,12 +1411,12 @@@ iwl_legacy_is_channel_passive(const str
        return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0;
  }
  
+ static inline int
+ iwl_legacy_is_channel_ibss(const struct iwl_channel_info *ch)
+ {
+       return (ch->flags & EEPROM_CHANNEL_IBSS) ? 1 : 0;
+ }
  static inline void
  __iwl_legacy_free_pages(struct iwl_priv *priv, struct page *page)
  {
@@@ -1,7 -1,7 +1,7 @@@
 -/**
 -  * This file contains the handling of command.
 -  * It prepares command and sends it to firmware when it is ready.
 -  */
 +/*
 + * This file contains the handling of command.
 + * It prepares command and sends it to firmware when it is ready.
 + */
  
  #include <linux/kfifo.h>
  #include <linux/sched.h>
  #define CAL_RSSI(snr, nf)     ((s32)((s32)(snr) + CAL_NF(nf)))
  
  /**
 - *  @brief Simple callback that copies response back into command
 + * lbs_cmd_copyback - Simple callback that copies response back into command
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param extra      A pointer to the original command structure for which
 - *                      'resp' is a response
 - *  @param resp         A pointer to the command response
 + * @priv:     A pointer to &struct lbs_private structure
 + * @extra:    A pointer to the original command structure for which
 + *            'resp' is a response
 + * @resp:     A pointer to the command response
   *
 - *  @return           0 on success, error on failure
 + * returns:   0 on success, error on failure
   */
  int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
                     struct cmd_header *resp)
  EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
  
  /**
 - *  @brief Simple callback that ignores the result. Use this if
 - *  you just want to send a command to the hardware, but don't
 + *  lbs_cmd_async_callback - Simple callback that ignores the result.
 + *  Use this if you just want to send a command to the hardware, but don't
   *  care for the result.
   *
 - *  @param priv         ignored
 - *  @param extra        ignored
 - *  @param resp         ignored
 + *  @priv:    ignored
 + *  @extra:   ignored
 + *  @resp:    ignored
   *
 - *  @return           0 for success
 + *  returns:  0 for success
   */
  static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
                     struct cmd_header *resp)
  
  
  /**
 - *  @brief Checks whether a command is allowed in Power Save mode
 + *  is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
 + *
 + *  @cmd:     the command ID
   *
 - *  @param command the command ID
 - *  @return      1 if allowed, 0 if not allowed
 + *  returns:  1 if allowed, 0 if not allowed
   */
  static u8 is_command_allowed_in_ps(u16 cmd)
  {
  }
  
  /**
 - *  @brief Updates the hardware details like MAC address and regulatory region
 + *  lbs_update_hw_spec - Updates the hardware details like MAC address
 + *  and regulatory region
   *
 - *  @param priv       A pointer to struct lbs_private structure
 + *  @priv:    A pointer to &struct lbs_private structure
   *
 - *  @return           0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_update_hw_spec(struct lbs_private *priv)
  {
         * CF card    firmware 5.0.16p0:   cap 0x00000303
         * USB dongle firmware 5.110.17p2: cap 0x00000303
         */
 -      lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
 +      netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
                cmd.permanentaddr,
                priv->fwrelease >> 24 & 0xff,
                priv->fwrelease >> 16 & 0xff,
        /* if it's unidentified region code, use the default (USA) */
        if (i >= MRVDRV_MAX_REGION_CODE) {
                priv->regioncode = 0x10;
 -              lbs_pr_info("unidentified region code; using the default (USA)\n");
 +              netdev_info(priv->dev,
 +                          "unidentified region code; using the default (USA)\n");
        }
  
        if (priv->current_addr[0] == 0xff)
@@@ -212,7 -209,7 +212,7 @@@ int lbs_host_sleep_cfg(struct lbs_priva
                                        (uint8_t *)&cmd_config.wol_conf,
                                        sizeof(struct wol_config));
        } else {
 -              lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
 +              netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
        }
  
        return ret;
  EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
  
  /**
 - *  @brief Sets the Power Save mode
 + *  lbs_set_ps_mode - Sets the Power Save mode
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
   *                         PS_MODE_ACTION_EXIT_PS)
 - *  @param block      Whether to block on a response or not
 + *  @block:   Whether to block on a response or not
   *
 - *  @return           0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
  {
@@@ -315,7 -312,7 +315,7 @@@ static int lbs_wait_for_ds_awake(struc
        if (priv->is_deep_sleep) {
                if (!wait_event_interruptible_timeout(priv->ds_awake_q,
                                        !priv->is_deep_sleep, (10 * HZ))) {
 -                      lbs_pr_err("ds_awake_q: timer expired\n");
 +                      netdev_err(priv->dev, "ds_awake_q: timer expired\n");
                        ret = -1;
                }
        }
@@@ -340,7 -337,7 +340,7 @@@ int lbs_set_deep_sleep(struct lbs_priva
                                netif_carrier_off(priv->dev);
                        }
                } else {
 -                      lbs_pr_err("deep sleep: already enabled\n");
 +                      netdev_err(priv->dev, "deep sleep: already enabled\n");
                }
        } else {
                if (priv->is_deep_sleep) {
                        if (!ret) {
                                ret = lbs_wait_for_ds_awake(priv);
                                if (ret)
 -                                      lbs_pr_err("deep sleep: wakeup"
 -                                                      "failed\n");
 +                                      netdev_err(priv->dev,
 +                                                 "deep sleep: wakeup failed\n");
                        }
                }
        }
@@@ -385,9 -382,8 +385,9 @@@ int lbs_set_host_sleep(struct lbs_priva
                        ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
                                        (struct wol_config *)NULL);
                        if (ret) {
 -                              lbs_pr_info("Host sleep configuration failed: "
 -                                              "%d\n", ret);
 +                              netdev_info(priv->dev,
 +                                          "Host sleep configuration failed: %d\n",
 +                                          ret);
                                return ret;
                        }
                        if (priv->psstate == PS_STATE_FULL_POWER) {
                                                sizeof(cmd),
                                                lbs_ret_host_sleep_activate, 0);
                                if (ret)
 -                                      lbs_pr_info("HOST_SLEEP_ACTIVATE "
 -                                                      "failed: %d\n", ret);
 +                                      netdev_info(priv->dev,
 +                                                  "HOST_SLEEP_ACTIVATE failed: %d\n",
 +                                                  ret);
                        }
  
                        if (!wait_event_interruptible_timeout(
                                                priv->host_sleep_q,
                                                priv->is_host_sleep_activated,
                                                (10 * HZ))) {
 -                              lbs_pr_err("host_sleep_q: timer expired\n");
 +                              netdev_err(priv->dev,
 +                                         "host_sleep_q: timer expired\n");
                                ret = -1;
                        }
                } else {
 -                      lbs_pr_err("host sleep: already enabled\n");
 +                      netdev_err(priv->dev, "host sleep: already enabled\n");
                }
        } else {
                if (priv->is_host_sleep_activated)
  }
  
  /**
 - *  @brief Set an SNMP MIB value
 + *  lbs_set_snmp_mib - Set an SNMP MIB value
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param oid        The OID to set in the firmware
 - *  @param val        Value to set the OID to
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @oid:     The OID to set in the firmware
 + *  @val:     Value to set the OID to
   *
 - *  @return           0 on success, error on failure
 + *  returns:          0 on success, error on failure
   */
  int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
  {
@@@ -473,13 -467,13 +473,13 @@@ out
  }
  
  /**
 - *  @brief Get an SNMP MIB value
 + *  lbs_get_snmp_mib - Get an SNMP MIB value
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param oid        The OID to retrieve from the firmware
 - *  @param out_val    Location for the returned value
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @oid:     The OID to retrieve from the firmware
 + *  @out_val: Location for the returned value
   *
 - *  @return           0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
  {
@@@ -516,14 -510,14 +516,14 @@@ out
  }
  
  /**
 - *  @brief Get the min, max, and current TX power
 + *  lbs_get_tx_power - Get the min, max, and current TX power
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param curlevel   Current power level in dBm
 - *  @param minlevel   Minimum supported power level in dBm (optional)
 - *  @param maxlevel   Maximum supported power level in dBm (optional)
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @curlevel:        Current power level in dBm
 + *  @minlevel:        Minimum supported power level in dBm (optional)
 + *  @maxlevel:        Maximum supported power level in dBm (optional)
   *
 - *  @return           0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
                     s16 *maxlevel)
  }
  
  /**
 - *  @brief Set the TX power
 + *  lbs_set_tx_power - Set the TX power
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param dbm        The desired power level in dBm
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @dbm:     The desired power level in dBm
   *
 - *  @return           0 on success, error on failure
 + *  returns:          0 on success, error on failure
   */
  int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
  {
  }
  
  /**
 - *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
 + *  lbs_set_monitor_mode - Enable or disable monitor mode
 + *  (only implemented on OLPC usb8388 FW)
   *
 - *  @param priv        A pointer to struct lbs_private structure
 - *  @param enable      1 to enable monitor mode, 0 to disable
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @enable:  1 to enable monitor mode, 0 to disable
   *
 - *  @return            0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
  {
  }
  
  /**
 - *  @brief Get the radio channel
 + *  lbs_get_channel - Get the radio channel
   *
 - *  @param priv       A pointer to struct lbs_private structure
 + *  @priv:    A pointer to &struct lbs_private structure
   *
 - *  @return           The channel on success, error on failure
 + *  returns:  The channel on success, error on failure
   */
  static int lbs_get_channel(struct lbs_private *priv)
  {
@@@ -657,12 -650,12 +657,12 @@@ int lbs_update_channel(struct lbs_priva
  }
  
  /**
 - *  @brief Set the radio channel
 + *  lbs_set_channel - Set the radio channel
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param channel    The desired channel, or 0 to clear a locked channel
 + *  @priv:    A pointer to &struct lbs_private structure
 + *  @channel: The desired channel, or 0 to clear a locked channel
   *
 - *  @return           0 on success, error on failure
 + *  returns:  0 on success, error on failure
   */
  int lbs_set_channel(struct lbs_private *priv, u8 channel)
  {
@@@ -693,13 -686,12 +693,13 @@@ out
  }
  
  /**
 - *  @brief Get current RSSI and noise floor
 + * lbs_get_rssi - Get current RSSI and noise floor
   *
 - *  @param priv               A pointer to struct lbs_private structure
 - *  @param rssi               On successful return, signal level in mBm
 + * @priv:     A pointer to &struct lbs_private structure
 + * @rssi:     On successful return, signal level in mBm
 + * @nf:               On successful return, Noise floor
   *
 - *  @return           The channel on success, error on failure
 + * returns:   The channel on success, error on failure
   */
  int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
  {
  }
  
  /**
 - *  @brief Send regulatory and 802.11d domain information to the firmware
 + *  lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
 + *  to the firmware
   *
 - *  @param priv               pointer to struct lbs_private
 - *  @param request    cfg80211 regulatory request structure
 - *  @param bands      the device's supported bands and channels
 + *  @priv:    pointer to &struct lbs_private
 + *  @request: cfg80211 regulatory request structure
 + *  @bands:   the device's supported bands and channels
   *
 - *  @return           0 on success, error code on failure
 + *  returns:  0 on success, error code on failure
  */
  int lbs_set_11d_domain_info(struct lbs_private *priv,
                            struct regulatory_request *request,
  }
  
  /**
 - *  @brief Read a MAC, Baseband, or RF register
 + *  lbs_get_reg - Read a MAC, Baseband, or RF register
   *
 - *  @param priv               pointer to struct lbs_private
 - *  @param cmd                register command, one of CMD_MAC_REG_ACCESS,
 - *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
 - *  @param offset       byte offset of the register to get
 - *  @param value        on success, the value of the register at 'offset'
 + *  @priv:    pointer to &struct lbs_private
 + *  @reg:     register command, one of CMD_MAC_REG_ACCESS,
 + *            CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
 + *  @offset:  byte offset of the register to get
 + *  @value:   on success, the value of the register at 'offset'
   *
 - *  @return           0 on success, error code on failure
 + *  returns:  0 on success, error code on failure
  */
  int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
  {
@@@ -895,15 -886,15 +895,15 @@@ out
  }
  
  /**
 - *  @brief Write a MAC, Baseband, or RF register
 + *  lbs_set_reg - Write a MAC, Baseband, or RF register
   *
 - *  @param priv               pointer to struct lbs_private
 - *  @param cmd                register command, one of CMD_MAC_REG_ACCESS,
 - *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
 - *  @param offset       byte offset of the register to set
 - *  @param value        the value to write to the register at 'offset'
 + *  @priv:    pointer to &struct lbs_private
 + *  @reg:     register command, one of CMD_MAC_REG_ACCESS,
 + *            CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
 + *  @offset:  byte offset of the register to set
 + *  @value:   the value to write to the register at 'offset'
   *
 - *  @return           0 on success, error code on failure
 + *  returns:  0 on success, error code on failure
  */
  int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
  {
@@@ -1011,8 -1002,7 +1011,8 @@@ static void lbs_submit_command(struct l
        ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
  
        if (ret) {
 -              lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
 +              netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
 +                          ret);
                /* Let the timer kick in and retry, and potentially reset
                   the whole thing if the condition persists */
                timeo = HZ/4;
        lbs_deb_leave(LBS_DEB_HOST);
  }
  
 -/**
 +/*
   *  This function inserts command node to cmdfreeq
   *  after cleans it. Requires priv->driver_lock held.
   */
@@@ -1135,12 -1125,11 +1135,12 @@@ void lbs_set_mac_control(struct lbs_pri
  }
  
  /**
 - *  @brief This function allocates the command buffer and link
 - *  it to command free queue.
 + *  lbs_allocate_cmd_buffer - allocates the command buffer and links
 + *  it to command free queue
 + *
 + *  @priv:    A pointer to &struct lbs_private structure
   *
 - *  @param priv               A pointer to struct lbs_private structure
 - *  @return           0 or -1
 + *  returns:  0 for success or -1 on error
   */
  int lbs_allocate_cmd_buffer(struct lbs_private *priv)
  {
@@@ -1182,11 -1171,10 +1182,11 @@@ done
  }
  
  /**
 - *  @brief This function frees the command buffer.
 + *  lbs_free_cmd_buffer - free the command buffer
   *
 - *  @param priv               A pointer to struct lbs_private structure
 - *  @return           0 or -1
 + *  @priv:    A pointer to &struct lbs_private structure
 + *
 + *  returns:  0 for success
   */
  int lbs_free_cmd_buffer(struct lbs_private *priv)
  {
@@@ -1223,13 -1211,11 +1223,13 @@@ done
  }
  
  /**
 - *  @brief This function gets a free command node if available in
 - *  command free queue.
 + *  lbs_get_free_cmd_node - gets a free command node if available in
 + *  command free queue
 + *
 + *  @priv:    A pointer to &struct lbs_private structure
   *
 - *  @param priv               A pointer to struct lbs_private structure
 - *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
 + *  returns:  A pointer to &cmd_ctrl_node structure on success
 + *            or %NULL on error
   */
  static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
  {
  }
  
  /**
 - *  @brief This function executes next command in command
 - *  pending queue. It will put firmware back to PS mode
 - *  if applicable.
 + *  lbs_execute_next_command - execute next command in command
 + *  pending queue. Will put firmware back to PS mode if applicable.
   *
 - *  @param priv     A pointer to struct lbs_private structure
 - *  @return      0 or -1
 + *  @priv:    A pointer to &struct lbs_private structure
 + *
 + *  returns:  0 on success or -1 on error
   */
  int lbs_execute_next_command(struct lbs_private *priv)
  {
        spin_lock_irqsave(&priv->driver_lock, flags);
  
        if (priv->cur_cmd) {
 -              lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
 +              netdev_alert(priv->dev,
 +                           "EXEC_NEXT_CMD: already processing command!\n");
                spin_unlock_irqrestore(&priv->driver_lock, flags);
                ret = -1;
                goto done;
                                    cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
-                                       list_del(&cmdnode->list);
                                        spin_lock_irqsave(&priv->driver_lock, flags);
+                                       list_del(&cmdnode->list);
                                        lbs_complete_command(priv, cmdnode, 0);
                                        spin_unlock_irqrestore(&priv->driver_lock, flags);
  
                                    (priv->psstate == PS_STATE_PRE_SLEEP)) {
                                        lbs_deb_host(
                                               "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
-                                       list_del(&cmdnode->list);
                                        spin_lock_irqsave(&priv->driver_lock, flags);
+                                       list_del(&cmdnode->list);
                                        lbs_complete_command(priv, cmdnode, 0);
                                        spin_unlock_irqrestore(&priv->driver_lock, flags);
                                        priv->needtowakeup = 1;
                                       "EXEC_NEXT_CMD: sending EXIT_PS\n");
                        }
                }
+               spin_lock_irqsave(&priv->driver_lock, flags);
                list_del(&cmdnode->list);
+               spin_unlock_irqrestore(&priv->driver_lock, flags);
                lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
                            le16_to_cpu(cmd->command));
                lbs_submit_command(priv, cmdnode);
@@@ -1444,7 -1431,7 +1446,7 @@@ static void lbs_send_confirmsleep(struc
        ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
                sizeof(confirm_sleep));
        if (ret) {
 -              lbs_pr_alert("confirm_sleep failed\n");
 +              netdev_alert(priv->dev, "confirm_sleep failed\n");
                goto out;
        }
  
  }
  
  /**
 - *  @brief This function checks condition and prepares to
 - *  send sleep confirm command to firmware if ok.
 + * lbs_ps_confirm_sleep - checks condition and prepares to
 + * send sleep confirm command to firmware if ok
 + *
 + * @priv:     A pointer to &struct lbs_private structure
   *
 - *  @param priv       A pointer to struct lbs_private structure
 - *  @param psmode     Power Saving mode
 - *  @return           n/a
 + * returns:   n/a
   */
  void lbs_ps_confirm_sleep(struct lbs_private *priv)
  {
  
  
  /**
 - * @brief Configures the transmission power control functionality.
 + * lbs_set_tpc_cfg - Configures the transmission power control functionality
   *
 - * @param priv                A pointer to struct lbs_private structure
 - * @param enable      Transmission power control enable
 - * @param p0          Power level when link quality is good (dBm).
 - * @param p1          Power level when link quality is fair (dBm).
 - * @param p2          Power level when link quality is poor (dBm).
 - * @param usesnr      Use Signal to Noise Ratio in TPC
 + * @priv:     A pointer to &struct lbs_private structure
 + * @enable:   Transmission power control enable
 + * @p0:               Power level when link quality is good (dBm).
 + * @p1:               Power level when link quality is fair (dBm).
 + * @p2:               Power level when link quality is poor (dBm).
 + * @usesnr:   Use Signal to Noise Ratio in TPC
   *
 - * @return 0 on success
 + * returns:   0 on success
   */
  int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
                int8_t p2, int usesnr)
  }
  
  /**
 - * @brief Configures the power adaptation settings.
 + * lbs_set_power_adapt_cfg - Configures the power adaptation settings
   *
 - * @param priv                A pointer to struct lbs_private structure
 - * @param enable      Power adaptation enable
 - * @param p0          Power level for 1, 2, 5.5 and 11 Mbps (dBm).
 - * @param p1          Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
 - * @param p2          Power level for 48 and 54 Mbps (dBm).
 + * @priv:     A pointer to &struct lbs_private structure
 + * @enable:   Power adaptation enable
 + * @p0:               Power level for 1, 2, 5.5 and 11 Mbps (dBm).
 + * @p1:               Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
 + * @p2:               Power level for 48 and 54 Mbps (dBm).
   *
 - * @return 0 on Success
 + * returns:   0 on Success
   */
  
  int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
@@@ -1670,7 -1657,7 +1672,7 @@@ int __lbs_cmd(struct lbs_private *priv
        spin_lock_irqsave(&priv->driver_lock, flags);
        ret = cmdnode->result;
        if (ret)
 -              lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
 +              netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
                            command, ret);
  
        __lbs_cleanup_and_insert_cmd(priv, cmdnode);
@@@ -219,7 -219,7 +219,7 @@@ static inline void nf_bridge_update_pro
  static int br_parse_ip_options(struct sk_buff *skb)
  {
        struct ip_options *opt;
 -      struct iphdr *iph;
 +      const struct iphdr *iph;
        struct net_device *dev = skb->dev;
        u32 len;
  
@@@ -554,7 -554,7 +554,7 @@@ static unsigned int br_nf_pre_routing_i
                                           const struct net_device *out,
                                           int (*okfn)(struct sk_buff *))
  {
 -      struct ipv6hdr *hdr;
 +      const struct ipv6hdr *hdr;
        u32 pkt_len;
  
        if (skb->len < sizeof(struct ipv6hdr))
@@@ -737,7 -737,7 +737,7 @@@ static unsigned int br_nf_forward_ip(un
                nf_bridge->mask |= BRNF_PKT_TYPE;
        }
  
-       if (br_parse_ip_options(skb))
+       if (pf == PF_INET && br_parse_ip_options(skb))
                return NF_DROP;
  
        /* The physdev module checks on this */
diff --combined net/core/dev.c
@@@ -948,7 -948,7 +948,7 @@@ int dev_alloc_name(struct net_device *d
  }
  EXPORT_SYMBOL(dev_alloc_name);
  
 -static int dev_get_valid_name(struct net_device *dev, const char *name, bool fmt)
 +static int dev_get_valid_name(struct net_device *dev, const char *name)
  {
        struct net *net;
  
        if (!dev_valid_name(name))
                return -EINVAL;
  
 -      if (fmt && strchr(name, '%'))
 +      if (strchr(name, '%'))
                return dev_alloc_name(dev, name);
        else if (__dev_get_by_name(net, name))
                return -EEXIST;
@@@ -995,7 -995,7 +995,7 @@@ int dev_change_name(struct net_device *
  
        memcpy(oldname, dev->name, IFNAMSIZ);
  
 -      err = dev_get_valid_name(dev, newname, 1);
 +      err = dev_get_valid_name(dev, newname);
        if (err < 0)
                return err;
  
@@@ -1007,7 -1007,7 +1007,7 @@@ rollback
        }
  
        write_lock_bh(&dev_base_lock);
-       hlist_del(&dev->name_hlist);
+       hlist_del_rcu(&dev->name_hlist);
        write_unlock_bh(&dev_base_lock);
  
        synchronize_rcu();
@@@ -1317,8 -1317,7 +1317,8 @@@ void dev_disable_lro(struct net_device 
                return;
  
        __ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);
 -      WARN_ON(dev->features & NETIF_F_LRO);
 +      if (unlikely(dev->features & NETIF_F_LRO))
 +              netdev_WARN(dev, "failed to disable LRO!\n");
  }
  EXPORT_SYMBOL(dev_disable_lro);
  
@@@ -2505,8 -2504,8 +2505,8 @@@ static inline void ____napi_schedule(st
  __u32 __skb_get_rxhash(struct sk_buff *skb)
  {
        int nhoff, hash = 0, poff;
 -      struct ipv6hdr *ip6;
 -      struct iphdr *ip;
 +      const struct ipv6hdr *ip6;
 +      const struct iphdr *ip;
        u8 ip_proto;
        u32 addr1, addr2, ihl;
        union {
                if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
                        goto done;
  
 -              ip = (struct iphdr *) (skb->data + nhoff);
 +              ip = (const struct iphdr *) (skb->data + nhoff);
                if (ip->frag_off & htons(IP_MF | IP_OFFSET))
                        ip_proto = 0;
                else
                if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
                        goto done;
  
 -              ip6 = (struct ipv6hdr *) (skb->data + nhoff);
 +              ip6 = (const struct ipv6hdr *) (skb->data + nhoff);
                ip_proto = ip6->nexthdr;
                addr1 = (__force u32) ip6->saddr.s6_addr32[3];
                addr2 = (__force u32) ip6->daddr.s6_addr32[3];
@@@ -3079,6 -3078,25 +3079,6 @@@ void netdev_rx_handler_unregister(struc
  }
  EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
  
 -static void vlan_on_bond_hook(struct sk_buff *skb)
 -{
 -      /*
 -       * Make sure ARP frames received on VLAN interfaces stacked on
 -       * bonding interfaces still make their way to any base bonding
 -       * device that may have registered for a specific ptype.
 -       */
 -      if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
 -          vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
 -          skb->protocol == htons(ETH_P_ARP)) {
 -              struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 -
 -              if (!skb2)
 -                      return;
 -              skb2->dev = vlan_dev_real_dev(skb->dev);
 -              netif_rx(skb2);
 -      }
 -}
 -
  static int __netif_receive_skb(struct sk_buff *skb)
  {
        struct packet_type *ptype, *pt_prev;
@@@ -3114,12 -3132,6 +3114,12 @@@ another_round
  
        __this_cpu_inc(softnet_data.processed);
  
 +      if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
 +              skb = vlan_untag(skb);
 +              if (unlikely(!skb))
 +                      goto out;
 +      }
 +
  #ifdef CONFIG_NET_CLS_ACT
        if (skb->tc_verd & TC_NCLS) {
                skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
@@@ -3167,13 -3179,15 +3167,13 @@@ ncls
                        ret = deliver_skb(skb, pt_prev, orig_dev);
                        pt_prev = NULL;
                }
 -              if (vlan_hwaccel_do_receive(&skb)) {
 +              if (vlan_do_receive(&skb)) {
                        ret = __netif_receive_skb(skb);
                        goto out;
                } else if (unlikely(!skb))
                        goto out;
        }
  
 -      vlan_on_bond_hook(skb);
 -
        /* deliver only exact match when indicated */
        null_or_dev = deliver_exact ? skb->dev : NULL;
  
@@@ -4498,30 -4512,6 +4498,30 @@@ void dev_set_rx_mode(struct net_device 
  }
  
  /**
 + *    dev_ethtool_get_settings - call device's ethtool_ops::get_settings()
 + *    @dev: device
 + *    @cmd: memory area for ethtool_ops::get_settings() result
 + *
 + *      The cmd arg is initialized properly (cleared and
 + *      ethtool_cmd::cmd field set to ETHTOOL_GSET).
 + *
 + *    Return device's ethtool_ops::get_settings() result value or
 + *    -EOPNOTSUPP when device doesn't expose
 + *    ethtool_ops::get_settings() operation.
 + */
 +int dev_ethtool_get_settings(struct net_device *dev,
 +                           struct ethtool_cmd *cmd)
 +{
 +      if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
 +              return -EOPNOTSUPP;
 +
 +      memset(cmd, 0, sizeof(struct ethtool_cmd));
 +      cmd->cmd = ETHTOOL_GSET;
 +      return dev->ethtool_ops->get_settings(dev, cmd);
 +}
 +EXPORT_SYMBOL(dev_ethtool_get_settings);
 +
 +/**
   *    dev_get_flags - get flags reported to userspace
   *    @dev: device
   *
@@@ -5196,27 -5186,27 +5196,27 @@@ u32 netdev_fix_features(struct net_devi
        /* Fix illegal checksum combinations */
        if ((features & NETIF_F_HW_CSUM) &&
            (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
-               netdev_info(dev, "mixed HW and IP checksum settings.\n");
+               netdev_warn(dev, "mixed HW and IP checksum settings.\n");
                features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
        }
  
        if ((features & NETIF_F_NO_CSUM) &&
            (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
-               netdev_info(dev, "mixed no checksumming and other settings.\n");
+               netdev_warn(dev, "mixed no checksumming and other settings.\n");
                features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM);
        }
  
        /* Fix illegal SG+CSUM combinations. */
        if ((features & NETIF_F_SG) &&
            !(features & NETIF_F_ALL_CSUM)) {
-               netdev_info(dev,
-                           "Dropping NETIF_F_SG since no checksum feature.\n");
+               netdev_dbg(dev,
+                       "Dropping NETIF_F_SG since no checksum feature.\n");
                features &= ~NETIF_F_SG;
        }
  
        /* TSO requires that SG is present as well. */
        if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) {
-               netdev_info(dev, "Dropping TSO features since no SG feature.\n");
+               netdev_dbg(dev, "Dropping TSO features since no SG feature.\n");
                features &= ~NETIF_F_ALL_TSO;
        }
  
  
        /* Software GSO depends on SG. */
        if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) {
-               netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n");
+               netdev_dbg(dev, "Dropping NETIF_F_GSO since no SG feature.\n");
                features &= ~NETIF_F_GSO;
        }
  
                if (!((features & NETIF_F_GEN_CSUM) ||
                    (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))
                            == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) {
-                       netdev_info(dev,
+                       netdev_dbg(dev,
                                "Dropping NETIF_F_UFO since no checksum offload features.\n");
                        features &= ~NETIF_F_UFO;
                }
  
                if (!(features & NETIF_F_SG)) {
-                       netdev_info(dev,
+                       netdev_dbg(dev,
                                "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n");
                        features &= ~NETIF_F_UFO;
                }
  }
  EXPORT_SYMBOL(netdev_fix_features);
  
 -void netdev_update_features(struct net_device *dev)
 +int __netdev_update_features(struct net_device *dev)
  {
        u32 features;
        int err = 0;
  
 +      ASSERT_RTNL();
 +
        features = netdev_get_wanted_features(dev);
  
        if (dev->netdev_ops->ndo_fix_features)
        features = netdev_fix_features(dev, features);
  
        if (dev->features == features)
 -              return;
 +              return 0;
  
-       netdev_info(dev, "Features changed: 0x%08x -> 0x%08x\n",
+       netdev_dbg(dev, "Features changed: 0x%08x -> 0x%08x\n",
                dev->features, features);
  
        if (dev->netdev_ops->ndo_set_features)
                err = dev->netdev_ops->ndo_set_features(dev, features);
  
 -      if (!err)
 -              dev->features = features;
 -      else if (err < 0)
 +      if (unlikely(err < 0)) {
                netdev_err(dev,
                        "set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
                        err, features, dev->features);
 +              return -1;
 +      }
 +
 +      if (!err)
 +              dev->features = features;
 +
 +      return 1;
 +}
 +
 +/**
 + *    netdev_update_features - recalculate device features
 + *    @dev: the device to check
 + *
 + *    Recalculate dev->features set and send notifications if it
 + *    has changed. Should be called after driver or hardware dependent
 + *    conditions might have changed that influence the features.
 + */
 +void netdev_update_features(struct net_device *dev)
 +{
 +      if (__netdev_update_features(dev))
 +              netdev_features_change(dev);
  }
  EXPORT_SYMBOL(netdev_update_features);
  
  /**
 + *    netdev_change_features - recalculate device features
 + *    @dev: the device to check
 + *
 + *    Recalculate dev->features set and send notifications even
 + *    if they have not changed. Should be called instead of
 + *    netdev_update_features() if also dev->vlan_features might
 + *    have changed to allow the changes to be propagated to stacked
 + *    VLAN devices.
 + */
 +void netdev_change_features(struct net_device *dev)
 +{
 +      __netdev_update_features(dev);
 +      netdev_features_change(dev);
 +}
 +EXPORT_SYMBOL(netdev_change_features);
 +
 +/**
   *    netif_stacked_transfer_operstate -      transfer operstate
   *    @rootdev: the root or lower level device to transfer state from
   *    @dev: the device to transfer operstate to
@@@ -5437,10 -5389,6 +5437,10 @@@ int register_netdevice(struct net_devic
  
        dev->iflink = -1;
  
 +      ret = dev_get_valid_name(dev, dev->name);
 +      if (ret < 0)
 +              goto out;
 +
        /* Init, if this function is available */
        if (dev->netdev_ops->ndo_init) {
                ret = dev->netdev_ops->ndo_init(dev);
                }
        }
  
 -      ret = dev_get_valid_name(dev, dev->name, 0);
 -      if (ret)
 -              goto err_uninit;
 -
        dev->ifindex = dev_new_index(net);
        if (dev->iflink == -1)
                dev->iflink = dev->ifindex;
        dev->features |= NETIF_F_SOFT_FEATURES;
        dev->wanted_features = dev->features & dev->hw_features;
  
-       /* Avoid warning from netdev_fix_features() for GSO without SG */
-       if (!(dev->wanted_features & NETIF_F_SG)) {
-               dev->wanted_features &= ~NETIF_F_GSO;
-               dev->features &= ~NETIF_F_GSO;
-       }
 +      /* Turn on no cache copy if HW is doing checksum */
 +      dev->hw_features |= NETIF_F_NOCACHE_COPY;
 +      if ((dev->features & NETIF_F_ALL_CSUM) &&
 +          !(dev->features & NETIF_F_NO_CSUM)) {
 +              dev->wanted_features |= NETIF_F_NOCACHE_COPY;
 +              dev->features |= NETIF_F_NOCACHE_COPY;
 +      }
 +
        /* Enable GRO and NETIF_F_HIGHDMA for vlans by default,
         * vlan_dev_init() will do the dev->features check, so these features
         * are enabled only if supported by underlying device.
                goto err_uninit;
        dev->reg_state = NETREG_REGISTERED;
  
 -      netdev_update_features(dev);
 +      __netdev_update_features(dev);
  
        /*
         *      Default initial state at registry is that the
@@@ -5589,7 -5527,19 +5583,7 @@@ int register_netdev(struct net_device *
        int err;
  
        rtnl_lock();
 -
 -      /*
 -       * If the name is a format string the caller wants us to do a
 -       * name allocation.
 -       */
 -      if (strchr(dev->name, '%')) {
 -              err = dev_alloc_name(dev, dev->name);
 -              if (err < 0)
 -                      goto out;
 -      }
 -
        err = register_netdevice(dev);
 -out:
        rtnl_unlock();
        return err;
  }
@@@ -6071,7 -6021,7 +6065,7 @@@ int dev_change_net_namespace(struct net
                /* We get here if we can't use the current device name */
                if (!pat)
                        goto out;
 -              if (dev_get_valid_name(dev, pat, 1))
 +              if (dev_get_valid_name(dev, pat) < 0)
                        goto out;
        }
  
@@@ -6203,20 -6153,29 +6197,20 @@@ static int dev_cpu_callback(struct noti
   */
  u32 netdev_increment_features(u32 all, u32 one, u32 mask)
  {
 -      /* If device needs checksumming, downgrade to it. */
 -      if (all & NETIF_F_NO_CSUM && !(one & NETIF_F_NO_CSUM))
 -              all ^= NETIF_F_NO_CSUM | (one & NETIF_F_ALL_CSUM);
 -      else if (mask & NETIF_F_ALL_CSUM) {
 -              /* If one device supports v4/v6 checksumming, set for all. */
 -              if (one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM) &&
 -                  !(all & NETIF_F_GEN_CSUM)) {
 -                      all &= ~NETIF_F_ALL_CSUM;
 -                      all |= one & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 -              }
 +      if (mask & NETIF_F_GEN_CSUM)
 +              mask |= NETIF_F_ALL_CSUM;
 +      mask |= NETIF_F_VLAN_CHALLENGED;
  
 -              /* If one device supports hw checksumming, set for all. */
 -              if (one & NETIF_F_GEN_CSUM && !(all & NETIF_F_GEN_CSUM)) {
 -                      all &= ~NETIF_F_ALL_CSUM;
 -                      all |= NETIF_F_HW_CSUM;
 -              }
 -      }
 +      all |= one & (NETIF_F_ONE_FOR_ALL|NETIF_F_ALL_CSUM) & mask;
 +      all &= one | ~NETIF_F_ALL_FOR_ALL;
  
 -      one |= NETIF_F_ALL_CSUM;
 +      /* If device needs checksumming, downgrade to it. */
 +      if (all & (NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM))
 +              all &= ~NETIF_F_NO_CSUM;
  
 -      one |= all & NETIF_F_ONE_FOR_ALL;
 -      all &= one | NETIF_F_LLTX | NETIF_F_GSO | NETIF_F_UFO;
 -      all |= one & mask & NETIF_F_ONE_FOR_ALL;
 +      /* If one device supports hw checksumming, set for all. */
 +      if (all & NETIF_F_GEN_CSUM)
 +              all &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_GEN_CSUM);
  
        return all;
  }
diff --combined net/core/ethtool.c
@@@ -21,8 -21,6 +21,8 @@@
  #include <linux/uaccess.h>
  #include <linux/vmalloc.h>
  #include <linux/slab.h>
 +#include <linux/rtnetlink.h>
 +#include <linux/sched.h>
  
  /*
   * Some useful ethtool_ops methods that're device independent.
@@@ -319,7 -317,7 +319,7 @@@ static int ethtool_set_features(struct 
  
        dev->wanted_features &= ~features[0].valid;
        dev->wanted_features |= features[0].valid & features[0].requested;
 -      netdev_update_features(dev);
 +      __netdev_update_features(dev);
  
        if ((dev->wanted_features ^ dev->features) & features[0].valid)
                ret |= ETHTOOL_F_WISH;
@@@ -332,7 -330,7 +332,7 @@@ static const char netdev_features_strin
        /* NETIF_F_IP_CSUM */         "tx-checksum-ipv4",
        /* NETIF_F_NO_CSUM */         "tx-checksum-unneeded",
        /* NETIF_F_HW_CSUM */         "tx-checksum-ip-generic",
-       /* NETIF_F_IPV6_CSUM */       "tx_checksum-ipv6",
+       /* NETIF_F_IPV6_CSUM */       "tx-checksum-ipv6",
        /* NETIF_F_HIGHDMA */         "highdma",
        /* NETIF_F_FRAGLIST */        "tx-scatter-gather-fraglist",
        /* NETIF_F_HW_VLAN_TX */      "tx-vlan-hw-insert",
        /* NETIF_F_NTUPLE */          "rx-ntuple-filter",
        /* NETIF_F_RXHASH */          "rx-hashing",
        /* NETIF_F_RXCSUM */          "rx-checksum",
 -      "",
 -      "",
 +      /* NETIF_F_NOCACHE_COPY */    "tx-nocache-copy",
 +      /* NETIF_F_LOOPBACK */        "loopback",
  };
  
  static int __ethtool_get_sset_count(struct net_device *dev, int sset)
@@@ -501,7 -499,7 +501,7 @@@ static int ethtool_set_one_feature(stru
                else
                        dev->wanted_features &= ~mask;
  
 -              netdev_update_features(dev);
 +              __netdev_update_features(dev);
                return 0;
        }
  
@@@ -546,14 -544,14 +546,14 @@@ int __ethtool_set_flags(struct net_devi
        }
  
        /* allow changing only bits set in hw_features */
 -      changed = (data ^ dev->wanted_features) & flags_dup_features;
 +      changed = (data ^ dev->features) & flags_dup_features;
        if (changed & ~dev->hw_features)
                return (changed & dev->hw_features) ? -EINVAL : -EOPNOTSUPP;
  
        dev->wanted_features =
 -              (dev->wanted_features & ~changed) | data;
 +              (dev->wanted_features & ~changed) | (data & dev->hw_features);
  
 -      netdev_update_features(dev);
 +      __netdev_update_features(dev);
  
        return 0;
  }
@@@ -910,9 -908,6 +910,9 @@@ static noinline_for_stack int ethtool_s
        struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL;
        int ret;
  
 +      if (!ops->set_rx_ntuple)
 +              return -EOPNOTSUPP;
 +
        if (!(dev->features & NETIF_F_NTUPLE))
                return -EINVAL;
  
@@@ -1446,35 -1441,6 +1446,35 @@@ static int ethtool_set_ringparam(struc
        return dev->ethtool_ops->set_ringparam(dev, &ringparam);
  }
  
 +static noinline_for_stack int ethtool_get_channels(struct net_device *dev,
 +                                                 void __user *useraddr)
 +{
 +      struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
 +
 +      if (!dev->ethtool_ops->get_channels)
 +              return -EOPNOTSUPP;
 +
 +      dev->ethtool_ops->get_channels(dev, &channels);
 +
 +      if (copy_to_user(useraddr, &channels, sizeof(channels)))
 +              return -EFAULT;
 +      return 0;
 +}
 +
 +static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
 +                                                 void __user *useraddr)
 +{
 +      struct ethtool_channels channels;
 +
 +      if (!dev->ethtool_ops->set_channels)
 +              return -EOPNOTSUPP;
 +
 +      if (copy_from_user(&channels, useraddr, sizeof(channels)))
 +              return -EFAULT;
 +
 +      return dev->ethtool_ops->set_channels(dev, &channels);
 +}
 +
  static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr)
  {
        struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
  static int ethtool_phys_id(struct net_device *dev, void __user *useraddr)
  {
        struct ethtool_value id;
 +      static bool busy;
 +      int rc;
  
 -      if (!dev->ethtool_ops->phys_id)
 +      if (!dev->ethtool_ops->set_phys_id)
                return -EOPNOTSUPP;
  
 +      if (busy)
 +              return -EBUSY;
 +
        if (copy_from_user(&id, useraddr, sizeof(id)))
                return -EFAULT;
  
 -      return dev->ethtool_ops->phys_id(dev, id.data);
 +      rc = dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_ACTIVE);
 +      if (rc < 0)
 +              return rc;
 +
 +      /* Drop the RTNL lock while waiting, but prevent reentry or
 +       * removal of the device.
 +       */
 +      busy = true;
 +      dev_hold(dev);
 +      rtnl_unlock();
 +
 +      if (rc == 0) {
 +              /* Driver will handle this itself */
 +              schedule_timeout_interruptible(
 +                      id.data ? (id.data * HZ) : MAX_SCHEDULE_TIMEOUT);
 +      } else {
 +              /* Driver expects to be called at twice the frequency in rc */
 +              int n = rc * 2, i, interval = HZ / n;
 +
 +              /* Count down seconds */
 +              do {
 +                      /* Count down iterations per second */
 +                      i = n;
 +                      do {
 +                              rtnl_lock();
 +                              rc = dev->ethtool_ops->set_phys_id(dev,
 +                                  (i & 1) ? ETHTOOL_ID_OFF : ETHTOOL_ID_ON);
 +                              rtnl_unlock();
 +                              if (rc)
 +                                      break;
 +                              schedule_timeout_interruptible(interval);
 +                      } while (!signal_pending(current) && --i != 0);
 +              } while (!signal_pending(current) &&
 +                       (id.data == 0 || --id.data != 0));
 +      }
 +
 +      rtnl_lock();
 +      dev_put(dev);
 +      busy = false;
 +
 +      (void)dev->ethtool_ops->set_phys_id(dev, ETHTOOL_ID_INACTIVE);
 +      return rc;
  }
  
  static int ethtool_get_stats(struct net_device *dev, void __user *useraddr)
@@@ -1823,87 -1743,6 +1823,87 @@@ static noinline_for_stack int ethtool_f
        return dev->ethtool_ops->flash_device(dev, &efl);
  }
  
 +static int ethtool_set_dump(struct net_device *dev,
 +                      void __user *useraddr)
 +{
 +      struct ethtool_dump dump;
 +
 +      if (!dev->ethtool_ops->set_dump)
 +              return -EOPNOTSUPP;
 +
 +      if (copy_from_user(&dump, useraddr, sizeof(dump)))
 +              return -EFAULT;
 +
 +      return dev->ethtool_ops->set_dump(dev, &dump);
 +}
 +
 +static int ethtool_get_dump_flag(struct net_device *dev,
 +                              void __user *useraddr)
 +{
 +      int ret;
 +      struct ethtool_dump dump;
 +      const struct ethtool_ops *ops = dev->ethtool_ops;
 +
 +      if (!dev->ethtool_ops->get_dump_flag)
 +              return -EOPNOTSUPP;
 +
 +      if (copy_from_user(&dump, useraddr, sizeof(dump)))
 +              return -EFAULT;
 +
 +      ret = ops->get_dump_flag(dev, &dump);
 +      if (ret)
 +              return ret;
 +
 +      if (copy_to_user(useraddr, &dump, sizeof(dump)))
 +              return -EFAULT;
 +      return 0;
 +}
 +
 +static int ethtool_get_dump_data(struct net_device *dev,
 +                              void __user *useraddr)
 +{
 +      int ret;
 +      __u32 len;
 +      struct ethtool_dump dump, tmp;
 +      const struct ethtool_ops *ops = dev->ethtool_ops;
 +      void *data = NULL;
 +
 +      if (!dev->ethtool_ops->get_dump_data ||
 +              !dev->ethtool_ops->get_dump_flag)
 +              return -EOPNOTSUPP;
 +
 +      if (copy_from_user(&dump, useraddr, sizeof(dump)))
 +              return -EFAULT;
 +
 +      memset(&tmp, 0, sizeof(tmp));
 +      tmp.cmd = ETHTOOL_GET_DUMP_FLAG;
 +      ret = ops->get_dump_flag(dev, &tmp);
 +      if (ret)
 +              return ret;
 +
 +      len = (tmp.len > dump.len) ? dump.len : tmp.len;
 +      if (!len)
 +              return -EFAULT;
 +
 +      data = vzalloc(tmp.len);
 +      if (!data)
 +              return -ENOMEM;
 +      ret = ops->get_dump_data(dev, &dump, data);
 +      if (ret)
 +              goto out;
 +
 +      if (copy_to_user(useraddr, &dump, sizeof(dump))) {
 +              ret = -EFAULT;
 +              goto out;
 +      }
 +      useraddr += offsetof(struct ethtool_dump, data);
 +      if (copy_to_user(useraddr, data, len))
 +              ret = -EFAULT;
 +out:
 +      vfree(data);
 +      return ret;
 +}
 +
  /* The main entry point in this file.  Called from net/core/dev.c */
  
  int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_SGRO:
                rc = ethtool_set_one_feature(dev, useraddr, ethcmd);
                break;
 +      case ETHTOOL_GCHANNELS:
 +              rc = ethtool_get_channels(dev, useraddr);
 +              break;
 +      case ETHTOOL_SCHANNELS:
 +              rc = ethtool_set_channels(dev, useraddr);
 +              break;
 +      case ETHTOOL_SET_DUMP:
 +              rc = ethtool_set_dump(dev, useraddr);
 +              break;
 +      case ETHTOOL_GET_DUMP_FLAG:
 +              rc = ethtool_get_dump_flag(dev, useraddr);
 +              break;
 +      case ETHTOOL_GET_DUMP_DATA:
 +              rc = ethtool_get_dump_data(dev, useraddr);
 +              break;
        default:
                rc = -EOPNOTSUPP;
        }
diff --combined net/mac80211/tx.c
@@@ -237,6 -237,10 +237,10 @@@ ieee80211_tx_h_dynamic_ps(struct ieee80
                                     &local->dynamic_ps_disable_work);
        }
  
+       /* Don't restart the timer if we're not disassociated */
+       if (!ifmgd->associated)
+               return TX_CONTINUE;
        mod_timer(&local->dynamic_ps_timer, jiffies +
                  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
  
@@@ -1036,11 -1040,14 +1040,11 @@@ static bool __ieee80211_parse_tx_radiot
        struct ieee80211_radiotap_iterator iterator;
        struct ieee80211_radiotap_header *rthdr =
                (struct ieee80211_radiotap_header *) skb->data;
 -      struct ieee80211_supported_band *sband;
        bool hw_frag;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len,
                                                   NULL);
  
 -      sband = tx->local->hw.wiphy->bands[tx->channel->band];
 -
        info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
        tx->flags &= ~IEEE80211_TX_FRAGMENTED;
  
@@@ -1147,7 -1154,7 +1151,7 @@@ static bool ieee80211_tx_prep_agg(struc
                 *     packet pass through because splicing the frames
                 *     back is already done.
                 */
 -              tid_tx = tx->sta->ampdu_mlme.tid_tx[tid];
 +              tid_tx = rcu_dereference_protected_tid_tx(tx->sta, tid);
  
                if (!tid_tx) {
                        /* do nothing, let packet pass through */
@@@ -1439,8 -1446,11 +1443,8 @@@ static bool ieee80211_tx(struct ieee802
        struct ieee80211_tx_data tx;
        ieee80211_tx_result res_prepare;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 -      u16 queue;
        bool result = true;
  
 -      queue = skb_get_queue_mapping(skb);
 -
        if (unlikely(skb->len < 10)) {
                dev_kfree_skb(skb);
                return true;
@@@ -1476,7 -1486,12 +1480,7 @@@ static int ieee80211_skb_resize(struct 
  {
        int tail_need = 0;
  
 -      /*
 -       * This could be optimised, devices that do full hardware
 -       * crypto (including TKIP MMIC) need no tailroom... But we
 -       * have no drivers for such devices currently.
 -       */
 -      if (may_encrypt) {
 +      if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) {
                tail_need = IEEE80211_ENCRYPT_TAILROOM;
                tail_need -= skb_tailroom(skb);
                tail_need = max_t(int, tail_need, 0);
@@@ -1751,7 -1766,6 +1755,7 @@@ netdev_tx_t ieee80211_subif_start_xmit(
                        ret = NETDEV_TX_OK;
                        goto fail;
                }
 +              rcu_read_lock();
                if (!is_multicast_ether_addr(skb->data))
                        mppath = mpp_path_lookup(skb->data, sdata);
  
                    !(mppath && compare_ether_addr(mppath->mpp, skb->data))) {
                        hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc,
                                        skb->data, skb->data + ETH_ALEN);
 +                      rcu_read_unlock();
                        meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr,
                                        sdata, NULL, NULL);
                } else {
                        int is_mesh_mcast = 1;
                        const u8 *mesh_da;
  
 -                      rcu_read_lock();
                        if (is_multicast_ether_addr(skb->data))
                                /* DA TA mSA AE:SA */
                                mesh_da = skb->data;
@@@ -2252,7 -2266,7 +2256,7 @@@ struct sk_buff *ieee80211_beacon_get_ti
  
                /* headroom, head length, tail length and maximum TIM length */
                skb = dev_alloc_skb(local->tx_headroom + 400 +
 -                              sdata->u.mesh.vendor_ie_len);
 +                              sdata->u.mesh.ie_len);
                if (!skb)
                        goto out;
  
@@@ -2475,6 -2489,7 +2479,6 @@@ ieee80211_get_buffered_bc(struct ieee80
  {
        struct ieee80211_local *local = hw_to_local(hw);
        struct sk_buff *skb = NULL;
 -      struct sta_info *sta;
        struct ieee80211_tx_data tx;
        struct ieee80211_sub_if_data *sdata;
        struct ieee80211_if_ap *bss = NULL;
  
        info = IEEE80211_SKB_CB(skb);
  
 -      sta = tx.sta;
        tx.flags |= IEEE80211_TX_PS_BUFFERED;
        tx.channel = local->hw.conf.channel;
        info->band = tx.channel->band;
@@@ -2535,9 -2551,8 +2539,9 @@@ void ieee80211_tx_skb(struct ieee80211_
        skb_set_network_header(skb, 0);
        skb_set_transport_header(skb, 0);
  
 -      /* send all internal mgmt frames on VO */
 -      skb_set_queue_mapping(skb, 0);
 +      /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */
 +      skb_set_queue_mapping(skb, IEEE80211_AC_VO);
 +      skb->priority = 7;
  
        /*
         * The other path calling ieee80211_xmit is from the tasklet,
@@@ -2066,9 -2066,12 +2066,9 @@@ static const struct file_operations ip_
        .open    = ip_vs_info_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release_private,
+       .release = seq_release_net,
  };
  
 -#endif
 -
 -#ifdef CONFIG_PROC_FS
  static int ip_vs_stats_show(struct seq_file *seq, void *v)
  {
        struct net *net = seq_file_single_net(seq);
@@@ -2106,7 -2109,7 +2106,7 @@@ static const struct file_operations ip_
        .open = ip_vs_stats_seq_open,
        .read = seq_read,
        .llseek = seq_lseek,
-       .release = single_release,
+       .release = single_release_net,
  };
  
  static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v)
@@@ -2175,7 -2178,7 +2175,7 @@@ static const struct file_operations ip_
        .open = ip_vs_stats_percpu_seq_open,
        .read = seq_read,
        .llseek = seq_lseek,
-       .release = single_release,
+       .release = single_release_net,
  };
  #endif
  
diff --combined net/socket.c
@@@ -551,10 -551,11 +551,10 @@@ int sock_tx_timestamp(struct sock *sk, 
  }
  EXPORT_SYMBOL(sock_tx_timestamp);
  
 -static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 -                               struct msghdr *msg, size_t size)
 +static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock,
 +                                     struct msghdr *msg, size_t size)
  {
        struct sock_iocb *si = kiocb_to_siocb(iocb);
 -      int err;
  
        sock_update_classid(sock->sk);
  
        si->msg = msg;
        si->size = size;
  
 -      err = security_socket_sendmsg(sock, msg, size);
 -      if (err)
 -              return err;
 -
        return sock->ops->sendmsg(iocb, sock, msg, size);
  }
  
 +static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 +                               struct msghdr *msg, size_t size)
 +{
 +      int err = security_socket_sendmsg(sock, msg, size);
 +
 +      return err ?: __sock_sendmsg_nosec(iocb, sock, msg, size);
 +}
 +
  int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
  {
        struct kiocb iocb;
  }
  EXPORT_SYMBOL(sock_sendmsg);
  
 +int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size)
 +{
 +      struct kiocb iocb;
 +      struct sock_iocb siocb;
 +      int ret;
 +
 +      init_sync_kiocb(&iocb, NULL);
 +      iocb.private = &siocb;
 +      ret = __sock_sendmsg_nosec(&iocb, sock, msg, size);
 +      if (-EIOCBQUEUED == ret)
 +              ret = wait_on_sync_kiocb(&iocb);
 +      return ret;
 +}
 +
  int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
                   struct kvec *vec, size_t num, size_t size)
  {
@@@ -1880,47 -1863,57 +1880,47 @@@ SYSCALL_DEFINE2(shutdown, int, fd, int
  #define COMPAT_NAMELEN(msg)   COMPAT_MSG(msg, msg_namelen)
  #define COMPAT_FLAGS(msg)     COMPAT_MSG(msg, msg_flags)
  
 -/*
 - *    BSD sendmsg interface
 - */
 -
 -SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
 +static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
 +                       struct msghdr *msg_sys, unsigned flags, int nosec)
  {
        struct compat_msghdr __user *msg_compat =
            (struct compat_msghdr __user *)msg;
 -      struct socket *sock;
        struct sockaddr_storage address;
        struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
        unsigned char ctl[sizeof(struct cmsghdr) + 20]
            __attribute__ ((aligned(sizeof(__kernel_size_t))));
        /* 20 is size of ipv6_pktinfo */
        unsigned char *ctl_buf = ctl;
 -      struct msghdr msg_sys;
        int err, ctl_len, iov_size, total_len;
 -      int fput_needed;
  
        err = -EFAULT;
        if (MSG_CMSG_COMPAT & flags) {
 -              if (get_compat_msghdr(&msg_sys, msg_compat))
 +              if (get_compat_msghdr(msg_sys, msg_compat))
                        return -EFAULT;
 -      } else if (copy_from_user(&msg_sys, msg, sizeof(struct msghdr)))
 +      } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr)))
                return -EFAULT;
  
 -      sock = sockfd_lookup_light(fd, &err, &fput_needed);
 -      if (!sock)
 -              goto out;
 -
        /* do not move before msg_sys is valid */
        err = -EMSGSIZE;
 -      if (msg_sys.msg_iovlen > UIO_MAXIOV)
 -              goto out_put;
 +      if (msg_sys->msg_iovlen > UIO_MAXIOV)
 +              goto out;
  
        /* Check whether to allocate the iovec area */
        err = -ENOMEM;
 -      iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
 -      if (msg_sys.msg_iovlen > UIO_FASTIOV) {
 +      iov_size = msg_sys->msg_iovlen * sizeof(struct iovec);
 +      if (msg_sys->msg_iovlen > UIO_FASTIOV) {
                iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
                if (!iov)
 -                      goto out_put;
 +                      goto out;
        }
  
        /* This will also move the address data into kernel space */
        if (MSG_CMSG_COMPAT & flags) {
 -              err = verify_compat_iovec(&msg_sys, iov,
 +              err = verify_compat_iovec(msg_sys, iov,
                                          (struct sockaddr *)&address,
                                          VERIFY_READ);
        } else
 -              err = verify_iovec(&msg_sys, iov,
 +              err = verify_iovec(msg_sys, iov,
                                   (struct sockaddr *)&address,
                                   VERIFY_READ);
        if (err < 0)
  
        err = -ENOBUFS;
  
 -      if (msg_sys.msg_controllen > INT_MAX)
 +      if (msg_sys->msg_controllen > INT_MAX)
                goto out_freeiov;
 -      ctl_len = msg_sys.msg_controllen;
 +      ctl_len = msg_sys->msg_controllen;
        if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
                err =
 -                  cmsghdr_from_user_compat_to_kern(&msg_sys, sock->sk, ctl,
 +                  cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
                                                     sizeof(ctl));
                if (err)
                        goto out_freeiov;
 -              ctl_buf = msg_sys.msg_control;
 -              ctl_len = msg_sys.msg_controllen;
 +              ctl_buf = msg_sys->msg_control;
 +              ctl_len = msg_sys->msg_controllen;
        } else if (ctl_len) {
                if (ctl_len > sizeof(ctl)) {
                        ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
                }
                err = -EFAULT;
                /*
 -               * Careful! Before this, msg_sys.msg_control contains a user pointer.
 +               * Careful! Before this, msg_sys->msg_control contains a user pointer.
                 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
                 * checking falls down on this.
                 */
                if (copy_from_user(ctl_buf,
 -                                 (void __user __force *)msg_sys.msg_control,
 +                                 (void __user __force *)msg_sys->msg_control,
                                   ctl_len))
                        goto out_freectl;
 -              msg_sys.msg_control = ctl_buf;
 +              msg_sys->msg_control = ctl_buf;
        }
 -      msg_sys.msg_flags = flags;
 +      msg_sys->msg_flags = flags;
  
        if (sock->file->f_flags & O_NONBLOCK)
 -              msg_sys.msg_flags |= MSG_DONTWAIT;
 -      err = sock_sendmsg(sock, &msg_sys, total_len);
 +              msg_sys->msg_flags |= MSG_DONTWAIT;
 +      err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys,
 +                                                        total_len);
  
  out_freectl:
        if (ctl_buf != ctl)
  out_freeiov:
        if (iov != iovstack)
                sock_kfree_s(sock->sk, iov, iov_size);
 -out_put:
 +out:
 +      return err;
 +}
 +
 +/*
 + *    BSD sendmsg interface
 + */
 +
 +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
 +{
 +      int fput_needed, err;
 +      struct msghdr msg_sys;
 +      struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed);
 +
 +      if (!sock)
 +              goto out;
 +
 +      err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0);
 +
        fput_light(sock->file, fput_needed);
  out:
        return err;
  }
  
 +/*
 + *    Linux sendmmsg interface
 + */
 +
 +int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
 +                 unsigned int flags)
 +{
 +      int fput_needed, err, datagrams;
 +      struct socket *sock;
 +      struct mmsghdr __user *entry;
 +      struct compat_mmsghdr __user *compat_entry;
 +      struct msghdr msg_sys;
 +
 +      datagrams = 0;
 +
 +      sock = sockfd_lookup_light(fd, &err, &fput_needed);
 +      if (!sock)
 +              return err;
 +
 +      err = sock_error(sock->sk);
 +      if (err)
 +              goto out_put;
 +
 +      entry = mmsg;
 +      compat_entry = (struct compat_mmsghdr __user *)mmsg;
 +
 +      while (datagrams < vlen) {
 +              /*
 +               * No need to ask LSM for more than the first datagram.
 +               */
 +              if (MSG_CMSG_COMPAT & flags) {
 +                      err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry,
 +                                          &msg_sys, flags, datagrams);
 +                      if (err < 0)
 +                              break;
 +                      err = __put_user(err, &compat_entry->msg_len);
 +                      ++compat_entry;
 +              } else {
 +                      err = __sys_sendmsg(sock, (struct msghdr __user *)entry,
 +                                          &msg_sys, flags, datagrams);
 +                      if (err < 0)
 +                              break;
 +                      err = put_user(err, &entry->msg_len);
 +                      ++entry;
 +              }
 +
 +              if (err)
 +                      break;
 +              ++datagrams;
 +      }
 +
 +out_put:
 +      fput_light(sock->file, fput_needed);
 +
 +      if (err == 0)
 +              return datagrams;
 +
 +      if (datagrams != 0) {
 +              /*
 +               * We may send less entries than requested (vlen) if the
 +               * sock is non blocking...
 +               */
 +              if (err != -EAGAIN) {
 +                      /*
 +                       * ... or if sendmsg returns an error after we
 +                       * send some datagrams, where we record the
 +                       * error to return on the next call or if the
 +                       * app asks about it using getsockopt(SO_ERROR).
 +                       */
 +                      sock->sk->sk_err = -err;
 +              }
 +
 +              return datagrams;
 +      }
 +
 +      return err;
 +}
 +
 +SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg,
 +              unsigned int, vlen, unsigned int, flags)
 +{
 +      return __sys_sendmmsg(fd, mmsg, vlen, flags);
 +}
 +
  static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                         struct msghdr *msg_sys, unsigned flags, int nosec)
  {
@@@ -2232,14 -2122,16 +2232,16 @@@ int __sys_recvmmsg(int fd, struct mmsgh
                 */
                if (MSG_CMSG_COMPAT & flags) {
                        err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
-                                           &msg_sys, flags, datagrams);
+                                           &msg_sys, flags & ~MSG_WAITFORONE,
+                                           datagrams);
                        if (err < 0)
                                break;
                        err = __put_user(err, &compat_entry->msg_len);
                        ++compat_entry;
                } else {
                        err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
-                                           &msg_sys, flags, datagrams);
+                                           &msg_sys, flags & ~MSG_WAITFORONE,
+                                           datagrams);
                        if (err < 0)
                                break;
                        err = put_user(err, &entry->msg_len);
@@@ -2324,11 -2216,11 +2326,11 @@@ SYSCALL_DEFINE5(recvmmsg, int, fd, stru
  #ifdef __ARCH_WANT_SYS_SOCKETCALL
  /* Argument list sizes for sys_socketcall */
  #define AL(x) ((x) * sizeof(unsigned long))
 -static const unsigned char nargs[20] = {
 +static const unsigned char nargs[21] = {
        AL(0), AL(3), AL(3), AL(3), AL(2), AL(3),
        AL(3), AL(3), AL(4), AL(4), AL(4), AL(6),
        AL(6), AL(2), AL(5), AL(5), AL(3), AL(3),
 -      AL(4), AL(5)
 +      AL(4), AL(5), AL(4)
  };
  
  #undef AL
@@@ -2348,7 -2240,7 +2350,7 @@@ SYSCALL_DEFINE2(socketcall, int, call, 
        int err;
        unsigned int len;
  
 -      if (call < 1 || call > SYS_RECVMMSG)
 +      if (call < 1 || call > SYS_SENDMMSG)
                return -EINVAL;
  
        len = nargs[call];
        case SYS_SENDMSG:
                err = sys_sendmsg(a0, (struct msghdr __user *)a1, a[2]);
                break;
 +      case SYS_SENDMMSG:
 +              err = sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3]);
 +              break;
        case SYS_RECVMSG:
                err = sys_recvmsg(a0, (struct msghdr __user *)a1, a[2]);
                break;
@@@ -2756,13 -2645,13 +2758,13 @@@ static int ethtool_ioctl(struct net *ne
                return -EFAULT;
  
        if (convert_in) {
 -              /* We expect there to be holes between fs.m_u and
 +              /* We expect there to be holes between fs.m_ext and
                 * fs.ring_cookie and at the end of fs, but nowhere else.
                 */
 -              BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) +
 -                           sizeof(compat_rxnfc->fs.m_u) !=
 -                           offsetof(struct ethtool_rxnfc, fs.m_u) +
 -                           sizeof(rxnfc->fs.m_u));
 +              BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) +
 +                           sizeof(compat_rxnfc->fs.m_ext) !=
 +                           offsetof(struct ethtool_rxnfc, fs.m_ext) +
 +                           sizeof(rxnfc->fs.m_ext));
                BUILD_BUG_ON(
                        offsetof(struct compat_ethtool_rxnfc, fs.location) -
                        offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) !=
                        offsetof(struct ethtool_rxnfc, fs.ring_cookie));
  
                if (copy_in_user(rxnfc, compat_rxnfc,
 -                               (void *)(&rxnfc->fs.m_u + 1) -
 +                               (void *)(&rxnfc->fs.m_ext + 1) -
                                 (void *)rxnfc) ||
                    copy_in_user(&rxnfc->fs.ring_cookie,
                                 &compat_rxnfc->fs.ring_cookie,
  
        if (convert_out) {
                if (copy_in_user(compat_rxnfc, rxnfc,
 -                               (const void *)(&rxnfc->fs.m_u + 1) -
 +                               (const void *)(&rxnfc->fs.m_ext + 1) -
                                 (const void *)rxnfc) ||
                    copy_in_user(&compat_rxnfc->fs.ring_cookie,
                                 &rxnfc->fs.ring_cookie,