From 0ced0e176ab854df15bd307188decba9c06650e5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 8 Jan 2009 13:32:13 +0200 Subject: ath9k: Setup MFP options for CCMP Configure hardware CCMP for management frame protection and use software crypto when needed. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 462e08c..dbf24be 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -593,6 +593,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) if (test_bit(keyix, sc->sc_keymap)) rx_status.flag |= RX_FLAG_DECRYPTED; } + if (ah->sw_mgmt_crypto && + (rx_status.flag & RX_FLAG_DECRYPTED) && + ieee80211_is_mgmt(hdr->frame_control)) { + /* Use software decrypt for management frames. */ + rx_status.flag &= ~RX_FLAG_DECRYPTED; + } /* Send the frame to mac80211 */ __ieee80211_rx(sc->hw, skb, &rx_status); -- cgit v1.1 From f5870acb3a8e2cad57b6c5ffd3157a7dfbb47942 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 Jan 2009 20:17:02 +0100 Subject: ath9k: convert to struct device Convert 'struct pci_dev' to 'struct device' to make it usable on the AHB bus as well. Changes-licensed-under: ISC Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Tested-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index dbf24be..645fae2 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -291,10 +291,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) } bf->bf_mpdu = skb; - bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, + bf->bf_buf_addr = pci_map_single(to_pci_dev(sc->dev), + skb->data, sc->rx.bufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(sc->pdev, + if (unlikely(pci_dma_mapping_error(to_pci_dev(sc->dev), bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; @@ -524,7 +525,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * 1. accessing the frame * 2. requeueing the same buffer to h/w */ - pci_dma_sync_single_for_cpu(sc->pdev, bf->bf_buf_addr, + pci_dma_sync_single_for_cpu(to_pci_dev(sc->dev), + bf->bf_buf_addr, sc->rx.bufsize, PCI_DMA_FROMDEVICE); @@ -557,7 +559,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) goto requeue; /* Unmap the frame */ - pci_unmap_single(sc->pdev, bf->bf_buf_addr, + pci_unmap_single(to_pci_dev(sc->dev), bf->bf_buf_addr, sc->rx.bufsize, PCI_DMA_FROMDEVICE); @@ -605,10 +607,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; - bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, + bf->bf_buf_addr = pci_map_single(to_pci_dev(sc->dev), + requeue_skb->data, sc->rx.bufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(sc->pdev, + if (unlikely(pci_dma_mapping_error(to_pci_dev(sc->dev), bf->bf_buf_addr))) { dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; -- cgit v1.1 From 7da3c55ce849e17fd9017c7bf770a03fa083d95b Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 14 Jan 2009 20:17:03 +0100 Subject: ath9k: convert to use bus-agnostic DMA routines Convert to use bus-agnostic DMA routines to make it usable on AHB bus as well. Changes-licensed-under: ISC Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Tested-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 645fae2..648bb49 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -291,16 +291,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) } bf->bf_mpdu = skb; - bf->bf_buf_addr = pci_map_single(to_pci_dev(sc->dev), - skb->data, + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, sc->rx.bufsize, - PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(to_pci_dev(sc->dev), + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; DPRINTF(sc, ATH_DBG_CONFIG, - "pci_dma_mapping_error() on RX init\n"); + "dma_mapping_error() on RX init\n"); error = -ENOMEM; break; } @@ -525,10 +524,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) * 1. accessing the frame * 2. requeueing the same buffer to h/w */ - pci_dma_sync_single_for_cpu(to_pci_dev(sc->dev), - bf->bf_buf_addr, + dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, sc->rx.bufsize, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); /* * If we're asked to flush receive queue, directly @@ -559,9 +557,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) goto requeue; /* Unmap the frame */ - pci_unmap_single(to_pci_dev(sc->dev), bf->bf_buf_addr, + dma_unmap_single(sc->dev, bf->bf_buf_addr, sc->rx.bufsize, - PCI_DMA_FROMDEVICE); + DMA_FROM_DEVICE); skb_put(skb, ds->ds_rxstat.rs_datalen); skb->protocol = cpu_to_be16(ETH_P_CONTROL); @@ -607,16 +605,15 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; - bf->bf_buf_addr = pci_map_single(to_pci_dev(sc->dev), - requeue_skb->data, + bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, sc->rx.bufsize, - PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(to_pci_dev(sc->dev), + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; DPRINTF(sc, ATH_DBG_CONFIG, - "pci_dma_mapping_error() on RX\n"); + "dma_mapping_error() on RX\n"); break; } bf->bf_dmacontext = bf->bf_buf_addr; -- cgit v1.1 From 3cbb5dd73697b3f1c677daffe29f00ace22b71e9 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Tue, 20 Jan 2009 11:17:08 +0530 Subject: ath9k: Enable dynamic power save in ath9k. This patch implements dynamic power save feature for ath9k. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 648bb49..8da08f9 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -628,6 +628,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) } else { sc->rx.rxotherant = 0; } + + if (ieee80211_is_beacon(hdr->frame_control) && + (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { + sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); + } requeue: list_move_tail(&bf->list, &sc->rx.rxbuf); ath_rx_buf_link(sc, bf); -- cgit v1.1 From d42c6b71a8e722e00a302e7e3365909560de478a Mon Sep 17 00:00:00 2001 From: Sujith Date: Wed, 4 Feb 2009 08:10:22 +0530 Subject: ath9k: Handle mac80211's FIF_CONTROL flag properly Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 8da08f9..630fa57 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -372,6 +372,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt &= ~ATH9K_RX_FILTER_UCAST; } + if (sc->rx.rxfilter & FIF_CONTROL) + rfilt |= ATH9K_RX_FILTER_CONTROL; + if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION || sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) rfilt |= ATH9K_RX_FILTER_BEACON; -- cgit v1.1 From 394cf0a1ca02e7998c8d01975b60a3cdc121e7d8 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:26:54 +0530 Subject: ath9k: Header file cleanup Split the core header files into manageable pieces. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 630fa57..69dd5e2 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -14,7 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "core.h" +#include "ath9k.h" /* * Setup and link descriptors. -- cgit v1.1 From 17d7904de85125c62c7258d7cb21207f26d04048 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:03 +0530 Subject: ath9k: Remove all the sc_ prefixes This patch removes the useless sc_ prefixes for all variables. Also, refer to interfaces as VIFs and not as VAPs anymore. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 69dd5e2..e8e4a32 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -97,11 +97,11 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) * Unfortunately this means we may get 8 KB here from the * kernel... and that is actually what is observed on some * systems :( */ - skb = dev_alloc_skb(len + sc->sc_cachelsz - 1); + skb = dev_alloc_skb(len + sc->cachelsz - 1); if (skb != NULL) { - off = ((unsigned long) skb->data) % sc->sc_cachelsz; + off = ((unsigned long) skb->data) % sc->cachelsz; if (off != 0) - skb_reserve(skb, sc->sc_cachelsz - off); + skb_reserve(skb, sc->cachelsz - off); } else { DPRINTF(sc, ATH_DBG_FATAL, "skbuff alloc of size %u failed\n", len); @@ -210,7 +210,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); rx_status->band = sc->hw->conf.channel->band; rx_status->freq = sc->hw->conf.channel->center_freq; - rx_status->noise = sc->sc_ani.sc_noise_floor; + rx_status->noise = sc->ani.noise_floor; rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; rx_status->antenna = ds->ds_rxstat.rs_antenna; @@ -242,13 +242,13 @@ static void ath_opmode_init(struct ath_softc *sc) /* configure bssid mask */ if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); + ath9k_hw_setbssidmask(ah, sc->bssidmask); /* configure operational mode */ ath9k_hw_setopmode(ah); /* Handle any link-level address change. */ - ath9k_hw_setmac(ah, sc->sc_myaddr); + ath9k_hw_setmac(ah, sc->macaddr); /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; @@ -267,11 +267,11 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) spin_lock_init(&sc->rx.rxbuflock); sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, - min(sc->sc_cachelsz, + min(sc->cachelsz, (u16)64)); DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", - sc->sc_cachelsz, sc->rx.bufsize); + sc->cachelsz, sc->rx.bufsize); /* Initialize rx descriptors */ @@ -593,7 +593,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) && !decrypt_error && skb->len >= hdrlen + 4) { keyix = skb->data[hdrlen + 3] >> 6; - if (test_bit(keyix, sc->sc_keymap)) + if (test_bit(keyix, sc->keymap)) rx_status.flag |= RX_FLAG_DECRYPTED; } if (ah->sw_mgmt_crypto && -- cgit v1.1 From ba52da58be0acf3b7775972b2b5234ce64388c79 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:10 +0530 Subject: ath9k: Remove duplicate variables A few variables (bssid, bssidmask, curaid) were duplicated in struct ath_softc and in ath_hal, remove them. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index e8e4a32..c51c085 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -242,13 +242,13 @@ static void ath_opmode_init(struct ath_softc *sc) /* configure bssid mask */ if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath9k_hw_setbssidmask(ah, sc->bssidmask); + ath9k_hw_setbssidmask(sc); /* configure operational mode */ ath9k_hw_setopmode(ah); /* Handle any link-level address change. */ - ath9k_hw_setmac(ah, sc->macaddr); + ath9k_hw_setmac(ah, sc->sc_ah->macaddr); /* calculate and install multicast filter */ mfilt[0] = mfilt[1] = ~0; -- cgit v1.1 From cbe61d8a41210600bc76b212edcd4dc0f55c014f Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:12 +0530 Subject: ath9k: Merge ath_hal and ath_hal_5416 structures Finally, merge these structures and have a single HW specific data structure. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index c51c085..7c011b1 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -26,7 +26,7 @@ */ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) { - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; struct ath_desc *ds; struct sk_buff *skb; @@ -233,7 +233,7 @@ rx_next: static void ath_opmode_init(struct ath_softc *sc) { - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; u32 rfilt, mfilt[2]; /* configure rx filter */ @@ -391,7 +391,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) int ath_startrecv(struct ath_softc *sc) { - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; struct ath_buf *bf, *tbf; spin_lock_bh(&sc->rx.rxbuflock); @@ -421,7 +421,7 @@ start_recv: bool ath_stoprecv(struct ath_softc *sc) { - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; bool stopped; ath9k_hw_stoppcurecv(ah); @@ -452,7 +452,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) struct ath_desc *ds; struct sk_buff *skb = NULL, *requeue_skb; struct ieee80211_rx_status rx_status; - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; struct ieee80211_hdr *hdr; int hdrlen, padsize, retval; bool decrypt_error = false; -- cgit v1.1 From 2660b81a378ab227b78c4cc618453fa7e19a7c7b Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:26 +0530 Subject: ath9k: Remove all the useless ah_ variable prefixes Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 7c011b1..08f676a 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -135,7 +135,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, * discard the frame. Enable this if you want to see * error frames in Monitor mode. */ - if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR) + if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR) goto rx_next; } else if (ds->ds_rxstat.rs_status != 0) { if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) @@ -161,7 +161,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, * decryption and MIC failures. For monitor mode, * we also ignore the CRC error. */ - if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) { + if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) { if (ds->ds_rxstat.rs_status & ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ATH9K_RXERR_CRC)) @@ -241,7 +241,7 @@ static void ath_opmode_init(struct ath_softc *sc) ath9k_hw_setrxfilter(ah, rfilt); /* configure bssid mask */ - if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) + if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) ath9k_hw_setbssidmask(sc); /* configure operational mode */ @@ -360,13 +360,13 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | ATH9K_RX_FILTER_MCAST; /* If not a STA, enable processing of Probe Requests */ - if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION) + if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* Can't set HOSTAP into promiscous mode */ - if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) && + if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) { + (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) { rfilt |= ATH9K_RX_FILTER_PROM; /* ??? To prevent from sending ACK */ rfilt &= ~ATH9K_RX_FILTER_UCAST; @@ -375,13 +375,13 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (sc->rx.rxfilter & FIF_CONTROL) rfilt |= ATH9K_RX_FILTER_CONTROL; - if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION || - sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) + if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION || + sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames & beacon frames */ - if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) + if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); return rfilt; -- cgit v1.1 From 0caa7b14f36e8c3c43dd9294a960ae55cafe07fb Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 16 Feb 2009 13:23:20 +0530 Subject: ath9k: Fix HW wait timeout RX and calibration have different timeout requirements. This patch fixes it by changing the HW wait routine to accept a timeout value. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 08f676a..28ad1d5 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -427,7 +427,6 @@ bool ath_stoprecv(struct ath_softc *sc) ath9k_hw_stoppcurecv(ah); ath9k_hw_setrxfilter(ah, 0); stopped = ath9k_hw_stopdmarecv(ah); - mdelay(3); /* 3ms is long enough for 1 frame */ sc->rx.rxlink = NULL; return stopped; -- cgit v1.1 From dbaaa147d6396c41d8f31156a777dfdaae2335a4 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 19 Feb 2009 15:41:52 +0530 Subject: ath9k: Filter out beacons from other BSS in STA mode Passing beacons received from other BSS to s/w in non-scanning state is unnecessary in STA mode. This patch filters them out in h/w. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 28ad1d5..23b6f54 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -375,14 +375,15 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (sc->rx.rxfilter & FIF_CONTROL) rfilt |= ATH9K_RX_FILTER_CONTROL; - if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION || - sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) + if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && + !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) + rfilt |= ATH9K_RX_FILTER_MYBEACON; + else rfilt |= ATH9K_RX_FILTER_BEACON; - /* If in HOSTAP mode, want to enable reception of PSPOLL frames - & beacon frames */ + /* If in HOSTAP mode, want to enable reception of PSPOLL frames */ if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) - rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); + rfilt |= ATH9K_RX_FILTER_PSPOLL; return rfilt; -- cgit v1.1 From bce048d77dff3dcfd75d54dc38580c81baa95853 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Mar 2009 19:23:28 +0200 Subject: ath9k: Add data structure for supporting virtual radio/wiphy operation This is the initial step in allowing ath9k to register multiple virtual radios (wiphys). The goal of virtual radios is to allow the same radio to be shared for multiple virtual interfaces that may operate on different channels. The mac80211 virtual interface support is designed only for single channel operation and as such, it is not suitable for this type of use. Anyway, it can be used on top of the virtual radio concept, if desired (e.g., use two virtual radios to handle two channels and then add multiple mac80211 virtual interfaces on top of each virtual radio). The new struct ath_wiphy is now registered as the driver data structure for wiphy. This structure has a pointer to the shared (among virtual wiphys of the same physical radio) struct ath_softc data. The primary wiphy maintains the allocated memory for ath_softc. Secondary (virtual) wiphys will only allocate the new ath_wiphy structure. Registration of secondary wiphys is added in a separate patch. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 23b6f54..ec53583 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -16,6 +16,12 @@ #include "ath9k.h" +static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, + struct ieee80211_hdr *hdr) +{ + return sc->pri_wiphy->hw; +} + /* * Setup and link descriptors. * @@ -123,10 +129,12 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, struct ieee80211_hdr *hdr; u8 ratecode; __le16 fc; + struct ieee80211_hw *hw; hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); + hw = ath_get_virt_hw(sc, hdr); if (ds->ds_rxstat.rs_more) { /* @@ -186,7 +194,6 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, rx_status->rate_idx = ratecode & 0x7f; } else { int i = 0, cur_band, n_rates; - struct ieee80211_hw *hw = sc->hw; cur_band = hw->conf.channel->band; n_rates = sc->sbands[cur_band].n_bitrates; @@ -208,8 +215,8 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, } rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); - rx_status->band = sc->hw->conf.channel->band; - rx_status->freq = sc->hw->conf.channel->center_freq; + rx_status->band = hw->conf.channel->band; + rx_status->freq = hw->conf.channel->center_freq; rx_status->noise = sc->ani.noise_floor; rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; rx_status->antenna = ds->ds_rxstat.rs_antenna; @@ -604,7 +611,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) } /* Send the frame to mac80211 */ - __ieee80211_rx(sc->hw, skb, &rx_status); + __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, &rx_status); /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; -- cgit v1.1 From c52f33d05e5f8d59f02722fbc308f5f391575ca5 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Mar 2009 19:23:29 +0200 Subject: ath9k: Add support for multiple secondary virtual wiphys The new struct ath_softc::sec_wiphy array is used to store information about virtual wiphys and select which wiphy is used in calls to mac80211. Each virtual wiphy will be assigned a different MAC address based on the virtual wiphy index. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index ec53583..a9a55df 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -19,7 +19,22 @@ static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, struct ieee80211_hdr *hdr) { - return sc->pri_wiphy->hw; + struct ieee80211_hw *hw = sc->pri_wiphy->hw; + int i; + + spin_lock_bh(&sc->wiphy_lock); + for (i = 0; i < sc->num_sec_wiphy; i++) { + struct ath_wiphy *aphy = sc->sec_wiphy[i]; + if (aphy == NULL) + continue; + if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr) + == 0) { + hw = aphy->hw; + break; + } + } + spin_unlock_bh(&sc->wiphy_lock); + return hw; } /* @@ -611,7 +626,29 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) } /* Send the frame to mac80211 */ - __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, &rx_status); + if (hdr->addr1[5] & 0x01) { + int i; + /* + * Deliver broadcast/multicast frames to all suitable + * virtual wiphys. + */ + /* TODO: filter based on channel configuration */ + for (i = 0; i < sc->num_sec_wiphy; i++) { + struct ath_wiphy *aphy = sc->sec_wiphy[i]; + struct sk_buff *nskb; + if (aphy == NULL) + continue; + nskb = skb_copy(skb, GFP_ATOMIC); + if (nskb) + __ieee80211_rx(aphy->hw, nskb, + &rx_status); + } + __ieee80211_rx(sc->hw, skb, &rx_status); + } else { + /* Deliver unicast frames based on receiver address */ + __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, + &rx_status); + } /* We will now give hardware our shiny new allocated skb */ bf->bf_mpdu = requeue_skb; -- cgit v1.1 From b93bce2a5e8fd5c9f5d8c982efd6bca71a9b83f3 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Mar 2009 19:23:30 +0200 Subject: ath9k: Configure RX filter for multi-BSSID broadcast Allow RX filter to pass through all broadcast/multicast frames (i.e., no BSSID filtering) if virtual interfaces are used. Software filtering will be used in this case to drop broadcast/multicast frames for foreign BSSIDs. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index a9a55df..3df5c78 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -407,6 +407,14 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) rfilt |= ATH9K_RX_FILTER_PSPOLL; + if (sc->sec_wiphy) { + /* TODO: only needed if more than one BSSID is in use in + * station/adhoc mode */ + /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM + */ + rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; + } + return rfilt; #undef RX_FILTER_PRESERVE -- cgit v1.1 From f0e6ce13c17afd74a49e0ef043d72581562f73ae Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Fri, 6 Mar 2009 11:24:08 +0530 Subject: ath9k: Get rid of unnecessary ATOMIC memory alloc during init time We can sleep for memory during init time and so allocating rx buffers, descriptro buffers with GFP_KERNEL should help us to get rid of transient alloc fails. Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 3df5c78..9439cb3 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -100,7 +100,7 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) return (tsf & ~0x7fff) | rstamp; } -static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) +static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask) { struct sk_buff *skb; u32 off; @@ -118,7 +118,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) * Unfortunately this means we may get 8 KB here from the * kernel... and that is actually what is observed on some * systems :( */ - skb = dev_alloc_skb(len + sc->cachelsz - 1); + skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask); if (skb != NULL) { off = ((unsigned long) skb->data) % sc->cachelsz; if (off != 0) @@ -306,7 +306,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) } list_for_each_entry(bf, &sc->rx.rxbuf, list) { - skb = ath_rxbuf_alloc(sc, sc->rx.bufsize); + skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); if (skb == NULL) { error = -ENOMEM; break; @@ -580,7 +580,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* Ensure we always have an skb to requeue once we are done * processing the current buffer's skb */ - requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize); + requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC); /* If there is no memory we ignore the current RX'd frame, * tell hardware it can give us a new frame using the old -- cgit v1.1 From 217ba9da8ea6bb270a1f463367083cc5d99f2493 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 10 Mar 2009 10:55:50 +0200 Subject: ath9k: Fix FIF_PROMISC_IN_BSS processing in station mode We must not disable ACK sending in this case since it would break normal station operations. In addition, clarify the comment about AP mode to make more sense. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 9439cb3..0bba176 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -385,14 +385,15 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) rfilt |= ATH9K_RX_FILTER_PROBEREQ; - /* Can't set HOSTAP into promiscous mode */ + /* + * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station + * mode interface or when in monitor mode. AP mode does not need this + * since it receives all in-BSS frames anyway. + */ if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) { + (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) rfilt |= ATH9K_RX_FILTER_PROM; - /* ??? To prevent from sending ACK */ - rfilt &= ~ATH9K_RX_FILTER_UCAST; - } if (sc->rx.rxfilter & FIF_CONTROL) rfilt |= ATH9K_RX_FILTER_CONTROL; -- cgit v1.1 From cee075a24eec64f1f5b2b3b14753b2d4b8ecce55 Mon Sep 17 00:00:00 2001 From: Sujith Date: Fri, 13 Mar 2009 09:07:23 +0530 Subject: ath9k: Update copyright in all the files How time flies. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 0bba176..917bac7 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Atheros Communications Inc. + * Copyright (c) 2008-2009 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above -- cgit v1.1 From 051b919188650fe4c93ca8701183ae88439388f6 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 23 Mar 2009 18:25:01 -0400 Subject: ath9k: fix dma mapping leak of rx buffer upon rmmod We were claiming DMA buffers on the RX tasklet but never upon a simple module removal. Cc: stable@kernel.org Signed-off-by: FUJITA Tomonori Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/recv.c') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 917bac7..71cb18d 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c @@ -344,8 +344,13 @@ void ath_rx_cleanup(struct ath_softc *sc) list_for_each_entry(bf, &sc->rx.rxbuf, list) { skb = bf->bf_mpdu; - if (skb) + if (skb) { + dma_unmap_single(sc->dev, + bf->bf_buf_addr, + sc->rx.bufsize, + DMA_FROM_DEVICE); dev_kfree_skb(skb); + } } if (sc->rx.rxdma.dd_desc_len != 0) -- cgit v1.1