提交 5eeaa2db 编写于 作者: D David S. Miller

Merge branch 'for-davem' of...

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
......@@ -1358,16 +1358,19 @@ F: drivers/mtd/devices/block2mtd.c
BLUETOOTH DRIVERS
M: Marcel Holtmann <marcel@holtmann.org>
M: Gustavo F. Padovan <padovan@profusion.mobi>
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
S: Maintained
F: drivers/bluetooth/
BLUETOOTH SUBSYSTEM
M: Marcel Holtmann <marcel@holtmann.org>
M: Gustavo F. Padovan <padovan@profusion.mobi>
L: linux-bluetooth@vger.kernel.org
W: http://www.bluez.org/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
S: Maintained
F: net/bluetooth/
F: include/net/bluetooth/
......@@ -6458,8 +6461,7 @@ 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/*
X: drivers/net/wireless/wl12xx/wl1271*
F: drivers/net/wireless/wl1251/*
WL1271 WIRELESS DRIVER
M: Luciano Coelho <luciano.coelho@nokia.com>
......
......@@ -117,8 +117,8 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
(event->data[2] == MODULE_ALREADY_UP)) ?
"Bring-up succeed" : "Bring-up failed");
if (event->length > 3)
priv->btmrvl_dev.dev_type = event->data[3];
if (event->length > 3 && event->data[3])
priv->btmrvl_dev.dev_type = HCI_AMP;
else
priv->btmrvl_dev.dev_type = HCI_BREDR;
......
......@@ -46,6 +46,9 @@ static const struct sdio_device_id btsdio_table[] = {
/* Generic Bluetooth Type-B SDIO device */
{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
/* Generic Bluetooth AMP controller */
{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) },
{ } /* Terminating entry */
};
......@@ -329,6 +332,11 @@ static int btsdio_probe(struct sdio_func *func,
hdev->bus = HCI_SDIO;
hdev->driver_data = data;
if (id->class == SDIO_CLASS_BT_AMP)
hdev->dev_type = HCI_AMP;
else
hdev->dev_type = HCI_BREDR;
data->hdev = hdev;
SET_HCIDEV_DEV(hdev, &func->dev);
......
......@@ -59,9 +59,15 @@ static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Apple MacBookPro 7,1 */
{ USB_DEVICE(0x05ac, 0x8213) },
/* Apple iMac11,1 */
{ USB_DEVICE(0x05ac, 0x8215) },
/* Apple MacBookPro6,2 */
{ USB_DEVICE(0x05ac, 0x8218) },
/* AVM BlueFRITZ! USB v2.0 */
{ USB_DEVICE(0x057c, 0x3800) },
......
......@@ -101,7 +101,7 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
break;
case HCI_SCODATA_PKT:
hdev->stat.cmd_tx++;
hdev->stat.sco_tx++;
break;
}
}
......
......@@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig"
source "drivers/net/wireless/orinoco/Kconfig"
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/rt2x00/Kconfig"
source "drivers/net/wireless/wl1251/Kconfig"
source "drivers/net/wireless/wl12xx/Kconfig"
source "drivers/net/wireless/zd1211rw/Kconfig"
......
......@@ -49,6 +49,7 @@ obj-$(CONFIG_ATH_COMMON) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
obj-$(CONFIG_WL1251) += wl1251/
obj-$(CONFIG_WL12XX) += wl12xx/
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
......
......@@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param)
if (priv->device_unplugged) {
at76_dbg(DBG_DEVSTART, "device unplugged");
if (urb)
at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
return;
}
......
......@@ -19,6 +19,7 @@
#include <linux/skbuff.h>
#include <linux/if_ether.h>
#include <linux/spinlock.h>
#include <net/mac80211.h>
/*
......@@ -42,6 +43,13 @@ struct ath_ani {
struct timer_list timer;
};
struct ath_cycle_counters {
u32 cycles;
u32 rx_busy;
u32 rx_frame;
u32 tx_frame;
};
enum ath_device_state {
ATH_HW_UNAVAILABLE,
ATH_HW_INITIALIZED,
......@@ -145,6 +153,12 @@ struct ath_common {
DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX);
enum ath_crypt_caps crypt_caps;
unsigned int clockrate;
spinlock_t cc_lock;
struct ath_cycle_counters cc_ani;
struct ath_cycle_counters cc_survey;
struct ath_regulatory regulatory;
const struct ath_ops *ops;
const struct ath_bus_ops *bus_ops;
......@@ -161,5 +175,7 @@ int ath_key_config(struct ath_common *common,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key);
bool ath_hw_keyreset(struct ath_common *common, u16 entry);
void ath_hw_cycle_counters_update(struct ath_common *common);
int32_t ath_hw_get_listen_time(struct ath_common *common);
#endif /* ATH_H */
......@@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as)
/**
* ath5k_hw_ani_get_listen_time() - Calculate time spent listening
* ath5k_hw_ani_get_listen_time() - Update counters and return listening time
*
* Return an approximation of the time spent "listening" in milliseconds (ms)
* since the last call of this function by deducting the cycles spent
* transmitting and receiving from the total cycle count.
* Save profile count values for debugging/statistics and because we might want
* to use them later.
*
* We assume no one else clears these registers!
* since the last call of this function.
* Save a snapshot of the counter values for debugging/statistics.
*/
static int
ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as)
{
struct ath_common *common = ath5k_hw_common(ah);
int listen;
/* freeze */
ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC);
/* read */
as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE);
as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR);
as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX);
as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX);
/* clear */
ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
/* un-freeze */
ath5k_hw_reg_write(ah, 0, AR5K_MIBC);
/* TODO: where does 44000 come from? (11g clock rate?) */
listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000;
if (as->pfc_cycles == 0 || listen < 0)
return 0;
spin_lock_bh(&common->cc_lock);
ath_hw_cycle_counters_update(common);
memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc));
/* clears common->cc_ani */
listen = ath_hw_get_listen_time(common);
spin_unlock_bh(&common->cc_lock);
return listen;
}
......
......@@ -75,10 +75,7 @@ struct ath5k_ani_state {
unsigned int cck_errors;
/* debug/statistics only: numbers from last ANI calibration */
unsigned int pfc_tx;
unsigned int pfc_rx;
unsigned int pfc_busy;
unsigned int pfc_cycles;
struct ath_cycle_counters last_cc;
unsigned int last_listen;
unsigned int last_ofdm_errors;
unsigned int last_cck_errors;
......
......@@ -1201,7 +1201,7 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
/* Clock rate related functions */
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
/* Queue Control Unit, DFS Control Unit Functions */
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
......
......@@ -62,6 +62,7 @@
#include "reg.h"
#include "debug.h"
#include "ani.h"
#include "../debug.h"
static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
......@@ -517,12 +518,14 @@ struct ath_vif_iter_data {
bool need_set_hw_addr;
bool found_active;
bool any_assoc;
enum nl80211_iftype opmode;
};
static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
{
struct ath_vif_iter_data *iter_data = data;
int i;
struct ath5k_vif *avf = (void *)vif->drv_priv;
if (iter_data->hw_macaddr)
for (i = 0; i < ETH_ALEN; i++)
......@@ -539,13 +542,32 @@ static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
iter_data->need_set_hw_addr = false;
if (!iter_data->any_assoc) {
struct ath5k_vif *avf = (void *)vif->drv_priv;
if (avf->assoc)
iter_data->any_assoc = true;
}
/* Calculate combined mode - when APs are active, operate in AP mode.
* Otherwise use the mode of the new interface. This can currently
* only deal with combinations of APs and STAs. Only one ad-hoc
* interfaces is allowed above.
*/
if (avf->opmode == NL80211_IFTYPE_AP)
iter_data->opmode = NL80211_IFTYPE_AP;
else
if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED)
iter_data->opmode = avf->opmode;
}
void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
static void ath_do_set_opmode(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
ath5k_hw_set_opmode(ah, sc->opmode);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n",
sc->opmode, ath_opmode_to_string(sc->opmode));
}
void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc,
struct ieee80211_vif *vif)
{
struct ath_common *common = ath5k_hw_common(sc->ah);
struct ath_vif_iter_data iter_data;
......@@ -558,6 +580,7 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
memset(&iter_data.mask, 0xff, ETH_ALEN);
iter_data.found_active = false;
iter_data.need_set_hw_addr = true;
iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED;
if (vif)
ath_vif_iter(&iter_data, vif->addr, vif);
......@@ -567,10 +590,18 @@ void ath5k_update_bssid_mask(struct ath5k_softc *sc, struct ieee80211_vif *vif)
&iter_data);
memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN);
sc->opmode = iter_data.opmode;
if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED)
/* Nothing active, default to station mode */
sc->opmode = NL80211_IFTYPE_STATION;
ath_do_set_opmode(sc);
if (iter_data.need_set_hw_addr && iter_data.found_active)
ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac);
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
if (ath5k_hw_hasbssidmask(sc->ah))
ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
}
static void
......@@ -582,15 +613,9 @@ ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif)
/* configure rx filter */
rfilt = sc->filter_flags;
ath5k_hw_set_rx_filter(ah, rfilt);
if (ath5k_hw_hasbssidmask(ah))
ath5k_update_bssid_mask(sc, vif);
/* configure operational mode */
ath5k_hw_set_opmode(ah, sc->opmode);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
ath5k_update_bssid_mask_and_opmode(sc, vif);
}
static inline int
......@@ -2688,7 +2713,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
SET_IEEE80211_PERM_ADDR(hw, mac);
memcpy(&sc->lladdr, mac, ETH_ALEN);
/* All MAC address bits matter for ACKs */
ath5k_update_bssid_mask(sc, NULL);
ath5k_update_bssid_mask_and_opmode(sc, NULL);
regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
......@@ -2786,7 +2811,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
{
struct ath5k_softc *sc = hw->priv;
int ret;
struct ath5k_hw *ah = sc->ah;
struct ath5k_vif *avf = (void *)vif->drv_priv;
mutex_lock(&sc->lock);
......@@ -2850,18 +2874,6 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
sc->num_adhoc_vifs++;
}
/* Set combined mode - when APs are configured, operate in AP mode.
* Otherwise use the mode of the new interface. This can currently
* only deal with combinations of APs and STAs. Only one ad-hoc
* interfaces is allowed above.
*/
if (sc->num_ap_vifs)
sc->opmode = NL80211_IFTYPE_AP;
else
sc->opmode = vif->type;
ath5k_hw_set_opmode(ah, sc->opmode);
/* Any MAC address is fine, all others are included through the
* filter.
*/
......@@ -2905,7 +2917,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
else if (avf->opmode == NL80211_IFTYPE_ADHOC)
sc->num_adhoc_vifs--;
ath5k_update_bssid_mask(sc, NULL);
ath5k_update_bssid_mask_and_opmode(sc, NULL);
mutex_unlock(&sc->lock);
}
......@@ -3529,8 +3541,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
sc->hw = hw;
sc->pdev = pdev;
ath5k_debug_init_device(sc);
/*
* Mark the device as detached to avoid processing
* interrupts until setup is complete.
......@@ -3638,6 +3648,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
}
}
ath5k_debug_init_device(sc);
/* ready to process interrupts */
__clear_bit(ATH_STAT_INVALID, sc->status);
......@@ -3724,8 +3735,6 @@ init_ath5k_pci(void)
{
int ret;
ath5k_debug_init();
ret = pci_register_driver(&ath5k_pci_driver);
if (ret) {
printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
......@@ -3739,8 +3748,6 @@ static void __exit
exit_ath5k_pci(void)
{
pci_unregister_driver(&ath5k_pci_driver);
ath5k_debug_finish();
}
module_init(init_ath5k_pci);
......
......@@ -60,6 +60,7 @@
#include "base.h"
#include "debug.h"
#include "../debug.h"
static unsigned int ath5k_debug;
module_param_named(debug, ath5k_debug, uint, 0);
......@@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0);
#include "reg.h"
#include "ani.h"
static struct dentry *ath5k_global_debugfs;
static int ath5k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
......@@ -520,9 +519,10 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
if (filt & AR5K_RX_FILTER_PHYERR_5211)
snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
if (filt & AR5K_RX_FILTER_RADARERR_5211)
len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n");
else
len += snprintf(buf+len, sizeof(buf)-len, "\n");
len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211");
len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n",
ath_opmode_to_string(sc->opmode), sc->opmode);
if (len > sizeof(buf))
len = sizeof(buf);
......@@ -715,20 +715,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
len += snprintf(buf+len, sizeof(buf)-len,
"beacon RSSI average:\t%d\n",
sc->ah->ah_beacon_rssi_avg.avg);
#define CC_PRINT(_struct, _field) \
_struct._field, \
_struct.cycles > 0 ? \
_struct._field*100/_struct.cycles : 0
len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n",
as->pfc_tx,
as->pfc_cycles > 0 ?
as->pfc_tx*100/as->pfc_cycles : 0);
CC_PRINT(as->last_cc, tx_frame));
len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n",
as->pfc_rx,
as->pfc_cycles > 0 ?
as->pfc_rx*100/as->pfc_cycles : 0);
CC_PRINT(as->last_cc, rx_frame));
len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n",
as->pfc_busy,
as->pfc_cycles > 0 ?
as->pfc_busy*100/as->pfc_cycles : 0);
CC_PRINT(as->last_cc, rx_busy));
#undef CC_PRINT
len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n",
as->pfc_cycles);
as->last_cc.cycles);
len += snprintf(buf+len, sizeof(buf)-len,
"listen time\t\t%d\tlast: %d\n",
as->listen_time, as->last_listen);
......@@ -879,21 +880,13 @@ static const struct file_operations fops_queue = {
};
/* init */
void
ath5k_debug_init(void)
{
ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
}
void
ath5k_debug_init_device(struct ath5k_softc *sc)
{
sc->debug.level = ath5k_debug;
sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
ath5k_global_debugfs);
sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
sc->hw->wiphy->debugfsdir);
sc->debug.debugfs_debug = debugfs_create_file("debug",
S_IWUSR | S_IRUSR,
......@@ -933,12 +926,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
&fops_queue);
}
void
ath5k_debug_finish(void)
{
debugfs_remove(ath5k_global_debugfs);
}
void
ath5k_debug_finish_device(struct ath5k_softc *sc)
{
......
......@@ -137,15 +137,9 @@ enum ath5k_debug_level {
__func__, __LINE__, ##__VA_ARGS__); \
} while (0)
void
ath5k_debug_init(void);
void
ath5k_debug_init_device(struct ath5k_softc *sc);
void
ath5k_debug_finish(void);
void
ath5k_debug_finish_device(struct ath5k_softc *sc);
......@@ -173,15 +167,9 @@ static inline void __attribute__ ((format (printf, 3, 4)))
ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
{}
static inline void
ath5k_debug_init(void) {}
static inline void
ath5k_debug_init_device(struct ath5k_softc *sc) {}
static inline void
ath5k_debug_finish(void) {}
static inline void
ath5k_debug_finish_device(struct ath5k_softc *sc) {}
......
......@@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
*/
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
{
return usec * ath5k_hw_get_clockrate(ah);
struct ath_common *common = ath5k_hw_common(ah);
return usec * common->clockrate;
}
/**
......@@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
*/
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
{
return clock / ath5k_hw_get_clockrate(ah);
struct ath_common *common = ath5k_hw_common(ah);
return clock / common->clockrate;
}
/**
* ath5k_hw_get_clockrate - Get the clock rate for current mode
* ath5k_hw_set_clockrate - Set common->clockrate for the current channel
*
* @ah: The &struct ath5k_hw
*/
unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
void ath5k_hw_set_clockrate(struct ath5k_hw *ah)
{
struct ieee80211_channel *channel = ah->ah_current_channel;
struct ath_common *common = ath5k_hw_common(ah);
int clock;
if (channel->hw_value & CHANNEL_5GHZ)
......@@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
if (channel->hw_value & CHANNEL_TURBO)
clock *= 2;
return clock;
common->clockrate = clock;
}
/**
......
......@@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
ah->ah_current_channel = channel;
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
ath5k_hw_set_clockrate(ah);
return 0;
}
......
......@@ -465,40 +465,6 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
}
static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah)
{
struct ath9k_channel *chan = ah->curchan;
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
u8 clockrate; /* in MHz */
if (!ah->curchan) /* should really check for CCK instead */
clockrate = ATH9K_CLOCK_RATE_CCK;
else if (conf->channel->band == IEEE80211_BAND_2GHZ)
clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
else if (IS_CHAN_A_FAST_CLOCK(ah, chan))
clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
else
clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
if (conf_is_ht40(conf))
return clockrate * 2;
return clockrate;
}
static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
{
int32_t listen_time;
int32_t clock_rate;
ath9k_hw_update_cycle_counters(ah);
clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;
listen_time = ah->listen_time / clock_rate;
ah->listen_time = 0;
return listen_time;
}
static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
{
struct ar5416AniState *aniState;
......@@ -667,7 +633,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
REGWRITE_BUFFER_FLUSH(ah);
}
static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ar5416AniState *aniState = &ah->curchan->ani;
......@@ -677,11 +643,13 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
u32 phyCnt1, phyCnt2;
int32_t listenTime;
listenTime = ath9k_hw_ani_get_listen_time(ah);
if (listenTime < 0) {
ath_hw_cycle_counters_update(common);
listenTime = ath_hw_get_listen_time(common);
if (listenTime <= 0) {
ah->stats.ast_ani_lneg++;
ath9k_ani_restart(ah);
return;
return false;
}
if (!use_new_ani(ah)) {
......@@ -696,7 +664,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
if (use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
if (phyCnt1 < ofdm_base) {
ath_print(common, ATH_DBG_ANI,
"phyCnt1 0x%x, resetting "
......@@ -715,7 +683,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
REG_WRITE(ah, AR_PHY_ERR_MASK_2,
AR_PHY_ERR_CCK_TIMING);
}
return;
return false;
}
ofdmPhyErrCnt = phyCnt1 - ofdm_base;
......@@ -727,7 +695,7 @@ static void ath9k_hw_ani_read_counters(struct ath_hw *ah)
ah->stats.ast_ani_cckerrs +=
cckPhyErrCnt - aniState->cckPhyErrCount;
aniState->cckPhyErrCount = cckPhyErrCnt;
return true;
}
void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
......@@ -743,7 +711,8 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
if (WARN_ON(!aniState))
return;
ath9k_hw_ani_read_counters(ah);
if (!ath9k_hw_ani_read_counters(ah))
return;
ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
aniState->listenTime;
......@@ -818,54 +787,6 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable_mib_counters);
void ath9k_hw_update_cycle_counters(struct ath_hw *ah)
{
struct ath_cycle_counters cc;
bool clear;
memcpy(&cc, &ah->cc, sizeof(cc));
/* freeze counters */
REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
ah->cc.cycles = REG_READ(ah, AR_CCCNT);
if (ah->cc.cycles < cc.cycles) {
clear = true;
goto skip;
}
ah->cc.rx_clear = REG_READ(ah, AR_RCCNT);
ah->cc.rx_frame = REG_READ(ah, AR_RFCNT);
ah->cc.tx_frame = REG_READ(ah, AR_TFCNT);
/* prevent wraparound */
if (ah->cc.cycles & BIT(31))
clear = true;
#define CC_DELTA(_field, _reg) ah->cc_delta._field += ah->cc._field - cc._field
CC_DELTA(cycles, AR_CCCNT);
CC_DELTA(rx_frame, AR_RFCNT);
CC_DELTA(rx_clear, AR_RCCNT);
CC_DELTA(tx_frame, AR_TFCNT);
#undef CC_DELTA
ah->listen_time += (ah->cc.cycles - cc.cycles) -
((ah->cc.rx_frame - cc.rx_frame) +
(ah->cc.tx_frame - cc.tx_frame));
skip:
if (clear) {
REG_WRITE(ah, AR_CCCNT, 0);
REG_WRITE(ah, AR_RFCNT, 0);
REG_WRITE(ah, AR_RCCNT, 0);
REG_WRITE(ah, AR_TFCNT, 0);
memset(&ah->cc, 0, sizeof(ah->cc));
}
/* unfreeze counters */
REG_WRITE(ah, AR_MIBC, 0);
}
/*
* Process a MIB interrupt. We may potentially be invoked because
* any of the MIB counters overflow/trigger so don't assume we're
......
......@@ -93,13 +93,6 @@ struct ath9k_mib_stats {
u32 beacons;
};
struct ath_cycle_counters {
u32 cycles;
u32 rx_frame;
u32 rx_clear;
u32 tx_frame;
};
/* INI default values for ANI registers */
struct ath9k_ani_default {
u16 m1ThreshLow;
......@@ -164,7 +157,6 @@ struct ar5416Stats {
void ath9k_enable_mib_counters(struct ath_hw *ah);
void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
void ath9k_hw_update_cycle_counters(struct ath_hw *ah);
void ath9k_hw_ani_setup(struct ath_hw *ah);
void ath9k_hw_ani_init(struct ath_hw *ah);
int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
......
......@@ -16,7 +16,6 @@
#include "hw.h"
#include "ar9003_mac.h"
#include "ar9003_2p0_initvals.h"
#include "ar9003_2p2_initvals.h"
/* General hardware code for the AR9003 hadware family */
......@@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion)
return false;
}
/* AR9003 2.0 */
static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah)
{
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
ar9300_2p0_mac_core,
ARRAY_SIZE(ar9300_2p0_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
ar9300_2p0_mac_postamble,
ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
/* bb */
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
ar9300_2p0_baseband_core,
ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
ar9300_2p0_baseband_postamble,
ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
ar9300_2p0_radio_core,
ARRAY_SIZE(ar9300_2p0_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
ar9300_2p0_radio_postamble,
ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
ar9300_2p0_soc_preamble,
ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
ar9300_2p0_soc_postamble,
ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p0,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
5);
/* Load PCIE SERDES settings from INI */
/* Awake Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdes,
ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
2);
/* Sleep Setting */
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
ar9300PciePhy_clkreq_enable_L1_2p0,
ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
2);
/* Fast clock modal settings */
INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9300Modes_fast_clock_2p0,
ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
3);
}
/* AR9003 2.2 */
static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
/*
* The AR9003 family uses a new INI format (pre, core, post
* arrays per subsystem). This provides support for the
* AR9003 2.2 chipsets.
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
......@@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah)
3);
}
/*
* The AR9003 family uses a new INI format (pre, core, post
* arrays per subsystem).
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
if (AR_SREV_9300_20(ah))
ar9003_2p0_hw_init_mode_regs(ah);
else
ar9003_2p2_hw_init_mode_regs(ah);
}
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
{
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9300_20(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
5);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
5);
break;
case 1:
if (AR_SREV_9300_20(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_high_ob_db_tx_gain_table_2p0,
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_high_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
5);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_high_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
5);
break;
case 2:
if (AR_SREV_9300_20(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_low_ob_db_tx_gain_table_2p0,
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
5);
else
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_low_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
5);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9300Modes_low_ob_db_tx_gain_table_2p2,
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
5);
break;
}
}
......@@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9300_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p0,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
2);
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
2);
break;
case 1:
if (AR_SREV_9300_20(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_wo_xlna_rx_gain_table_2p0,
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
2);
else
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_wo_xlna_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
2);
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9300Common_wo_xlna_rx_gain_table_2p2,
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
2);
break;
}
}
......
......@@ -1254,13 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
"** BB mode: BB_gen_controls=0x%08x **\n",
REG_READ(ah, AR_PHY_GEN_CTRL));
ath9k_hw_update_cycle_counters(ah);
#define PCT(_field) (ah->cc_delta._field * 100 / ah->cc_delta.cycles)
if (ah->cc_delta.cycles)
#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles)
if (common->cc_survey.cycles)
ath_print(common, ATH_DBG_RESET,
"** BB busy times: rx_clear=%d%%, "
"rx_frame=%d%%, tx_frame=%d%% **\n",
PCT(rx_clear), PCT(rx_frame), PCT(tx_frame));
PCT(rx_busy), PCT(rx_frame), PCT(tx_frame));
ath_print(common, ATH_DBG_RESET,
"==== BB update: done ====\n\n");
......
......@@ -239,12 +239,11 @@ struct ath_buf {
struct sk_buff *bf_mpdu; /* enclosing frame structure */
void *bf_desc; /* virtual addr of desc */
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
bool bf_stale;
bool bf_tx_aborted;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
struct ath_wiphy *aphy;
};
......@@ -593,6 +592,8 @@ struct ath_softc {
struct delayed_work wiphy_work;
unsigned long wiphy_scheduler_int;
int wiphy_scheduler_index;
struct survey_info *cur_survey;
struct survey_info survey[ATH9K_NUM_CHANNELS];
struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet;
......@@ -621,8 +622,6 @@ struct ath_softc {
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
const struct ath_rate_table *cur_rate_table;
enum wireless_mode cur_rate_mode;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led;
......
......@@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
bf = avp->av_bcbuf;
skb = bf->bf_mpdu;
if (skb) {
dma_unmap_single(sc->dev, bf->bf_dmacontext,
dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_buf_addr = 0;
}
/* Get a new beacon from mac80211 */
......@@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
}
bf->bf_buf_addr = bf->bf_dmacontext =
dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error on beaconing\n");
return NULL;
......@@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
}
/* NB: the beacon data buffer must be 32-bit aligned. */
......@@ -296,12 +298,12 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
avp->tsf_adjust = cpu_to_le64(0);
bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_dmacontext =
dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error on beacon alloc\n");
return -ENOMEM;
......@@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = bf->bf_mpdu;
dma_unmap_single(sc->dev, bf->bf_dmacontext,
dma_unmap_single(sc->dev, bf->bf_buf_addr,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
}
list_add_tail(&bf->list, &sc->beacon.bbuf);
......
......@@ -378,95 +378,6 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
{
struct ath_rc_stats *stats;
stats = &sc->debug.stats.rcstats[final_rate];
stats->success++;
}
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
int xretries, int retries, u8 per)
{
struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
stats->xretries += xretries;
stats->retries += retries;
stats->per = per;
}
static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char *buf;
unsigned int len = 0, max;
int i = 0;
ssize_t retval;
if (sc->cur_rate_table == NULL)
return 0;
max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1;
buf = kmalloc(max, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
len += sprintf(buf, "%6s %6s %6s "
"%10s %10s %10s %10s\n",
"HT", "MCS", "Rate",
"Success", "Retries", "XRetries", "PER");
for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
char mcs[5];
char htmode[5];
int used_mcs = 0, used_htmode = 0;
if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) {
used_mcs = snprintf(mcs, 5, "%d",
sc->cur_rate_table->info[i].ratecode);
if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy))
used_htmode = snprintf(htmode, 5, "HT40");
else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy))
used_htmode = snprintf(htmode, 5, "HT20");
else
used_htmode = snprintf(htmode, 5, "????");
}
mcs[used_mcs] = '\0';
htmode[used_htmode] = '\0';
len += snprintf(buf + len, max - len,
"%6s %6s %3u.%d: "
"%10u %10u %10u %10u\n",
htmode,
mcs,
ratekbps / 1000,
(ratekbps % 1000) / 100,
stats->success,
stats->retries,
stats->xretries,
stats->per);
}
if (len > max)
len = max;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_rcstat = {
.read = read_file_rcstat,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
{
switch (state) {
......@@ -977,10 +888,6 @@ int ath9k_init_debug(struct ath_hw *ah)
sc, &fops_interrupt))
goto err;
if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_rcstat))
goto err;
if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_wiphy))
goto err;
......
......@@ -80,13 +80,6 @@ struct ath_interrupt_stats {
u32 bb_watchdog;
};
struct ath_rc_stats {
u32 success;
u32 retries;
u32 xretries;
u8 per;
};
/**
* struct ath_tx_stats - Statistics about TX
* @tx_pkts_all: No. of total frames transmitted, including ones that
......@@ -160,7 +153,6 @@ struct ath_rx_stats {
struct ath_stats {
struct ath_interrupt_stats istats;
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
struct ath_rx_stats rxstats;
};
......@@ -177,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah);
int ath9k_debug_create_root(void);
void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf, struct ath_tx_status *ts);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
int xretries, int retries, u8 per);
#else
......@@ -209,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
{
}
static inline void ath_debug_stat_rc(struct ath_softc *sc,
int final_rate)
{
}
static inline void ath_debug_stat_tx(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_buf *bf,
......@@ -226,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc,
{
}
static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
int xretries, int retries, u8 per)
{
}
#endif /* CONFIG_ATH9K_DEBUGFS */
#endif /* DEBUG_H */
......@@ -566,7 +566,7 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
{
if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
priv->sbands[IEEE80211_BAND_2GHZ].channels =
ath9k_2ghz_channels;
priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
......@@ -577,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
ARRAY_SIZE(ath9k_legacy_rates);
}
if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) {
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels;
priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
priv->sbands[IEEE80211_BAND_5GHZ].n_channels =
......@@ -740,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
sizeof(struct htc_frame_hdr) + 4;
if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&priv->sbands[IEEE80211_BAND_2GHZ];
if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->sbands[IEEE80211_BAND_5GHZ];
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
setup_ht_cap(priv,
&priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes))
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
setup_ht_cap(priv,
&priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
}
......
......@@ -1454,6 +1454,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
FIF_PSPOLL | \
FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \
FIF_PROBE_REQ | \
FIF_FCSFAIL)
static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
......
......@@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
| ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */
if (ah->opmode != NL80211_IFTYPE_STATION)
if (priv->rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/*
......
......@@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah)
/* Helper Functions */
/********************/
static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
static void ath9k_hw_set_clockrate(struct ath_hw *ah)
{
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
struct ath_common *common = ath9k_hw_common(ah);
unsigned int clockrate;
if (!ah->curchan) /* should really check for CCK instead */
return usecs *ATH9K_CLOCK_RATE_CCK;
if (conf->channel->band == IEEE80211_BAND_2GHZ)
return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
clockrate = ATH9K_CLOCK_RATE_CCK;
else if (conf->channel->band == IEEE80211_BAND_2GHZ)
clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
else
return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM;
clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
if (conf_is_ht40(conf))
clockrate *= 2;
common->clockrate = clockrate;
}
static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
{
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
struct ath_common *common = ath9k_hw_common(ah);
if (conf_is_ht40(conf))
return ath9k_hw_mac_clks(ah, usecs) * 2;
else
return ath9k_hw_mac_clks(ah, usecs);
return usecs * common->clockrate;
}
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
......@@ -1156,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
"Failed to set channel\n");
return false;
}
ath9k_hw_set_clockrate(ah);
ah->eep_ops->set_txpower(ah, chan,
ath9k_regd_get_ctl(regulatory, chan),
......@@ -1368,6 +1372,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (r)
return r;
ath9k_hw_set_clockrate(ah);
ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < AR_NUM_DCU; i++)
......@@ -1794,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
return -EINVAL;
}
bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
if (eeval & AR5416_OPFLAGS_11A) {
set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
set_bit(ATH9K_MODE_11NA_HT20,
pCap->wireless_modes);
if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
set_bit(ATH9K_MODE_11NA_HT40PLUS,
pCap->wireless_modes);
set_bit(ATH9K_MODE_11NA_HT40MINUS,
pCap->wireless_modes);
}
}
}
if (eeval & AR5416_OPFLAGS_11A)
pCap->hw_caps |= ATH9K_HW_CAP_5GHZ;
if (eeval & AR5416_OPFLAGS_11G) {
set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
set_bit(ATH9K_MODE_11NG_HT20,
pCap->wireless_modes);
if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
set_bit(ATH9K_MODE_11NG_HT40PLUS,
pCap->wireless_modes);
set_bit(ATH9K_MODE_11NG_HT40MINUS,
pCap->wireless_modes);
}
}
}
if (eeval & AR5416_OPFLAGS_11G)
pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
/*
......
......@@ -61,6 +61,8 @@
#define ATH9K_RSSI_BAD -128
#define ATH9K_NUM_CHANNELS 38
/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) \
ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
......@@ -162,18 +164,6 @@ enum ath_ini_subsys {
ATH_INI_NUM_SPLIT,
};
enum wireless_mode {
ATH9K_MODE_11A = 0,
ATH9K_MODE_11G,
ATH9K_MODE_11NA_HT20,
ATH9K_MODE_11NG_HT20,
ATH9K_MODE_11NA_HT40PLUS,
ATH9K_MODE_11NA_HT40MINUS,
ATH9K_MODE_11NG_HT40PLUS,
ATH9K_MODE_11NG_HT40MINUS,
ATH9K_MODE_MAX,
};
enum ath9k_hw_caps {
ATH9K_HW_CAP_HT = BIT(0),
ATH9K_HW_CAP_RFSILENT = BIT(1),
......@@ -188,11 +178,12 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_SGI_20 = BIT(10),
ATH9K_HW_CAP_PAPRD = BIT(11),
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
ATH9K_HW_CAP_2GHZ = BIT(13),
ATH9K_HW_CAP_5GHZ = BIT(14),
};
struct ath9k_hw_capabilities {
u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
u16 total_queues;
u16 keycache_size;
u16 low_5ghz_chan, high_5ghz_chan;
......@@ -618,7 +609,7 @@ struct ath_hw {
struct ath9k_hw_version hw_version;
struct ath9k_ops_config config;
struct ath9k_hw_capabilities caps;
struct ath9k_channel channels[38];
struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
struct ath9k_channel *curchan;
union {
......@@ -740,8 +731,6 @@ struct ath_hw {
int coarse_low[5];
int firpwr[5];
enum ath9k_ani_cmd ani_function;
struct ath_cycle_counters cc, cc_delta;
int32_t listen_time;
/* Bluetooth coexistance */
struct ath_btcoex_hw btcoex_hw;
......
......@@ -481,7 +481,11 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
{
void *channels;
if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) +
ARRAY_SIZE(ath9k_5ghz_chantable) !=
ATH9K_NUM_CHANNELS);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
channels = kmemdup(ath9k_2ghz_chantable,
sizeof(ath9k_2ghz_chantable), GFP_KERNEL);
if (!channels)
......@@ -496,7 +500,7 @@ static int ath9k_init_channels_rates(struct ath_softc *sc)
ARRAY_SIZE(ath9k_legacy_rates);
}
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
channels = kmemdup(ath9k_5ghz_chantable,
sizeof(ath9k_5ghz_chantable), GFP_KERNEL);
if (!channels) {
......@@ -677,17 +681,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->rate_control_algorithm = "ath9k_rate_control";
#endif
if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&sc->sbands[IEEE80211_BAND_2GHZ];
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&sc->sbands[IEEE80211_BAND_5GHZ];
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
}
......
......@@ -18,36 +18,6 @@
#include "ath9k.h"
#include "btcoex.h"
static void ath_cache_conf_rate(struct ath_softc *sc,
struct ieee80211_conf *conf)
{
switch (conf->channel->band) {
case IEEE80211_BAND_2GHZ:
if (conf_is_ht20(conf))
sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
else if (conf_is_ht40_minus(conf))
sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
else if (conf_is_ht40_plus(conf))
sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS;
else
sc->cur_rate_mode = ATH9K_MODE_11G;
break;
case IEEE80211_BAND_5GHZ:
if (conf_is_ht20(conf))
sc->cur_rate_mode = ATH9K_MODE_11NA_HT20;
else if (conf_is_ht40_minus(conf))
sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS;
else if (conf_is_ht40_plus(conf))
sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS;
else
sc->cur_rate_mode = ATH9K_MODE_11A;
break;
default:
BUG_ON(1);
break;
}
}
static void ath_update_txpow(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
......@@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
void ath9k_ps_wakeup(struct ath_softc *sc)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long flags;
spin_lock_irqsave(&sc->sc_pm_lock, flags);
......@@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
/*
* While the hardware is asleep, the cycle counters contain no
* useful data. Better clear them now so that they don't mess up
* survey data results.
*/
spin_lock(&common->cc_lock);
ath_hw_cycle_counters_update(common);
memset(&common->cc_survey, 0, sizeof(common->cc_survey));
spin_unlock(&common->cc_lock);
unlock:
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
void ath9k_ps_restore(struct ath_softc *sc)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long flags;
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (--sc->ps_usecount != 0)
goto unlock;
spin_lock(&common->cc_lock);
ath_hw_cycle_counters_update(common);
spin_unlock(&common->cc_lock);
if (sc->ps_idle)
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
else if (sc->ps_enabled &&
......@@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common)
msecs_to_jiffies((u32)ah->config.ani_poll_interval));
}
static void ath_update_survey_nf(struct ath_softc *sc, int channel)
{
struct ath_hw *ah = sc->sc_ah;
struct ath9k_channel *chan = &ah->channels[channel];
struct survey_info *survey = &sc->survey[channel];
if (chan->noisefloor) {
survey->filled |= SURVEY_INFO_NOISE_DBM;
survey->noise = chan->noisefloor;
}
}
static void ath_update_survey_stats(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
int pos = ah->curchan - &ah->channels[0];
struct survey_info *survey = &sc->survey[pos];
struct ath_cycle_counters *cc = &common->cc_survey;
unsigned int div = common->clockrate * 1000;
if (ah->power_mode == ATH9K_PM_AWAKE)
ath_hw_cycle_counters_update(common);
if (cc->cycles > 0) {
survey->filled |= SURVEY_INFO_CHANNEL_TIME |
SURVEY_INFO_CHANNEL_TIME_BUSY |
SURVEY_INFO_CHANNEL_TIME_RX |
SURVEY_INFO_CHANNEL_TIME_TX;
survey->channel_time += cc->cycles / div;
survey->channel_time_busy += cc->rx_busy / div;
survey->channel_time_rx += cc->rx_frame / div;
survey->channel_time_tx += cc->tx_frame / div;
}
memset(cc, 0, sizeof(*cc));
ath_update_survey_nf(sc, pos);
}
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
......@@ -251,7 +276,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
goto ps_restore;
}
ath_cache_conf_rate(sc, &hw->conf);
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
......@@ -399,6 +423,7 @@ void ath_ani_calibrate(unsigned long data)
bool aniflag = false;
unsigned int timestamp = jiffies_to_msecs(jiffies);
u32 cal_interval, short_cal_interval, long_cal_interval;
unsigned long flags;
if (ah->caldata && ah->caldata->nfcal_interference)
long_cal_interval = ATH_LONG_CALINTERVAL_INT;
......@@ -449,8 +474,12 @@ void ath_ani_calibrate(unsigned long data)
/* Skip all processing if there's nothing to do. */
if (longcal || shortcal || aniflag) {
/* Call ANI routine if necessary */
if (aniflag)
if (aniflag) {
spin_lock_irqsave(&common->cc_lock, flags);
ath9k_hw_ani_monitor(ah, ah->curchan);
ath_update_survey_stats(sc);
spin_unlock_irqrestore(&common->cc_lock, flags);
}
/* Perform calibration if necessary */
if (longcal || shortcal) {
......@@ -635,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev)
struct ath_softc *sc = dev;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
enum ath9k_int status;
bool sched = false;
......@@ -684,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev)
if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
(status & ATH9K_INT_BB_WATCHDOG)) {
spin_lock(&common->cc_lock);
ath_hw_cycle_counters_update(common);
ar9003_hw_bb_watchdog_dbg_info(ah);
spin_unlock(&common->cc_lock);
goto chip_reset;
}
......@@ -713,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev)
* it will clear whatever condition caused
* the interrupt.
*/
spin_lock(&common->cc_lock);
ath9k_hw_proc_mib_event(ah);
spin_unlock(&common->cc_lock);
ath9k_hw_set_interrupts(ah, ah->imask);
}
......@@ -945,8 +982,6 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
* that changes the channel so update any state that
* might change as a result.
*/
ath_cache_conf_rate(sc, &hw->conf);
ath_update_txpow(sc);
if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
......@@ -1153,8 +1188,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)
ah->imask |= ATH9K_INT_CST;
ath_cache_conf_rate(sc, &hw->conf);
sc->sc_flags &= ~SC_OP_INVALID;
/* Disable BMISS interrupt when we're not associated */
......@@ -1522,7 +1555,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &hw->conf;
bool disable_radio;
......@@ -1588,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel;
int pos = curchan->hw_value;
int old_pos = -1;
unsigned long flags;
if (ah->curchan)
old_pos = ah->curchan - &ah->channels[0];
aphy->chan_idx = pos;
aphy->chan_is_ht = conf_is_ht(conf);
......@@ -1615,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
ath_update_chainmask(sc, conf_is_ht(conf));
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
ath_update_survey_stats(sc);
spin_unlock_irqrestore(&common->cc_lock, flags);
/*
* If the operating channel changes, change the survey in-use flags
* along with it.
* Reset the survey data for the new channel, unless we're switching
* back to the operating channel from an off-channel operation.
*/
if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
sc->cur_survey != &sc->survey[pos]) {
if (sc->cur_survey)
sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
sc->cur_survey = &sc->survey[pos];
memset(sc->cur_survey, 0, sizeof(struct survey_info));
sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
ath_print(common, ATH_DBG_FATAL,
"Unable to set channel\n");
mutex_unlock(&sc->mutex);
return -EINVAL;
}
/*
* The most recent snapshot of channel->noisefloor for the old
* channel is only available after the hardware reset. Copy it to
* the survey stats now.
*/
if (old_pos >= 0)
ath_update_survey_nf(sc, old_pos);
}
skip_chan_change:
......@@ -1651,6 +1723,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
FIF_PSPOLL | \
FIF_OTHER_BSS | \
FIF_BCN_PRBRESP_PROMISC | \
FIF_PROBE_REQ | \
FIF_FCSFAIL)
/* FIXME: sc->sc_full_reset ? */
......@@ -1990,9 +2063,15 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ieee80211_supported_band *sband;
struct ath9k_channel *chan;
struct ieee80211_channel *chan;
unsigned long flags;
int pos;
spin_lock_irqsave(&common->cc_lock, flags);
if (idx == 0)
ath_update_survey_stats(sc);
sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ];
if (sband && idx >= sband->n_channels) {
......@@ -2003,21 +2082,17 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
if (!sband)
sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ];
if (!sband || idx >= sband->n_channels)
return -ENOENT;
survey->channel = &sband->channels[idx];
chan = &ah->channels[survey->channel->hw_value];
survey->filled = 0;
if (chan == ah->curchan)
survey->filled |= SURVEY_INFO_IN_USE;
if (chan->noisefloor) {
survey->filled |= SURVEY_INFO_NOISE_DBM;
survey->noise = chan->noisefloor;
if (!sband || idx >= sband->n_channels) {
spin_unlock_irqrestore(&common->cc_lock, flags);
return -ENOENT;
}
chan = &sband->channels[idx];
pos = chan->hw_value;
memcpy(survey, &sc->survey[pos], sizeof(*survey));
survey->channel = chan;
spin_unlock_irqrestore(&common->cc_lock, flags);
return 0;
}
......
......@@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
[64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
[65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */
[66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
[67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
......@@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
0, /* Phy rates allowed initially */
};
static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = {
[ATH9K_MODE_11A] = &ar5416_11a_ratetable,
[ATH9K_MODE_11G] = &ar5416_11g_ratetable,
[ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable,
[ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable,
[ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable,
[ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable,
[ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable,
[ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable,
};
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate);
......@@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
*/
try_per_rate = 4;
rate_table = sc->cur_rate_table;
rate_table = ath_rc_priv->rate_table;
rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
/*
......@@ -1026,6 +1015,16 @@ static bool ath_rc_update_per(struct ath_softc *sc,
return state_change;
}
static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
int xretries, int retries, u8 per)
{
struct ath_rc_stats *stats = &rc->rcstats[rix];
stats->xretries += xretries;
stats->retries += retries;
stats->per = per;
}
/* Update PER, RSSI and whatever else that the code thinks it is doing.
If you can make sense of all this, you really need to go out more. */
......@@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
int rate;
u8 last_per;
bool state_change = false;
const struct ath_rate_table *rate_table = sc->cur_rate_table;
const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
......@@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
ath_rc_priv->per_down_time = now_msec;
}
ath_debug_stat_retries(sc, tx_rate, xretries, retries,
ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries,
ath_rc_priv->per[tx_rate]);
}
......@@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
u8 flags;
u32 i = 0, rix;
rate_table = sc->cur_rate_table;
rate_table = ath_rc_priv->rate_table;
/*
* If the first rate is not the final index, there
......@@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc,
static const
struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
enum ieee80211_band band,
bool is_ht,
bool is_cw_40)
bool is_ht)
{
int mode = 0;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
switch(band) {
case IEEE80211_BAND_2GHZ:
mode = ATH9K_MODE_11G;
if (is_ht)
mode = ATH9K_MODE_11NG_HT20;
if (is_cw_40)
mode = ATH9K_MODE_11NG_HT40PLUS;
break;
return &ar5416_11ng_ratetable;
return &ar5416_11g_ratetable;
case IEEE80211_BAND_5GHZ:
mode = ATH9K_MODE_11A;
if (is_ht)
mode = ATH9K_MODE_11NA_HT20;
if (is_cw_40)
mode = ATH9K_MODE_11NA_HT40PLUS;
break;
return &ar5416_11na_ratetable;
return &ar5416_11a_ratetable;
default:
ath_print(common, ATH_DBG_CONFIG, "Invalid band\n");
return NULL;
}
BUG_ON(mode >= ATH9K_MODE_MAX);
ath_print(common, ATH_DBG_CONFIG,
"Choosing rate table for mode: %d\n", mode);
sc->cur_rate_mode = mode;
return hw_rate_table[mode];
}
static void ath_rc_init(struct ath_softc *sc,
......@@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->max_valid_rate = k;
ath_rc_sort_validrates(rate_table, ath_rc_priv);
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
sc->cur_rate_table = rate_table;
ath_rc_priv->rate_table = rate_table;
ath_print(common, ATH_DBG_CONFIG,
"RC Initialized with capabilities: 0x%x\n",
......@@ -1340,6 +1323,15 @@ static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
/* mac80211 Rate Control callbacks */
/***********************************/
static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate)
{
struct ath_rc_stats *stats;
stats = &rc->rcstats[final_rate];
stats->success++;
}
static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
......@@ -1375,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
return;
if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
tx_info->status.ampdu_ack_len =
(tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
tx_info->status.ampdu_len = 1;
}
/*
* If an underrun error is seen assume it as an excessive retry only
* if max frame trigger level has been reached (2 KB for singel stream,
......@@ -1413,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
}
}
ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table,
&tx_info->status.rates[final_ts_idx]));
ath_debug_stat_rc(ath_rc_priv,
ath_rc_get_rateindex(ath_rc_priv->rate_table,
&tx_info->status.rates[final_ts_idx]));
}
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
......@@ -1454,14 +1453,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
/* Choose rate table first */
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
rate_table = ath_choose_rate_table(sc, sband->band,
sta->ht_cap.ht_supported, is_cw40);
} else {
rate_table = hw_rate_table[sc->cur_rate_mode];
}
rate_table = ath_choose_rate_table(sc, sband->band,
sta->ht_cap.ht_supported);
ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
......@@ -1501,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) {
rate_table = ath_choose_rate_table(sc, sband->band,
sta->ht_cap.ht_supported,
oper_cw40);
sta->ht_cap.ht_supported);
ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
oper_cw40, oper_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
......@@ -1510,11 +1502,98 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
"Operating HT Bandwidth changed to: %d\n",
sc->hw->conf.channel_type);
sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode];
}
}
}
#ifdef CONFIG_ATH9K_DEBUGFS
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_rate_priv *rc = file->private_data;
char *buf;
unsigned int len = 0, max;
int i = 0;
ssize_t retval;
if (rc->rate_table == NULL)
return 0;
max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
buf = kmalloc(max, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
len += sprintf(buf, "%6s %6s %6s "
"%10s %10s %10s %10s\n",
"HT", "MCS", "Rate",
"Success", "Retries", "XRetries", "PER");
for (i = 0; i < rc->rate_table->rate_cnt; i++) {
u32 ratekbps = rc->rate_table->info[i].ratekbps;
struct ath_rc_stats *stats = &rc->rcstats[i];
char mcs[5];
char htmode[5];
int used_mcs = 0, used_htmode = 0;
if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) {
used_mcs = snprintf(mcs, 5, "%d",
rc->rate_table->info[i].ratecode);
if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy))
used_htmode = snprintf(htmode, 5, "HT40");
else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy))
used_htmode = snprintf(htmode, 5, "HT20");
else
used_htmode = snprintf(htmode, 5, "????");
}
mcs[used_mcs] = '\0';
htmode[used_htmode] = '\0';
len += snprintf(buf + len, max - len,
"%6s %6s %3u.%d: "
"%10u %10u %10u %10u\n",
htmode,
mcs,
ratekbps / 1000,
(ratekbps % 1000) / 100,
stats->success,
stats->retries,
stats->xretries,
stats->per);
}
if (len > max)
len = max;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_rcstat = {
.read = read_file_rcstat,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta,
struct dentry *dir)
{
struct ath_rate_priv *rc = priv_sta;
debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat);
}
#endif /* CONFIG_ATH9K_DEBUGFS */
static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
struct ath_wiphy *aphy = hw->priv;
......@@ -1561,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = {
.free = ath_rate_free,
.alloc_sta = ath_rate_alloc_sta,
.free_sta = ath_rate_free_sta,
#ifdef CONFIG_ATH9K_DEBUGFS
.add_sta_debugfs = ath_rate_add_sta_debugfs,
#endif
};
int ath_rate_control_register(void)
......
......@@ -135,20 +135,21 @@ enum {
/**
* struct ath_rate_table - Rate Control table
* @valid: valid for use in rate control
* @valid_single_stream: valid for use in rate control for
* single stream operation
* @phy: CCK/OFDM
* @rate_cnt: total number of rates for the given wireless mode
* @mcs_start: MCS rate index offset
* @rate_flags: Rate Control flags
* @phy: CCK/OFDM/HT20/HT40
* @ratekbps: rate in Kbits per second
* @user_ratekbps: user rate in Kbits per second
* @ratecode: rate that goes into HW descriptors
* @short_preamble: Mask for enabling short preamble in ratecode for CCK
* @dot11rate: value that goes into supported
* rates info element of MLME
* @ctrl_rate: Index of next lower basic rate, used for duration computation
* @max_4ms_framelen: maximum frame length(bytes) for tx duration
* @cw40index: Index of rates having 40MHz channel width
* @sgi_index: Index of rates having Short Guard Interval
* @ht_index: high throughput rates having 40MHz channel width and
* Short Guard Interval
* @probe_interval: interval for rate control to probe for other rates
* @rssi_reduce_interval: interval for rate control to reduce rssi
* @initial_ratemax: initial ratemax value
*/
struct ath_rate_table {
......@@ -175,6 +176,13 @@ struct ath_rateset {
u8 rs_rates[ATH_RATE_MAX];
};
struct ath_rc_stats {
u32 success;
u32 retries;
u32 xretries;
u8 per;
};
/**
* struct ath_rate_priv - Rate Control priv data
* @state: RC state
......@@ -211,6 +219,10 @@ struct ath_rate_priv {
struct ath_rateset neg_rates;
struct ath_rateset neg_ht_rates;
struct ath_rate_softc *asc;
const struct ath_rate_table *rate_table;
struct dentry *debugfs_rcstats;
struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
};
#define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0)
......
......@@ -268,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
......@@ -358,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX init\n");
error = -ENOMEM;
goto err;
}
bf->bf_dmacontext = bf->bf_buf_addr;
}
sc->rx.rxlink = NULL;
}
......@@ -393,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc)
common->rx_bufsize,
DMA_FROM_DEVICE);
dev_kfree_skb(skb);
bf->bf_buf_addr = 0;
bf->bf_mpdu = NULL;
}
}
......@@ -430,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
| ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */
if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
if (sc->rx.rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/*
......@@ -1735,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(common, ATH_DBG_FATAL,
"dma_mapping_error() on RX\n");
ath_rx_send_to_mac80211(hw, sc, skb, rxs);
break;
}
bf->bf_dmacontext = bf->bf_buf_addr;
/*
* change the default rx antenna if rx diversity chooses the
......
......@@ -107,12 +107,6 @@
#define AR_RXCFG_DMASZ_256B 6
#define AR_RXCFG_DMASZ_512B 7
#define AR_MIBC 0x0040
#define AR_MIBC_COW 0x00000001
#define AR_MIBC_FMC 0x00000002
#define AR_MIBC_CMC 0x00000004
#define AR_MIBC_MCS 0x00000008
#define AR_TOPS 0x0044
#define AR_TOPS_MASK 0x0000FFFF
......@@ -859,9 +853,6 @@
#define AR_SREV_9300(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
#define AR_SREV_9300_20(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20))
#define AR_SREV_9300_20_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
......@@ -1524,11 +1515,6 @@ enum {
#define AR_TPC_CHIRP 0x003f0000
#define AR_TPC_CHIRP_S 0x16
#define AR_TFCNT 0x80ec
#define AR_RFCNT 0x80f0
#define AR_RCCNT 0x80f4
#define AR_CCCNT 0x80f8
#define AR_QUIET1 0x80fc
#define AR_QUIET1_NEXT_QUIET_S 0
#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
......
......@@ -294,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
tbf->bf_buf_addr = bf->bf_buf_addr;
memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
tbf->bf_state = bf->bf_state;
tbf->bf_dmacontext = bf->bf_dmacontext;
return tbf;
}
......@@ -317,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
struct ieee80211_tx_rate rates[4];
int nframes;
skb = bf->bf_mpdu;
hdr = (struct ieee80211_hdr *)skb->data;
......@@ -325,6 +325,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
hw = bf->aphy->hw;
memcpy(rates, tx_info->control.rates, sizeof(rates));
nframes = bf->bf_nframes;
rcu_read_lock();
......@@ -341,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
!bf->bf_stale || bf_next != NULL)
list_move_tail(&bf->list, &bf_head);
ath_tx_rc_status(bf, ts, 0, 0, false);
ath_tx_rc_status(bf, ts, 1, 0, false);
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
0, 0);
......@@ -446,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
memcpy(tx_info->control.rates, rates, sizeof(rates));
bf->bf_nframes = nframes;
ath_tx_rc_status(bf, ts, nbad, txok, true);
rc_update = false;
} else {
......@@ -1637,17 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
bf->bf_mpdu = skb;
bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
skb->len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
bf->bf_mpdu = NULL;
bf->bf_buf_addr = 0;
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
"dma_mapping_error() on TX\n");
return -ENOMEM;
}
bf->bf_buf_addr = bf->bf_dmacontext;
bf->bf_tx_aborted = false;
return 0;
......@@ -1911,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
tx_flags |= ATH_TX_XRETRY;
}
dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
bf->bf_buf_addr = 0;
if (bf->bf_state.bfs_paprd) {
if (time_after(jiffies,
......@@ -1921,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
else
complete(&sc->paprd_complete);
} else {
ath_tx_complete(sc, skb, bf->aphy, tx_flags);
ath_debug_stat_tx(sc, txq, bf, ts);
ath_tx_complete(sc, skb, bf->aphy, tx_flags);
}
/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
* accidentally reference it later.
*/
bf->bf_mpdu = NULL;
/*
* Return the list of ath_buf of this mpdu to free queue
......@@ -1979,9 +1985,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if (ts->ts_status & ATH9K_TXERR_FILT)
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc)
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
BUG_ON(nbad > bf->bf_nframes);
tx_info->status.ampdu_len = bf->bf_nframes;
tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
}
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
if (ieee80211_is_data(hdr->frame_control)) {
......@@ -1991,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts,
if ((ts->ts_status & ATH9K_TXERR_XRETRY) ||
(ts->ts_status & ATH9K_TXERR_FIFO))
tx_info->pad[0] |= ATH_TX_INFO_XRETRY;
tx_info->status.ampdu_len = bf->bf_nframes;
tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad;
}
}
......@@ -2102,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
*/
if (ts.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
ath_tx_rc_status(bf, &ts, 0, txok, true);
ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true);
}
if (bf_isampdu(bf))
......@@ -2220,7 +2230,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
if (!bf_isampdu(bf)) {
if (txs.ts_status & ATH9K_TXERR_XRETRY)
bf->bf_state.bf_type |= BUF_XRETRY;
ath_tx_rc_status(bf, &txs, 0, txok, true);
ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true);
}
if (bf_isampdu(bf))
......
......@@ -576,6 +576,41 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
}
}
static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
{
__le16 fc;
if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
/*
* This frame is not part of an aMPDU.
* Therefore it is not subjected to any
* of the following content restrictions.
*/
return true;
}
/*
* "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
* certain frame types can be part of an aMPDU.
*
* In order to keep the processing cost down, I opted for a
* stateless filter solely based on the frame control field.
*/
fc = ((struct ieee80211_hdr *)buf)->frame_control;
if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
return true;
if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
ieee80211_is_back_req(fc))
return true;
if (ieee80211_is_action(fc))
return true;
return false;
}
/*
* If the frame alignment is right (or the kernel has
* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
......@@ -594,24 +629,19 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
struct ieee80211_rx_status status;
struct sk_buff *skb;
int mpdu_len;
u8 mac_status;
if (!IS_STARTED(ar))
return;
if (unlikely(len < sizeof(*mac))) {
ar->rx_dropped++;
return;
}
if (unlikely(len < sizeof(*mac)))
goto drop;
mpdu_len = len - sizeof(*mac);
mac = (void *)(buf + mpdu_len);
if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
ar->rx_dropped++;
return;
}
switch (mac->status & AR9170_RX_STATUS_MPDU) {
mac_status = mac->status;
switch (mac_status & AR9170_RX_STATUS_MPDU) {
case AR9170_RX_STATUS_MPDU_FIRST:
/* Aggregated MPDUs start with an PLCP header */
if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
......@@ -638,8 +668,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
"is clipped.\n");
}
ar->rx_dropped++;
return;
goto drop;
}
break;
......@@ -659,8 +688,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
"is clipped.\n");
}
ar->rx_dropped++;
return;
goto drop;
}
case AR9170_RX_STATUS_MPDU_MIDDLE:
......@@ -672,8 +700,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
wiphy_err(ar->hw->wiphy, "rx stream does not start "
"with a first_mpdu frame tag.\n");
ar->rx_dropped++;
return;
goto drop;
}
head = &ar->rx_plcp;
......@@ -696,16 +723,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
}
/* FC + DU + RA + FCS */
if (unlikely(mpdu_len < (2 + 2 + 6 + FCS_LEN))) {
ar->rx_dropped++;
return;
}
if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
goto drop;
memset(&status, 0, sizeof(status));
if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) {
ar->rx_dropped++;
return;
}
if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
goto drop;
if (!carl9170_ampdu_check(ar, buf, mac_status))
goto drop;
if (phy)
carl9170_rx_phy_status(ar, phy, &status);
......@@ -713,12 +739,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
carl9170_ps_beacon(ar, buf, mpdu_len);
skb = carl9170_rx_copy_data(buf, mpdu_len);
if (likely(skb)) {
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
ieee80211_rx(ar->hw, skb);
} else {
ar->rx_dropped++;
}
if (!skb)
goto drop;
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
ieee80211_rx(ar->hw, skb);
return;
drop:
ar->rx_dropped++;
}
static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf,
......
......@@ -74,6 +74,9 @@
#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30
#define AR9170_RX_STATUS_MPDU_LAST 0x10
#define AR9170_RX_STATUS_CONT_AGGR 0x40
#define AR9170_RX_STATUS_TOTAL_ERROR 0x80
#define AR9170_RX_ERROR_RXTO 0x01
#define AR9170_RX_ERROR_OVERRUN 0x02
#define AR9170_RX_ERROR_DECRYPT 0x04
......@@ -81,7 +84,6 @@
#define AR9170_RX_ERROR_WRONG_RA 0x10
#define AR9170_RX_ERROR_PLCP 0x20
#define AR9170_RX_ERROR_MMIC 0x40
#define AR9170_RX_ERROR_FATAL 0x80
/* these are either-or */
#define AR9170_TX_MAC_PROT_RTS 0x0001
......@@ -329,13 +331,15 @@ struct _carl9170_tx_superframe {
#define CARL9170_TX_SUPERDESC_LEN 24
#define AR9170_TX_HWDESC_LEN 8
#define AR9170_TX_SUPERFRAME_LEN (CARL9170_TX_HWDESC_LEN + \
AR9170_TX_SUPERDESC_LEN)
#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \
AR9170_TX_HWDESC_LEN)
struct ar9170_rx_head {
u8 plcp[12];
} __packed;
#define AR9170_RX_HEAD_LEN 12
struct ar9170_rx_phystatus {
union {
struct {
......@@ -350,12 +354,16 @@ struct ar9170_rx_phystatus {
u8 phy_err;
} __packed;
#define AR9170_RX_PHYSTATUS_LEN 20
struct ar9170_rx_macstatus {
u8 SAidx, DAidx;
u8 error;
u8 status;
} __packed;
#define AR9170_RX_MACSTATUS_LEN 4
struct ar9170_rx_frame_single {
struct ar9170_rx_head phy_head;
struct ieee80211_hdr i3e;
......
......@@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
va_end(args);
}
EXPORT_SYMBOL(ath_print);
const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
switch (opmode) {
case NL80211_IFTYPE_UNSPECIFIED:
return "UNSPEC";
case NL80211_IFTYPE_ADHOC:
return "ADHOC";
case NL80211_IFTYPE_STATION:
return "STATION";
case NL80211_IFTYPE_AP:
return "AP";
case NL80211_IFTYPE_AP_VLAN:
return "AP-VLAN";
case NL80211_IFTYPE_WDS:
return "WDS";
case NL80211_IFTYPE_MONITOR:
return "MONITOR";
case NL80211_IFTYPE_MESH_POINT:
return "MESH";
case NL80211_IFTYPE_P2P_CLIENT:
return "P2P-CLIENT";
case NL80211_IFTYPE_P2P_GO:
return "P2P-GO";
default:
return "UNKNOWN";
}
}
EXPORT_SYMBOL(ath_opmode_to_string);
......@@ -77,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...)
}
#endif /* CONFIG_ATH_DEBUG */
/** Returns string describing opmode, or NULL if unknown mode. */
#ifdef CONFIG_ATH_DEBUG
const char *ath_opmode_to_string(enum nl80211_iftype opmode);
#else
static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
{
return "UNKNOWN";
}
#endif
#endif /* ATH_DEBUG_H */
......@@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common)
REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
}
EXPORT_SYMBOL(ath_hw_setbssidmask);
/**
* ath_hw_cycle_counters_update - common function to update cycle counters
*
* @common: the ath_common struct for the device.
*
* This function is used to update all cycle counters in one place.
* It has to be called while holding common->cc_lock!
*/
void ath_hw_cycle_counters_update(struct ath_common *common)
{
u32 cycles, busy, rx, tx;
void *ah = common->ah;
/* freeze */
REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
/* read */
cycles = REG_READ(ah, AR_CCCNT);
busy = REG_READ(ah, AR_RCCNT);
rx = REG_READ(ah, AR_RFCNT);
tx = REG_READ(ah, AR_TFCNT);
/* clear */
REG_WRITE(ah, 0, AR_CCCNT);
REG_WRITE(ah, 0, AR_RFCNT);
REG_WRITE(ah, 0, AR_RCCNT);
REG_WRITE(ah, 0, AR_TFCNT);
/* unfreeze */
REG_WRITE(ah, 0, AR_MIBC);
/* update all cycle counters here */
common->cc_ani.cycles += cycles;
common->cc_ani.rx_busy += busy;
common->cc_ani.rx_frame += rx;
common->cc_ani.tx_frame += tx;
common->cc_survey.cycles += cycles;
common->cc_survey.rx_busy += busy;
common->cc_survey.rx_frame += rx;
common->cc_survey.tx_frame += tx;
}
EXPORT_SYMBOL(ath_hw_cycle_counters_update);
int32_t ath_hw_get_listen_time(struct ath_common *common)
{
struct ath_cycle_counters *cc = &common->cc_ani;
int32_t listen_time;
listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
(common->clockrate * 1000);
memset(cc, 0, sizeof(*cc));
return listen_time;
}
EXPORT_SYMBOL(ath_hw_get_listen_time);
......@@ -17,6 +17,12 @@
#ifndef ATH_REGISTERS_H
#define ATH_REGISTERS_H
#define AR_MIBC 0x0040
#define AR_MIBC_COW 0x00000001
#define AR_MIBC_FMC 0x00000002
#define AR_MIBC_CMC 0x00000004
#define AR_MIBC_MCS 0x00000008
/*
* BSSID mask registers. See ath_hw_set_bssid_mask()
* for detailed documentation about these registers.
......@@ -24,6 +30,11 @@
#define AR_BSSMSKL 0x80e0
#define AR_BSSMSKU 0x80e4
#define AR_TFCNT 0x80ec
#define AR_RFCNT 0x80f0
#define AR_RCCNT 0x80f4
#define AR_CCCNT 0x80f8
#define AR_KEYTABLE_0 0x8800
#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
#define AR_KEY_CACHE_SIZE 128
......
b43-y += main.o
b43-y += tables.o
b43-$(CONFIG_B43_NPHY) += tables_nphy.o
b43-$(CONFIG_B43_NPHY) += radio_2055.o
b43-$(CONFIG_B43_NPHY) += radio_2056.o
b43-y += phy_common.o
b43-y += phy_g.o
b43-y += phy_a.o
......
......@@ -2,6 +2,7 @@
#define LINUX_B43_PHY_COMMON_H_
#include <linux/types.h>
#include <linux/nl80211.h>
struct b43_wldev;
......@@ -250,8 +251,10 @@ struct b43_phy {
* check is needed. */
unsigned long next_txpwr_check_time;
/* current channel */
/* Current channel */
unsigned int channel;
u16 channel_freq;
enum nl80211_channel_type channel_type;
/* PHY TX errors counter. */
atomic_t txerr_cnt;
......
......@@ -29,6 +29,8 @@
#include "b43.h"
#include "phy_n.h"
#include "tables_nphy.h"
#include "radio_2055.h"
#include "radio_2056.h"
#include "main.h"
struct nphy_txgains {
......@@ -74,19 +76,11 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
u16 value, u8 core);
static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec)
static inline bool b43_channel_type_is_40mhz(
enum nl80211_channel_type channel_type)
{
return !chanspec->channel && !chanspec->sideband &&
!chanspec->b_width && !chanspec->b_freq;
}
static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1,
struct b43_chanspec *chanspec2)
{
return (chanspec1->channel == chanspec2->channel &&
chanspec1->sideband == chanspec2->sideband &&
chanspec1->b_width == chanspec2->b_width &&
chanspec1->b_freq == chanspec2->b_freq);
return (channel_type == NL80211_CHAN_HT40MINUS ||
channel_type == NL80211_CHAN_HT40PLUS);
}
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
......@@ -781,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
{
struct b43_phy_n *nphy = dev->phy.n;
u8 channel = nphy->radio_chanspec.channel;
u8 channel = dev->phy.channel;
int tone[2] = { 57, 58 };
u32 noise[2] = { 0x3FF, 0x3FF };
......@@ -855,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
gain[0] = 6;
gain[1] = 6;
} else {
tmp = 40370 - 315 * nphy->radio_chanspec.channel;
tmp = 40370 - 315 * dev->phy.channel;
gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1));
tmp = 23242 - 224 * nphy->radio_chanspec.channel;
tmp = 23242 - 224 * dev->phy.channel;
gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1));
}
} else {
......@@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
u16 *rssical_phy_regs = NULL;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if (b43_empty_chanspec(&nphy->rssical_chanspec_2G))
if (!nphy->rssical_chanspec_2G.center_freq)
return;
rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
} else {
if (b43_empty_chanspec(&nphy->rssical_chanspec_5G))
if (!nphy->rssical_chanspec_5G.center_freq)
return;
rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
......@@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
}
*iqcal_chanspec = nphy->radio_chanspec;
b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table);
iqcal_chanspec->center_freq = dev->phy.channel_freq;
iqcal_chanspec->channel_type = dev->phy.channel_type;
b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
if (nphy->hang_avoid)
b43_nphy_stay_in_carrier_search(dev, 0);
......@@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev)
struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G))
if (!nphy->iqcal_chanspec_2G.center_freq)
return;
table = nphy->cal_cache.txcal_coeffs_2G;
loft = &nphy->cal_cache.txcal_coeffs_2G[5];
} else {
if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G))
if (!nphy->iqcal_chanspec_5G.center_freq)
return;
table = nphy->cal_cache.txcal_coeffs_5G;
loft = &nphy->cal_cache.txcal_coeffs_5G[5];
......@@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length,
nphy->txiqlocal_bestc);
nphy->txiqlocal_coeffsvalid = true;
nphy->txiqlocal_chanspec = nphy->radio_chanspec;
nphy->txiqlocal_chanspec.center_freq =
dev->phy.channel_freq;
nphy->txiqlocal_chanspec.channel_type =
dev->phy.channel_type;
} else {
length = 11;
if (dev->phy.rev < 3)
......@@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
bool equal = true;
if (!nphy->txiqlocal_coeffsvalid ||
b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec))
nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq ||
nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type)
return;
b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
......@@ -3257,11 +3256,9 @@ int b43_phy_initn(struct b43_wldev *dev)
do_rssi_cal = false;
if (phy->rev >= 3) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
do_rssi_cal =
b43_empty_chanspec(&nphy->rssical_chanspec_2G);
do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq;
else
do_rssi_cal =
b43_empty_chanspec(&nphy->rssical_chanspec_5G);
do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq;
if (do_rssi_cal)
b43_nphy_rssi_cal(dev);
......@@ -3273,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev)
if (!((nphy->measure_hold & 0x6) != 0)) {
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G);
do_cal = !nphy->iqcal_chanspec_2G.center_freq;
else
do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G);
do_cal = !nphy->iqcal_chanspec_5G.center_freq;
if (nphy->mute)
do_cal = false;
......@@ -3323,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev)
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
static void b43_nphy_channel_setup(struct b43_wldev *dev,
const struct b43_phy_n_sfo_cfg *e,
struct b43_chanspec chanspec)
struct ieee80211_channel *new_channel)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
u16 tmp;
u16 old_band_5ghz;
u32 tmp32;
tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
if (chanspec.b_freq == 1 && tmp == 0) {
old_band_5ghz =
b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ;
if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32);
b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ);
} else if (chanspec.b_freq == 1) {
} else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) {
b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ);
tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR);
b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4);
......@@ -3350,13 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
b43_chantab_phy_upload(dev, e);
if (nphy->radio_chanspec.channel == 14) {
if (new_channel->hw_value == 14) {
b43_nphy_classifier(dev, 2, 0);
b43_phy_set(dev, B43_PHY_B_TEST, 0x0800);
} else {
b43_nphy_classifier(dev, 2, 2);
if (chanspec.b_freq == 2)
if (new_channel->band == IEEE80211_BAND_2GHZ)
b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840);
}
......@@ -3379,53 +3376,57 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev,
}
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */
static int b43_nphy_set_chanspec(struct b43_wldev *dev,
struct b43_chanspec chanspec)
static int b43_nphy_set_channel(struct b43_wldev *dev,
struct ieee80211_channel *channel,
enum nl80211_channel_type channel_type)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_n *nphy = dev->phy.n;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
u8 tmp;
u8 channel = chanspec.channel;
if (dev->phy.rev >= 3) {
/* TODO */
tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
channel->center_freq);
tabent_r3 = NULL;
if (!tabent_r3)
return -ESRCH;
} else {
tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel);
tabent_r2 = b43_nphy_get_chantabent_rev2(dev,
channel->hw_value);
if (!tabent_r2)
return -ESRCH;
}
nphy->radio_chanspec = chanspec;
/* Channel is set later in common code, but we need to set it on our
own to let this function's subcalls work properly. */
phy->channel = channel->hw_value;
phy->channel_freq = channel->center_freq;
if (chanspec.b_width != nphy->b_width)
; /* TODO: BMAC BW Set (chanspec.b_width) */
if (b43_channel_type_is_40mhz(phy->channel_type) !=
b43_channel_type_is_40mhz(channel_type))
; /* TODO: BMAC BW Set (channel_type) */
/* TODO: use defines */
if (chanspec.b_width == 3) {
if (chanspec.sideband == 2)
b43_phy_set(dev, B43_NPHY_RXCTL,
B43_NPHY_RXCTL_BSELU20);
else
b43_phy_mask(dev, B43_NPHY_RXCTL,
~B43_NPHY_RXCTL_BSELU20);
}
if (channel_type == NL80211_CHAN_HT40PLUS)
b43_phy_set(dev, B43_NPHY_RXCTL,
B43_NPHY_RXCTL_BSELU20);
else if (channel_type == NL80211_CHAN_HT40MINUS)
b43_phy_mask(dev, B43_NPHY_RXCTL,
~B43_NPHY_RXCTL_BSELU20);
if (dev->phy.rev >= 3) {
tmp = (chanspec.b_freq == 1) ? 4 : 0;
tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
/* TODO: PHY Radio2056 Setup (dev, tabent_r3); */
b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec);
b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel);
} else {
tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050;
tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050;
b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp);
b43_radio_2055_setup(dev, tabent_r2);
b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec);
b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel);
}
return 0;
......@@ -3567,8 +3568,8 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on)
static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
unsigned int new_channel)
{
struct b43_phy_n *nphy = dev->phy.n;
struct b43_chanspec chanspec;
struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
if ((new_channel < 1) || (new_channel > 14))
......@@ -3578,10 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev,
return -EINVAL;
}
chanspec = nphy->radio_chanspec;
chanspec.channel = new_channel;
return b43_nphy_set_chanspec(dev, chanspec);
return b43_nphy_set_channel(dev, channel, channel_type);
}
static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev)
......
......@@ -714,223 +714,11 @@
#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */
#define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A)
/* Broadcom 2055 radio registers */
#define B2055_GEN_SPARE 0x00 /* GEN spare */
#define B2055_SP_PINPD 0x02 /* SP PIN PD */
#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */
#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */
#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */
#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */
#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */
#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */
#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */
#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */
#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */
#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */
#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */
#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */
#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */
#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */
#define B2055_MASTER1 0x11 /* Master control 1 */
#define B2055_MASTER2 0x12 /* Master control 2 */
#define B2055_PD_LGEN 0x13 /* PD LGEN */
#define B2055_PD_PLLTS 0x14 /* PD PLL TS */
#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */
#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */
#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */
#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */
#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */
#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */
#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */
#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */
#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */
#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */
#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */
#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */
#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */
#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */
#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */
#define B2055_CAL_MISC 0x24 /* CAL MISC */
#define B2055_CAL_COUT 0x25 /* CAL Counter out */
#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */
#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */
#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */
#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */
#define B2055_CAL_TS 0x2A /* CAL TS */
#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */
#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */
#define B2055_PADDRV 0x2D /* PAD driver */
#define B2055_XOCTL1 0x2E /* XO Control 1 */
#define B2055_XOCTL2 0x2F /* XO Control 2 */
#define B2055_XOREGUL 0x30 /* XO Regulator */
#define B2055_XOMISC 0x31 /* XO misc */
#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */
#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */
#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */
#define B2055_PLL_REF 0x35 /* PLL reference */
#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */
#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */
#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */
#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */
#define B2055_PLL_RCAL 0x3A /* PLL RCAL */
#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */
#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */
#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */
#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */
#define B2055_RF_MMDSP 0x3F /* RF MMD spare */
#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */
#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */
#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */
#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */
#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */
#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */
#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */
#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */
#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */
#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */
#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */
#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */
#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */
#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */
#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */
#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */
#define B2055_VCO_KVCO 0x50 /* VCO KVCO */
#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */
#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */
#define B2055_VCO_REG 0x53 /* VCO Regulator */
#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */
#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */
#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */
#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */
#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */
#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */
#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */
#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */
#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */
#define B2055_LGEN_DIV 0x5D /* LGEN div */
#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */
#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */
#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */
#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */
#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */
#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */
#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */
#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */
#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */
#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */
#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */
#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */
#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */
#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */
#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */
#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */
#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */
#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */
#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */
#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */
#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */
#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */
#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */
#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */
#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */
#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */
#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */
#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */
#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */
#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */
#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */
#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */
#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */
#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */
#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */
#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */
#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */
#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */
#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */
#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */
#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */
#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */
#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */
#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */
#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */
#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */
#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */
#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */
#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */
#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */
#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */
#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */
#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */
#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */
#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */
#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */
#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */
#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */
#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */
#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */
#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */
#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */
#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */
#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */
#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */
#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */
#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */
#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */
#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */
#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */
#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */
#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */
#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */
#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */
#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */
#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */
#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */
#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */
#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */
#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */
#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */
#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */
#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */
#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */
#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */
#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */
#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */
#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */
#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */
#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */
#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */
#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */
#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */
#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */
#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */
#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */
#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */
#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */
#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */
#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */
#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */
#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */
#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */
#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */
#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */
#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */
#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */
#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */
#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */
#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */
#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */
struct b43_wldev;
struct b43_chanspec {
u8 channel;
u8 sideband;
u8 b_width;
u8 b_freq;
u16 center_freq;
enum nl80211_channel_type channel_type;
};
struct b43_phy_n_iq_comp {
......@@ -984,8 +772,6 @@ struct b43_phy_n {
u16 papd_epsilon_offset[2];
s32 preamble_override;
u32 bb_mult_save;
u8 b_width;
struct b43_chanspec radio_chanspec;
bool gain_boost;
bool elna_gain_config;
......
此差异已折叠。
此差异已折叠。
/*
Broadcom B43 wireless driver
IEEE 802.11n 2056 radio device data tables
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "b43.h"
#include "radio_2056.h"
#include "phy_common.h"
static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = {
};
const struct b43_nphy_channeltab_entry_rev3 *
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
{
const struct b43_nphy_channeltab_entry_rev3 *e;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) {
e = &(b43_nphy_channeltab_rev3[i]);
if (e->freq == freq)
return e;
}
return NULL;
}
此差异已折叠。
......@@ -12,7 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o
iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o
iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o
iwlagn-objs += iwl-agn-tt.o
iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册