Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem

This commit is contained in:
John W. Linville 2012-12-07 13:03:50 -05:00
commit 8024dc1910
147 changed files with 2867 additions and 1435 deletions

View File

@ -1674,10 +1674,9 @@ F: drivers/net/ethernet/broadcom/tg3.*
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
M: Brett Rudley <brudley@broadcom.com> M: Brett Rudley <brudley@broadcom.com>
M: Roland Vossen <rvossen@broadcom.com>
M: Arend van Spriel <arend@broadcom.com> M: Arend van Spriel <arend@broadcom.com>
M: Franky (Zhenhui) Lin <frankyl@broadcom.com> M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
M: Kan Yan <kanyan@broadcom.com> M: Hante Meuleman <meuleman@broadcom.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
L: brcm80211-dev-list@broadcom.com L: brcm80211-dev-list@broadcom.com
S: Supported S: Supported

View File

@ -84,6 +84,8 @@ extern void __exit bcma_host_pci_exit(void);
/* driver_pci.c */ /* driver_pci.c */
u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc); bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);

View File

@ -4,12 +4,15 @@
* *
* Copyright 2005, Broadcom Corporation * Copyright 2005, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <m@bues.ch> * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
* Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
* *
* Licensed under the GNU/GPL. See COPYING for details. * Licensed under the GNU/GPL. See COPYING for details.
*/ */
#include "bcma_private.h" #include "bcma_private.h"
#include <linux/bcm47xx_wdt.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/bcma/bcma.h> #include <linux/bcma/bcma.h>
static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
@ -22,6 +25,90 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
return value; return value;
} }
static u32 bcma_chipco_alp_clock(struct bcma_drv_cc *cc)
{
if (cc->capabilities & BCMA_CC_CAP_PMU)
return bcma_pmu_alp_clock(cc);
return 20000000;
}
static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
u32 nb;
if (cc->capabilities & BCMA_CC_CAP_PMU) {
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
nb = 32;
else if (cc->core->id.rev < 26)
nb = 16;
else
nb = (cc->core->id.rev >= 37) ? 32 : 24;
} else {
nb = 28;
}
if (nb == 32)
return 0xffffffff;
else
return (1 << nb) - 1;
}
static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
u32 ticks)
{
struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
return bcma_chipco_watchdog_timer_set(cc, ticks);
}
static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
u32 ms)
{
struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
u32 ticks;
ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
return ticks / cc->ticks_per_ms;
}
static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
if (cc->capabilities & BCMA_CC_CAP_PMU) {
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
/* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
return bcma_chipco_alp_clock(cc) / 4000;
else
/* based on 32KHz ILP clock */
return 32;
} else {
return bcma_chipco_alp_clock(cc) / 1000;
}
}
int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
{
struct bcm47xx_wdt wdt = {};
struct platform_device *pdev;
wdt.driver_data = cc;
wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
cc->core->bus->num, &wdt,
sizeof(wdt));
if (IS_ERR(pdev))
return PTR_ERR(pdev);
cc->watchdog = pdev;
return 0;
}
void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
{ {
if (cc->early_setup_done) if (cc->early_setup_done)
@ -69,15 +156,33 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
(leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
} }
cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
cc->setup_done = true; cc->setup_done = true;
} }
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
{ {
/* instant NMI */ u32 maxt;
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); enum bcma_clkmode clkmode;
maxt = bcma_chipco_watchdog_get_max_timer(cc);
if (cc->capabilities & BCMA_CC_CAP_PMU) {
if (ticks == 1)
ticks = 2;
else if (ticks > maxt)
ticks = maxt;
bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
} else {
clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC;
bcma_core_set_clockmode(cc->core, clkmode);
if (ticks > maxt)
ticks = maxt;
/* instant NMI */
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
}
return ticks;
} }
void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
@ -131,8 +236,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
struct bcma_serial_port *ports = cc->serial_ports; struct bcma_serial_port *ports = cc->serial_ports;
if (ccrev >= 11 && ccrev != 15) { if (ccrev >= 11 && ccrev != 15) {
/* Fixed ALP clock */ baud_base = bcma_chipco_alp_clock(cc);
baud_base = bcma_pmu_alp_clock(cc);
if (ccrev >= 21) { if (ccrev >= 21) {
/* Turn off UART clock before switching clocksource. */ /* Turn off UART clock before switching clocksource. */
bcma_cc_write32(cc, BCMA_CC_CORECTL, bcma_cc_write32(cc, BCMA_CC_CORECTL,

View File

@ -538,7 +538,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
{ {
struct resource *res; struct resource *res;
int pos; int pos, err;
if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
/* This is not a device on the PCI-core bridge. */ /* This is not a device on the PCI-core bridge. */
@ -551,8 +551,12 @@ static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
for (pos = 0; pos < 6; pos++) { for (pos = 0; pos < 6; pos++) {
res = &dev->resource[pos]; res = &dev->resource[pos];
if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) {
pci_assign_resource(dev, pos); err = pci_assign_resource(dev, pos);
if (err)
pr_err("PCI: Problem fixing up the addresses on %s\n",
pci_name(dev));
}
} }
} }
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);

View File

@ -165,6 +165,12 @@ static int bcma_register_cores(struct bcma_bus *bus)
} }
#endif #endif
if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
err = bcma_chipco_watchdog_register(&bus->drv_cc);
if (err)
bcma_err(bus, "Error registering watchdog driver\n");
}
return 0; return 0;
} }
@ -177,6 +183,8 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
if (core->dev_registered) if (core->dev_registered)
device_unregister(&core->dev); device_unregister(&core->dev);
} }
if (bus->hosttype == BCMA_HOSTTYPE_SOC)
platform_device_unregister(bus->drv_cc.watchdog);
} }
int __devinit bcma_bus_register(struct bcma_bus *bus) int __devinit bcma_bus_register(struct bcma_bus *bus)

View File

@ -1761,7 +1761,7 @@ static const struct ieee80211_ops adm8211_ops = {
.get_tsf = adm8211_get_tsft .get_tsf = adm8211_get_tsft
}; };
static int __devinit adm8211_probe(struct pci_dev *pdev, static int adm8211_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct ieee80211_hw *dev; struct ieee80211_hw *dev;
@ -1935,7 +1935,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
} }
static void __devexit adm8211_remove(struct pci_dev *pdev) static void adm8211_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *dev = pci_get_drvdata(pdev); struct ieee80211_hw *dev = pci_get_drvdata(pdev);
struct adm8211_priv *priv; struct adm8211_priv *priv;
@ -1985,7 +1985,7 @@ static struct pci_driver adm8211_driver = {
.name = "adm8211", .name = "adm8211",
.id_table = adm8211_pci_id_table, .id_table = adm8211_pci_id_table,
.probe = adm8211_probe, .probe = adm8211_probe,
.remove = __devexit_p(adm8211_remove), .remove = adm8211_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = adm8211_suspend, .suspend = adm8211_suspend,
.resume = adm8211_resume, .resume = adm8211_resume,

View File

@ -78,7 +78,7 @@ static struct pci_driver airo_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = card_ids, .id_table = card_ids,
.probe = airo_pci_probe, .probe = airo_pci_probe,
.remove = __devexit_p(airo_pci_remove), .remove = airo_pci_remove,
.suspend = airo_pci_suspend, .suspend = airo_pci_suspend,
.resume = airo_pci_resume, .resume = airo_pci_resume,
}; };
@ -5584,7 +5584,7 @@ static void timer_func( struct net_device *dev ) {
} }
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
static int __devinit airo_pci_probe(struct pci_dev *pdev, static int airo_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pent) const struct pci_device_id *pent)
{ {
struct net_device *dev; struct net_device *dev;
@ -5606,7 +5606,7 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
return 0; return 0;
} }
static void __devexit airo_pci_remove(struct pci_dev *pdev) static void airo_pci_remove(struct pci_dev *pdev)
{ {
struct net_device *dev = pci_get_drvdata(pdev); struct net_device *dev = pci_get_drvdata(pdev);

View File

@ -1,4 +1,7 @@
menuconfig ATH_COMMON config ATH_COMMON
tristate
menuconfig ATH_CARDS
tristate "Atheros Wireless Cards" tristate "Atheros Wireless Cards"
depends on CFG80211 && (!UML || BROKEN) depends on CFG80211 && (!UML || BROKEN)
---help--- ---help---
@ -14,7 +17,7 @@ menuconfig ATH_COMMON
http://wireless.kernel.org/en/users/Drivers/Atheros http://wireless.kernel.org/en/users/Drivers/Atheros
if ATH_COMMON if ATH_CARDS
config ATH_DEBUG config ATH_DEBUG
bool "Atheros wireless debugging" bool "Atheros wireless debugging"

View File

@ -1,6 +1,7 @@
config AR5523 config AR5523
tristate "Atheros AR5523 wireless driver support" tristate "Atheros AR5523 wireless driver support"
depends on MAC80211 && USB depends on MAC80211 && USB
select ATH_COMMON
select FW_LOADER select FW_LOADER
---help--- ---help---
This module add support for AR5523 based USB dongles such as D-Link This module add support for AR5523 based USB dongles such as D-Link

View File

@ -1,6 +1,7 @@
config ATH5K config ATH5K
tristate "Atheros 5xxx wireless cards support" tristate "Atheros 5xxx wireless cards support"
depends on (PCI || ATHEROS_AR231X) && MAC80211 depends on (PCI || ATHEROS_AR231X) && MAC80211
select ATH_COMMON
select MAC80211_LEDS select MAC80211_LEDS
select LEDS_CLASS select LEDS_CLASS
select NEW_LEDS select NEW_LEDS

View File

@ -2435,7 +2435,7 @@ static const struct ieee80211_iface_combination if_comb = {
.num_different_channels = 1, .num_different_channels = 1,
}; };
int __devinit int
ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
{ {
struct ieee80211_hw *hw = ah->hw; struct ieee80211_hw *hw = ah->hw;
@ -2861,7 +2861,7 @@ static void ath5k_reset_work(struct work_struct *work)
mutex_unlock(&ah->lock); mutex_unlock(&ah->lock);
} }
static int __devinit static int
ath5k_init(struct ieee80211_hw *hw) ath5k_init(struct ieee80211_hw *hw)
{ {

View File

@ -158,7 +158,7 @@ void ath5k_unregister_leds(struct ath5k_hw *ah)
ath5k_unregister_led(&ah->tx_led); ath5k_unregister_led(&ah->tx_led);
} }
int __devinit ath5k_init_leds(struct ath5k_hw *ah) int ath5k_init_leds(struct ath5k_hw *ah)
{ {
int ret = 0; int ret = 0;
struct ieee80211_hw *hw = ah->hw; struct ieee80211_hw *hw = ah->hw;

View File

@ -155,7 +155,7 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
* PCI Initialization * * PCI Initialization *
\********************/ \********************/
static int __devinit static int
ath5k_pci_probe(struct pci_dev *pdev, ath5k_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
@ -285,7 +285,7 @@ err:
return ret; return ret;
} }
static void __devexit static void
ath5k_pci_remove(struct pci_dev *pdev) ath5k_pci_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ieee80211_hw *hw = pci_get_drvdata(pdev);
@ -336,7 +336,7 @@ static struct pci_driver ath5k_pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = ath5k_pci_id_table, .id_table = ath5k_pci_id_table,
.probe = ath5k_pci_probe, .probe = ath5k_pci_probe,
.remove = __devexit_p(ath5k_pci_remove), .remove = ath5k_pci_remove,
.driver.pm = ATH5K_PM_OPS, .driver.pm = ATH5K_PM_OPS,
}; };

View File

@ -17,6 +17,7 @@ config ATH9K_BTCOEX_SUPPORT
config ATH9K config ATH9K
tristate "Atheros 802.11n wireless cards support" tristate "Atheros 802.11n wireless cards support"
depends on MAC80211 depends on MAC80211
select ATH_COMMON
select ATH9K_HW select ATH9K_HW
select MAC80211_LEDS select MAC80211_LEDS
select LEDS_CLASS select LEDS_CLASS

View File

@ -259,9 +259,10 @@ struct ath_atx_tid {
}; };
struct ath_node { struct ath_node {
struct ath_softc *sc;
struct ieee80211_sta *sta; /* station struct we're part of */ struct ieee80211_sta *sta; /* station struct we're part of */
struct ieee80211_vif *vif; /* interface with which we're associated */ struct ieee80211_vif *vif; /* interface with which we're associated */
struct ath_atx_tid tid[WME_NUM_TID]; struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
struct ath_atx_ac ac[IEEE80211_NUM_ACS]; struct ath_atx_ac ac[IEEE80211_NUM_ACS];
int ps_key; int ps_key;
@ -269,6 +270,10 @@ struct ath_node {
u8 mpdudensity; u8 mpdudensity;
bool sleeping; bool sleeping;
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
struct dentry *node_stat;
#endif
}; };
#define AGGR_CLEANUP BIT(1) #define AGGR_CLEANUP BIT(1)

View File

@ -23,7 +23,6 @@
/* Common header for Atheros 802.11n base driver cores */ /* Common header for Atheros 802.11n base driver cores */
#define WME_NUM_TID 16
#define WME_BA_BMP_SIZE 64 #define WME_BA_BMP_SIZE 64
#define WME_MAX_BA WME_BA_BMP_SIZE #define WME_MAX_BA WME_BA_BMP_SIZE
#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)

View File

@ -1509,6 +1509,215 @@ static const struct file_operations fops_btcoex = {
}; };
#endif #endif
static ssize_t read_file_node_stat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_node *an = file->private_data;
struct ath_softc *sc = an->sc;
struct ath_atx_tid *tid;
struct ath_atx_ac *ac;
struct ath_txq *txq;
u32 len = 0, size = 4096;
char *buf;
size_t retval;
int tidno, acno;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
if (!an->sta->ht_cap.ht_supported) {
len = snprintf(buf, size, "%s\n",
"HT not supported");
goto exit;
}
len = snprintf(buf, size, "Max-AMPDU: %d\n",
an->maxampdu);
len += snprintf(buf + len, size - len, "MPDU Density: %d\n\n",
an->mpdudensity);
len += snprintf(buf + len, size - len,
"%2s%7s\n", "AC", "SCHED");
for (acno = 0, ac = &an->ac[acno];
acno < IEEE80211_NUM_ACS; acno++, ac++) {
txq = ac->txq;
ath_txq_lock(sc, txq);
len += snprintf(buf + len, size - len,
"%2d%7d\n",
acno, ac->sched);
ath_txq_unlock(sc, txq);
}
len += snprintf(buf + len, size - len,
"\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
"TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
"BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
for (tidno = 0, tid = &an->tid[tidno];
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
txq = tid->ac->txq;
ath_txq_lock(sc, txq);
len += snprintf(buf + len, size - len,
"%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
tid->tidno, tid->seq_start, tid->seq_next,
tid->baw_size, tid->baw_head, tid->baw_tail,
tid->bar_index, tid->sched, tid->paused);
ath_txq_unlock(sc, txq);
}
exit:
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_node_stat = {
.read = read_file_node_stat,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct dentry *dir)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
an->node_stat = debugfs_create_file("node_stat", S_IRUGO,
dir, an, &fops_node_stat);
}
void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct dentry *dir)
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
debugfs_remove(an->node_stat);
}
/* Ethtool support for get-stats */
#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
"tx_pkts_nic",
"tx_bytes_nic",
"rx_pkts_nic",
"rx_bytes_nic",
AMKSTR(d_tx_pkts),
AMKSTR(d_tx_bytes),
AMKSTR(d_tx_mpdus_queued),
AMKSTR(d_tx_mpdus_completed),
AMKSTR(d_tx_mpdu_xretries),
AMKSTR(d_tx_aggregates),
AMKSTR(d_tx_ampdus_queued_hw),
AMKSTR(d_tx_ampdus_queued_sw),
AMKSTR(d_tx_ampdus_completed),
AMKSTR(d_tx_ampdu_retries),
AMKSTR(d_tx_ampdu_xretries),
AMKSTR(d_tx_fifo_underrun),
AMKSTR(d_tx_op_exceeded),
AMKSTR(d_tx_timer_expiry),
AMKSTR(d_tx_desc_cfg_err),
AMKSTR(d_tx_data_underrun),
AMKSTR(d_tx_delim_underrun),
"d_rx_decrypt_crc_err",
"d_rx_phy_err",
"d_rx_mic_err",
"d_rx_pre_delim_crc_err",
"d_rx_post_delim_crc_err",
"d_rx_decrypt_busy_err",
"d_rx_phyerr_radar",
"d_rx_phyerr_ofdm_timing",
"d_rx_phyerr_cck_timing",
};
#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
void ath9k_get_et_strings(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
memcpy(data, *ath9k_gstrings_stats,
sizeof(ath9k_gstrings_stats));
}
int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int sset)
{
if (sset == ETH_SS_STATS)
return ATH9K_SSTATS_LEN;
return 0;
}
#define AWDATA(elem) \
do { \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
} while (0)
#define AWDATA_RX(elem) \
do { \
data[i++] = sc->debug.stats.rxstats.elem; \
} while (0)
void ath9k_get_et_stats(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ethtool_stats *stats, u64 *data)
{
struct ath_softc *sc = hw->priv;
int i = 0;
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
AWDATA_RX(rx_pkts_all);
AWDATA_RX(rx_bytes_all);
AWDATA(tx_pkts_all);
AWDATA(tx_bytes_all);
AWDATA(queued);
AWDATA(completed);
AWDATA(xretries);
AWDATA(a_aggr);
AWDATA(a_queued_hw);
AWDATA(a_queued_sw);
AWDATA(a_completed);
AWDATA(a_retries);
AWDATA(a_xretries);
AWDATA(fifo_underrun);
AWDATA(xtxop);
AWDATA(timer_exp);
AWDATA(desc_cfg_err);
AWDATA(data_underrun);
AWDATA(delim_underrun);
AWDATA_RX(decrypt_crc_err);
AWDATA_RX(phy_err);
AWDATA_RX(mic_err);
AWDATA_RX(pre_delim_crc_err);
AWDATA_RX(post_delim_crc_err);
AWDATA_RX(decrypt_busy_err);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
WARN_ON(i != ATH9K_SSTATS_LEN);
}
int ath9k_init_debug(struct ath_hw *ah) int ath9k_init_debug(struct ath_hw *ah)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);

