]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/wireless/ath/ath5k/base.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[net-next-2.6.git] / drivers / net / wireless / ath / ath5k / base.c
index 0d5de2574dd106af6c3bdbad8e8028b4c24b3987..116ac66c6e3ecd60d19800a46af184926cfafc76 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/netdevice.h>
 #include <linux/cache.h>
 #include <linux/pci.h>
+#include <linux/pci-aspm.h>
 #include <linux/ethtool.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
@@ -476,6 +477,26 @@ ath5k_pci_probe(struct pci_dev *pdev,
        int ret;
        u8 csz;
 
+       /*
+        * L0s needs to be disabled on all ath5k cards.
+        *
+        * For distributions shipping with CONFIG_PCIEASPM (this will be enabled
+        * by default in the future in 2.6.36) this will also mean both L1 and
+        * L0s will be disabled when a pre 1.1 PCIe device is detected. We do
+        * know L1 works correctly even for all ath5k pre 1.1 PCIe devices
+        * though but cannot currently undue the effect of a blacklist, for
+        * details you can read pcie_aspm_sanity_check() and see how it adjusts
+        * the device link capability.
+        *
+        * It may be possible in the future to implement some PCI API to allow
+        * drivers to override blacklists for pre 1.1 PCIe but for now it is
+        * best to accept that both L0s and L1 will be disabled completely for
+        * distributions shipping with CONFIG_PCIEASPM rather than having this
+        * issue present. Motivation for adding this new API will be to help
+        * with power consumption for some of these devices.
+        */
+       pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
+
        ret = pci_enable_device(pdev);
        if (ret) {
                dev_err(&pdev->dev, "can't enable device\n");
@@ -591,7 +612,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
                goto err_free;
        }
 
-       /*If we passed the test malloc a ath5k_hw struct*/
+       /* If we passed the test, malloc an ath5k_hw struct */
        sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
        if (!sc->ah) {
                ret = -ENOMEM;
@@ -679,10 +700,10 @@ ath5k_pci_probe(struct pci_dev *pdev,
        return 0;
 err_ah:
        ath5k_hw_detach(sc->ah);
-err_irq:
-       free_irq(pdev->irq, sc);
 err_free_ah:
        kfree(sc->ah);
+err_irq:
+       free_irq(pdev->irq, sc);
 err_free:
        ieee80211_free_hw(hw);
 err_map:
@@ -765,8 +786,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
        /*
         * Check if the MAC has multi-rate retry support.
         * We do this by trying to setup a fake extended
-        * descriptor.  MAC's that don't have support will
-        * return false w/o doing anything.  MAC's that do
+        * descriptor.  MACs that don't have support will
+        * return false w/o doing anything.  MACs that do
         * support it will return true w/o doing anything.
         */
        ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
@@ -806,7 +827,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
        /*
         * Allocate hardware transmit queues: one queue for
         * beacon frames and one data queue for each QoS
-        * priority.  Note that hw functions handle reseting
+        * priority.  Note that hw functions handle resetting
         * these queues at the needed time.
         */
        ret = ath5k_beaconq_setup(ah);
@@ -888,7 +909,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
        /*
         * NB: the order of these is important:
         * o call the 802.11 layer before detaching ath5k_hw to
-        *   insure callbacks into the driver to delete global
+        *   ensure callbacks into the driver to delete global
         *   key cache entries can be handled
         * o reclaim the tx queue data structures after calling
         *   the 802.11 layer as we'll get called back to reclaim
@@ -1306,6 +1327,10 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
                        PCI_DMA_TODEVICE);
 
        rate = ieee80211_get_tx_rate(sc->hw, info);
+       if (!rate) {
+               ret = -EINVAL;
+               goto err_unmap;
+       }
 
        if (info->flags & IEEE80211_TX_CTL_NO_ACK)
                flags |= AR5K_TXDESC_NOACK;
@@ -1493,7 +1518,7 @@ ath5k_txq_setup(struct ath5k_softc *sc,
        /*
         * Enable interrupts only for EOL and DESC conditions.
         * We mark tx descriptors to receive a DESC interrupt
-        * when a tx queue gets deep; otherwise waiting for the
+        * when a tx queue gets deep; otherwise we wait for the
         * EOL to reap descriptors.  Note that this is done to
         * reduce interrupt load and this only defers reaping
         * descriptors, never transmitting frames.  Aside from
@@ -1688,7 +1713,7 @@ ath5k_rx_start(struct ath5k_softc *sc)
        struct ath5k_buf *bf;
        int ret;
 
-       common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
+       common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz);
 
        ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n",
                  common->cachelsz, common->rx_bufsize);
@@ -1838,7 +1863,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi)
 }
 
 /*
- * Compute padding position. skb must contains an IEEE 802.11 frame
+ * Compute padding position. skb must contain an IEEE 802.11 frame
  */
 static int ath5k_common_padpos(struct sk_buff *skb)
 {
@@ -1857,10 +1882,9 @@ static int ath5k_common_padpos(struct sk_buff *skb)
 }
 
 /*
- * This function expects a 802.11 frame and returns the number of
- * bytes added, or -1 if we don't have enought header room.
+ * This function expects an 802.11 frame and returns the number of
+ * bytes added, or -1 if we don't have enough header room.
  */
-
 static int ath5k_add_padding(struct sk_buff *skb)
 {
        int padpos = ath5k_common_padpos(skb);
@@ -1880,10 +1904,18 @@ static int ath5k_add_padding(struct sk_buff *skb)
 }
 
 /*
- * This function expects a 802.11 frame and returns the number of
- * bytes removed
+ * The MAC header is padded to have 32-bit boundary if the
+ * packet payload is non-zero. The general calculation for
+ * padsize would take into account odd header lengths:
+ * padsize = 4 - (hdrlen & 3); however, since only
+ * even-length headers are used, padding can only be 0 or 2
+ * bytes and we can optimize this a bit.  We must not try to
+ * remove padding from short control frames that do not have a
+ * payload.
+ *
+ * This function expects an 802.11 frame and returns the number of
+ * bytes removed.
  */
-
 static int ath5k_remove_padding(struct sk_buff *skb)
 {
        int padpos = ath5k_common_padpos(skb);
@@ -1904,14 +1936,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb,
 {
        struct ieee80211_rx_status *rxs;
 
-       /* The MAC header is padded to have 32-bit boundary if the
-        * packet payload is non-zero. The general calculation for
-        * padsize would take into account odd header lengths:
-        * padsize = (4 - hdrlen % 4) % 4; However, since only
-        * even-length headers are used, padding can only be 0 or 2
-        * bytes and we can optimize this a bit. In addition, we must
-        * not try to remove padding from short control frames that do
-        * not have payload. */
        ath5k_remove_padding(skb);
 
        rxs = IEEE80211_SKB_RXCB(skb);
@@ -2015,9 +2039,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs)
                        return true;
                }
 
-               /* let crypto-error packets fall through in MNTR */
-               if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
-                   sc->opmode != NL80211_IFTYPE_MONITOR)
+               /* reject any frames with non-crypto errors */
+               if (rs->rs_status & ~(AR5K_RXERR_DECRYPT))
                        return false;
        }
 
@@ -2260,10 +2283,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
         * default antenna which is supposed to be an omni.
         *
         * Note2: On sectored scenarios it's possible to have
-        * multiple antennas (1omni -the default- and 14 sectors)
-        * so if we choose to actually support this mode we need
-        * to allow user to set how many antennas we have and tweak
-        * the code below to send beacons on all of them.
+        * multiple antennas (1 omni -- the default -- and 14
+        * sectors), so if we choose to actually support this
+        * mode, we need to allow the user to set how many antennas
+        * we have and tweak the code below to send beacons
+        * on all of them.
         */
        if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
                antenna = sc->bsent & 4 ? 2 : 1;
@@ -2305,14 +2329,13 @@ ath5k_beacon_send(struct ath5k_softc *sc)
 
        ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
 
-       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
-                       sc->opmode == NL80211_IFTYPE_MONITOR)) {
+       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION)) {
                ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
                return;
        }
        /*
         * Check if the previous beacon has gone out.  If
-        * not don't don't try to post another, skip this
+        * not, don't don't try to post another: skip this
         * period and wait for the next.  Missed beacons
         * indicate a problem and should not occur.  If we
         * miss too many consecutive beacons reset the device.
@@ -2880,12 +2903,9 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
 
        ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
 
-       if (sc->opmode == NL80211_IFTYPE_MONITOR)
-               ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
-
        /*
-        * the hardware expects the header padded to 4 byte boundaries
-        * if this is not the case we add the padding after the header
+        * The hardware expects the header padded to 4 byte boundaries.
+        * If this is not the case, we add the padding after the header.
         */
        padsize = ath5k_add_padding(skb);
        if (padsize < 0) {
@@ -3028,7 +3048,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_ADHOC:
        case NL80211_IFTYPE_MESH_POINT:
-       case NL80211_IFTYPE_MONITOR:
                sc->opmode = vif->type;
                break;
        default:
@@ -3212,9 +3231,9 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
                rfilt |= AR5K_RX_FILTER_PHYERR;
 
        /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
-       * and probes for any BSSID, this needs testing */
+       * and probes for any BSSID */
        if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
-               rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
+               rfilt |= AR5K_RX_FILTER_BEACON;
 
        /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
         * set we should only pass on control frames for this
@@ -3230,7 +3249,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
 
        switch (sc->opmode) {
        case NL80211_IFTYPE_MESH_POINT:
-       case NL80211_IFTYPE_MONITOR:
                rfilt |= AR5K_RX_FILTER_CONTROL |
                         AR5K_RX_FILTER_BEACON |
                         AR5K_RX_FILTER_PROBEREQ |
@@ -3253,7 +3271,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
 
        /* Set multicast bits */
        ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
-       /* Set the cached hw filter flags, this will alter actually
+       /* Set the cached hw filter flags, this will later actually
         * be set in HW */
        sc->filter_flags = rfilt;
 
@@ -3276,11 +3294,12 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (sc->opmode == NL80211_IFTYPE_AP)
                return -EOPNOTSUPP;
 
-       switch (key->alg) {
-       case ALG_WEP:
-       case ALG_TKIP:
+       switch (key->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+       case WLAN_CIPHER_SUITE_TKIP:
                break;
-       case ALG_CCMP:
+       case WLAN_CIPHER_SUITE_CCMP:
                if (sc->ah->ah_aes_support)
                        break;
 
@@ -3454,7 +3473,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
                /* Cache for later use during resets */
                memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
                common->curaid = 0;
-               ath5k_hw_set_associd(ah);
+               ath5k_hw_set_bssid(ah);
                mmiowb();
        }
 
@@ -3472,7 +3491,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
                                  "Bss Info ASSOC %d, bssid: %pM\n",
                                  bss_conf->aid, common->curbssid);
                        common->curaid = bss_conf->aid;
-                       ath5k_hw_set_associd(ah);
+                       ath5k_hw_set_bssid(ah);
                        /* Once ANI is available you would start it here */
                }
        }