summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c17
4 files changed, 21 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 46dc41a16faa..77b359162d6c 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -107,12 +107,14 @@ static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
static void hif_usb_tx_cb(struct urb *urb)
{
struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
- struct hif_device_usb *hif_dev = tx_buf->hif_dev;
+ struct hif_device_usb *hif_dev;
struct sk_buff *skb;
- if (!hif_dev || !tx_buf)
+ if (!tx_buf || !tx_buf->hif_dev)
return;
+ hif_dev = tx_buf->hif_dev;
+
switch (urb->status) {
case 0:
break;
@@ -607,6 +609,10 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
return 0;
err:
+ if (tx_buf) {
+ kfree(tx_buf->buf);
+ kfree(tx_buf);
+ }
ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
return -ENOMEM;
}
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index ad556aa8da39..c251603ab032 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -23,6 +23,7 @@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/leds.h>
+#include <linux/slab.h>
#include <net/mac80211.h>
#include "common.h"
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 257b10ba6f57..1ec836cf1c0d 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -28,7 +28,6 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
- { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
{ 0 }
};
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index ba139132c85f..ca6065b71b46 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -19,6 +19,12 @@
#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))
+static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
+{
+ return sc->ps_enabled &&
+ (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP);
+}
+
static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
struct ieee80211_hdr *hdr)
{
@@ -616,8 +622,8 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
hdr = (struct ieee80211_hdr *)skb->data;
/* Process Beacon and CAB receive in PS state */
- if ((sc->ps_flags & PS_WAIT_FOR_BEACON) &&
- ieee80211_is_beacon(hdr->frame_control))
+ if (((sc->ps_flags & PS_WAIT_FOR_BEACON) || ath9k_check_auto_sleep(sc))
+ && ieee80211_is_beacon(hdr->frame_control))
ath_rx_ps_beacon(sc, skb);
else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
(ieee80211_is_data(hdr->frame_control) ||
@@ -932,9 +938,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
sc->rx.rxotherant = 0;
}
- if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON |
- PS_WAIT_FOR_CAB |
- PS_WAIT_FOR_PSPOLL_DATA)))
+ if (unlikely(ath9k_check_auto_sleep(sc) ||
+ (sc->ps_flags & (PS_WAIT_FOR_BEACON |
+ PS_WAIT_FOR_CAB |
+ PS_WAIT_FOR_PSPOLL_DATA))))
ath_rx_ps(sc, skb);
ath_rx_send_to_mac80211(hw, sc, skb, rxs);