View File

@ -307,7 +307,22 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
struct ath_tx_status *ts, struct ath_txq *txq, struct ath_tx_status *ts, struct ath_txq *txq,
unsigned int flags); unsigned int flags);
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int sset);
void ath9k_get_et_stats(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ethtool_stats *stats, u64 *data);
void ath9k_get_et_strings(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 sset, u8 *data);
void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct dentry *dir);
void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct dentry *dir);
#else #else
#define RX_STAT_INC(c) /* NOP */ #define RX_STAT_INC(c) /* NOP */

View File

@ -331,6 +331,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
u8 density; u8 density;
an = (struct ath_node *)sta->drv_priv; an = (struct ath_node *)sta->drv_priv;
an->sc = sc;
an->sta = sta; an->sta = sta;
an->vif = vif; an->vif = vif;
@ -1882,133 +1883,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
return 0; return 0;
} }
#ifdef CONFIG_ATH9K_DEBUGFS
/* Ethtool support for get-stats */
#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
"tx_pkts_nic",
"tx_bytes_nic",
"rx_pkts_nic",
"rx_bytes_nic",
AMKSTR(d_tx_pkts),
AMKSTR(d_tx_bytes),
AMKSTR(d_tx_mpdus_queued),
AMKSTR(d_tx_mpdus_completed),
AMKSTR(d_tx_mpdu_xretries),
AMKSTR(d_tx_aggregates),
AMKSTR(d_tx_ampdus_queued_hw),
AMKSTR(d_tx_ampdus_queued_sw),
AMKSTR(d_tx_ampdus_completed),
AMKSTR(d_tx_ampdu_retries),
AMKSTR(d_tx_ampdu_xretries),
AMKSTR(d_tx_fifo_underrun),
AMKSTR(d_tx_op_exceeded),
AMKSTR(d_tx_timer_expiry),
AMKSTR(d_tx_desc_cfg_err),
AMKSTR(d_tx_data_underrun),
AMKSTR(d_tx_delim_underrun),
"d_rx_decrypt_crc_err",
"d_rx_phy_err",
"d_rx_mic_err",
"d_rx_pre_delim_crc_err",
"d_rx_post_delim_crc_err",
"d_rx_decrypt_busy_err",
"d_rx_phyerr_radar",
"d_rx_phyerr_ofdm_timing",
"d_rx_phyerr_cck_timing",
};
#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
static void ath9k_get_et_strings(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 sset, u8 *data)
{
if (sset == ETH_SS_STATS)
memcpy(data, *ath9k_gstrings_stats,
sizeof(ath9k_gstrings_stats));
}
static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int sset)
{
if (sset == ETH_SS_STATS)
return ATH9K_SSTATS_LEN;
return 0;
}
#define AWDATA(elem) \
do { \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
} while (0)
#define AWDATA_RX(elem) \
do { \
data[i++] = sc->debug.stats.rxstats.elem; \
} while (0)
static void ath9k_get_et_stats(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ethtool_stats *stats, u64 *data)
{
struct ath_softc *sc = hw->priv;
int i = 0;
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
AWDATA_RX(rx_pkts_all);
AWDATA_RX(rx_bytes_all);
AWDATA(tx_pkts_all);
AWDATA(tx_bytes_all);
AWDATA(queued);
AWDATA(completed);
AWDATA(xretries);
AWDATA(a_aggr);
AWDATA(a_queued_hw);
AWDATA(a_queued_sw);
AWDATA(a_completed);
AWDATA(a_retries);
AWDATA(a_xretries);
AWDATA(fifo_underrun);
AWDATA(xtxop);
AWDATA(timer_exp);
AWDATA(desc_cfg_err);
AWDATA(data_underrun);
AWDATA(delim_underrun);
AWDATA_RX(decrypt_crc_err);
AWDATA_RX(phy_err);
AWDATA_RX(mic_err);
AWDATA_RX(pre_delim_crc_err);
AWDATA_RX(post_delim_crc_err);
AWDATA_RX(decrypt_busy_err);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
WARN_ON(i != ATH9K_SSTATS_LEN);
}
/* End of ethtool get-stats functions */
#endif
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static void ath9k_wow_map_triggers(struct ath_softc *sc, static void ath9k_wow_map_triggers(struct ath_softc *sc,
@ -2402,7 +2276,12 @@ struct ieee80211_ops ath9k_ops = {
#ifdef CONFIG_ATH9K_DEBUGFS #ifdef CONFIG_ATH9K_DEBUGFS
.get_et_sset_count = ath9k_get_et_sset_count, .get_et_sset_count = ath9k_get_et_sset_count,
.get_et_stats = ath9k_get_et_stats, .get_et_stats = ath9k_get_et_stats,
.get_et_strings = ath9k_get_et_strings, .get_et_strings = ath9k_get_et_strings,
#endif
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
.sta_add_debugfs = ath9k_sta_add_debugfs,
.sta_remove_debugfs = ath9k_sta_remove_debugfs,
#endif #endif
}; };

View File

@ -257,8 +257,9 @@ static void ath_mci_set_concur_txprio(struct ath_softc *sc)
{ {
struct ath_btcoex *btcoex = &sc->btcoex; struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_mci_profile *mci = &btcoex->mci; struct ath_mci_profile *mci = &btcoex->mci;
u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */ u8 stomp_txprio[ATH_BTCOEX_STOMP_MAX];
memset(stomp_txprio, 0, sizeof(stomp_txprio));
if (mci->num_mgmt) { if (mci->num_mgmt) {
stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO; stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO;
if (!mci->num_pan && !mci->num_other_acl) if (!mci->num_pan && !mci->num_other_acl)

View File

@ -287,7 +287,7 @@ static void ath_pci_remove(struct pci_dev *pdev)
pci_release_region(pdev, 0); pci_release_region(pdev, 0);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int ath_pci_suspend(struct device *device) static int ath_pci_suspend(struct device *device)
{ {
@ -333,22 +333,15 @@ static int ath_pci_resume(struct device *device)
return 0; return 0;
} }
static const struct dev_pm_ops ath9k_pm_ops = { static SIMPLE_DEV_PM_OPS(ath9k_pm_ops, ath_pci_suspend, ath_pci_resume);
.suspend = ath_pci_suspend,
.resume = ath_pci_resume,
.freeze = ath_pci_suspend,
.thaw = ath_pci_resume,
.poweroff = ath_pci_suspend,
.restore = ath_pci_resume,
};
#define ATH9K_PM_OPS (&ath9k_pm_ops) #define ATH9K_PM_OPS (&ath9k_pm_ops)
#else /* !CONFIG_PM */ #else /* !CONFIG_PM_SLEEP */
#define ATH9K_PM_OPS NULL #define ATH9K_PM_OPS NULL
#endif /* !CONFIG_PM */ #endif /* !CONFIG_PM_SLEEP */
MODULE_DEVICE_TABLE(pci, ath_pci_id_table); MODULE_DEVICE_TABLE(pci, ath_pci_id_table);

View File

@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
} }
bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
bf->bf_next = NULL;
list_del(&bf->list); list_del(&bf->list);
spin_unlock_bh(&sc->tx.txbuflock); spin_unlock_bh(&sc->tx.txbuflock);
@ -1263,7 +1262,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
int tidno; int tidno;
for (tidno = 0, tid = &an->tid[tidno]; for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno++, tid++) { tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
if (!tid->sched) if (!tid->sched)
continue; continue;
@ -1297,7 +1296,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
int tidno; int tidno;
for (tidno = 0, tid = &an->tid[tidno]; for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno++, tid++) { tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
ac = tid->ac; ac = tid->ac;
txq = ac->txq; txq = ac->txq;
@ -2448,7 +2447,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
int tidno, acno; int tidno, acno;
for (tidno = 0, tid = &an->tid[tidno]; for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno < IEEE80211_NUM_TIDS;
tidno++, tid++) { tidno++, tid++) {
tid->an = an; tid->an = an;
tid->tidno = tidno; tid->tidno = tidno;
@ -2481,7 +2480,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
int tidno; int tidno;
for (tidno = 0, tid = &an->tid[tidno]; for (tidno = 0, tid = &an->tid[tidno];
tidno < WME_NUM_TID; tidno++, tid++) { tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
ac = tid->ac; ac = tid->ac;
txq = ac->txq; txq = ac->txq;

View File

@ -1,6 +1,7 @@
config CARL9170 config CARL9170
tristate "Linux Community AR9170 802.11n USB support" tristate "Linux Community AR9170 802.11n USB support"
depends on USB && MAC80211 && EXPERIMENTAL depends on USB && MAC80211 && EXPERIMENTAL
select ATH_COMMON
select FW_LOADER select FW_LOADER
select CRC32 select CRC32
help help

View File

@ -814,6 +814,8 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
if (phy) if (phy)
carl9170_rx_phy_status(ar, phy, &status); carl9170_rx_phy_status(ar, phy, &status);
else
status.flag |= RX_FLAG_NO_SIGNAL_VAL;
if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status)) if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status))
goto drop; goto drop;

View File

@ -1485,6 +1485,13 @@ void carl9170_op_tx(struct ieee80211_hw *hw,
} }
if (info->flags & IEEE80211_TX_CTL_AMPDU) { if (info->flags & IEEE80211_TX_CTL_AMPDU) {
/* to static code analyzers and reviewers:
* mac80211 guarantees that a valid "sta"
* reference is present, if a frame is to
* be part of an ampdu. Hence any extra
* sta == NULL checks are redundant in this
* special case.
*/
run = carl9170_tx_ampdu_queue(ar, sta, skb); run = carl9170_tx_ampdu_queue(ar, sta, skb);
if (run) if (run)
carl9170_tx_ampdu(ar); carl9170_tx_ampdu(ar);

View File

@ -45,11 +45,11 @@ static struct pci_driver atmel_driver = {
.name = "atmel", .name = "atmel",
.id_table = card_ids, .id_table = card_ids,
.probe = atmel_pci_probe, .probe = atmel_pci_probe,
.remove = __devexit_p(atmel_pci_remove), .remove = atmel_pci_remove,
}; };
static int __devinit atmel_pci_probe(struct pci_dev *pdev, static int atmel_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pent) const struct pci_device_id *pent)
{ {
struct net_device *dev; struct net_device *dev;
@ -69,7 +69,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
return 0; return 0;
} }
static void __devexit atmel_pci_remove(struct pci_dev *pdev) static void atmel_pci_remove(struct pci_dev *pdev)
{ {
stop_atmel_card(pci_get_drvdata(pdev)); stop_atmel_card(pci_get_drvdata(pdev));
} }

View File

@ -60,7 +60,7 @@ static int b43_pcmcia_resume(struct pcmcia_device *dev)
# define b43_pcmcia_resume NULL # define b43_pcmcia_resume NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) static int b43_pcmcia_probe(struct pcmcia_device *dev)
{ {
struct ssb_bus *ssb; struct ssb_bus *ssb;
int err = -ENOMEM; int err = -ENOMEM;
@ -110,7 +110,7 @@ out_error:
return err; return err;
} }
static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev) static void b43_pcmcia_remove(struct pcmcia_device *dev)
{ {
struct ssb_bus *ssb = dev->priv; struct ssb_bus *ssb = dev->priv;
@ -125,7 +125,7 @@ static struct pcmcia_driver b43_pcmcia_driver = {
.name = "b43-pcmcia", .name = "b43-pcmcia",
.id_table = b43_pcmcia_tbl, .id_table = b43_pcmcia_tbl,
.probe = b43_pcmcia_probe, .probe = b43_pcmcia_probe,
.remove = __devexit_p(b43_pcmcia_remove), .remove = b43_pcmcia_remove,
.suspend = b43_pcmcia_suspend, .suspend = b43_pcmcia_suspend,
.resume = b43_pcmcia_resume, .resume = b43_pcmcia_resume,
}; };

View File

@ -93,7 +93,7 @@ void b43_sdio_free_irq(struct b43_wldev *dev)
sdio->irq_handler = NULL; sdio->irq_handler = NULL;
} }
static int __devinit b43_sdio_probe(struct sdio_func *func, static int b43_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
struct b43_sdio *sdio; struct b43_sdio *sdio;
@ -171,7 +171,7 @@ out:
return error; return error;
} }
static void __devexit b43_sdio_remove(struct sdio_func *func) static void b43_sdio_remove(struct sdio_func *func)
{ {
struct b43_sdio *sdio = sdio_get_drvdata(func); struct b43_sdio *sdio = sdio_get_drvdata(func);
@ -193,7 +193,7 @@ static struct sdio_driver b43_sdio_driver = {
.name = "b43-sdio", .name = "b43-sdio",
.id_table = b43_sdio_ids, .id_table = b43_sdio_ids,
.probe = b43_sdio_probe, .probe = b43_sdio_probe,
.remove = __devexit_p(b43_sdio_remove), .remove = b43_sdio_remove,
}; };
int b43_sdio_init(void) int b43_sdio_init(void)

View File

@ -314,7 +314,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
while ((event = brcmf_fweh_dequeue_event(fweh))) { while ((event = brcmf_fweh_dequeue_event(fweh))) {
ifp = drvr->iflist[event->ifidx]; ifp = drvr->iflist[event->ifidx];
brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n", brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n",
brcmf_fweh_event_name(event->code), event->code, brcmf_fweh_event_name(event->code), event->code,
event->emsg.ifidx, event->emsg.bsscfgidx, event->emsg.ifidx, event->emsg.bsscfgidx,
event->emsg.addr); event->emsg.addr);
@ -337,7 +337,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
emsg.version, emsg.flags, emsg.status, emsg.reason); emsg.version, emsg.flags, emsg.status, emsg.reason);
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
min_t(u32, emsg.datalen, 64), min_t(u32, emsg.datalen, 64),
"appended:"); "event payload, len=%d\n", emsg.datalen);
/* special handling of interface event */ /* special handling of interface event */
if (event->code == BRCMF_E_IF) { if (event->code == BRCMF_E_IF) {

View File

@ -158,7 +158,7 @@ typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
*/ */
struct brcmf_fweh_info { struct brcmf_fweh_info {
struct work_struct event_work; struct work_struct event_work;
struct spinlock evt_q_lock; spinlock_t evt_q_lock;
struct list_head event_q; struct list_head event_q;
int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
const struct brcmf_event_msg *evtmsg, const struct brcmf_event_msg *evtmsg,

View File

@ -447,7 +447,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
struct vif_params *params) struct vif_params *params)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_cfg80211_vif *vif = ifp->vif;
s32 infra = 0; s32 infra = 0;
s32 ap = 0; s32 ap = 0;
s32 err = 0; s32 err = 0;
@ -461,15 +461,15 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
type); type);
return -EOPNOTSUPP; return -EOPNOTSUPP;
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
cfg->conf->mode = WL_MODE_IBSS; vif->mode = WL_MODE_IBSS;
infra = 0; infra = 0;
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
cfg->conf->mode = WL_MODE_BSS; vif->mode = WL_MODE_BSS;
infra = 1; infra = 1;
break; break;
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
cfg->conf->mode = WL_MODE_AP; vif->mode = WL_MODE_AP;
ap = 1; ap = 1;
break; break;
default: default:
@ -478,18 +478,16 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
} }
if (ap) { if (ap) {
set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
WL_INFO("IF Type = AP\n"); WL_INFO("IF Type = AP\n");
} else { } else {
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
BRCMF_C_SET_INFRA, infra);
if (err) { if (err) {
WL_ERR("WLC_SET_INFRA error (%d)\n", err); WL_ERR("WLC_SET_INFRA error (%d)\n", err);
err = -EAGAIN; err = -EAGAIN;
goto done; goto done;
} }
WL_INFO("IF Type = %s\n", WL_INFO("IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
(cfg->conf->mode == WL_MODE_IBSS) ?
"Adhoc" : "Infra"); "Adhoc" : "Infra");
} }
ndev->ieee80211_ptr->iftype = type; ndev->ieee80211_ptr->iftype = type;
@ -963,22 +961,21 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
} }
} }
static void brcmf_link_down(struct brcmf_cfg80211_info *cfg) static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
{ {
struct net_device *ndev = NULL;
s32 err = 0; s32 err = 0;
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
if (cfg->link_up) { if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
ndev = cfg_to_ndev(cfg);
WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
err = brcmf_fil_cmd_data_set(netdev_priv(ndev), err = brcmf_fil_cmd_data_set(vif->ifp,
BRCMF_C_DISASSOC, NULL, 0); BRCMF_C_DISASSOC, NULL, 0);
if (err) if (err)
WL_ERR("WLC_DISASSOC failed (%d)\n", err); WL_ERR("WLC_DISASSOC failed (%d)\n", err);
cfg->link_up = false; clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
} }
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
} }
@ -1130,7 +1127,6 @@ done:
static s32 static s32
brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
s32 err = 0; s32 err = 0;
@ -1138,7 +1134,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
if (!check_vif_up(ifp->vif)) if (!check_vif_up(ifp->vif))
return -EIO; return -EIO;
brcmf_link_down(cfg); brcmf_link_down(ifp->vif);
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
@ -1496,7 +1492,6 @@ static s32
brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
u16 reason_code) u16 reason_code)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_scb_val_le scbval; struct brcmf_scb_val_le scbval;
@ -1515,8 +1510,6 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
if (err) if (err)
WL_ERR("error (%d)\n", err); WL_ERR("error (%d)\n", err);
cfg->link_up = false;
WL_TRACE("Exit\n"); WL_TRACE("Exit\n");
return err; return err;
} }
@ -1716,7 +1709,6 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool pairwise, const u8 *mac_addr, u8 key_idx, bool pairwise, const u8 *mac_addr,
struct key_params *params) struct key_params *params)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_wsec_key key; struct brcmf_wsec_key key;
s32 val; s32 val;
@ -1758,7 +1750,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
break; break;
case WLAN_CIPHER_SUITE_TKIP: case WLAN_CIPHER_SUITE_TKIP:
if (cfg->conf->mode != WL_MODE_AP) { if (ifp->vif->mode != WL_MODE_AP) {
WL_CONN("Swapping key\n"); WL_CONN("Swapping key\n");
memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(keybuf, &key.data[24], sizeof(keybuf));
memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
@ -1908,7 +1900,6 @@ static s32
brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
u8 *mac, struct station_info *sinfo) u8 *mac, struct station_info *sinfo)
{ {
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_scb_val_le scb_val; struct brcmf_scb_val_le scb_val;
@ -1922,7 +1913,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
if (!check_vif_up(ifp->vif)) if (!check_vif_up(ifp->vif))
return -EIO; return -EIO;
if (cfg->conf->mode == WL_MODE_AP) { if (ifp->vif->mode == WL_MODE_AP) {
memcpy(&sta_info_le, mac, ETH_ALEN); memcpy(&sta_info_le, mac, ETH_ALEN);
err = brcmf_fil_iovar_data_get(ifp, "sta_info", err = brcmf_fil_iovar_data_get(ifp, "sta_info",
&sta_info_le, &sta_info_le,
@ -1939,7 +1930,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
} }
WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
sinfo->inactive_time, sinfo->connected_time); sinfo->inactive_time, sinfo->connected_time);
} else if (cfg->conf->mode == WL_MODE_BSS) { } else if (ifp->vif->mode == WL_MODE_BSS) {
if (memcmp(mac, bssid, ETH_ALEN)) { if (memcmp(mac, bssid, ETH_ALEN)) {
WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
mac, bssid); mac, bssid);
@ -2249,9 +2240,9 @@ CleanUp:
return err; return err;
} }
static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg) static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
{ {
return cfg->conf->mode == WL_MODE_IBSS; return vif->mode == WL_MODE_IBSS;
} }
/* /*
@ -2336,7 +2327,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
s32 err = 0; s32 err = 0;
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
if (brcmf_is_ibssmode(cfg)) if (brcmf_is_ibssmode(ifp->vif))
return err; return err;
ssid = &profile->ssid; ssid = &profile->ssid;
@ -2596,17 +2587,13 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
* While going to suspend if associated with AP disassociate * While going to suspend if associated with AP disassociate
* from AP to save power while system is in suspended state * from AP to save power while system is in suspended state
*/ */
if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) || brcmf_link_down(vif);
test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
WL_INFO("Disassociating from AP before suspend\n");
brcmf_link_down(cfg);
/* Make sure WPA_Supplicant receives all the event /* Make sure WPA_Supplicant receives all the event
* generated due to DISASSOC call to the fw to keep * generated due to DISASSOC call to the fw to keep
* the state fw and WPA_Supplicant state consistent * the state fw and WPA_Supplicant state consistent
*/ */
brcmf_delay(500); brcmf_delay(500);
}
} }
/* end any scanning */ /* end any scanning */
@ -3306,11 +3293,12 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
break; break;
next: next:
remaining_len -= ie->len; remaining_len -= (ie->len + TLV_HDR_LEN);
if (remaining_len <= 2) if (remaining_len <= TLV_HDR_LEN)
ie = NULL; ie = NULL;
else else
ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len); ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
TLV_HDR_LEN);
} }
return err; return err;
} }
@ -3409,11 +3397,11 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
} }
} }
if (mgmt_ie_buf != NULL) { if (mgmt_ie_buf && *mgmt_ie_len) {
if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) && if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
(memcmp(mgmt_ie_buf, curr_ie_buf, (memcmp(mgmt_ie_buf, curr_ie_buf,
parsed_ie_buf_len) == 0)) { parsed_ie_buf_len) == 0)) {
WL_TRACE("Previous mgmt IE is equals to current IE"); WL_TRACE("Previous mgmt IE equals to current IE\n");
goto exit; goto exit;
} }
@ -3451,6 +3439,16 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
for (i = 0; i < new_vndr_ies.count; i++) { for (i = 0; i < new_vndr_ies.count; i++) {
vndrie_info = &new_vndr_ies.ie_info[i]; vndrie_info = &new_vndr_ies.ie_info[i];
/* verify remained buf size before copy data */
if (remained_buf_len < (vndrie_info->vndrie.len +
VNDR_IE_VSIE_OFFSET)) {
WL_ERR("no space in mgmt_ie_buf: len left %d",
remained_buf_len);
break;
}
remained_buf_len -= (vndrie_info->ie_len +
VNDR_IE_VSIE_OFFSET);
WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
vndrie_info->vndrie.id, vndrie_info->vndrie.id,
vndrie_info->vndrie.len, vndrie_info->vndrie.len,
@ -3462,13 +3460,6 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
vndrie_info->ie_ptr, vndrie_info->ie_ptr,
vndrie_info->ie_len, vndrie_info->ie_len,
"add"); "add");
/* verify remained buf size before copy data */
remained_buf_len -= vndrie_info->ie_len;
if (remained_buf_len < 0) {
WL_ERR("no space in mgmt_ie_buf: len left %d",
remained_buf_len);
break;
}
/* save the parsed IE in wl struct */ /* save the parsed IE in wl struct */
memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr, memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
@ -3643,22 +3634,20 @@ exit:
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
{ {
struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
s32 err = -EPERM; s32 err = -EPERM;
WL_TRACE("Enter\n"); WL_TRACE("Enter\n");
if (cfg->conf->mode == WL_MODE_AP) { if (ifp->vif->mode == WL_MODE_AP) {
/* Due to most likely deauths outstanding we sleep */ /* Due to most likely deauths outstanding we sleep */
/* first to make sure they get processed by fw. */ /* first to make sure they get processed by fw. */
msleep(400); msleep(400);
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
BRCMF_C_SET_AP, 0);
if (err < 0) { if (err < 0) {
WL_ERR("setting AP mode failed %d\n", err); WL_ERR("setting AP mode failed %d\n", err);
goto exit; goto exit;
} }
err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0); err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
if (err < 0) { if (err < 0) {
WL_ERR("BRCMF_C_UP error %d\n", err); WL_ERR("BRCMF_C_UP error %d\n", err);
goto exit; goto exit;
@ -3849,23 +3838,20 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
} }
} }
static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
const struct brcmf_event_msg *e)
{ {
u32 event = e->event_code; u32 event = e->event_code;
u32 status = e->status; u32 status = e->status;
if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
WL_CONN("Processing set ssid\n"); WL_CONN("Processing set ssid\n");
cfg->link_up = true;
return true; return true;
} }
return false; return false;
} }
static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
const struct brcmf_event_msg *e)
{ {
u32 event = e->event_code; u32 event = e->event_code;
u16 flags = e->flags; u16 flags = e->flags;
@ -4115,11 +4101,11 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
s32 err = 0; s32 err = 0;
if (cfg->conf->mode == WL_MODE_AP) { if (ifp->vif->mode == WL_MODE_AP) {
err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
} else if (brcmf_is_linkup(cfg, e)) { } else if (brcmf_is_linkup(e)) {
WL_CONN("Linkup\n"); WL_CONN("Linkup\n");
if (brcmf_is_ibssmode(cfg)) { if (brcmf_is_ibssmode(ifp->vif)) {
memcpy(profile->bssid, e->addr, ETH_ALEN); memcpy(profile->bssid, e->addr, ETH_ALEN);
wl_inform_ibss(cfg, ndev, e->addr); wl_inform_ibss(cfg, ndev, e->addr);
cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
@ -4129,26 +4115,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
&ifp->vif->sme_state); &ifp->vif->sme_state);
} else } else
brcmf_bss_connect_done(cfg, ndev, e, true); brcmf_bss_connect_done(cfg, ndev, e, true);
} else if (brcmf_is_linkdown(cfg, e)) { } else if (brcmf_is_linkdown(e)) {
WL_CONN("Linkdown\n"); WL_CONN("Linkdown\n");
if (brcmf_is_ibssmode(cfg)) { if (!brcmf_is_ibssmode(ifp->vif)) {
clear_bit(BRCMF_VIF_STATUS_CONNECTING,
&ifp->vif->sme_state);
if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state))
brcmf_link_down(cfg);
} else {
brcmf_bss_connect_done(cfg, ndev, e, false); brcmf_bss_connect_done(cfg, ndev, e, false);
if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
&ifp->vif->sme_state)) { &ifp->vif->sme_state))
cfg80211_disconnected(ndev, 0, NULL, 0, cfg80211_disconnected(ndev, 0, NULL, 0,
GFP_KERNEL); GFP_KERNEL);
brcmf_link_down(cfg);
}
} }
brcmf_link_down(ifp->vif);
brcmf_init_prof(ndev_to_prof(ndev)); brcmf_init_prof(ndev_to_prof(ndev));
} else if (brcmf_is_nonetwork(cfg, e)) { } else if (brcmf_is_nonetwork(cfg, e)) {
if (brcmf_is_ibssmode(cfg)) if (brcmf_is_ibssmode(ifp->vif))
clear_bit(BRCMF_VIF_STATUS_CONNECTING, clear_bit(BRCMF_VIF_STATUS_CONNECTING,
&ifp->vif->sme_state); &ifp->vif->sme_state);
else else
@ -4197,7 +4176,6 @@ brcmf_notify_mic_status(struct brcmf_if *ifp,
static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
{ {
conf->mode = (u32)-1;
conf->frag_threshold = (u32)-1; conf->frag_threshold = (u32)-1;
conf->rts_threshold = (u32)-1; conf->rts_threshold = (u32)-1;
conf->retry_short = (u32)-1; conf->retry_short = (u32)-1;
@ -4282,7 +4260,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
mutex_init(&cfg->usr_sync); mutex_init(&cfg->usr_sync);
brcmf_init_escan(cfg); brcmf_init_escan(cfg);
brcmf_init_conf(cfg->conf); brcmf_init_conf(cfg->conf);
brcmf_link_down(cfg);
return err; return err;
} }
@ -4290,7 +4267,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
{ {
cfg->dongle_up = false; /* dongle down */ cfg->dongle_up = false; /* dongle down */
brcmf_link_down(cfg);
brcmf_abort_scanning(cfg); brcmf_abort_scanning(cfg);
brcmf_deinit_priv_mem(cfg); brcmf_deinit_priv_mem(cfg);
} }
@ -4537,11 +4513,8 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
* While going down, if associated with AP disassociate * While going down, if associated with AP disassociate
* from AP to save power * from AP to save power
*/ */
if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) || if (check_vif_up(ifp->vif)) {
test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) && brcmf_link_down(ifp->vif);
check_vif_up(ifp->vif)) {
WL_INFO("Disassociating from AP");
brcmf_link_down(cfg);
/* Make sure WPA_Supplicant receives all the event /* Make sure WPA_Supplicant receives all the event
generated due to DISASSOC call to the fw to keep generated due to DISASSOC call to the fw to keep

View File

@ -128,7 +128,6 @@ enum wl_mode {
/* dongle configuration */ /* dongle configuration */
struct brcmf_cfg80211_conf { struct brcmf_cfg80211_conf {
u32 mode; /* adhoc , infrastructure or ap */
u32 frag_threshold; u32 frag_threshold;
u32 rts_threshold; u32 rts_threshold;
u32 retry_short; u32 retry_short;
@ -359,7 +358,6 @@ struct brcmf_pno_scanresults_le {
* @active_scan: current scan mode. * @active_scan: current scan mode.
* @sched_escan: e-scan for scheduled scan support running. * @sched_escan: e-scan for scheduled scan support running.
* @ibss_starter: indicates this sta is ibss starter. * @ibss_starter: indicates this sta is ibss starter.
* @link_up: link/connection up flag.
* @pwr_save: indicate whether dongle to support power save mode. * @pwr_save: indicate whether dongle to support power save mode.
* @dongle_up: indicate whether dongle up or not. * @dongle_up: indicate whether dongle up or not.
* @roam_on: on/off switch for dongle self-roaming. * @roam_on: on/off switch for dongle self-roaming.
@ -391,7 +389,6 @@ struct brcmf_cfg80211_info {
bool active_scan; bool active_scan;
bool sched_escan; bool sched_escan;
bool ibss_starter; bool ibss_starter;
bool link_up;
bool pwr_save; bool pwr_save;
bool dongle_up; bool dongle_up;
bool roam_on; bool roam_on;

View File

@ -1,8 +1,120 @@
/*
* Copyright (c) 2012 Broadcom Corporation
* Copyright (c) 2012 Canonical Ltd.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <linux/debugfs.h>
#include <linux/if_ether.h>
#include <linux/if.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/ieee80211.h>
#include <linux/module.h>
#include <net/mac80211.h>
#include <defs.h>
#include <brcmu_wifi.h>
#include <brcmu_utils.h>
#include "types.h" #include "types.h"
#include "main.h"
#include "debug.h" #include "debug.h"
#include "brcms_trace_events.h" #include "brcms_trace_events.h"
static struct dentry *root_folder;
void brcms_debugfs_init(void)
{
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (IS_ERR(root_folder))
root_folder = NULL;
}
void brcms_debugfs_exit(void)
{
if (!root_folder)
return;
debugfs_remove_recursive(root_folder);
root_folder = NULL;
}
int brcms_debugfs_attach(struct brcms_pub *drvr)
{
if (!root_folder)
return -ENODEV;
drvr->dbgfs_dir = debugfs_create_dir(
dev_name(&drvr->wlc->hw->d11core->dev), root_folder);
return PTR_RET(drvr->dbgfs_dir);
}
void brcms_debugfs_detach(struct brcms_pub *drvr)
{
if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
debugfs_remove_recursive(drvr->dbgfs_dir);
}
struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
{
return drvr->dbgfs_dir;
}
static
ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data,
size_t count, loff_t *ppos)
{
char buf[128];
int res;
struct brcms_pub *drvr = f->private_data;
/* only allow read from start */
if (*ppos > 0)
return 0;
res = scnprintf(buf, sizeof(buf),
"board vendor: %x\n"
"board type: %x\n"
"board revision: %x\n"
"board flags: %x\n"
"board flags2: %x\n"
"firmware revision: %x\n",
drvr->wlc->hw->d11core->bus->boardinfo.vendor,
drvr->wlc->hw->d11core->bus->boardinfo.type,
drvr->wlc->hw->boardrev,
drvr->wlc->hw->boardflags,
drvr->wlc->hw->boardflags2,
drvr->wlc->ucode_rev
);
return simple_read_from_buffer(data, count, ppos, buf, res);
}
static const struct file_operations brcms_debugfs_hardware_ops = {
.owner = THIS_MODULE,
.open = simple_open,
.read = brcms_debugfs_hardware_read
};
void brcms_debugfs_create_files(struct brcms_pub *drvr)
{
struct dentry *dentry = drvr->dbgfs_dir;
if (!IS_ERR_OR_NULL(dentry))
debugfs_create_file("hardware", S_IRUGO, dentry,
drvr, &brcms_debugfs_hardware_ops);
}
#define __brcms_fn(fn) \ #define __brcms_fn(fn) \
void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
{ \ { \

View File

@ -1,3 +1,18 @@
/*
* Copyright (c) 2012 Broadcom Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BRCMS_DEBUG_H_ #ifndef _BRCMS_DEBUG_H_
#define _BRCMS_DEBUG_H_ #define _BRCMS_DEBUG_H_
@ -49,4 +64,12 @@ void __brcms_dbg(struct device *dev, u32 level, const char *func,
#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) #define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)
#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) #define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a)
struct brcms_pub;
void brcms_debugfs_init(void);
void brcms_debugfs_exit(void);
int brcms_debugfs_attach(struct brcms_pub *drvr);
void brcms_debugfs_detach(struct brcms_pub *drvr);
struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr);
void brcms_debugfs_create_files(struct brcms_pub *drvr);
#endif /* _BRCMS_DEBUG_H_ */ #endif /* _BRCMS_DEBUG_H_ */

View File

@ -349,10 +349,8 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
{ {
uint dmactrlflags; uint dmactrlflags;
if (di == NULL) { if (di == NULL)
brcms_dbg_dma(di->core, "NULL dma handle\n");
return 0; return 0;
}
dmactrlflags = di->dma.dmactrlflags; dmactrlflags = di->dma.dmactrlflags;
dmactrlflags &= ~mask; dmactrlflags &= ~mask;

View File

@ -285,8 +285,8 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,
kfree_skb(skb); kfree_skb(skb);
goto done; goto done;
} }
brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
tx_info->rate_driver_data[0] = control->sta; tx_info->rate_driver_data[0] = control->sta;
done: done:
spin_unlock_bh(&wl->lock); spin_unlock_bh(&wl->lock);
} }
@ -846,8 +846,10 @@ static void brcms_free(struct brcms_info *wl)
/* kill dpc */ /* kill dpc */
tasklet_kill(&wl->tasklet); tasklet_kill(&wl->tasklet);
if (wl->pub) if (wl->pub) {
brcms_debugfs_detach(wl->pub);
brcms_c_module_unregister(wl->pub, "linux", wl); brcms_c_module_unregister(wl->pub, "linux", wl);
}
/* free common resources */ /* free common resources */
if (wl->wlc) { if (wl->wlc) {
@ -896,27 +898,22 @@ static void brcms_remove(struct bcma_device *pdev)
static irqreturn_t brcms_isr(int irq, void *dev_id) static irqreturn_t brcms_isr(int irq, void *dev_id)
{ {
struct brcms_info *wl; struct brcms_info *wl;
bool ours, wantdpc; irqreturn_t ret = IRQ_NONE;
wl = (struct brcms_info *) dev_id; wl = (struct brcms_info *) dev_id;
spin_lock(&wl->isr_lock); spin_lock(&wl->isr_lock);
/* call common first level interrupt handler */ /* call common first level interrupt handler */
ours = brcms_c_isr(wl->wlc, &wantdpc); if (brcms_c_isr(wl->wlc)) {
if (ours) { /* schedule second level handler */
/* if more to do... */ tasklet_schedule(&wl->tasklet);
if (wantdpc) { ret = IRQ_HANDLED;
/* ...and call the second level interrupt handler */
/* schedule dpc */
tasklet_schedule(&wl->tasklet);
}
} }
spin_unlock(&wl->isr_lock); spin_unlock(&wl->isr_lock);
return IRQ_RETVAL(ours); return ret;
} }
/* /*
@ -1082,6 +1079,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) regulatory_hint(wl->wiphy, wl->pub->srom_ccode))
wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__);
brcms_debugfs_attach(wl->pub);
brcms_debugfs_create_files(wl->pub);
n_adapters_found++; n_adapters_found++;
return wl; return wl;
@ -1100,7 +1099,7 @@ fail:
* *
* Perimeter lock is initialized in the course of this function. * Perimeter lock is initialized in the course of this function.
*/ */
static int __devinit brcms_bcma_probe(struct bcma_device *pdev) static int brcms_bcma_probe(struct bcma_device *pdev)
{ {
struct brcms_info *wl; struct brcms_info *wl;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
@ -1166,7 +1165,7 @@ static struct bcma_driver brcms_bcma_driver = {
.probe = brcms_bcma_probe, .probe = brcms_bcma_probe,
.suspend = brcms_suspend, .suspend = brcms_suspend,
.resume = brcms_resume, .resume = brcms_resume,
.remove = __devexit_p(brcms_remove), .remove = brcms_remove,
.id_table = brcms_coreid_table, .id_table = brcms_coreid_table,
}; };
@ -1190,6 +1189,7 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
static int __init brcms_module_init(void) static int __init brcms_module_init(void)
{ {
brcms_debugfs_init();
if (!schedule_work(&brcms_driver_work)) if (!schedule_work(&brcms_driver_work))
return -EBUSY; return -EBUSY;
@ -1207,6 +1207,7 @@ static void __exit brcms_module_exit(void)
{ {
cancel_work_sync(&brcms_driver_work); cancel_work_sync(&brcms_driver_work);
bcma_driver_unregister(&brcms_bcma_driver); bcma_driver_unregister(&brcms_bcma_driver);
brcms_debugfs_exit();
} }
module_init(brcms_module_init); module_init(brcms_module_init);

View File

@ -1044,11 +1044,17 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
while (!(*fatal) while (!(*fatal)
&& (s1 & TXS_V)) { && (s1 & TXS_V)) {
/* !give others some time to run! */
if (n >= max_tx_num) {
morepending = true;
break;
}
if (s1 == 0xffffffff) { if (s1 == 0xffffffff) {
brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__); __func__);
return morepending; *fatal = true;
return false;
} }
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
@ -1060,17 +1066,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
/* !give others some time to run! */
if (++n >= max_tx_num)
break;
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
n++;
} }
if (*fatal) if (*fatal)
return 0; return false;
if (n >= max_tx_num)
morepending = true;
return morepending; return morepending;
} }
@ -2546,10 +2547,6 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
if (macintstatus == 0) if (macintstatus == 0)
return 0; return 0;
/* interrupts are already turned off for CFE build
* Caution: For CFE Turning off the interrupts again has some undesired
* consequences
*/
/* turn off the interrupts */ /* turn off the interrupts */
bcma_write32(core, D11REGOFFS(macintmask), 0); bcma_write32(core, D11REGOFFS(macintmask), 0);
(void)bcma_read32(core, D11REGOFFS(macintmask)); (void)bcma_read32(core, D11REGOFFS(macintmask));
@ -2592,33 +2589,31 @@ bool brcms_c_intrsupd(struct brcms_c_info *wlc)
/* /*
* First-level interrupt processing. * First-level interrupt processing.
* Return true if this was our interrupt, false otherwise. * Return true if this was our interrupt
* *wantdpc will be set to true if further brcms_c_dpc() processing is required, * and if further brcms_c_dpc() processing is required,
* false otherwise. * false otherwise.
*/ */
bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) bool brcms_c_isr(struct brcms_c_info *wlc)
{ {
struct brcms_hardware *wlc_hw = wlc->hw; struct brcms_hardware *wlc_hw = wlc->hw;
u32 macintstatus; u32 macintstatus;
*wantdpc = false;
if (!wlc_hw->up || !wlc->macintmask) if (!wlc_hw->up || !wlc->macintmask)
return false; return false;
/* read and clear macintstatus and intstatus registers */ /* read and clear macintstatus and intstatus registers */
macintstatus = wlc_intstatus(wlc, true); macintstatus = wlc_intstatus(wlc, true);
if (macintstatus == 0xffffffff) if (macintstatus == 0xffffffff) {
brcms_err(wlc_hw->d11core, brcms_err(wlc_hw->d11core,
"DEVICEREMOVED detected in the ISR code path\n"); "DEVICEREMOVED detected in the ISR code path\n");
return false;
}
/* it is not for us */ /* it is not for us */
if (macintstatus == 0) if (macintstatus == 0)
return false; return false;
*wantdpc = true;
/* save interrupt status bits */ /* save interrupt status bits */
wlc->macintstatus = macintstatus; wlc->macintstatus = macintstatus;
@ -6928,17 +6923,20 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
return ret; return ret;
} }
void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
struct ieee80211_hw *hw) struct ieee80211_hw *hw)
{ {
uint fifo; uint fifo;
struct scb *scb = &wlc->pri_scb; struct scb *scb = &wlc->pri_scb;
fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
return; if (!brcms_c_tx(wlc, sdu))
if (brcms_c_tx(wlc, sdu)) return true;
dev_kfree_skb_any(sdu);
/* packet discarded */
dev_kfree_skb_any(sdu);
return false;
} }
int int
@ -7634,16 +7632,19 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
uint n = 0; uint n = 0;
uint bound_limit = bound ? RXBND : -1; uint bound_limit = bound ? RXBND : -1;
bool morepending;
skb_queue_head_init(&recv_frames); skb_queue_head_init(&recv_frames);
/* gather received frames */ /* gather received frames */
while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { do {
/* !give others some time to run! */ /* !give others some time to run! */
if (++n >= bound_limit) if (n >= bound_limit)
break; break;
}
morepending = dma_rx(wlc_hw->di[fifo], &recv_frames);
n++;
} while (morepending);
/* post more rbufs */ /* post more rbufs */
dma_rxfill(wlc_hw->di[fifo]); dma_rxfill(wlc_hw->di[fifo]);
@ -7673,7 +7674,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
brcms_c_recv(wlc_hw->wlc, p); brcms_c_recv(wlc_hw->wlc, p);
} }
return n >= bound_limit; return morepending;
} }
/* second-level interrupt processing /* second-level interrupt processing

View File

@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
gain0_15 = ((biq1 & 0xf) << 12) | gain0_15 = ((biq1 & 0xf) << 12) |
((tia & 0xf) << 8) | ((tia & 0xf) << 8) |
((lna2 & 0x3) << 6) | ((lna2 & 0x3) << 6) |
((lna2 & ((lna2 & 0x3) << 4) |
0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); ((lna1 & 0x3) << 2) |
((lna1 & 0x3) << 0);
mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
} }
mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
} }
@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
} }
static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
u16 tia_gain, u16 lna2_gain)
{
u32 i_thresh_l, q_thresh_l;
u32 i_thresh_h, q_thresh_h;
struct lcnphy_iq_est iq_est_h, iq_est_l;
wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
lna2_gain, 0);
wlc_lcnphy_rx_gain_override_enable(pi, true);
wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
usleep_range(500, 500);
write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
return false;
wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
usleep_range(500, 500);
write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
return false;
i_thresh_l = (iq_est_l.i_pwr << 1);
i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
q_thresh_l = (iq_est_l.q_pwr << 1);
q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
if ((iq_est_h.i_pwr > i_thresh_l) &&
(iq_est_h.i_pwr < i_thresh_h) &&
(iq_est_h.q_pwr > q_thresh_l) &&
(iq_est_h.q_pwr < q_thresh_h))
return true;
return false;
}
static bool static bool
wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
const struct lcnphy_rx_iqcomp *iqcomp, const struct lcnphy_rx_iqcomp *iqcomp,
@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
rfoverride3_old, rfoverride3val_old, rfoverride4_old, rfoverride3_old, rfoverride3val_old, rfoverride4_old,
rfoverride4val_old, afectrlovr_old, afectrlovrval_old; rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
int tia_gain; int tia_gain, lna2_gain, biq1_gain;
u32 received_power, rx_pwr_threshold; bool set_gain;
u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
u16 values_to_save[11]; u16 values_to_save[11];
s16 *ptr; s16 *ptr;
@ -1368,127 +1408,135 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
goto cal_done; goto cal_done;
} }
if (module == 1) { WARN_ON(module != 1);
tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); for (i = 0; i < 11; i++)
wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); values_to_save[i] =
read_radio_reg(pi, rxiq_cal_rf_reg[i]);
Core1TxControl_old = read_phy_reg(pi, 0x631);
for (i = 0; i < 11; i++) or_phy_reg(pi, 0x631, 0x0015);
values_to_save[i] =
read_radio_reg(pi, rxiq_cal_rf_reg[i]);
Core1TxControl_old = read_phy_reg(pi, 0x631);
or_phy_reg(pi, 0x631, 0x0015); RFOverride0_old = read_phy_reg(pi, 0x44c);
RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
rfoverride2_old = read_phy_reg(pi, 0x4b0);
rfoverride2val_old = read_phy_reg(pi, 0x4b1);
rfoverride3_old = read_phy_reg(pi, 0x4f9);
rfoverride3val_old = read_phy_reg(pi, 0x4fa);
rfoverride4_old = read_phy_reg(pi, 0x938);
rfoverride4val_old = read_phy_reg(pi, 0x939);
afectrlovr_old = read_phy_reg(pi, 0x43b);
afectrlovrval_old = read_phy_reg(pi, 0x43c);
old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
RFOverride0_old = read_phy_reg(pi, 0x44c); tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
RFOverrideVal0_old = read_phy_reg(pi, 0x44d); if (tx_gain_override_old) {
rfoverride2_old = read_phy_reg(pi, 0x4b0); wlc_lcnphy_get_tx_gain(pi, &old_gains);
rfoverride2val_old = read_phy_reg(pi, 0x4b1); tx_gain_index_old = pi_lcn->lcnphy_current_index;
rfoverride3_old = read_phy_reg(pi, 0x4f9);
rfoverride3val_old = read_phy_reg(pi, 0x4fa);
rfoverride4_old = read_phy_reg(pi, 0x938);
rfoverride4val_old = read_phy_reg(pi, 0x939);
afectrlovr_old = read_phy_reg(pi, 0x43b);
afectrlovrval_old = read_phy_reg(pi, 0x43c);
old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
if (tx_gain_override_old) {
wlc_lcnphy_get_tx_gain(pi, &old_gains);
tx_gain_index_old = pi_lcn->lcnphy_current_index;
}
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
write_radio_reg(pi, RADIO_2064_REG116, 0x06);
write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
write_radio_reg(pi, RADIO_2064_REG098, 0x03);
write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
write_radio_reg(pi, RADIO_2064_REG114, 0x01);
write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
write_phy_reg(pi, 0x6da, 0xffff);
or_phy_reg(pi, 0x6db, 0x3);
wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
wlc_lcnphy_rx_gain_override_enable(pi, true);
tia_gain = 8;
rx_pwr_threshold = 950;
while (tia_gain > 0) {
tia_gain -= 1;
wlc_lcnphy_set_rx_gain_by_distribution(pi,
0, 0, 2, 2,
(u16)
tia_gain, 1, 0);
udelay(500);
received_power =
wlc_lcnphy_measure_digital_power(pi, 2000);
if (received_power < rx_pwr_threshold)
break;
}
result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff);
wlc_lcnphy_stop_tx_tone(pi);
write_phy_reg(pi, 0x631, Core1TxControl_old);
write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
write_phy_reg(pi, 0x4b0, rfoverride2_old);
write_phy_reg(pi, 0x4b1, rfoverride2val_old);
write_phy_reg(pi, 0x4f9, rfoverride3_old);
write_phy_reg(pi, 0x4fa, rfoverride3val_old);
write_phy_reg(pi, 0x938, rfoverride4_old);
write_phy_reg(pi, 0x939, rfoverride4val_old);
write_phy_reg(pi, 0x43b, afectrlovr_old);
write_phy_reg(pi, 0x43c, afectrlovrval_old);
write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
wlc_lcnphy_clear_trsw_override(pi);
mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
for (i = 0; i < 11; i++)
write_radio_reg(pi, rxiq_cal_rf_reg[i],
values_to_save[i]);
if (tx_gain_override_old)
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
else
wlc_lcnphy_disable_tx_gain_override(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
wlc_lcnphy_rx_gain_override_enable(pi, false);
} }
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
write_radio_reg(pi, RADIO_2064_REG116, 0x06);
write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
write_radio_reg(pi, RADIO_2064_REG098, 0x03);
write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
write_radio_reg(pi, RADIO_2064_REG114, 0x01);
write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
write_phy_reg(pi, 0x6da, 0xffff);
or_phy_reg(pi, 0x6db, 0x3);
wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
set_gain = false;
lna2_gain = 3;
while ((lna2_gain >= 0) && !set_gain) {
tia_gain = 4;
while ((tia_gain >= 0) && !set_gain) {
biq1_gain = 6;
while ((biq1_gain >= 0) && !set_gain) {
set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
(u16)
biq1_gain,
(u16)
tia_gain,
(u16)
lna2_gain);
biq1_gain -= 1;
}
tia_gain -= 1;
}
lna2_gain -= 1;
}
if (set_gain)
result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
else
result = false;
wlc_lcnphy_stop_tx_tone(pi);
write_phy_reg(pi, 0x631, Core1TxControl_old);
write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
write_phy_reg(pi, 0x4b0, rfoverride2_old);
write_phy_reg(pi, 0x4b1, rfoverride2val_old);
write_phy_reg(pi, 0x4f9, rfoverride3_old);
write_phy_reg(pi, 0x4fa, rfoverride3val_old);
write_phy_reg(pi, 0x938, rfoverride4_old);
write_phy_reg(pi, 0x939, rfoverride4val_old);
write_phy_reg(pi, 0x43b, afectrlovr_old);
write_phy_reg(pi, 0x43c, afectrlovrval_old);
write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
wlc_lcnphy_clear_trsw_override(pi);
mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
for (i = 0; i < 11; i++)
write_radio_reg(pi, rxiq_cal_rf_reg[i],
values_to_save[i]);
if (tx_gain_override_old)
wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
else
wlc_lcnphy_disable_tx_gain_override(pi);
wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
wlc_lcnphy_rx_gain_override_enable(pi, false);
cal_done: cal_done:
kfree(ptr); kfree(ptr);
return result; return result;
@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
write_radio_reg(pi, RADIO_2064_REG038, 3); write_radio_reg(pi, RADIO_2064_REG038, 3);
write_radio_reg(pi, RADIO_2064_REG091, 7); write_radio_reg(pi, RADIO_2064_REG091, 7);
} }
if (!(pi->sh->boardflags & BFL_FEM)) {
u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
write_radio_reg(pi, RADIO_2064_REG091, 0x3);
write_radio_reg(pi, RADIO_2064_REG038, 0x3);
write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
}
} }
static int static int
@ -1860,41 +1919,6 @@ wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
return (filt_index != -1) ? 0 : -1; return (filt_index != -1) ? 0 : -1;
} }
void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
{
u8 channel = CHSPEC_CHANNEL(chanspec);
wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
or_phy_reg(pi, 0x44a, 0x44);
write_phy_reg(pi, 0x44a, 0x80);
wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
udelay(1000);
wlc_lcnphy_toggle_afe_pwdn(pi);
write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
} else {
mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
}
wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
}
static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi) static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
{ {
u16 pa_gain; u16 pa_gain;
@ -1936,6 +1960,21 @@ static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
wlc_lcnphy_enable_tx_gain_override(pi); wlc_lcnphy_enable_tx_gain_override(pi);
} }
static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
{
u16 m0m1;
struct phytbl_info tab;
tab.tbl_ptr = &m0m1;
tab.tbl_len = 1;
tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
tab.tbl_offset = 87;
tab.tbl_width = 16;
wlc_lcnphy_read_table(pi, &tab);
return (u8) ((m0m1 & 0xff00) >> 8);
}
static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0) static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
{ {
u16 m0m1 = (u16) m0 << 8; u16 m0m1 = (u16) m0 << 8;
@ -1995,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
} else { } else {
mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
} }
} else { } else {
mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@ -2081,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
(auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
} }
static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
{ {
struct phytbl_info tab; struct phytbl_info tab;
u32 rfseq, ind; u32 rfseq, ind;
u8 tssi_sel;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32; tab.tbl_width = 32;
@ -2108,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); if (pi->sh->boardflags & BFL_FEM) {
tssi_sel = 0x1;
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
} else {
tssi_sel = 0xe;
wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
}
mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@ -2144,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
} else { } else {
mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
} }
@ -2193,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
wlc_lcnphy_pwrctrl_rssiparams(pi); wlc_lcnphy_pwrctrl_rssiparams(pi);
} }
@ -2811,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
read_radio_reg(pi, RADIO_2064_REG007) & 1; read_radio_reg(pi, RADIO_2064_REG007) & 1;
u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
idleTssi = read_phy_reg(pi, 0x4ab); idleTssi = read_phy_reg(pi, 0x4ab);
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
MCTL_EN_MAC)); MCTL_EN_MAC));
@ -2828,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
wlc_lcnphy_tssi_setup(pi); wlc_lcnphy_tssi_setup(pi);
mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
wlc_lcnphy_set_bbmult(pi, 0x0);
wlc_phy_do_dummy_tx(pi, true, OFF); wlc_phy_do_dummy_tx(pi, true, OFF);
idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
>> 0); >> 0);
@ -2849,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
wlc_lcnphy_set_tx_gain(pi, &old_gains); wlc_lcnphy_set_tx_gain(pi, &old_gains);
wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@ -3062,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlc_lcnphy_write_table(pi, &tab); wlc_lcnphy_write_table(pi, &tab);
tab.tbl_offset++; tab.tbl_offset++;
} }
mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
@ -3075,21 +3151,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
wlapi_enable_mac(pi->sh->physhim); wlapi_enable_mac(pi->sh->physhim);
} }
static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
{
u16 m0m1;
struct phytbl_info tab;
tab.tbl_ptr = &m0m1;
tab.tbl_len = 1;
tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
tab.tbl_offset = 87;
tab.tbl_width = 16;
wlc_lcnphy_read_table(pi, &tab);
return (u8) ((m0m1 & 0xff00) >> 8);
}
static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain) static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
{ {
mod_phy_reg(pi, 0x4fb, mod_phy_reg(pi, 0x4fb,
@ -3878,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
target_gains.pad_gain = 21; target_gains.pad_gain = 21;
target_gains.dac_gain = 0; target_gains.dac_gain = 0;
wlc_lcnphy_set_tx_gain(pi, &target_gains); wlc_lcnphy_set_tx_gain(pi, &target_gains);
wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
@ -3889,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
lcnphy_recal ? LCNPHY_CAL_RECAL : lcnphy_recal ? LCNPHY_CAL_RECAL :
LCNPHY_CAL_FULL), false); LCNPHY_CAL_FULL), false);
} else { } else {
wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
wlc_lcnphy_tx_iqlo_soft_cal_full(pi); wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
} }
@ -4313,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
if (CHSPEC_IS5G(pi->radio_chanspec)) if (CHSPEC_IS5G(pi->radio_chanspec))
pa_gain = 0x70; pa_gain = 0x70;
else else
pa_gain = 0x70; pa_gain = 0x60;
if (pi->sh->boardflags & BFL_FEM) if (pi->sh->boardflags & BFL_FEM)
pa_gain = 0x10; pa_gain = 0x10;
tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
tab.tbl_width = 32; tab.tbl_width = 32;
tab.tbl_len = 1; tab.tbl_len = 1;
tab.tbl_ptr = &val; tab.tbl_ptr = &val;
for (j = 0; j < 128; j++) { for (j = 0; j < 128; j++) {
gm_gain = gain_table[j].gm; if (pi->sh->boardflags & BFL_FEM)
gm_gain = gain_table[j].gm;
else
gm_gain = 15;
val = (((u32) pa_gain << 24) | val = (((u32) pa_gain << 24) |
(gain_table[j].pad << 16) | (gain_table[j].pad << 16) |
(gain_table[j].pga << 8) | gm_gain); (gain_table[j].pga << 8) | gm_gain);
@ -4534,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
write_phy_reg(pi, 0x4ea, 0x4688); write_phy_reg(pi, 0x4ea, 0x4688);
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); if (pi->sh->boardflags & BFL_FEM)
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
else
mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
@ -4545,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
wlc_lcnphy_rcal(pi); wlc_lcnphy_rcal(pi);
wlc_lcnphy_rc_cal(pi); wlc_lcnphy_rc_cal(pi);
if (!(pi->sh->boardflags & BFL_FEM)) {
write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
write_radio_reg(pi, RADIO_2064_REG033, 0x19);
write_radio_reg(pi, RADIO_2064_REG039, 0xe);
}
} }
static void wlc_lcnphy_radio_init(struct brcms_phy *pi) static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@ -4574,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
wlc_lcnphy_write_table(pi, &tab); wlc_lcnphy_write_table(pi, &tab);
} }
tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; if (!(pi->sh->boardflags & BFL_FEM)) {
tab.tbl_width = 16; tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
tab.tbl_ptr = &val; tab.tbl_width = 16;
tab.tbl_len = 1; tab.tbl_ptr = &val;
tab.tbl_len = 1;
val = 114; val = 150;
tab.tbl_offset = 0; tab.tbl_offset = 0;
wlc_lcnphy_write_table(pi, &tab); wlc_lcnphy_write_table(pi, &tab);
val = 130; val = 220;
tab.tbl_offset = 1; tab.tbl_offset = 1;
wlc_lcnphy_write_table(pi, &tab); wlc_lcnphy_write_table(pi, &tab);
}
val = 6;
tab.tbl_offset = 8;
wlc_lcnphy_write_table(pi, &tab);
if (CHSPEC_IS2G(pi->radio_chanspec)) { if (CHSPEC_IS2G(pi->radio_chanspec)) {
if (pi->sh->boardflags & BFL_FEM) if (pi->sh->boardflags & BFL_FEM)
@ -4946,6 +5020,44 @@ void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
} }
} }
void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
{
u8 channel = CHSPEC_CHANNEL(chanspec);
wlc_phy_chanspec_radio_set((struct brcms_phy_pub *)pi, chanspec);
wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
or_phy_reg(pi, 0x44a, 0x44);
write_phy_reg(pi, 0x44a, 0x80);
wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
udelay(1000);
wlc_lcnphy_toggle_afe_pwdn(pi);
write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
} else {
mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
}
if (pi->sh->boardflags & BFL_FEM)
wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
else
wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
wlc_lcnphy_tssi_setup(pi);
}
void wlc_phy_detach_lcnphy(struct brcms_phy *pi) void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
{ {
kfree(pi->u.pi_lcnphy); kfree(pi->u.pi_lcnphy);
@ -4982,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
return false; return false;
if ((pi->sh->boardflags & BFL_FEM) && if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
(LCNREV_IS(pi->pubpi.phy_rev, 1))) {
if (pi_lcn->lcnphy_tempsense_option == 3) { if (pi_lcn->lcnphy_tempsense_option == 3) {
pi->hwpwrctrl = true; pi->hwpwrctrl = true;
pi->hwpwrctrl_capable = true; pi->hwpwrctrl_capable = true;

View File

@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
}; };
static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
0x000a,
0x0009, 0x0009,
0x0006,
0x0005,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a, 0x000a,
0x0009,
0x0006,
0x0005, 0x0005,
0x0006,
0x0009,
0x000a,
0x0005,
0x0006,
}; };
static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {

View File

@ -176,6 +176,7 @@ struct brcms_pub {
bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
struct wl_cnt *_cnt; /* low-level counters in driver */ struct wl_cnt *_cnt; /* low-level counters in driver */
struct dentry *dbgfs_dir;
}; };
enum wlc_par_id { enum wlc_par_id {
@ -282,9 +283,9 @@ extern void brcms_c_intrson(struct brcms_c_info *wlc);
extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc); extern bool brcms_c_isr(struct brcms_c_info *wlc);
extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
struct sk_buff *sdu, struct sk_buff *sdu,
struct ieee80211_hw *hw); struct ieee80211_hw *hw);
extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);

