提交 a8519de4 编写于 作者: D David S. Miller
...@@ -3583,9 +3583,12 @@ M: "John W. Linville" <linville@tuxdriver.com> ...@@ -3583,9 +3583,12 @@ M: "John W. Linville" <linville@tuxdriver.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
S: Maintained S: Maintained
F: net/mac80211/
F: net/rfkill/
F: net/wireless/ F: net/wireless/
F: include/net/ieee80211* F: include/net/ieee80211*
F: include/linux/wireless.h F: include/linux/wireless.h
F: drivers/net/wireless/
NETWORKING DRIVERS NETWORKING DRIVERS
L: netdev@vger.kernel.org L: netdev@vger.kernel.org
...@@ -5577,7 +5580,16 @@ L: linux-wireless@vger.kernel.org ...@@ -5577,7 +5580,16 @@ L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org W: http://wireless.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained S: Maintained
F: drivers/net/wireless/wl12xx/wl1251* F: drivers/net/wireless/wl12xx/*
X: drivers/net/wireless/wl12xx/wl1271*
WL1271 WIRELESS DRIVER
M: Luciano Coelho <luciano.coelho@nokia.com>
L: linux-wireless@vger.kernel.org
W: http://wireless.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
S: Maintained
F: drivers/net/wireless/wl12xx/wl1271*
WL3501 WIRELESS PCMCIA CARD DRIVER WL3501 WIRELESS PCMCIA CARD DRIVER
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
......
...@@ -233,6 +233,11 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb) ...@@ -233,6 +233,11 @@ void usbnet_skb_return (struct usbnet *dev, struct sk_buff *skb)
{ {
int status; int status;
if (test_bit(EVENT_RX_PAUSED, &dev->flags)) {
skb_queue_tail(&dev->rxq_pause, skb);
return;
}
skb->protocol = eth_type_trans (skb, dev->net); skb->protocol = eth_type_trans (skb, dev->net);
dev->net->stats.rx_packets++; dev->net->stats.rx_packets++;
dev->net->stats.rx_bytes += skb->len; dev->net->stats.rx_bytes += skb->len;
...@@ -525,6 +530,41 @@ static void intr_complete (struct urb *urb) ...@@ -525,6 +530,41 @@ static void intr_complete (struct urb *urb)
deverr(dev, "intr resubmit --> %d", status); deverr(dev, "intr resubmit --> %d", status);
} }
/*-------------------------------------------------------------------------*/
void usbnet_pause_rx(struct usbnet *dev)
{
set_bit(EVENT_RX_PAUSED, &dev->flags);
if (netif_msg_rx_status(dev))
devdbg(dev, "paused rx queue enabled");
}
EXPORT_SYMBOL_GPL(usbnet_pause_rx);
void usbnet_resume_rx(struct usbnet *dev)
{
struct sk_buff *skb;
int num = 0;
clear_bit(EVENT_RX_PAUSED, &dev->flags);
while ((skb = skb_dequeue(&dev->rxq_pause)) != NULL) {
usbnet_skb_return(dev, skb);
num++;
}
tasklet_schedule(&dev->bh);
if (netif_msg_rx_status(dev))
devdbg(dev, "paused rx queue disabled, %d skbs requeued", num);
}
EXPORT_SYMBOL_GPL(usbnet_resume_rx);
void usbnet_purge_paused_rxq(struct usbnet *dev)
{
skb_queue_purge(&dev->rxq_pause);
}
EXPORT_SYMBOL_GPL(usbnet_purge_paused_rxq);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
// unlink pending rx/tx; completion handlers do all other cleanup // unlink pending rx/tx; completion handlers do all other cleanup
...@@ -623,6 +663,8 @@ int usbnet_stop (struct net_device *net) ...@@ -623,6 +663,8 @@ int usbnet_stop (struct net_device *net)
usb_kill_urb(dev->interrupt); usb_kill_urb(dev->interrupt);
usbnet_purge_paused_rxq(dev);
/* deferred work (task, timer, softirq) must also stop. /* deferred work (task, timer, softirq) must also stop.
* can't flush_scheduled_work() until we drop rtnl (later), * can't flush_scheduled_work() until we drop rtnl (later),
* else workers could deadlock; so make workers a NOP. * else workers could deadlock; so make workers a NOP.
...@@ -1113,7 +1155,6 @@ static void usbnet_bh (unsigned long param) ...@@ -1113,7 +1155,6 @@ static void usbnet_bh (unsigned long param)
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* USB Device Driver support * USB Device Driver support
...@@ -1210,6 +1251,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -1210,6 +1251,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
skb_queue_head_init (&dev->rxq); skb_queue_head_init (&dev->rxq);
skb_queue_head_init (&dev->txq); skb_queue_head_init (&dev->txq);
skb_queue_head_init (&dev->done); skb_queue_head_init (&dev->done);
skb_queue_head_init(&dev->rxq_pause);
dev->bh.func = usbnet_bh; dev->bh.func = usbnet_bh;
dev->bh.data = (unsigned long) dev; dev->bh.data = (unsigned long) dev;
INIT_WORK (&dev->kevent, kevent); INIT_WORK (&dev->kevent, kevent);
......
...@@ -5,9 +5,7 @@ menuconfig ATH_COMMON ...@@ -5,9 +5,7 @@ menuconfig ATH_COMMON
---help--- ---help---
This will enable the support for the Atheros wireless drivers. This will enable the support for the Atheros wireless drivers.
ath5k, ath9k and ar9170 drivers share some common code, this option ath5k, ath9k and ar9170 drivers share some common code, this option
enables the common ath.ko module which currently shares just common enables the common ath.ko module which shares common helpers.
regulatory EEPROM helpers but will likely be extended later to share
more between modules.
For more information and documentation on this module you can visit: For more information and documentation on this module you can visit:
......
/*
* 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
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef ATH_H
#define ATH_H
#include <linux/skbuff.h>
struct ath_common {
u16 cachelsz;
};
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
u32 len,
gfp_t gfp_mask);
#endif /* ATH_H */
...@@ -919,6 +919,12 @@ enum ath5k_int { ...@@ -919,6 +919,12 @@ enum ath5k_int {
AR5K_INT_NOCARD = 0xffffffff AR5K_INT_NOCARD = 0xffffffff
}; };
/* Software interrupts used for calibration */
enum ath5k_software_interrupt {
AR5K_SWI_FULL_CALIBRATION = 0x01,
AR5K_SWI_SHORT_CALIBRATION = 0x02,
};
/* /*
* Power management * Power management
*/ */
...@@ -1123,6 +1129,15 @@ struct ath5k_hw { ...@@ -1123,6 +1129,15 @@ struct ath5k_hw {
/* noise floor from last periodic calibration */ /* noise floor from last periodic calibration */
s32 ah_noise_floor; s32 ah_noise_floor;
/* Calibration timestamp */
unsigned long ah_cal_tstamp;
/* Calibration interval (secs) */
u8 ah_cal_intval;
/* Software interrupt mask */
u8 ah_swi_mask;
/* /*
* Function pointers * Function pointers
*/ */
...@@ -1157,6 +1172,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc); ...@@ -1157,6 +1172,7 @@ extern void ath5k_unregister_leds(struct ath5k_softc *sc);
/* Reset Functions */ /* Reset Functions */
extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
extern int ath5k_hw_on_hold(struct ath5k_hw *ah);
extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
/* Power management functions */ /* Power management functions */
extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
...@@ -1275,6 +1291,7 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann ...@@ -1275,6 +1291,7 @@ extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *chann
/* PHY calibration */ /* PHY calibration */
extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah);
/* Spur mitigation */ /* Spur mitigation */
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
struct ieee80211_channel *channel); struct ieee80211_channel *channel);
......
...@@ -145,7 +145,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ...@@ -145,7 +145,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free; goto err_free;
/* Bring device out of sleep and reset it's units */ /* Bring device out of sleep and reset it's units */
ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true); ret = ath5k_hw_nic_wakeup(ah, 0, true);
if (ret) if (ret)
goto err_free; goto err_free;
...@@ -252,28 +252,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ...@@ -252,28 +252,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free; goto err_free;
} }
/*
* Write PCI-E power save settings
*/
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
/* Shut off RX when elecidle is asserted */
ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
/* TODO: EEPROM work */
ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
/* Shut off PLL and CLKREQ active in L1 */
ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
/* Preserce other settings */
ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
/* Reset SERDES to load new settings */
ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
mdelay(1);
}
/* /*
* POST * POST
*/ */
...@@ -283,7 +261,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ...@@ -283,7 +261,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
/* Enable pci core retry fix on Hainan (5213A) and later chips */ /* Enable pci core retry fix on Hainan (5213A) and later chips */
if (srev >= AR5K_SREV_AR5213A) if (srev >= AR5K_SREV_AR5213A)
ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_RETRY_FIX);
/* /*
* Get card capabilities, calibration values etc * Get card capabilities, calibration values etc
...@@ -295,6 +273,40 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ...@@ -295,6 +273,40 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free; goto err_free;
} }
/*
* Write PCI-E power save settings
*/
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
/* Shut off RX when elecidle is asserted */
ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
/* If serdes programing is enabled, increase PCI-E
* tx power for systems with long trace from host
* to minicard connector. */
if (ee->ee_serdes)
ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
else
ath5k_hw_reg_write(ah, 0xf6800579, AR5K_PCIE_SERDES);
/* Shut off PLL and CLKREQ active in L1 */
ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
/* Preserve other settings */
ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
/* Reset SERDES to load new settings */
ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
mdelay(1);
}
/* Get misc capabilities */ /* Get misc capabilities */
ret = ath5k_hw_set_capabilities(ah); ret = ath5k_hw_set_capabilities(ah);
if (ret) { if (ret) {
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
#include "reg.h" #include "reg.h"
#include "debug.h" #include "debug.h"
static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
static int modparam_nohwcrypt; static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
...@@ -376,7 +376,7 @@ static int ath5k_stop_hw(struct ath5k_softc *sc); ...@@ -376,7 +376,7 @@ static int ath5k_stop_hw(struct ath5k_softc *sc);
static irqreturn_t ath5k_intr(int irq, void *dev_id); static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void ath5k_tasklet_reset(unsigned long data); static void ath5k_tasklet_reset(unsigned long data);
static void ath5k_calibrate(unsigned long data); static void ath5k_tasklet_calibrate(unsigned long data);
/* /*
* Module init/exit functions * Module init/exit functions
...@@ -471,7 +471,7 @@ ath5k_pci_probe(struct pci_dev *pdev, ...@@ -471,7 +471,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
* DMA to work so force a reasonable value here if it * DMA to work so force a reasonable value here if it
* comes up zero. * comes up zero.
*/ */
csz = L1_CACHE_BYTES / sizeof(u32); csz = L1_CACHE_BYTES >> 2;
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
} }
/* /*
...@@ -544,7 +544,7 @@ ath5k_pci_probe(struct pci_dev *pdev, ...@@ -544,7 +544,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
__set_bit(ATH_STAT_INVALID, sc->status); __set_bit(ATH_STAT_INVALID, sc->status);
sc->iobase = mem; /* So we can unmap it on detach */ sc->iobase = mem; /* So we can unmap it on detach */
sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ sc->common.cachelsz = csz << 2; /* convert to bytes */
sc->opmode = NL80211_IFTYPE_STATION; sc->opmode = NL80211_IFTYPE_STATION;
sc->bintval = 1000; sc->bintval = 1000;
mutex_init(&sc->lock); mutex_init(&sc->lock);
...@@ -799,8 +799,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) ...@@ -799,8 +799,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc);
tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
ret = ath5k_eeprom_read_mac(ah, mac); ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) { if (ret) {
...@@ -1071,10 +1071,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw) ...@@ -1071,10 +1071,9 @@ ath5k_setup_bands(struct ieee80211_hw *hw)
} }
/* /*
* Set/change channels. If the channel is really being changed, * Set/change channels. We always reset the chip.
* it's done by reseting the chip. To accomplish this we must * To accomplish this we must first cleanup any pending DMA,
* first cleanup any pending DMA, then restart stuff after a la * then restart stuff after a la ath5k_init.
* ath5k_init.
* *
* Called with sc->lock. * Called with sc->lock.
*/ */
...@@ -1084,19 +1083,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) ...@@ -1084,19 +1083,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
sc->curchan->center_freq, chan->center_freq); sc->curchan->center_freq, chan->center_freq);
if (chan->center_freq != sc->curchan->center_freq || /*
chan->hw_value != sc->curchan->hw_value) { * To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the
/* * hardware at the new frequency, and then re-enable
* To switch channels clear any pending DMA operations; * the relevant bits of the h/w.
* wait long enough for the RX fifo to drain, reset the */
* hardware at the new frequency, and then re-enable return ath5k_reset(sc, chan);
* the relevant bits of the h/w.
*/
return ath5k_reset(sc, chan);
}
return 0;
} }
static void static void
...@@ -1158,27 +1151,20 @@ static ...@@ -1158,27 +1151,20 @@ static
struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
{ {
struct sk_buff *skb; struct sk_buff *skb;
unsigned int off;
/* /*
* Allocate buffer with headroom_needed space for the * Allocate buffer with headroom_needed space for the
* fake physical layer header at the start. * fake physical layer header at the start.
*/ */
skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1); skb = ath_rxbuf_alloc(&sc->common,
sc->rxbufsize + sc->common.cachelsz - 1,
GFP_ATOMIC);
if (!skb) { if (!skb) {
ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
sc->rxbufsize + sc->cachelsz - 1); sc->rxbufsize + sc->common.cachelsz - 1);
return NULL; return NULL;
} }
/*
* Cache-line-align. This is important (for the
* 5210 at least) as not doing so causes bogus data
* in rx'd frames.
*/
off = ((unsigned long)skb->data) % sc->cachelsz;
if (off != 0)
skb_reserve(skb, sc->cachelsz - off);
*skb_addr = pci_map_single(sc->pdev, *skb_addr = pci_map_single(sc->pdev,
skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
...@@ -1620,10 +1606,10 @@ ath5k_rx_start(struct ath5k_softc *sc) ...@@ -1620,10 +1606,10 @@ ath5k_rx_start(struct ath5k_softc *sc)
struct ath5k_buf *bf; struct ath5k_buf *bf;
int ret; int ret;
sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz); sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n", ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
sc->cachelsz, sc->rxbufsize); sc->common.cachelsz, sc->rxbufsize);
spin_lock_bh(&sc->rxbuflock); spin_lock_bh(&sc->rxbuflock);
sc->rxlink = NULL; sc->rxlink = NULL;
...@@ -2371,7 +2357,7 @@ ath5k_init(struct ath5k_softc *sc) ...@@ -2371,7 +2357,7 @@ ath5k_init(struct ath5k_softc *sc)
sc->curband = &sc->sbands[sc->curchan->band]; sc->curband = &sc->sbands[sc->curchan->band];
sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
AR5K_INT_FATAL | AR5K_INT_GLOBAL; AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI;
ret = ath5k_reset(sc, NULL); ret = ath5k_reset(sc, NULL);
if (ret) if (ret)
goto done; goto done;
...@@ -2388,8 +2374,8 @@ ath5k_init(struct ath5k_softc *sc) ...@@ -2388,8 +2374,8 @@ ath5k_init(struct ath5k_softc *sc)
/* Set ack to be sent at low bit-rates */ /* Set ack to be sent at low bit-rates */
ath5k_hw_set_ack_bitrate_high(ah, false); ath5k_hw_set_ack_bitrate_high(ah, false);
mod_timer(&sc->calib_tim, round_jiffies(jiffies + /* Set PHY calibration inteval */
msecs_to_jiffies(ath5k_calinterval * 1000))); ah->ah_cal_intval = ath5k_calinterval;
ret = 0; ret = 0;
done: done:
...@@ -2453,37 +2439,39 @@ ath5k_stop_hw(struct ath5k_softc *sc) ...@@ -2453,37 +2439,39 @@ ath5k_stop_hw(struct ath5k_softc *sc)
ret = ath5k_stop_locked(sc); ret = ath5k_stop_locked(sc);
if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
/* /*
* Set the chip in full sleep mode. Note that we are * Don't set the card in full sleep mode!
* careful to do this only when bringing the interface *
* completely to a stop. When the chip is in this state * a) When the device is in this state it must be carefully
* it must be carefully woken up or references to * woken up or references to registers in the PCI clock
* registers in the PCI clock domain may freeze the bus * domain may freeze the bus (and system). This varies
* (and system). This varies by chip and is mostly an * by chip and is mostly an issue with newer parts
* issue with newer parts that go to sleep more quickly. * (madwifi sources mentioned srev >= 0x78) that go to
*/ * sleep more quickly.
if (sc->ah->ah_mac_srev >= 0x78) { *
/* * b) On older chips full sleep results a weird behaviour
* XXX * during wakeup. I tested various cards with srev < 0x78
* don't put newer MAC revisions > 7.8 to sleep because * and they don't wake up after module reload, a second
* of the above mentioned problems * module reload is needed to bring the card up again.
*/ *
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, " * Until we figure out what's going on don't enable
"not putting device to sleep\n"); * full chip reset on any chip (this is what Legacy HAL
} else { * and Sam's HAL do anyway). Instead Perform a full reset
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, * on the device (same as initial state after attach) and
"putting device to full sleep\n"); * leave it idle (keep MAC/BB on warm reset) */
ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0); ret = ath5k_hw_on_hold(sc->ah);
}
ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
"putting device to sleep\n");
} }
ath5k_txbuf_free(sc, sc->bbuf); ath5k_txbuf_free(sc, sc->bbuf);
mmiowb(); mmiowb();
mutex_unlock(&sc->lock); mutex_unlock(&sc->lock);
del_timer_sync(&sc->calib_tim);
tasklet_kill(&sc->rxtq); tasklet_kill(&sc->rxtq);
tasklet_kill(&sc->txtq); tasklet_kill(&sc->txtq);
tasklet_kill(&sc->restq); tasklet_kill(&sc->restq);
tasklet_kill(&sc->calib);
tasklet_kill(&sc->beacontq); tasklet_kill(&sc->beacontq);
ath5k_rfkill_hw_stop(sc->ah); ath5k_rfkill_hw_stop(sc->ah);
...@@ -2539,6 +2527,9 @@ ath5k_intr(int irq, void *dev_id) ...@@ -2539,6 +2527,9 @@ ath5k_intr(int irq, void *dev_id)
if (status & AR5K_INT_BMISS) { if (status & AR5K_INT_BMISS) {
/* TODO */ /* TODO */
} }
if (status & AR5K_INT_SWI) {
tasklet_schedule(&sc->calib);
}
if (status & AR5K_INT_MIB) { if (status & AR5K_INT_MIB) {
/* /*
* These stats are also used for ANI i think * These stats are also used for ANI i think
...@@ -2555,6 +2546,8 @@ ath5k_intr(int irq, void *dev_id) ...@@ -2555,6 +2546,8 @@ ath5k_intr(int irq, void *dev_id)
if (unlikely(!counter)) if (unlikely(!counter))
ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
ath5k_hw_calibration_poll(ah);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -2571,11 +2564,19 @@ ath5k_tasklet_reset(unsigned long data) ...@@ -2571,11 +2564,19 @@ ath5k_tasklet_reset(unsigned long data)
* for temperature/environment changes. * for temperature/environment changes.
*/ */
static void static void
ath5k_calibrate(unsigned long data) ath5k_tasklet_calibrate(unsigned long data)
{ {
struct ath5k_softc *sc = (void *)data; struct ath5k_softc *sc = (void *)data;
struct ath5k_hw *ah = sc->ah; struct ath5k_hw *ah = sc->ah;
/* Only full calibration for now */
if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION)
return;
/* Stop queues so that calibration
* doesn't interfere with tx */
ieee80211_stop_queues(sc->hw);
ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
ieee80211_frequency_to_channel(sc->curchan->center_freq), ieee80211_frequency_to_channel(sc->curchan->center_freq),
sc->curchan->hw_value); sc->curchan->hw_value);
...@@ -2593,8 +2594,11 @@ ath5k_calibrate(unsigned long data) ...@@ -2593,8 +2594,11 @@ ath5k_calibrate(unsigned long data)
ieee80211_frequency_to_channel( ieee80211_frequency_to_channel(
sc->curchan->center_freq)); sc->curchan->center_freq));
mod_timer(&sc->calib_tim, round_jiffies(jiffies + ah->ah_swi_mask = 0;
msecs_to_jiffies(ath5k_calinterval * 1000)));
/* Wake queues */
ieee80211_wake_queues(sc->hw);
} }
...@@ -2811,9 +2815,11 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -2811,9 +2815,11 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
mutex_lock(&sc->lock); mutex_lock(&sc->lock);
ret = ath5k_chan_set(sc, conf->channel); if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
if (ret < 0) ret = ath5k_chan_set(sc, conf->channel);
goto unlock; if (ret < 0)
goto unlock;
}
if ((changed & IEEE80211_CONF_CHANGE_POWER) && if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
(sc->power_level != conf->power_level)) { (sc->power_level != conf->power_level)) {
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "ath5k.h" #include "ath5k.h"
#include "debug.h" #include "debug.h"
#include "../ath.h"
#define ATH_RXBUF 40 /* number of RX buffers */ #define ATH_RXBUF 40 /* number of RX buffers */
#define ATH_TXBUF 200 /* number of TX buffers */ #define ATH_TXBUF 200 /* number of TX buffers */
...@@ -112,6 +113,7 @@ struct ath5k_rfkill { ...@@ -112,6 +113,7 @@ struct ath5k_rfkill {
* associated with an instance of a device */ * associated with an instance of a device */
struct ath5k_softc { struct ath5k_softc {
struct pci_dev *pdev; /* for dma mapping */ struct pci_dev *pdev; /* for dma mapping */
struct ath_common common;
void __iomem *iobase; /* address of the device */ void __iomem *iobase; /* address of the device */
struct mutex lock; /* dev-level lock */ struct mutex lock; /* dev-level lock */
struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES]; struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
...@@ -134,7 +136,6 @@ struct ath5k_softc { ...@@ -134,7 +136,6 @@ struct ath5k_softc {
struct ath5k_desc *desc; /* TX/RX descriptors */ struct ath5k_desc *desc; /* TX/RX descriptors */
dma_addr_t desc_daddr; /* DMA (physical) address */ dma_addr_t desc_daddr; /* DMA (physical) address */
size_t desc_len; /* size of TX/RX descriptors */ size_t desc_len; /* size of TX/RX descriptors */
u16 cachelsz; /* cache line size */
DECLARE_BITMAP(status, 5); DECLARE_BITMAP(status, 5);
#define ATH_STAT_INVALID 0 /* disable hardware accesses */ #define ATH_STAT_INVALID 0 /* disable hardware accesses */
...@@ -177,6 +178,8 @@ struct ath5k_softc { ...@@ -177,6 +178,8 @@ struct ath5k_softc {
struct ath5k_rfkill rf_kill; struct ath5k_rfkill rf_kill;
struct tasklet_struct calib; /* calibration tasklet */
spinlock_t block; /* protects beacon */ spinlock_t block; /* protects beacon */
struct tasklet_struct beacontq; /* beacon intr tasklet */ struct tasklet_struct beacontq; /* beacon intr tasklet */
struct ath5k_buf *bbuf; /* beacon buffer */ struct ath5k_buf *bbuf; /* beacon buffer */
...@@ -187,7 +190,6 @@ struct ath5k_softc { ...@@ -187,7 +190,6 @@ struct ath5k_softc {
unsigned int nexttbtt; /* next beacon time in TU */ unsigned int nexttbtt; /* next beacon time in TU */
struct ath5k_txq *cabq; /* content after beacon */ struct ath5k_txq *cabq; /* content after beacon */
struct timer_list calib_tim; /* calibration timer */
int power_level; /* Requested tx power in dbm */ int power_level; /* Requested tx power in dbm */
bool assoc; /* assocate state */ bool assoc; /* assocate state */
bool enable_beacon; /* true if beacons are on */ bool enable_beacon; /* true if beacons are on */
......
...@@ -167,6 +167,16 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) ...@@ -167,6 +167,16 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL); ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false; ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
/* Check if PCIE_OFFSET points to PCIE_SERDES_SECTION
* and enable serdes programming if needed.
*
* XXX: Serdes values seem to be fixed so
* no need to read them here, we write them
* during ath5k_hw_attach */
AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
true : false;
return 0; return 0;
} }
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
/* /*
* Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE) * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
*/ */
#define AR5K_EEPROM_PCIE_OFFSET 0x02 /* Contains offset to PCI-E infos */
#define AR5K_EEPROM_PCIE_SERDES_SECTION 0x40 /* PCIE_OFFSET points here when
* SERDES infos are present */
#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
...@@ -391,6 +394,7 @@ struct ath5k_eeprom_info { ...@@ -391,6 +394,7 @@ struct ath5k_eeprom_info {
u8 ee_rfkill_pin; u8 ee_rfkill_pin;
bool ee_rfkill_pol; bool ee_rfkill_pol;
bool ee_is_hb63; bool ee_is_hb63;
bool ee_serdes;
u16 ee_misc0; u16 ee_misc0;
u16 ee_misc1; u16 ee_misc1;
u16 ee_misc2; u16 ee_misc2;
......
...@@ -740,13 +740,22 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, ...@@ -740,13 +740,22 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
AR5K_RF_XPD_GAIN, true); AR5K_RF_XPD_GAIN, true);
} else { } else {
/* TODO: Set high and low gain bits */ u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
ath5k_hw_rfb_op(ah, rf_regs, if (ee->ee_pd_gains[ee_mode] > 1) {
ee->ee_x_gain[ee_mode], ath5k_hw_rfb_op(ah, rf_regs,
pdg_curve_to_idx[0],
AR5K_RF_PD_GAIN_LO, true); AR5K_RF_PD_GAIN_LO, true);
ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_rfb_op(ah, rf_regs,
ee->ee_x_gain[ee_mode], pdg_curve_to_idx[1],
AR5K_RF_PD_GAIN_HI, true); AR5K_RF_PD_GAIN_HI, true);
} else {
ath5k_hw_rfb_op(ah, rf_regs,
pdg_curve_to_idx[0],
AR5K_RF_PD_GAIN_LO, true);
ath5k_hw_rfb_op(ah, rf_regs,
pdg_curve_to_idx[0],
AR5K_RF_PD_GAIN_HI, true);
}
/* Lower synth voltage on Rev 2 */ /* Lower synth voltage on Rev 2 */
ath5k_hw_rfb_op(ah, rf_regs, 2, ath5k_hw_rfb_op(ah, rf_regs, 2,
...@@ -1095,6 +1104,29 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) ...@@ -1095,6 +1104,29 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
PHY calibration PHY calibration
\*****************/ \*****************/
void
ath5k_hw_calibration_poll(struct ath5k_hw *ah)
{
/* Calibration interval in jiffies */
unsigned long cal_intval;
cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000);
/* Initialize timestamp if needed */
if (!ah->ah_cal_tstamp)
ah->ah_cal_tstamp = jiffies;
/* For now we always do full calibration
* Mark software interrupt mask and fire software
* interrupt (bit gets auto-cleared) */
if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) {
ah->ah_cal_tstamp = jiffies;
ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION;
AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI);
}
}
/** /**
* ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
* *
...@@ -1896,8 +1928,9 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR, ...@@ -1896,8 +1928,9 @@ ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
s16 min_pwrL, min_pwrR; s16 min_pwrL, min_pwrR;
s16 pwr_i; s16 pwr_i;
if (WARN_ON(stepL[0] == stepL[1] || stepR[0] == stepR[1])) /* Some vendors write the same pcdac value twice !!! */
return 0; if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
return max(pwrL[0], pwrR[0]);
if (pwrL[0] == pwrL[1]) if (pwrL[0] == pwrL[1])
min_pwrL = pwrL[0]; min_pwrL = pwrL[0];
......
...@@ -362,7 +362,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) ...@@ -362,7 +362,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
} }
if (tq->tqi_ready_time && if (tq->tqi_ready_time &&
(tq->tqi_type != AR5K_TX_QUEUE_ID_CAB)) (tq->tqi_type != AR5K_TX_QUEUE_CAB))
ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
AR5K_QCU_RDYTIMECFG_INTVAL) | AR5K_QCU_RDYTIMECFG_INTVAL) |
AR5K_QCU_RDYTIMECFG_ENABLE, AR5K_QCU_RDYTIMECFG_ENABLE,
......
...@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, ...@@ -258,29 +258,35 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
if (!set_chip) if (!set_chip)
goto commit; goto commit;
/* Preserve sleep duration */
data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
/* If card is down we 'll get 0xffff... so we
* need to clean this up before we write the register
*/
if (data & 0xffc00000) if (data & 0xffc00000)
data = 0; data = 0;
else else
data = data & 0xfffcffff; /* Preserve sleep duration etc */
data = data & ~AR5K_SLEEP_CTL_SLE;
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
AR5K_SLEEP_CTL);
udelay(15); udelay(15);
for (i = 50; i > 0; i--) { for (i = 200; i > 0; i--) {
/* Check if the chip did wake up */ /* Check if the chip did wake up */
if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
AR5K_PCICFG_SPWR_DN) == 0) AR5K_PCICFG_SPWR_DN) == 0)
break; break;
/* Wait a bit and retry */ /* Wait a bit and retry */
udelay(200); udelay(50);
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); ath5k_hw_reg_write(ah, data | AR5K_SLEEP_CTL_SLE_WAKE,
AR5K_SLEEP_CTL);
} }
/* Fail if the chip didn't wake up */ /* Fail if the chip didn't wake up */
if (i <= 0) if (i == 0)
return -EIO; return -EIO;
break; break;
...@@ -295,6 +301,64 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, ...@@ -295,6 +301,64 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
return 0; return 0;
} }
/*
* Put device on hold
*
* Put MAC and Baseband on warm reset and
* keep that state (don't clean sleep control
* register). After this MAC and Baseband are
* disabled and a full reset is needed to come
* back. This way we save as much power as possible
* without puting the card on full sleep.
*/
int ath5k_hw_on_hold(struct ath5k_hw *ah)
{
struct pci_dev *pdev = ah->ah_sc->pdev;
u32 bus_flags;
int ret;
/* Make sure device is awake */
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
return ret;
}
/*
* Put chipset on warm reset...
*
* Note: puting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
mdelay(2);
} else {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_BASEBAND | bus_flags);
}
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to put device on warm reset\n");
return -EIO;
}
/* ...wakeup again!*/
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to put device on hold\n");
return ret;
}
return ret;
}
/* /*
* Bring up MAC + PHY Chips and program PLL * Bring up MAC + PHY Chips and program PLL
* TODO: Half/Quarter rate support * TODO: Half/Quarter rate support
...@@ -318,6 +382,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) ...@@ -318,6 +382,50 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
return ret; return ret;
} }
/*
* Put chipset on warm reset...
*
* Note: puting PCI core on warm reset on PCI-E cards
* results card to hang and always return 0xffff... so
* we ingore that flag for PCI-E cards. On PCI cards
* this flag gets cleared after 64 PCI clocks.
*/
bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
mdelay(2);
} else {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_BASEBAND | bus_flags);
}
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
return -EIO;
}
/* ...wakeup again!...*/
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
return ret;
}
/* ...clear reset control register and pull device out of
* warm reset */
if (ath5k_hw_nic_reset(ah, 0)) {
ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
return -EIO;
}
/* On initialization skip PLL programming since we don't have
* a channel / mode set yet */
if (initial)
return 0;
if (ah->ah_version != AR5K_AR5210) { if (ah->ah_version != AR5K_AR5210) {
/* /*
* Get channel mode flags * Get channel mode flags
...@@ -383,39 +491,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) ...@@ -383,39 +491,6 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
AR5K_PHY_TURBO); AR5K_PHY_TURBO);
} }
/* reseting PCI on PCI-E cards results card to hang
* and always return 0xffff... so we ingore that flag
* for PCI-E cards */
bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
/* Reset chipset */
if (ah->ah_version == AR5K_AR5210) {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
mdelay(2);
} else {
ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
AR5K_RESET_CTL_BASEBAND | bus_flags);
}
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
return -EIO;
}
/* ...wakeup again!*/
ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
if (ret) {
ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
return ret;
}
/* ...final warm reset */
if (ath5k_hw_nic_reset(ah, 0)) {
ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
return -EIO;
}
if (ah->ah_version != AR5K_AR5210) { if (ah->ah_version != AR5K_AR5210) {
/* ...update PLL if needed */ /* ...update PLL if needed */
......
...@@ -6,7 +6,13 @@ config ATH9K ...@@ -6,7 +6,13 @@ config ATH9K
select NEW_LEDS select NEW_LEDS
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. Atheros IEEE 802.11n AR5008, AR9001 and AR9002 family
of chipsets. For a specific list of supported external
cards, laptops that already ship with these cards and
APs that come with these cards refer to to ath9k wiki
products page:
http://wireless.kernel.org/en/users/Drivers/ath9k/products
If you choose to build a module, it'll be called ath9k. If you choose to build a module, it'll be called ath9k.
......
ath9k-y += hw.o \ ath9k-y += hw.o \
eeprom.o \ eeprom.o \
eeprom_def.o \
eeprom_4k.o \
eeprom_9287.o \
mac.o \ mac.o \
calib.o \ calib.o \
ani.o \ ani.o \
......
...@@ -236,36 +236,35 @@ static void ath9k_ani_restart(struct ath_hw *ah) ...@@ -236,36 +236,35 @@ static void ath9k_ani_restart(struct ath_hw *ah)
return; return;
aniState = ah->curani; aniState = ah->curani;
aniState->listenTime = 0; aniState->listenTime = 0;
if (ah->has_hw_phycounters) {
if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
aniState->ofdmPhyErrBase = 0; aniState->ofdmPhyErrBase = 0;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"OFDM Trigger is too high for hw counters\n");
} else {
aniState->ofdmPhyErrBase =
AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
}
if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
aniState->cckPhyErrBase = 0;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"CCK Trigger is too high for hw counters\n");
} else {
aniState->cckPhyErrBase =
AR_PHY_COUNTMAX - aniState->cckTrigHigh;
}
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Writing ofdmbase=%u cckbase=%u\n", "OFDM Trigger is too high for hw counters\n");
aniState->ofdmPhyErrBase, } else {
aniState->cckPhyErrBase); aniState->ofdmPhyErrBase =
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); }
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); aniState->cckPhyErrBase = 0;
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); "CCK Trigger is too high for hw counters\n");
} else {
aniState->cckPhyErrBase =
AR_PHY_COUNTMAX - aniState->cckTrigHigh;
} }
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Writing ofdmbase=%u cckbase=%u\n",
aniState->ofdmPhyErrBase,
aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
aniState->ofdmPhyErrCount = 0; aniState->ofdmPhyErrCount = 0;
aniState->cckPhyErrCount = 0; aniState->cckPhyErrCount = 0;
} }
...@@ -530,18 +529,12 @@ void ath9k_ani_reset(struct ath_hw *ah) ...@@ -530,18 +529,12 @@ void ath9k_ani_reset(struct ath_hw *ah)
if (aniState->firstepLevel != 0) if (aniState->firstepLevel != 0)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel); aniState->firstepLevel);
if (ah->has_hw_phycounters) {
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
~ATH9K_RX_FILTER_PHYERR);
ath9k_ani_restart(ah);
REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
} else { ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
ath9k_ani_restart(ah); ~ATH9K_RX_FILTER_PHYERR);
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | ath9k_ani_restart(ah);
ATH9K_RX_FILTER_PHYERR); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
} REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
} }
void ath9k_hw_ani_monitor(struct ath_hw *ah, void ath9k_hw_ani_monitor(struct ath_hw *ah,
...@@ -550,6 +543,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, ...@@ -550,6 +543,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
{ {
struct ar5416AniState *aniState; struct ar5416AniState *aniState;
int32_t listenTime; int32_t listenTime;
u32 phyCnt1, phyCnt2;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
if (!DO_ANI(ah)) if (!DO_ANI(ah))
return; return;
...@@ -566,50 +561,45 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, ...@@ -566,50 +561,45 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
aniState->listenTime += listenTime; aniState->listenTime += listenTime;
if (ah->has_hw_phycounters) { ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
u32 phyCnt1, phyCnt2;
u32 ofdmPhyErrCnt, cckPhyErrCnt;
ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (phyCnt1 < aniState->ofdmPhyErrBase ||
phyCnt2 < aniState->cckPhyErrBase) {
if (phyCnt1 < aniState->ofdmPhyErrBase || if (phyCnt1 < aniState->ofdmPhyErrBase) {
phyCnt2 < aniState->cckPhyErrBase) { DPRINTF(ah->ah_sc, ATH_DBG_ANI,
if (phyCnt1 < aniState->ofdmPhyErrBase) { "phyCnt1 0x%x, resetting "
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "counter value to 0x%x\n",
"phyCnt1 0x%x, resetting " phyCnt1, aniState->ofdmPhyErrBase);
"counter value to 0x%x\n", REG_WRITE(ah, AR_PHY_ERR_1,
phyCnt1, aniState->ofdmPhyErrBase); aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, REG_WRITE(ah, AR_PHY_ERR_MASK_1,
aniState->ofdmPhyErrBase); AR_PHY_ERR_OFDM_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_1, }
AR_PHY_ERR_OFDM_TIMING); if (phyCnt2 < aniState->cckPhyErrBase) {
} DPRINTF(ah->ah_sc, ATH_DBG_ANI,
if (phyCnt2 < aniState->cckPhyErrBase) { "phyCnt2 0x%x, resetting "
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "counter value to 0x%x\n",
"phyCnt2 0x%x, resetting " phyCnt2, aniState->cckPhyErrBase);
"counter value to 0x%x\n", REG_WRITE(ah, AR_PHY_ERR_2,
phyCnt2, aniState->cckPhyErrBase); aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, REG_WRITE(ah, AR_PHY_ERR_MASK_2,
aniState->cckPhyErrBase); AR_PHY_ERR_CCK_TIMING);
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
AR_PHY_ERR_CCK_TIMING);
}
return;
} }
return;
}
ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
ah->stats.ast_ani_ofdmerrs += ah->stats.ast_ani_ofdmerrs +=
ofdmPhyErrCnt - aniState->ofdmPhyErrCount; ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
aniState->ofdmPhyErrCount = ofdmPhyErrCnt; aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
ah->stats.ast_ani_cckerrs += ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount; cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt; aniState->cckPhyErrCount = cckPhyErrCnt;
}
if (aniState->listenTime > 5 * ah->aniperiod) { if (aniState->listenTime > 5 * ah->aniperiod) {
if (aniState->ofdmPhyErrCount <= aniState->listenTime * if (aniState->ofdmPhyErrCount <= aniState->listenTime *
...@@ -632,11 +622,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, ...@@ -632,11 +622,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
} }
} }
bool ath9k_hw_phycounters(struct ath_hw *ah)
{
return ah->has_hw_phycounters ? true : false;
}
void ath9k_enable_mib_counters(struct ath_hw *ah) void ath9k_enable_mib_counters(struct ath_hw *ah)
{ {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n"); DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
...@@ -781,9 +766,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ...@@ -781,9 +766,7 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
{ {
int i; int i;
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n"); DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Initialize ANI\n");
ah->has_hw_phycounters = 1;
memset(ah->ani, 0, sizeof(ah->ani)); memset(ah->ani, 0, sizeof(ah->ani));
for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
...@@ -799,24 +782,22 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ...@@ -799,24 +782,22 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
ATH9K_ANI_CCK_WEAK_SIG_THR; ATH9K_ANI_CCK_WEAK_SIG_THR;
ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL; ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
if (ah->has_hw_phycounters) { ah->ani[i].ofdmPhyErrBase =
ah->ani[i].ofdmPhyErrBase = AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH; ah->ani[i].cckPhyErrBase =
ah->ani[i].cckPhyErrBase = AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
}
}
if (ah->has_hw_phycounters) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Setting OfdmErrBase = 0x%08x\n",
ah->ani[0].ofdmPhyErrBase);
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
ah->ani[0].cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
ath9k_enable_mib_counters(ah);
} }
DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"Setting OfdmErrBase = 0x%08x\n",
ah->ani[0].ofdmPhyErrBase);
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
ah->ani[0].cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
ath9k_enable_mib_counters(ah);
ah->aniperiod = ATH9K_ANI_PERIOD; ah->aniperiod = ATH9K_ANI_PERIOD;
if (ah->config.enable_ani) if (ah->config.enable_ani)
ah->proc_phyerr |= HAL_PROCESS_ANI; ah->proc_phyerr |= HAL_PROCESS_ANI;
...@@ -826,9 +807,7 @@ void ath9k_hw_ani_disable(struct ath_hw *ah) ...@@ -826,9 +807,7 @@ void ath9k_hw_ani_disable(struct ath_hw *ah)
{ {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n"); DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n");
if (ah->has_hw_phycounters) { ath9k_hw_disable_mib_counters(ah);
ath9k_hw_disable_mib_counters(ah); REG_WRITE(ah, AR_PHY_ERR_1, 0);
REG_WRITE(ah, AR_PHY_ERR_1, 0); REG_WRITE(ah, AR_PHY_ERR_2, 0);
REG_WRITE(ah, AR_PHY_ERR_2, 0);
}
} }
...@@ -124,7 +124,6 @@ void ath9k_ani_reset(struct ath_hw *ah); ...@@ -124,7 +124,6 @@ void ath9k_ani_reset(struct ath_hw *ah);
void ath9k_hw_ani_monitor(struct ath_hw *ah, void ath9k_hw_ani_monitor(struct ath_hw *ah,
const struct ath9k_node_stats *stats, const struct ath9k_node_stats *stats,
struct ath9k_channel *chan); struct ath9k_channel *chan);
bool ath9k_hw_phycounters(struct ath_hw *ah);
void ath9k_enable_mib_counters(struct ath_hw *ah); void ath9k_enable_mib_counters(struct ath_hw *ah);
void ath9k_hw_disable_mib_counters(struct ath_hw *ah); void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "hw.h" #include "hw.h"
#include "rc.h" #include "rc.h"
#include "debug.h" #include "debug.h"
#include "../ath.h"
struct ath_node; struct ath_node;
...@@ -532,6 +533,8 @@ struct ath_softc { ...@@ -532,6 +533,8 @@ struct ath_softc {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct device *dev; struct device *dev;
struct ath_common common;
spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */ spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
struct ath_wiphy *pri_wiphy; struct ath_wiphy *pri_wiphy;
struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
...@@ -564,7 +567,6 @@ struct ath_softc { ...@@ -564,7 +567,6 @@ struct ath_softc {
u32 sc_flags; /* SC_OP_* */ u32 sc_flags; /* SC_OP_* */
u16 curtxpow; u16 curtxpow;
u16 curaid; u16 curaid;
u16 cachelsz;
u8 nbcnvifs; u8 nbcnvifs;
u16 nvifs; u16 nvifs;
u8 tx_chainmask; u8 tx_chainmask;
......
...@@ -385,106 +385,124 @@ struct calDataPerFreqOpLoop { ...@@ -385,106 +385,124 @@ struct calDataPerFreqOpLoop {
} __packed; } __packed;
struct modal_eep_4k_header { struct modal_eep_4k_header {
u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
u32 antCtrlCommon; u32 antCtrlCommon;
u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS]; u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
u8 switchSettling; u8 switchSettling;
u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS]; u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS]; u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
u8 adcDesiredSize; u8 adcDesiredSize;
u8 pgaDesiredSize; u8 pgaDesiredSize;
u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS]; u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
u8 txEndToXpaOff; u8 txEndToXpaOff;
u8 txEndToRxOn; u8 txEndToRxOn;
u8 txFrameToXpaOn; u8 txFrameToXpaOn;
u8 thresh62; u8 thresh62;
u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS]; u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
u8 xpdGain; u8 xpdGain;
u8 xpd; u8 xpd;
u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS]; u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS]; u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
u8 pdGainOverlap; u8 pdGainOverlap;
u8 ob_01; #ifdef __BIG_ENDIAN_BITFIELD
u8 db1_01; u8 ob_1:4, ob_0:4;
u8 xpaBiasLvl; u8 db1_1:4, db1_0:4;
u8 txFrameToDataStart; #else
u8 txFrameToPaOn; u8 ob_0:4, ob_1:4;
u8 ht40PowerIncForPdadc; u8 db1_0:4, db1_1:4;
u8 bswAtten[AR5416_EEP4K_MAX_CHAINS]; #endif
u8 bswMargin[AR5416_EEP4K_MAX_CHAINS]; u8 xpaBiasLvl;
u8 swSettleHt40; u8 txFrameToDataStart;
u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS]; u8 txFrameToPaOn;
u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS]; u8 ht40PowerIncForPdadc;
u8 db2_01; u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
u8 version; u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
u16 ob_234; u8 swSettleHt40;
u16 db1_234; u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
u16 db2_234; u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
u8 futureModal[4]; #ifdef __BIG_ENDIAN_BITFIELD
u8 db2_1:4, db2_0:4;
#else
u8 db2_0:4, db2_1:4;
#endif
u8 version;
#ifdef __BIG_ENDIAN_BITFIELD
u8 ob_3:4, ob_2:4;
u8 antdiv_ctl1:4, ob_4:4;
u8 db1_3:4, db1_2:4;
u8 antdiv_ctl2:4, db1_4:4;
u8 db2_2:4, db2_3:4;
u8 reserved:4, db2_4:4;
#else
u8 ob_2:4, ob_3:4;
u8 ob_4:4, antdiv_ctl1:4;
u8 db1_2:4, db1_3:4;
u8 db1_4:4, antdiv_ctl2:4;
u8 db2_2:4, db2_3:4;
u8 db2_4:4, reserved:4;
#endif
u8 futureModal[4];
struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
} __packed; } __packed;
struct base_eep_ar9287_header { struct base_eep_ar9287_header {
u16 length; u16 length;
u16 checksum; u16 checksum;
u16 version; u16 version;
u8 opCapFlags; u8 opCapFlags;
u8 eepMisc; u8 eepMisc;
u16 regDmn[2]; u16 regDmn[2];
u8 macAddr[6]; u8 macAddr[6];
u8 rxMask; u8 rxMask;
u8 txMask; u8 txMask;
u16 rfSilent; u16 rfSilent;
u16 blueToothOptions; u16 blueToothOptions;
u16 deviceCap; u16 deviceCap;
u32 binBuildNumber; u32 binBuildNumber;
u8 deviceType; u8 deviceType;
u8 openLoopPwrCntl; u8 openLoopPwrCntl;
int8_t pwrTableOffset; int8_t pwrTableOffset;
int8_t tempSensSlope; int8_t tempSensSlope;
int8_t tempSensSlopePalOn; int8_t tempSensSlopePalOn;
u8 futureBase[29]; u8 futureBase[29];
} __packed; } __packed;
struct modal_eep_ar9287_header { struct modal_eep_ar9287_header {
u32 antCtrlChain[AR9287_MAX_CHAINS]; u32 antCtrlChain[AR9287_MAX_CHAINS];
u32 antCtrlCommon; u32 antCtrlCommon;
int8_t antennaGainCh[AR9287_MAX_CHAINS]; int8_t antennaGainCh[AR9287_MAX_CHAINS];
u8 switchSettling; u8 switchSettling;
u8 txRxAttenCh[AR9287_MAX_CHAINS]; u8 txRxAttenCh[AR9287_MAX_CHAINS];
u8 rxTxMarginCh[AR9287_MAX_CHAINS]; u8 rxTxMarginCh[AR9287_MAX_CHAINS];
int8_t adcDesiredSize; int8_t adcDesiredSize;
u8 txEndToXpaOff; u8 txEndToXpaOff;
u8 txEndToRxOn; u8 txEndToRxOn;
u8 txFrameToXpaOn; u8 txFrameToXpaOn;
u8 thresh62; u8 thresh62;
int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS]; int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
u8 xpdGain; u8 xpdGain;
u8 xpd; u8 xpd;
int8_t iqCalICh[AR9287_MAX_CHAINS]; int8_t iqCalICh[AR9287_MAX_CHAINS];
int8_t iqCalQCh[AR9287_MAX_CHAINS]; int8_t iqCalQCh[AR9287_MAX_CHAINS];
u8 pdGainOverlap; u8 pdGainOverlap;
u8 xpaBiasLvl; u8 xpaBiasLvl;
u8 txFrameToDataStart; u8 txFrameToDataStart;
u8 txFrameToPaOn; u8 txFrameToPaOn;
u8 ht40PowerIncForPdadc; u8 ht40PowerIncForPdadc;
u8 bswAtten[AR9287_MAX_CHAINS]; u8 bswAtten[AR9287_MAX_CHAINS];
u8 bswMargin[AR9287_MAX_CHAINS]; u8 bswMargin[AR9287_MAX_CHAINS];
u8 swSettleHt40; u8 swSettleHt40;
u8 version; u8 version;
u8 db1; u8 db1;
u8 db2; u8 db2;
u8 ob_cck; u8 ob_cck;
u8 ob_psk; u8 ob_psk;
u8 ob_qam; u8 ob_qam;
u8 ob_pal_off; u8 ob_pal_off;
u8 futureModal[30]; u8 futureModal[30];
struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS]; struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
} __packed; } __packed;
struct cal_data_per_freq { struct cal_data_per_freq {
u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
...@@ -525,7 +543,6 @@ struct cal_data_op_loop_ar9287 { ...@@ -525,7 +543,6 @@ struct cal_data_op_loop_ar9287 {
u8 empty[2][5]; u8 empty[2][5];
} __packed; } __packed;
struct cal_data_per_freq_ar9287 { struct cal_data_per_freq_ar9287 {
u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS]; u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
...@@ -601,26 +618,25 @@ struct ar5416_eeprom_4k { ...@@ -601,26 +618,25 @@ struct ar5416_eeprom_4k {
} __packed; } __packed;
struct ar9287_eeprom { struct ar9287_eeprom {
struct base_eep_ar9287_header baseEepHeader; struct base_eep_ar9287_header baseEepHeader;
u8 custData[AR9287_DATA_SZ]; u8 custData[AR9287_DATA_SZ];
struct modal_eep_ar9287_header modalHeader; struct modal_eep_ar9287_header modalHeader;
u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS]; u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
union cal_data_per_freq_ar9287_u union cal_data_per_freq_ar9287_u
calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS]; calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
struct cal_target_power_leg struct cal_target_power_leg
calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS]; calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
struct cal_target_power_leg struct cal_target_power_leg
calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS]; calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
struct cal_target_power_ht struct cal_target_power_ht
calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS]; calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
struct cal_target_power_ht struct cal_target_power_ht
calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS]; calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
u8 ctlIndex[AR9287_NUM_CTLS]; u8 ctlIndex[AR9287_NUM_CTLS];
struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS]; struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
u8 padding; u8 padding;
} __packed; } __packed;
enum reg_ext_bitmap { enum reg_ext_bitmap {
REG_EXT_JAPAN_MIDBAND = 1, REG_EXT_JAPAN_MIDBAND = 1,
REG_EXT_FCC_DFS_HT40 = 2, REG_EXT_FCC_DFS_HT40 = 2,
...@@ -661,10 +677,39 @@ struct eeprom_ops { ...@@ -661,10 +677,39 @@ struct eeprom_ops {
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
}; };
void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
u32 shift, u32 val);
int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
int16_t targetLeft,
int16_t targetRight);
bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
u16 *indexL, u16 *indexR);
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
u8 *pVpdList, u16 numIntercepts,
u8 *pRetVpdList);
void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
struct ath9k_channel *chan,
struct cal_target_power_leg *powInfo,
u16 numChannels,
struct cal_target_power_leg *pNewPower,
u16 numRates, bool isExtTarget);
void ath9k_hw_get_target_powers(struct ath_hw *ah,
struct ath9k_channel *chan,
struct cal_target_power_ht *powInfo,
u16 numChannels,
struct cal_target_power_ht *pNewPower,
u16 numRates, bool isHt40Target);
u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
bool is2GHz, int num_band_edges);
int ath9k_hw_eeprom_init(struct ath_hw *ah);
#define ar5416_get_ntxchains(_txchainmask) \ #define ar5416_get_ntxchains(_txchainmask) \
(((_txchainmask >> 2) & 1) + \ (((_txchainmask >> 2) & 1) + \
((_txchainmask >> 1) & 1) + (_txchainmask & 1)) ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
int ath9k_hw_eeprom_init(struct ath_hw *ah); extern const struct eeprom_ops eep_def_ops;
extern const struct eeprom_ops eep_4k_ops;
extern const struct eeprom_ops eep_AR9287_ops;
#endif /* EEPROM_H */ #endif /* EEPROM_H */
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -407,7 +407,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ...@@ -407,7 +407,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
ah->config.cck_trig_high = 200; ah->config.cck_trig_high = 200;
ah->config.cck_trig_low = 100; ah->config.cck_trig_low = 100;
ah->config.enable_ani = 1; ah->config.enable_ani = 1;
ah->config.diversity_control = 0; ah->config.diversity_control = ATH9K_ANT_VARIABLE;
ah->config.antenna_switch_swap = 0; ah->config.antenna_switch_swap = 0;
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
...@@ -452,9 +452,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) ...@@ -452,9 +452,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
ah->regulatory.power_limit = MAX_RATE_POWER; ah->regulatory.power_limit = MAX_RATE_POWER;
ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX; ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
ah->atim_window = 0; ah->atim_window = 0;
ah->diversity_control = ah->config.diversity_control;
ah->antenna_switch_swap =
ah->config.antenna_switch_swap;
ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
ah->beacon_interval = 100; ah->beacon_interval = 100;
ah->enable_32kHz_clock = DONT_USE_32KHZ; ah->enable_32kHz_clock = DONT_USE_32KHZ;
...@@ -3891,7 +3888,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah, ...@@ -3891,7 +3888,7 @@ bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
break; break;
} }
} else { } else {
ah->diversity_control = settings; ah->config.diversity_control = settings;
} }
return true; return true;
...@@ -4019,14 +4016,12 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah) ...@@ -4019,14 +4016,12 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah)
ath9k_ps_restore(ah->ah_sc); ath9k_ps_restore(ah->ah_sc);
} }
bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
{ {
if (setting) if (setting)
ah->misc_mode |= AR_PCU_TX_ADD_TSF; ah->misc_mode |= AR_PCU_TX_ADD_TSF;
else else
ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
return true;
} }
bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us) bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
......
...@@ -127,6 +127,12 @@ enum wireless_mode { ...@@ -127,6 +127,12 @@ enum wireless_mode {
ATH9K_MODE_MAX, ATH9K_MODE_MAX,
}; };
enum ath9k_ant_setting {
ATH9K_ANT_VARIABLE = 0,
ATH9K_ANT_FIXED_A,
ATH9K_ANT_FIXED_B
};
enum ath9k_hw_caps { enum ath9k_hw_caps {
ATH9K_HW_CAP_MIC_AESCCM = BIT(0), ATH9K_HW_CAP_MIC_AESCCM = BIT(0),
ATH9K_HW_CAP_MIC_CKIP = BIT(1), ATH9K_HW_CAP_MIC_CKIP = BIT(1),
...@@ -191,7 +197,7 @@ struct ath9k_ops_config { ...@@ -191,7 +197,7 @@ struct ath9k_ops_config {
u32 cck_trig_high; u32 cck_trig_high;
u32 cck_trig_low; u32 cck_trig_low;
u32 enable_ani; u32 enable_ani;
u16 diversity_control; enum ath9k_ant_setting diversity_control;
u16 antenna_switch_swap; u16 antenna_switch_swap;
int serialize_regmode; int serialize_regmode;
bool intr_mitigation; bool intr_mitigation;
...@@ -330,12 +336,6 @@ enum ath9k_power_mode { ...@@ -330,12 +336,6 @@ enum ath9k_power_mode {
ATH9K_PM_UNDEFINED ATH9K_PM_UNDEFINED
}; };
enum ath9k_ant_setting {
ATH9K_ANT_VARIABLE = 0,
ATH9K_ANT_FIXED_A,
ATH9K_ANT_FIXED_B
};
enum ath9k_tp_scale { enum ath9k_tp_scale {
ATH9K_TP_SCALE_MAX = 0, ATH9K_TP_SCALE_MAX = 0,
ATH9K_TP_SCALE_50, ATH9K_TP_SCALE_50,
...@@ -437,8 +437,6 @@ struct ath_hw { ...@@ -437,8 +437,6 @@ struct ath_hw {
u32 txurn_interrupt_mask; u32 txurn_interrupt_mask;
bool chip_fullsleep; bool chip_fullsleep;
u32 atim_window; u32 atim_window;
u16 antenna_switch_swap;
enum ath9k_ant_setting diversity_control;
/* Calibration */ /* Calibration */
enum ath9k_cal_types supp_cals; enum ath9k_cal_types supp_cals;
...@@ -507,7 +505,6 @@ struct ath_hw { ...@@ -507,7 +505,6 @@ struct ath_hw {
/* ANI */ /* ANI */
u32 proc_phyerr; u32 proc_phyerr;
bool has_hw_phycounters;
u32 aniperiod; u32 aniperiod;
struct ar5416AniState *curani; struct ar5416AniState *curani;
struct ar5416AniState ani[255]; struct ar5416AniState ani[255];
...@@ -601,7 +598,7 @@ void ath9k_hw_write_associd(struct ath_softc *sc); ...@@ -601,7 +598,7 @@ void ath9k_hw_write_associd(struct ath_softc *sc);
u64 ath9k_hw_gettsf64(struct ath_hw *ah); u64 ath9k_hw_gettsf64(struct ath_hw *ah);
void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah); void ath9k_hw_reset_tsf(struct ath_hw *ah);
bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode); void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
......
...@@ -40,20 +40,15 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) ...@@ -40,20 +40,15 @@ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
return REG_READ(ah, AR_QTXDP(q)); return REG_READ(ah, AR_QTXDP(q));
} }
bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
{ {
REG_WRITE(ah, AR_QTXDP(q), txdp); REG_WRITE(ah, AR_QTXDP(q), txdp);
return true;
} }
bool ath9k_hw_txstart(struct ath_hw *ah, u32 q) void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
{ {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q); DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q); REG_WRITE(ah, AR_Q_TXE, 1 << q);
return true;
} }
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
...@@ -178,7 +173,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) ...@@ -178,7 +173,7 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
#undef ATH9K_TIME_QUANTUM #undef ATH9K_TIME_QUANTUM
} }
bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 segLen, bool firstSeg, u32 segLen, bool firstSeg,
bool lastSeg, const struct ath_desc *ds0) bool lastSeg, const struct ath_desc *ds0)
{ {
...@@ -202,8 +197,6 @@ bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, ...@@ -202,8 +197,6 @@ bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
ads->ds_txstatus4 = ads->ds_txstatus5 = 0; ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
ads->ds_txstatus6 = ads->ds_txstatus7 = 0; ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
ads->ds_txstatus8 = ads->ds_txstatus9 = 0; ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
return true;
} }
void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds) void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
...@@ -888,7 +881,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, ...@@ -888,7 +881,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
return 0; return 0;
} }
bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags) u32 size, u32 flags)
{ {
struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *ads = AR5416DESC(ds);
...@@ -901,8 +894,6 @@ bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, ...@@ -901,8 +894,6 @@ bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
ads->ds_rxstatus8 &= ~AR_RxDone; ads->ds_rxstatus8 &= ~AR_RxDone;
if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
memset(&(ads->u), 0, sizeof(ads->u)); memset(&(ads->u), 0, sizeof(ads->u));
return true;
} }
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
......
...@@ -628,12 +628,12 @@ struct ath9k_channel; ...@@ -628,12 +628,12 @@ struct ath9k_channel;
struct ath_rate_table; struct ath_rate_table;
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
bool ath9k_hw_txstart(struct ath_hw *ah, u32 q); void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 segLen, bool firstSeg, u32 segLen, bool firstSeg,
bool lastSeg, const struct ath_desc *ds0); bool lastSeg, const struct ath_desc *ds0);
void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
...@@ -668,7 +668,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); ...@@ -668,7 +668,7 @@ bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 pa, struct ath_desc *nds, u64 tsf); u32 pa, struct ath_desc *nds, u64 tsf);
bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
u32 size, u32 flags); u32 size, u32 flags);
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
......
...@@ -1327,7 +1327,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc) ...@@ -1327,7 +1327,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc)
*/ */
ath_read_cachesize(sc, &csz); ath_read_cachesize(sc, &csz);
/* XXX assert csz is non-zero */ /* XXX assert csz is non-zero */
sc->cachelsz = csz << 2; /* convert to bytes */ sc->common.cachelsz = csz << 2; /* convert to bytes */
ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
if (!ah) { if (!ah) {
...@@ -2140,6 +2140,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ...@@ -2140,6 +2140,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
/* disable HAL and put h/w to sleep */ /* disable HAL and put h/w to sleep */
ath9k_hw_disable(sc->sc_ah); ath9k_hw_disable(sc->sc_ah);
ath9k_hw_configpcipowersave(sc->sc_ah, 1); ath9k_hw_configpcipowersave(sc->sc_ah, 1);
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
sc->sc_flags |= SC_OP_INVALID; sc->sc_flags |= SC_OP_INVALID;
...@@ -2214,8 +2215,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ...@@ -2214,8 +2215,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
if ((conf->type == NL80211_IFTYPE_STATION) || if ((conf->type == NL80211_IFTYPE_STATION) ||
(conf->type == NL80211_IFTYPE_ADHOC) || (conf->type == NL80211_IFTYPE_ADHOC) ||
(conf->type == NL80211_IFTYPE_MESH_POINT)) { (conf->type == NL80211_IFTYPE_MESH_POINT)) {
if (ath9k_hw_phycounters(sc->sc_ah)) sc->imask |= ATH9K_INT_MIB;
sc->imask |= ATH9K_INT_MIB;
sc->imask |= ATH9K_INT_TSFOOR; sc->imask |= ATH9K_INT_TSFOOR;
} }
...@@ -2380,6 +2380,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -2380,6 +2380,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
(FIF_PROMISC_IN_BSS | \ (FIF_PROMISC_IN_BSS | \
FIF_ALLMULTI | \ FIF_ALLMULTI | \
FIF_CONTROL | \ FIF_CONTROL | \
FIF_PSPOLL | \
FIF_OTHER_BSS | \ FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \ FIF_BCN_PRBRESP_PROMISC | \
FIF_FCSFAIL) FIF_FCSFAIL)
......
...@@ -253,10 +253,12 @@ static int ath_pci_resume(struct pci_dev *pdev) ...@@ -253,10 +253,12 @@ static int ath_pci_resume(struct pci_dev *pdev)
u32 val; u32 val;
int err; int err;
pci_restore_state(pdev);
err = pci_enable_device(pdev); err = pci_enable_device(pdev);
if (err) if (err)
return err; return err;
pci_restore_state(pdev);
/* /*
* Suspend/Resume resets the PCI configuration space, so we have to * Suspend/Resume resets the PCI configuration space, so we have to
* re-disable the RETRY_TIMEOUT register (0x41) to keep * re-disable the RETRY_TIMEOUT register (0x41) to keep
......
...@@ -353,18 +353,16 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -353,18 +353,16 @@ ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
u32 bank6SelMask; u32 bank6SelMask;
u32 *bank6Temp = ah->bank6Temp; u32 *bank6Temp = ah->bank6Temp;
switch (ah->diversity_control) { switch (ah->config.diversity_control) {
case ATH9K_ANT_FIXED_A: case ATH9K_ANT_FIXED_A:
bank6SelMask = bank6SelMask =
(ah-> (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 : REDUCE_CHAIN_0 : REDUCE_CHAIN_1;
REDUCE_CHAIN_1;
break; break;
case ATH9K_ANT_FIXED_B: case ATH9K_ANT_FIXED_B:
bank6SelMask = bank6SelMask =
(ah-> (ah->config.antenna_switch_swap & ANTSWAP_AB) ?
antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 : REDUCE_CHAIN_1 : REDUCE_CHAIN_0;
REDUCE_CHAIN_0;
break; break;
case ATH9K_ANT_VARIABLE: case ATH9K_ANT_VARIABLE:
return; return;
......
...@@ -312,7 +312,25 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, ...@@ -312,7 +312,25 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12)) #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
#define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000
#define AR_PHY_9285_ANT_DIV_CTL 0x01000000
#define AR_PHY_9285_ANT_DIV_CTL_S 24
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000
#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000
#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000
#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000
#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30
#define AR_PHY_9285_ANT_DIV_LNA1 2
#define AR_PHY_9285_ANT_DIV_LNA2 1
#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3
#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
#define AR_PHY_9285_ANT_DIV_GAINTB_0 0
#define AR_PHY_9285_ANT_DIV_GAINTB_1 1
#define AR_PHY_EXT_CCA0 0x99b8 #define AR_PHY_EXT_CCA0 0x99b8
#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF #define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
...@@ -401,6 +419,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah, ...@@ -401,6 +419,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13
#define AR_PHY_GAIN_2GHZ 0xA20C #define AR_PHY_GAIN_2GHZ 0xA20C
#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
......
...@@ -100,38 +100,6 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp) ...@@ -100,38 +100,6 @@ static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
return (tsf & ~0x7fff) | rstamp; return (tsf & ~0x7fff) | rstamp;
} }
static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
{
struct sk_buff *skb;
u32 off;
/*
* Cache-line-align. This is important (for the
* 5210 at least) as not doing so causes bogus data
* in rx'd frames.
*/
/* Note: the kernel can allocate a value greater than
* what we ask it to give us. We really only need 4 KB as that
* is this hardware supports and in fact we need at least 3849
* as that is the MAX AMSDU size this hardware supports.
* 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, gfp_mask);
if (skb != NULL) {
off = ((unsigned long) skb->data) % sc->cachelsz;
if (off != 0)
skb_reserve(skb, sc->cachelsz - off);
} else {
DPRINTF(sc, ATH_DBG_FATAL,
"skbuff alloc of size %u failed\n", len);
return NULL;
}
return skb;
}
/* /*
* For Decrypt or Demic errors, we only mark packet status here and always push * For Decrypt or Demic errors, we only mark packet status here and always push
* up the frame up to let mac80211 handle the actual error case, be it no * up the frame up to let mac80211 handle the actual error case, be it no
...@@ -252,6 +220,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, ...@@ -252,6 +220,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
else if (ds->ds_rxstat.rs_rssi > 127) else if (ds->ds_rxstat.rs_rssi > 127)
ds->ds_rxstat.rs_rssi = 127; ds->ds_rxstat.rs_rssi = 127;
/* Update Beacon RSSI, this is used by ANI. */
if (ieee80211_is_beacon(fc))
sc->nodestats.ns_avgbrssi = ds->ds_rxstat.rs_rssi;
rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
rx_status->band = hw->conf.channel->band; rx_status->band = hw->conf.channel->band;
rx_status->freq = hw->conf.channel->center_freq; rx_status->freq = hw->conf.channel->center_freq;
...@@ -332,10 +304,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -332,10 +304,10 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
spin_lock_init(&sc->rx.rxbuflock); spin_lock_init(&sc->rx.rxbuflock);
sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN, sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
min(sc->cachelsz, (u16)64)); min(sc->common.cachelsz, (u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
sc->cachelsz, sc->rx.bufsize); sc->common.cachelsz, sc->rx.bufsize);
/* Initialize rx descriptors */ /* Initialize rx descriptors */
...@@ -348,7 +320,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -348,7 +320,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
} }
list_for_each_entry(bf, &sc->rx.rxbuf, list) { list_for_each_entry(bf, &sc->rx.rxbuf, list) {
skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL); skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_KERNEL);
if (skb == NULL) { if (skb == NULL) {
error = -ENOMEM; error = -ENOMEM;
goto err; goto err;
...@@ -448,8 +420,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -448,8 +420,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
else else
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
/* If in HOSTAP mode, want to enable reception of PSPOLL frames */ if (sc->rx.rxfilter & FIF_PSPOLL)
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
rfilt |= ATH9K_RX_FILTER_PSPOLL; rfilt |= ATH9K_RX_FILTER_PSPOLL;
if (sc->sec_wiphy) { if (sc->sec_wiphy) {
...@@ -774,7 +745,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -774,7 +745,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
/* Ensure we always have an skb to requeue once we are done /* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */ * processing the current buffer's skb */
requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC); requeue_skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_ATOMIC);
/* If there is no memory we ignore the current RX'd frame, /* If there is no memory we ignore the current RX'd frame,
* tell hardware it can give us a new frame using the old * tell hardware it can give us a new frame using the old
...@@ -789,7 +760,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -789,7 +760,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
skb_put(skb, ds->ds_rxstat.rs_datalen); skb_put(skb, ds->ds_rxstat.rs_datalen);
skb->protocol = cpu_to_be16(ETH_P_CONTROL);
/* see if any padding is done by the hw and remove it */ /* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
......
...@@ -17,6 +17,42 @@ ...@@ -17,6 +17,42 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include "ath.h"
MODULE_AUTHOR("Atheros Communications"); MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards."); MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
u32 len,
gfp_t gfp_mask)
{
struct sk_buff *skb;
u32 off;
/*
* Cache-line-align. This is important (for the
* 5210 at least) as not doing so causes bogus data
* in rx'd frames.
*/
/* Note: the kernel can allocate a value greater than
* what we ask it to give us. We really only need 4 KB as that
* is this hardware supports and in fact we need at least 3849
* as that is the MAX AMSDU size this hardware supports.
* 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 + common->cachelsz - 1, gfp_mask);
if (skb != NULL) {
off = ((unsigned long) skb->data) % common->cachelsz;
if (off != 0)
skb_reserve(skb, common->cachelsz - off);
} else {
printk(KERN_ERR "skbuff alloc of size %u failed\n", len);
return NULL;
}
return skb;
}
EXPORT_SYMBOL(ath_rxbuf_alloc);
...@@ -493,6 +493,10 @@ enum { ...@@ -493,6 +493,10 @@ enum {
/* Max size of a security key */ /* Max size of a security key */
#define B43_SEC_KEYSIZE 16 #define B43_SEC_KEYSIZE 16
/* Max number of group keys */
#define B43_NR_GROUP_KEYS 4
/* Max number of pairwise keys */
#define B43_NR_PAIRWISE_KEYS 50
/* Security algorithms. */ /* Security algorithms. */
enum { enum {
B43_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */ B43_SEC_ALGO_NONE = 0, /* unencrypted, as of TX header. */
...@@ -639,7 +643,7 @@ struct b43_wl { ...@@ -639,7 +643,7 @@ struct b43_wl {
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
/* Current BSSID */ /* Current BSSID */
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
/* Interface type. (IEEE80211_IF_TYPE_XXX) */ /* Interface type. (NL80211_IFTYPE_XXX) */
int if_type; int if_type;
/* Is the card operating in AP, STA or IBSS mode? */ /* Is the card operating in AP, STA or IBSS mode? */
bool operating; bool operating;
...@@ -819,8 +823,7 @@ struct b43_wldev { ...@@ -819,8 +823,7 @@ struct b43_wldev {
/* encryption/decryption */ /* encryption/decryption */
u16 ktp; /* Key table pointer */ u16 ktp; /* Key table pointer */
u8 max_nr_keys; struct b43_key key[B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS];
struct b43_key key[58];
/* Firmware data */ /* Firmware data */
struct b43_firmware fw; struct b43_firmware fw;
...@@ -845,7 +848,7 @@ static inline struct b43_wldev *dev_to_b43_wldev(struct device *dev) ...@@ -845,7 +848,7 @@ static inline struct b43_wldev *dev_to_b43_wldev(struct device *dev)
return ssb_get_drvdata(ssb_dev); return ssb_get_drvdata(ssb_dev);
} }
/* Is the device operating in a specified mode (IEEE80211_IF_TYPE_XXX). */ /* Is the device operating in a specified mode (NL80211_IFTYPE_XXX). */
static inline int b43_is_mode(struct b43_wl *wl, int type) static inline int b43_is_mode(struct b43_wl *wl, int type)
{ {
return (wl->operating && wl->if_type == type); return (wl->operating && wl->if_type == type);
......
...@@ -796,18 +796,19 @@ static void key_write(struct b43_wldev *dev, ...@@ -796,18 +796,19 @@ static void key_write(struct b43_wldev *dev,
static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr) static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{ {
u32 addrtmp[2] = { 0, 0, }; u32 addrtmp[2] = { 0, 0, };
u8 per_sta_keys_start = 8; u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
if (b43_new_kidx_api(dev)) if (b43_new_kidx_api(dev))
per_sta_keys_start = 4; pairwise_keys_start = B43_NR_GROUP_KEYS;
B43_WARN_ON(index < per_sta_keys_start); B43_WARN_ON(index < pairwise_keys_start);
/* We have two default TX keys and possibly two default RX keys. /* We have four default TX keys and possibly four default RX keys.
* Physical mac 0 is mapped to physical key 4 or 8, depending * Physical mac 0 is mapped to physical key 4 or 8, depending
* on the firmware version. * on the firmware version.
* So we must adjust the index here. * So we must adjust the index here.
*/ */
index -= per_sta_keys_start; index -= pairwise_keys_start;
B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
if (addr) { if (addr) {
addrtmp[0] = addr[0]; addrtmp[0] = addr[0];
...@@ -818,27 +819,11 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr) ...@@ -818,27 +819,11 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
addrtmp[1] |= ((u32) (addr[5]) << 8); addrtmp[1] |= ((u32) (addr[5]) << 8);
} }
if (dev->dev->id.revision >= 5) { /* Receive match transmitter address (RCMTA) mechanism */
/* Receive match transmitter address mechanism */ b43_shm_write32(dev, B43_SHM_RCMTA,
b43_shm_write32(dev, B43_SHM_RCMTA, (index * 2) + 0, addrtmp[0]);
(index * 2) + 0, addrtmp[0]); b43_shm_write16(dev, B43_SHM_RCMTA,
b43_shm_write16(dev, B43_SHM_RCMTA, (index * 2) + 1, addrtmp[1]);
(index * 2) + 1, addrtmp[1]);
} else {
/* RXE (Receive Engine) and
* PSM (Programmable State Machine) mechanism
*/
if (index < 8) {
/* TODO write to RCM 16, 19, 22 and 25 */
} else {
b43_shm_write32(dev, B43_SHM_SHARED,
B43_SHM_SH_PSM + (index * 6) + 0,
addrtmp[0]);
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_PSM + (index * 6) + 4,
addrtmp[1]);
}
}
} }
static void do_key_write(struct b43_wldev *dev, static void do_key_write(struct b43_wldev *dev,
...@@ -846,20 +831,20 @@ static void do_key_write(struct b43_wldev *dev, ...@@ -846,20 +831,20 @@ static void do_key_write(struct b43_wldev *dev,
const u8 *key, size_t key_len, const u8 *mac_addr) const u8 *key, size_t key_len, const u8 *mac_addr)
{ {
u8 buf[B43_SEC_KEYSIZE] = { 0, }; u8 buf[B43_SEC_KEYSIZE] = { 0, };
u8 per_sta_keys_start = 8; u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
if (b43_new_kidx_api(dev)) if (b43_new_kidx_api(dev))
per_sta_keys_start = 4; pairwise_keys_start = B43_NR_GROUP_KEYS;
B43_WARN_ON(index >= dev->max_nr_keys); B43_WARN_ON(index >= ARRAY_SIZE(dev->key));
B43_WARN_ON(key_len > B43_SEC_KEYSIZE); B43_WARN_ON(key_len > B43_SEC_KEYSIZE);
if (index >= per_sta_keys_start) if (index >= pairwise_keys_start)
keymac_write(dev, index, NULL); /* First zero out mac. */ keymac_write(dev, index, NULL); /* First zero out mac. */
if (key) if (key)
memcpy(buf, key, key_len); memcpy(buf, key, key_len);
key_write(dev, index, algorithm, buf); key_write(dev, index, algorithm, buf);
if (index >= per_sta_keys_start) if (index >= pairwise_keys_start)
keymac_write(dev, index, mac_addr); keymac_write(dev, index, mac_addr);
dev->key[index].algorithm = algorithm; dev->key[index].algorithm = algorithm;
...@@ -872,21 +857,24 @@ static int b43_key_write(struct b43_wldev *dev, ...@@ -872,21 +857,24 @@ static int b43_key_write(struct b43_wldev *dev,
struct ieee80211_key_conf *keyconf) struct ieee80211_key_conf *keyconf)
{ {
int i; int i;
int sta_keys_start; int pairwise_keys_start;
if (key_len > B43_SEC_KEYSIZE) if (key_len > B43_SEC_KEYSIZE)
return -EINVAL; return -EINVAL;
for (i = 0; i < dev->max_nr_keys; i++) { for (i = 0; i < ARRAY_SIZE(dev->key); i++) {
/* Check that we don't already have this key. */ /* Check that we don't already have this key. */
B43_WARN_ON(dev->key[i].keyconf == keyconf); B43_WARN_ON(dev->key[i].keyconf == keyconf);
} }
if (index < 0) { if (index < 0) {
/* Pairwise key. Get an empty slot for the key. */ /* Pairwise key. Get an empty slot for the key. */
if (b43_new_kidx_api(dev)) if (b43_new_kidx_api(dev))
sta_keys_start = 4; pairwise_keys_start = B43_NR_GROUP_KEYS;
else else
sta_keys_start = 8; pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
for (i = sta_keys_start; i < dev->max_nr_keys; i++) { for (i = pairwise_keys_start;
i < pairwise_keys_start + B43_NR_PAIRWISE_KEYS;
i++) {
B43_WARN_ON(i >= ARRAY_SIZE(dev->key));
if (!dev->key[i].keyconf) { if (!dev->key[i].keyconf) {
/* found empty */ /* found empty */
index = i; index = i;
...@@ -914,7 +902,7 @@ static int b43_key_write(struct b43_wldev *dev, ...@@ -914,7 +902,7 @@ static int b43_key_write(struct b43_wldev *dev,
static int b43_key_clear(struct b43_wldev *dev, int index) static int b43_key_clear(struct b43_wldev *dev, int index)
{ {
if (B43_WARN_ON((index < 0) || (index >= dev->max_nr_keys))) if (B43_WARN_ON((index < 0) || (index >= ARRAY_SIZE(dev->key))))
return -EINVAL; return -EINVAL;
do_key_write(dev, index, B43_SEC_ALGO_NONE, do_key_write(dev, index, B43_SEC_ALGO_NONE,
NULL, B43_SEC_KEYSIZE, NULL); NULL, B43_SEC_KEYSIZE, NULL);
...@@ -929,15 +917,19 @@ static int b43_key_clear(struct b43_wldev *dev, int index) ...@@ -929,15 +917,19 @@ static int b43_key_clear(struct b43_wldev *dev, int index)
static void b43_clear_keys(struct b43_wldev *dev) static void b43_clear_keys(struct b43_wldev *dev)
{ {
int i; int i, count;
for (i = 0; i < dev->max_nr_keys; i++) if (b43_new_kidx_api(dev))
count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
else
count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
for (i = 0; i < count; i++)
b43_key_clear(dev, i); b43_key_clear(dev, i);
} }
static void b43_dump_keymemory(struct b43_wldev *dev) static void b43_dump_keymemory(struct b43_wldev *dev)
{ {
unsigned int i, index, offset; unsigned int i, index, count, offset, pairwise_keys_start;
u8 mac[ETH_ALEN]; u8 mac[ETH_ALEN];
u16 algo; u16 algo;
u32 rcmta0; u32 rcmta0;
...@@ -951,7 +943,14 @@ static void b43_dump_keymemory(struct b43_wldev *dev) ...@@ -951,7 +943,14 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
hf = b43_hf_read(dev); hf = b43_hf_read(dev);
b43dbg(dev->wl, "Hardware key memory dump: USEDEFKEYS=%u\n", b43dbg(dev->wl, "Hardware key memory dump: USEDEFKEYS=%u\n",
!!(hf & B43_HF_USEDEFKEYS)); !!(hf & B43_HF_USEDEFKEYS));
for (index = 0; index < dev->max_nr_keys; index++) { if (b43_new_kidx_api(dev)) {
pairwise_keys_start = B43_NR_GROUP_KEYS;
count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
} else {
pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
}
for (index = 0; index < count; index++) {
key = &(dev->key[index]); key = &(dev->key[index]);
printk(KERN_DEBUG "Key slot %02u: %s", printk(KERN_DEBUG "Key slot %02u: %s",
index, (key->keyconf == NULL) ? " " : "*"); index, (key->keyconf == NULL) ? " " : "*");
...@@ -965,11 +964,11 @@ static void b43_dump_keymemory(struct b43_wldev *dev) ...@@ -965,11 +964,11 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
B43_SHM_SH_KEYIDXBLOCK + (index * 2)); B43_SHM_SH_KEYIDXBLOCK + (index * 2));
printk(" Algo: %04X/%02X", algo, key->algorithm); printk(" Algo: %04X/%02X", algo, key->algorithm);
if (index >= 4) { if (index >= pairwise_keys_start) {
rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA, rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
((index - 4) * 2) + 0); ((index - pairwise_keys_start) * 2) + 0);
rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA, rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
((index - 4) * 2) + 1); ((index - pairwise_keys_start) * 2) + 1);
*((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0); *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0);
*((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1); *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1);
printk(" MAC: %pM", mac); printk(" MAC: %pM", mac);
...@@ -1429,116 +1428,6 @@ static void b43_write_beacon_template(struct b43_wldev *dev, ...@@ -1429,116 +1428,6 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset); b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
} }
static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
u16 shm_offset, u16 size,
struct ieee80211_rate *rate)
{
struct b43_plcp_hdr4 plcp;
u32 tmp;
__le16 dur;
plcp.data = 0;
b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, size,
rate);
/* Write PLCP in two parts and timing for packet transfer */
tmp = le32_to_cpu(plcp.data);
b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF);
b43_shm_write16(dev, B43_SHM_SHARED, shm_offset + 2, tmp >> 16);
b43_shm_write16(dev, B43_SHM_SHARED, shm_offset + 6, le16_to_cpu(dur));
}
/* Instead of using custom probe response template, this function
* just patches custom beacon template by:
* 1) Changing packet type
* 2) Patching duration field
* 3) Stripping TIM
*/
static const u8 *b43_generate_probe_resp(struct b43_wldev *dev,
u16 *dest_size,
struct ieee80211_rate *rate)
{
const u8 *src_data;
u8 *dest_data;
u16 src_size, elem_size, src_pos, dest_pos;
__le16 dur;
struct ieee80211_hdr *hdr;
size_t ie_start;
src_size = dev->wl->current_beacon->len;
src_data = (const u8 *)dev->wl->current_beacon->data;
/* Get the start offset of the variable IEs in the packet. */
ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
B43_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt, u.beacon.variable));
if (B43_WARN_ON(src_size < ie_start))
return NULL;
dest_data = kmalloc(src_size, GFP_ATOMIC);
if (unlikely(!dest_data))
return NULL;
/* Copy the static data and all Information Elements, except the TIM. */
memcpy(dest_data, src_data, ie_start);
src_pos = ie_start;
dest_pos = ie_start;
for ( ; src_pos < src_size - 2; src_pos += elem_size) {
elem_size = src_data[src_pos + 1] + 2;
if (src_data[src_pos] == 5) {
/* This is the TIM. */
continue;
}
memcpy(dest_data + dest_pos, src_data + src_pos,
elem_size);
dest_pos += elem_size;
}
*dest_size = dest_pos;
hdr = (struct ieee80211_hdr *)dest_data;
/* Set the frame control. */
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
IEEE80211_STYPE_PROBE_RESP);
dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, *dest_size,
rate);
hdr->duration_id = dur;
return dest_data;
}
static void b43_write_probe_resp_template(struct b43_wldev *dev,
u16 ram_offset,
u16 shm_size_offset,
struct ieee80211_rate *rate)
{
const u8 *probe_resp_data;
u16 size;
size = dev->wl->current_beacon->len;
probe_resp_data = b43_generate_probe_resp(dev, &size, rate);
if (unlikely(!probe_resp_data))
return;
/* Looks like PLCP headers plus packet timings are stored for
* all possible basic rates
*/
/* FIXME this is the wrong offset : it goes in tkip rx phase1 shm */
#if 0
b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
#endif
size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
b43_write_template_common(dev, probe_resp_data,
size, ram_offset, shm_size_offset,
rate->hw_value);
kfree(probe_resp_data);
}
static void b43_upload_beacon0(struct b43_wldev *dev) static void b43_upload_beacon0(struct b43_wldev *dev)
{ {
struct b43_wl *wl = dev->wl; struct b43_wl *wl = dev->wl;
...@@ -1546,10 +1435,6 @@ static void b43_upload_beacon0(struct b43_wldev *dev) ...@@ -1546,10 +1435,6 @@ static void b43_upload_beacon0(struct b43_wldev *dev)
if (wl->beacon0_uploaded) if (wl->beacon0_uploaded)
return; return;
b43_write_beacon_template(dev, 0x68, 0x18); b43_write_beacon_template(dev, 0x68, 0x18);
/* FIXME: Probe resp upload doesn't really belong here,
* but we don't use that feature anyway. */
b43_write_probe_resp_template(dev, 0x268, 0x4A,
&__b43_ratetable[3]);
wl->beacon0_uploaded = 1; wl->beacon0_uploaded = 1;
} }
...@@ -2990,17 +2875,14 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) ...@@ -2990,17 +2875,14 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
static void b43_security_init(struct b43_wldev *dev) static void b43_security_init(struct b43_wldev *dev)
{ {
dev->max_nr_keys = (dev->dev->id.revision >= 5) ? 58 : 20;
B43_WARN_ON(dev->max_nr_keys > ARRAY_SIZE(dev->key));
dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP); dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);
/* KTP is a word address, but we address SHM bytewise. /* KTP is a word address, but we address SHM bytewise.
* So multiply by two. * So multiply by two.
*/ */
dev->ktp *= 2; dev->ktp *= 2;
if (dev->dev->id.revision >= 5) { /* Number of RCMTA address slots */
/* Number of RCMTA address slots */ b43_write16(dev, B43_MMIO_RCMTA_COUNT, B43_NR_PAIRWISE_KEYS);
b43_write16(dev, B43_MMIO_RCMTA_COUNT, dev->max_nr_keys - 8); /* Clear the key memory. */
}
b43_clear_keys(dev); b43_clear_keys(dev);
} }
......
此差异已折叠。
...@@ -831,6 +831,22 @@ struct b43_phy_lp { ...@@ -831,6 +831,22 @@ struct b43_phy_lp {
/* Transmit isolation high band */ /* Transmit isolation high band */
u8 tx_isolation_hi_band; /* FIXME initial value? */ u8 tx_isolation_hi_band; /* FIXME initial value? */
/* Max transmit power medium band */
u16 max_tx_pwr_med_band;
/* Max transmit power low band */
u16 max_tx_pwr_low_band;
/* Max transmit power high band */
u16 max_tx_pwr_hi_band;
/* FIXME What are these used for? */
/* FIXME Is 15 the correct array size? */
u16 tx_max_rate[15];
u16 tx_max_ratel[15];
u16 tx_max_rateh[15];
/* Transmit power arrays */
s16 txpa[3], txpal[3], txpah[3];
/* Receive power offset */ /* Receive power offset */
u8 rx_pwr_offset; /* FIXME initial value? */ u8 rx_pwr_offset; /* FIXME initial value? */
...@@ -865,6 +881,9 @@ struct b43_phy_lp { ...@@ -865,6 +881,9 @@ struct b43_phy_lp {
/* Transmit iqlocal best coeffs */ /* Transmit iqlocal best coeffs */
bool tx_iqloc_best_coeffs_valid; bool tx_iqloc_best_coeffs_valid;
u8 tx_iqloc_best_coeffs[11]; u8 tx_iqloc_best_coeffs[11];
/* Used for "Save/Restore Dig Filt State" */
u16 dig_flt_state[9];
}; };
......
...@@ -26,6 +26,19 @@ void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset, ...@@ -26,6 +26,19 @@ void b43_lptab_write_bulk(struct b43_wldev *dev, u32 offset,
unsigned int nr_elements, const void *data); unsigned int nr_elements, const void *data);
void b2062_upload_init_table(struct b43_wldev *dev); void b2062_upload_init_table(struct b43_wldev *dev);
void b2063_upload_init_table(struct b43_wldev *dev);
struct lpphy_tx_gain_table_entry {
u8 gm, pga, pad, dac, bb_mult;
};
void lpphy_write_gain_table(struct b43_wldev *dev, int offset,
struct lpphy_tx_gain_table_entry data);
void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
struct lpphy_tx_gain_table_entry *table);
void lpphy_rev0_1_table_init(struct b43_wldev *dev);
void lpphy_rev2plus_table_init(struct b43_wldev *dev);
void lpphy_init_tx_gain_table(struct b43_wldev *dev);
#endif /* B43_TABLES_LPPHY_H_ */ #endif /* B43_TABLES_LPPHY_H_ */
...@@ -237,7 +237,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -237,7 +237,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
int wlhdr_len; int wlhdr_len;
size_t iv_len; size_t iv_len;
B43_WARN_ON(key_idx >= dev->max_nr_keys); B43_WARN_ON(key_idx >= ARRAY_SIZE(dev->key));
key = &(dev->key[key_idx]); key = &(dev->key[key_idx]);
if (unlikely(!key->keyconf)) { if (unlikely(!key->keyconf)) {
...@@ -578,7 +578,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -578,7 +578,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
* key index, but the ucode passed it slightly different. * key index, but the ucode passed it slightly different.
*/ */
keyidx = b43_kidx_to_raw(dev, keyidx); keyidx = b43_kidx_to_raw(dev, keyidx);
B43_WARN_ON(keyidx >= dev->max_nr_keys); B43_WARN_ON(keyidx >= ARRAY_SIZE(dev->key));
if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) { if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) {
wlhdr_len = ieee80211_hdrlen(fctl); wlhdr_len = ieee80211_hdrlen(fctl);
......
...@@ -117,8 +117,8 @@ static struct iwl_lib_ops iwl1000_lib = { ...@@ -117,8 +117,8 @@ static struct iwl_lib_ops iwl1000_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS, EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS, EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS, EEPROM_5000_REG_BAND_5_CHANNELS,
EEPROM_5000_REG_BAND_24_FAT_CHANNELS, EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_FAT_CHANNELS EEPROM_5000_REG_BAND_52_HT40_CHANNELS
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
......
...@@ -176,7 +176,7 @@ struct iwl3945_eeprom { ...@@ -176,7 +176,7 @@ struct iwl3945_eeprom {
* in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
* txpower (MSB). * txpower (MSB).
* *
* Entries immediately below are for 20 MHz channel width. FAT (40 MHz) * Entries immediately below are for 20 MHz channel width. HT40 (40 MHz)
* channels (only for 4965, not supported by 3945) appear later in the EEPROM. * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
* *
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
......
...@@ -502,14 +502,14 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv, ...@@ -502,14 +502,14 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
} }
} }
if (print_dump) if (print_dump)
iwl_print_hex_dump(IWL_DL_RX, data, length); iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
} }
static void iwl3945_dbg_report_frame(struct iwl_priv *priv, static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
struct iwl_rx_packet *pkt, struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100) struct ieee80211_hdr *header, int group100)
{ {
if (iwl_debug_level & IWL_DL_RX) if (iwl_get_debug_level(priv) & IWL_DL_RX)
_iwl3945_dbg_report_frame(priv, pkt, header, group100); _iwl3945_dbg_report_frame(priv, pkt, header, group100);
} }
...@@ -544,9 +544,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, ...@@ -544,9 +544,7 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
struct ieee80211_rx_status *stats) struct ieee80211_rx_status *stats)
{ {
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
#ifdef CONFIG_IWLWIFI_LEDS
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
#endif
struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
short len = le16_to_cpu(rx_hdr->len); short len = le16_to_cpu(rx_hdr->len);
...@@ -577,6 +575,8 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv, ...@@ -577,6 +575,8 @@ static void iwl3945_pass_packet_to_mac80211(struct iwl_priv *priv,
if (ieee80211_is_data(hdr->frame_control)) if (ieee80211_is_data(hdr->frame_control))
priv->rxtxpackets += len; priv->rxtxpackets += len;
#endif #endif
iwl_update_stats(priv, false, hdr->frame_control, len);
memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
ieee80211_rx_irqsafe(priv->hw, rxb->skb); ieee80211_rx_irqsafe(priv->hw, rxb->skb);
rxb->skb = NULL; rxb->skb = NULL;
...@@ -679,6 +679,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, ...@@ -679,6 +679,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
/* Set "1" to report good data frames in groups of 100 */ /* Set "1" to report good data frames in groups of 100 */
iwl3945_dbg_report_frame(priv, pkt, header, 1); iwl3945_dbg_report_frame(priv, pkt, header, 1);
iwl_dbg_log_rx_data_frame(priv, le16_to_cpu(rx_hdr->len), header);
if (network_packet) { if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
...@@ -2851,8 +2852,8 @@ static struct iwl_lib_ops iwl3945_lib = { ...@@ -2851,8 +2852,8 @@ static struct iwl_lib_ops iwl3945_lib = {
EEPROM_REGULATORY_BAND_3_CHANNELS, EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS, EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS, EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_REGULATORY_BAND_NO_FAT, EEPROM_REGULATORY_BAND_NO_HT40,
EEPROM_REGULATORY_BAND_NO_FAT, EEPROM_REGULATORY_BAND_NO_HT40,
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwl3945_eeprom_acquire_semaphore, .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
......
...@@ -188,7 +188,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) ...@@ -188,7 +188,7 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
* *
* 1) Regulatory information (max txpower and channel usage flags) is provided * 1) Regulatory information (max txpower and channel usage flags) is provided
* separately for each channel that can possibly supported by 4965. * separately for each channel that can possibly supported by 4965.
* 40 MHz wide (.11n fat) channels are listed separately from 20 MHz * 40 MHz wide (.11n HT40) channels are listed separately from 20 MHz
* (legacy) channels. * (legacy) channels.
* *
* See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom
...@@ -251,8 +251,8 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) ...@@ -251,8 +251,8 @@ static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr)
* no reduction (such as with regulatory txpower limits) is required. * no reduction (such as with regulatory txpower limits) is required.
* *
* Saturation and Backoff values apply equally to 20 Mhz (legacy) channel * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel
* widths and 40 Mhz (.11n fat) channel widths; there is no separate * widths and 40 Mhz (.11n HT40) channel widths; there is no separate
* factory measurement for fat channels. * factory measurement for ht40 channels.
* *
* The result of this step is the final target txpower. The rest of * The result of this step is the final target txpower. The rest of
* the steps figure out the proper settings for the device to achieve * the steps figure out the proper settings for the device to achieve
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "iwl-sta.h" #include "iwl-sta.h"
static int iwl4965_send_tx_power(struct iwl_priv *priv); static int iwl4965_send_tx_power(struct iwl_priv *priv);
static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL4965_UCODE_API_MAX 2 #define IWL4965_UCODE_API_MAX 2
...@@ -146,7 +146,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv) ...@@ -146,7 +146,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Begin load bsm\n"); IWL_DEBUG_INFO(priv, "Begin load bsm\n");
priv->ucode_type = UCODE_INIT; priv->ucode_type = UCODE_RT;
/* make sure bootstrap program is no larger than BSM's SRAM size */ /* make sure bootstrap program is no larger than BSM's SRAM size */
if (len > IWL49_MAX_BSM_SIZE) if (len > IWL49_MAX_BSM_SIZE)
...@@ -256,8 +256,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv) ...@@ -256,8 +256,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
*/ */
static void iwl4965_init_alive_start(struct iwl_priv *priv) static void iwl4965_init_alive_start(struct iwl_priv *priv)
{ {
int ret;
/* Check alive response for "valid" sign from uCode */ /* Check alive response for "valid" sign from uCode */
if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
/* We had an error bringing up the hardware, so take it /* We had an error bringing up the hardware, so take it
...@@ -289,35 +287,13 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) ...@@ -289,35 +287,13 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
goto restart; goto restart;
} }
priv->ucode_type = UCODE_RT;
if (test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
IWL_WARN(priv, "Runtime uCode already alive? "
"Waiting for alive anyway\n");
clear_bit(STATUS_RT_UCODE_ALIVE, &priv->status);
}
ret = wait_event_interruptible_timeout(
priv->wait_command_queue,
test_bit(STATUS_RT_UCODE_ALIVE, &priv->status),
UCODE_ALIVE_TIMEOUT);
if (!ret) {
/* FIXME: if STATUS_RT_UCODE_ALIVE timeout
* go back to restart the download Init uCode again
* this might cause to trap in the restart loop
*/
priv->ucode_type = UCODE_NONE;
if (!test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
IWL_ERR(priv, "Runtime timeout after %dms\n",
jiffies_to_msecs(UCODE_ALIVE_TIMEOUT));
goto restart;
}
}
return; return;
restart: restart:
queue_work(priv->workqueue, &priv->restart); queue_work(priv->workqueue, &priv->restart);
} }
static bool is_fat_channel(__le32 rxon_flags) static bool is_ht40_channel(__le32 rxon_flags)
{ {
int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK) int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK)
>> RXON_FLG_CHANNEL_MODE_POS; >> RXON_FLG_CHANNEL_MODE_POS;
...@@ -806,7 +782,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) ...@@ -806,7 +782,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_5GHZ); priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
...@@ -1266,7 +1242,7 @@ static const struct gain_entry gain_table[2][108] = { ...@@ -1266,7 +1242,7 @@ static const struct gain_entry gain_table[2][108] = {
}; };
static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
u8 is_fat, u8 ctrl_chan_high, u8 is_ht40, u8 ctrl_chan_high,
struct iwl4965_tx_power_db *tx_power_tbl) struct iwl4965_tx_power_db *tx_power_tbl)
{ {
u8 saturation_power; u8 saturation_power;
...@@ -1298,8 +1274,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1298,8 +1274,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
user_target_power = 2 * priv->tx_power_user_lmt; user_target_power = 2 * priv->tx_power_user_lmt;
/* Get current (RXON) channel, band, width */ /* Get current (RXON) channel, band, width */
IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_fat %d\n", channel, band, IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band,
is_fat); is_ht40);
ch_info = iwl_get_channel_info(priv, priv->band, channel); ch_info = iwl_get_channel_info(priv, priv->band, channel);
...@@ -1318,7 +1294,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1318,7 +1294,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
channel, txatten_grp); channel, txatten_grp);
if (is_fat) { if (is_ht40) {
if (ctrl_chan_high) if (ctrl_chan_high)
channel -= 2; channel -= 2;
else else
...@@ -1342,8 +1318,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1342,8 +1318,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* regulatory txpower limits ... reg_limit values are in half-dBm, /* regulatory txpower limits ... reg_limit values are in half-dBm,
* max_power_avg values are in dBm, convert * 2 */ * max_power_avg values are in dBm, convert * 2 */
if (is_fat) if (is_ht40)
reg_limit = ch_info->fat_max_power_avg * 2; reg_limit = ch_info->ht40_max_power_avg * 2;
else else
reg_limit = ch_info->max_power_avg * 2; reg_limit = ch_info->max_power_avg * 2;
...@@ -1509,7 +1485,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1509,7 +1485,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/** /**
* iwl4965_send_tx_power - Configure the TXPOWER level user limit * iwl4965_send_tx_power - Configure the TXPOWER level user limit
* *
* Uses the active RXON for channel, band, and characteristics (fat, high) * Uses the active RXON for channel, band, and characteristics (ht40, high)
* The power limit is taken from priv->tx_power_user_lmt. * The power limit is taken from priv->tx_power_user_lmt.
*/ */
static int iwl4965_send_tx_power(struct iwl_priv *priv) static int iwl4965_send_tx_power(struct iwl_priv *priv)
...@@ -1517,7 +1493,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) ...@@ -1517,7 +1493,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
struct iwl4965_txpowertable_cmd cmd = { 0 }; struct iwl4965_txpowertable_cmd cmd = { 0 };
int ret; int ret;
u8 band = 0; u8 band = 0;
bool is_fat = false; bool is_ht40 = false;
u8 ctrl_chan_high = 0; u8 ctrl_chan_high = 0;
if (test_bit(STATUS_SCANNING, &priv->status)) { if (test_bit(STATUS_SCANNING, &priv->status)) {
...@@ -1530,9 +1506,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) ...@@ -1530,9 +1506,9 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
band = priv->band == IEEE80211_BAND_2GHZ; band = priv->band == IEEE80211_BAND_2GHZ;
is_fat = is_fat_channel(priv->active_rxon.flags); is_ht40 = is_ht40_channel(priv->active_rxon.flags);
if (is_fat && if (is_ht40 &&
(priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1; ctrl_chan_high = 1;
...@@ -1541,7 +1517,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) ...@@ -1541,7 +1517,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
ret = iwl4965_fill_txpower_tbl(priv, band, ret = iwl4965_fill_txpower_tbl(priv, band,
le16_to_cpu(priv->active_rxon.channel), le16_to_cpu(priv->active_rxon.channel),
is_fat, ctrl_chan_high, &cmd.tx_power); is_ht40, ctrl_chan_high, &cmd.tx_power);
if (ret) if (ret)
goto out; goto out;
...@@ -1595,7 +1571,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) ...@@ -1595,7 +1571,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
{ {
int rc; int rc;
u8 band = 0; u8 band = 0;
bool is_fat = false; bool is_ht40 = false;
u8 ctrl_chan_high = 0; u8 ctrl_chan_high = 0;
struct iwl4965_channel_switch_cmd cmd = { 0 }; struct iwl4965_channel_switch_cmd cmd = { 0 };
const struct iwl_channel_info *ch_info; const struct iwl_channel_info *ch_info;
...@@ -1604,9 +1580,9 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) ...@@ -1604,9 +1580,9 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
ch_info = iwl_get_channel_info(priv, priv->band, channel); ch_info = iwl_get_channel_info(priv, priv->band, channel);
is_fat = is_fat_channel(priv->staging_rxon.flags); is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
if (is_fat && if (is_ht40 &&
(priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1; ctrl_chan_high = 1;
...@@ -1621,7 +1597,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) ...@@ -1621,7 +1597,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
else else
cmd.expect_beacon = 1; cmd.expect_beacon = 1;
rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_fat, rc = iwl4965_fill_txpower_tbl(priv, band, channel, is_ht40,
ctrl_chan_high, &cmd.tx_power); ctrl_chan_high, &cmd.tx_power);
if (rc) { if (rc) {
IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc); IWL_DEBUG_11H(priv, "error:%d fill txpower_tbl\n", rc);
...@@ -1680,7 +1656,7 @@ static s32 sign_extend(u32 oper, int index) ...@@ -1680,7 +1656,7 @@ static s32 sign_extend(u32 oper, int index)
* *
* A return of <0 indicates bogus data in the statistics * A return of <0 indicates bogus data in the statistics
*/ */
static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
{ {
s32 temperature; s32 temperature;
s32 vt; s32 vt;
...@@ -1688,8 +1664,8 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) ...@@ -1688,8 +1664,8 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
u32 R4; u32 R4;
if (test_bit(STATUS_TEMPERATURE, &priv->status) && if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
(priv->statistics.flag & STATISTICS_REPLY_FLG_FAT_MODE_MSK)) { (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
IWL_DEBUG_TEMP(priv, "Running FAT temperature calibration\n"); IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]); R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]); R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]); R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
...@@ -2330,8 +2306,8 @@ static struct iwl_lib_ops iwl4965_lib = { ...@@ -2330,8 +2306,8 @@ static struct iwl_lib_ops iwl4965_lib = {
EEPROM_REGULATORY_BAND_3_CHANNELS, EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS, EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS, EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS, EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
......
...@@ -845,7 +845,7 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -845,7 +845,7 @@ int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
} }
priv->hw_params.max_bsm_size = 0; priv->hw_params.max_bsm_size = 0;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ); BIT(IEEE80211_BAND_5GHZ);
priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
...@@ -1547,8 +1547,8 @@ struct iwl_lib_ops iwl5000_lib = { ...@@ -1547,8 +1547,8 @@ struct iwl_lib_ops iwl5000_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS, EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS, EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS, EEPROM_5000_REG_BAND_5_CHANNELS,
EEPROM_5000_REG_BAND_24_FAT_CHANNELS, EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_FAT_CHANNELS EEPROM_5000_REG_BAND_52_HT40_CHANNELS
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
...@@ -1597,8 +1597,8 @@ static struct iwl_lib_ops iwl5150_lib = { ...@@ -1597,8 +1597,8 @@ static struct iwl_lib_ops iwl5150_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS, EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS, EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS, EEPROM_5000_REG_BAND_5_CHANNELS,
EEPROM_5000_REG_BAND_24_FAT_CHANNELS, EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_FAT_CHANNELS EEPROM_5000_REG_BAND_52_HT40_CHANNELS
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
......
...@@ -118,8 +118,8 @@ static struct iwl_lib_ops iwl6000_lib = { ...@@ -118,8 +118,8 @@ static struct iwl_lib_ops iwl6000_lib = {
EEPROM_5000_REG_BAND_3_CHANNELS, EEPROM_5000_REG_BAND_3_CHANNELS,
EEPROM_5000_REG_BAND_4_CHANNELS, EEPROM_5000_REG_BAND_4_CHANNELS,
EEPROM_5000_REG_BAND_5_CHANNELS, EEPROM_5000_REG_BAND_5_CHANNELS,
EEPROM_5000_REG_BAND_24_FAT_CHANNELS, EEPROM_5000_REG_BAND_24_HT40_CHANNELS,
EEPROM_5000_REG_BAND_52_FAT_CHANNELS EEPROM_5000_REG_BAND_52_HT40_CHANNELS
}, },
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
......
...@@ -852,7 +852,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, ...@@ -852,7 +852,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
priv->cfg->ops->lib->update_chain_flags(priv); priv->cfg->ops->lib->update_chain_flags(priv);
data->state = IWL_CHAIN_NOISE_DONE; data->state = IWL_CHAIN_NOISE_DONE;
iwl_power_update_mode(priv, 0); iwl_power_update_mode(priv, false);
} }
EXPORT_SYMBOL(iwl_chain_noise_calibration); EXPORT_SYMBOL(iwl_chain_noise_calibration);
......
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
#include "iwl-core.h" #include "iwl-core.h"
#define IWL_CMD(x) case x: return #x
const char *get_cmd_string(u8 cmd) const char *get_cmd_string(u8 cmd)
{ {
switch (cmd) { switch (cmd) {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -1069,8 +1069,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry) ...@@ -1069,8 +1069,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry)
* otherwise we might be sending out invalid data. * otherwise we might be sending out invalid data.
*/ */
rt2x00pci_register_read(rt2x00dev, CSR14, &reg); rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
rt2x00_set_field32(&reg, CSR14_TBCN, 0);
rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0); rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
rt2x00pci_register_write(rt2x00dev, CSR14, reg); rt2x00pci_register_write(rt2x00dev, CSR14, reg);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册