Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Wed, 1 Oct 2008 13:12:56 +0000 (06:12 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 1 Oct 2008 13:12:56 +0000 (06:12 -0700)
Conflicts:

drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/main.c
net/core/dev.c

15 files changed:
1  2 
Documentation/feature-removal-schedule.txt
MAINTAINERS
drivers/net/bnx2.h
drivers/net/e100.c
drivers/net/forcedeth.c
drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/xmit.c
drivers/net/wireless/b43/rfkill.c
include/net/netlink.h
net/core/dev.c
net/ipv4/tcp_ipv4.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c

diff --cc MAINTAINERS
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -683,9 -806,9 +689,10 @@@ int ath_open(struct ath_softc *sc, stru
         * Note we only do this (at the moment) for station mode.
         */
        if (ath9k_hw_phycounters(ah) &&
 -          ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS)))
 +          ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
 +           (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
                sc->sc_imask |= ATH9K_INT_MIB;
+ #endif
        /*
         * Some hardware processes the TIM IE and fires an
         * interrupt when the TIM bit is set.  For hardware
@@@ -1184,8 -1341,10 +1191,10 @@@ void ath_deinit(struct ath_softc *sc
  
        DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
  
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
        ath_stop(sc);
 -      if (!sc->sc_invalid)
 +      if (!(sc->sc_flags & SC_OP_INVALID))
                ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
        ath_rate_detach(sc->sc_rc);
        /* cleanup tx queues */
Simple merge
@@@ -1368,292 -1149,145 +1366,291 @@@ static int ath9k_config_interface(struc
        return 0;
  }
  
 -int ath_rx_subframe(struct ath_node *an,
 -                  struct sk_buff *skb,
 -                  struct ath_recv_status *status)
 +#define SUPPORTED_FILTERS                     \
 +      (FIF_PROMISC_IN_BSS |                   \
 +      FIF_ALLMULTI |                          \
 +      FIF_CONTROL |                           \
 +      FIF_OTHER_BSS |                         \
 +      FIF_BCN_PRBRESP_PROMISC |               \
 +      FIF_FCSFAIL)
 +
 +/* FIXME: sc->sc_full_reset ? */
 +static void ath9k_configure_filter(struct ieee80211_hw *hw,
 +                                 unsigned int changed_flags,
 +                                 unsigned int *total_flags,
 +                                 int mc_count,
 +                                 struct dev_mc_list *mclist)
  {
 -      struct ath_softc *sc = an->an_sc;
 -      struct ieee80211_hw *hw = sc->hw;
 -      struct ieee80211_rx_status rx_status;
 +      struct ath_softc *sc = hw->priv;
 +      u32 rfilt;
  
 -      /* Prepare rx status */
 -      ath9k_rx_prepare(sc, skb, status, &rx_status);
 -      if (!(status->flags & ATH_RX_DECRYPT_ERROR))
 -              rx_status.flag |= RX_FLAG_DECRYPTED;
 +      changed_flags &= SUPPORTED_FILTERS;
 +      *total_flags &= SUPPORTED_FILTERS;
  
 -      __ieee80211_rx(hw, skb, &rx_status);
 +      sc->rx_filter = *total_flags;
 +      rfilt = ath_calcrxfilter(sc);
 +      ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
  
 -      return 0;
 -}
 +      if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
 +              if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
 +                      ath9k_hw_write_associd(sc->sc_ah, ath_bcast_mac, 0);
 +      }
  
 -enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc)
 -{
 -      return sc->sc_ht_info.tx_chan_width;
 +      DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set HW RX filter: 0x%x\n",
 +              __func__, sc->rx_filter);
  }
  
 -static int ath_detach(struct ath_softc *sc)
 +static void ath9k_sta_notify(struct ieee80211_hw *hw,
 +                           struct ieee80211_vif *vif,
 +                           enum sta_notify_cmd cmd,
 +                           struct ieee80211_sta *sta)
  {
 -      struct ieee80211_hw *hw = sc->hw;
 -
 -      DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
 +      struct ath_softc *sc = hw->priv;
 +      struct ath_node *an;
 +      unsigned long flags;
 +      DECLARE_MAC_BUF(mac);
  
 -      /* Unregister hw */
 +      spin_lock_irqsave(&sc->node_lock, flags);
 +      an = ath_node_find(sc, sta->addr);
 +      spin_unlock_irqrestore(&sc->node_lock, flags);
  
 -      ieee80211_unregister_hw(hw);
 +      switch (cmd) {
 +      case STA_NOTIFY_ADD:
 +              spin_lock_irqsave(&sc->node_lock, flags);
 +              if (!an) {
 +                      ath_node_attach(sc, sta->addr, 0);
 +                      DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n",
 +                              __func__, print_mac(mac, sta->addr));
 +              } else {
 +                      ath_node_get(sc, sta->addr);
 +              }
 +              spin_unlock_irqrestore(&sc->node_lock, flags);
 +              break;
 +      case STA_NOTIFY_REMOVE:
 +              if (!an)
 +                      DPRINTF(sc, ATH_DBG_FATAL,
 +                              "%s: Removal of a non-existent node\n",
 +                              __func__);
 +              else {
 +                      ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT);
 +                      DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n",
 +                              __func__,
 +                              print_mac(mac, sta->addr));
 +              }
 +              break;
 +      default:
 +              break;
 +      }
 +}
  
 -      /* unregister Rate control */
 -      ath_rate_control_unregister();
 +static int ath9k_conf_tx(struct ieee80211_hw *hw,
 +                       u16 queue,
 +                       const struct ieee80211_tx_queue_params *params)
 +{
 +      struct ath_softc *sc = hw->priv;
 +      struct ath9k_tx_queue_info qi;
 +      int ret = 0, qnum;
  
 -      /* tx/rx cleanup */
 +      if (queue >= WME_NUM_AC)
 +              return 0;
  
 -      ath_rx_cleanup(sc);
 -      ath_tx_cleanup(sc);
 +      qi.tqi_aifs = params->aifs;
 +      qi.tqi_cwmin = params->cw_min;
 +      qi.tqi_cwmax = params->cw_max;
 +      qi.tqi_burstTime = params->txop;
 +      qnum = ath_get_hal_qnum(queue, sc);
  
 -      /* Deinit */
 +      DPRINTF(sc, ATH_DBG_CONFIG,
 +              "%s: Configure tx [queue/halq] [%d/%d],  "
 +              "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
 +              __func__,
 +              queue,
 +              qnum,
 +              params->aifs,
 +              params->cw_min,
 +              params->cw_max,
 +              params->txop);
  
 -      ath_deinit(sc);
 +      ret = ath_txq_update(sc, qnum, &qi);
 +      if (ret)
 +              DPRINTF(sc, ATH_DBG_FATAL,
 +                      "%s: TXQ Update failed\n", __func__);
  
 -      return 0;
 +      return ret;
  }
  
 -static int ath_attach(u16 devid,
 -                    struct ath_softc *sc)
 +static int ath9k_set_key(struct ieee80211_hw *hw,
 +                       enum set_key_cmd cmd,
 +                       const u8 *local_addr,
 +                       const u8 *addr,
 +                       struct ieee80211_key_conf *key)
  {
 -      struct ieee80211_hw *hw = sc->hw;
 -      int error = 0;
 +      struct ath_softc *sc = hw->priv;
 +      int ret = 0;
  
 -      DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__);
 +      DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__);
  
 -      error = ath_init(devid, sc);
 -      if (error != 0)
 -              return error;
 +      switch (cmd) {
 +      case SET_KEY:
 +              ret = ath_key_config(sc, addr, key);
 +              if (!ret) {
 +                      set_bit(key->keyidx, sc->sc_keymap);
 +                      key->hw_key_idx = key->keyidx;
 +                      /* push IV and Michael MIC generation to stack */
 +                      key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 +                      if (key->alg == ALG_TKIP)
 +                              key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
 +              }
 +              break;
 +      case DISABLE_KEY:
 +              ath_key_delete(sc, key);
 +              clear_bit(key->keyidx, sc->sc_keymap);
-               sc->sc_keytype = ATH9K_CIPHER_CLR;
 +              break;
 +      default:
 +              ret = -EINVAL;
 +      }
  
 -      /* Init nodes */
 +      return ret;
 +}
  
 -      INIT_LIST_HEAD(&sc->node_list);
 -      spin_lock_init(&sc->node_lock);
 +static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
 +                                 struct ieee80211_vif *vif,
 +                                 struct ieee80211_bss_conf *bss_conf,
 +                                 u32 changed)
 +{
 +      struct ath_softc *sc = hw->priv;
  
 -      /* get mac address from hardware and set in mac80211 */
 +      if (changed & BSS_CHANGED_ERP_PREAMBLE) {
 +              DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n",
 +                      __func__,
 +                      bss_conf->use_short_preamble);
 +              if (bss_conf->use_short_preamble)
 +                      sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
 +              else
 +                      sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
 +      }
  
 -      SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
 +      if (changed & BSS_CHANGED_ERP_CTS_PROT) {
 +              DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n",
 +                      __func__,
 +                      bss_conf->use_cts_prot);
 +              if (bss_conf->use_cts_prot &&
 +                  hw->conf.channel->band != IEEE80211_BAND_5GHZ)
 +                      sc->sc_flags |= SC_OP_PROTECT_ENABLE;
 +              else
 +                      sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
 +      }
  
 -      /* setup channels and rates */
 +      if (changed & BSS_CHANGED_HT) {
 +              DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n",
 +                      __func__,
 +                      bss_conf->assoc_ht);
 +              ath9k_ht_conf(sc, bss_conf);
 +      }
  
 -      sc->sbands[IEEE80211_BAND_2GHZ].channels =
 -              sc->channels[IEEE80211_BAND_2GHZ];
 -      sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
 -              sc->rates[IEEE80211_BAND_2GHZ];
 -      sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
 +      if (changed & BSS_CHANGED_ASSOC) {
 +              DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
 +                      __func__,
 +                      bss_conf->assoc);
 +              ath9k_bss_assoc_info(sc, bss_conf);
 +      }
 +}
  
 -      if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
 -              /* Setup HT capabilities for 2.4Ghz*/
 -              setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
 +static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
 +{
 +      u64 tsf;
 +      struct ath_softc *sc = hw->priv;
 +      struct ath_hal *ah = sc->sc_ah;
  
 -      hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
 -              &sc->sbands[IEEE80211_BAND_2GHZ];
 +      tsf = ath9k_hw_gettsf64(ah);
  
 -      if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
 -              sc->sbands[IEEE80211_BAND_5GHZ].channels =
 -                      sc->channels[IEEE80211_BAND_5GHZ];
 -              sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
 -                      sc->rates[IEEE80211_BAND_5GHZ];
 -              sc->sbands[IEEE80211_BAND_5GHZ].band =
 -                      IEEE80211_BAND_5GHZ;
 +      return tsf;
 +}
  
 -              if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
 -                      /* Setup HT capabilities for 5Ghz*/
 -                      setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
 +static void ath9k_reset_tsf(struct ieee80211_hw *hw)
 +{
 +      struct ath_softc *sc = hw->priv;
 +      struct ath_hal *ah = sc->sc_ah;
  
 -              hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 -                      &sc->sbands[IEEE80211_BAND_5GHZ];
 -      }
 +      ath9k_hw_reset_tsf(ah);
 +}
  
 -      /* FIXME: Have to figure out proper hw init values later */
 +static int ath9k_ampdu_action(struct ieee80211_hw *hw,
 +                     enum ieee80211_ampdu_mlme_action action,
 +                     struct ieee80211_sta *sta,
 +                     u16 tid, u16 *ssn)
 +{
 +      struct ath_softc *sc = hw->priv;
 +      int ret = 0;
  
 -      hw->queues = 4;
 -      hw->ampdu_queues = 1;
 +      switch (action) {
 +      case IEEE80211_AMPDU_RX_START:
 +              ret = ath_rx_aggr_start(sc, sta->addr, tid, ssn);
 +              if (ret < 0)
 +                      DPRINTF(sc, ATH_DBG_FATAL,
 +                              "%s: Unable to start RX aggregation\n",
 +                              __func__);
 +              break;
 +      case IEEE80211_AMPDU_RX_STOP:
 +              ret = ath_rx_aggr_stop(sc, sta->addr, tid);
 +              if (ret < 0)
 +                      DPRINTF(sc, ATH_DBG_FATAL,
 +                              "%s: Unable to stop RX aggregation\n",
 +                              __func__);
 +              break;
 +      case IEEE80211_AMPDU_TX_START:
 +              ret = ath_tx_aggr_start(sc, sta->addr, tid, ssn);
 +              if (ret < 0)
 +                      DPRINTF(sc, ATH_DBG_FATAL,
 +                              "%s: Unable to start TX aggregation\n",
 +                              __func__);
 +              else
 +                      ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
 +              break;
 +      case IEEE80211_AMPDU_TX_STOP:
 +              ret = ath_tx_aggr_stop(sc, sta->addr, tid);
 +              if (ret < 0)
 +                      DPRINTF(sc, ATH_DBG_FATAL,
 +                              "%s: Unable to stop TX aggregation\n",
 +                              __func__);
  
 -      /* Register rate control */
 -      hw->rate_control_algorithm = "ath9k_rate_control";
 -      error = ath_rate_control_register();
 -      if (error != 0) {
 +              ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
 +              break;
 +      default:
                DPRINTF(sc, ATH_DBG_FATAL,
 -                      "%s: Unable to register rate control "
 -                      "algorithm:%d\n", __func__, error);
 -              ath_rate_control_unregister();
 -              goto bad;
 -      }
 -
 -      error = ieee80211_register_hw(hw);
 -      if (error != 0) {
 -              ath_rate_control_unregister();
 -              goto bad;
 +                      "%s: Unknown AMPDU action\n", __func__);
        }
  
 -      /* initialize tx/rx engine */
 -
 -      error = ath_tx_init(sc, ATH_TXBUF);
 -      if (error != 0)
 -              goto bad1;
 -
 -      error = ath_rx_init(sc, ATH_RXBUF);
 -      if (error != 0)
 -              goto bad1;
 -
 -      return 0;
 -bad1:
 -      ath_detach(sc);
 -bad:
 -      return error;
 +      return ret;
  }
  
 +static struct ieee80211_ops ath9k_ops = {
 +      .tx                 = ath9k_tx,
 +      .start              = ath9k_start,
 +      .stop               = ath9k_stop,
 +      .add_interface      = ath9k_add_interface,
 +      .remove_interface   = ath9k_remove_interface,
 +      .config             = ath9k_config,
 +      .config_interface   = ath9k_config_interface,
 +      .configure_filter   = ath9k_configure_filter,
 +      .get_stats          = NULL,
 +      .sta_notify         = ath9k_sta_notify,
 +      .conf_tx            = ath9k_conf_tx,
 +      .get_tx_stats       = NULL,
 +      .bss_info_changed   = ath9k_bss_info_changed,
 +      .set_tim            = NULL,
 +      .set_key            = ath9k_set_key,
 +      .hw_scan            = NULL,
 +      .get_tkip_seq       = NULL,
 +      .set_rts_threshold  = NULL,
 +      .set_frag_threshold = NULL,
 +      .set_retry_limit    = NULL,
 +      .get_tsf            = ath9k_get_tsf,
 +      .reset_tsf          = ath9k_reset_tsf,
 +      .tx_last_beacon     = NULL,
 +      .ampdu_action       = ath9k_ampdu_action
 +};
 +
  static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  {
        void __iomem *mem;
@@@ -1784,10 -1411,17 +1781,17 @@@ static void ath_pci_remove(struct pci_d
  {
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
        struct ath_softc *sc = hw->priv;
+       enum ath9k_int status;
  
-       if (pdev->irq)
+       if (pdev->irq) {
+               ath9k_hw_set_interrupts(sc->sc_ah, 0);
+               /* clear the ISR */
+               ath9k_hw_getisr(sc->sc_ah, &status);
 -              sc->sc_invalid = 1;
++              sc->sc_flags |= SC_OP_INVALID;
                free_irq(pdev->irq, sc);
+       }
        ath_detach(sc);
        pci_iounmap(pdev, sc->mem);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
Simple merge
Simple merge
Simple merge
diff --cc net/core/dev.c
@@@ -1706,8 -1676,9 +1707,9 @@@ static u16 simple_tx_hash(struct net_de
        }
  
        switch (skb->protocol) {
 -      case __constant_htons(ETH_P_IP):
 +      case htons(ETH_P_IP):
-               ip_proto = ip_hdr(skb)->protocol;
+               if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
+                       ip_proto = ip_hdr(skb)->protocol;
                addr1 = ip_hdr(skb)->saddr;
                addr2 = ip_hdr(skb)->daddr;
                ihl = ip_hdr(skb)->ihl;
Simple merge
Simple merge
Simple merge