View File

@ -6410,7 +6410,7 @@ out:
goto out; goto out;
} }
static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) static void ipw2100_pci_remove_one(struct pci_dev *pci_dev)
{ {
struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
struct net_device *dev = priv->net_dev; struct net_device *dev = priv->net_dev;
@ -6606,7 +6606,7 @@ static struct pci_driver ipw2100_pci_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = ipw2100_pci_id_table, .id_table = ipw2100_pci_id_table,
.probe = ipw2100_pci_init_one, .probe = ipw2100_pci_init_one,
.remove = __devexit_p(ipw2100_pci_remove_one), .remove = ipw2100_pci_remove_one,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = ipw2100_suspend, .suspend = ipw2100_suspend,
.resume = ipw2100_resume, .resume = ipw2100_resume,

View File

@ -6812,7 +6812,6 @@ static int ipw_wx_get_auth(struct net_device *dev,
struct libipw_device *ieee = priv->ieee; struct libipw_device *ieee = priv->ieee;
struct lib80211_crypt_data *crypt; struct lib80211_crypt_data *crypt;
struct iw_param *param = &wrqu->param; struct iw_param *param = &wrqu->param;
int ret = 0;
switch (param->flags & IW_AUTH_INDEX) { switch (param->flags & IW_AUTH_INDEX) {
case IW_AUTH_WPA_VERSION: case IW_AUTH_WPA_VERSION:
@ -6822,8 +6821,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
/* /*
* wpa_supplicant will control these internally * wpa_supplicant will control these internally
*/ */
ret = -EOPNOTSUPP; return -EOPNOTSUPP;
break;
case IW_AUTH_TKIP_COUNTERMEASURES: case IW_AUTH_TKIP_COUNTERMEASURES:
crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
@ -10774,7 +10772,7 @@ static void ipw_bg_link_down(struct work_struct *work)
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
} }
static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) static int ipw_setup_deferred_work(struct ipw_priv *priv)
{ {
int ret = 0; int ret = 0;
@ -11728,7 +11726,7 @@ static const struct net_device_ops ipw_netdev_ops = {
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
}; };
static int __devinit ipw_pci_probe(struct pci_dev *pdev, static int ipw_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent) const struct pci_device_id *ent)
{ {
int err = 0; int err = 0;
@ -11901,7 +11899,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit ipw_pci_remove(struct pci_dev *pdev) static void ipw_pci_remove(struct pci_dev *pdev)
{ {
struct ipw_priv *priv = pci_get_drvdata(pdev); struct ipw_priv *priv = pci_get_drvdata(pdev);
struct list_head *p, *q; struct list_head *p, *q;
@ -12063,7 +12061,7 @@ static struct pci_driver ipw_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = card_ids, .id_table = card_ids,
.probe = ipw_pci_probe, .probe = ipw_pci_probe,
.remove = __devexit_p(ipw_pci_remove), .remove = ipw_pci_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = ipw_pci_suspend, .suspend = ipw_pci_suspend,
.resume = ipw_pci_resume, .resume = ipw_pci_resume,

View File

@ -3794,7 +3794,7 @@ out:
return err; return err;
} }
static void __devexit static void
il3945_pci_remove(struct pci_dev *pdev) il3945_pci_remove(struct pci_dev *pdev)
{ {
struct il_priv *il = pci_get_drvdata(pdev); struct il_priv *il = pci_get_drvdata(pdev);
@ -3884,7 +3884,7 @@ static struct pci_driver il3945_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = il3945_hw_card_ids, .id_table = il3945_hw_card_ids,
.probe = il3945_pci_probe, .probe = il3945_pci_probe,
.remove = __devexit_p(il3945_pci_remove), .remove = il3945_pci_remove,
.driver.pm = IL_LEGACY_PM_OPS, .driver.pm = IL_LEGACY_PM_OPS,
}; };

View File

@ -6664,7 +6664,7 @@ out:
return err; return err;
} }
static void __devexit static void
il4965_pci_remove(struct pci_dev *pdev) il4965_pci_remove(struct pci_dev *pdev)
{ {
struct il_priv *il = pci_get_drvdata(pdev); struct il_priv *il = pci_get_drvdata(pdev);
@ -6772,7 +6772,7 @@ static struct pci_driver il4965_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = il4965_hw_card_ids, .id_table = il4965_hw_card_ids,
.probe = il4965_pci_probe, .probe = il4965_pci_probe,
.remove = __devexit_p(il4965_pci_remove), .remove = il4965_pci_remove,
.driver.pm = IL_LEGACY_PM_OPS, .driver.pm = IL_LEGACY_PM_OPS,
}; };

View File

@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
* As a consequence, it's not as complicated as it sounds, just add * As a consequence, it's not as complicated as it sounds, just add
* any lower rates to the ACK rate bitmap. * any lower rates to the ACK rate bitmap.
*/ */
if (IWL_RATE_11M_INDEX < lowest_present_ofdm) if (IWL_RATE_11M_INDEX < lowest_present_cck)
ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
if (IWL_RATE_5M_INDEX < lowest_present_ofdm) if (IWL_RATE_5M_INDEX < lowest_present_cck)
ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
if (IWL_RATE_2M_INDEX < lowest_present_ofdm) if (IWL_RATE_2M_INDEX < lowest_present_cck)
ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
/* 1M already there or needed so always add */ /* 1M already there or needed so always add */
cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;

View File

@ -293,7 +293,7 @@ out_free_trans:
return -EFAULT; return -EFAULT;
} }
static void __devexit iwl_pci_remove(struct pci_dev *pdev) static void iwl_pci_remove(struct pci_dev *pdev)
{ {
struct iwl_trans *trans = pci_get_drvdata(pdev); struct iwl_trans *trans = pci_get_drvdata(pdev);
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@ -352,7 +352,7 @@ static struct pci_driver iwl_pci_driver = {
.name = DRV_NAME, .name = DRV_NAME,
.id_table = iwl_hw_card_ids, .id_table = iwl_hw_card_ids,
.probe = iwl_pci_probe, .probe = iwl_pci_probe,
.remove = __devexit_p(iwl_pci_remove), .remove = iwl_pci_remove,
.driver.pm = IWL_PM_OPS, .driver.pm = IWL_PM_OPS,
}; };

View File

@ -298,6 +298,7 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
const u8 *rates_eid, *ext_rates_eid; const u8 *rates_eid, *ext_rates_eid;
int n = 0; int n = 0;
rcu_read_lock();
rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
@ -325,6 +326,7 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
*tlv++ = 0x96; *tlv++ = 0x96;
n = 4; n = 4;
} }
rcu_read_unlock();
rate_tlv->header.len = cpu_to_le16(n); rate_tlv->header.len = cpu_to_le16(n);
return sizeof(rate_tlv->header) + n; return sizeof(rate_tlv->header) + n;
@ -1140,11 +1142,13 @@ static int lbs_associate(struct lbs_private *priv,
cmd->capability = cpu_to_le16(bss->capability); cmd->capability = cpu_to_le16(bss->capability);
/* add SSID TLV */ /* add SSID TLV */
rcu_read_lock();
ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
if (ssid_eid) if (ssid_eid)
pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]); pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
else else
lbs_deb_assoc("no SSID\n"); lbs_deb_assoc("no SSID\n");
rcu_read_unlock();
/* add DS param TLV */ /* add DS param TLV */
if (bss->channel) if (bss->channel)
@ -1782,7 +1786,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
struct cfg80211_ibss_params *params, struct cfg80211_ibss_params *params,
struct cfg80211_bss *bss) struct cfg80211_bss *bss)
{ {
const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); const u8 *rates_eid;
struct cmd_ds_802_11_ad_hoc_join cmd; struct cmd_ds_802_11_ad_hoc_join cmd;
u8 preamble = RADIO_PREAMBLE_SHORT; u8 preamble = RADIO_PREAMBLE_SHORT;
int ret = 0; int ret = 0;
@ -1841,6 +1845,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
/* set rates to the intersection of our rates and the rates in the /* set rates to the intersection of our rates and the rates in the
bss */ bss */
rcu_read_lock();
rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
if (!rates_eid) { if (!rates_eid) {
lbs_add_rates(cmd.bss.rates); lbs_add_rates(cmd.bss.rates);
} else { } else {
@ -1860,6 +1866,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
} }
} }
} }
rcu_read_unlock();
/* Only v8 and below support setting this */ /* Only v8 and below support setting this */
if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {

View File

@ -1124,7 +1124,7 @@ static void if_spi_resume_worker(struct work_struct *work)
} }
} }
static int __devinit if_spi_probe(struct spi_device *spi) static int if_spi_probe(struct spi_device *spi)
{ {
struct if_spi_card *card; struct if_spi_card *card;
struct lbs_private *priv = NULL; struct lbs_private *priv = NULL;
@ -1226,7 +1226,7 @@ out:
return err; return err;
} }
static int __devexit libertas_spi_remove(struct spi_device *spi) static int libertas_spi_remove(struct spi_device *spi)
{ {
struct if_spi_card *card = spi_get_drvdata(spi); struct if_spi_card *card = spi_get_drvdata(spi);
struct lbs_private *priv = card->priv; struct lbs_private *priv = card->priv;
@ -1285,7 +1285,7 @@ static const struct dev_pm_ops if_spi_pm_ops = {
static struct spi_driver libertas_spi_driver = { static struct spi_driver libertas_spi_driver = {
.probe = if_spi_probe, .probe = if_spi_probe,
.remove = __devexit_p(libertas_spi_remove), .remove = libertas_spi_remove,
.driver = { .driver = {
.name = "libertas_spi", .name = "libertas_spi",
.owner = THIS_MODULE, .owner = THIS_MODULE,

View File

@ -1347,9 +1347,14 @@ static void hw_scan_work(struct work_struct *work)
hwsim->hw_scan_vif, hwsim->hw_scan_vif,
req->ssids[i].ssid, req->ssids[i].ssid,
req->ssids[i].ssid_len, req->ssids[i].ssid_len,
req->ie, req->ie_len); req->ie_len);
if (!probe) if (!probe)
continue; continue;
if (req->ie_len)
memcpy(skb_put(probe, req->ie_len), req->ie,
req->ie_len);
local_bh_disable(); local_bh_disable();
mac80211_hwsim_tx_frame(hwsim->hw, probe, mac80211_hwsim_tx_frame(hwsim->hw, probe,
hwsim->tmp_chan); hwsim->tmp_chan);

View File

@ -1948,6 +1948,21 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
else else
ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap))
ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
else
ht_info->cap &= ~IEEE80211_HT_CAP_GRN_FLD;
if (ISENABLED_40MHZ_INTOLERANT(adapter->hw_dot_11n_dev_cap))
ht_info->cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
else
ht_info->cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
if (ISSUPP_RXLDPC(adapter->hw_dot_11n_dev_cap))
ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
else
ht_info->cap &= ~IEEE80211_HT_CAP_LDPC_CODING;
ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
ht_info->cap |= IEEE80211_HT_CAP_SM_PS; ht_info->cap |= IEEE80211_HT_CAP_SM_PS;

View File

@ -194,6 +194,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) #define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25))
#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) #define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8))
#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
/* httxcfg bitmap /* httxcfg bitmap
* 0 reserved * 0 reserved

View File

@ -160,10 +160,21 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
{ {
int ret; int ret;
u8 *beacon_ie; u8 *beacon_ie;
size_t beacon_ie_len;
struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
const struct cfg80211_bss_ies *ies;
rcu_read_lock();
ies = rcu_dereference(bss->ies);
if (WARN_ON(!ies)) {
/* should never happen */
rcu_read_unlock();
return -EINVAL;
}
beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
beacon_ie_len = ies->len;
rcu_read_unlock();
beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies,
GFP_KERNEL);
if (!beacon_ie) { if (!beacon_ie) {
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
return -ENOMEM; return -ENOMEM;
@ -172,7 +183,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
bss_desc->rssi = bss->signal; bss_desc->rssi = bss->signal;
bss_desc->beacon_buf = beacon_ie; bss_desc->beacon_buf = beacon_ie;
bss_desc->beacon_buf_size = bss->len_beacon_ies; bss_desc->beacon_buf_size = beacon_ie_len;
bss_desc->beacon_period = bss->beacon_interval; bss_desc->beacon_period = bss->beacon_interval;
bss_desc->cap_info_bitmap = bss->capability; bss_desc->cap_info_bitmap = bss->capability;
bss_desc->bss_band = bss_priv->band; bss_desc->bss_band = bss_priv->band;
@ -198,18 +209,23 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
static int mwifiex_process_country_ie(struct mwifiex_private *priv, static int mwifiex_process_country_ie(struct mwifiex_private *priv,
struct cfg80211_bss *bss) struct cfg80211_bss *bss)
{ {
u8 *country_ie, country_ie_len; const u8 *country_ie;
u8 country_ie_len;
struct mwifiex_802_11d_domain_reg *domain_info = struct mwifiex_802_11d_domain_reg *domain_info =
&priv->adapter->domain_reg; &priv->adapter->domain_reg;
country_ie = (u8 *)ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); rcu_read_lock();
country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
if (!country_ie) if (!country_ie) {
rcu_read_unlock();
return 0; return 0;
}
country_ie_len = country_ie[1]; country_ie_len = country_ie[1];
if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) {
rcu_read_unlock();
return 0; return 0;
}
domain_info->country_code[0] = country_ie[2]; domain_info->country_code[0] = country_ie[2];
domain_info->country_code[1] = country_ie[3]; domain_info->country_code[1] = country_ie[3];
@ -223,6 +239,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
memcpy((u8 *)domain_info->triplet, memcpy((u8 *)domain_info->triplet,
&country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len); &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);
rcu_read_unlock();
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
HostCmd_ACT_GEN_SET, 0, NULL)) { HostCmd_ACT_GEN_SET, 0, NULL)) {
wiphy_err(priv->adapter->wiphy, wiphy_err(priv->adapter->wiphy,
@ -461,7 +479,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
} }
if (adapter->hs_activated) { if (adapter->hs_activated) {
dev_dbg(adapter->dev, "cmd: HS Already actived\n"); dev_dbg(adapter->dev, "cmd: HS Already activated\n");
return true; return true;
} }

View File

@ -351,7 +351,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
card->udev = udev; card->udev = udev;
card->intf = intf; card->intf = intf;
pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocl=%#x\n", pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass, udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
udev->descriptor.bDeviceSubClass, udev->descriptor.bDeviceSubClass,
udev->descriptor.bDeviceProtocol); udev->descriptor.bDeviceProtocol);

View File

@ -5258,7 +5258,7 @@ enum {
#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" #define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { static struct mwl8k_device_info mwl8k_info_tbl[] = {
[MWL8363] = { [MWL8363] = {
.part_name = "88w8363", .part_name = "88w8363",
.helper_image = "mwl8k/helper_8363.fw", .helper_image = "mwl8k/helper_8363.fw",
@ -5756,7 +5756,7 @@ err_free_cookie:
return rc; return rc;
} }
static int __devinit mwl8k_probe(struct pci_dev *pdev, static int mwl8k_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
static int printed_version; static int printed_version;
@ -5873,12 +5873,7 @@ err_disable_device:
return rc; return rc;
} }
static void __devexit mwl8k_shutdown(struct pci_dev *pdev) static void mwl8k_remove(struct pci_dev *pdev)
{
printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
}
static void __devexit mwl8k_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct mwl8k_priv *priv; struct mwl8k_priv *priv;
@ -5930,8 +5925,7 @@ static struct pci_driver mwl8k_driver = {
.name = MWL8K_NAME, .name = MWL8K_NAME,
.id_table = mwl8k_pci_id_table, .id_table = mwl8k_pci_id_table,
.probe = mwl8k_probe, .probe = mwl8k_probe,
.remove = __devexit_p(mwl8k_remove), .remove = mwl8k_remove,
.shutdown = __devexit_p(mwl8k_shutdown),
}; };
module_pci_driver(mwl8k_driver); module_pci_driver(mwl8k_driver);

View File

@ -255,7 +255,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev) static void orinoco_nortel_remove_one(struct pci_dev *pdev)
{ {
struct orinoco_private *priv = pci_get_drvdata(pdev); struct orinoco_private *priv = pci_get_drvdata(pdev);
struct orinoco_pci_card *card = priv->card; struct orinoco_pci_card *card = priv->card;
@ -288,7 +288,7 @@ static struct pci_driver orinoco_nortel_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = orinoco_nortel_id_table, .id_table = orinoco_nortel_id_table,
.probe = orinoco_nortel_init_one, .probe = orinoco_nortel_init_one,
.remove = __devexit_p(orinoco_nortel_remove_one), .remove = orinoco_nortel_remove_one,
.suspend = orinoco_pci_suspend, .suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume, .resume = orinoco_pci_resume,
}; };

View File

@ -199,7 +199,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev) static void orinoco_pci_remove_one(struct pci_dev *pdev)
{ {
struct orinoco_private *priv = pci_get_drvdata(pdev); struct orinoco_private *priv = pci_get_drvdata(pdev);
@ -228,7 +228,7 @@ static struct pci_driver orinoco_pci_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = orinoco_pci_id_table, .id_table = orinoco_pci_id_table,
.probe = orinoco_pci_init_one, .probe = orinoco_pci_init_one,
.remove = __devexit_p(orinoco_pci_remove_one), .remove = orinoco_pci_remove_one,
.suspend = orinoco_pci_suspend, .suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume, .resume = orinoco_pci_resume,
}; };

View File

@ -294,7 +294,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) static void orinoco_plx_remove_one(struct pci_dev *pdev)
{ {
struct orinoco_private *priv = pci_get_drvdata(pdev); struct orinoco_private *priv = pci_get_drvdata(pdev);
struct orinoco_pci_card *card = priv->card; struct orinoco_pci_card *card = priv->card;
@ -334,7 +334,7 @@ static struct pci_driver orinoco_plx_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = orinoco_plx_id_table, .id_table = orinoco_plx_id_table,
.probe = orinoco_plx_init_one, .probe = orinoco_plx_init_one,
.remove = __devexit_p(orinoco_plx_remove_one), .remove = orinoco_plx_remove_one,
.suspend = orinoco_pci_suspend, .suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume, .resume = orinoco_pci_resume,
}; };

View File

@ -188,7 +188,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev) static void orinoco_tmd_remove_one(struct pci_dev *pdev)
{ {
struct orinoco_private *priv = pci_get_drvdata(pdev); struct orinoco_private *priv = pci_get_drvdata(pdev);
struct orinoco_pci_card *card = priv->card; struct orinoco_pci_card *card = priv->card;
@ -214,7 +214,7 @@ static struct pci_driver orinoco_tmd_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.id_table = orinoco_tmd_id_table, .id_table = orinoco_tmd_id_table,
.probe = orinoco_tmd_init_one, .probe = orinoco_tmd_init_one,
.remove = __devexit_p(orinoco_tmd_remove_one), .remove = orinoco_tmd_remove_one,
.suspend = orinoco_pci_suspend, .suspend = orinoco_pci_suspend,
.resume = orinoco_pci_resume, .resume = orinoco_pci_resume,
}; };

View File

@ -541,8 +541,9 @@ static int p54_parse_rssical(struct ieee80211_hw *dev,
entries = (len - offset) / entries = (len - offset) /
sizeof(struct pda_rssi_cal_ext_entry); sizeof(struct pda_rssi_cal_ext_entry);
if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || if (len < offset ||
entries <= 0) { (len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
entries == 0) {
wiphy_err(dev->wiphy, "invalid rssi database.\n"); wiphy_err(dev->wiphy, "invalid rssi database.\n");
goto err_data; goto err_data;
} }

View File

@ -540,7 +540,7 @@ out:
pci_dev_put(pdev); pci_dev_put(pdev);
} }
static int __devinit p54p_probe(struct pci_dev *pdev, static int p54p_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct p54p_priv *priv; struct p54p_priv *priv;
@ -639,7 +639,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit p54p_remove(struct pci_dev *pdev) static void p54p_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *dev = pci_get_drvdata(pdev); struct ieee80211_hw *dev = pci_get_drvdata(pdev);
struct p54p_priv *priv; struct p54p_priv *priv;
@ -659,7 +659,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
p54_free_common(dev); p54_free_common(dev);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM_SLEEP
static int p54p_suspend(struct device *device) static int p54p_suspend(struct device *device)
{ {
struct pci_dev *pdev = to_pci_dev(device); struct pci_dev *pdev = to_pci_dev(device);
@ -681,25 +681,18 @@ static int p54p_resume(struct device *device)
return pci_set_power_state(pdev, PCI_D0); return pci_set_power_state(pdev, PCI_D0);
} }
static const struct dev_pm_ops p54pci_pm_ops = { static SIMPLE_DEV_PM_OPS(p54pci_pm_ops, p54p_suspend, p54p_resume);
.suspend = p54p_suspend,
.resume = p54p_resume,
.freeze = p54p_suspend,
.thaw = p54p_resume,
.poweroff = p54p_suspend,
.restore = p54p_resume,
};
#define P54P_PM_OPS (&p54pci_pm_ops) #define P54P_PM_OPS (&p54pci_pm_ops)
#else #else
#define P54P_PM_OPS (NULL) #define P54P_PM_OPS (NULL)
#endif /* CONFIG_PM */ #endif /* CONFIG_PM_SLEEP */
static struct pci_driver p54p_driver = { static struct pci_driver p54p_driver = {
.name = "p54pci", .name = "p54pci",
.id_table = p54p_table, .id_table = p54p_table,
.probe = p54p_probe, .probe = p54p_probe,
.remove = __devexit_p(p54p_remove), .remove = p54p_remove,
.driver.pm = P54P_PM_OPS, .driver.pm = P54P_PM_OPS,
}; };

View File

@ -595,7 +595,7 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
cancel_work_sync(&priv->work); cancel_work_sync(&priv->work);
} }
static int __devinit p54spi_probe(struct spi_device *spi) static int p54spi_probe(struct spi_device *spi)
{ {
struct p54s_priv *priv = NULL; struct p54s_priv *priv = NULL;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
@ -683,7 +683,7 @@ err_free:
return ret; return ret;
} }
static int __devexit p54spi_remove(struct spi_device *spi) static int p54spi_remove(struct spi_device *spi)
{ {
struct p54s_priv *priv = dev_get_drvdata(&spi->dev); struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
@ -710,7 +710,7 @@ static struct spi_driver p54spi_driver = {
}, },
.probe = p54spi_probe, .probe = p54spi_probe,
.remove = __devexit_p(p54spi_remove), .remove = p54spi_remove,
}; };
static int __init p54spi_init(void) static int __init p54spi_init(void)

View File

@ -986,7 +986,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev,
return err; return err;
} }
static int __devinit p54u_probe(struct usb_interface *intf, static int p54u_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
@ -1057,7 +1057,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
return err; return err;
} }
static void __devexit p54u_disconnect(struct usb_interface *intf) static void p54u_disconnect(struct usb_interface *intf)
{ {
struct ieee80211_hw *dev = usb_get_intfdata(intf); struct ieee80211_hw *dev = usb_get_intfdata(intf);
struct p54u_priv *priv; struct p54u_priv *priv;
@ -1131,7 +1131,7 @@ static struct usb_driver p54u_driver = {
.name = "p54usb", .name = "p54usb",
.id_table = p54u_table, .id_table = p54u_table,
.probe = p54u_probe, .probe = p54u_probe,
.disconnect = __devexit_p(p54u_disconnect), .disconnect = p54u_disconnect,
.pre_reset = p54u_pre_reset, .pre_reset = p54u_pre_reset,
.post_reset = p54u_post_reset, .post_reset = p54u_post_reset,
#ifdef CONFIG_PM #ifdef CONFIG_PM

View File

@ -1831,7 +1831,7 @@ static struct pci_driver rt2400pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rt2400pci_device_table, .id_table = rt2400pci_device_table,
.probe = rt2400pci_probe, .probe = rt2400pci_probe,
.remove = __devexit_p(rt2x00pci_remove), .remove = rt2x00pci_remove,
.suspend = rt2x00pci_suspend, .suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume, .resume = rt2x00pci_resume,
}; };

View File

@ -2122,7 +2122,7 @@ static struct pci_driver rt2500pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rt2500pci_device_table, .id_table = rt2500pci_device_table,
.probe = rt2500pci_probe, .probe = rt2500pci_probe,
.remove = __devexit_p(rt2x00pci_remove), .remove = rt2x00pci_remove,
.suspend = rt2x00pci_suspend, .suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume, .resume = rt2x00pci_resume,
}; };

View File

@ -1993,8 +1993,10 @@ struct mac_iveiv_entry {
*/ */
#define RFCSR3_K FIELD8(0x0f) #define RFCSR3_K FIELD8(0x0f)
/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ /* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */
#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70); #define RFCSR3_PA1_BIAS_CCK FIELD8(0x70)
#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80); #define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80)
/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
#define RFCSR3_VCOCAL_EN FIELD8(0x80)
/* /*
* FRCSR 5: * FRCSR 5:

View File

@ -2173,7 +2173,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 59, rt2800_rfcsr_write(rt2x00dev, 59,
r59_nonbt_rev[idx]); r59_nonbt_rev[idx]);
} else if (rt2x00_rt(rt2x00dev, RT5390) || } else if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) { rt2x00_rt(rt2x00dev, RT5392)) {
static const char r59_non_bt[] = {0x8f, 0x8f, static const char r59_non_bt[] = {0x8f, 0x8f,
0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
@ -2243,7 +2243,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
} }
@ -2264,7 +2264,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
if (rf->channel <= 14) { if (rf->channel <= 14) {
if (!rt2x00_rt(rt2x00dev, RT5390) && if (!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2x00_rt(rt2x00dev, RT5392)) { !rt2x00_rt(rt2x00dev, RT5392)) {
if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, if (test_bit(CAPABILITY_EXTERNAL_LNA_BG,
&rt2x00dev->cap_flags)) { &rt2x00dev->cap_flags)) {
rt2800_bbp_write(rt2x00dev, 82, 0x62); rt2800_bbp_write(rt2x00dev, 82, 0x62);
@ -2804,7 +2804,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
case RF5390: case RF5390:
case RF5392: case RF5392:
rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
break; break;
default: default:
@ -3592,8 +3592,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
rt2800_bbp_write(rt2x00dev, 84, 0x19); rt2800_bbp_write(rt2x00dev, 84, 0x19);
else if (rt2x00_rt(rt2x00dev, RT3290) || else if (rt2x00_rt(rt2x00dev, RT3290) ||
rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 84, 0x9a); rt2800_bbp_write(rt2x00dev, 84, 0x9a);
else else
rt2800_bbp_write(rt2x00dev, 84, 0x99); rt2800_bbp_write(rt2x00dev, 84, 0x99);
@ -3652,7 +3652,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
else if (rt2x00_rt(rt2x00dev, RT3352)) else if (rt2x00_rt(rt2x00dev, RT3352))
rt2800_bbp_write(rt2x00dev, 105, 0x34); rt2800_bbp_write(rt2x00dev, 105, 0x34);
else if (rt2x00_rt(rt2x00dev, RT5390) || else if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) rt2x00_rt(rt2x00dev, RT5392))
rt2800_bbp_write(rt2x00dev, 105, 0x3c); rt2800_bbp_write(rt2x00dev, 105, 0x3c);
else else
rt2800_bbp_write(rt2x00dev, 105, 0x05); rt2800_bbp_write(rt2x00dev, 105, 0x05);
@ -3746,7 +3746,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
} }
if (rt2x00_rt(rt2x00dev, RT5390) || if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) { rt2x00_rt(rt2x00dev, RT5392)) {
int ant, div_mode; int ant, div_mode;
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
@ -4220,66 +4220,66 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
rt2800_rfcsr_write(rt2x00dev, 62, 0x00); rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
rt2800_rfcsr_write(rt2x00dev, 63, 0x00); rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
} else if (rt2x00_rt(rt2x00dev, RT5392)) { } else if (rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_rfcsr_write(rt2x00dev, 1, 0x17); rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
rt2800_rfcsr_write(rt2x00dev, 2, 0x80); rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
rt2800_rfcsr_write(rt2x00dev, 3, 0x88); rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
rt2800_rfcsr_write(rt2x00dev, 5, 0x10); rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
rt2800_rfcsr_write(rt2x00dev, 7, 0x00); rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
rt2800_rfcsr_write(rt2x00dev, 10, 0x53); rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
rt2800_rfcsr_write(rt2x00dev, 12, 0x46); rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
rt2800_rfcsr_write(rt2x00dev, 14, 0x00); rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
rt2800_rfcsr_write(rt2x00dev, 15, 0x00); rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
rt2800_rfcsr_write(rt2x00dev, 16, 0x00); rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
rt2800_rfcsr_write(rt2x00dev, 18, 0x03); rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); rt2800_rfcsr_write(rt2x00dev, 19, 0x4d);
rt2800_rfcsr_write(rt2x00dev, 20, 0x00); rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); rt2800_rfcsr_write(rt2x00dev, 21, 0x8d);
rt2800_rfcsr_write(rt2x00dev, 22, 0x20); rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); rt2800_rfcsr_write(rt2x00dev, 23, 0x0b);
rt2800_rfcsr_write(rt2x00dev, 24, 0x44); rt2800_rfcsr_write(rt2x00dev, 24, 0x44);
rt2800_rfcsr_write(rt2x00dev, 25, 0x80); rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
rt2800_rfcsr_write(rt2x00dev, 26, 0x82); rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
rt2800_rfcsr_write(rt2x00dev, 27, 0x09); rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
rt2800_rfcsr_write(rt2x00dev, 28, 0x00); rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
rt2800_rfcsr_write(rt2x00dev, 29, 0x10); rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
rt2800_rfcsr_write(rt2x00dev, 30, 0x10); rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
rt2800_rfcsr_write(rt2x00dev, 31, 0x80); rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
rt2800_rfcsr_write(rt2x00dev, 32, 0x20); rt2800_rfcsr_write(rt2x00dev, 32, 0x20);
rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
rt2800_rfcsr_write(rt2x00dev, 34, 0x07); rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
rt2800_rfcsr_write(rt2x00dev, 35, 0x12); rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
rt2800_rfcsr_write(rt2x00dev, 36, 0x00); rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
rt2800_rfcsr_write(rt2x00dev, 37, 0x08); rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
rt2800_rfcsr_write(rt2x00dev, 38, 0x89); rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); rt2800_rfcsr_write(rt2x00dev, 40, 0x0f);
rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
rt2800_rfcsr_write(rt2x00dev, 46, 0x73); rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); rt2800_rfcsr_write(rt2x00dev, 47, 0x0c);
rt2800_rfcsr_write(rt2x00dev, 48, 0x10); rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
rt2800_rfcsr_write(rt2x00dev, 49, 0x94); rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
rt2800_rfcsr_write(rt2x00dev, 50, 0x94); rt2800_rfcsr_write(rt2x00dev, 50, 0x94);
rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); rt2800_rfcsr_write(rt2x00dev, 51, 0x3a);
rt2800_rfcsr_write(rt2x00dev, 52, 0x48); rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
rt2800_rfcsr_write(rt2x00dev, 53, 0x44); rt2800_rfcsr_write(rt2x00dev, 53, 0x44);
rt2800_rfcsr_write(rt2x00dev, 54, 0x38); rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
rt2800_rfcsr_write(rt2x00dev, 55, 0x43); rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); rt2800_rfcsr_write(rt2x00dev, 56, 0xa1);
rt2800_rfcsr_write(rt2x00dev, 57, 0x00); rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
rt2800_rfcsr_write(rt2x00dev, 58, 0x39); rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
rt2800_rfcsr_write(rt2x00dev, 59, 0x07); rt2800_rfcsr_write(rt2x00dev, 59, 0x07);
rt2800_rfcsr_write(rt2x00dev, 60, 0x45); rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
rt2800_rfcsr_write(rt2x00dev, 61, 0x91); rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
rt2800_rfcsr_write(rt2x00dev, 62, 0x39); rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
rt2800_rfcsr_write(rt2x00dev, 63, 0x07); rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
} }
if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@ -4356,7 +4356,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
if (!rt2x00_rt(rt2x00dev, RT5390) && if (!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2x00_rt(rt2x00dev, RT5392)) { !rt2x00_rt(rt2x00dev, RT5392)) {
/* /*
* Set back to initial state * Set back to initial state
*/ */
@ -4385,7 +4385,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
if (!rt2x00_rt(rt2x00dev, RT5390) && if (!rt2x00_rt(rt2x00dev, RT5390) &&
!rt2x00_rt(rt2x00dev, RT5392)) { !rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
if (rt2x00_rt(rt2x00dev, RT3070) || if (rt2x00_rt(rt2x00dev, RT3070) ||
@ -4457,7 +4457,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
} }
if (rt2x00_rt(rt2x00dev, RT5390) || if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392)) { rt2x00_rt(rt2x00dev, RT5392)) {
rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);

View File

@ -1176,7 +1176,7 @@ static struct platform_driver rt2800soc_driver = {
.mod_name = KBUILD_MODNAME, .mod_name = KBUILD_MODNAME,
}, },
.probe = rt2800soc_probe, .probe = rt2800soc_probe,
.remove = __devexit_p(rt2x00soc_remove), .remove = rt2x00soc_remove,
.suspend = rt2x00soc_suspend, .suspend = rt2x00soc_suspend,
.resume = rt2x00soc_resume, .resume = rt2x00soc_resume,
}; };
@ -1193,7 +1193,7 @@ static struct pci_driver rt2800pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rt2800pci_device_table, .id_table = rt2800pci_device_table,
.probe = rt2800pci_probe, .probe = rt2800pci_probe,
.remove = __devexit_p(rt2x00pci_remove), .remove = rt2x00pci_remove,
.suspend = rt2x00pci_suspend, .suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume, .resume = rt2x00pci_resume,
}; };

View File

@ -1124,6 +1124,9 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
struct ieee80211_iface_limit *if_limit; struct ieee80211_iface_limit *if_limit;
struct ieee80211_iface_combination *if_combination; struct ieee80211_iface_combination *if_combination;
if (rt2x00dev->ops->max_ap_intf < 2)
return;
/* /*
* Build up AP interface limits structure. * Build up AP interface limits structure.
*/ */
@ -1182,6 +1185,13 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
*/ */
rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf);
/*
* rt2x00 devices can only use the last n bits of the MAC address
* for virtual interfaces.
*/
rt2x00dev->hw->wiphy->addr_mask[ETH_ALEN - 1] =
(rt2x00dev->ops->max_ap_intf - 1);
/* /*
* Determine which operating modes are supported, all modes * Determine which operating modes are supported, all modes
* which require beaconing, depend on the availability of * which require beaconing, depend on the availability of

View File

@ -3094,7 +3094,7 @@ static struct pci_driver rt61pci_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rt61pci_device_table, .id_table = rt61pci_device_table,
.probe = rt61pci_probe, .probe = rt61pci_probe,
.remove = __devexit_p(rt2x00pci_remove), .remove = rt2x00pci_remove,
.suspend = rt2x00pci_suspend, .suspend = rt2x00pci_suspend,
.resume = rt2x00pci_resume, .resume = rt2x00pci_resume,
}; };

View File

@ -901,7 +901,7 @@ static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
udelay(10); udelay(10);
} }
static int __devinit rtl8180_probe(struct pci_dev *pdev, static int rtl8180_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct ieee80211_hw *dev; struct ieee80211_hw *dev;
@ -1131,7 +1131,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
return err; return err;
} }
static void __devexit rtl8180_remove(struct pci_dev *pdev) static void rtl8180_remove(struct pci_dev *pdev)
{ {
struct ieee80211_hw *dev = pci_get_drvdata(pdev); struct ieee80211_hw *dev = pci_get_drvdata(pdev);
struct rtl8180_priv *priv; struct rtl8180_priv *priv;
@ -1170,7 +1170,7 @@ static struct pci_driver rtl8180_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rtl8180_table, .id_table = rtl8180_table,
.probe = rtl8180_probe, .probe = rtl8180_probe,
.remove = __devexit_p(rtl8180_remove), .remove = rtl8180_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.suspend = rtl8180_suspend, .suspend = rtl8180_suspend,
.resume = rtl8180_resume, .resume = rtl8180_resume,

View File

@ -1411,7 +1411,7 @@ static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
udelay(10); udelay(10);
} }
static int __devinit rtl8187_probe(struct usb_interface *intf, static int rtl8187_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
@ -1639,7 +1639,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
return err; return err;
} }
static void __devexit rtl8187_disconnect(struct usb_interface *intf) static void rtl8187_disconnect(struct usb_interface *intf)
{ {
struct ieee80211_hw *dev = usb_get_intfdata(intf); struct ieee80211_hw *dev = usb_get_intfdata(intf);
struct rtl8187_priv *priv; struct rtl8187_priv *priv;
@ -1664,7 +1664,7 @@ static struct usb_driver rtl8187_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = rtl8187_table, .id_table = rtl8187_table,
.probe = rtl8187_probe, .probe = rtl8187_probe,
.disconnect = __devexit_p(rtl8187_disconnect), .disconnect = rtl8187_disconnect,
.disable_hub_initiated_lpm = 1, .disable_hub_initiated_lpm = 1,
}; };

View File

@ -1756,7 +1756,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
return true; return true;
} }
int __devinit rtl_pci_probe(struct pci_dev *pdev, int rtl_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id) const struct pci_device_id *id)
{ {
struct ieee80211_hw *hw = NULL; struct ieee80211_hw *hw = NULL;
@ -1982,6 +1982,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
} }
EXPORT_SYMBOL(rtl_pci_disconnect); EXPORT_SYMBOL(rtl_pci_disconnect);
#ifdef CONFIG_PM_SLEEP
/*************************************** /***************************************
kernel pci power state define: kernel pci power state define:
PCI_D0 ((pci_power_t __force) 0) PCI_D0 ((pci_power_t __force) 0)
@ -2021,6 +2022,7 @@ int rtl_pci_resume(struct device *dev)
return 0; return 0;
} }
EXPORT_SYMBOL(rtl_pci_resume); EXPORT_SYMBOL(rtl_pci_resume);
#endif /* CONFIG_PM_SLEEP */
struct rtl_intf_ops rtl_pci_ops = { struct rtl_intf_ops rtl_pci_ops = {
.read_efuse_byte = read_efuse_byte, .read_efuse_byte = read_efuse_byte,

View File

@ -236,11 +236,13 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
extern struct rtl_intf_ops rtl_pci_ops; extern struct rtl_intf_ops rtl_pci_ops;
int __devinit rtl_pci_probe(struct pci_dev *pdev, int rtl_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id); const struct pci_device_id *id);
void rtl_pci_disconnect(struct pci_dev *pdev); void rtl_pci_disconnect(struct pci_dev *pdev);
#ifdef CONFIG_PM_SLEEP
int rtl_pci_suspend(struct device *dev); int rtl_pci_suspend(struct device *dev);
int rtl_pci_resume(struct device *dev); int rtl_pci_resume(struct device *dev);
#endif /* CONFIG_PM_SLEEP */
static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
{ {
return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);

View File

@ -372,14 +372,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static const struct dev_pm_ops rtlwifi_pm_ops = { static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
.suspend = rtl_pci_suspend,
.resume = rtl_pci_resume,
.freeze = rtl_pci_suspend,
.thaw = rtl_pci_resume,
.poweroff = rtl_pci_suspend,
.restore = rtl_pci_resume,
};
static struct pci_driver rtl92ce_driver = { static struct pci_driver rtl92ce_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,

View File

@ -352,7 +352,7 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
.maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
}; };
static struct pci_device_id rtl92de_pci_ids[] __devinitdata = { static struct pci_device_id rtl92de_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)}, {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)}, {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)},
{}, {},
@ -378,14 +378,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static const struct dev_pm_ops rtlwifi_pm_ops = { static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
.suspend = rtl_pci_suspend,
.resume = rtl_pci_resume,
.freeze = rtl_pci_suspend,
.thaw = rtl_pci_resume,
.poweroff = rtl_pci_suspend,
.restore = rtl_pci_resume,
};
static struct pci_driver rtl92de_driver = { static struct pci_driver rtl92de_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,

View File

@ -522,8 +522,7 @@ enum fwcmd_iotype {
FW_CMD_IQK_ENABLE = 30, FW_CMD_IQK_ENABLE = 30,
}; };
/* /* Driver info contain PHY status
* Driver info contain PHY status
* and other variabel size info * and other variabel size info
* PHY Status content as below * PHY Status content as below
*/ */

View File

@ -465,8 +465,8 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
digtable->cur_igvalue = digtable->cur_igvalue =
digtable->rx_gain_range_min; digtable->rx_gain_range_min;
else else
digtable->cur_igvalue = digtable->rssi_val + 10 - digtable->cur_igvalue = digtable->rssi_val + 10
digtable->back_val; - digtable->back_val;
if (falsealm_cnt->cnt_all > 10000) if (falsealm_cnt->cnt_all > 10000)
digtable->cur_igvalue = digtable->cur_igvalue =
@ -518,7 +518,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
{ {
struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_priv *rtlpriv = rtl_priv(hw);
struct dig_t *digtable = &rtlpriv->dm_digtable; struct dig_t *dig = &rtlpriv->dm_digtable;
if (rtlpriv->mac80211.act_scanning) if (rtlpriv->mac80211.act_scanning)
return; return;
@ -526,17 +526,17 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
/* Decide the current status and if modify initial gain or not */ /* Decide the current status and if modify initial gain or not */
if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
digtable->cur_sta_cstate = DIG_STA_CONNECT; dig->cur_sta_cstate = DIG_STA_CONNECT;
else else
digtable->cur_sta_cstate = DIG_STA_DISCONNECT; dig->cur_sta_cstate = DIG_STA_DISCONNECT;
digtable->rssi_val = rtlpriv->dm.undec_sm_pwdb; dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
/* Change dig mode to rssi */ /* Change dig mode to rssi */
if (digtable->cur_sta_cstate != DIG_STA_DISCONNECT) { if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
if (digtable->dig_twoport_algorithm == if (dig->dig_twoport_algorithm ==
DIG_TWO_PORT_ALGO_FALSE_ALARM) { DIG_TWO_PORT_ALGO_FALSE_ALARM) {
digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS); rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
} }
} }
@ -544,7 +544,7 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
_rtl92s_dm_false_alarm_counter_statistics(hw); _rtl92s_dm_false_alarm_counter_statistics(hw);
_rtl92s_dm_initial_gain_sta_beforeconnect(hw); _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
digtable->pre_sta_cstate = digtable->cur_sta_cstate; dig->pre_sta_cstate = dig->cur_sta_cstate;
} }
static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)

View File

@ -1089,8 +1089,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
return err; return err;
} }
void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr) void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr)
{ {
/* This is a stub. */
} }
void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)

View File

@ -54,7 +54,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw);
int rtl92se_set_network_type(struct ieee80211_hw *hw, int rtl92se_set_network_type(struct ieee80211_hw *hw,
enum nl80211_iftype type); enum nl80211_iftype type);
void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr); void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr);
void rtl92se_set_qos(struct ieee80211_hw *hw, int aci); void rtl92se_set_qos(struct ieee80211_hw *hw, int aci);
void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw); void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw);
void rtl92se_set_beacon_interval(struct ieee80211_hw *hw); void rtl92se_set_beacon_interval(struct ieee80211_hw *hw);

View File

@ -50,8 +50,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
/*close ASPM for AMD defaultly */ /*close ASPM for AMD defaultly */
rtlpci->const_amdpci_aspm = 0; rtlpci->const_amdpci_aspm = 0;
/* /* ASPM PS mode.
* ASPM PS mode.
* 0 - Disable ASPM, * 0 - Disable ASPM,
* 1 - Enable ASPM without Clock Req, * 1 - Enable ASPM without Clock Req,
* 2 - Enable ASPM with Clock Req, * 2 - Enable ASPM with Clock Req,
@ -67,8 +66,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
/*Setting for PCI-E bridge */ /*Setting for PCI-E bridge */
rtlpci->const_hostpci_aspm_setting = 0x02; rtlpci->const_hostpci_aspm_setting = 0x02;
/* /* In Hw/Sw Radio Off situation.
* In Hw/Sw Radio Off situation.
* 0 - Default, * 0 - Default,
* 1 - From ASPM setting without low Mac Pwr, * 1 - From ASPM setting without low Mac Pwr,
* 2 - From ASPM setting with low Mac Pwr, * 2 - From ASPM setting with low Mac Pwr,
@ -77,8 +75,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
*/ */
rtlpci->const_hwsw_rfoff_d3 = 2; rtlpci->const_hwsw_rfoff_d3 = 2;
/* /* This setting works for those device with
* This setting works for those device with
* backdoor ASPM setting such as EPHY setting. * backdoor ASPM setting such as EPHY setting.
* 0 - Not support ASPM, * 0 - Not support ASPM,
* 1 - Support ASPM, * 1 - Support ASPM,
@ -403,7 +400,7 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
.maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
}; };
static struct pci_device_id rtl92se_pci_ids[] __devinitdata = { static struct pci_device_id rtl92se_pci_ids[] = {
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)}, {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)}, {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)},
{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)}, {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)},
@ -432,14 +429,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static const struct dev_pm_ops rtlwifi_pm_ops = { static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
.suspend = rtl_pci_suspend,
.resume = rtl_pci_resume,
.freeze = rtl_pci_suspend,
.thaw = rtl_pci_resume,
.poweroff = rtl_pci_suspend,
.restore = rtl_pci_resume,
};
static struct pci_driver rtl92se_driver = { static struct pci_driver rtl92se_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,

View File

@ -367,14 +367,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
static const struct dev_pm_ops rtlwifi_pm_ops = { static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
.suspend = rtl_pci_suspend,
.resume = rtl_pci_resume,
.freeze = rtl_pci_suspend,
.thaw = rtl_pci_resume,
.poweroff = rtl_pci_suspend,
.restore = rtl_pci_resume,
};
static struct pci_driver rtl8723ae_driver = { static struct pci_driver rtl8723ae_driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,

View File

@ -940,7 +940,7 @@ static struct rtl_intf_ops rtl_usb_ops = {
.waitq_insert = rtl_usb_tx_chk_waitq_insert, .waitq_insert = rtl_usb_tx_chk_waitq_insert,
}; };
int __devinit rtl_usb_probe(struct usb_interface *intf, int rtl_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
int err; int err;

View File

@ -156,7 +156,7 @@ struct rtl_usb_priv {
int __devinit rtl_usb_probe(struct usb_interface *intf, int rtl_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id); const struct usb_device_id *id);
void rtl_usb_disconnect(struct usb_interface *intf); void rtl_usb_disconnect(struct usb_interface *intf);
int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);

View File

@ -896,11 +896,13 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
goto out; goto out;
skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
req->ie, req->ie_len); req->ie_len);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
if (req->ie_len)
memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data, ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
skb->len); skb->len);

View File

@ -305,7 +305,7 @@ out_free_hw:
return ret; return ret;
} }
static void __devexit wl1251_sdio_remove(struct sdio_func *func) static void wl1251_sdio_remove(struct sdio_func *func)
{ {
struct wl1251 *wl = sdio_get_drvdata(func); struct wl1251 *wl = sdio_get_drvdata(func);
struct wl1251_sdio *wl_sdio = wl->if_priv; struct wl1251_sdio *wl_sdio = wl->if_priv;
@ -347,7 +347,7 @@ static struct sdio_driver wl1251_sdio_driver = {
.name = "wl1251_sdio", .name = "wl1251_sdio",
.id_table = wl1251_devices, .id_table = wl1251_devices,
.probe = wl1251_sdio_probe, .probe = wl1251_sdio_probe,
.remove = __devexit_p(wl1251_sdio_remove), .remove = wl1251_sdio_remove,
.drv.pm = &wl1251_sdio_pm_ops, .drv.pm = &wl1251_sdio_pm_ops,
}; };

View File

@ -237,7 +237,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
.power = wl1251_spi_set_power, .power = wl1251_spi_set_power,
}; };
static int __devinit wl1251_spi_probe(struct spi_device *spi) static int wl1251_spi_probe(struct spi_device *spi)
{ {
struct wl12xx_platform_data *pdata; struct wl12xx_platform_data *pdata;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
@ -309,7 +309,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
return ret; return ret;
} }
static int __devexit wl1251_spi_remove(struct spi_device *spi) static int wl1251_spi_remove(struct spi_device *spi)
{ {
struct wl1251 *wl = dev_get_drvdata(&spi->dev); struct wl1251 *wl = dev_get_drvdata(&spi->dev);
@ -326,7 +326,7 @@ static struct spi_driver wl1251_spi_driver = {
}, },
.probe = wl1251_spi_probe, .probe = wl1251_spi_probe,
.remove = __devexit_p(wl1251_spi_remove), .remove = wl1251_spi_remove,
}; };
static int __init wl1251_spi_init(void) static int __init wl1251_spi_init(void)

View File

@ -1696,7 +1696,7 @@ static int wl12xx_setup(struct wl1271 *wl)
return 0; return 0;
} }
static int __devinit wl12xx_probe(struct platform_device *pdev) static int wl12xx_probe(struct platform_device *pdev)
{ {
struct wl1271 *wl; struct wl1271 *wl;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
@ -1725,7 +1725,7 @@ out:
return ret; return ret;
} }
static const struct platform_device_id wl12xx_id_table[] __devinitconst = { static const struct platform_device_id wl12xx_id_table[] = {
{ "wl12xx", 0 }, { "wl12xx", 0 },
{ } /* Terminating Entry */ { } /* Terminating Entry */
}; };
@ -1733,7 +1733,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
static struct platform_driver wl12xx_driver = { static struct platform_driver wl12xx_driver = {
.probe = wl12xx_probe, .probe = wl12xx_probe,
.remove = __devexit_p(wlcore_remove), .remove = wlcore_remove,
.id_table = wl12xx_id_table, .id_table = wl12xx_id_table,
.driver = { .driver = {
.name = "wl12xx_driver", .name = "wl12xx_driver",

View File

@ -1499,7 +1499,7 @@ static int wl18xx_setup(struct wl1271 *wl)
return 0; return 0;
} }
static int __devinit wl18xx_probe(struct platform_device *pdev) static int wl18xx_probe(struct platform_device *pdev)
{ {
struct wl1271 *wl; struct wl1271 *wl;
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
@ -1528,7 +1528,7 @@ out:
return ret; return ret;
} }
static const struct platform_device_id wl18xx_id_table[] __devinitconst = { static const struct platform_device_id wl18xx_id_table[] = {
{ "wl18xx", 0 }, { "wl18xx", 0 },
{ } /* Terminating Entry */ { } /* Terminating Entry */
}; };
@ -1536,7 +1536,7 @@ MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
static struct platform_driver wl18xx_driver = { static struct platform_driver wl18xx_driver = {
.probe = wl18xx_probe, .probe = wl18xx_probe,
.remove = __devexit_p(wlcore_remove), .remove = wlcore_remove,
.id_table = wl18xx_id_table, .id_table = wl18xx_id_table,
.driver = { .driver = {
.name = "wl18xx_driver", .name = "wl18xx_driver",

View File

@ -1038,11 +1038,13 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
ie, ie_len); ie_len);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
if (ie_len)
memcpy(skb_put(skb, ie_len), ie, ie_len);
wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);

View File

@ -5660,7 +5660,7 @@ out:
complete_all(&wl->nvs_loading_complete); complete_all(&wl->nvs_loading_complete);
} }
int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
{ {
int ret; int ret;
@ -5683,7 +5683,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
} }
EXPORT_SYMBOL_GPL(wlcore_probe); EXPORT_SYMBOL_GPL(wlcore_probe);
int __devexit wlcore_remove(struct platform_device *pdev) int wlcore_remove(struct platform_device *pdev)
{ {
struct wl1271 *wl = platform_get_drvdata(pdev); struct wl1271 *wl = platform_get_drvdata(pdev);

View File

@ -54,7 +54,7 @@ struct wl12xx_sdio_glue {
struct platform_device *core; struct platform_device *core;
}; };
static const struct sdio_device_id wl1271_devices[] __devinitconst = { static const struct sdio_device_id wl1271_devices[] = {
{ SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
{} {}
}; };
@ -214,7 +214,7 @@ static struct wl1271_if_operations sdio_ops = {
.set_block_size = wl1271_sdio_set_block_size, .set_block_size = wl1271_sdio_set_block_size,
}; };
static int __devinit wl1271_probe(struct sdio_func *func, static int wl1271_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
struct wl12xx_platform_data *wlan_data; struct wl12xx_platform_data *wlan_data;
@ -319,7 +319,7 @@ out:
return ret; return ret;
} }
static void __devexit wl1271_remove(struct sdio_func *func) static void wl1271_remove(struct sdio_func *func)
{ {
struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
@ -384,7 +384,7 @@ static struct sdio_driver wl1271_sdio_driver = {
.name = "wl1271_sdio", .name = "wl1271_sdio",
.id_table = wl1271_devices, .id_table = wl1271_devices,
.probe = wl1271_probe, .probe = wl1271_probe,
.remove = __devexit_p(wl1271_remove), .remove = wl1271_remove,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.drv = { .drv = {
.pm = &wl1271_sdio_pm_ops, .pm = &wl1271_sdio_pm_ops,

View File

@ -324,7 +324,7 @@ static struct wl1271_if_operations spi_ops = {
.set_block_size = NULL, .set_block_size = NULL,
}; };
static int __devinit wl1271_probe(struct spi_device *spi) static int wl1271_probe(struct spi_device *spi)
{ {
struct wl12xx_spi_glue *glue; struct wl12xx_spi_glue *glue;
struct wl12xx_platform_data *pdata; struct wl12xx_platform_data *pdata;
@ -403,7 +403,7 @@ out:
return ret; return ret;
} }
static int __devexit wl1271_remove(struct spi_device *spi) static int wl1271_remove(struct spi_device *spi)
{ {
struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
@ -422,7 +422,7 @@ static struct spi_driver wl1271_spi_driver = {
}, },
.probe = wl1271_probe, .probe = wl1271_probe,
.remove = __devexit_p(wl1271_remove), .remove = wl1271_remove,
}; };
static int __init wl1271_init(void) static int __init wl1271_init(void)

View File

@ -414,8 +414,8 @@ struct wl1271 {
struct completion nvs_loading_complete; struct completion nvs_loading_complete;
}; };
int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
int __devexit wlcore_remove(struct platform_device *pdev); int wlcore_remove(struct platform_device *pdev);
struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size); struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size);
int wlcore_free_hw(struct wl1271 *wl); int wlcore_free_hw(struct wl1271 *wl);
int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,

View File

@ -4,6 +4,7 @@
* *
* Copyright 2005, Broadcom Corporation * Copyright 2005, Broadcom Corporation
* Copyright 2006, 2007, Michael Buesch <m@bues.ch> * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
* Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
* *
* Licensed under the GNU/GPL. See COPYING for details. * Licensed under the GNU/GPL. See COPYING for details.
*/ */
@ -12,6 +13,7 @@
#include <linux/ssb/ssb_regs.h> #include <linux/ssb/ssb_regs.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/bcm47xx_wdt.h>
#include "ssb_private.h" #include "ssb_private.h"
@ -280,6 +282,69 @@ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
cc->fast_pwrup_delay = tmp; cc->fast_pwrup_delay = tmp;
} }
static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc)
{
if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
return ssb_pmu_get_alp_clock(cc);
return 20000000;
}
static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)
{
u32 nb;
if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
if (cc->dev->id.revision < 26)
nb = 16;
else
nb = (cc->dev->id.revision >= 37) ? 32 : 24;
} else {
nb = 28;
}
if (nb == 32)
return 0xffffffff;
else
return (1 << nb) - 1;
}
u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
{
struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
return 0;
return ssb_chipco_watchdog_timer_set(cc, ticks);
}
u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
{
struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
u32 ticks;
if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
return 0;
ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
return ticks / cc->ticks_per_ms;
}
static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
/* based on 32KHz ILP clock */
return 32;
} else {
if (cc->dev->id.revision < 18)
return ssb_clockspeed(bus) / 1000;
else
return ssb_chipco_alp_clock(cc) / 1000;
}
}
void ssb_chipcommon_init(struct ssb_chipcommon *cc) void ssb_chipcommon_init(struct ssb_chipcommon *cc)
{ {
if (!cc->dev) if (!cc->dev)
@ -297,6 +362,11 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
chipco_powercontrol_init(cc); chipco_powercontrol_init(cc);
ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
calc_fast_powerup_delay(cc); calc_fast_powerup_delay(cc);
if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {
cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);
cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
}
} }
void ssb_chipco_suspend(struct ssb_chipcommon *cc) void ssb_chipco_suspend(struct ssb_chipcommon *cc)
@ -395,10 +465,27 @@ void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
} }
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
{ {
/* instant NMI */ u32 maxt;
chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); enum ssb_clkmode clkmode;
maxt = ssb_chipco_watchdog_get_max_timer(cc);
if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
if (ticks == 1)
ticks = 2;
else if (ticks > maxt)
ticks = maxt;
chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);
} else {
clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;
ssb_chipco_set_clockmode(cc, clkmode);
if (ticks > maxt)
ticks = maxt;
/* instant NMI */
chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
}
return ticks;
} }
void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)
@ -473,12 +560,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
chipco_read32(cc, SSB_CHIPCO_CORECTL) chipco_read32(cc, SSB_CHIPCO_CORECTL)
| SSB_CHIPCO_CORECTL_UARTCLK0); | SSB_CHIPCO_CORECTL_UARTCLK0);
} else if ((ccrev >= 11) && (ccrev != 15)) { } else if ((ccrev >= 11) && (ccrev != 15)) {
/* Fixed ALP clock */ baud_base = ssb_chipco_alp_clock(cc);
baud_base = 20000000;
if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
/* FIXME: baud_base is different for devices with a PMU */
SSB_WARN_ON(1);
}
div = 1; div = 1;
if (ccrev >= 21) { if (ccrev >= 21) {
/* Turn off UART clock before switching clocksource. */ /* Turn off UART clock before switching clocksource. */

View File

@ -618,6 +618,33 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc)
{
u32 crystalfreq;
const struct pmu0_plltab_entry *e = NULL;
crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) &
SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT;
e = pmu0_plltab_find_entry(crystalfreq);
BUG_ON(!e);
return e->freq * 1000;
}
u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc)
{
struct ssb_bus *bus = cc->dev->bus;
switch (bus->chip_id) {
case 0x5354:
ssb_pmu_get_alp_clock_clk0(cc);
default:
ssb_printk(KERN_ERR PFX
"ERROR: PMU alp clock unknown for device %04X\n",
bus->chip_id);
return 0;
}
}
u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
{ {
struct ssb_bus *bus = cc->dev->bus; struct ssb_bus *bus = cc->dev->bus;

View File

@ -112,10 +112,30 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
*m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
} }
void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
u32 ticks)
{ {
struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
return ssb_extif_watchdog_timer_set(extif, ticks);
}
u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
{
struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms;
ticks = ssb_extif_watchdog_timer_set(extif, ticks);
return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK;
}
u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
{
if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER)
ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER;
extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
return ticks;
} }
u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)

View File

@ -178,9 +178,9 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
{ {
struct ssb_bus *bus = mcore->dev->bus; struct ssb_bus *bus = mcore->dev->bus;
if (bus->extif.dev) if (ssb_extif_available(&bus->extif))
mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
else if (bus->chipco.dev) else if (ssb_chipco_available(&bus->chipco))
mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports); mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
else else
mcore->nr_serial_ports = 0; mcore->nr_serial_ports = 0;
@ -191,7 +191,7 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
struct ssb_bus *bus = mcore->dev->bus; struct ssb_bus *bus = mcore->dev->bus;
/* When there is no chipcommon on the bus there is 4MB flash */ /* When there is no chipcommon on the bus there is 4MB flash */
if (!bus->chipco.dev) { if (!ssb_chipco_available(&bus->chipco)) {
mcore->pflash.present = true; mcore->pflash.present = true;
mcore->pflash.buswidth = 2; mcore->pflash.buswidth = 2;
mcore->pflash.window = SSB_FLASH1; mcore->pflash.window = SSB_FLASH1;
@ -227,9 +227,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
return ssb_pmu_get_cpu_clock(&bus->chipco); return ssb_pmu_get_cpu_clock(&bus->chipco);
if (bus->extif.dev) { if (ssb_extif_available(&bus->extif)) {
ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
} else if (bus->chipco.dev) { } else if (ssb_chipco_available(&bus->chipco)) {
ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
} else } else
return 0; return 0;
@ -265,9 +265,9 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
hz = 100000000; hz = 100000000;
ns = 1000000000 / hz; ns = 1000000000 / hz;
if (bus->extif.dev) if (ssb_extif_available(&bus->extif))
ssb_extif_timing_init(&bus->extif, ns); ssb_extif_timing_init(&bus->extif, ns);
else if (bus->chipco.dev) else if (ssb_chipco_available(&bus->chipco))
ssb_chipco_timing_init(&bus->chipco, ns); ssb_chipco_timing_init(&bus->chipco, ns);
/* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */

View File

@ -4,11 +4,13 @@
* *
* Copyright 2005-2008, Broadcom Corporation * Copyright 2005-2008, Broadcom Corporation
* Copyright 2006-2008, Michael Buesch <m@bues.ch> * Copyright 2006-2008, Michael Buesch <m@bues.ch>
* Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
* *
* Licensed under the GNU/GPL. See COPYING for details. * Licensed under the GNU/GPL. See COPYING for details.
*/ */
#include <linux/export.h> #include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/ssb/ssb.h> #include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_embedded.h> #include <linux/ssb/ssb_embedded.h>
#include <linux/ssb/ssb_driver_pci.h> #include <linux/ssb/ssb_driver_pci.h>
@ -32,6 +34,39 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks)
} }
EXPORT_SYMBOL(ssb_watchdog_timer_set); EXPORT_SYMBOL(ssb_watchdog_timer_set);
int ssb_watchdog_register(struct ssb_bus *bus)
{
struct bcm47xx_wdt wdt = {};
struct platform_device *pdev;
if (ssb_chipco_available(&bus->chipco)) {
wdt.driver_data = &bus->chipco;
wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms;
wdt.max_timer_ms = bus->chipco.max_timer_ms;
} else if (ssb_extif_available(&bus->extif)) {
wdt.driver_data = &bus->extif;
wdt.timer_set = ssb_extif_watchdog_timer_set_wdt;
wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms;
wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS;
} else {
return -ENODEV;
}
pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
bus->busnumber, &wdt,
sizeof(wdt));
if (IS_ERR(pdev)) {
ssb_dprintk(KERN_INFO PFX
"can not register watchdog device, err: %li\n",
PTR_ERR(pdev));
return PTR_ERR(pdev);
}
bus->watchdog = pdev;
return 0;
}
u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
{ {
unsigned long flags; unsigned long flags;

View File

@ -13,6 +13,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/ssb/ssb.h> #include <linux/ssb/ssb.h>
#include <linux/ssb/ssb_regs.h> #include <linux/ssb/ssb_regs.h>
#include <linux/ssb/ssb_driver_gige.h> #include <linux/ssb/ssb_driver_gige.h>
@ -433,6 +434,11 @@ static void ssb_devices_unregister(struct ssb_bus *bus)
if (sdev->dev) if (sdev->dev)
device_unregister(sdev->dev); device_unregister(sdev->dev);
} }
#ifdef CONFIG_SSB_EMBEDDED
if (bus->bustype == SSB_BUSTYPE_SSB)
platform_device_unregister(bus->watchdog);
#endif
} }
void ssb_bus_unregister(struct ssb_bus *bus) void ssb_bus_unregister(struct ssb_bus *bus)
@ -561,6 +567,8 @@ static int __devinit ssb_attach_queued_buses(void)
if (err) if (err)
goto error; goto error;
ssb_pcicore_init(&bus->pcicore); ssb_pcicore_init(&bus->pcicore);
if (bus->bustype == SSB_BUSTYPE_SSB)
ssb_watchdog_register(bus);
ssb_bus_may_powerdown(bus); ssb_bus_may_powerdown(bus);
err = ssb_devices_register(bus); err = ssb_devices_register(bus);

View File

@ -3,6 +3,7 @@
#include <linux/ssb/ssb.h> #include <linux/ssb/ssb.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/bcm47xx_wdt.h>
#define PFX "ssb: " #define PFX "ssb: "
@ -210,5 +211,35 @@ static inline void b43_pci_ssb_bridge_exit(void)
/* driver_chipcommon_pmu.c */ /* driver_chipcommon_pmu.c */
extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc);
extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
u32 ticks);
extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
#ifdef CONFIG_SSB_DRIVER_EXTIF
extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
#else
static inline u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
u32 ticks)
{
return 0;
}
static inline u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt,
u32 ms)
{
return 0;
}
#endif
#ifdef CONFIG_SSB_EMBEDDED
extern int ssb_watchdog_register(struct ssb_bus *bus);
#else /* CONFIG_SSB_EMBEDDED */
static inline int ssb_watchdog_register(struct ssb_bus *bus)
{
return 0;
}
#endif /* CONFIG_SSB_EMBEDDED */
#endif /* LINUX_SSB_PRIVATE_H_ */ #endif /* LINUX_SSB_PRIVATE_H_ */

Some files were not shown because too many files have changed in this diff Show More