mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
This commit is contained in:
commit
9f6e20cee6
@ -18,6 +18,9 @@ void bcma_bus_unregister(struct bcma_bus *bus);
|
||||
int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
struct bcma_device *core_cc,
|
||||
struct bcma_device *core_mips);
|
||||
#ifdef CONFIG_PM
|
||||
int bcma_bus_resume(struct bcma_bus *bus);
|
||||
#endif
|
||||
|
||||
/* scan.c */
|
||||
int bcma_bus_scan(struct bcma_bus *bus);
|
||||
|
@ -234,6 +234,41 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
|
||||
pci_set_drvdata(dev, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
|
||||
{
|
||||
/* Host specific */
|
||||
pci_save_state(dev);
|
||||
pci_disable_device(dev);
|
||||
pci_set_power_state(dev, pci_choose_state(dev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bcma_host_pci_resume(struct pci_dev *dev)
|
||||
{
|
||||
struct bcma_bus *bus = pci_get_drvdata(dev);
|
||||
int err;
|
||||
|
||||
/* Host specific */
|
||||
pci_set_power_state(dev, 0);
|
||||
err = pci_enable_device(dev);
|
||||
if (err)
|
||||
return err;
|
||||
pci_restore_state(dev);
|
||||
|
||||
/* Bus specific */
|
||||
err = bcma_bus_resume(bus);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* CONFIG_PM */
|
||||
# define bcma_host_pci_suspend NULL
|
||||
# define bcma_host_pci_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
|
||||
@ -249,6 +284,8 @@ static struct pci_driver bcma_pci_bridge_driver = {
|
||||
.id_table = bcma_pci_bridge_tbl,
|
||||
.probe = bcma_host_pci_probe,
|
||||
.remove = bcma_host_pci_remove,
|
||||
.suspend = bcma_host_pci_suspend,
|
||||
.resume = bcma_host_pci_resume,
|
||||
};
|
||||
|
||||
int __init bcma_host_pci_init(void)
|
||||
|
@ -240,6 +240,22 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
int bcma_bus_resume(struct bcma_bus *bus)
|
||||
{
|
||||
struct bcma_device *core;
|
||||
|
||||
/* Init CC core */
|
||||
core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
|
||||
if (core) {
|
||||
bus->drv_cc.setup_done = false;
|
||||
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
|
||||
{
|
||||
drv->drv.name = drv->name;
|
||||
|
@ -129,6 +129,9 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
||||
u16 v;
|
||||
int i;
|
||||
|
||||
bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
|
||||
SSB_SPROM_REVISION_REV;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
|
||||
*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
|
||||
@ -136,12 +139,70 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
||||
|
||||
bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
|
||||
|
||||
bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
|
||||
SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
|
||||
bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
|
||||
SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
|
||||
bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
|
||||
SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
|
||||
bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
|
||||
SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
|
||||
|
||||
bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
|
||||
SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
|
||||
bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
|
||||
SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
|
||||
bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
|
||||
SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
|
||||
bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
|
||||
SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
|
||||
|
||||
bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
|
||||
SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
|
||||
bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
|
||||
SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
|
||||
bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
|
||||
SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
|
||||
bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
|
||||
SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
|
||||
|
||||
bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
|
||||
SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
|
||||
bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
|
||||
SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
|
||||
bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
|
||||
SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
|
||||
bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
|
||||
SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
|
||||
|
||||
bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
|
||||
bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
|
||||
bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
|
||||
bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
|
||||
|
||||
bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
|
||||
|
||||
bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
|
||||
SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
|
||||
bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
|
||||
SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
|
||||
bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
|
||||
SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
|
||||
bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
|
||||
SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
|
||||
bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
|
||||
SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
|
||||
|
||||
bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
|
||||
SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
|
||||
bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
|
||||
SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
|
||||
bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
|
||||
SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
|
||||
bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
|
||||
SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
|
||||
bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
|
||||
SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
|
||||
}
|
||||
|
||||
int bcma_sprom_get(struct bcma_bus *bus)
|
||||
|
@ -152,6 +152,7 @@ struct ath_common {
|
||||
struct ath_cycle_counters cc_survey;
|
||||
|
||||
struct ath_regulatory regulatory;
|
||||
struct ath_regulatory reg_world_copy;
|
||||
const struct ath_ops *ops;
|
||||
const struct ath_bus_ops *bus_ops;
|
||||
|
||||
@ -214,6 +215,10 @@ do { \
|
||||
* @ATH_DBG_HWTIMER: hardware timer handling
|
||||
* @ATH_DBG_BTCOEX: bluetooth coexistance
|
||||
* @ATH_DBG_BSTUCK: stuck beacons
|
||||
* @ATH_DBG_MCI: Message Coexistence Interface, a private protocol
|
||||
* used exclusively for WLAN-BT coexistence starting from
|
||||
* AR9462.
|
||||
* @ATH_DBG_DFS: radar datection
|
||||
* @ATH_DBG_ANY: enable all debugging
|
||||
*
|
||||
* The debug level is used to control the amount and type of debugging output
|
||||
@ -240,6 +245,7 @@ enum ATH_DEBUG {
|
||||
ATH_DBG_WMI = 0x00004000,
|
||||
ATH_DBG_BSTUCK = 0x00008000,
|
||||
ATH_DBG_MCI = 0x00010000,
|
||||
ATH_DBG_DFS = 0x00020000,
|
||||
ATH_DBG_ANY = 0xffffffff
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,9 @@ config ATH9K_HW
|
||||
tristate
|
||||
config ATH9K_COMMON
|
||||
tristate
|
||||
config ATH9K_DFS_DEBUGFS
|
||||
def_bool y
|
||||
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
|
||||
|
||||
config ATH9K
|
||||
tristate "Atheros 802.11n wireless cards support"
|
||||
@ -51,6 +54,25 @@ config ATH9K_DEBUGFS
|
||||
|
||||
Also required for changing debug message flags at run time.
|
||||
|
||||
config ATH9K_DFS_CERTIFIED
|
||||
bool "Atheros DFS support for certified platforms"
|
||||
depends on ATH9K && EXPERT
|
||||
default n
|
||||
---help---
|
||||
This option enables DFS support for initiating radiation on
|
||||
ath9k. There is no way to dynamically detect if a card was DFS
|
||||
certified and as such this is left as a build time option. This
|
||||
option should only be enabled by system integrators that can
|
||||
guarantee that all the platforms that their kernel will run on
|
||||
have obtained appropriate regulatory body certification for a
|
||||
respective Atheros card by using ath9k on the target shipping
|
||||
platforms.
|
||||
|
||||
This is currently only a placeholder for future DFS support,
|
||||
as DFS support requires more components that still need to be
|
||||
developed. At this point enabling this option won't do anything
|
||||
except increase code size.
|
||||
|
||||
config ATH9K_RATE_CONTROL
|
||||
bool "Atheros ath9k rate control"
|
||||
depends on ATH9K
|
||||
|
@ -10,6 +10,8 @@ ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
|
||||
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
|
||||
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
|
||||
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
|
||||
|
||||
obj-$(CONFIG_ATH9K) += ath9k.o
|
||||
|
||||
|
@ -187,40 +187,12 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
isr = REG_READ(ah, AR_ISR);
|
||||
}
|
||||
|
||||
if (async_cause & AR_INTR_ASYNC_MASK_MCI) {
|
||||
u32 raw_intr, rx_msg_intr;
|
||||
|
||||
rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
|
||||
raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
|
||||
|
||||
if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef))
|
||||
ath_dbg(common, ATH_DBG_MCI,
|
||||
"MCI gets 0xdeadbeef during MCI int processing"
|
||||
"new raw_intr=0x%08x, new rx_msg_raw=0x%08x, "
|
||||
"raw_intr=0x%08x, rx_msg_raw=0x%08x\n",
|
||||
raw_intr, rx_msg_intr, mci->raw_intr,
|
||||
mci->rx_msg_intr);
|
||||
else {
|
||||
mci->rx_msg_intr |= rx_msg_intr;
|
||||
mci->raw_intr |= raw_intr;
|
||||
*masked |= ATH9K_INT_MCI;
|
||||
|
||||
if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
|
||||
mci->cont_status =
|
||||
REG_READ(ah, AR_MCI_CONT_STATUS);
|
||||
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
|
||||
ath_dbg(common, ATH_DBG_MCI, "AR_INTR_SYNC_MCI\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
|
||||
|
||||
*masked = 0;
|
||||
|
||||
if (!isr && !sync_cause)
|
||||
if (!isr && !sync_cause && !async_cause)
|
||||
return false;
|
||||
|
||||
if (isr) {
|
||||
@ -326,6 +298,35 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
ar9003_hw_bb_watchdog_read(ah);
|
||||
}
|
||||
|
||||
if (async_cause & AR_INTR_ASYNC_MASK_MCI) {
|
||||
u32 raw_intr, rx_msg_intr;
|
||||
|
||||
rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
|
||||
raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
|
||||
|
||||
if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef))
|
||||
ath_dbg(common, ATH_DBG_MCI,
|
||||
"MCI gets 0xdeadbeef during MCI int processing"
|
||||
"new raw_intr=0x%08x, new rx_msg_raw=0x%08x, "
|
||||
"raw_intr=0x%08x, rx_msg_raw=0x%08x\n",
|
||||
raw_intr, rx_msg_intr, mci->raw_intr,
|
||||
mci->rx_msg_intr);
|
||||
else {
|
||||
mci->rx_msg_intr |= rx_msg_intr;
|
||||
mci->raw_intr |= raw_intr;
|
||||
*masked |= ATH9K_INT_MCI;
|
||||
|
||||
if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
|
||||
mci->cont_status =
|
||||
REG_READ(ah, AR_MCI_CONT_STATUS);
|
||||
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
|
||||
ath_dbg(common, ATH_DBG_MCI, "AR_INTR_SYNC_MCI\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (sync_cause) {
|
||||
if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
|
||||
REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
|
||||
|
@ -159,6 +159,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
/* return block-ack bitmap index given sequence and starting sequence */
|
||||
#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
|
||||
|
||||
/* return the seqno for _start + _offset */
|
||||
#define ATH_BA_INDEX2SEQ(_seq, _offset) (((_seq) + (_offset)) & (IEEE80211_SEQ_MAX - 1))
|
||||
|
||||
/* returns delimiter padding required given the packet length */
|
||||
#define ATH_AGGR_GET_NDELIM(_len) \
|
||||
(((_len) >= ATH_AGGR_MINPLEN) ? 0 : \
|
||||
@ -238,6 +241,7 @@ struct ath_atx_tid {
|
||||
struct ath_node *an;
|
||||
struct ath_atx_ac *ac;
|
||||
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
|
||||
int bar_index;
|
||||
u16 seq_start;
|
||||
u16 seq_next;
|
||||
u16 baw_size;
|
||||
@ -252,9 +256,9 @@ struct ath_atx_tid {
|
||||
struct ath_node {
|
||||
#ifdef CONFIG_ATH9K_DEBUGFS
|
||||
struct list_head list; /* for sc->nodes */
|
||||
#endif
|
||||
struct ieee80211_sta *sta; /* station struct we're part of */
|
||||
struct ieee80211_vif *vif; /* interface with which we're associated */
|
||||
#endif
|
||||
struct ath_atx_tid tid[WME_NUM_TID];
|
||||
struct ath_atx_ac ac[WME_NUM_AC];
|
||||
int ps_key;
|
||||
@ -276,7 +280,6 @@ struct ath_tx_control {
|
||||
};
|
||||
|
||||
#define ATH_TX_ERROR 0x01
|
||||
#define ATH_TX_BAR 0x02
|
||||
|
||||
/**
|
||||
* @txq_map: Index is mac80211 queue number. This is
|
||||
@ -542,7 +545,7 @@ struct ath_ant_comb {
|
||||
#define DEFAULT_CACHELINE 32
|
||||
#define ATH_REGCLASSIDS_MAX 10
|
||||
#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
|
||||
#define ATH_MAX_SW_RETRIES 10
|
||||
#define ATH_MAX_SW_RETRIES 30
|
||||
#define ATH_CHAN_MAX 255
|
||||
|
||||
#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
|
||||
|
@ -856,7 +856,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
|
||||
|
||||
if (bf_isampdu(bf)) {
|
||||
if (flags & ATH_TX_BAR)
|
||||
if (flags & ATH_TX_ERROR)
|
||||
TX_STAT_INC(qnum, a_xretries);
|
||||
else
|
||||
TX_STAT_INC(qnum, a_completed);
|
||||
@ -1630,6 +1630,9 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
sc, &fops_debug);
|
||||
#endif
|
||||
|
||||
ath9k_dfs_init_debug(sc);
|
||||
|
||||
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
&fops_dma);
|
||||
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "hw.h"
|
||||
#include "rc.h"
|
||||
#include "dfs_debug.h"
|
||||
|
||||
struct ath_txq;
|
||||
struct ath_buf;
|
||||
@ -187,6 +188,7 @@ struct ath_stats {
|
||||
struct ath_interrupt_stats istats;
|
||||
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
|
||||
struct ath_rx_stats rxstats;
|
||||
struct ath_dfs_stats dfs_stats;
|
||||
u32 reset[__RESET_TYPE_MAX];
|
||||
};
|
||||
|
||||
|
215
drivers/net/wireless/ath/ath9k/dfs.c
Normal file
215
drivers/net/wireless/ath/ath9k/dfs.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Neratec Solutions AG
|
||||
*
|
||||
* 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 "hw.h"
|
||||
#include "hw-ops.h"
|
||||
#include "ath9k.h"
|
||||
#include "dfs.h"
|
||||
#include "dfs_debug.h"
|
||||
|
||||
/*
|
||||
* TODO: move into or synchronize this with generic header
|
||||
* as soon as IF is defined
|
||||
*/
|
||||
struct dfs_radar_pulse {
|
||||
u16 freq;
|
||||
u64 ts;
|
||||
u32 width;
|
||||
u8 rssi;
|
||||
};
|
||||
|
||||
/* internal struct to pass radar data */
|
||||
struct ath_radar_data {
|
||||
u8 pulse_bw_info;
|
||||
u8 rssi;
|
||||
u8 ext_rssi;
|
||||
u8 pulse_length_ext;
|
||||
u8 pulse_length_pri;
|
||||
};
|
||||
|
||||
/* convert pulse duration to usecs, considering clock mode */
|
||||
static u32 dur_to_usecs(struct ath_hw *ah, u32 dur)
|
||||
{
|
||||
const u32 AR93X_NSECS_PER_DUR = 800;
|
||||
const u32 AR93X_NSECS_PER_DUR_FAST = (8000 / 11);
|
||||
u32 nsecs;
|
||||
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, ah->curchan))
|
||||
nsecs = dur * AR93X_NSECS_PER_DUR_FAST;
|
||||
else
|
||||
nsecs = dur * AR93X_NSECS_PER_DUR;
|
||||
|
||||
return (nsecs + 500) / 1000;
|
||||
}
|
||||
|
||||
#define PRI_CH_RADAR_FOUND 0x01
|
||||
#define EXT_CH_RADAR_FOUND 0x02
|
||||
static bool
|
||||
ath9k_postprocess_radar_event(struct ath_softc *sc,
|
||||
struct ath_radar_data *are,
|
||||
struct dfs_radar_pulse *drp)
|
||||
{
|
||||
u8 rssi;
|
||||
u16 dur;
|
||||
|
||||
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_DFS,
|
||||
"pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n",
|
||||
are->pulse_bw_info,
|
||||
are->pulse_length_pri, are->rssi,
|
||||
are->pulse_length_ext, are->ext_rssi);
|
||||
|
||||
/*
|
||||
* Only the last 2 bits of the BW info are relevant, they indicate
|
||||
* which channel the radar was detected in.
|
||||
*/
|
||||
are->pulse_bw_info &= 0x03;
|
||||
|
||||
switch (are->pulse_bw_info) {
|
||||
case PRI_CH_RADAR_FOUND:
|
||||
/* radar in ctrl channel */
|
||||
dur = are->pulse_length_pri;
|
||||
DFS_STAT_INC(sc, pri_phy_errors);
|
||||
/*
|
||||
* cannot use ctrl channel RSSI
|
||||
* if extension channel is stronger
|
||||
*/
|
||||
rssi = (are->ext_rssi >= (are->rssi + 3)) ? 0 : are->rssi;
|
||||
break;
|
||||
case EXT_CH_RADAR_FOUND:
|
||||
/* radar in extension channel */
|
||||
dur = are->pulse_length_ext;
|
||||
DFS_STAT_INC(sc, ext_phy_errors);
|
||||
/*
|
||||
* cannot use extension channel RSSI
|
||||
* if control channel is stronger
|
||||
*/
|
||||
rssi = (are->rssi >= (are->ext_rssi + 12)) ? 0 : are->ext_rssi;
|
||||
break;
|
||||
case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
|
||||
/*
|
||||
* Conducted testing, when pulse is on DC, both pri and ext
|
||||
* durations are reported to be same
|
||||
*
|
||||
* Radiated testing, when pulse is on DC, different pri and
|
||||
* ext durations are reported, so take the larger of the two
|
||||
*/
|
||||
if (are->pulse_length_ext >= are->pulse_length_pri)
|
||||
dur = are->pulse_length_ext;
|
||||
else
|
||||
dur = are->pulse_length_pri;
|
||||
DFS_STAT_INC(sc, dc_phy_errors);
|
||||
|
||||
/* when both are present use stronger one */
|
||||
rssi = (are->rssi < are->ext_rssi) ? are->ext_rssi : are->rssi;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Bogus bandwidth info was received in descriptor,
|
||||
* so ignore this PHY error
|
||||
*/
|
||||
DFS_STAT_INC(sc, bwinfo_discards);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rssi == 0) {
|
||||
DFS_STAT_INC(sc, rssi_discards);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: check chirping pulses
|
||||
* checks for chirping are dependent on the DFS regulatory domain
|
||||
* used, which is yet TBD
|
||||
*/
|
||||
|
||||
/* convert duration to usecs */
|
||||
drp->width = dur_to_usecs(sc->sc_ah, dur);
|
||||
drp->rssi = rssi;
|
||||
|
||||
DFS_STAT_INC(sc, pulses_detected);
|
||||
return true;
|
||||
}
|
||||
#undef PRI_CH_RADAR_FOUND
|
||||
#undef EXT_CH_RADAR_FOUND
|
||||
|
||||
/*
|
||||
* DFS: check PHY-error for radar pulse and feed the detector
|
||||
*/
|
||||
void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
|
||||
struct ath_rx_status *rs, u64 mactime)
|
||||
{
|
||||
struct ath_radar_data ard;
|
||||
u16 datalen;
|
||||
char *vdata_end;
|
||||
struct dfs_radar_pulse drp;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if ((!(rs->rs_phyerr != ATH9K_PHYERR_RADAR)) &&
|
||||
(!(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT))) {
|
||||
ath_dbg(common, ATH_DBG_DFS,
|
||||
"Error: rs_phyer=0x%x not a radar error\n",
|
||||
rs->rs_phyerr);
|
||||
return;
|
||||
}
|
||||
|
||||
datalen = rs->rs_datalen;
|
||||
if (datalen == 0) {
|
||||
DFS_STAT_INC(sc, datalen_discards);
|
||||
return;
|
||||
}
|
||||
|
||||
ard.rssi = rs->rs_rssi_ctl0;
|
||||
ard.ext_rssi = rs->rs_rssi_ext0;
|
||||
|
||||
/*
|
||||
* hardware stores this as 8 bit signed value.
|
||||
* we will cap it at 0 if it is a negative number
|
||||
*/
|
||||
if (ard.rssi & 0x80)
|
||||
ard.rssi = 0;
|
||||
if (ard.ext_rssi & 0x80)
|
||||
ard.ext_rssi = 0;
|
||||
|
||||
vdata_end = (char *)data + datalen;
|
||||
ard.pulse_bw_info = vdata_end[-1];
|
||||
ard.pulse_length_ext = vdata_end[-2];
|
||||
ard.pulse_length_pri = vdata_end[-3];
|
||||
|
||||
ath_dbg(common, ATH_DBG_DFS,
|
||||
"bw_info=%d, length_pri=%d, length_ext=%d, "
|
||||
"rssi_pri=%d, rssi_ext=%d\n",
|
||||
ard.pulse_bw_info, ard.pulse_length_pri, ard.pulse_length_ext,
|
||||
ard.rssi, ard.ext_rssi);
|
||||
|
||||
drp.freq = ah->curchan->channel;
|
||||
drp.ts = mactime;
|
||||
if (ath9k_postprocess_radar_event(sc, &ard, &drp)) {
|
||||
static u64 last_ts;
|
||||
ath_dbg(common, ATH_DBG_DFS,
|
||||
"ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
|
||||
"width=%d, rssi=%d, delta_ts=%llu\n",
|
||||
drp.freq, drp.ts, drp.width, drp.rssi, drp.ts-last_ts);
|
||||
last_ts = drp.ts;
|
||||
/*
|
||||
* TODO: forward pulse to pattern detector
|
||||
*
|
||||
* ieee80211_add_radar_pulse(drp.freq, drp.ts,
|
||||
* drp.width, drp.rssi);
|
||||
*/
|
||||
}
|
||||
}
|
43
drivers/net/wireless/ath/ath9k/dfs.h
Normal file
43
drivers/net/wireless/ath/ath9k/dfs.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Neratec Solutions AG
|
||||
*
|
||||
* 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 ATH9K_DFS_H
|
||||
#define ATH9K_DFS_H
|
||||
|
||||
#if defined(CONFIG_ATH9K_DFS_CERTIFIED)
|
||||
/**
|
||||
* ath9k_dfs_process_phyerr - process radar PHY error
|
||||
* @sc: ath_softc
|
||||
* @data: RX payload data
|
||||
* @rs: RX status after processing descriptor
|
||||
* @mactime: receive time
|
||||
*
|
||||
* This function is called whenever the HW DFS module detects a radar
|
||||
* pulse and reports it as a PHY error.
|
||||
*
|
||||
* The radar information provided as raw payload data is validated and
|
||||
* filtered for false pulses. Events passing all tests are forwarded to
|
||||
* the upper layer for pattern detection.
|
||||
*/
|
||||
void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
|
||||
struct ath_rx_status *rs, u64 mactime);
|
||||
#else
|
||||
static inline void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
|
||||
struct ath_rx_status *rs, u64 mactime) { }
|
||||
#endif
|
||||
|
||||
#endif /* ATH9K_DFS_H */
|
81
drivers/net/wireless/ath/ath9k/dfs_debug.c
Normal file
81
drivers/net/wireless/ath/ath9k/dfs_debug.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Neratec Solutions AG
|
||||
*
|
||||
* 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/export.h>
|
||||
|
||||
#include "ath9k.h"
|
||||
#include "dfs_debug.h"
|
||||
|
||||
#define ATH9K_DFS_STAT(s, p) \
|
||||
len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
|
||||
sc->debug.stats.dfs_stats.p);
|
||||
|
||||
static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath9k_hw_version *hw_ver = &sc->sc_ah->hw_version;
|
||||
char *buf;
|
||||
unsigned int len = 0, size = 8000;
|
||||
ssize_t retval = 0;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
len += snprintf(buf + len, size - len, "DFS support for "
|
||||
"macVersion = 0x%x, macRev = 0x%x: %s\n",
|
||||
hw_ver->macVersion, hw_ver->macRev,
|
||||
(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ?
|
||||
"enabled" : "disabled");
|
||||
ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected);
|
||||
ATH9K_DFS_STAT("Datalen discards ", datalen_discards);
|
||||
ATH9K_DFS_STAT("RSSI discards ", rssi_discards);
|
||||
ATH9K_DFS_STAT("BW info discards ", bwinfo_discards);
|
||||
ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors);
|
||||
ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors);
|
||||
ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ath9k_dfs_debugfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_dfs_stats = {
|
||||
.read = read_file_dfs,
|
||||
.open = ath9k_dfs_debugfs_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void ath9k_dfs_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
debugfs_create_file("dfs_stats", S_IRUSR,
|
||||
sc->debug.debugfs_phy, sc, &fops_dfs_stats);
|
||||
}
|
57
drivers/net/wireless/ath/ath9k/dfs_debug.h
Normal file
57
drivers/net/wireless/ath/ath9k/dfs_debug.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011 Neratec Solutions AG
|
||||
*
|
||||
* 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 DFS_DEBUG_H
|
||||
#define DFS_DEBUG_H
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
/**
|
||||
* struct ath_dfs_stats - DFS Statistics
|
||||
*
|
||||
* @pulses_detected: No. of pulses detected so far
|
||||
* @datalen_discards: No. of pulses discarded due to invalid datalen
|
||||
* @rssi_discards: No. of pulses discarded due to invalid RSSI
|
||||
* @bwinfo_discards: No. of pulses discarded due to invalid BW info
|
||||
* @pri_phy_errors: No. of pulses reported for primary channel
|
||||
* @ext_phy_errors: No. of pulses reported for extension channel
|
||||
* @dc_phy_errors: No. of pulses reported for primary + extension channel
|
||||
*/
|
||||
struct ath_dfs_stats {
|
||||
u32 pulses_detected;
|
||||
u32 datalen_discards;
|
||||
u32 rssi_discards;
|
||||
u32 bwinfo_discards;
|
||||
u32 pri_phy_errors;
|
||||
u32 ext_phy_errors;
|
||||
u32 dc_phy_errors;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ATH9K_DFS_DEBUGFS)
|
||||
|
||||
#define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++)
|
||||
void ath9k_dfs_init_debug(struct ath_softc *sc);
|
||||
|
||||
#else
|
||||
|
||||
#define DFS_STAT_INC(sc, c) do { } while (0)
|
||||
static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { }
|
||||
|
||||
#endif /* CONFIG_ATH9K_DFS_DEBUGFS */
|
||||
|
||||
#endif /* DFS_DEBUG_H */
|
@ -212,4 +212,13 @@ static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
|
||||
return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
|
||||
ini_reloaded);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_radar_params(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_private_ops(ah)->set_radar_params)
|
||||
return;
|
||||
|
||||
ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf);
|
||||
}
|
||||
|
||||
#endif /* ATH9K_HW_OPS_H */
|
||||
|
@ -2277,6 +2277,30 @@ static u8 fixup_chainmask(u8 chip_chainmask, u8 eeprom_chainmask)
|
||||
return chip_chainmask;
|
||||
}
|
||||
|
||||
/**
|
||||
* ath9k_hw_dfs_tested - checks if DFS has been tested with used chipset
|
||||
* @ah: the atheros hardware data structure
|
||||
*
|
||||
* We enable DFS support upstream on chipsets which have passed a series
|
||||
* of tests. The testing requirements are going to be documented. Desired
|
||||
* test requirements are documented at:
|
||||
*
|
||||
* http://wireless.kernel.org/en/users/Drivers/ath9k/dfs
|
||||
*
|
||||
* Once a new chipset gets properly tested an individual commit can be used
|
||||
* to document the testing for DFS for that chipset.
|
||||
*/
|
||||
static bool ath9k_hw_dfs_tested(struct ath_hw *ah)
|
||||
{
|
||||
|
||||
switch (ah->hw_version.macVersion) {
|
||||
/* AR9580 will likely be our first target to get testing on */
|
||||
case AR_SREV_VERSION_9580:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
{
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
@ -2375,12 +2399,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
else
|
||||
pCap->num_gpio_pins = AR_NUM_GPIO;
|
||||
|
||||
if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_CST;
|
||||
if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah))
|
||||
pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
|
||||
} else {
|
||||
else
|
||||
pCap->rts_aggr_limit = (8 * 1024);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
|
||||
ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
|
||||
@ -2490,6 +2512,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
pCap->pcie_lcr_offset = 0x80;
|
||||
}
|
||||
|
||||
if (ath9k_hw_dfs_tested(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_DFS;
|
||||
|
||||
tx_chainmask = pCap->tx_chainmask;
|
||||
rx_chainmask = pCap->rx_chainmask;
|
||||
while (tx_chainmask || rx_chainmask) {
|
||||
|
@ -196,21 +196,21 @@ enum ath_ini_subsys {
|
||||
enum ath9k_hw_caps {
|
||||
ATH9K_HW_CAP_HT = BIT(0),
|
||||
ATH9K_HW_CAP_RFSILENT = BIT(1),
|
||||
ATH9K_HW_CAP_CST = BIT(2),
|
||||
ATH9K_HW_CAP_AUTOSLEEP = BIT(4),
|
||||
ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5),
|
||||
ATH9K_HW_CAP_EDMA = BIT(6),
|
||||
ATH9K_HW_CAP_RAC_SUPPORTED = BIT(7),
|
||||
ATH9K_HW_CAP_LDPC = BIT(8),
|
||||
ATH9K_HW_CAP_FASTCLOCK = BIT(9),
|
||||
ATH9K_HW_CAP_SGI_20 = BIT(10),
|
||||
ATH9K_HW_CAP_PAPRD = BIT(11),
|
||||
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12),
|
||||
ATH9K_HW_CAP_2GHZ = BIT(13),
|
||||
ATH9K_HW_CAP_5GHZ = BIT(14),
|
||||
ATH9K_HW_CAP_APM = BIT(15),
|
||||
ATH9K_HW_CAP_RTT = BIT(16),
|
||||
ATH9K_HW_CAP_MCI = BIT(17),
|
||||
ATH9K_HW_CAP_AUTOSLEEP = BIT(2),
|
||||
ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(3),
|
||||
ATH9K_HW_CAP_EDMA = BIT(4),
|
||||
ATH9K_HW_CAP_RAC_SUPPORTED = BIT(5),
|
||||
ATH9K_HW_CAP_LDPC = BIT(6),
|
||||
ATH9K_HW_CAP_FASTCLOCK = BIT(7),
|
||||
ATH9K_HW_CAP_SGI_20 = BIT(8),
|
||||
ATH9K_HW_CAP_PAPRD = BIT(9),
|
||||
ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10),
|
||||
ATH9K_HW_CAP_2GHZ = BIT(11),
|
||||
ATH9K_HW_CAP_5GHZ = BIT(12),
|
||||
ATH9K_HW_CAP_APM = BIT(13),
|
||||
ATH9K_HW_CAP_RTT = BIT(14),
|
||||
ATH9K_HW_CAP_MCI = BIT(15),
|
||||
ATH9K_HW_CAP_DFS = BIT(16),
|
||||
};
|
||||
|
||||
struct ath9k_hw_capabilities {
|
||||
|
@ -297,9 +297,22 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
int ret;
|
||||
|
||||
return ath_reg_notifier_apply(wiphy, request, reg);
|
||||
ret = ath_reg_notifier_apply(wiphy, request, reg);
|
||||
|
||||
/* Set tx power */
|
||||
if (ah->curchan) {
|
||||
sc->config.txpowlimit = 2 * ah->curchan->chan->max_power;
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false);
|
||||
sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -644,9 +644,9 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
spin_lock(&sc->nodes_lock);
|
||||
list_add(&an->list, &sc->nodes);
|
||||
spin_unlock(&sc->nodes_lock);
|
||||
#endif
|
||||
an->sta = sta;
|
||||
an->vif = vif;
|
||||
#endif
|
||||
if (sc->sc_flags & SC_OP_TXAGGR) {
|
||||
ath_tx_node_init(sc, an);
|
||||
an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
@ -1873,7 +1873,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
|
||||
if (ath9k_modparam_nohwcrypt)
|
||||
return -ENOSPC;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_ADHOC &&
|
||||
if ((vif->type == NL80211_IFTYPE_ADHOC ||
|
||||
vif->type == NL80211_IFTYPE_MESH_POINT) &&
|
||||
(key->cipher == WLAN_CIPHER_SUITE_TKIP ||
|
||||
key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
|
||||
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
|
||||
|
@ -234,8 +234,8 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
|
||||
}
|
||||
}
|
||||
|
||||
void ath_mci_process_profile(struct ath_softc *sc,
|
||||
struct ath_mci_profile_info *info)
|
||||
static void ath_mci_process_profile(struct ath_softc *sc,
|
||||
struct ath_mci_profile_info *info)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
@ -261,8 +261,8 @@ void ath_mci_process_profile(struct ath_softc *sc,
|
||||
ath_mci_update_scheme(sc);
|
||||
}
|
||||
|
||||
void ath_mci_process_status(struct ath_softc *sc,
|
||||
struct ath_mci_profile_status *status)
|
||||
static void ath_mci_process_status(struct ath_softc *sc,
|
||||
struct ath_mci_profile_status *status)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
|
@ -128,10 +128,6 @@ struct ath_mci_coex {
|
||||
};
|
||||
|
||||
void ath_mci_flush_profile(struct ath_mci_profile *mci);
|
||||
void ath_mci_process_profile(struct ath_softc *sc,
|
||||
struct ath_mci_profile_info *info);
|
||||
void ath_mci_process_status(struct ath_softc *sc,
|
||||
struct ath_mci_profile_status *status);
|
||||
int ath_mci_setup(struct ath_softc *sc);
|
||||
void ath_mci_cleanup(struct ath_softc *sc);
|
||||
void ath_mci_intr(struct ath_softc *sc);
|
||||
|
@ -1271,7 +1271,9 @@ static void ath_rc_init(struct ath_softc *sc,
|
||||
|
||||
ath_rc_priv->max_valid_rate = k;
|
||||
ath_rc_sort_validrates(rate_table, ath_rc_priv);
|
||||
ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
|
||||
ath_rc_priv->rate_max_phy = (k > 4) ?
|
||||
ath_rc_priv->valid_rate_index[k-4] :
|
||||
ath_rc_priv->valid_rate_index[k-1];
|
||||
ath_rc_priv->rate_table = rate_table;
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
|
@ -1823,6 +1823,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
hdr = (struct ieee80211_hdr *) (hdr_skb->data + rx_status_len);
|
||||
rxs = IEEE80211_SKB_RXCB(hdr_skb);
|
||||
if (ieee80211_is_beacon(hdr->frame_control) &&
|
||||
!is_zero_ether_addr(common->curbssid) &&
|
||||
!compare_ether_addr(hdr->addr3, common->curbssid))
|
||||
rs.is_mybeacon = true;
|
||||
else
|
||||
|
@ -53,7 +53,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
int tx_flags, struct ath_txq *txq);
|
||||
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_txq *txq, struct list_head *bf_q,
|
||||
struct ath_tx_status *ts, int txok, int sendbar);
|
||||
struct ath_tx_status *ts, int txok);
|
||||
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *head, bool internal);
|
||||
static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
@ -150,6 +150,12 @@ static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
|
||||
return (struct ath_frame_info *) &tx_info->rate_driver_data[0];
|
||||
}
|
||||
|
||||
static void ath_send_bar(struct ath_atx_tid *tid, u16 seqno)
|
||||
{
|
||||
ieee80211_send_bar(tid->an->vif, tid->an->sta->addr, tid->tidno,
|
||||
seqno << IEEE80211_SEQ_SEQ_SHIFT);
|
||||
}
|
||||
|
||||
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_txq *txq = tid->ac->txq;
|
||||
@ -158,25 +164,24 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
struct list_head bf_head;
|
||||
struct ath_tx_status ts;
|
||||
struct ath_frame_info *fi;
|
||||
bool sendbar = false;
|
||||
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
while ((skb = __skb_dequeue(&tid->buf_q))) {
|
||||
fi = get_frame_info(skb);
|
||||
bf = fi->bf;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (bf && fi->retries) {
|
||||
list_add_tail(&bf->list, &bf_head);
|
||||
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 1);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||
sendbar = true;
|
||||
} else {
|
||||
ath_tx_send_normal(sc, txq, NULL, skb);
|
||||
}
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
if (tid->baw_head == tid->baw_tail) {
|
||||
@ -184,7 +189,8 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
|
||||
tid->state &= ~AGGR_CLEANUP;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (sendbar)
|
||||
ath_send_bar(tid, tid->seq_start);
|
||||
}
|
||||
|
||||
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
@ -200,6 +206,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) {
|
||||
INCR(tid->seq_start, IEEE80211_SEQ_MAX);
|
||||
INCR(tid->baw_head, ATH_TID_MAX_BUFS);
|
||||
if (tid->bar_index >= 0)
|
||||
tid->bar_index--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,9 +251,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf = fi->bf;
|
||||
|
||||
if (!bf) {
|
||||
spin_unlock(&txq->axq_lock);
|
||||
ath_tx_complete(sc, skb, ATH_TX_ERROR, txq);
|
||||
spin_lock(&txq->axq_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -254,24 +260,26 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (fi->retries)
|
||||
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
|
||||
|
||||
spin_unlock(&txq->axq_lock);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
|
||||
spin_lock(&txq->axq_lock);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||
}
|
||||
|
||||
tid->seq_next = tid->seq_start;
|
||||
tid->baw_tail = tid->baw_head;
|
||||
tid->bar_index = -1;
|
||||
}
|
||||
|
||||
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb, int count)
|
||||
{
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
struct ath_buf *bf = fi->bf;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int prev = fi->retries;
|
||||
|
||||
TX_STAT_INC(txq->axq_qnum, a_retries);
|
||||
if (fi->retries++ > 0)
|
||||
fi->retries += count;
|
||||
|
||||
if (prev > 0)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
@ -370,7 +378,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
|
||||
struct list_head bf_head;
|
||||
struct sk_buff_head bf_pending;
|
||||
u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
|
||||
u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
|
||||
u32 ba[WME_BA_BMP_SIZE >> 5];
|
||||
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
|
||||
bool rc_update = true;
|
||||
@ -379,6 +387,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
int nframes;
|
||||
u8 tidno;
|
||||
bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
|
||||
int i, retries;
|
||||
int bar_index = -1;
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
@ -387,6 +397,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
memcpy(rates, tx_info->control.rates, sizeof(rates));
|
||||
|
||||
retries = ts->ts_longretry + 1;
|
||||
for (i = 0; i < ts->ts_rateindex; i++)
|
||||
retries += rates[i].count;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
|
||||
@ -400,8 +414,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (!bf->bf_stale || bf_next != NULL)
|
||||
list_move_tail(&bf->list, &bf_head);
|
||||
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||
0, 0);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0);
|
||||
|
||||
bf = bf_next;
|
||||
}
|
||||
@ -411,6 +424,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
|
||||
tid = ATH_AN_2_TID(an, tidno);
|
||||
seq_first = tid->seq_start;
|
||||
|
||||
/*
|
||||
* The hardware occasionally sends a tx status for the wrong TID.
|
||||
@ -460,25 +474,25 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
} else if (!isaggr && txok) {
|
||||
/* transmit completion */
|
||||
acked_cnt++;
|
||||
} else {
|
||||
if ((tid->state & AGGR_CLEANUP) || !retry) {
|
||||
/*
|
||||
* cleanup in progress, just fail
|
||||
* the un-acked sub-frames
|
||||
*/
|
||||
txfail = 1;
|
||||
} else if (flush) {
|
||||
txpending = 1;
|
||||
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
|
||||
if (txok || !an->sleeping)
|
||||
ath_tx_set_retry(sc, txq, bf->bf_mpdu);
|
||||
} else if ((tid->state & AGGR_CLEANUP) || !retry) {
|
||||
/*
|
||||
* cleanup in progress, just fail
|
||||
* the un-acked sub-frames
|
||||
*/
|
||||
txfail = 1;
|
||||
} else if (flush) {
|
||||
txpending = 1;
|
||||
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
|
||||
if (txok || !an->sleeping)
|
||||
ath_tx_set_retry(sc, txq, bf->bf_mpdu,
|
||||
retries);
|
||||
|
||||
txpending = 1;
|
||||
} else {
|
||||
txfail = 1;
|
||||
sendbar = 1;
|
||||
txfail_cnt++;
|
||||
}
|
||||
txpending = 1;
|
||||
} else {
|
||||
txfail = 1;
|
||||
txfail_cnt++;
|
||||
bar_index = max_t(int, bar_index,
|
||||
ATH_BA_INDEX(seq_first, seqno));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -495,9 +509,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
* complete the acked-ones/xretried ones; update
|
||||
* block-ack window
|
||||
*/
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_tx_update_baw(sc, tid, seqno);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
|
||||
memcpy(tx_info->control.rates, rates, sizeof(rates));
|
||||
@ -506,33 +518,30 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
}
|
||||
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||
!txfail, sendbar);
|
||||
!txfail);
|
||||
} else {
|
||||
/* retry the un-acked ones */
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
|
||||
if (bf->bf_next == NULL && bf_last->bf_stale) {
|
||||
struct ath_buf *tbf;
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) &&
|
||||
bf->bf_next == NULL && bf_last->bf_stale) {
|
||||
struct ath_buf *tbf;
|
||||
|
||||
tbf = ath_clone_txbuf(sc, bf_last);
|
||||
/*
|
||||
* Update tx baw and complete the
|
||||
* frame with failed status if we
|
||||
* run out of tx buf.
|
||||
*/
|
||||
if (!tbf) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_tx_update_baw(sc, tid, seqno);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
tbf = ath_clone_txbuf(sc, bf_last);
|
||||
/*
|
||||
* Update tx baw and complete the
|
||||
* frame with failed status if we
|
||||
* run out of tx buf.
|
||||
*/
|
||||
if (!tbf) {
|
||||
ath_tx_update_baw(sc, tid, seqno);
|
||||
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head,
|
||||
ts, 0,
|
||||
!flush);
|
||||
break;
|
||||
}
|
||||
|
||||
fi->bf = tbf;
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head, ts, 0);
|
||||
bar_index = max_t(int, bar_index,
|
||||
ATH_BA_INDEX(seq_first, seqno));
|
||||
break;
|
||||
}
|
||||
|
||||
fi->bf = tbf;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -545,12 +554,18 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf = bf_next;
|
||||
}
|
||||
|
||||
if (bar_index >= 0) {
|
||||
u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index);
|
||||
ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1));
|
||||
if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq))
|
||||
tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq);
|
||||
}
|
||||
|
||||
/* prepend un-acked frames to the beginning of the pending frame queue */
|
||||
if (!skb_queue_empty(&bf_pending)) {
|
||||
if (an->sleeping)
|
||||
ieee80211_sta_set_buffered(sta, tid->tidno, true);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
skb_queue_splice(&bf_pending, &tid->buf_q);
|
||||
if (!an->sleeping) {
|
||||
ath_tx_queue_tid(txq, tid);
|
||||
@ -558,7 +573,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
tid->ac->clear_ps_filter = true;
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
if (tid->state & AGGR_CLEANUP)
|
||||
@ -617,24 +631,26 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
|
||||
max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (rates[i].count) {
|
||||
int modeidx;
|
||||
if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) {
|
||||
legacy = 1;
|
||||
break;
|
||||
}
|
||||
int modeidx;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
modeidx = MCS_HT40;
|
||||
else
|
||||
modeidx = MCS_HT20;
|
||||
if (!rates[i].count)
|
||||
continue;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
modeidx++;
|
||||
|
||||
frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
|
||||
max_4ms_framelen = min(max_4ms_framelen, frmlen);
|
||||
if (!(rates[i].flags & IEEE80211_TX_RC_MCS)) {
|
||||
legacy = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
modeidx = MCS_HT40;
|
||||
else
|
||||
modeidx = MCS_HT20;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
modeidx++;
|
||||
|
||||
frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
|
||||
max_4ms_framelen = min(max_4ms_framelen, frmlen);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -770,8 +786,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
|
||||
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
|
||||
seqno = bf->bf_state.seqno;
|
||||
if (!bf_first)
|
||||
bf_first = bf;
|
||||
|
||||
/* do not step over block-ack window */
|
||||
if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
|
||||
@ -779,6 +793,21 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
break;
|
||||
}
|
||||
|
||||
if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
|
||||
struct ath_tx_status ts = {};
|
||||
struct list_head bf_head;
|
||||
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
list_add(&bf->list, &bf_head);
|
||||
__skb_unlink(skb, &tid->buf_q);
|
||||
ath_tx_update_baw(sc, tid, seqno);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!bf_first)
|
||||
bf_first = bf;
|
||||
|
||||
if (!rl) {
|
||||
aggr_limit = ath_lookup_rate(sc, bf, tid);
|
||||
rl = 1;
|
||||
@ -1121,6 +1150,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
txtid->state |= AGGR_ADDBA_PROGRESS;
|
||||
txtid->paused = true;
|
||||
*ssn = txtid->seq_start = txtid->seq_next;
|
||||
txtid->bar_index = -1;
|
||||
|
||||
memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf));
|
||||
txtid->baw_head = txtid->baw_tail = 0;
|
||||
@ -1155,9 +1185,9 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
|
||||
txtid->state |= AGGR_CLEANUP;
|
||||
else
|
||||
txtid->state &= ~AGGR_ADDBA_COMPLETE;
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
ath_tx_flush_tid(sc, txtid);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
|
||||
@ -1399,8 +1429,6 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
|
||||
|
||||
static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *list, bool retry_tx)
|
||||
__releases(txq->axq_lock)
|
||||
__acquires(txq->axq_lock)
|
||||
{
|
||||
struct ath_buf *bf, *lastbf;
|
||||
struct list_head bf_head;
|
||||
@ -1427,13 +1455,11 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
if (bf_isampdu(bf))
|
||||
ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0,
|
||||
retry_tx);
|
||||
else
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1560,11 +1586,9 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!list_empty(&ac->tid_q)) {
|
||||
if (!ac->sched) {
|
||||
ac->sched = true;
|
||||
list_add_tail(&ac->list, &txq->axq_acq);
|
||||
}
|
||||
if (!list_empty(&ac->tid_q) && !ac->sched) {
|
||||
ac->sched = true;
|
||||
list_add_tail(&ac->list, &txq->axq_acq);
|
||||
}
|
||||
|
||||
if (ac == last_ac ||
|
||||
@ -1707,10 +1731,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
||||
list_add_tail(&bf->list, &bf_head);
|
||||
bf->bf_state.bf_type = 0;
|
||||
|
||||
/* update starting sequence number for subsequent ADDBA request */
|
||||
if (tid)
|
||||
INCR(tid->seq_start, IEEE80211_SEQ_MAX);
|
||||
|
||||
bf->bf_lastbf = bf;
|
||||
ath_tx_fill_desc(sc, bf, txq, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_head, false);
|
||||
@ -1818,7 +1838,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
|
||||
struct ath_buf *bf;
|
||||
u8 tidno;
|
||||
|
||||
spin_lock_bh(&txctl->txq->axq_lock);
|
||||
if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an &&
|
||||
ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
tidno = ieee80211_get_qos_ctl(hdr)[0] &
|
||||
@ -1837,7 +1856,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
|
||||
} else {
|
||||
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
|
||||
if (!bf)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
bf->bf_state.bfs_paprd = txctl->paprd;
|
||||
|
||||
@ -1846,9 +1865,6 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
ath_tx_send_normal(sc, txctl->txq, tid, skb);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&txctl->txq->axq_lock);
|
||||
}
|
||||
|
||||
/* Upon failure caller should free skb */
|
||||
@ -1915,9 +1931,11 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
ieee80211_stop_queue(sc->hw, q);
|
||||
txq->stopped = 1;
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
ath_tx_start_dma(sc, skb, txctl);
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1936,9 +1954,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
ath_dbg(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
|
||||
|
||||
if (tx_flags & ATH_TX_BAR)
|
||||
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||
|
||||
if (!(tx_flags & ATH_TX_ERROR))
|
||||
/* Frame was ACKed */
|
||||
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
@ -1966,7 +1981,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
q = skb_get_queue_mapping(skb);
|
||||
if (txq == sc->tx.txq_map[q]) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (WARN_ON(--txq->pending_frames < 0))
|
||||
txq->pending_frames = 0;
|
||||
|
||||
@ -1974,7 +1988,6 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
ieee80211_wake_queue(sc->hw, q);
|
||||
txq->stopped = 0;
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
ieee80211_tx_status(hw, skb);
|
||||
@ -1982,16 +1995,13 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_txq *txq, struct list_head *bf_q,
|
||||
struct ath_tx_status *ts, int txok, int sendbar)
|
||||
struct ath_tx_status *ts, int txok)
|
||||
{
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
unsigned long flags;
|
||||
int tx_flags = 0;
|
||||
|
||||
if (sendbar)
|
||||
tx_flags = ATH_TX_BAR;
|
||||
|
||||
if (!txok)
|
||||
tx_flags |= ATH_TX_ERROR;
|
||||
|
||||
@ -2083,8 +2093,6 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_tx_status *ts, struct ath_buf *bf,
|
||||
struct list_head *bf_head)
|
||||
__releases(txq->axq_lock)
|
||||
__acquires(txq->axq_lock)
|
||||
{
|
||||
int txok;
|
||||
|
||||
@ -2094,16 +2102,12 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (bf_is_ampdu_not_probing(bf))
|
||||
txq->axq_ampdu_depth--;
|
||||
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
|
||||
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
|
||||
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
|
||||
} else
|
||||
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
ath_txq_schedule(sc, txq);
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "regd.h"
|
||||
#include "regd_common.h"
|
||||
|
||||
static int __ath_regd_init(struct ath_regulatory *reg);
|
||||
|
||||
/*
|
||||
* This is a set of common rules used by our world regulatory domains.
|
||||
* We have 12 world regulatory domains. To save space we consolidate
|
||||
@ -347,10 +349,26 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ath_regd_find_country_by_name(char *alpha2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
|
||||
if (!memcmp(allCountries[i].isoName, alpha2, 2))
|
||||
return allCountries[i].countryCode;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ath_reg_notifier_apply(struct wiphy *wiphy,
|
||||
struct regulatory_request *request,
|
||||
struct ath_regulatory *reg)
|
||||
{
|
||||
struct ath_common *common = container_of(reg, struct ath_common,
|
||||
regulatory);
|
||||
u16 country_code;
|
||||
|
||||
/* We always apply this */
|
||||
ath_reg_apply_radar_flags(wiphy);
|
||||
|
||||
@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy,
|
||||
return 0;
|
||||
|
||||
switch (request->initiator) {
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
case NL80211_REGDOM_SET_BY_CORE:
|
||||
/*
|
||||
* If common->reg_world_copy is world roaming it means we *were*
|
||||
* world roaming... so we now have to restore that data.
|
||||
*/
|
||||
if (!ath_is_world_regd(&common->reg_world_copy))
|
||||
break;
|
||||
|
||||
memcpy(reg, &common->reg_world_copy,
|
||||
sizeof(struct ath_regulatory));
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
if (ath_is_world_regd(reg))
|
||||
ath_reg_apply_world_flags(wiphy, request->initiator,
|
||||
reg);
|
||||
if (!ath_is_world_regd(reg))
|
||||
break;
|
||||
|
||||
country_code = ath_regd_find_country_by_name(request->alpha2);
|
||||
if (country_code == (u16) -1)
|
||||
break;
|
||||
|
||||
reg->current_rd = COUNTRY_ERD_FLAG;
|
||||
reg->current_rd |= country_code;
|
||||
|
||||
printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n",
|
||||
reg->current_rd);
|
||||
__ath_regd_init(reg);
|
||||
|
||||
ath_reg_apply_world_flags(wiphy, request->initiator, reg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -508,11 +549,7 @@ static void ath_regd_sanitize(struct ath_regulatory *reg)
|
||||
reg->current_rd = 0x64;
|
||||
}
|
||||
|
||||
int
|
||||
ath_regd_init(struct ath_regulatory *reg,
|
||||
struct wiphy *wiphy,
|
||||
int (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request))
|
||||
static int __ath_regd_init(struct ath_regulatory *reg)
|
||||
{
|
||||
struct country_code_to_enum_rd *country = NULL;
|
||||
u16 regdmn;
|
||||
@ -583,7 +620,29 @@ ath_regd_init(struct ath_regulatory *reg,
|
||||
printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
|
||||
reg->regpair->regDmnEnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ath_regd_init(struct ath_regulatory *reg,
|
||||
struct wiphy *wiphy,
|
||||
int (*reg_notifier)(struct wiphy *wiphy,
|
||||
struct regulatory_request *request))
|
||||
{
|
||||
struct ath_common *common = container_of(reg, struct ath_common,
|
||||
regulatory);
|
||||
int r;
|
||||
|
||||
r = __ath_regd_init(reg);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (ath_is_world_regd(reg))
|
||||
memcpy(&common->reg_world_copy, reg,
|
||||
sizeof(struct ath_regulatory));
|
||||
|
||||
ath_regd_init_wiphy(reg, wiphy, reg_notifier);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath_regd_init);
|
||||
|
@ -228,10 +228,98 @@ static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
|
||||
static void b43_radio_2056_setup(struct b43_wldev *dev,
|
||||
const struct b43_nphy_channeltab_entry_rev3 *e)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
enum ieee80211_band band = b43_current_band(dev->wl);
|
||||
u16 offset;
|
||||
u8 i;
|
||||
u16 bias, cbias, pag_boost, pgag_boost, mixg_boost, padg_boost;
|
||||
|
||||
B43_WARN_ON(dev->phy.rev < 3);
|
||||
|
||||
b43_chantab_radio_2056_upload(dev, e);
|
||||
/* TODO */
|
||||
b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ);
|
||||
|
||||
if (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
|
||||
if (dev->dev->chip_id == 0x4716) {
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0);
|
||||
} else {
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x0B);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14);
|
||||
}
|
||||
}
|
||||
if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x05);
|
||||
b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x0C);
|
||||
}
|
||||
|
||||
if (dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
offset = i ? B2056_TX1 : B2056_TX0;
|
||||
if (dev->phy.rev >= 5) {
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_PADG_IDAC, 0xcc);
|
||||
|
||||
if (dev->dev->chip_id == 0x4716) {
|
||||
bias = 0x40;
|
||||
cbias = 0x45;
|
||||
pag_boost = 0x5;
|
||||
pgag_boost = 0x33;
|
||||
mixg_boost = 0x55;
|
||||
} else {
|
||||
bias = 0x25;
|
||||
cbias = 0x20;
|
||||
pag_boost = 0x4;
|
||||
pgag_boost = 0x03;
|
||||
mixg_boost = 0x65;
|
||||
}
|
||||
padg_boost = 0x77;
|
||||
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_IMAIN_STAT,
|
||||
bias);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_IAUX_STAT,
|
||||
bias);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_CASCBIAS,
|
||||
cbias);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_BOOST_TUNE,
|
||||
pag_boost);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_PGAG_BOOST_TUNE,
|
||||
pgag_boost);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_PADG_BOOST_TUNE,
|
||||
padg_boost);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_MIXG_BOOST_TUNE,
|
||||
mixg_boost);
|
||||
} else {
|
||||
bias = dev->phy.is_40mhz ? 0x40 : 0x20;
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_IMAIN_STAT,
|
||||
bias);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_IAUX_STAT,
|
||||
bias);
|
||||
b43_radio_write(dev,
|
||||
offset | B2056_TX_INTPAG_CASCBIAS,
|
||||
0x30);
|
||||
}
|
||||
b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
|
||||
}
|
||||
} else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
udelay(50);
|
||||
/* VCO calibration */
|
||||
b43_radio_write(dev, B2056_SYN_PLL_VCOCAL12, 0x00);
|
||||
@ -387,7 +475,9 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 1);
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (dev->phy.rev >= 7) {
|
||||
txpi[0] = txpi[1] = 30;
|
||||
} else if (dev->phy.rev >= 3) {
|
||||
txpi[0] = 40;
|
||||
txpi[1] = 40;
|
||||
} else if (sprom->revision < 4) {
|
||||
@ -411,6 +501,9 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
txpi[1] = 91;
|
||||
}
|
||||
}
|
||||
if (dev->phy.rev < 7 &&
|
||||
(txpi[0] < 40 || txpi[0] > 100 || txpi[1] < 40 || txpi[1] > 10))
|
||||
txpi[0] = txpi[1] = 91;
|
||||
|
||||
/*
|
||||
for (i = 0; i < 2; i++) {
|
||||
@ -421,15 +514,31 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (dev->phy.rev >= 3) {
|
||||
/* FIXME: support 5GHz */
|
||||
txgain = b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
txgain = *(b43_nphy_get_ipa_gain_table(dev) +
|
||||
txpi[i]);
|
||||
} else if (b43_current_band(dev->wl) ==
|
||||
IEEE80211_BAND_5GHZ) {
|
||||
/* FIXME: use 5GHz tables */
|
||||
txgain =
|
||||
b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
|
||||
} else {
|
||||
if (dev->phy.rev >= 5 &&
|
||||
sprom->fem.ghz5.extpa_gain == 3)
|
||||
; /* FIXME: 5GHz_txgain_HiPwrEPA */
|
||||
txgain =
|
||||
b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]];
|
||||
}
|
||||
radio_gain = (txgain >> 16) & 0x1FFFF;
|
||||
} else {
|
||||
txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]];
|
||||
radio_gain = (txgain >> 16) & 0x1FFF;
|
||||
}
|
||||
|
||||
dac_gain = (txgain >> 8) & 0x3F;
|
||||
if (dev->phy.rev >= 7)
|
||||
dac_gain = (txgain >> 8) & 0x7;
|
||||
else
|
||||
dac_gain = (txgain >> 8) & 0x3F;
|
||||
bbmult = txgain & 0xFF;
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
@ -459,7 +568,8 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
u32 tmp32;
|
||||
u16 reg = (i == 0) ?
|
||||
B43_NPHY_PAPD_EN0 : B43_NPHY_PAPD_EN1;
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(26 + i, txpi[i]));
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(26 + i,
|
||||
576 + txpi[i]));
|
||||
b43_phy_maskset(dev, reg, 0xE00F, (u32) tmp32 << 4);
|
||||
b43_phy_set(dev, reg, 0x4);
|
||||
}
|
||||
@ -1493,8 +1603,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
/* TX to RX */
|
||||
u8 tx2rx_events[9] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F };
|
||||
u8 tx2rx_delays[9] = { 8, 4, 2, 2, 4, 4, 6, 1 };
|
||||
u8 tx2rx_events[8] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F };
|
||||
u8 tx2rx_delays[8] = { 8, 4, 2, 2, 4, 4, 6, 1 };
|
||||
/* RX to TX */
|
||||
u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
|
||||
0x1F };
|
||||
@ -1505,6 +1615,9 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
u16 tmp16;
|
||||
u32 tmp32;
|
||||
|
||||
b43_phy_write(dev, 0x23f, 0x1f8);
|
||||
b43_phy_write(dev, 0x240, 0x1f8);
|
||||
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
|
||||
tmp32 &= 0xffffff;
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
|
||||
@ -1520,12 +1633,13 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, 0x2AE, 0x000C);
|
||||
|
||||
/* TX to RX */
|
||||
b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, 9);
|
||||
b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays,
|
||||
ARRAY_SIZE(tx2rx_events));
|
||||
|
||||
/* RX to TX */
|
||||
if (b43_nphy_ipa(dev))
|
||||
b43_nphy_set_rf_sequence(dev, 1, rx2tx_events_ipa,
|
||||
rx2tx_delays_ipa, 9);
|
||||
b43_nphy_set_rf_sequence(dev, 0, rx2tx_events_ipa,
|
||||
rx2tx_delays_ipa, ARRAY_SIZE(rx2tx_events_ipa));
|
||||
if (nphy->hw_phyrxchain != 3 &&
|
||||
nphy->hw_phyrxchain != nphy->hw_phytxchain) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
@ -1533,7 +1647,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
rx2tx_delays[6] = 1;
|
||||
rx2tx_events[7] = 0x1F;
|
||||
}
|
||||
b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, 9);
|
||||
b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays,
|
||||
ARRAY_SIZE(rx2tx_events));
|
||||
}
|
||||
|
||||
tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ?
|
||||
@ -1547,8 +1662,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
|
||||
b43_nphy_gain_ctrl_workarounds(dev);
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 0), 2);
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 16), 2);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0), 2);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 16), 2);
|
||||
|
||||
/* TODO */
|
||||
|
||||
@ -1560,6 +1675,8 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_CMFB_IDAC, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_CMFB_IDAC, 0x00);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
|
||||
@ -1584,18 +1701,18 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
0x70);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, 0x224, 0x039C);
|
||||
b43_phy_write(dev, 0x225, 0x0357);
|
||||
b43_phy_write(dev, 0x226, 0x0317);
|
||||
b43_phy_write(dev, 0x227, 0x02D7);
|
||||
b43_phy_write(dev, 0x228, 0x039C);
|
||||
b43_phy_write(dev, 0x229, 0x0357);
|
||||
b43_phy_write(dev, 0x22A, 0x0317);
|
||||
b43_phy_write(dev, 0x22B, 0x02D7);
|
||||
b43_phy_write(dev, 0x22C, 0x039C);
|
||||
b43_phy_write(dev, 0x22D, 0x0357);
|
||||
b43_phy_write(dev, 0x22E, 0x0317);
|
||||
b43_phy_write(dev, 0x22F, 0x02D7);
|
||||
b43_phy_write(dev, 0x224, 0x03eb);
|
||||
b43_phy_write(dev, 0x225, 0x03eb);
|
||||
b43_phy_write(dev, 0x226, 0x0341);
|
||||
b43_phy_write(dev, 0x227, 0x0341);
|
||||
b43_phy_write(dev, 0x228, 0x042b);
|
||||
b43_phy_write(dev, 0x229, 0x042b);
|
||||
b43_phy_write(dev, 0x22a, 0x0381);
|
||||
b43_phy_write(dev, 0x22b, 0x0381);
|
||||
b43_phy_write(dev, 0x22c, 0x042b);
|
||||
b43_phy_write(dev, 0x22d, 0x042b);
|
||||
b43_phy_write(dev, 0x22e, 0x0381);
|
||||
b43_phy_write(dev, 0x22f, 0x0381);
|
||||
}
|
||||
|
||||
static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
|
||||
@ -3928,6 +4045,76 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */
|
||||
static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
|
||||
{
|
||||
struct bcma_drv_cc *cc;
|
||||
u32 pmu_ctl;
|
||||
|
||||
switch (dev->dev->bus_type) {
|
||||
#ifdef CONFIG_B43_BCMA
|
||||
case B43_BUS_BCMA:
|
||||
cc = &dev->dev->bdev->bus->drv_cc;
|
||||
if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
|
||||
if (avoid) {
|
||||
bcma_chipco_pll_write(cc, 0x0, 0x11500010);
|
||||
bcma_chipco_pll_write(cc, 0x1, 0x000C0C06);
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x0F600a08);
|
||||
bcma_chipco_pll_write(cc, 0x3, 0x00000000);
|
||||
bcma_chipco_pll_write(cc, 0x4, 0x2001E920);
|
||||
bcma_chipco_pll_write(cc, 0x5, 0x88888815);
|
||||
} else {
|
||||
bcma_chipco_pll_write(cc, 0x0, 0x11100010);
|
||||
bcma_chipco_pll_write(cc, 0x1, 0x000c0c06);
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x03000a08);
|
||||
bcma_chipco_pll_write(cc, 0x3, 0x00000000);
|
||||
bcma_chipco_pll_write(cc, 0x4, 0x200005c0);
|
||||
bcma_chipco_pll_write(cc, 0x5, 0x88888815);
|
||||
}
|
||||
pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD;
|
||||
} else if (dev->dev->chip_id == 0x4716) {
|
||||
if (avoid) {
|
||||
bcma_chipco_pll_write(cc, 0x0, 0x11500060);
|
||||
bcma_chipco_pll_write(cc, 0x1, 0x080C0C06);
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x0F600000);
|
||||
bcma_chipco_pll_write(cc, 0x3, 0x00000000);
|
||||
bcma_chipco_pll_write(cc, 0x4, 0x2001E924);
|
||||
bcma_chipco_pll_write(cc, 0x5, 0x88888815);
|
||||
} else {
|
||||
bcma_chipco_pll_write(cc, 0x0, 0x11100060);
|
||||
bcma_chipco_pll_write(cc, 0x1, 0x080c0c06);
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x03000000);
|
||||
bcma_chipco_pll_write(cc, 0x3, 0x00000000);
|
||||
bcma_chipco_pll_write(cc, 0x4, 0x200005c0);
|
||||
bcma_chipco_pll_write(cc, 0x5, 0x88888815);
|
||||
}
|
||||
pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD |
|
||||
BCMA_CC_PMU_CTL_NOILPONW;
|
||||
} else if (dev->dev->chip_id == 0x4322 ||
|
||||
dev->dev->chip_id == 0x4340 ||
|
||||
dev->dev->chip_id == 0x4341) {
|
||||
bcma_chipco_pll_write(cc, 0x0, 0x11100070);
|
||||
bcma_chipco_pll_write(cc, 0x1, 0x1014140a);
|
||||
bcma_chipco_pll_write(cc, 0x5, 0x88888854);
|
||||
if (avoid)
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x05201828);
|
||||
else
|
||||
bcma_chipco_pll_write(cc, 0x2, 0x05001828);
|
||||
pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
bcma_cc_set32(cc, BCMA_CC_PMU_CTL, pmu_ctl);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_B43_SSB
|
||||
case B43_BUS_SSB:
|
||||
/* FIXME */
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
|
||||
static void b43_nphy_channel_setup(struct b43_wldev *dev,
|
||||
const struct b43_phy_n_sfo_cfg *e,
|
||||
@ -3935,6 +4122,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
int ch = new_channel->hw_value;
|
||||
|
||||
u16 old_band_5ghz;
|
||||
u32 tmp32;
|
||||
@ -3974,8 +4162,41 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
|
||||
|
||||
b43_nphy_tx_lp_fbw(dev);
|
||||
|
||||
if (dev->phy.rev >= 3 && 0) {
|
||||
/* TODO */
|
||||
if (dev->phy.rev >= 3 &&
|
||||
dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
|
||||
bool avoid = false;
|
||||
if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
|
||||
avoid = true;
|
||||
} else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
|
||||
if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
|
||||
avoid = true;
|
||||
} else { /* 40MHz */
|
||||
if (nphy->aband_spurwar_en &&
|
||||
(ch == 38 || ch == 102 || ch == 118))
|
||||
avoid = dev->dev->chip_id == 0x4716;
|
||||
}
|
||||
|
||||
b43_nphy_pmu_spur_avoid(dev, avoid);
|
||||
|
||||
if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
|
||||
dev->dev->chip_id == 43225) {
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
|
||||
avoid ? 0x5341 : 0x8889);
|
||||
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
|
||||
}
|
||||
|
||||
if (dev->phy.rev == 3 || dev->phy.rev == 4)
|
||||
; /* TODO: reset PLL */
|
||||
|
||||
if (avoid)
|
||||
b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
|
||||
else
|
||||
b43_phy_mask(dev, B43_NPHY_BBCFG,
|
||||
~B43_NPHY_BBCFG_RSTRX & 0xFFFF);
|
||||
|
||||
b43_nphy_reset_cca(dev);
|
||||
|
||||
/* wl sets useless phy_isspuravoid here */
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);
|
||||
@ -4055,10 +4276,13 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_n *nphy = phy->n;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
memset(nphy, 0, sizeof(*nphy));
|
||||
|
||||
nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);
|
||||
nphy->spur_avoid = (phy->rev >= 3) ?
|
||||
B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;
|
||||
nphy->gain_boost = true; /* this way we follow wl, assume it is true */
|
||||
nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
|
||||
nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
|
||||
@ -4067,6 +4291,38 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
|
||||
* 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */
|
||||
nphy->tx_pwr_idx[0] = 128;
|
||||
nphy->tx_pwr_idx[1] = 128;
|
||||
|
||||
/* Hardware TX power control and 5GHz power gain */
|
||||
nphy->txpwrctrl = false;
|
||||
nphy->pwg_gain_5ghz = false;
|
||||
if (dev->phy.rev >= 3 ||
|
||||
(dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
|
||||
(dev->dev->core_rev == 11 || dev->dev->core_rev == 12))) {
|
||||
nphy->txpwrctrl = true;
|
||||
nphy->pwg_gain_5ghz = true;
|
||||
} else if (sprom->revision >= 4) {
|
||||
if (dev->phy.rev >= 2 &&
|
||||
(sprom->boardflags2_lo & B43_BFL2_TXPWRCTRL_EN)) {
|
||||
nphy->txpwrctrl = true;
|
||||
#ifdef CONFIG_B43_SSB
|
||||
if (dev->dev->bus_type == B43_BUS_SSB &&
|
||||
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI) {
|
||||
struct pci_dev *pdev =
|
||||
dev->dev->sdev->bus->host_pci;
|
||||
if (pdev->device == 0x4328 ||
|
||||
pdev->device == 0x432a)
|
||||
nphy->pwg_gain_5ghz = true;
|
||||
}
|
||||
#endif
|
||||
} else if (sprom->boardflags2_lo & B43_BFL2_5G_PWRGAIN) {
|
||||
nphy->pwg_gain_5ghz = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;
|
||||
nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_nphy_op_free(struct b43_wldev *dev)
|
||||
|
@ -716,6 +716,12 @@
|
||||
|
||||
struct b43_wldev;
|
||||
|
||||
enum b43_nphy_spur_avoid {
|
||||
B43_SPUR_AVOID_DISABLE,
|
||||
B43_SPUR_AVOID_AUTO,
|
||||
B43_SPUR_AVOID_FORCE,
|
||||
};
|
||||
|
||||
struct b43_chanspec {
|
||||
u16 center_freq;
|
||||
enum nl80211_channel_type channel_type;
|
||||
@ -785,6 +791,7 @@ struct b43_phy_n {
|
||||
u16 mphase_txcal_bestcoeffs[11];
|
||||
|
||||
bool txpwrctrl;
|
||||
bool pwg_gain_5ghz;
|
||||
u8 tx_pwr_idx[2];
|
||||
u16 adj_pwr_tbl[84];
|
||||
u16 txcal_bbmult;
|
||||
@ -803,6 +810,7 @@ struct b43_phy_n {
|
||||
u16 classifier_state;
|
||||
u16 clip_state[2];
|
||||
|
||||
enum b43_nphy_spur_avoid spur_avoid;
|
||||
bool aband_spurwar_en;
|
||||
bool gband_spurwar_en;
|
||||
|
||||
|
@ -1572,14 +1572,14 @@ static const struct b2056_inittab_entry b2056_inittab_rev6_syn[] = {
|
||||
[B2056_SYN_PLL_XTAL5] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_XTAL6] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_REFDIV] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_PFD] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_PFD] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
|
||||
[B2056_SYN_PLL_CP1] = { .ghz5 = 0x000f, .ghz2 = 0x000f, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_CP2] = { .ghz5 = 0x0030, .ghz2 = 0x0030, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_CP2] = { .ghz5 = 0x003f, .ghz2 = 0x003f, UPLOAD, },
|
||||
[B2056_SYN_PLL_CP3] = { .ghz5 = 0x0032, .ghz2 = 0x0032, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x000d, .ghz2 = 0x000d, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER1] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER2] = { .ghz5 = 0x0006, .ghz2 = 0x0006, UPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER3] = { .ghz5 = 0x0004, .ghz2 = 0x0004, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER4] = { .ghz5 = 0x002b, .ghz2 = 0x002b, UPLOAD, },
|
||||
[B2056_SYN_PLL_LOOPFILTER5] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_MMD1] = { .ghz5 = 0x001c, .ghz2 = 0x001c, NOUPLOAD, },
|
||||
[B2056_SYN_PLL_MMD2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, },
|
||||
@ -9055,6 +9055,21 @@ void b2056_upload_inittabs(struct b43_wldev *dev,
|
||||
B2056_RX1, pts->rx, pts->rx_length);
|
||||
}
|
||||
|
||||
void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5)
|
||||
{
|
||||
struct b2056_inittabs_pts *pts;
|
||||
const struct b2056_inittab_entry *e;
|
||||
|
||||
if (dev->phy.rev >= ARRAY_SIZE(b2056_inittabs)) {
|
||||
B43_WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
pts = &b2056_inittabs[dev->phy.rev];
|
||||
e = &pts->syn[B2056_SYN_PLL_CP2];
|
||||
|
||||
b43_radio_write(dev, B2056_SYN_PLL_CP2, ghz5 ? e->ghz5 : e->ghz2);
|
||||
}
|
||||
|
||||
const struct b43_nphy_channeltab_entry_rev3 *
|
||||
b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq)
|
||||
{
|
||||
|
@ -1090,6 +1090,7 @@ struct b43_nphy_channeltab_entry_rev3 {
|
||||
|
||||
void b2056_upload_inittabs(struct b43_wldev *dev,
|
||||
bool ghz5, bool ignore_uploadflag);
|
||||
void b2056_upload_syn_pll_cp2(struct b43_wldev *dev, bool ghz5);
|
||||
|
||||
/* Get the NPHY Channel Switch Table entry for a channel.
|
||||
* Returns NULL on failure to find an entry. */
|
||||
|
@ -2171,6 +2171,48 @@ static const u16 b43_ntab_loftlt1_r3[] = {
|
||||
0x0000, 0x0000,
|
||||
};
|
||||
|
||||
/* volatile tables, PHY revision >= 3 */
|
||||
|
||||
/* indexed by antswctl2g */
|
||||
static const u16 b43_ntab_antswctl2g_r3[4][32] = {
|
||||
{
|
||||
0x0082, 0x0082, 0x0211, 0x0222, 0x0328,
|
||||
0x0000, 0x0000, 0x0000, 0x0144, 0x0000,
|
||||
0x0000, 0x0000, 0x0188, 0x0000, 0x0000,
|
||||
0x0000, 0x0082, 0x0082, 0x0211, 0x0222,
|
||||
0x0328, 0x0000, 0x0000, 0x0000, 0x0144,
|
||||
0x0000, 0x0000, 0x0000, 0x0188, 0x0000,
|
||||
0x0000, 0x0000,
|
||||
},
|
||||
{
|
||||
0x0022, 0x0022, 0x0011, 0x0022, 0x0022,
|
||||
0x0000, 0x0000, 0x0000, 0x0011, 0x0000,
|
||||
0x0000, 0x0000, 0x0022, 0x0000, 0x0000,
|
||||
0x0000, 0x0022, 0x0022, 0x0011, 0x0022,
|
||||
0x0022, 0x0000, 0x0000, 0x0000, 0x0011,
|
||||
0x0000, 0x0000, 0x0000, 0x0022, 0x0000,
|
||||
0x0000, 0x0000,
|
||||
},
|
||||
{
|
||||
0x0088, 0x0088, 0x0044, 0x0088, 0x0088,
|
||||
0x0000, 0x0000, 0x0000, 0x0044, 0x0000,
|
||||
0x0000, 0x0000, 0x0088, 0x0000, 0x0000,
|
||||
0x0000, 0x0088, 0x0088, 0x0044, 0x0088,
|
||||
0x0088, 0x0000, 0x0000, 0x0000, 0x0044,
|
||||
0x0000, 0x0000, 0x0000, 0x0088, 0x0000,
|
||||
0x0000, 0x0000,
|
||||
},
|
||||
{
|
||||
0x0022, 0x0022, 0x0011, 0x0022, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0011, 0x0000,
|
||||
0x0000, 0x0000, 0x0022, 0x0000, 0x0000,
|
||||
0x03cc, 0x0022, 0x0022, 0x0011, 0x0022,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0011,
|
||||
0x0000, 0x0000, 0x0000, 0x0022, 0x0000,
|
||||
0x0000, 0x03cc,
|
||||
}
|
||||
};
|
||||
|
||||
/* TX gain tables */
|
||||
const u32 b43_ntab_tx_gain_rev0_1_2[] = {
|
||||
0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
|
||||
@ -2652,7 +2694,7 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
|
||||
const s16 tbl_tx_filter_coef_rev4[7][15] = {
|
||||
{ -377, 137, -407, 208, -1527,
|
||||
956, 93, 186, 93, 230,
|
||||
-44, 230, 20, -191, 201 },
|
||||
-44, 230, 201, -191, 201 },
|
||||
{ -77, 20, -98, 49, -93,
|
||||
60, 56, 111, 56, 26,
|
||||
-5, 26, 34, -32, 34 },
|
||||
@ -2838,9 +2880,8 @@ u32 b43_ntab_read(struct b43_wldev *dev, u32 offset)
|
||||
break;
|
||||
case B43_NTAB_32BIT:
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
|
||||
value <<= 16;
|
||||
value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
value |= b43_phy_read(dev, B43_NPHY_TABLE_DATAHI) << 16;
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
@ -2864,6 +2905,12 @@ void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
|
||||
for (i = 0; i < nr_elements; i++) {
|
||||
/* Auto increment broken + caching issue on BCM43224? */
|
||||
if (dev->dev->chip_id == 43224 && dev->dev->chip_rev == 1) {
|
||||
b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset + i);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case B43_NTAB_8BIT:
|
||||
*data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF;
|
||||
@ -2874,9 +2921,10 @@ void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
data += 2;
|
||||
break;
|
||||
case B43_NTAB_32BIT:
|
||||
*((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI);
|
||||
*((u32 *)data) <<= 16;
|
||||
*((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
*((u32 *)data) =
|
||||
b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
*((u32 *)data) |=
|
||||
b43_phy_read(dev, B43_NPHY_TABLE_DATAHI) << 16;
|
||||
data += 4;
|
||||
break;
|
||||
default:
|
||||
@ -2932,6 +2980,13 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset);
|
||||
|
||||
for (i = 0; i < nr_elements; i++) {
|
||||
/* Auto increment broken + caching issue on BCM43224? */
|
||||
if ((offset >> 10) == 9 && dev->dev->chip_id == 43224 &&
|
||||
dev->dev->chip_rev == 1) {
|
||||
b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset + i);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case B43_NTAB_8BIT:
|
||||
value = *data;
|
||||
@ -2999,6 +3054,8 @@ void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
|
||||
} while (0)
|
||||
void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
/* Static tables */
|
||||
ntab_upload_r3(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
|
||||
ntab_upload_r3(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
|
||||
@ -3029,7 +3086,11 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
|
||||
ntab_upload_r3(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
|
||||
|
||||
/* Volatile tables */
|
||||
/* TODO */
|
||||
if (sprom->fem.ghz2.antswlut < ARRAY_SIZE(b43_ntab_antswctl2g_r3))
|
||||
ntab_upload_r3(dev, B43_NTAB_ANT_SW_CTL_R3,
|
||||
b43_ntab_antswctl2g_r3[sprom->fem.ghz2.antswlut]);
|
||||
else
|
||||
B43_WARN_ON(1);
|
||||
}
|
||||
|
||||
struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
|
||||
|
@ -126,26 +126,29 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
|
||||
#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
|
||||
#define B43_NTAB_C1_LOFEEDTH_SIZE 128
|
||||
|
||||
/* Volatile N-PHY tables, PHY revision >= 3 */
|
||||
#define B43_NTAB_ANT_SW_CTL_R3 B43_NTAB16( 9, 0) /* antenna software control */
|
||||
|
||||
/* Static N-PHY tables, PHY revision >= 3 */
|
||||
#define B43_NTAB_FRAMESTRUCT_R3 B43_NTAB32(10, 000) /* frame struct */
|
||||
#define B43_NTAB_PILOT_R3 B43_NTAB16(11, 000) /* pilot */
|
||||
#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 000) /* TM AP */
|
||||
#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 000) /* INT LV */
|
||||
#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 000) /* TD TRN */
|
||||
#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 000) /* noise variance 0 */
|
||||
#define B43_NTAB_FRAMESTRUCT_R3 B43_NTAB32(10, 0) /* frame struct */
|
||||
#define B43_NTAB_PILOT_R3 B43_NTAB16(11, 0) /* pilot */
|
||||
#define B43_NTAB_TMAP_R3 B43_NTAB32(12, 0) /* TM AP */
|
||||
#define B43_NTAB_INTLEVEL_R3 B43_NTAB32(13, 0) /* INT LV */
|
||||
#define B43_NTAB_TDTRN_R3 B43_NTAB32(14, 0) /* TD TRN */
|
||||
#define B43_NTAB_NOISEVAR0_R3 B43_NTAB32(16, 0) /* noise variance 0 */
|
||||
#define B43_NTAB_NOISEVAR1_R3 B43_NTAB32(16, 128) /* noise variance 1 */
|
||||
#define B43_NTAB_MCS_R3 B43_NTAB16(18, 000) /* MCS */
|
||||
#define B43_NTAB_MCS_R3 B43_NTAB16(18, 0) /* MCS */
|
||||
#define B43_NTAB_TDI20A0_R3 B43_NTAB32(19, 128) /* TDI 20/0 */
|
||||
#define B43_NTAB_TDI20A1_R3 B43_NTAB32(19, 256) /* TDI 20/1 */
|
||||
#define B43_NTAB_TDI40A0_R3 B43_NTAB32(19, 640) /* TDI 40/0 */
|
||||
#define B43_NTAB_TDI40A1_R3 B43_NTAB32(19, 768) /* TDI 40/1 */
|
||||
#define B43_NTAB_PILOTLT_R3 B43_NTAB32(20, 000) /* PLT lookup */
|
||||
#define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 000) /* channel estimate */
|
||||
#define B43_NTAB_FRAMELT_R3 B43_NTAB8 (24, 000) /* frame lookup */
|
||||
#define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8 (26, 000) /* estimated power lookup 0 */
|
||||
#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8 (27, 000) /* estimated power lookup 1 */
|
||||
#define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8 (26, 064) /* adjusted power lookup 0 */
|
||||
#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8 (27, 064) /* adjusted power lookup 1 */
|
||||
#define B43_NTAB_PILOTLT_R3 B43_NTAB32(20, 0) /* PLT lookup */
|
||||
#define B43_NTAB_CHANEST_R3 B43_NTAB32(22, 0) /* channel estimate */
|
||||
#define B43_NTAB_FRAMELT_R3 B43_NTAB8(24, 0) /* frame lookup */
|
||||
#define B43_NTAB_C0_ESTPLT_R3 B43_NTAB8(26, 0) /* estimated power lookup 0 */
|
||||
#define B43_NTAB_C1_ESTPLT_R3 B43_NTAB8(27, 0) /* estimated power lookup 1 */
|
||||
#define B43_NTAB_C0_ADJPLT_R3 B43_NTAB8(26, 64) /* adjusted power lookup 0 */
|
||||
#define B43_NTAB_C1_ADJPLT_R3 B43_NTAB8(27, 64) /* adjusted power lookup 1 */
|
||||
#define B43_NTAB_C0_GAINCTL_R3 B43_NTAB32(26, 192) /* gain control lookup 0 */
|
||||
#define B43_NTAB_C1_GAINCTL_R3 B43_NTAB32(27, 192) /* gain control lookup 1 */
|
||||
#define B43_NTAB_C0_IQLT_R3 B43_NTAB32(26, 320) /* I/Q lookup 0 */
|
||||
|
@ -3,9 +3,8 @@ config BRCMUTIL
|
||||
|
||||
config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on PCI
|
||||
depends on MAC80211
|
||||
depends on BCMA=n
|
||||
depends on BCMA
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
|
@ -40,8 +40,7 @@
|
||||
|
||||
static void brcmf_sdioh_irqhandler(struct sdio_func *func)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(&func->card->dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv;
|
||||
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
|
||||
brcmf_dbg(TRACE, "***IRQHandler\n");
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#define DMA_ALIGN_MASK 0x03
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
|
||||
|
||||
#define SDIO_FUNC1_BLOCKSIZE 64
|
||||
#define SDIO_FUNC2_BLOCKSIZE 512
|
||||
@ -47,6 +48,7 @@
|
||||
/* devices we support, null terminated */
|
||||
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
@ -481,12 +483,12 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
kfree(bus_if);
|
||||
return -ENOMEM;
|
||||
}
|
||||
sdiodev->dev = &func->card->dev;
|
||||
sdiodev->func[0] = func->card->sdio_func[0];
|
||||
sdiodev->func[1] = func;
|
||||
sdiodev->bus_if = bus_if;
|
||||
bus_if->bus_priv = sdiodev;
|
||||
bus_if->type = SDIO_BUS;
|
||||
dev_set_drvdata(&func->card->dev, bus_if);
|
||||
dev_set_drvdata(&func->card->dev, sdiodev);
|
||||
|
||||
atomic_set(&sdiodev->suspend, false);
|
||||
init_waitqueue_head(&sdiodev->request_byte_wait);
|
||||
@ -496,12 +498,15 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
}
|
||||
|
||||
if (func->num == 2) {
|
||||
bus_if = dev_get_drvdata(&func->card->dev);
|
||||
sdiodev = bus_if->bus_priv;
|
||||
sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
|
||||
return -ENODEV;
|
||||
sdiodev->func[2] = func;
|
||||
|
||||
bus_if = sdiodev->bus_if;
|
||||
sdiodev->dev = &func->dev;
|
||||
dev_set_drvdata(&func->dev, bus_if);
|
||||
|
||||
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
|
||||
ret = brcmf_sdio_probe(sdiodev);
|
||||
}
|
||||
@ -520,11 +525,12 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
|
||||
brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
|
||||
|
||||
if (func->num == 2) {
|
||||
bus_if = dev_get_drvdata(&func->card->dev);
|
||||
bus_if = dev_get_drvdata(&func->dev);
|
||||
sdiodev = bus_if->bus_priv;
|
||||
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
|
||||
brcmf_sdio_remove(sdiodev);
|
||||
dev_set_drvdata(&func->card->dev, NULL);
|
||||
dev_set_drvdata(&func->dev, NULL);
|
||||
kfree(bus_if);
|
||||
kfree(sdiodev);
|
||||
}
|
||||
@ -534,15 +540,12 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
|
||||
static int brcmf_sdio_suspend(struct device *dev)
|
||||
{
|
||||
mmc_pm_flag_t sdio_flags;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(&func->card->dev);
|
||||
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
int ret = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "\n");
|
||||
|
||||
sdiodev = bus_if->bus_priv;
|
||||
|
||||
atomic_set(&sdiodev->suspend, true);
|
||||
|
||||
sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
|
||||
@ -564,11 +567,9 @@ static int brcmf_sdio_suspend(struct device *dev)
|
||||
|
||||
static int brcmf_sdio_resume(struct device *dev)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(&func->card->dev);
|
||||
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
|
||||
sdiodev = bus_if->bus_priv;
|
||||
brcmf_sdio_wdtmr_enable(sdiodev, true);
|
||||
atomic_set(&sdiodev->suspend, false);
|
||||
return 0;
|
||||
|
@ -87,7 +87,7 @@
|
||||
#define TOE_TX_CSUM_OL 0x00000001
|
||||
#define TOE_RX_CSUM_OL 0x00000002
|
||||
|
||||
#define BRCMF_BSS_INFO_VERSION 108 /* curr ver of brcmf_bss_info_le struct */
|
||||
#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
|
||||
|
||||
/* size of brcmf_scan_params not including variable length array */
|
||||
#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
|
||||
|
@ -58,7 +58,7 @@ struct brcmf_proto_cdc_dcmd {
|
||||
* Used on data packets to convey priority across USB.
|
||||
*/
|
||||
#define BDC_HEADER_LEN 4
|
||||
#define BDC_PROTO_VER 1 /* Protocol version */
|
||||
#define BDC_PROTO_VER 2 /* Protocol version */
|
||||
#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
|
||||
@ -77,7 +77,7 @@ struct brcmf_proto_bdc_header {
|
||||
u8 flags;
|
||||
u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
|
||||
u8 flags2;
|
||||
u8 rssi;
|
||||
u8 data_offset;
|
||||
};
|
||||
|
||||
|
||||
@ -372,7 +372,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
|
||||
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->rssi = 0;
|
||||
h->data_offset = 0;
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
}
|
||||
|
||||
|
@ -3636,6 +3636,8 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid)
|
||||
{
|
||||
if (chipid == BCM4329_CHIP_ID)
|
||||
return true;
|
||||
if (chipid == BCM4330_CHIP_ID)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -59,37 +59,17 @@ struct sdiod_drive_str {
|
||||
u8 strength; /* Pad Drive Strength in mA */
|
||||
u8 sel; /* Chip-specific select value */
|
||||
};
|
||||
/* SDIO Drive Strength to sel value table for PMU Rev 1 */
|
||||
static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
|
||||
{
|
||||
4, 0x2}, {
|
||||
2, 0x3}, {
|
||||
1, 0x0}, {
|
||||
0, 0x0}
|
||||
};
|
||||
/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
|
||||
static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
|
||||
{
|
||||
12, 0x7}, {
|
||||
10, 0x6}, {
|
||||
8, 0x5}, {
|
||||
6, 0x4}, {
|
||||
4, 0x2}, {
|
||||
2, 0x1}, {
|
||||
0, 0x0}
|
||||
};
|
||||
/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
|
||||
static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
|
||||
{
|
||||
32, 0x7}, {
|
||||
26, 0x6}, {
|
||||
22, 0x5}, {
|
||||
16, 0x4}, {
|
||||
12, 0x3}, {
|
||||
8, 0x2}, {
|
||||
4, 0x1}, {
|
||||
0, 0x0}
|
||||
};
|
||||
/* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
|
||||
static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
|
||||
{32, 0x6},
|
||||
{26, 0x7},
|
||||
{22, 0x4},
|
||||
{16, 0x5},
|
||||
{12, 0x2},
|
||||
{8, 0x3},
|
||||
{4, 0x0},
|
||||
{0, 0x1}
|
||||
};
|
||||
|
||||
u8
|
||||
brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
|
||||
@ -396,6 +376,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
|
||||
ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
|
||||
ci->ramsize = BCM4329_RAMSIZE;
|
||||
break;
|
||||
case BCM4330_CHIP_ID:
|
||||
ci->c_inf[0].wrapbase = 0x18100000;
|
||||
ci->c_inf[0].cib = 0x27004211;
|
||||
ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
|
||||
ci->c_inf[1].base = 0x18002000;
|
||||
ci->c_inf[1].wrapbase = 0x18102000;
|
||||
ci->c_inf[1].cib = 0x07004211;
|
||||
ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
|
||||
ci->c_inf[2].base = 0x18004000;
|
||||
ci->c_inf[2].wrapbase = 0x18104000;
|
||||
ci->c_inf[2].cib = 0x0d080401;
|
||||
ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
|
||||
ci->c_inf[3].base = 0x18003000;
|
||||
ci->c_inf[3].wrapbase = 0x18103000;
|
||||
ci->c_inf[3].cib = 0x03004211;
|
||||
ci->ramsize = 0x48000;
|
||||
break;
|
||||
default:
|
||||
brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
|
||||
return -ENODEV;
|
||||
@ -569,19 +566,8 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
|
||||
return;
|
||||
|
||||
switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
|
||||
case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
|
||||
str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
|
||||
str_mask = 0x30000000;
|
||||
str_shift = 28;
|
||||
break;
|
||||
case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
|
||||
case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
|
||||
str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
|
||||
str_mask = 0x00003800;
|
||||
str_shift = 11;
|
||||
break;
|
||||
case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
|
||||
str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
|
||||
case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
|
||||
str_tab = (struct sdiod_drive_str *)&sdiod_drvstr_tab1_1v8;
|
||||
str_mask = 0x00003800;
|
||||
str_shift = 11;
|
||||
break;
|
||||
|
@ -135,6 +135,7 @@ struct brcmf_sdio_dev {
|
||||
wait_queue_head_t request_chain_wait;
|
||||
wait_queue_head_t request_buffer_wait;
|
||||
struct device *dev;
|
||||
struct brcmf_bus *bus_if;
|
||||
};
|
||||
|
||||
/* Register/deregister device interrupt handler. */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,8 @@
|
||||
#ifndef _BRCM_AIUTILS_H_
|
||||
#define _BRCM_AIUTILS_H_
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
@ -144,26 +146,15 @@
|
||||
* public (read-only) portion of aiutils handle returned by si_attach()
|
||||
*/
|
||||
struct si_pub {
|
||||
uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
|
||||
uint buscorerev; /* buscore rev */
|
||||
uint buscoreidx; /* buscore index */
|
||||
int ccrev; /* chip common core rev */
|
||||
u32 cccaps; /* chip common capabilities */
|
||||
u32 cccaps_ext; /* chip common capabilities extension */
|
||||
int pmurev; /* pmu core rev */
|
||||
u32 pmucaps; /* pmu capabilities */
|
||||
uint boardtype; /* board type */
|
||||
uint boardvendor; /* board vendor */
|
||||
uint boardflags; /* board flags */
|
||||
uint boardflags2; /* board flags2 */
|
||||
uint chip; /* chip number */
|
||||
uint chiprev; /* chip revision */
|
||||
uint chippkg; /* chip package option */
|
||||
u32 chipst; /* chip status */
|
||||
bool issim; /* chip is in simulation or emulation */
|
||||
uint socirev; /* SOC interconnect rev */
|
||||
bool pci_pr32414;
|
||||
|
||||
};
|
||||
|
||||
struct pci_dev;
|
||||
@ -179,38 +170,13 @@ struct gpioh_item {
|
||||
/* misc si info needed by some of the routines */
|
||||
struct si_info {
|
||||
struct si_pub pub; /* back plane public state (must be first) */
|
||||
struct pci_dev *pbus; /* handle to pci bus */
|
||||
uint dev_coreid; /* the core provides driver functions */
|
||||
void *intr_arg; /* interrupt callback function arg */
|
||||
u32 (*intrsoff_fn) (void *intr_arg); /* turns chip interrupts off */
|
||||
/* restore chip interrupts */
|
||||
void (*intrsrestore_fn) (void *intr_arg, u32 arg);
|
||||
/* check if interrupts are enabled */
|
||||
bool (*intrsenabled_fn) (void *intr_arg);
|
||||
|
||||
struct bcma_bus *icbus; /* handle to soc interconnect bus */
|
||||
struct pci_dev *pcibus; /* handle to pci bus */
|
||||
struct pcicore_info *pch; /* PCI/E core handle */
|
||||
|
||||
struct bcma_device *buscore;
|
||||
struct list_head var_list; /* list of srom variables */
|
||||
|
||||
void __iomem *curmap; /* current regs va */
|
||||
void __iomem *regs[SI_MAXCORES]; /* other regs va */
|
||||
|
||||
uint curidx; /* current core index */
|
||||
uint numcores; /* # discovered cores */
|
||||
uint coreid[SI_MAXCORES]; /* id of each core */
|
||||
u32 coresba[SI_MAXCORES]; /* backplane address of each core */
|
||||
void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
|
||||
u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
|
||||
u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
|
||||
u32 coresba2_size[SI_MAXCORES]; /* second address space size */
|
||||
|
||||
void *curwrap; /* current wrapper va */
|
||||
void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
|
||||
u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
|
||||
|
||||
u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 oob_router; /* oob router registers for axi */
|
||||
u32 chipst; /* chip status */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -223,52 +189,15 @@ struct si_info {
|
||||
|
||||
|
||||
/* AMBA Interconnect exported externs */
|
||||
extern uint ai_flag(struct si_pub *sih);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern uint ai_coreidx(struct si_pub *sih);
|
||||
extern uint ai_corevendor(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern int ai_numaddrspaces(struct si_pub *sih);
|
||||
extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
|
||||
extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
|
||||
extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
|
||||
extern struct bcma_device *ai_findcore(struct si_pub *sih,
|
||||
u16 coreid, u16 coreunit);
|
||||
extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val);
|
||||
|
||||
/* === exported functions === */
|
||||
extern struct si_pub *ai_attach(void __iomem *regs, struct pci_dev *sdh);
|
||||
extern struct si_pub *ai_attach(struct bcma_bus *pbus);
|
||||
extern void ai_detach(struct si_pub *sih);
|
||||
extern uint ai_coreid(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_setcoreidx(struct si_pub *sih, uint coreidx);
|
||||
extern void __iomem *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_switch_core(struct si_pub *sih, uint coreid,
|
||||
uint *origidx, uint *intr_val);
|
||||
extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern u32 ai_alp_clock(struct si_pub *sih);
|
||||
extern u32 ai_ilp_clock(struct si_pub *sih);
|
||||
extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val);
|
||||
extern void ai_pci_setup(struct si_pub *sih, uint coremask);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern bool ai_backplane64(struct si_pub *sih);
|
||||
extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
|
||||
void *intrsrestore_fn,
|
||||
void *intrsenabled_fn, void *intr_arg);
|
||||
extern void ai_deregister_intr_callback(struct si_pub *sih);
|
||||
extern void ai_clkctl_init(struct si_pub *sih);
|
||||
extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
|
||||
@ -283,13 +212,6 @@ extern bool ai_is_otp_disabled(struct si_pub *sih);
|
||||
/* SPROM availability */
|
||||
extern bool ai_is_sprom_available(struct si_pub *sih);
|
||||
|
||||
/*
|
||||
* Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
|
||||
* The returned path is NULL terminated and has trailing '/'.
|
||||
* Return 0 on success, nonzero otherwise.
|
||||
*/
|
||||
extern int ai_devpath(struct si_pub *sih, char *path, int size);
|
||||
|
||||
extern void ai_pci_sleep(struct si_pub *sih);
|
||||
extern void ai_pci_down(struct si_pub *sih);
|
||||
extern void ai_pci_up(struct si_pub *sih);
|
||||
@ -299,4 +221,52 @@ extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
|
||||
/* Enable Ex-PA for 4313 */
|
||||
extern void ai_epa_4313war(struct si_pub *sih);
|
||||
|
||||
extern uint ai_get_buscoretype(struct si_pub *sih);
|
||||
extern uint ai_get_buscorerev(struct si_pub *sih);
|
||||
|
||||
static inline int ai_get_ccrev(struct si_pub *sih)
|
||||
{
|
||||
return sih->ccrev;
|
||||
}
|
||||
|
||||
static inline u32 ai_get_cccaps(struct si_pub *sih)
|
||||
{
|
||||
return sih->cccaps;
|
||||
}
|
||||
|
||||
static inline int ai_get_pmurev(struct si_pub *sih)
|
||||
{
|
||||
return sih->pmurev;
|
||||
}
|
||||
|
||||
static inline u32 ai_get_pmucaps(struct si_pub *sih)
|
||||
{
|
||||
return sih->pmucaps;
|
||||
}
|
||||
|
||||
static inline uint ai_get_boardtype(struct si_pub *sih)
|
||||
{
|
||||
return sih->boardtype;
|
||||
}
|
||||
|
||||
static inline uint ai_get_boardvendor(struct si_pub *sih)
|
||||
{
|
||||
return sih->boardvendor;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chip_id(struct si_pub *sih)
|
||||
{
|
||||
return sih->chip;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chiprev(struct si_pub *sih)
|
||||
{
|
||||
return sih->chiprev;
|
||||
}
|
||||
|
||||
static inline uint ai_get_chippkg(struct si_pub *sih)
|
||||
{
|
||||
return sih->chippkg;
|
||||
}
|
||||
|
||||
#endif /* _BRCM_AIUTILS_H_ */
|
||||
|
@ -1118,14 +1118,17 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
|
||||
u8 status_delay = 0;
|
||||
|
||||
/* wait till the next 8 bytes of txstatus is available */
|
||||
while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) {
|
||||
s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
|
||||
while ((s1 & TXS_V) == 0) {
|
||||
udelay(1);
|
||||
status_delay++;
|
||||
if (status_delay > 10)
|
||||
return; /* error condition */
|
||||
s1 = bcma_read32(wlc->hw->d11core,
|
||||
D11REGOFFS(frmtxstatus));
|
||||
}
|
||||
|
||||
s2 = R_REG(&wlc->regs->frmtxstatus2);
|
||||
s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
|
||||
}
|
||||
|
||||
if (scb) {
|
||||
|
@ -430,6 +430,9 @@ struct d11regs {
|
||||
u16 PAD[0x380]; /* 0x800 - 0xEFE */
|
||||
};
|
||||
|
||||
/* d11 register field offset */
|
||||
#define D11REGOFFS(field) offsetof(struct d11regs, field)
|
||||
|
||||
#define PIHR_BASE 0x0400 /* byte address of packed IHR region */
|
||||
|
||||
/* biststatus */
|
||||
|
@ -26,6 +26,13 @@
|
||||
#include "dma.h"
|
||||
#include "soc.h"
|
||||
|
||||
/*
|
||||
* dma register field offset calculation
|
||||
*/
|
||||
#define DMA64REGOFFS(field) offsetof(struct dma64regs, field)
|
||||
#define DMA64TXREGOFFS(di, field) (di->d64txregbase + DMA64REGOFFS(field))
|
||||
#define DMA64RXREGOFFS(di, field) (di->d64rxregbase + DMA64REGOFFS(field))
|
||||
|
||||
/*
|
||||
* DMA hardware requires each descriptor ring to be 8kB aligned, and fit within
|
||||
* a contiguous 8kB physical address.
|
||||
@ -220,15 +227,16 @@ struct dma_info {
|
||||
uint *msg_level; /* message level pointer */
|
||||
char name[MAXNAMEL]; /* callers name for diag msgs */
|
||||
|
||||
struct pci_dev *pbus; /* bus handle */
|
||||
struct bcma_device *core;
|
||||
struct device *dmadev;
|
||||
|
||||
bool dma64; /* this dma engine is operating in 64-bit mode */
|
||||
bool addrext; /* this dma engine supports DmaExtendedAddrChanges */
|
||||
|
||||
/* 64-bit dma tx engine registers */
|
||||
struct dma64regs __iomem *d64txregs;
|
||||
uint d64txregbase;
|
||||
/* 64-bit dma rx engine registers */
|
||||
struct dma64regs __iomem *d64rxregs;
|
||||
uint d64rxregbase;
|
||||
/* pointer to dma64 tx descriptor ring */
|
||||
struct dma64desc *txd64;
|
||||
/* pointer to dma64 rx descriptor ring */
|
||||
@ -375,15 +383,16 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
|
||||
if (dmactrlflags & DMA_CTRL_PEN) {
|
||||
u32 control;
|
||||
|
||||
control = R_REG(&di->d64txregs->control);
|
||||
W_REG(&di->d64txregs->control,
|
||||
control = bcma_read32(di->core, DMA64TXREGOFFS(di, control));
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, control),
|
||||
control | D64_XC_PD);
|
||||
if (R_REG(&di->d64txregs->control) & D64_XC_PD)
|
||||
if (bcma_read32(di->core, DMA64TXREGOFFS(di, control)) &
|
||||
D64_XC_PD)
|
||||
/* We *can* disable it so it is supported,
|
||||
* restore control register
|
||||
*/
|
||||
W_REG(&di->d64txregs->control,
|
||||
control);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, control),
|
||||
control);
|
||||
else
|
||||
/* Not supported, don't allow it to be enabled */
|
||||
dmactrlflags &= ~DMA_CTRL_PEN;
|
||||
@ -394,12 +403,12 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
|
||||
return dmactrlflags;
|
||||
}
|
||||
|
||||
static bool _dma64_addrext(struct dma64regs __iomem *dma64regs)
|
||||
static bool _dma64_addrext(struct dma_info *di, uint ctrl_offset)
|
||||
{
|
||||
u32 w;
|
||||
OR_REG(&dma64regs->control, D64_XC_AE);
|
||||
w = R_REG(&dma64regs->control);
|
||||
AND_REG(&dma64regs->control, ~D64_XC_AE);
|
||||
bcma_set32(di->core, ctrl_offset, D64_XC_AE);
|
||||
w = bcma_read32(di->core, ctrl_offset);
|
||||
bcma_mask32(di->core, ctrl_offset, ~D64_XC_AE);
|
||||
return (w & D64_XC_AE) == D64_XC_AE;
|
||||
}
|
||||
|
||||
@ -412,13 +421,13 @@ static bool _dma_isaddrext(struct dma_info *di)
|
||||
/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
|
||||
|
||||
/* not all tx or rx channel are available */
|
||||
if (di->d64txregs != NULL) {
|
||||
if (!_dma64_addrext(di->d64txregs))
|
||||
if (di->d64txregbase != 0) {
|
||||
if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control)))
|
||||
DMA_ERROR("%s: DMA64 tx doesn't have AE set\n",
|
||||
di->name);
|
||||
return true;
|
||||
} else if (di->d64rxregs != NULL) {
|
||||
if (!_dma64_addrext(di->d64rxregs))
|
||||
} else if (di->d64rxregbase != 0) {
|
||||
if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control)))
|
||||
DMA_ERROR("%s: DMA64 rx doesn't have AE set\n",
|
||||
di->name);
|
||||
return true;
|
||||
@ -432,14 +441,14 @@ static bool _dma_descriptor_align(struct dma_info *di)
|
||||
u32 addrl;
|
||||
|
||||
/* Check to see if the descriptors need to be aligned on 4K/8K or not */
|
||||
if (di->d64txregs != NULL) {
|
||||
W_REG(&di->d64txregs->addrlow, 0xff0);
|
||||
addrl = R_REG(&di->d64txregs->addrlow);
|
||||
if (di->d64txregbase != 0) {
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow), 0xff0);
|
||||
addrl = bcma_read32(di->core, DMA64TXREGOFFS(di, addrlow));
|
||||
if (addrl != 0)
|
||||
return false;
|
||||
} else if (di->d64rxregs != NULL) {
|
||||
W_REG(&di->d64rxregs->addrlow, 0xff0);
|
||||
addrl = R_REG(&di->d64rxregs->addrlow);
|
||||
} else if (di->d64rxregbase != 0) {
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow), 0xff0);
|
||||
addrl = bcma_read32(di->core, DMA64RXREGOFFS(di, addrlow));
|
||||
if (addrl != 0)
|
||||
return false;
|
||||
}
|
||||
@ -450,7 +459,7 @@ static bool _dma_descriptor_align(struct dma_info *di)
|
||||
* Descriptor table must start at the DMA hardware dictated alignment, so
|
||||
* allocated memory must be large enough to support this requirement.
|
||||
*/
|
||||
static void *dma_alloc_consistent(struct pci_dev *pdev, uint size,
|
||||
static void *dma_alloc_consistent(struct dma_info *di, uint size,
|
||||
u16 align_bits, uint *alloced,
|
||||
dma_addr_t *pap)
|
||||
{
|
||||
@ -460,7 +469,7 @@ static void *dma_alloc_consistent(struct pci_dev *pdev, uint size,
|
||||
size += align;
|
||||
*alloced = size;
|
||||
}
|
||||
return pci_alloc_consistent(pdev, size, pap);
|
||||
return dma_alloc_coherent(di->dmadev, size, pap, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
static
|
||||
@ -486,7 +495,7 @@ static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
|
||||
u32 desc_strtaddr;
|
||||
u32 alignbytes = 1 << *alignbits;
|
||||
|
||||
va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
|
||||
va = dma_alloc_consistent(di, size, *alignbits, alloced, descpa);
|
||||
|
||||
if (NULL == va)
|
||||
return NULL;
|
||||
@ -495,8 +504,8 @@ static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size,
|
||||
if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
|
||||
& boundary)) {
|
||||
*alignbits = dma_align_sizetobits(size);
|
||||
pci_free_consistent(di->pbus, size, va, *descpa);
|
||||
va = dma_alloc_consistent(di->pbus, size, *alignbits,
|
||||
dma_free_coherent(di->dmadev, size, va, *descpa);
|
||||
va = dma_alloc_consistent(di, size, *alignbits,
|
||||
alloced, descpa);
|
||||
}
|
||||
return va;
|
||||
@ -556,12 +565,13 @@ static bool _dma_alloc(struct dma_info *di, uint direction)
|
||||
}
|
||||
|
||||
struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
void __iomem *dmaregstx, void __iomem *dmaregsrx,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level)
|
||||
struct bcma_device *core,
|
||||
uint txregbase, uint rxregbase, uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level)
|
||||
{
|
||||
struct dma_info *di;
|
||||
u8 rev = core->id.rev;
|
||||
uint size;
|
||||
|
||||
/* allocate private info structure */
|
||||
@ -572,11 +582,13 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
di->msg_level = msg_level ? msg_level : &dma_msg_level;
|
||||
|
||||
|
||||
di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
|
||||
di->dma64 =
|
||||
((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64);
|
||||
|
||||
/* init dma reg pointer */
|
||||
di->d64txregs = (struct dma64regs __iomem *) dmaregstx;
|
||||
di->d64rxregs = (struct dma64regs __iomem *) dmaregsrx;
|
||||
/* init dma reg info */
|
||||
di->core = core;
|
||||
di->d64txregbase = txregbase;
|
||||
di->d64rxregbase = rxregbase;
|
||||
|
||||
/*
|
||||
* Default flags (which can be changed by the driver calling
|
||||
@ -585,16 +597,17 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
*/
|
||||
_dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0);
|
||||
|
||||
DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d dmaregstx %p dmaregsrx %p\n",
|
||||
name, "DMA64",
|
||||
DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d "
|
||||
"rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
|
||||
"txregbase %u rxregbase %u\n", name, "DMA64",
|
||||
di->dma.dmactrlflags, ntxd, nrxd, rxbufsize,
|
||||
rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx);
|
||||
rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase);
|
||||
|
||||
/* make a private copy of our callers name */
|
||||
strncpy(di->name, name, MAXNAMEL);
|
||||
di->name[MAXNAMEL - 1] = '\0';
|
||||
|
||||
di->pbus = ((struct si_info *)sih)->pbus;
|
||||
di->dmadev = core->dma_dev;
|
||||
|
||||
/* save tunables */
|
||||
di->ntxd = (u16) ntxd;
|
||||
@ -626,11 +639,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
di->dataoffsetlow = di->ddoffsetlow;
|
||||
di->dataoffsethigh = di->ddoffsethigh;
|
||||
/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
|
||||
if ((ai_coreid(sih) == SDIOD_CORE_ID)
|
||||
&& ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
|
||||
if ((core->id.id == SDIOD_CORE_ID)
|
||||
&& ((rev > 0) && (rev <= 2)))
|
||||
di->addrext = 0;
|
||||
else if ((ai_coreid(sih) == I2S_CORE_ID) &&
|
||||
((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
|
||||
else if ((core->id.id == I2S_CORE_ID) &&
|
||||
((rev == 0) || (rev == 1)))
|
||||
di->addrext = 0;
|
||||
else
|
||||
di->addrext = _dma_isaddrext(di);
|
||||
@ -749,13 +762,13 @@ void dma_detach(struct dma_pub *pub)
|
||||
|
||||
/* free dma descriptor rings */
|
||||
if (di->txd64)
|
||||
pci_free_consistent(di->pbus, di->txdalloc,
|
||||
((s8 *)di->txd64 - di->txdalign),
|
||||
(di->txdpaorig));
|
||||
dma_free_coherent(di->dmadev, di->txdalloc,
|
||||
((s8 *)di->txd64 - di->txdalign),
|
||||
(di->txdpaorig));
|
||||
if (di->rxd64)
|
||||
pci_free_consistent(di->pbus, di->rxdalloc,
|
||||
((s8 *)di->rxd64 - di->rxdalign),
|
||||
(di->rxdpaorig));
|
||||
dma_free_coherent(di->dmadev, di->rxdalloc,
|
||||
((s8 *)di->rxd64 - di->rxdalign),
|
||||
(di->rxdpaorig));
|
||||
|
||||
/* free packet pointer vectors */
|
||||
kfree(di->txp);
|
||||
@ -780,11 +793,15 @@ _dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
|
||||
if ((di->ddoffsetlow == 0)
|
||||
|| !(pa & PCI32ADDR_HIGH)) {
|
||||
if (direction == DMA_TX) {
|
||||
W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
|
||||
W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
|
||||
pa + di->ddoffsetlow);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
|
||||
di->ddoffsethigh);
|
||||
} else {
|
||||
W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
|
||||
W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
|
||||
pa + di->ddoffsetlow);
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
|
||||
di->ddoffsethigh);
|
||||
}
|
||||
} else {
|
||||
/* DMA64 32bits address extension */
|
||||
@ -795,15 +812,19 @@ _dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa)
|
||||
pa &= ~PCI32ADDR_HIGH;
|
||||
|
||||
if (direction == DMA_TX) {
|
||||
W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow);
|
||||
W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh);
|
||||
SET_REG(&di->d64txregs->control,
|
||||
D64_XC_AE, (ae << D64_XC_AE_SHIFT));
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, addrlow),
|
||||
pa + di->ddoffsetlow);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, addrhigh),
|
||||
di->ddoffsethigh);
|
||||
bcma_maskset32(di->core, DMA64TXREGOFFS(di, control),
|
||||
D64_XC_AE, (ae << D64_XC_AE_SHIFT));
|
||||
} else {
|
||||
W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow);
|
||||
W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh);
|
||||
SET_REG(&di->d64rxregs->control,
|
||||
D64_RC_AE, (ae << D64_RC_AE_SHIFT));
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, addrlow),
|
||||
pa + di->ddoffsetlow);
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, addrhigh),
|
||||
di->ddoffsethigh);
|
||||
bcma_maskset32(di->core, DMA64RXREGOFFS(di, control),
|
||||
D64_RC_AE, (ae << D64_RC_AE_SHIFT));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -815,9 +836,9 @@ static void _dma_rxenable(struct dma_info *di)
|
||||
|
||||
DMA_TRACE("%s:\n", di->name);
|
||||
|
||||
control =
|
||||
(R_REG(&di->d64rxregs->control) & D64_RC_AE) |
|
||||
D64_RC_RE;
|
||||
control = D64_RC_RE | (bcma_read32(di->core,
|
||||
DMA64RXREGOFFS(di, control)) &
|
||||
D64_RC_AE);
|
||||
|
||||
if ((dmactrlflags & DMA_CTRL_PEN) == 0)
|
||||
control |= D64_RC_PD;
|
||||
@ -825,7 +846,7 @@ static void _dma_rxenable(struct dma_info *di)
|
||||
if (dmactrlflags & DMA_CTRL_ROC)
|
||||
control |= D64_RC_OC;
|
||||
|
||||
W_REG(&di->d64rxregs->control,
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, control),
|
||||
((di->rxoffset << D64_RC_RO_SHIFT) | control));
|
||||
}
|
||||
|
||||
@ -868,7 +889,8 @@ static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
|
||||
return NULL;
|
||||
|
||||
curr =
|
||||
B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
|
||||
B2I(((bcma_read32(di->core,
|
||||
DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) -
|
||||
di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc);
|
||||
|
||||
/* ignore curr if forceall */
|
||||
@ -882,7 +904,7 @@ static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall)
|
||||
pa = le32_to_cpu(di->rxd64[i].addrlow) - di->dataoffsetlow;
|
||||
|
||||
/* clear this packet from the descriptor ring */
|
||||
pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
|
||||
dma_unmap_single(di->dmadev, pa, di->rxbufsize, DMA_FROM_DEVICE);
|
||||
|
||||
di->rxd64[i].addrlow = cpu_to_le32(0xdeadbeef);
|
||||
di->rxd64[i].addrhigh = cpu_to_le32(0xdeadbeef);
|
||||
@ -950,12 +972,12 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
|
||||
if (resid > 0) {
|
||||
uint cur;
|
||||
cur =
|
||||
B2I(((R_REG(&di->d64rxregs->status0) &
|
||||
D64_RS0_CD_MASK) -
|
||||
di->rcvptrbase) & D64_RS0_CD_MASK,
|
||||
struct dma64desc);
|
||||
B2I(((bcma_read32(di->core,
|
||||
DMA64RXREGOFFS(di, status0)) &
|
||||
D64_RS0_CD_MASK) - di->rcvptrbase) &
|
||||
D64_RS0_CD_MASK, struct dma64desc);
|
||||
DMA_ERROR("rxin %d rxout %d, hw_curr %d\n",
|
||||
di->rxin, di->rxout, cur);
|
||||
di->rxin, di->rxout, cur);
|
||||
}
|
||||
#endif /* BCMDBG */
|
||||
|
||||
@ -983,8 +1005,10 @@ static bool dma64_rxidle(struct dma_info *di)
|
||||
if (di->nrxd == 0)
|
||||
return true;
|
||||
|
||||
return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
|
||||
(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
|
||||
return ((bcma_read32(di->core,
|
||||
DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) ==
|
||||
(bcma_read32(di->core, DMA64RXREGOFFS(di, ptr)) &
|
||||
D64_RS0_CD_MASK));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1048,8 +1072,8 @@ bool dma_rxfill(struct dma_pub *pub)
|
||||
*/
|
||||
*(u32 *) (p->data) = 0;
|
||||
|
||||
pa = pci_map_single(di->pbus, p->data,
|
||||
di->rxbufsize, PCI_DMA_FROMDEVICE);
|
||||
pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
/* save the free packet pointer */
|
||||
di->rxp[rxout] = p;
|
||||
@ -1067,7 +1091,7 @@ bool dma_rxfill(struct dma_pub *pub)
|
||||
di->rxout = rxout;
|
||||
|
||||
/* update the chip lastdscr pointer */
|
||||
W_REG(&di->d64rxregs->ptr,
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, ptr),
|
||||
di->rcvptrbase + I2B(rxout, struct dma64desc));
|
||||
|
||||
return ring_empty;
|
||||
@ -1128,7 +1152,7 @@ void dma_txinit(struct dma_pub *pub)
|
||||
|
||||
if ((di->dma.dmactrlflags & DMA_CTRL_PEN) == 0)
|
||||
control |= D64_XC_PD;
|
||||
OR_REG(&di->d64txregs->control, control);
|
||||
bcma_set32(di->core, DMA64TXREGOFFS(di, control), control);
|
||||
|
||||
/* DMA engine with alignment requirement requires table to be inited
|
||||
* before enabling the engine
|
||||
@ -1146,7 +1170,7 @@ void dma_txsuspend(struct dma_pub *pub)
|
||||
if (di->ntxd == 0)
|
||||
return;
|
||||
|
||||
OR_REG(&di->d64txregs->control, D64_XC_SE);
|
||||
bcma_set32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
|
||||
}
|
||||
|
||||
void dma_txresume(struct dma_pub *pub)
|
||||
@ -1158,7 +1182,7 @@ void dma_txresume(struct dma_pub *pub)
|
||||
if (di->ntxd == 0)
|
||||
return;
|
||||
|
||||
AND_REG(&di->d64txregs->control, ~D64_XC_SE);
|
||||
bcma_mask32(di->core, DMA64TXREGOFFS(di, control), ~D64_XC_SE);
|
||||
}
|
||||
|
||||
bool dma_txsuspended(struct dma_pub *pub)
|
||||
@ -1166,8 +1190,9 @@ bool dma_txsuspended(struct dma_pub *pub)
|
||||
struct dma_info *di = (struct dma_info *)pub;
|
||||
|
||||
return (di->ntxd == 0) ||
|
||||
((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
|
||||
D64_XC_SE);
|
||||
((bcma_read32(di->core,
|
||||
DMA64TXREGOFFS(di, control)) & D64_XC_SE) ==
|
||||
D64_XC_SE);
|
||||
}
|
||||
|
||||
void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
|
||||
@ -1200,16 +1225,17 @@ bool dma_txreset(struct dma_pub *pub)
|
||||
return true;
|
||||
|
||||
/* suspend tx DMA first */
|
||||
W_REG(&di->d64txregs->control, D64_XC_SE);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, control), D64_XC_SE);
|
||||
SPINWAIT(((status =
|
||||
(R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
|
||||
!= D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
|
||||
&& (status != D64_XS0_XS_STOPPED), 10000);
|
||||
(bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
|
||||
D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED) &&
|
||||
(status != D64_XS0_XS_IDLE) && (status != D64_XS0_XS_STOPPED),
|
||||
10000);
|
||||
|
||||
W_REG(&di->d64txregs->control, 0);
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, control), 0);
|
||||
SPINWAIT(((status =
|
||||
(R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
|
||||
!= D64_XS0_XS_DISABLED), 10000);
|
||||
(bcma_read32(di->core, DMA64TXREGOFFS(di, status0)) &
|
||||
D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED), 10000);
|
||||
|
||||
/* wait for the last transaction to complete */
|
||||
udelay(300);
|
||||
@ -1225,10 +1251,10 @@ bool dma_rxreset(struct dma_pub *pub)
|
||||
if (di->nrxd == 0)
|
||||
return true;
|
||||
|
||||
W_REG(&di->d64rxregs->control, 0);
|
||||
bcma_write32(di->core, DMA64RXREGOFFS(di, control), 0);
|
||||
SPINWAIT(((status =
|
||||
(R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
|
||||
!= D64_RS0_RS_DISABLED), 10000);
|
||||
(bcma_read32(di->core, DMA64RXREGOFFS(di, status0)) &
|
||||
D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED), 10000);
|
||||
|
||||
return status == D64_RS0_RS_DISABLED;
|
||||
}
|
||||
@ -1267,7 +1293,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
|
||||
goto outoftxd;
|
||||
|
||||
/* get physical address of buffer start */
|
||||
pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
|
||||
pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
|
||||
|
||||
/* With a DMA segment list, Descriptor table is filled
|
||||
* using the segment list instead of looping over
|
||||
@ -1290,7 +1316,7 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit)
|
||||
|
||||
/* kick the chip */
|
||||
if (commit)
|
||||
W_REG(&di->d64txregs->ptr,
|
||||
bcma_write32(di->core, DMA64TXREGOFFS(di, ptr),
|
||||
di->xmtptrbase + I2B(txout, struct dma64desc));
|
||||
|
||||
/* tx flow control */
|
||||
@ -1338,16 +1364,15 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
|
||||
if (range == DMA_RANGE_ALL)
|
||||
end = di->txout;
|
||||
else {
|
||||
struct dma64regs __iomem *dregs = di->d64txregs;
|
||||
|
||||
end = (u16) (B2I(((R_REG(&dregs->status0) &
|
||||
D64_XS0_CD_MASK) -
|
||||
di->xmtptrbase) & D64_XS0_CD_MASK,
|
||||
struct dma64desc));
|
||||
end = (u16) (B2I(((bcma_read32(di->core,
|
||||
DMA64TXREGOFFS(di, status0)) &
|
||||
D64_XS0_CD_MASK) - di->xmtptrbase) &
|
||||
D64_XS0_CD_MASK, struct dma64desc));
|
||||
|
||||
if (range == DMA_RANGE_TRANSFERED) {
|
||||
active_desc =
|
||||
(u16) (R_REG(&dregs->status1) &
|
||||
(u16)(bcma_read32(di->core,
|
||||
DMA64TXREGOFFS(di, status1)) &
|
||||
D64_XS1_AD_MASK);
|
||||
active_desc =
|
||||
(active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
|
||||
@ -1376,7 +1401,7 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
|
||||
txp = di->txp[i];
|
||||
di->txp[i] = NULL;
|
||||
|
||||
pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
|
||||
dma_unmap_single(di->dmadev, pa, size, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
di->txin = i;
|
||||
|
@ -75,10 +75,11 @@ struct dma_pub {
|
||||
};
|
||||
|
||||
extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
void __iomem *dmaregstx, void __iomem *dmaregsrx,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level);
|
||||
struct bcma_device *d11core,
|
||||
uint txregbase, uint rxregbase,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level);
|
||||
|
||||
void dma_rxinit(struct dma_pub *pub);
|
||||
int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list);
|
||||
|
@ -17,11 +17,11 @@
|
||||
#define __UNDEF_NO_VERSION__
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <defs.h>
|
||||
#include "nicpci.h"
|
||||
@ -87,16 +87,14 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
|
||||
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
/* recognized PCI IDs */
|
||||
static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, /* 43225 2G */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, /* 43224 DUAL */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, /* 4313 DUAL */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, /* 43224 Ven */
|
||||
{0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, brcms_pci_id_table);
|
||||
/* recognized BCMA Core IDs */
|
||||
static struct bcma_device_id brcms_coreid_table[] = {
|
||||
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
|
||||
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
|
||||
BCMA_CORETABLE_END
|
||||
};
|
||||
MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
|
||||
|
||||
#ifdef BCMDBG
|
||||
static int msglevel = 0xdeadbeef;
|
||||
@ -724,7 +722,7 @@ static const struct ieee80211_ops brcms_ops = {
|
||||
};
|
||||
|
||||
/*
|
||||
* is called in brcms_pci_probe() context, therefore no locking required.
|
||||
* is called in brcms_bcma_probe() context, therefore no locking required.
|
||||
*/
|
||||
static int brcms_set_hint(struct brcms_info *wl, char *abbrev)
|
||||
{
|
||||
@ -864,25 +862,15 @@ static void brcms_free(struct brcms_info *wl)
|
||||
#endif
|
||||
kfree(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* unregister_netdev() calls get_stats() which may read chip
|
||||
* registers so we cannot unmap the chip registers until
|
||||
* after calling unregister_netdev() .
|
||||
*/
|
||||
if (wl->regsva)
|
||||
iounmap(wl->regsva);
|
||||
|
||||
wl->regsva = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* called from both kernel as from this kernel module (error flow on attach)
|
||||
* precondition: perimeter lock is not acquired.
|
||||
*/
|
||||
static void brcms_remove(struct pci_dev *pdev)
|
||||
static void brcms_remove(struct bcma_device *pdev)
|
||||
{
|
||||
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
|
||||
struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
|
||||
struct brcms_info *wl = hw->priv;
|
||||
|
||||
if (wl->wlc) {
|
||||
@ -890,11 +878,10 @@ static void brcms_remove(struct pci_dev *pdev)
|
||||
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
|
||||
ieee80211_unregister_hw(hw);
|
||||
}
|
||||
pci_disable_device(pdev);
|
||||
|
||||
brcms_free(wl);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
bcma_set_drvdata(pdev, NULL);
|
||||
ieee80211_free_hw(hw);
|
||||
}
|
||||
|
||||
@ -1002,11 +989,9 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
|
||||
* it as static.
|
||||
*
|
||||
*
|
||||
* is called in brcms_pci_probe() context, therefore no locking required.
|
||||
* is called in brcms_bcma_probe() context, therefore no locking required.
|
||||
*/
|
||||
static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
||||
resource_size_t regs,
|
||||
struct pci_dev *btparam, uint irq)
|
||||
static struct brcms_info *brcms_attach(struct bcma_device *pdev)
|
||||
{
|
||||
struct brcms_info *wl = NULL;
|
||||
int unit, err;
|
||||
@ -1020,7 +1005,7 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
||||
return NULL;
|
||||
|
||||
/* allocate private info */
|
||||
hw = pci_get_drvdata(btparam); /* btparam == pdev */
|
||||
hw = bcma_get_drvdata(pdev);
|
||||
if (hw != NULL)
|
||||
wl = hw->priv;
|
||||
if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
|
||||
@ -1032,26 +1017,20 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
||||
/* setup the bottom half handler */
|
||||
tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
|
||||
|
||||
wl->regsva = ioremap_nocache(regs, PCI_BAR0_WINSZ);
|
||||
if (wl->regsva == NULL) {
|
||||
wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
spin_lock_init(&wl->lock);
|
||||
spin_lock_init(&wl->isr_lock);
|
||||
|
||||
/* prepare ucode */
|
||||
if (brcms_request_fw(wl, btparam) < 0) {
|
||||
if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) {
|
||||
wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
|
||||
"%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
|
||||
brcms_release_fw(wl);
|
||||
brcms_remove(btparam);
|
||||
brcms_remove(pdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* common load-time initialization */
|
||||
wl->wlc = brcms_c_attach(wl, vendor, device, unit, false,
|
||||
wl->regsva, btparam, &err);
|
||||
wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
|
||||
brcms_release_fw(wl);
|
||||
if (!wl->wlc) {
|
||||
wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
|
||||
@ -1063,11 +1042,12 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
|
||||
wl->pub->ieee_hw = hw;
|
||||
|
||||
/* register our interrupt handler */
|
||||
if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
|
||||
if (request_irq(pdev->bus->host_pci->irq, brcms_isr,
|
||||
IRQF_SHARED, KBUILD_MODNAME, wl)) {
|
||||
wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
|
||||
goto fail;
|
||||
}
|
||||
wl->irq = irq;
|
||||
wl->irq = pdev->bus->host_pci->irq;
|
||||
|
||||
/* register module */
|
||||
brcms_c_module_register(wl->pub, "linux", wl, NULL);
|
||||
@ -1114,38 +1094,19 @@ fail:
|
||||
*
|
||||
* Perimeter lock is initialized in the course of this function.
|
||||
*/
|
||||
static int __devinit
|
||||
brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
|
||||
{
|
||||
int rc;
|
||||
struct brcms_info *wl;
|
||||
struct ieee80211_hw *hw;
|
||||
u32 val;
|
||||
|
||||
dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
|
||||
pdev->bus->number, PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn), pdev->irq);
|
||||
dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
|
||||
pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
|
||||
pdev->bus->host_pci->irq);
|
||||
|
||||
if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
|
||||
((pdev->device != 0x0576) &&
|
||||
((pdev->device & 0xff00) != 0x4300) &&
|
||||
((pdev->device & 0xff00) != 0x4700) &&
|
||||
((pdev->device < 43000) || (pdev->device > 43999))))
|
||||
if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
|
||||
(pdev->id.id != BCMA_CORE_80211))
|
||||
return -ENODEV;
|
||||
|
||||
rc = pci_enable_device(pdev);
|
||||
if (rc) {
|
||||
pr_err("%s: Cannot enable device %d-%d_%d\n",
|
||||
__func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
|
||||
PCI_FUNC(pdev->devfn));
|
||||
return -ENODEV;
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
|
||||
pci_read_config_dword(pdev, 0x40, &val);
|
||||
if ((val & 0x0000ff00) != 0)
|
||||
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
|
||||
|
||||
hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
|
||||
if (!hw) {
|
||||
pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
|
||||
@ -1154,14 +1115,11 @@ brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
SET_IEEE80211_DEV(hw, &pdev->dev);
|
||||
|
||||
pci_set_drvdata(pdev, hw);
|
||||
bcma_set_drvdata(pdev, hw);
|
||||
|
||||
memset(hw->priv, 0, sizeof(*wl));
|
||||
|
||||
wl = brcms_attach(pdev->vendor, pdev->device,
|
||||
pci_resource_start(pdev, 0), pdev,
|
||||
pdev->irq);
|
||||
|
||||
wl = brcms_attach(pdev);
|
||||
if (!wl) {
|
||||
pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME,
|
||||
__func__);
|
||||
@ -1170,16 +1128,23 @@ brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int brcms_pci_suspend(struct pci_dev *pdev)
|
||||
{
|
||||
pci_save_state(pdev);
|
||||
pci_disable_device(pdev);
|
||||
return pci_set_power_state(pdev, PCI_D3hot);
|
||||
}
|
||||
|
||||
static int brcms_suspend(struct bcma_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct brcms_info *wl;
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
hw = pci_get_drvdata(pdev);
|
||||
hw = bcma_get_drvdata(pdev);
|
||||
wl = hw->priv;
|
||||
if (!wl) {
|
||||
wiphy_err(wl->wiphy,
|
||||
"brcms_suspend: pci_get_drvdata failed\n");
|
||||
"brcms_suspend: bcma_get_drvdata failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -1188,25 +1153,14 @@ static int brcms_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
wl->pub->hw_up = false;
|
||||
spin_unlock_bh(&wl->lock);
|
||||
|
||||
pci_save_state(pdev);
|
||||
pci_disable_device(pdev);
|
||||
return pci_set_power_state(pdev, PCI_D3hot);
|
||||
/* temporarily do suspend ourselves */
|
||||
return brcms_pci_suspend(pdev->bus->host_pci);
|
||||
}
|
||||
|
||||
static int brcms_resume(struct pci_dev *pdev)
|
||||
static int brcms_pci_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct brcms_info *wl;
|
||||
struct ieee80211_hw *hw;
|
||||
int err = 0;
|
||||
u32 val;
|
||||
|
||||
hw = pci_get_drvdata(pdev);
|
||||
wl = hw->priv;
|
||||
if (!wl) {
|
||||
wiphy_err(wl->wiphy,
|
||||
"wl: brcms_resume: pci_get_drvdata failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
uint val;
|
||||
|
||||
err = pci_set_power_state(pdev, PCI_D0);
|
||||
if (err)
|
||||
@ -1224,24 +1178,28 @@ static int brcms_resume(struct pci_dev *pdev)
|
||||
if ((val & 0x0000ff00) != 0)
|
||||
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
|
||||
|
||||
/*
|
||||
* done. driver will be put in up state
|
||||
* in brcms_ops_add_interface() call.
|
||||
*/
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pci_driver brcms_pci_driver = {
|
||||
static int brcms_resume(struct bcma_device *pdev)
|
||||
{
|
||||
/*
|
||||
* just do pci resume for now until bcma supports it.
|
||||
*/
|
||||
return brcms_pci_resume(pdev->bus->host_pci);
|
||||
}
|
||||
|
||||
static struct bcma_driver brcms_bcma_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.probe = brcms_pci_probe,
|
||||
.probe = brcms_bcma_probe,
|
||||
.suspend = brcms_suspend,
|
||||
.resume = brcms_resume,
|
||||
.remove = __devexit_p(brcms_remove),
|
||||
.id_table = brcms_pci_id_table,
|
||||
.id_table = brcms_coreid_table,
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the main entry point for the WL driver.
|
||||
* This is the main entry point for the brcmsmac driver.
|
||||
*
|
||||
* This function determines if a device pointed to by pdev is a WL device,
|
||||
* and if so, performs a brcms_attach() on it.
|
||||
@ -1256,26 +1214,24 @@ static int __init brcms_module_init(void)
|
||||
brcm_msg_level = msglevel;
|
||||
#endif /* BCMDBG */
|
||||
|
||||
error = pci_register_driver(&brcms_pci_driver);
|
||||
error = bcma_driver_register(&brcms_bcma_driver);
|
||||
printk(KERN_ERR "%s: register returned %d\n", __func__, error);
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function unloads the WL driver from the system.
|
||||
* This function unloads the brcmsmac driver from the system.
|
||||
*
|
||||
* This function unconditionally unloads the WL driver module from the
|
||||
* This function unconditionally unloads the brcmsmac driver module from the
|
||||
* system.
|
||||
*
|
||||
*/
|
||||
static void __exit brcms_module_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&brcms_pci_driver);
|
||||
|
||||
bcma_driver_unregister(&brcms_bcma_driver);
|
||||
}
|
||||
|
||||
module_init(brcms_module_init);
|
||||
@ -1562,7 +1518,7 @@ fail:
|
||||
}
|
||||
|
||||
/*
|
||||
* Precondition: Since this function is called in brcms_pci_probe() context,
|
||||
* Precondition: Since this function is called in brcms_bcma_probe() context,
|
||||
* no locking is required.
|
||||
*/
|
||||
int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
|
||||
@ -1602,7 +1558,7 @@ void brcms_ucode_free_buf(void *p)
|
||||
/*
|
||||
* checks validity of all firmware images loaded from user space
|
||||
*
|
||||
* Precondition: Since this function is called in brcms_pci_probe() context,
|
||||
* Precondition: Since this function is called in brcms_bcma_probe() context,
|
||||
* no locking is required.
|
||||
*/
|
||||
int brcms_check_firmwares(struct brcms_info *wl)
|
||||
|
@ -68,8 +68,6 @@ struct brcms_info {
|
||||
spinlock_t lock; /* per-device perimeter lock */
|
||||
spinlock_t isr_lock; /* per-device ISR synchronization lock */
|
||||
|
||||
/* regsva for unmap in brcms_free() */
|
||||
void __iomem *regsva; /* opaque chip registers virtual address */
|
||||
|
||||
/* timer related fields */
|
||||
atomic_t callbacks; /* # outstanding callback functions */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -334,7 +334,7 @@ struct brcms_hardware {
|
||||
u32 machwcap_backup; /* backup of machwcap */
|
||||
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
struct d11regs __iomem *regs; /* pointer to device registers */
|
||||
struct bcma_device *d11core; /* pointer to 802.11 core */
|
||||
struct phy_shim_info *physhim; /* phy shim layer handler */
|
||||
struct shared_phy *phy_sh; /* pointer to shared phy state */
|
||||
struct brcms_hw_band *band;/* pointer to active per-band state */
|
||||
@ -400,7 +400,6 @@ struct brcms_txq_info {
|
||||
*
|
||||
* pub: pointer to driver public state.
|
||||
* wl: pointer to specific private state.
|
||||
* regs: pointer to device registers.
|
||||
* hw: HW related state.
|
||||
* clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
|
||||
* fastpwrup_dly: time in us needed to bring up d11 fast clock.
|
||||
@ -477,7 +476,6 @@ struct brcms_txq_info {
|
||||
struct brcms_c_info {
|
||||
struct brcms_pub *pub;
|
||||
struct brcms_info *wl;
|
||||
struct d11regs __iomem *regs;
|
||||
struct brcms_hardware *hw;
|
||||
|
||||
/* clock */
|
||||
|
@ -139,6 +139,9 @@
|
||||
#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
|
||||
#define SRSH_PI_SHIFT 12 /* bit 15:12 */
|
||||
|
||||
#define PCIREGOFFS(field) offsetof(struct sbpciregs, field)
|
||||
#define PCIEREGOFFS(field) offsetof(struct sbpcieregs, field)
|
||||
|
||||
/* Sonics side: PCI core and host control registers */
|
||||
struct sbpciregs {
|
||||
u32 control; /* PCI control */
|
||||
@ -205,11 +208,7 @@ struct sbpcieregs {
|
||||
};
|
||||
|
||||
struct pcicore_info {
|
||||
union {
|
||||
struct sbpcieregs __iomem *pcieregs;
|
||||
struct sbpciregs __iomem *pciregs;
|
||||
} regs; /* Memory mapped register to the core */
|
||||
|
||||
struct bcma_device *core;
|
||||
struct si_pub *sih; /* System interconnect handle */
|
||||
struct pci_dev *dev;
|
||||
u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
|
||||
@ -224,9 +223,9 @@ struct pcicore_info {
|
||||
};
|
||||
|
||||
#define PCIE_ASPM(sih) \
|
||||
(((sih)->buscoretype == PCIE_CORE_ID) && \
|
||||
(((sih)->buscorerev >= 3) && \
|
||||
((sih)->buscorerev <= 5)))
|
||||
((ai_get_buscoretype(sih) == PCIE_CORE_ID) && \
|
||||
((ai_get_buscorerev(sih) >= 3) && \
|
||||
(ai_get_buscorerev(sih) <= 5)))
|
||||
|
||||
|
||||
/* delay needed between the mdio control/ mdiodata register data access */
|
||||
@ -238,8 +237,7 @@ static void pr28829_delay(void)
|
||||
/* Initialize the PCI core.
|
||||
* It's caller's responsibility to make sure that this is done only once
|
||||
*/
|
||||
struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
|
||||
void __iomem *regs)
|
||||
struct pcicore_info *pcicore_init(struct si_pub *sih, struct bcma_device *core)
|
||||
{
|
||||
struct pcicore_info *pi;
|
||||
|
||||
@ -249,17 +247,15 @@ struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
|
||||
return NULL;
|
||||
|
||||
pi->sih = sih;
|
||||
pi->dev = pdev;
|
||||
pi->dev = core->bus->host_pci;
|
||||
pi->core = core;
|
||||
|
||||
if (sih->buscoretype == PCIE_CORE_ID) {
|
||||
if (core->id.id == PCIE_CORE_ID) {
|
||||
u8 cap_ptr;
|
||||
pi->regs.pcieregs = regs;
|
||||
cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
|
||||
NULL, NULL);
|
||||
pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
|
||||
} else
|
||||
pi->regs.pciregs = regs;
|
||||
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
|
||||
@ -334,37 +330,37 @@ end:
|
||||
|
||||
/* ***** Register Access API */
|
||||
static uint
|
||||
pcie_readreg(struct sbpcieregs __iomem *pcieregs, uint addrtype, uint offset)
|
||||
pcie_readreg(struct bcma_device *core, uint addrtype, uint offset)
|
||||
{
|
||||
uint retval = 0xFFFFFFFF;
|
||||
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG(&pcieregs->configaddr, offset);
|
||||
(void)R_REG((&pcieregs->configaddr));
|
||||
retval = R_REG(&pcieregs->configdata);
|
||||
bcma_write32(core, PCIEREGOFFS(configaddr), offset);
|
||||
(void)bcma_read32(core, PCIEREGOFFS(configaddr));
|
||||
retval = bcma_read32(core, PCIEREGOFFS(configdata));
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG(&pcieregs->pcieindaddr, offset);
|
||||
(void)R_REG(&pcieregs->pcieindaddr);
|
||||
retval = R_REG(&pcieregs->pcieinddata);
|
||||
bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
|
||||
(void)bcma_read32(core, PCIEREGOFFS(pcieindaddr));
|
||||
retval = bcma_read32(core, PCIEREGOFFS(pcieinddata));
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
|
||||
static uint pcie_writereg(struct bcma_device *core, uint addrtype,
|
||||
uint offset, uint val)
|
||||
{
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG((&pcieregs->configaddr), offset);
|
||||
W_REG((&pcieregs->configdata), val);
|
||||
bcma_write32(core, PCIEREGOFFS(configaddr), offset);
|
||||
bcma_write32(core, PCIEREGOFFS(configdata), val);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG((&pcieregs->pcieindaddr), offset);
|
||||
W_REG((&pcieregs->pcieinddata), val);
|
||||
bcma_write32(core, PCIEREGOFFS(pcieindaddr), offset);
|
||||
bcma_write32(core, PCIEREGOFFS(pcieinddata), val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -374,7 +370,6 @@ static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
|
||||
|
||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata, i = 0;
|
||||
uint pcie_serdes_spinwait = 200;
|
||||
|
||||
@ -382,12 +377,13 @@ static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
|
||||
(MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
|
||||
(blk << 4));
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
|
||||
if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
|
||||
MDIOCTL_ACCESS_DONE)
|
||||
break;
|
||||
|
||||
udelay(1000);
|
||||
@ -404,15 +400,15 @@ static int
|
||||
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
uint *val)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata;
|
||||
uint i = 0;
|
||||
uint pcie_serdes_spinwait = 10;
|
||||
|
||||
/* enable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
|
||||
bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol),
|
||||
MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
|
||||
|
||||
if (pi->sih->buscorerev >= 10) {
|
||||
if (ai_get_buscorerev(pi->sih) >= 10) {
|
||||
/* new serdes is slower in rw,
|
||||
* using two layers of reg address mapping
|
||||
*/
|
||||
@ -432,20 +428,22 @@ pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
*val);
|
||||
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
bcma_write32(pi->core, PCIEREGOFFS(mdiodata), mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
|
||||
if (bcma_read32(pi->core, PCIEREGOFFS(mdiocontrol)) &
|
||||
MDIOCTL_ACCESS_DONE) {
|
||||
if (!write) {
|
||||
pr28829_delay();
|
||||
*val = (R_REG(&pcieregs->mdiodata) &
|
||||
*val = (bcma_read32(pi->core,
|
||||
PCIEREGOFFS(mdiodata)) &
|
||||
MDIODATA_MASK);
|
||||
}
|
||||
/* Disable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
|
||||
return 0;
|
||||
}
|
||||
udelay(1000);
|
||||
@ -453,7 +451,7 @@ pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
}
|
||||
|
||||
/* Timed out. Disable mdio access to SERDES. */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
bcma_write32(pi->core, PCIEREGOFFS(mdiocontrol), 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -502,18 +500,18 @@ static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
|
||||
{
|
||||
u32 w;
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
|
||||
if (sih->buscoretype != PCIE_CORE_ID || sih->buscorerev < 7)
|
||||
if (ai_get_buscoretype(sih) != PCIE_CORE_ID ||
|
||||
ai_get_buscorerev(sih) < 7)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
if (extend)
|
||||
w |= PCIE_ASPMTIMER_EXTEND;
|
||||
else
|
||||
w &= ~PCIE_ASPMTIMER_EXTEND;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
}
|
||||
|
||||
/* centralized clkreq control policy */
|
||||
@ -527,25 +525,27 @@ static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
break;
|
||||
case SI_PCIDOWN:
|
||||
if (sih->buscorerev == 6) { /* turn on serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0);
|
||||
/* turn on serdes PLL down */
|
||||
if (ai_get_buscorerev(sih) == 6) {
|
||||
ai_cc_reg(sih,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_cc_reg(sih,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0);
|
||||
} else if (pi->pcie_pr42767) {
|
||||
pcie_clkreq(pi, 1, 1);
|
||||
}
|
||||
break;
|
||||
case SI_PCIUP:
|
||||
if (sih->buscorerev == 6) { /* turn off serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0x40);
|
||||
/* turn off serdes PLL down */
|
||||
if (ai_get_buscorerev(sih) == 6) {
|
||||
ai_cc_reg(sih,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_cc_reg(sih,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0x40);
|
||||
} else if (PCIE_ASPM(sih)) { /* disable clkreq */
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
}
|
||||
@ -562,7 +562,7 @@ static void pcie_war_polarity(struct pcicore_info *pi)
|
||||
if (pi->pcie_polarity != 0)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
|
||||
|
||||
/* Detect the current polarity at attach and force that polarity and
|
||||
* disable changing the polarity
|
||||
@ -581,18 +581,15 @@ static void pcie_war_polarity(struct pcicore_info *pi)
|
||||
*/
|
||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
struct si_pub *sih = pi->sih;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
u32 w;
|
||||
|
||||
if (!PCIE_ASPM(sih))
|
||||
return;
|
||||
|
||||
/* bypass this on QT or VSIM */
|
||||
reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
|
||||
val16 = R_REG(reg16);
|
||||
val16 = bcma_read16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]));
|
||||
|
||||
val16 &= ~SRSH_ASPM_ENB;
|
||||
if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
|
||||
@ -602,15 +599,15 @@ static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
|
||||
val16 |= SRSH_ASPM_L0s_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_ASPM_OFFSET]), val16);
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_ASPM_ENAB;
|
||||
w |= pi->pcie_war_aspm_ovr;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
|
||||
val16 = R_REG(reg16);
|
||||
val16 = bcma_read16(pi->core,
|
||||
PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]));
|
||||
|
||||
if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
|
||||
val16 |= SRSH_CLKREQ_ENB;
|
||||
@ -618,7 +615,8 @@ static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
} else
|
||||
val16 &= ~SRSH_CLKREQ_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_CLKREQ_OFFSET_REV5]),
|
||||
val16);
|
||||
}
|
||||
|
||||
/* Apply the polarity determined at the start */
|
||||
@ -642,16 +640,15 @@ static void pcie_war_serdes(struct pcicore_info *pi)
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_misc_config_fixup(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
|
||||
val16 = R_REG(reg16);
|
||||
val16 = bcma_read16(pi->core,
|
||||
PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]));
|
||||
|
||||
if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
|
||||
val16 |= SRSH_L23READY_EXIT_NOPERST;
|
||||
W_REG(reg16, val16);
|
||||
bcma_write16(pi->core,
|
||||
PCIEREGOFFS(sprom[SRSH_PCIE_MISC_CONFIG]), val16);
|
||||
}
|
||||
}
|
||||
|
||||
@ -659,62 +656,57 @@ static void pcie_misc_config_fixup(struct pcicore_info *pi)
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_noplldown(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
/* turn off serdes PLL down */
|
||||
ai_corereg(pi->sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol),
|
||||
CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
|
||||
ai_cc_reg(pi->sih, offsetof(struct chipcregs, chipcontrol),
|
||||
CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
|
||||
|
||||
/* clear srom shadow backdoor */
|
||||
reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
|
||||
W_REG(reg16, 0);
|
||||
bcma_write16(pi->core, PCIEREGOFFS(sprom[SRSH_BD_OFFSET]), 0);
|
||||
}
|
||||
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_pci_setup(struct pcicore_info *pi)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u32 w;
|
||||
|
||||
if (sih->buscorerev == 0 || sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
if (ai_get_buscorerev(sih) == 0 || ai_get_buscorerev(sih) == 1) {
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG);
|
||||
w |= 0x8;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
pcie_writereg(pi->core, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
|
||||
if (ai_get_buscorerev(sih) == 1) {
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
|
||||
w |= 0x40;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
|
||||
pcie_writereg(pi->core, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 0) {
|
||||
if (ai_get_buscorerev(sih) == 0) {
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
|
||||
} else if (PCIE_ASPM(sih)) {
|
||||
/* Change the L1 threshold for better performance */
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
w = pcie_readreg(pi->core, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG);
|
||||
w &= ~PCIE_L1THRESHOLDTIME_MASK;
|
||||
w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
pcie_writereg(pi->core, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG, w);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
} else if (pi->sih->buscorerev == 7)
|
||||
} else if (ai_get_buscorerev(pi->sih) == 7)
|
||||
pcie_war_noplldown(pi);
|
||||
|
||||
/* Note that the fix is actually in the SROM,
|
||||
* that's why this is open-ended
|
||||
*/
|
||||
if (pi->sih->buscorerev >= 6)
|
||||
if (ai_get_buscorerev(pi->sih) >= 6)
|
||||
pcie_misc_config_fixup(pi);
|
||||
}
|
||||
|
||||
@ -745,7 +737,7 @@ void pcicore_attach(struct pcicore_info *pi, int state)
|
||||
|
||||
void pcicore_hwup(struct pcicore_info *pi)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_war_pci_setup(pi);
|
||||
@ -753,7 +745,7 @@ void pcicore_hwup(struct pcicore_info *pi)
|
||||
|
||||
void pcicore_up(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
/* Restore L1 timer for better performance */
|
||||
@ -781,7 +773,7 @@ void pcicore_sleep(struct pcicore_info *pi)
|
||||
|
||||
void pcicore_down(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
if (!pi || ai_get_buscoretype(pi->sih) != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
@ -790,46 +782,45 @@ void pcicore_down(struct pcicore_info *pi, int state)
|
||||
pcie_extendL1timer(pi, false);
|
||||
}
|
||||
|
||||
/* precondition: current core is sii->buscoretype */
|
||||
static void pcicore_fixcfg(struct pcicore_info *pi, u16 __iomem *reg16)
|
||||
void pcicore_fixcfg(struct pcicore_info *pi)
|
||||
{
|
||||
struct si_info *sii = (struct si_info *)(pi->sih);
|
||||
struct bcma_device *core = pi->core;
|
||||
u16 val16;
|
||||
uint pciidx;
|
||||
uint regoff;
|
||||
|
||||
pciidx = ai_coreidx(&sii->pub);
|
||||
val16 = R_REG(reg16);
|
||||
if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
|
||||
val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
|
||||
(val16 & ~SRSH_PI_MASK);
|
||||
W_REG(reg16, val16);
|
||||
switch (pi->core->id.id) {
|
||||
case BCMA_CORE_PCI:
|
||||
regoff = PCIREGOFFS(sprom[SRSH_PI_OFFSET]);
|
||||
break;
|
||||
|
||||
case BCMA_CORE_PCIE:
|
||||
regoff = PCIEREGOFFS(sprom[SRSH_PI_OFFSET]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]);
|
||||
}
|
||||
|
||||
void pcicore_fixcfg_pcie(struct pcicore_info *pi,
|
||||
struct sbpcieregs __iomem *pcieregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]);
|
||||
val16 = bcma_read16(pi->core, regoff);
|
||||
if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) !=
|
||||
(u16)core->core_index) {
|
||||
val16 = ((u16)core->core_index << SRSH_PI_SHIFT) |
|
||||
(val16 & ~SRSH_PI_MASK);
|
||||
bcma_write16(pi->core, regoff, val16);
|
||||
}
|
||||
}
|
||||
|
||||
/* precondition: current core is pci core */
|
||||
void
|
||||
pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
pcicore_pci_setup(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
|
||||
SBTOPCI_PREF | SBTOPCI_BURST);
|
||||
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
|
||||
|
||||
if (((struct si_info *)(pi->sih))->pub.buscorerev >= 11) {
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
if (pi->core->id.rev >= 11) {
|
||||
bcma_set32(pi->core, PCIREGOFFS(sbtopci2),
|
||||
SBTOPCI_RC_READMULTI);
|
||||
bcma_set32(pi->core, PCIREGOFFS(clkrun), PCI_CLKRUN_DSBL);
|
||||
(void)bcma_read32(pi->core, PCIREGOFFS(clkrun));
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,7 @@ struct sbpciregs;
|
||||
struct sbpcieregs;
|
||||
|
||||
extern struct pcicore_info *pcicore_init(struct si_pub *sih,
|
||||
struct pci_dev *pdev,
|
||||
void __iomem *regs);
|
||||
struct bcma_device *core);
|
||||
extern void pcicore_deinit(struct pcicore_info *pch);
|
||||
extern void pcicore_attach(struct pcicore_info *pch, int state);
|
||||
extern void pcicore_hwup(struct pcicore_info *pch);
|
||||
@ -72,11 +71,7 @@ extern void pcicore_sleep(struct pcicore_info *pch);
|
||||
extern void pcicore_down(struct pcicore_info *pch, int state);
|
||||
extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen);
|
||||
extern void pcicore_fixcfg_pci(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
extern void pcicore_fixcfg_pcie(struct pcicore_info *pch,
|
||||
struct sbpcieregs __iomem *pciregs);
|
||||
extern void pcicore_pci_setup(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
extern void pcicore_fixcfg(struct pcicore_info *pch);
|
||||
extern void pcicore_pci_setup(struct pcicore_info *pch);
|
||||
|
||||
#endif /* _BRCM_NICPCI_H_ */
|
||||
|
@ -77,7 +77,7 @@ struct otp_fn_s {
|
||||
};
|
||||
|
||||
struct otpinfo {
|
||||
uint ccrev; /* chipc revision */
|
||||
struct bcma_device *core; /* chipc core */
|
||||
const struct otp_fn_s *fn; /* OTP functions */
|
||||
struct si_pub *sih; /* Saved sb handle */
|
||||
|
||||
@ -133,9 +133,10 @@ struct otpinfo {
|
||||
#define OTP_SZ_FU_144 (144/8) /* 144 bits */
|
||||
|
||||
static u16
|
||||
ipxotp_otpr(struct otpinfo *oi, struct chipcregs __iomem *cc, uint wn)
|
||||
ipxotp_otpr(struct otpinfo *oi, uint wn)
|
||||
{
|
||||
return R_REG(&cc->sromotp[wn]);
|
||||
return bcma_read16(oi->core,
|
||||
CHIPCREGOFFS(sromotp[wn]));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -146,7 +147,7 @@ static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
@ -161,19 +162,21 @@ static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
static void _ipxotp_init(struct otpinfo *oi)
|
||||
{
|
||||
uint k;
|
||||
u32 otpp, st;
|
||||
int ccrev = ai_get_ccrev(oi->sih);
|
||||
|
||||
|
||||
/*
|
||||
* record word offset of General Use Region
|
||||
* for various chipcommon revs
|
||||
*/
|
||||
if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
|
||||
|| oi->sih->ccrev == 27) {
|
||||
if (ccrev == 21 || ccrev == 24
|
||||
|| ccrev == 27) {
|
||||
oi->otpgu_base = REVA4_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 36) {
|
||||
} else if (ccrev == 36) {
|
||||
/*
|
||||
* OTP size greater than equal to 2KB (128 words),
|
||||
* otpgu_base is similar to rev23
|
||||
@ -182,7 +185,7 @@ static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
else
|
||||
oi->otpgu_base = REV36_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
|
||||
} else if (ccrev == 23 || ccrev >= 25) {
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
}
|
||||
|
||||
@ -190,24 +193,21 @@ static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
otpp =
|
||||
OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
|
||||
|
||||
W_REG(&cc->otpprog, otpp);
|
||||
for (k = 0;
|
||||
((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
|
||||
&& (k < OTPP_TRIES); k++)
|
||||
;
|
||||
bcma_write32(oi->core, CHIPCREGOFFS(otpprog), otpp);
|
||||
st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
|
||||
for (k = 0; (st & OTPP_START_BUSY) && (k < OTPP_TRIES); k++)
|
||||
st = bcma_read32(oi->core, CHIPCREGOFFS(otpprog));
|
||||
if (k >= OTPP_TRIES)
|
||||
return;
|
||||
|
||||
/* Read OTP lock bits and subregion programmed indication bits */
|
||||
oi->status = R_REG(&cc->otpstatus);
|
||||
oi->status = bcma_read32(oi->core, CHIPCREGOFFS(otpstatus));
|
||||
|
||||
if ((oi->sih->chip == BCM43224_CHIP_ID)
|
||||
|| (oi->sih->chip == BCM43225_CHIP_ID)) {
|
||||
if ((ai_get_chip_id(oi->sih) == BCM43224_CHIP_ID)
|
||||
|| (ai_get_chip_id(oi->sih) == BCM43225_CHIP_ID)) {
|
||||
u32 p_bits;
|
||||
p_bits =
|
||||
(ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
|
||||
OTPGU_P_MSK)
|
||||
>> OTPGU_P_SHIFT;
|
||||
p_bits = (ipxotp_otpr(oi, oi->otpgu_base + OTPGU_P_OFF) &
|
||||
OTPGU_P_MSK) >> OTPGU_P_SHIFT;
|
||||
oi->status |= (p_bits << OTPS_GUP_SHIFT);
|
||||
}
|
||||
|
||||
@ -220,7 +220,7 @@ static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
oi->hwlim = oi->wsize;
|
||||
if (oi->status & OTPS_GUP_HW) {
|
||||
oi->hwlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
|
||||
ipxotp_otpr(oi, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
|
||||
oi->swbase = oi->hwlim;
|
||||
} else
|
||||
oi->swbase = oi->hwbase;
|
||||
@ -230,7 +230,7 @@ static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
|
||||
if (oi->status & OTPS_GUP_SW) {
|
||||
oi->swlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
|
||||
ipxotp_otpr(oi, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
|
||||
oi->fbase = oi->swlim;
|
||||
} else
|
||||
oi->fbase = oi->swbase;
|
||||
@ -240,11 +240,8 @@ static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
|
||||
static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
|
||||
/* Make sure we're running IPX OTP */
|
||||
if (!OTPTYPE_IPX(sih->ccrev))
|
||||
if (!OTPTYPE_IPX(ai_get_ccrev(sih)))
|
||||
return -EBADE;
|
||||
|
||||
/* Make sure OTP is not disabled */
|
||||
@ -252,7 +249,7 @@ static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
return -EBADE;
|
||||
|
||||
/* Check for otp size */
|
||||
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
|
||||
switch ((ai_get_cccaps(sih) & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
|
||||
case 0:
|
||||
/* Nothing there */
|
||||
return -EBADE;
|
||||
@ -282,21 +279,13 @@ static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
}
|
||||
|
||||
/* Retrieve OTP region info */
|
||||
idx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
_ipxotp_init(oi, cc);
|
||||
|
||||
ai_setcoreidx(sih, idx);
|
||||
|
||||
_ipxotp_init(oi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
uint base, i, sz;
|
||||
|
||||
/* Validate region selection */
|
||||
@ -365,14 +354,10 @@ ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
idx = ai_coreidx(oi->sih);
|
||||
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
|
||||
|
||||
/* Read the data */
|
||||
for (i = 0; i < sz; i++)
|
||||
data[i] = ipxotp_otpr(oi, cc, base + i);
|
||||
data[i] = ipxotp_otpr(oi, base + i);
|
||||
|
||||
ai_setcoreidx(oi->sih, idx);
|
||||
*wlen = sz;
|
||||
return 0;
|
||||
}
|
||||
@ -384,14 +369,13 @@ static const struct otp_fn_s ipxotp_fn = {
|
||||
|
||||
static int otp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
memset(oi, 0, sizeof(struct otpinfo));
|
||||
|
||||
oi->ccrev = sih->ccrev;
|
||||
oi->core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
|
||||
if (OTPTYPE_IPX(oi->ccrev))
|
||||
if (OTPTYPE_IPX(ai_get_ccrev(sih)))
|
||||
oi->fn = &ipxotp_fn;
|
||||
|
||||
if (oi->fn == NULL)
|
||||
@ -399,7 +383,7 @@ static int otp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
|
||||
oi->sih = sih;
|
||||
|
||||
ret = (oi->fn->init) (sih, oi);
|
||||
ret = (oi->fn->init)(sih, oi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -149,9 +149,8 @@ void wlc_radioreg_enter(struct brcms_phy_pub *pih)
|
||||
void wlc_radioreg_exit(struct brcms_phy_pub *pih)
|
||||
{
|
||||
struct brcms_phy *pi = (struct brcms_phy *) pih;
|
||||
u16 dummy;
|
||||
|
||||
dummy = R_REG(&pi->regs->phyversion);
|
||||
(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
|
||||
pi->phy_wreg = 0;
|
||||
wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, 0);
|
||||
}
|
||||
@ -186,11 +185,11 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr)
|
||||
if ((D11REV_GE(pi->sh->corerev, 24)) ||
|
||||
(D11REV_IS(pi->sh->corerev, 22)
|
||||
&& (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
|
||||
W_REG_FLUSH(&pi->regs->radioregaddr, addr);
|
||||
data = R_REG(&pi->regs->radioregdata);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
|
||||
data = bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
|
||||
} else {
|
||||
W_REG_FLUSH(&pi->regs->phy4waddr, addr);
|
||||
data = R_REG(&pi->regs->phy4wdatalo);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
|
||||
data = bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
|
||||
}
|
||||
pi->phy_wreg = 0;
|
||||
|
||||
@ -203,15 +202,15 @@ void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val)
|
||||
(D11REV_IS(pi->sh->corerev, 22)
|
||||
&& (pi->pubpi.phy_type != PHY_TYPE_SSN))) {
|
||||
|
||||
W_REG_FLUSH(&pi->regs->radioregaddr, addr);
|
||||
W_REG(&pi->regs->radioregdata, val);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), addr);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(radioregdata), val);
|
||||
} else {
|
||||
W_REG_FLUSH(&pi->regs->phy4waddr, addr);
|
||||
W_REG(&pi->regs->phy4wdatalo, val);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), addr);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(phy4wdatalo), val);
|
||||
}
|
||||
|
||||
if (++pi->phy_wreg >= pi->phy_wreg_limit) {
|
||||
(void)R_REG(&pi->regs->maccontrol);
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
pi->phy_wreg = 0;
|
||||
}
|
||||
}
|
||||
@ -223,19 +222,20 @@ static u32 read_radio_id(struct brcms_phy *pi)
|
||||
if (D11REV_GE(pi->sh->corerev, 24)) {
|
||||
u32 b0, b1, b2;
|
||||
|
||||
W_REG_FLUSH(&pi->regs->radioregaddr, 0);
|
||||
b0 = (u32) R_REG(&pi->regs->radioregdata);
|
||||
W_REG_FLUSH(&pi->regs->radioregaddr, 1);
|
||||
b1 = (u32) R_REG(&pi->regs->radioregdata);
|
||||
W_REG_FLUSH(&pi->regs->radioregaddr, 2);
|
||||
b2 = (u32) R_REG(&pi->regs->radioregdata);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 0);
|
||||
b0 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 1);
|
||||
b1 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(radioregaddr), 2);
|
||||
b2 = (u32) bcma_read16(pi->d11core, D11REGOFFS(radioregdata));
|
||||
|
||||
id = ((b0 & 0xf) << 28) | (((b2 << 8) | b1) << 12) | ((b0 >> 4)
|
||||
& 0xf);
|
||||
} else {
|
||||
W_REG_FLUSH(&pi->regs->phy4waddr, RADIO_IDCODE);
|
||||
id = (u32) R_REG(&pi->regs->phy4wdatalo);
|
||||
id |= (u32) R_REG(&pi->regs->phy4wdatahi) << 16;
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phy4waddr), RADIO_IDCODE);
|
||||
id = (u32) bcma_read16(pi->d11core, D11REGOFFS(phy4wdatalo));
|
||||
id |= (u32) bcma_read16(pi->d11core,
|
||||
D11REGOFFS(phy4wdatahi)) << 16;
|
||||
}
|
||||
pi->phy_wreg = 0;
|
||||
return id;
|
||||
@ -275,75 +275,52 @@ void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
|
||||
|
||||
void write_phy_channel_reg(struct brcms_phy *pi, uint val)
|
||||
{
|
||||
W_REG(&pi->regs->phychannel, val);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(phychannel), val);
|
||||
}
|
||||
|
||||
u16 read_phy_reg(struct brcms_phy *pi, u16 addr)
|
||||
{
|
||||
struct d11regs __iomem *regs;
|
||||
|
||||
regs = pi->regs;
|
||||
|
||||
W_REG_FLUSH(®s->phyregaddr, addr);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
|
||||
|
||||
pi->phy_wreg = 0;
|
||||
return R_REG(®s->phyregdata);
|
||||
return bcma_read16(pi->d11core, D11REGOFFS(phyregdata));
|
||||
}
|
||||
|
||||
void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
|
||||
{
|
||||
struct d11regs __iomem *regs;
|
||||
|
||||
regs = pi->regs;
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
W_REG_FLUSH(®s->phyregaddr, addr);
|
||||
W_REG(®s->phyregdata, val);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(phyregdata), val);
|
||||
if (addr == 0x72)
|
||||
(void)R_REG(®s->phyregdata);
|
||||
(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
|
||||
#else
|
||||
W_REG((u32 __iomem *)(®s->phyregaddr), addr | (val << 16));
|
||||
bcma_write32(pi->d11core, D11REGOFFS(phyregaddr), addr | (val << 16));
|
||||
if (++pi->phy_wreg >= pi->phy_wreg_limit) {
|
||||
pi->phy_wreg = 0;
|
||||
(void)R_REG(®s->phyversion);
|
||||
(void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
|
||||
{
|
||||
struct d11regs __iomem *regs;
|
||||
|
||||
regs = pi->regs;
|
||||
|
||||
W_REG_FLUSH(®s->phyregaddr, addr);
|
||||
|
||||
W_REG(®s->phyregdata, (R_REG(®s->phyregdata) & val));
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
|
||||
bcma_mask16(pi->d11core, D11REGOFFS(phyregdata), val);
|
||||
pi->phy_wreg = 0;
|
||||
}
|
||||
|
||||
void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val)
|
||||
{
|
||||
struct d11regs __iomem *regs;
|
||||
|
||||
regs = pi->regs;
|
||||
|
||||
W_REG_FLUSH(®s->phyregaddr, addr);
|
||||
|
||||
W_REG(®s->phyregdata, (R_REG(®s->phyregdata) | val));
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
|
||||
bcma_set16(pi->d11core, D11REGOFFS(phyregdata), val);
|
||||
pi->phy_wreg = 0;
|
||||
}
|
||||
|
||||
void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val)
|
||||
{
|
||||
struct d11regs __iomem *regs;
|
||||
|
||||
regs = pi->regs;
|
||||
|
||||
W_REG_FLUSH(®s->phyregaddr, addr);
|
||||
|
||||
W_REG(®s->phyregdata,
|
||||
((R_REG(®s->phyregdata) & ~mask) | (val & mask)));
|
||||
val &= mask;
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr), addr);
|
||||
bcma_maskset16(pi->d11core, D11REGOFFS(phyregdata), ~mask, val);
|
||||
pi->phy_wreg = 0;
|
||||
}
|
||||
|
||||
@ -404,10 +381,8 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp)
|
||||
sh->sromrev = shp->sromrev;
|
||||
sh->boardtype = shp->boardtype;
|
||||
sh->boardrev = shp->boardrev;
|
||||
sh->boardvendor = shp->boardvendor;
|
||||
sh->boardflags = shp->boardflags;
|
||||
sh->boardflags2 = shp->boardflags2;
|
||||
sh->buscorerev = shp->buscorerev;
|
||||
|
||||
sh->fast_timer = PHY_SW_TIMER_FAST;
|
||||
sh->slow_timer = PHY_SW_TIMER_SLOW;
|
||||
@ -450,7 +425,7 @@ static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi)
|
||||
}
|
||||
|
||||
struct brcms_phy_pub *
|
||||
wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
|
||||
wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core,
|
||||
int bandtype, struct wiphy *wiphy)
|
||||
{
|
||||
struct brcms_phy *pi;
|
||||
@ -462,7 +437,7 @@ wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
|
||||
if (D11REV_IS(sh->corerev, 4))
|
||||
sflags = SISF_2G_PHY | SISF_5G_PHY;
|
||||
else
|
||||
sflags = ai_core_sflags(sh->sih, 0, 0);
|
||||
sflags = bcma_aread32(d11core, BCMA_IOST);
|
||||
|
||||
if (bandtype == BRCM_BAND_5G) {
|
||||
if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0)
|
||||
@ -480,7 +455,7 @@ wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
|
||||
if (pi == NULL)
|
||||
return NULL;
|
||||
pi->wiphy = wiphy;
|
||||
pi->regs = regs;
|
||||
pi->d11core = d11core;
|
||||
pi->sh = sh;
|
||||
pi->phy_init_por = true;
|
||||
pi->phy_wreg_limit = PHY_WREG_LIMIT;
|
||||
@ -495,7 +470,7 @@ wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
|
||||
pi->pubpi.coreflags = SICF_GMODE;
|
||||
|
||||
wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags);
|
||||
phyversion = R_REG(&pi->regs->phyversion);
|
||||
phyversion = bcma_read16(pi->d11core, D11REGOFFS(phyversion));
|
||||
|
||||
pi->pubpi.phy_type = PHY_TYPE(phyversion);
|
||||
pi->pubpi.phy_rev = phyversion & PV_PV_MASK;
|
||||
@ -507,8 +482,8 @@ wlc_phy_attach(struct shared_phy *sh, struct d11regs __iomem *regs,
|
||||
pi->pubpi.phy_corenum = PHY_CORE_NUM_2;
|
||||
pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT;
|
||||
|
||||
if (!pi->pubpi.phy_type == PHY_TYPE_N &&
|
||||
!pi->pubpi.phy_type == PHY_TYPE_LCN)
|
||||
if (pi->pubpi.phy_type != PHY_TYPE_N &&
|
||||
pi->pubpi.phy_type != PHY_TYPE_LCN)
|
||||
goto err;
|
||||
|
||||
if (bandtype == BRCM_BAND_5G) {
|
||||
@ -779,14 +754,14 @@ void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
|
||||
|
||||
pi->radio_chanspec = chanspec;
|
||||
|
||||
mc = R_REG(&pi->regs->maccontrol);
|
||||
mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
|
||||
return;
|
||||
|
||||
if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN))
|
||||
pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
|
||||
|
||||
if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
|
||||
if (WARN(!(bcma_aread32(pi->d11core, BCMA_IOST) & SISF_FCLKA),
|
||||
"HW error SISF_FCLKA\n"))
|
||||
return;
|
||||
|
||||
@ -825,8 +800,8 @@ void wlc_phy_cal_init(struct brcms_phy_pub *pih)
|
||||
struct brcms_phy *pi = (struct brcms_phy *) pih;
|
||||
void (*cal_init)(struct brcms_phy *) = NULL;
|
||||
|
||||
if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
|
||||
"HW error: MAC enabled during phy cal\n"))
|
||||
if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n"))
|
||||
return;
|
||||
|
||||
if (!pi->initialized) {
|
||||
@ -1017,7 +992,7 @@ wlc_phy_init_radio_regs(struct brcms_phy *pi,
|
||||
void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
|
||||
{
|
||||
#define DUMMY_PKT_LEN 20
|
||||
struct d11regs __iomem *regs = pi->regs;
|
||||
struct bcma_device *core = pi->d11core;
|
||||
int i, count;
|
||||
u8 ofdmpkt[DUMMY_PKT_LEN] = {
|
||||
0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
|
||||
@ -1033,26 +1008,28 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
|
||||
wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
|
||||
dummypkt);
|
||||
|
||||
W_REG(®s->xmtsel, 0);
|
||||
bcma_write16(core, D11REGOFFS(xmtsel), 0);
|
||||
|
||||
if (D11REV_GE(pi->sh->corerev, 11))
|
||||
W_REG(®s->wepctl, 0x100);
|
||||
bcma_write16(core, D11REGOFFS(wepctl), 0x100);
|
||||
else
|
||||
W_REG(®s->wepctl, 0);
|
||||
bcma_write16(core, D11REGOFFS(wepctl), 0);
|
||||
|
||||
W_REG(®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
|
||||
bcma_write16(core, D11REGOFFS(txe_phyctl),
|
||||
(ofdm ? 1 : 0) | PHY_TXC_ANT_0);
|
||||
if (ISNPHY(pi) || ISLCNPHY(pi))
|
||||
W_REG(®s->txe_phyctl1, 0x1A02);
|
||||
bcma_write16(core, D11REGOFFS(txe_phyctl1), 0x1A02);
|
||||
|
||||
W_REG(®s->txe_wm_0, 0);
|
||||
W_REG(®s->txe_wm_1, 0);
|
||||
bcma_write16(core, D11REGOFFS(txe_wm_0), 0);
|
||||
bcma_write16(core, D11REGOFFS(txe_wm_1), 0);
|
||||
|
||||
W_REG(®s->xmttplatetxptr, 0);
|
||||
W_REG(®s->xmttxcnt, DUMMY_PKT_LEN);
|
||||
bcma_write16(core, D11REGOFFS(xmttplatetxptr), 0);
|
||||
bcma_write16(core, D11REGOFFS(xmttxcnt), DUMMY_PKT_LEN);
|
||||
|
||||
W_REG(®s->xmtsel, ((8 << 8) | (1 << 5) | (1 << 2) | 2));
|
||||
bcma_write16(core, D11REGOFFS(xmtsel),
|
||||
((8 << 8) | (1 << 5) | (1 << 2) | 2));
|
||||
|
||||
W_REG(®s->txe_ctl, 0);
|
||||
bcma_write16(core, D11REGOFFS(txe_ctl), 0);
|
||||
|
||||
if (!pa_on) {
|
||||
if (ISNPHY(pi))
|
||||
@ -1060,27 +1037,28 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
|
||||
}
|
||||
|
||||
if (ISNPHY(pi) || ISLCNPHY(pi))
|
||||
W_REG(®s->txe_aux, 0xD0);
|
||||
bcma_write16(core, D11REGOFFS(txe_aux), 0xD0);
|
||||
else
|
||||
W_REG(®s->txe_aux, ((1 << 5) | (1 << 4)));
|
||||
bcma_write16(core, D11REGOFFS(txe_aux), ((1 << 5) | (1 << 4)));
|
||||
|
||||
(void)R_REG(®s->txe_aux);
|
||||
(void)bcma_read16(core, D11REGOFFS(txe_aux));
|
||||
|
||||
i = 0;
|
||||
count = ofdm ? 30 : 250;
|
||||
while ((i++ < count)
|
||||
&& (R_REG(®s->txe_status) & (1 << 7)))
|
||||
&& (bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 7)))
|
||||
udelay(10);
|
||||
|
||||
i = 0;
|
||||
|
||||
while ((i++ < 10)
|
||||
&& ((R_REG(®s->txe_status) & (1 << 10)) == 0))
|
||||
while ((i++ < 10) &&
|
||||
((bcma_read16(core, D11REGOFFS(txe_status)) & (1 << 10)) == 0))
|
||||
udelay(10);
|
||||
|
||||
i = 0;
|
||||
|
||||
while ((i++ < 10) && ((R_REG(®s->ifsstat) & (1 << 8))))
|
||||
while ((i++ < 10) &&
|
||||
((bcma_read16(core, D11REGOFFS(ifsstat)) & (1 << 8))))
|
||||
udelay(10);
|
||||
|
||||
if (!pa_on) {
|
||||
@ -1137,7 +1115,7 @@ static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
|
||||
void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
|
||||
{
|
||||
struct brcms_phy *pi = (struct brcms_phy *) pih;
|
||||
(void)R_REG(&pi->regs->maccontrol);
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
|
||||
if (ISNPHY(pi)) {
|
||||
wlc_phy_switch_radio_nphy(pi, on);
|
||||
@ -1377,7 +1355,7 @@ void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
|
||||
memcpy(&pi->tx_user_target[TXP_FIRST_MCS_40_SDM],
|
||||
&txpwr->mcs_40_mimo[0], BRCMS_NUM_RATES_MCS_2_STREAM);
|
||||
|
||||
if (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)
|
||||
if (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)
|
||||
mac_enabled = true;
|
||||
|
||||
if (mac_enabled)
|
||||
@ -1407,7 +1385,8 @@ int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
|
||||
if (!SCAN_INPROG_PHY(pi)) {
|
||||
bool suspend;
|
||||
|
||||
suspend = (0 == (R_REG(&pi->regs->maccontrol) &
|
||||
suspend = (0 == (bcma_read32(pi->d11core,
|
||||
D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
|
||||
if (!suspend)
|
||||
@ -1860,18 +1839,17 @@ void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
|
||||
|
||||
if (NREV_IS(pi->pubpi.phy_rev, 3)
|
||||
|| NREV_IS(pi->pubpi.phy_rev, 4)) {
|
||||
W_REG(&pi->regs->phyregaddr, 0xa0);
|
||||
(void)R_REG(&pi->regs->phyregaddr);
|
||||
rxc = R_REG(&pi->regs->phyregdata);
|
||||
W_REG(&pi->regs->phyregdata,
|
||||
(0x1 << 15) | rxc);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
|
||||
0xa0);
|
||||
bcma_set16(pi->d11core, D11REGOFFS(phyregdata),
|
||||
0x1 << 15);
|
||||
}
|
||||
} else {
|
||||
if (NREV_IS(pi->pubpi.phy_rev, 3)
|
||||
|| NREV_IS(pi->pubpi.phy_rev, 4)) {
|
||||
W_REG(&pi->regs->phyregaddr, 0xa0);
|
||||
(void)R_REG(&pi->regs->phyregaddr);
|
||||
W_REG(&pi->regs->phyregdata, rxc);
|
||||
bcma_wflush16(pi->d11core, D11REGOFFS(phyregaddr),
|
||||
0xa0);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(phyregdata), rxc);
|
||||
}
|
||||
|
||||
wlc_phy_por_inform(ppi);
|
||||
@ -1991,7 +1969,9 @@ void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
|
||||
pi->txpwrctrl = hwpwrctrl;
|
||||
|
||||
if (ISNPHY(pi)) {
|
||||
suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core,
|
||||
D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
||||
@ -2193,7 +2173,8 @@ void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
|
||||
if (!pi->sh->clk)
|
||||
return;
|
||||
|
||||
suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
||||
@ -2411,8 +2392,8 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
|
||||
wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
|
||||
wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
|
||||
|
||||
OR_REG(&pi->regs->maccommand,
|
||||
MCMD_BG_NOISE);
|
||||
bcma_set32(pi->d11core, D11REGOFFS(maccommand),
|
||||
MCMD_BG_NOISE);
|
||||
} else {
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_deaf_mode(pi, (bool) 0);
|
||||
@ -2430,8 +2411,8 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
|
||||
wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP2, 0);
|
||||
wlapi_bmac_write_shm(pi->sh->physhim, M_PWRIND_MAP3, 0);
|
||||
|
||||
OR_REG(&pi->regs->maccommand,
|
||||
MCMD_BG_NOISE);
|
||||
bcma_set32(pi->d11core, D11REGOFFS(maccommand),
|
||||
MCMD_BG_NOISE);
|
||||
} else {
|
||||
struct phy_iq_est est[PHY_CORE_MAX];
|
||||
u32 cmplx_pwr[PHY_CORE_MAX];
|
||||
@ -2924,29 +2905,29 @@ void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode)
|
||||
mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
|
||||
|
||||
}
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpiocontrol),
|
||||
~0x0, 0x0);
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpioout), 0x40,
|
||||
0x40);
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpioouten), 0x40,
|
||||
0x40);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpiocontrol),
|
||||
~0x0, 0x0);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpioout),
|
||||
0x40, 0x40);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpioouten),
|
||||
0x40, 0x40);
|
||||
} else {
|
||||
mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2);
|
||||
|
||||
mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
|
||||
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpioout), 0x40,
|
||||
0x00);
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpioouten), 0x40,
|
||||
0x0);
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, gpiocontrol),
|
||||
~0x0, 0x40);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpioout),
|
||||
0x40, 0x00);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpioouten),
|
||||
0x40, 0x0);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, gpiocontrol),
|
||||
~0x0, 0x40);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,6 @@ struct shared_phy_params {
|
||||
struct phy_shim_info *physhim;
|
||||
uint unit;
|
||||
uint corerev;
|
||||
uint buscorerev;
|
||||
u16 vid;
|
||||
u16 did;
|
||||
uint chip;
|
||||
@ -175,7 +174,6 @@ struct shared_phy_params {
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
uint boardvendor;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
};
|
||||
@ -183,7 +181,7 @@ struct shared_phy_params {
|
||||
|
||||
extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
|
||||
extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
|
||||
struct d11regs __iomem *regs,
|
||||
struct bcma_device *d11core,
|
||||
int bandtype, struct wiphy *wiphy);
|
||||
extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
|
||||
|
||||
|
@ -503,10 +503,8 @@ struct shared_phy {
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
uint boardvendor;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
uint buscorerev;
|
||||
uint fast_timer;
|
||||
uint slow_timer;
|
||||
uint glacial_timer;
|
||||
@ -559,7 +557,7 @@ struct brcms_phy {
|
||||
} u;
|
||||
bool user_txpwr_at_rfport;
|
||||
|
||||
struct d11regs __iomem *regs;
|
||||
struct bcma_device *d11core;
|
||||
struct brcms_phy *next;
|
||||
struct brcms_phy_pub pubpi;
|
||||
|
||||
@ -1090,7 +1088,7 @@ extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32,
|
||||
|
||||
#define BRCMS_PHY_WAR_PR51571(pi) \
|
||||
if (NREV_LT((pi)->pubpi.phy_rev, 3)) \
|
||||
(void)R_REG(&(pi)->regs->maccontrol)
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol))
|
||||
|
||||
extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype);
|
||||
extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi);
|
||||
|
@ -2813,10 +2813,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
|
||||
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;
|
||||
idleTssi = read_phy_reg(pi, 0x4ab);
|
||||
suspend =
|
||||
(0 ==
|
||||
(R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) &
|
||||
MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
|
||||
@ -2890,7 +2888,8 @@ static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode)
|
||||
|
||||
for (i = 0; i < 14; i++)
|
||||
values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]);
|
||||
suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4);
|
||||
@ -3016,8 +3015,8 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
|
||||
bool suspend;
|
||||
struct brcms_phy *pi = (struct brcms_phy *) ppi;
|
||||
|
||||
suspend =
|
||||
(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
||||
@ -3535,15 +3534,17 @@ wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
|
||||
timer = 0;
|
||||
old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
|
||||
|
||||
curval1 = R_REG(&pi->regs->psm_corectlsts);
|
||||
curval1 = bcma_read16(pi->d11core, D11REGOFFS(psm_corectlsts));
|
||||
ptr[130] = 0;
|
||||
W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1));
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts),
|
||||
((1 << 6) | curval1));
|
||||
|
||||
W_REG(&pi->regs->smpl_clct_strptr, 0x7E00);
|
||||
W_REG(&pi->regs->smpl_clct_stpptr, 0x8000);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_strptr), 0x7E00);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(smpl_clct_stpptr), 0x8000);
|
||||
udelay(20);
|
||||
curval2 = R_REG(&pi->regs->psm_phy_hdr_param);
|
||||
W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30);
|
||||
curval2 = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
|
||||
curval2 | 0x30);
|
||||
|
||||
write_phy_reg(pi, 0x555, 0x0);
|
||||
write_phy_reg(pi, 0x5a6, 0x5);
|
||||
@ -3560,19 +3561,19 @@ wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
|
||||
|
||||
sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
|
||||
write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008));
|
||||
stpptr = R_REG(&pi->regs->smpl_clct_stpptr);
|
||||
curptr = R_REG(&pi->regs->smpl_clct_curptr);
|
||||
stpptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_stpptr));
|
||||
curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
|
||||
do {
|
||||
udelay(10);
|
||||
curptr = R_REG(&pi->regs->smpl_clct_curptr);
|
||||
curptr = bcma_read16(pi->d11core, D11REGOFFS(smpl_clct_curptr));
|
||||
timer++;
|
||||
} while ((curptr != stpptr) && (timer < 500));
|
||||
|
||||
W_REG(&pi->regs->psm_phy_hdr_param, 0x2);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), 0x2);
|
||||
strptr = 0x7E00;
|
||||
W_REG(&pi->regs->tplatewrptr, strptr);
|
||||
bcma_write32(pi->d11core, D11REGOFFS(tplatewrptr), strptr);
|
||||
while (strptr < 0x8000) {
|
||||
val = R_REG(&pi->regs->tplatewrdata);
|
||||
val = bcma_read32(pi->d11core, D11REGOFFS(tplatewrdata));
|
||||
imag = ((val >> 16) & 0x3ff);
|
||||
real = ((val) & 0x3ff);
|
||||
if (imag > 511)
|
||||
@ -3597,8 +3598,8 @@ wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh,
|
||||
}
|
||||
|
||||
write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
|
||||
W_REG(&pi->regs->psm_phy_hdr_param, curval2);
|
||||
W_REG(&pi->regs->psm_corectlsts, curval1);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), curval2);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_corectlsts), curval1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3968,9 +3969,9 @@ s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode)
|
||||
bool suspend = 0;
|
||||
|
||||
if (mode == 1) {
|
||||
suspend =
|
||||
(0 ==
|
||||
(R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core,
|
||||
D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
|
||||
@ -4012,9 +4013,9 @@ u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode)
|
||||
struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
|
||||
|
||||
if (mode == 1) {
|
||||
suspend =
|
||||
(0 ==
|
||||
(R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core,
|
||||
D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE);
|
||||
@ -4078,9 +4079,9 @@ s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode)
|
||||
bool suspend = 0;
|
||||
|
||||
if (mode == 1) {
|
||||
suspend =
|
||||
(0 ==
|
||||
(R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core,
|
||||
D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE);
|
||||
@ -4127,8 +4128,8 @@ static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi)
|
||||
s8 index;
|
||||
u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
|
||||
struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
|
||||
suspend =
|
||||
(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
wlc_lcnphy_deaf_mode(pi, true);
|
||||
@ -4166,8 +4167,8 @@ static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi)
|
||||
pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec);
|
||||
index = pi_lcn->lcnphy_current_index;
|
||||
|
||||
suspend =
|
||||
(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend) {
|
||||
wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000);
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
@ -17802,7 +17802,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
|
||||
|
||||
if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
|
||||
wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
|
||||
(void)R_REG(&pi->regs->maccontrol);
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
@ -17953,7 +17953,7 @@ static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi)
|
||||
|
||||
if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
|
||||
wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
|
||||
(void)R_REG(&pi->regs->maccontrol);
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
@ -19447,8 +19447,6 @@ void wlc_phy_init_nphy(struct brcms_phy *pi)
|
||||
u8 tx_pwr_ctrl_state;
|
||||
bool do_nphy_cal = false;
|
||||
uint core;
|
||||
uint origidx, intr_val;
|
||||
struct d11regs __iomem *regs;
|
||||
u32 d11_clk_ctl_st;
|
||||
bool do_rssi_cal = false;
|
||||
|
||||
@ -19462,25 +19460,21 @@ void wlc_phy_init_nphy(struct brcms_phy *pi)
|
||||
(pi->sh->chippkg == BCM4718_PKG_ID))) {
|
||||
if ((pi->sh->boardflags & BFL_EXTLNA) &&
|
||||
(CHSPEC_IS2G(pi->radio_chanspec)))
|
||||
ai_corereg(pi->sh->sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol),
|
||||
0x40, 0x40);
|
||||
ai_cc_reg(pi->sh->sih,
|
||||
offsetof(struct chipcregs, chipcontrol),
|
||||
0x40, 0x40);
|
||||
}
|
||||
|
||||
if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
|
||||
CHSPEC_IS40(pi->radio_chanspec)) {
|
||||
|
||||
regs = (struct d11regs __iomem *)
|
||||
ai_switch_core(pi->sh->sih,
|
||||
D11_CORE_ID, &origidx,
|
||||
&intr_val);
|
||||
d11_clk_ctl_st = R_REG(®s->clk_ctl_st);
|
||||
AND_REG(®s->clk_ctl_st,
|
||||
~(CCS_FORCEHT | CCS_HTAREQ));
|
||||
d11_clk_ctl_st = bcma_read32(pi->d11core,
|
||||
D11REGOFFS(clk_ctl_st));
|
||||
bcma_mask32(pi->d11core, D11REGOFFS(clk_ctl_st),
|
||||
~(CCS_FORCEHT | CCS_HTAREQ));
|
||||
|
||||
W_REG(®s->clk_ctl_st, d11_clk_ctl_st);
|
||||
|
||||
ai_restore_core(pi->sh->sih, origidx, intr_val);
|
||||
bcma_write32(pi->d11core, D11REGOFFS(clk_ctl_st),
|
||||
d11_clk_ctl_st);
|
||||
}
|
||||
|
||||
pi->use_int_tx_iqlo_cal_nphy =
|
||||
@ -19885,7 +19879,8 @@ void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
|
||||
if (!pi->sh->clk)
|
||||
return;
|
||||
|
||||
suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!suspend)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
||||
@ -21263,28 +21258,28 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
|
||||
val = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand;
|
||||
if (CHSPEC_IS5G(chanspec) && !val) {
|
||||
|
||||
val = R_REG(&pi->regs->psm_phy_hdr_param);
|
||||
W_REG(&pi->regs->psm_phy_hdr_param,
|
||||
val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
|
||||
(val | MAC_PHY_FORCE_CLK));
|
||||
|
||||
or_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
|
||||
(BBCFG_RESETCCA | BBCFG_RESETRX));
|
||||
|
||||
W_REG(&pi->regs->psm_phy_hdr_param, val);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
|
||||
|
||||
or_phy_reg(pi, 0x09, NPHY_BandControl_currentBand);
|
||||
} else if (!CHSPEC_IS5G(chanspec) && val) {
|
||||
|
||||
and_phy_reg(pi, 0x09, ~NPHY_BandControl_currentBand);
|
||||
|
||||
val = R_REG(&pi->regs->psm_phy_hdr_param);
|
||||
W_REG(&pi->regs->psm_phy_hdr_param,
|
||||
val = bcma_read16(pi->d11core, D11REGOFFS(psm_phy_hdr_param));
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param),
|
||||
(val | MAC_PHY_FORCE_CLK));
|
||||
|
||||
and_phy_reg(pi, (NPHY_TO_BPHY_OFF + BPHY_BB_CONFIG),
|
||||
(u16) (~(BBCFG_RESETCCA | BBCFG_RESETRX)));
|
||||
|
||||
W_REG(&pi->regs->psm_phy_hdr_param, val);
|
||||
bcma_write16(pi->d11core, D11REGOFFS(psm_phy_hdr_param), val);
|
||||
}
|
||||
|
||||
write_phy_reg(pi, 0x1ce, ci->PHY_BW1a);
|
||||
@ -21342,24 +21337,23 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec,
|
||||
spuravoid = 1;
|
||||
|
||||
wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false);
|
||||
si_pmu_spuravoid(pi->sh->sih, spuravoid);
|
||||
si_pmu_spuravoid_pllupdate(pi->sh->sih, spuravoid);
|
||||
wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true);
|
||||
|
||||
if ((pi->sh->chip == BCM43224_CHIP_ID) ||
|
||||
(pi->sh->chip == BCM43225_CHIP_ID)) {
|
||||
|
||||
if (spuravoid == 1) {
|
||||
|
||||
W_REG(&pi->regs->tsf_clk_frac_l,
|
||||
0x5341);
|
||||
W_REG(&pi->regs->tsf_clk_frac_h,
|
||||
0x8);
|
||||
bcma_write16(pi->d11core,
|
||||
D11REGOFFS(tsf_clk_frac_l),
|
||||
0x5341);
|
||||
bcma_write16(pi->d11core,
|
||||
D11REGOFFS(tsf_clk_frac_h), 0x8);
|
||||
} else {
|
||||
|
||||
W_REG(&pi->regs->tsf_clk_frac_l,
|
||||
0x8889);
|
||||
W_REG(&pi->regs->tsf_clk_frac_h,
|
||||
0x8);
|
||||
bcma_write16(pi->d11core,
|
||||
D11REGOFFS(tsf_clk_frac_l),
|
||||
0x8889);
|
||||
bcma_write16(pi->d11core,
|
||||
D11REGOFFS(tsf_clk_frac_h), 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21499,13 +21493,13 @@ void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
|
||||
|
||||
ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
|
||||
|
||||
mc = R_REG(&pi->regs->maccontrol);
|
||||
mc = bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
mc &= ~MCTL_GPOUT_SEL_MASK;
|
||||
W_REG(&pi->regs->maccontrol, mc);
|
||||
bcma_write32(pi->d11core, D11REGOFFS(maccontrol), mc);
|
||||
|
||||
OR_REG(&pi->regs->psm_gpio_oe, mask);
|
||||
bcma_set16(pi->d11core, D11REGOFFS(psm_gpio_oe), mask);
|
||||
|
||||
AND_REG(&pi->regs->psm_gpio_out, ~mask);
|
||||
bcma_mask16(pi->d11core, D11REGOFFS(psm_gpio_out), ~mask);
|
||||
|
||||
if (lut_init) {
|
||||
write_phy_reg(pi, 0xf8, 0x02d8);
|
||||
@ -21522,9 +21516,8 @@ u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val)
|
||||
bool suspended = false;
|
||||
|
||||
if (D11REV_IS(pi->sh->corerev, 16)) {
|
||||
suspended =
|
||||
(R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ?
|
||||
false : true;
|
||||
suspended = (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC) ? false : true;
|
||||
if (!suspended)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
}
|
||||
@ -25383,7 +25376,8 @@ static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal)
|
||||
if (pi->nphy_papd_skip == 1)
|
||||
return;
|
||||
|
||||
phy_b3 = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
|
||||
phy_b3 = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
|
||||
MCTL_EN_MAC));
|
||||
if (!phy_b3)
|
||||
wlapi_suspend_mac_and_wait(pi->sh->physhim);
|
||||
|
||||
@ -28357,7 +28351,7 @@ void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi)
|
||||
|
||||
if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) {
|
||||
wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK);
|
||||
(void)R_REG(&pi->regs->maccontrol);
|
||||
(void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
|
@ -115,10 +115,10 @@ static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
|
||||
uint rsrcs;
|
||||
|
||||
/* # resources */
|
||||
rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
|
||||
rsrcs = (ai_get_pmucaps(sih) & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
|
||||
|
||||
/* determine min/max rsrc masks */
|
||||
switch (sih->chip) {
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
@ -139,75 +139,84 @@ static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
|
||||
*pmax = max_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs __iomem *cc,
|
||||
u8 spuravoid)
|
||||
void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
struct bcma_device *core;
|
||||
|
||||
switch (sih->chip) {
|
||||
/* switch to chipc */
|
||||
core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
if (spuravoid == 1) {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11500010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000C0C06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x0F600a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x2001E920);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL0);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x11500010);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL1);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x000C0C06);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL2);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x0F600a08);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL3);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x00000000);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL4);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x2001E920);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL5);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x88888815);
|
||||
} else {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000c0c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL0);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x11100010);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL1);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x000c0c06);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL2);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x03000a08);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL3);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x00000000);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL4);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x200005c0);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_addr),
|
||||
PMU1_PLL0_PLLCTL5);
|
||||
bcma_write32(core, CHIPCREGOFFS(pllcontrol_data),
|
||||
0x88888815);
|
||||
}
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100008);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x0c000c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888855);
|
||||
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
tmp |= R_REG(&cc->pmucontrol);
|
||||
W_REG(&cc->pmucontrol, tmp);
|
||||
bcma_set32(core, CHIPCREGOFFS(pmucontrol), tmp);
|
||||
}
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
uint delay = PMU_MAX_TRANSITION_DLY;
|
||||
|
||||
switch (sih->chip) {
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
@ -220,54 +229,35 @@ u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
return (u16) delay;
|
||||
}
|
||||
|
||||
void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* Read/write a chipcontrol reg */
|
||||
u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data), mask,
|
||||
val);
|
||||
ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, reg);
|
||||
return ai_cc_reg(sih, offsetof(struct chipcregs, chipcontrol_data),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
/* Read/write a regcontrol reg */
|
||||
u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, regcontrol_data), mask,
|
||||
val);
|
||||
ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_addr), ~0, reg);
|
||||
return ai_cc_reg(sih, offsetof(struct chipcregs, regcontrol_data),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
/* Read/write a pllcontrol reg */
|
||||
u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, pllcontrol_data), mask,
|
||||
val);
|
||||
ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_addr), ~0, reg);
|
||||
return ai_cc_reg(sih, offsetof(struct chipcregs, pllcontrol_data),
|
||||
mask, val);
|
||||
}
|
||||
|
||||
/* PMU PLL update */
|
||||
void si_pmu_pllupd(struct si_pub *sih)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol),
|
||||
PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
|
||||
ai_cc_reg(sih, offsetof(struct chipcregs, pmucontrol),
|
||||
PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
|
||||
}
|
||||
|
||||
/* query alp/xtal clock frequency */
|
||||
@ -276,10 +266,10 @@ u32 si_pmu_alp_clock(struct si_pub *sih)
|
||||
u32 clock = ALP_CLOCK;
|
||||
|
||||
/* bail out with default */
|
||||
if (!(sih->cccaps & CC_CAP_PMU))
|
||||
if (!(ai_get_cccaps(sih) & CC_CAP_PMU))
|
||||
return clock;
|
||||
|
||||
switch (sih->chip) {
|
||||
switch (ai_get_chip_id(sih)) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
@ -293,95 +283,29 @@ u32 si_pmu_alp_clock(struct si_pub *sih)
|
||||
return clock;
|
||||
}
|
||||
|
||||
void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx, intr_val;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
cc = (struct chipcregs __iomem *)
|
||||
ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
|
||||
|
||||
/* update the pll changes */
|
||||
si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
|
||||
|
||||
/* Return to original core */
|
||||
ai_restore_core(sih, origidx, intr_val);
|
||||
}
|
||||
|
||||
/* initialize PMU */
|
||||
void si_pmu_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
struct bcma_device *core;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
/* select chipc */
|
||||
core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
|
||||
if (sih->pmurev == 1)
|
||||
AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
|
||||
else if (sih->pmurev >= 2)
|
||||
OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU chip controls and other chip level stuff */
|
||||
void si_pmu_chip_init(struct si_pub *sih)
|
||||
{
|
||||
uint origidx;
|
||||
|
||||
/* Gate off SPROM clock and chip select signals */
|
||||
si_pmu_sprom_enable(sih, false);
|
||||
|
||||
/* Remember original core */
|
||||
origidx = ai_coreidx(sih);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU switch/regulators */
|
||||
void si_pmu_swreg_init(struct si_pub *sih)
|
||||
{
|
||||
}
|
||||
|
||||
/* initialize PLL */
|
||||
void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM4313_CHIP_ID:
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
if (ai_get_pmurev(sih) == 1)
|
||||
bcma_mask32(core, CHIPCREGOFFS(pmucontrol),
|
||||
~PCTL_NOILP_ON_WAIT);
|
||||
else if (ai_get_pmurev(sih) >= 2)
|
||||
bcma_set32(core, CHIPCREGOFFS(pmucontrol), PCTL_NOILP_ON_WAIT);
|
||||
}
|
||||
|
||||
/* initialize PMU resources */
|
||||
void si_pmu_res_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
struct bcma_device *core;
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
/* select to chipc */
|
||||
core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
|
||||
/* Determine min/max rsrc masks */
|
||||
si_pmu_res_masks(sih, &min_mask, &max_mask);
|
||||
@ -391,55 +315,50 @@ void si_pmu_res_init(struct si_pub *sih)
|
||||
/* Program max resource mask */
|
||||
|
||||
if (max_mask)
|
||||
W_REG(&cc->max_res_mask, max_mask);
|
||||
bcma_write32(core, CHIPCREGOFFS(max_res_mask), max_mask);
|
||||
|
||||
/* Program min resource mask */
|
||||
|
||||
if (min_mask)
|
||||
W_REG(&cc->min_res_mask, min_mask);
|
||||
bcma_write32(core, CHIPCREGOFFS(min_res_mask), min_mask);
|
||||
|
||||
/* Add some delay; allow resources to come up and settle. */
|
||||
mdelay(2);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
struct bcma_device *core;
|
||||
u32 alp_khz;
|
||||
|
||||
if (sih->pmurev < 10)
|
||||
if (ai_get_pmurev(sih) < 10)
|
||||
return 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
|
||||
if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
|
||||
if (bcma_read32(core, CHIPCREGOFFS(pmustatus)) & PST_EXTLPOAVAIL) {
|
||||
u32 ilp_ctr, alp_hz;
|
||||
|
||||
/*
|
||||
* Enable the reg to measure the freq,
|
||||
* in case it was disabled before
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq,
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq),
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
|
||||
/* Delay for well over 4 ILP clocks */
|
||||
udelay(1000);
|
||||
|
||||
/* Read the latched number of ALP ticks per 4 ILP ticks */
|
||||
ilp_ctr =
|
||||
R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
ilp_ctr = bcma_read32(core, CHIPCREGOFFS(pmu_xtalfreq)) &
|
||||
PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
|
||||
/*
|
||||
* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
|
||||
* bit to save power
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq, 0);
|
||||
bcma_write32(core, CHIPCREGOFFS(pmu_xtalfreq), 0);
|
||||
|
||||
/* Calculate ALP frequency */
|
||||
alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
|
||||
@ -452,8 +371,5 @@ u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
} else
|
||||
alp_khz = 0;
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
|
||||
return alp_khz;
|
||||
}
|
||||
|
@ -26,13 +26,10 @@ extern u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern u32 si_pmu_alp_clock(struct si_pub *sih);
|
||||
extern void si_pmu_pllupd(struct si_pub *sih);
|
||||
extern void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid);
|
||||
extern void si_pmu_spuravoid_pllupdate(struct si_pub *sih, u8 spuravoid);
|
||||
extern u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val);
|
||||
extern void si_pmu_init(struct si_pub *sih);
|
||||
extern void si_pmu_chip_init(struct si_pub *sih);
|
||||
extern void si_pmu_pll_init(struct si_pub *sih, u32 xtalfreq);
|
||||
extern void si_pmu_res_init(struct si_pub *sih);
|
||||
extern void si_pmu_swreg_init(struct si_pub *sih);
|
||||
extern u32 si_pmu_measure_alpclk(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_PMU_H_ */
|
||||
|
@ -17,6 +17,7 @@
|
||||
#ifndef _BRCM_PUB_H_
|
||||
#define _BRCM_PUB_H_
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include "types.h"
|
||||
#include "defs.h"
|
||||
@ -530,9 +531,8 @@ struct brcms_antselcfg {
|
||||
|
||||
/* common functions for every port */
|
||||
extern struct brcms_c_info *
|
||||
brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
|
||||
bool piomode, void __iomem *regsva, struct pci_dev *btparam,
|
||||
uint *perr);
|
||||
brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit,
|
||||
bool piomode, uint *perr);
|
||||
extern uint brcms_c_detach(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_up(struct brcms_c_info *wlc);
|
||||
extern uint brcms_c_down(struct brcms_c_info *wlc);
|
||||
|
@ -586,17 +586,6 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = {
|
||||
* shared between devices. */
|
||||
static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE];
|
||||
|
||||
static u8 __iomem *
|
||||
srom_window_address(struct si_pub *sih, u8 __iomem *curmap)
|
||||
{
|
||||
if (sih->ccrev < 32)
|
||||
return curmap + PCI_BAR0_SPROM_OFFSET;
|
||||
if (sih->cccaps & CC_CAP_SROM)
|
||||
return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint mask_shift(u16 mask)
|
||||
{
|
||||
uint i;
|
||||
@ -779,17 +768,27 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list)
|
||||
* Return 0 on success, nonzero on error.
|
||||
*/
|
||||
static int
|
||||
sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff,
|
||||
u16 *buf, uint nwords, bool check_crc)
|
||||
sprom_read_pci(struct si_pub *sih, u16 *buf, uint nwords, bool check_crc)
|
||||
{
|
||||
int err = 0;
|
||||
uint i;
|
||||
u8 *bbuf = (u8 *)buf; /* byte buffer */
|
||||
uint nbytes = nwords << 1;
|
||||
struct bcma_device *core;
|
||||
uint sprom_offset;
|
||||
|
||||
/* determine core to read */
|
||||
if (ai_get_ccrev(sih) < 32) {
|
||||
core = ai_findcore(sih, BCMA_CORE_80211, 0);
|
||||
sprom_offset = PCI_BAR0_SPROM_OFFSET;
|
||||
} else {
|
||||
core = ai_findcore(sih, BCMA_CORE_CHIPCOMMON, 0);
|
||||
sprom_offset = CHIPCREGOFFS(sromotp);
|
||||
}
|
||||
|
||||
/* read the sprom in bytes */
|
||||
for (i = 0; i < nbytes; i++)
|
||||
bbuf[i] = readb(sprom+i);
|
||||
bbuf[i] = bcma_read8(core, sprom_offset+i);
|
||||
|
||||
if (buf[0] == 0xffff)
|
||||
/*
|
||||
@ -851,10 +850,9 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords)
|
||||
* Initialize nonvolatile variable table from sprom.
|
||||
* Return 0 on success, nonzero on error.
|
||||
*/
|
||||
static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
|
||||
int srom_var_init(struct si_pub *sih)
|
||||
{
|
||||
u16 *srom;
|
||||
u8 __iomem *sromwindow;
|
||||
u8 sromrev = 0;
|
||||
u32 sr;
|
||||
int err = 0;
|
||||
@ -866,12 +864,9 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap)
|
||||
if (!srom)
|
||||
return -ENOMEM;
|
||||
|
||||
sromwindow = srom_window_address(sih, curmap);
|
||||
|
||||
crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY);
|
||||
if (ai_is_sprom_available(sih)) {
|
||||
err = sprom_read_pci(sih, sromwindow, 0, srom,
|
||||
SROM4_WORDS, true);
|
||||
err = sprom_read_pci(sih, srom, SROM4_WORDS, true);
|
||||
|
||||
if (err == 0)
|
||||
/* srom read and passed crc */
|
||||
@ -921,21 +916,6 @@ void srom_free_vars(struct si_pub *sih)
|
||||
kfree(entry);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Initialize local vars from the right source for this platform.
|
||||
* Return 0 on success, nonzero on error.
|
||||
*/
|
||||
int srom_var_init(struct si_pub *sih, void __iomem *curmap)
|
||||
{
|
||||
uint len;
|
||||
|
||||
len = 0;
|
||||
|
||||
if (curmap != NULL)
|
||||
return initvars_srom_pci(sih, curmap);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search the name=value vars for a specific one and return its value.
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "types.h"
|
||||
|
||||
/* Prototypes */
|
||||
extern int srom_var_init(struct si_pub *sih, void __iomem *curmap);
|
||||
extern int srom_var_init(struct si_pub *sih);
|
||||
extern void srom_free_vars(struct si_pub *sih);
|
||||
|
||||
extern int srom_read(struct si_pub *sih, uint bus, void *curmap,
|
||||
|
@ -250,66 +250,18 @@ do { \
|
||||
wiphy_err(dev, "%s: " fmt, __func__, ##args); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Register access macros.
|
||||
*
|
||||
* These macro's take a pointer to the address to read as one of their
|
||||
* arguments. The macro itself deduces the size of the IO transaction (u8, u16
|
||||
* or u32). Advantage of this approach in combination with using a struct to
|
||||
* define the registers in a register block, is that access size and access
|
||||
* location are defined in only one spot. This reduces the risk of the
|
||||
* programmer trying to use an unsupported transaction size on a register.
|
||||
*
|
||||
*/
|
||||
|
||||
#define R_REG(r) \
|
||||
({ \
|
||||
__typeof(*(r)) __osl_v; \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
__osl_v = readb((u8 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
__osl_v = readw((u16 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
__osl_v = readl((u32 __iomem *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
__osl_v; \
|
||||
})
|
||||
|
||||
#define W_REG(r, v) do { \
|
||||
switch (sizeof(*(r))) { \
|
||||
case sizeof(u8): \
|
||||
writeb((u8)((v) & 0xFF), (u8 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u16): \
|
||||
writew((u16)((v) & 0xFFFF), (u16 __iomem *)(r)); \
|
||||
break; \
|
||||
case sizeof(u32): \
|
||||
writel((u32)(v), (u32 __iomem *)(r)); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef CONFIG_BCM47XX
|
||||
/*
|
||||
* bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder
|
||||
* transactions. As a fix, a read after write is performed on certain places
|
||||
* in the code. Older chips and the newer 5357 family don't require this fix.
|
||||
*/
|
||||
#define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); })
|
||||
#define bcma_wflush16(c, o, v) \
|
||||
({ bcma_write16(c, o, v); (void)bcma_read16(c, o); })
|
||||
#else
|
||||
#define W_REG_FLUSH(r, v) W_REG((r), (v))
|
||||
#define bcma_wflush16(c, o, v) bcma_write16(c, o, v)
|
||||
#endif /* CONFIG_BCM47XX */
|
||||
|
||||
#define AND_REG(r, v) W_REG((r), R_REG(r) & (v))
|
||||
#define OR_REG(r, v) W_REG((r), R_REG(r) | (v))
|
||||
|
||||
#define SET_REG(r, mask, val) \
|
||||
W_REG((r), ((R_REG(r) & ~(mask)) | (val)))
|
||||
|
||||
/* multi-bool data type: set of bools, mbool is true if any is set */
|
||||
|
||||
/* set one bool */
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "defs.h" /* for PAD macro */
|
||||
|
||||
#define CHIPCREGOFFS(field) offsetof(struct chipcregs, field)
|
||||
|
||||
struct chipcregs {
|
||||
u32 chipid; /* 0x0 */
|
||||
u32 capabilities;
|
||||
|
@ -102,12 +102,28 @@ config IWLWIFI_DEVICE_TRACING
|
||||
occur.
|
||||
endmenu
|
||||
|
||||
config IWLWIFI_DEVICE_SVTOOL
|
||||
bool "iwlwifi device svtool support"
|
||||
config IWLWIFI_DEVICE_TESTMODE
|
||||
def_bool y
|
||||
depends on IWLWIFI
|
||||
select NL80211_TESTMODE
|
||||
depends on NL80211_TESTMODE
|
||||
help
|
||||
This option enables the svtool support for iwlwifi device through
|
||||
NL80211_TESTMODE. svtool is a software validation tool that runs in
|
||||
the user space and interacts with the device in the kernel space
|
||||
through the generic netlink message via NL80211_TESTMODE channel.
|
||||
This option enables the testmode support for iwlwifi device through
|
||||
NL80211_TESTMODE. This provide the capabilities of enable user space
|
||||
validation applications to interacts with the device through the
|
||||
generic netlink message via NL80211_TESTMODE channel.
|
||||
|
||||
config IWLWIFI_P2P
|
||||
bool "iwlwifi experimental P2P support"
|
||||
depends on IWLWIFI
|
||||
help
|
||||
This option enables experimental P2P support for some devices
|
||||
based on microcode support. Since P2P support is still under
|
||||
development, this option may even enable it for some devices
|
||||
now that turn out to not support it in the future due to
|
||||
microcode restrictions.
|
||||
|
||||
To determine if your microcode supports the experimental P2P
|
||||
offered by this option, check if the driver advertises AP
|
||||
support when it is loaded.
|
||||
|
||||
Say Y only if you want to experiment with P2P.
|
||||
|
@ -18,7 +18,7 @@ iwlwifi-objs += iwl-trans-pcie.o iwl-trans-pcie-rx.o iwl-trans-pcie-tx.o
|
||||
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-testmode.o
|
||||
iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-testmode.o
|
||||
|
||||
CFLAGS_iwl-devtrace.o := -I$(src)
|
||||
|
||||
|
@ -134,10 +134,10 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
|
||||
|
||||
#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF (-5)
|
||||
|
||||
static s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
|
||||
static s32 iwl_temp_calib_to_offset(struct iwl_shared *shrd)
|
||||
{
|
||||
u16 temperature, voltage;
|
||||
__le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(priv,
|
||||
__le16 *temp_calib = (__le16 *)iwl_eeprom_query_addr(shrd,
|
||||
EEPROM_KELVIN_TEMPERATURE);
|
||||
|
||||
temperature = le16_to_cpu(temp_calib[0]);
|
||||
@ -151,7 +151,7 @@ static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
|
||||
{
|
||||
const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
|
||||
s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
|
||||
iwl_temp_calib_to_offset(priv);
|
||||
iwl_temp_calib_to_offset(priv->shrd);
|
||||
|
||||
hw_params(priv).ct_kill_threshold = threshold * volt2temp_coef;
|
||||
}
|
||||
@ -223,7 +223,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
|
||||
static void iwl5150_temperature(struct iwl_priv *priv)
|
||||
{
|
||||
u32 vt = 0;
|
||||
s32 offset = iwl_temp_calib_to_offset(priv);
|
||||
s32 offset = iwl_temp_calib_to_offset(priv->shrd);
|
||||
|
||||
vt = le32_to_cpu(priv->statistics.common.temperature);
|
||||
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
|
||||
|
@ -81,7 +81,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (iwlagn_eeprom_calib_version(priv) >= 6)
|
||||
if (iwl_eeprom_calib_version(priv->shrd) >= 6)
|
||||
iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
}
|
||||
@ -89,7 +89,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
|
||||
static void iwl6150_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (iwlagn_eeprom_calib_version(priv) >= 6)
|
||||
if (iwl_eeprom_calib_version(priv->shrd) >= 6)
|
||||
iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG,
|
||||
|
@ -82,7 +82,7 @@ struct statistics_general_data {
|
||||
u32 beacon_energy_c;
|
||||
};
|
||||
|
||||
int iwl_send_calib_results(struct iwl_priv *priv)
|
||||
int iwl_send_calib_results(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.id = REPLY_PHY_CALIBRATION_CMD,
|
||||
@ -90,15 +90,15 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
||||
};
|
||||
struct iwl_calib_result *res;
|
||||
|
||||
list_for_each_entry(res, &priv->calib_results, list) {
|
||||
list_for_each_entry(res, &trans->calib_results, list) {
|
||||
int ret;
|
||||
|
||||
hcmd.len[0] = res->cmd_len;
|
||||
hcmd.data[0] = &res->hdr;
|
||||
hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
|
||||
ret = iwl_trans_send_cmd(trans(priv), &hcmd);
|
||||
ret = iwl_trans_send_cmd(trans, &hcmd);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error %d on calib cmd %d\n",
|
||||
IWL_ERR(trans, "Error %d on calib cmd %d\n",
|
||||
ret, res->hdr.op_code);
|
||||
return ret;
|
||||
}
|
||||
@ -107,7 +107,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_calib_set(struct iwl_priv *priv,
|
||||
int iwl_calib_set(struct iwl_trans *trans,
|
||||
const struct iwl_calib_hdr *cmd, int len)
|
||||
{
|
||||
struct iwl_calib_result *res, *tmp;
|
||||
@ -119,7 +119,7 @@ int iwl_calib_set(struct iwl_priv *priv,
|
||||
memcpy(&res->hdr, cmd, len);
|
||||
res->cmd_len = len;
|
||||
|
||||
list_for_each_entry(tmp, &priv->calib_results, list) {
|
||||
list_for_each_entry(tmp, &trans->calib_results, list) {
|
||||
if (tmp->hdr.op_code == res->hdr.op_code) {
|
||||
list_replace(&tmp->list, &res->list);
|
||||
kfree(tmp);
|
||||
@ -128,16 +128,16 @@ int iwl_calib_set(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
/* wasn't in list already */
|
||||
list_add_tail(&res->list, &priv->calib_results);
|
||||
list_add_tail(&res->list, &trans->calib_results);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwl_calib_free_results(struct iwl_priv *priv)
|
||||
void iwl_calib_free_results(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_calib_result *res, *tmp;
|
||||
|
||||
list_for_each_entry_safe(res, tmp, &priv->calib_results, list) {
|
||||
list_for_each_entry_safe(res, tmp, &trans->calib_results, list) {
|
||||
list_del(&res->list);
|
||||
kfree(res);
|
||||
}
|
||||
|
@ -72,9 +72,4 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv);
|
||||
void iwl_init_sensitivity(struct iwl_priv *priv);
|
||||
void iwl_reset_run_time_calib(struct iwl_priv *priv);
|
||||
|
||||
int iwl_send_calib_results(struct iwl_priv *priv);
|
||||
int iwl_calib_set(struct iwl_priv *priv,
|
||||
const struct iwl_calib_hdr *cmd, int len);
|
||||
void iwl_calib_free_results(struct iwl_priv *priv);
|
||||
|
||||
#endif /* __iwl_calib_h__ */
|
||||
|
@ -92,11 +92,11 @@ void iwlagn_temperature(struct iwl_priv *priv)
|
||||
iwl_tt_handler(priv);
|
||||
}
|
||||
|
||||
u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
|
||||
u16 iwl_eeprom_calib_version(struct iwl_shared *shrd)
|
||||
{
|
||||
struct iwl_eeprom_calib_hdr *hdr;
|
||||
|
||||
hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
|
||||
hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(shrd,
|
||||
EEPROM_CALIB_ALL);
|
||||
return hdr->version;
|
||||
|
||||
@ -105,7 +105,7 @@ u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
|
||||
/*
|
||||
* EEPROM
|
||||
*/
|
||||
static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
|
||||
static u32 eeprom_indirect_address(const struct iwl_shared *shrd, u32 address)
|
||||
{
|
||||
u16 offset = 0;
|
||||
|
||||
@ -114,31 +114,31 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
|
||||
|
||||
switch (address & INDIRECT_TYPE_MSK) {
|
||||
case INDIRECT_HOST:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_HOST);
|
||||
break;
|
||||
case INDIRECT_GENERAL:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_GENERAL);
|
||||
break;
|
||||
case INDIRECT_REGULATORY:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_REGULATORY);
|
||||
break;
|
||||
case INDIRECT_TXP_LIMIT:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT);
|
||||
break;
|
||||
case INDIRECT_TXP_LIMIT_SIZE:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_TXP_LIMIT_SIZE);
|
||||
break;
|
||||
case INDIRECT_CALIBRATION:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_CALIBRATION);
|
||||
break;
|
||||
case INDIRECT_PROCESS_ADJST:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_PROCESS_ADJST);
|
||||
break;
|
||||
case INDIRECT_OTHERS:
|
||||
offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
|
||||
offset = iwl_eeprom_query16(shrd, EEPROM_LINK_OTHERS);
|
||||
break;
|
||||
default:
|
||||
IWL_ERR(priv, "illegal indirect type: 0x%X\n",
|
||||
IWL_ERR(shrd->trans, "illegal indirect type: 0x%X\n",
|
||||
address & INDIRECT_TYPE_MSK);
|
||||
break;
|
||||
}
|
||||
@ -147,11 +147,11 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
|
||||
return (address & ADDRESS_MSK) + (offset << 1);
|
||||
}
|
||||
|
||||
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
|
||||
const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset)
|
||||
{
|
||||
u32 address = eeprom_indirect_address(priv, offset);
|
||||
BUG_ON(address >= priv->cfg->base_params->eeprom_size);
|
||||
return &priv->eeprom[address];
|
||||
u32 address = eeprom_indirect_address(shrd, offset);
|
||||
BUG_ON(address >= shrd->priv->cfg->base_params->eeprom_size);
|
||||
return &shrd->eeprom[address];
|
||||
}
|
||||
|
||||
struct iwl_mod_params iwlagn_mod_params = {
|
||||
@ -1157,7 +1157,7 @@ int iwlagn_suspend(struct iwl_priv *priv,
|
||||
* For QoS counters, we store the one to use next, so subtract 0x10
|
||||
* since the uCode will add 0x10 before using the value.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
|
||||
seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number;
|
||||
seq -= 0x10;
|
||||
wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq);
|
||||
|
@ -298,7 +298,7 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
|
||||
} else
|
||||
return IWL_MAX_TID_COUNT;
|
||||
|
||||
if (unlikely(tid >= TID_MAX_LOAD_COUNT))
|
||||
if (unlikely(tid >= IWL_MAX_TID_COUNT))
|
||||
return IWL_MAX_TID_COUNT;
|
||||
|
||||
tl = &lq_data->load[tid];
|
||||
@ -352,7 +352,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
|
||||
lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
|
||||
lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
/* testmode has higher priority to overwirte the fixed rate */
|
||||
if (priv->tm_fixed_rate)
|
||||
lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
|
||||
@ -379,7 +379,7 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
s32 index;
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
|
||||
if (tid >= TID_MAX_LOAD_COUNT)
|
||||
if (tid >= IWL_MAX_TID_COUNT)
|
||||
return 0;
|
||||
|
||||
tl = &(lq_data->load[tid]);
|
||||
@ -444,11 +444,11 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
|
||||
struct iwl_lq_sta *lq_data,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
if (tid < TID_MAX_LOAD_COUNT)
|
||||
if (tid < IWL_MAX_TID_COUNT)
|
||||
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
|
||||
else
|
||||
IWL_ERR(priv, "tid exceeds max load count: %d/%d\n",
|
||||
tid, TID_MAX_LOAD_COUNT);
|
||||
IWL_ERR(priv, "tid exceeds max TID count: %d/%d\n",
|
||||
tid, IWL_MAX_TID_COUNT);
|
||||
}
|
||||
|
||||
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
|
||||
@ -1081,7 +1081,7 @@ done:
|
||||
if (sta && sta->supp_rates[sband->band])
|
||||
rs_rate_scale_perform(priv, skb, sta, lq_sta);
|
||||
|
||||
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_SVTOOL)
|
||||
#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE)
|
||||
if ((priv->tm_fixed_rate) &&
|
||||
(priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
|
||||
rs_program_fix_rate(priv, lq_sta);
|
||||
@ -2904,7 +2904,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
|
||||
if (sband->band == IEEE80211_BAND_5GHZ)
|
||||
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
|
||||
lq_sta->is_agg = 0;
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
priv->tm_fixed_rate = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
|
@ -281,7 +281,6 @@ enum {
|
||||
#define TID_QUEUE_CELL_SPACING 50 /*mS */
|
||||
#define TID_QUEUE_MAX_SIZE 20
|
||||
#define TID_ROUND_VALUE 5 /* mS */
|
||||
#define TID_MAX_LOAD_COUNT 8
|
||||
|
||||
#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
|
||||
#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
|
||||
@ -402,7 +401,7 @@ struct iwl_lq_sta {
|
||||
|
||||
struct iwl_link_quality_cmd lq;
|
||||
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
|
||||
struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
|
||||
struct iwl_traffic_load load[IWL_MAX_TID_COUNT];
|
||||
u8 tx_agg_tid_en;
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
struct dentry *rs_sta_dbgfs_scale_table_file;
|
||||
|
@ -1165,7 +1165,7 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
|
||||
pkt->hdr.cmd);
|
||||
w->triggered = true;
|
||||
if (w->fn)
|
||||
w->fn(priv, pkt, w->fn_data);
|
||||
w->fn(trans(priv), pkt, w->fn_data);
|
||||
}
|
||||
spin_unlock(&priv->shrd->notif_wait_lock);
|
||||
|
||||
|
@ -610,8 +610,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||
if (ctx->ht.enabled) {
|
||||
/* if HT40 is used, it should not change
|
||||
* after associated except channel switch */
|
||||
if (iwl_is_associated_ctx(ctx) &&
|
||||
!ctx->ht.is_40mhz)
|
||||
if (!ctx->ht.is_40mhz ||
|
||||
!iwl_is_associated_ctx(ctx))
|
||||
iwlagn_config_ht40(conf, ctx);
|
||||
} else
|
||||
ctx->ht.is_40mhz = false;
|
||||
|
@ -135,8 +135,8 @@ static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
|
||||
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
|
||||
struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
|
||||
memcpy(addsta, cmd, size);
|
||||
/* resrved in 5000 */
|
||||
addsta->rate_n_flags = cpu_to_le16(0);
|
||||
/* resrved in agn */
|
||||
addsta->legacy_reserved = cpu_to_le16(0);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,10 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
|
||||
tx_cmd->tid_tspec = qc[0] & 0xf;
|
||||
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
} else {
|
||||
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
|
||||
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
else
|
||||
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
|
||||
}
|
||||
|
||||
iwlagn_tx_cmd_protection(priv, info, fc, &tx_flags);
|
||||
@ -148,7 +151,7 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
|
||||
if (ieee80211_is_data(fc)) {
|
||||
tx_cmd->initial_rate_index = 0;
|
||||
tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
if (priv->tm_fixed_rate) {
|
||||
/*
|
||||
* rate overwrite by testmode
|
||||
@ -161,7 +164,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
} else if (ieee80211_is_back_req(fc))
|
||||
tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
|
||||
|
||||
/**
|
||||
* If the current TX rate stored in mac80211 has the MCS bit set, it's
|
||||
|
@ -366,7 +366,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv)
|
||||
u32 num_wraps; /* # times uCode wrapped to top of log */
|
||||
u32 next_entry; /* index of next entry to be written by uCode */
|
||||
|
||||
base = priv->device_pointers.error_event_table;
|
||||
base = priv->shrd->device_pointers.error_event_table;
|
||||
if (iwlagn_hw_valid_rtc_data_addr(base)) {
|
||||
capacity = iwl_read_targ_mem(bus(priv), base);
|
||||
num_wraps = iwl_read_targ_mem(bus(priv),
|
||||
@ -1036,6 +1036,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
priv->inst_evtlog_size =
|
||||
priv->cfg->base_params->max_event_log_size;
|
||||
priv->inst_errlog_ptr = pieces.inst_errlog_ptr;
|
||||
#ifndef CONFIG_IWLWIFI_P2P
|
||||
ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN;
|
||||
#endif
|
||||
|
||||
priv->new_scan_threshold_behaviour =
|
||||
!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
|
||||
@ -1057,7 +1060,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
priv->sta_key_max_num = STA_KEY_MAX_NUM;
|
||||
priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out the offset of chain noise reset and gain commands
|
||||
* base on the size of standard phy calibration commands table size
|
||||
@ -1575,7 +1577,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
|
||||
|
||||
mutex_init(&priv->shrd->mutex);
|
||||
|
||||
INIT_LIST_HEAD(&priv->calib_results);
|
||||
INIT_LIST_HEAD(&trans(priv)->calib_results);
|
||||
|
||||
priv->ieee_channels = NULL;
|
||||
priv->ieee_rates = NULL;
|
||||
@ -1633,7 +1635,6 @@ err:
|
||||
|
||||
static void iwl_uninit_drv(struct iwl_priv *priv)
|
||||
{
|
||||
iwl_calib_free_results(priv);
|
||||
iwl_free_geos(priv);
|
||||
iwl_free_channel_map(priv);
|
||||
if (priv->tx_cmd_pool)
|
||||
@ -1703,8 +1704,14 @@ static void iwl_debug_config(struct iwl_priv *priv)
|
||||
"disabled\n");
|
||||
#endif
|
||||
|
||||
dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_SVTOOL "
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
"enabled\n");
|
||||
#else
|
||||
"disabled\n");
|
||||
#endif
|
||||
dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P "
|
||||
#ifdef CONFIG_IWLWIFI_P2P
|
||||
"enabled\n");
|
||||
#else
|
||||
"disabled\n");
|
||||
@ -1814,11 +1821,11 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
|
||||
goto out_free_eeprom;
|
||||
|
||||
/* extract MAC Address */
|
||||
iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
|
||||
iwl_eeprom_get_mac(priv->shrd, priv->addresses[0].addr);
|
||||
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
|
||||
priv->hw->wiphy->addresses = priv->addresses;
|
||||
priv->hw->wiphy->n_addresses = 1;
|
||||
num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS);
|
||||
num_mac = iwl_eeprom_query16(priv->shrd, EEPROM_NUM_MAC_ADDRESS);
|
||||
if (num_mac > 1) {
|
||||
memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
|
||||
ETH_ALEN);
|
||||
@ -1883,7 +1890,7 @@ out_destroy_workqueue:
|
||||
priv->shrd->workqueue = NULL;
|
||||
iwl_uninit_drv(priv);
|
||||
out_free_eeprom:
|
||||
iwl_eeprom_free(priv);
|
||||
iwl_eeprom_free(priv->shrd);
|
||||
out_free_trans:
|
||||
iwl_trans_free(trans(priv));
|
||||
out_free_traffic_mem:
|
||||
@ -1922,7 +1929,7 @@ void __devexit iwl_remove(struct iwl_priv * priv)
|
||||
|
||||
iwl_dealloc_ucode(trans(priv));
|
||||
|
||||
iwl_eeprom_free(priv);
|
||||
iwl_eeprom_free(priv->shrd);
|
||||
|
||||
/*netif_stop_queue(dev); */
|
||||
flush_workqueue(priv->shrd->workqueue);
|
||||
|
@ -117,7 +117,7 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
/* lib */
|
||||
int iwlagn_send_tx_power(struct iwl_priv *priv);
|
||||
void iwlagn_temperature(struct iwl_priv *priv);
|
||||
u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
|
||||
u16 iwl_eeprom_calib_version(struct iwl_shared *shrd);
|
||||
int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
|
||||
void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
|
||||
int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
|
||||
@ -354,12 +354,12 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
|
||||
|
||||
/* eeprom */
|
||||
void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv);
|
||||
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
|
||||
void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac);
|
||||
|
||||
extern int iwlagn_init_alive_start(struct iwl_priv *priv);
|
||||
extern int iwl_alive_start(struct iwl_priv *priv);
|
||||
/* svtool */
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
|
||||
int len);
|
||||
extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
|
||||
|
@ -109,10 +109,10 @@ enum {
|
||||
/* RX, TX, LEDs */
|
||||
REPLY_TX = 0x1c,
|
||||
REPLY_LEDS_CMD = 0x48,
|
||||
REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */
|
||||
REPLY_TX_LINK_QUALITY_CMD = 0x4e,
|
||||
|
||||
/* WiMAX coexistence */
|
||||
COEX_PRIORITY_TABLE_CMD = 0x5a, /* for 5000 series and up */
|
||||
COEX_PRIORITY_TABLE_CMD = 0x5a,
|
||||
COEX_MEDIUM_NOTIFICATION = 0x5b,
|
||||
COEX_EVENT_CMD = 0x5c,
|
||||
|
||||
@ -466,23 +466,27 @@ struct iwl_error_event_table {
|
||||
u32 frame_ptr; /* frame pointer */
|
||||
u32 stack_ptr; /* stack pointer */
|
||||
u32 hcmd; /* last host command header */
|
||||
#if 0
|
||||
/* no need to read the remainder, we don't use the values */
|
||||
u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */
|
||||
u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */
|
||||
u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */
|
||||
u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */
|
||||
u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */
|
||||
u32 isr0; /* isr status register LMPM_NIC_ISR0:
|
||||
* rxtx_flag */
|
||||
u32 isr1; /* isr status register LMPM_NIC_ISR1:
|
||||
* host_flag */
|
||||
u32 isr2; /* isr status register LMPM_NIC_ISR2:
|
||||
* enc_flag */
|
||||
u32 isr3; /* isr status register LMPM_NIC_ISR3:
|
||||
* time_flag */
|
||||
u32 isr4; /* isr status register LMPM_NIC_ISR4:
|
||||
* wico interrupt */
|
||||
u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
|
||||
u32 wait_event; /* wait event() caller address */
|
||||
u32 l2p_control; /* L2pControlField */
|
||||
u32 l2p_duration; /* L2pDurationField */
|
||||
u32 l2p_mhvalid; /* L2pMhValidBits */
|
||||
u32 l2p_addr_match; /* L2pAddrMatchStat */
|
||||
u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */
|
||||
u32 u_timestamp; /* indicate when the date and time of the compilation */
|
||||
u32 lmpm_pmg_sel; /* indicate which clocks are turned on
|
||||
* (LMPM_PMG_SEL) */
|
||||
u32 u_timestamp; /* indicate when the date and time of the
|
||||
* compilation */
|
||||
u32 flow_handler; /* FH read/write pointers, RX credit */
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct iwl_alive_resp {
|
||||
@ -810,7 +814,7 @@ struct iwl_qosparam_cmd {
|
||||
#define IWLAGN_STATION_COUNT 16
|
||||
|
||||
#define IWL_INVALID_STATION 255
|
||||
#define IWL_MAX_TID_COUNT 9
|
||||
#define IWL_MAX_TID_COUNT 8
|
||||
|
||||
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
|
||||
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
|
||||
@ -931,8 +935,7 @@ struct iwl_addsta_cmd {
|
||||
* corresponding to bit (e.g. bit 5 controls TID 5).
|
||||
* Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
|
||||
__le16 tid_disable_tx;
|
||||
|
||||
__le16 rate_n_flags; /* 3945 only */
|
||||
__le16 legacy_reserved;
|
||||
|
||||
/* TID for which to add block-ack support.
|
||||
* Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
|
||||
@ -1162,8 +1165,7 @@ struct iwl_rx_mpdu_res_start {
|
||||
*
|
||||
* uCode handles retrying Tx when an ACK is expected but not received.
|
||||
* This includes trying lower data rates than the one requested in the Tx
|
||||
* command, as set up by the REPLY_RATE_SCALE (for 3945) or
|
||||
* REPLY_TX_LINK_QUALITY_CMD (agn).
|
||||
* command, as set up by the REPLY_TX_LINK_QUALITY_CMD (agn).
|
||||
*
|
||||
* Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD.
|
||||
* This command must be executed after every RXON command, before Tx can occur.
|
||||
@ -1175,25 +1177,9 @@ struct iwl_rx_mpdu_res_start {
|
||||
* 1: Use RTS/CTS protocol or CTS-to-self if spec allows it
|
||||
* before this frame. if CTS-to-self required check
|
||||
* RXON_FLG_SELF_CTS_EN status.
|
||||
* unused in 3945/4965, used in 5000 series and after
|
||||
*/
|
||||
#define TX_CMD_FLG_PROT_REQUIRE_MSK cpu_to_le32(1 << 0)
|
||||
|
||||
/*
|
||||
* 1: Use Request-To-Send protocol before this frame.
|
||||
* Mutually exclusive vs. TX_CMD_FLG_CTS_MSK.
|
||||
* used in 3945/4965, unused in 5000 series and after
|
||||
*/
|
||||
#define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
|
||||
|
||||
/*
|
||||
* 1: Transmit Clear-To-Send to self before this frame.
|
||||
* Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
|
||||
* Mutually exclusive vs. TX_CMD_FLG_RTS_MSK.
|
||||
* used in 3945/4965, unused in 5000 series and after
|
||||
*/
|
||||
#define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
|
||||
|
||||
/* 1: Expect ACK from receiving station
|
||||
* 0: Don't expect ACK (MAC header's duration field s/b 0)
|
||||
* Set this for unicast frames, but not broadcast/multicast. */
|
||||
@ -1211,18 +1197,8 @@ struct iwl_rx_mpdu_res_start {
|
||||
* Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */
|
||||
#define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6)
|
||||
|
||||
/*
|
||||
* 1: Frame requires full Tx-Op protection.
|
||||
* Set this if either RTS or CTS Tx Flag gets set.
|
||||
* used in 3945/4965, unused in 5000 series and after
|
||||
*/
|
||||
#define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
|
||||
|
||||
/* Tx antenna selection field; used only for 3945, reserved (0) for agn devices.
|
||||
* Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
|
||||
/* Tx antenna selection field; reserved (0) for agn devices. */
|
||||
#define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
|
||||
#define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
|
||||
#define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
|
||||
|
||||
/* 1: Ignore Bluetooth priority for this frame.
|
||||
* 0: Delay Tx until Bluetooth device is done (normal usage). */
|
||||
@ -1568,7 +1544,6 @@ struct iwl_compressed_ba_resp {
|
||||
__le64 bitmap;
|
||||
__le16 scd_flow;
|
||||
__le16 scd_ssn;
|
||||
/* following only for 5000 series and up */
|
||||
u8 txed; /* number of frames sent */
|
||||
u8 txed_2_done; /* number of frames acked */
|
||||
} __packed;
|
||||
@ -1670,7 +1645,7 @@ struct iwl_link_qual_agg_params {
|
||||
/*
|
||||
* REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response)
|
||||
*
|
||||
* For agn devices only; 3945 uses REPLY_RATE_SCALE.
|
||||
* For agn devices
|
||||
*
|
||||
* Each station in the agn device's internal station table has its own table
|
||||
* of 16
|
||||
@ -1919,7 +1894,7 @@ struct iwl_link_quality_cmd {
|
||||
/*
|
||||
* REPLY_BT_CONFIG = 0x9b (command, has simple generic response)
|
||||
*
|
||||
* 3945 and agn devices support hardware handshake with Bluetooth device on
|
||||
* agn devices support hardware handshake with Bluetooth device on
|
||||
* same platform. Bluetooth device alerts wireless device when it will Tx;
|
||||
* wireless device can delay or kill its own Tx to accommodate.
|
||||
*/
|
||||
@ -2203,8 +2178,8 @@ struct iwl_spectrum_notification {
|
||||
|
||||
struct iwl_powertable_cmd {
|
||||
__le16 flags;
|
||||
u8 keep_alive_seconds; /* 3945 reserved */
|
||||
u8 debug_flags; /* 3945 reserved */
|
||||
u8 keep_alive_seconds;
|
||||
u8 debug_flags;
|
||||
__le32 rx_data_timeout;
|
||||
__le32 tx_data_timeout;
|
||||
__le32 sleep_interval[IWL_POWER_VEC_SIZE];
|
||||
@ -2325,9 +2300,9 @@ struct iwl_scan_channel {
|
||||
/**
|
||||
* struct iwl_ssid_ie - directed scan network information element
|
||||
*
|
||||
* Up to 20 of these may appear in REPLY_SCAN_CMD (Note: Only 4 are in
|
||||
* 3945 SCAN api), selected by "type" bit field in struct iwl_scan_channel;
|
||||
* each channel may select different ssids from among the 20 (4) entries.
|
||||
* Up to 20 of these may appear in REPLY_SCAN_CMD,
|
||||
* selected by "type" bit field in struct iwl_scan_channel;
|
||||
* each channel may select different ssids from among the 20 entries.
|
||||
* SSID IEs get transmitted in reverse order of entry.
|
||||
*/
|
||||
struct iwl_ssid_ie {
|
||||
@ -2336,7 +2311,6 @@ struct iwl_ssid_ie {
|
||||
u8 ssid[32];
|
||||
} __packed;
|
||||
|
||||
#define PROBE_OPTION_MAX_3945 4
|
||||
#define PROBE_OPTION_MAX 20
|
||||
#define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
|
||||
#define IWL_GOOD_CRC_TH_DISABLED 0
|
||||
@ -2417,8 +2391,6 @@ struct iwl_scan_cmd {
|
||||
* channel */
|
||||
__le32 suspend_time; /* pause scan this long (in "extended beacon
|
||||
* format") when returning to service chnl:
|
||||
* 3945; 31:24 # beacons, 19:0 additional usec,
|
||||
* 4965; 31:22 # beacons, 21:0 additional usec.
|
||||
*/
|
||||
__le32 flags; /* RXON_FLG_* */
|
||||
__le32 filter_flags; /* RXON_FILTER_* */
|
||||
@ -2734,7 +2706,7 @@ struct statistics_div {
|
||||
|
||||
struct statistics_general_common {
|
||||
__le32 temperature; /* radio temperature */
|
||||
__le32 temperature_m; /* for 5000 and up, this is radio voltage */
|
||||
__le32 temperature_m; /* radio voltage */
|
||||
struct statistics_dbg dbg;
|
||||
__le32 sleep_time;
|
||||
__le32 slots_out;
|
||||
|
@ -416,7 +416,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
ptr = priv->eeprom;
|
||||
ptr = priv->shrd->eeprom;
|
||||
if (!ptr) {
|
||||
IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
|
||||
return -ENOMEM;
|
||||
@ -428,7 +428,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
|
||||
eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION);
|
||||
pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
|
||||
"version: 0x%x\n",
|
||||
(trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP)
|
||||
|
@ -60,11 +60,10 @@ struct iwl_tx_queue;
|
||||
|
||||
/* Default noise level to report when noise measurement is not available.
|
||||
* This may be because we're:
|
||||
* 1) Not associated (4965, no beacon statistics being sent to driver)
|
||||
* 1) Not associated no beacon statistics being sent to driver)
|
||||
* 2) Scanning (noise measurement does not apply to associated channel)
|
||||
* 3) Receiving CCK (3945 delivers noise info only for OFDM frames)
|
||||
* Use default noise value of -127 ... this is below the range of measurable
|
||||
* Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user.
|
||||
* Rx dBm for all agn devices, so it can indicate "unmeasurable" to user.
|
||||
* Also, -127 works better than 0 when averaging frames with/without
|
||||
* noise info (e.g. averaging might be done in app); measured dBm values are
|
||||
* always negative ... using a negative value as the default keeps all
|
||||
@ -441,15 +440,6 @@ enum iwlagn_chain_noise_state {
|
||||
IWL_CHAIN_NOISE_DONE,
|
||||
};
|
||||
|
||||
|
||||
/* Opaque calibration results */
|
||||
struct iwl_calib_result {
|
||||
struct list_head list;
|
||||
size_t cmd_len;
|
||||
struct iwl_calib_hdr hdr;
|
||||
/* data follows */
|
||||
};
|
||||
|
||||
/* Sensitivity calib data */
|
||||
struct iwl_sensitivity_data {
|
||||
u32 auto_corr_ofdm;
|
||||
@ -751,7 +741,7 @@ enum iwl_scan_type {
|
||||
IWL_SCAN_ROC,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
struct iwl_testmode_trace {
|
||||
u32 buff_size;
|
||||
u32 total_size;
|
||||
@ -831,9 +821,6 @@ struct iwl_priv {
|
||||
s32 temperature; /* Celsius */
|
||||
s32 last_temperature;
|
||||
|
||||
/* init calibration results */
|
||||
struct list_head calib_results;
|
||||
|
||||
struct iwl_wipan_noa_data __rcu *noa_data;
|
||||
|
||||
/* Scan related variables */
|
||||
@ -866,11 +853,6 @@ struct iwl_priv {
|
||||
|
||||
__le16 switch_channel;
|
||||
|
||||
struct {
|
||||
u32 error_event_table;
|
||||
u32 log_event_table;
|
||||
} device_pointers;
|
||||
|
||||
u16 active_rate;
|
||||
|
||||
u8 start_calib;
|
||||
@ -904,10 +886,6 @@ struct iwl_priv {
|
||||
/* Indication if ieee80211_ops->open has been called */
|
||||
u8 is_open;
|
||||
|
||||
/* eeprom -- this is in the card's little endian byte order */
|
||||
u8 *eeprom;
|
||||
struct iwl_eeprom_calib_info *calib_info;
|
||||
|
||||
enum nl80211_iftype iw_mode;
|
||||
|
||||
/* Last Rx'd beacon timestamp */
|
||||
@ -1040,7 +1018,7 @@ struct iwl_priv {
|
||||
struct led_classdev led;
|
||||
unsigned long blink_on, blink_off;
|
||||
bool led_registered;
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
|
||||
struct iwl_testmode_trace testmode_trace;
|
||||
struct iwl_testmode_sram testmode_sram;
|
||||
u32 tm_fixed_rate;
|
||||
|
@ -215,11 +215,11 @@ static int iwl_eeprom_verify_signature(struct iwl_trans *trans)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
|
||||
u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset)
|
||||
{
|
||||
if (!priv->eeprom)
|
||||
if (!shrd->eeprom)
|
||||
return 0;
|
||||
return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
|
||||
return (u16)shrd->eeprom[offset] | ((u16)shrd->eeprom[offset + 1] << 8);
|
||||
}
|
||||
|
||||
int iwl_eeprom_check_version(struct iwl_priv *priv)
|
||||
@ -227,8 +227,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
|
||||
u16 eeprom_ver;
|
||||
u16 calib_ver;
|
||||
|
||||
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
|
||||
calib_ver = iwlagn_eeprom_calib_version(priv);
|
||||
eeprom_ver = iwl_eeprom_query16(priv->shrd, EEPROM_VERSION);
|
||||
calib_ver = iwl_eeprom_calib_version(priv->shrd);
|
||||
|
||||
if (eeprom_ver < priv->cfg->eeprom_ver ||
|
||||
calib_ver < priv->cfg->eeprom_calib_ver)
|
||||
@ -249,11 +249,12 @@ err:
|
||||
|
||||
int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_shared *shrd = priv->shrd;
|
||||
u16 radio_cfg;
|
||||
|
||||
if (!priv->cfg->sku) {
|
||||
/* not using sku overwrite */
|
||||
priv->cfg->sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
|
||||
priv->cfg->sku = iwl_eeprom_query16(shrd, EEPROM_SKU_CAP);
|
||||
if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE &&
|
||||
!priv->cfg->ht_params) {
|
||||
IWL_ERR(priv, "Invalid 11n configuration\n");
|
||||
@ -269,7 +270,7 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||
|
||||
if (!priv->cfg->valid_tx_ant && !priv->cfg->valid_rx_ant) {
|
||||
/* not using .cfg overwrite */
|
||||
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
|
||||
radio_cfg = iwl_eeprom_query16(shrd, EEPROM_RADIO_CONFIG);
|
||||
priv->cfg->valid_tx_ant = EEPROM_RF_CFG_TX_ANT_MSK(radio_cfg);
|
||||
priv->cfg->valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
|
||||
if (!priv->cfg->valid_tx_ant || !priv->cfg->valid_rx_ant) {
|
||||
@ -289,9 +290,9 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
|
||||
void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac)
|
||||
{
|
||||
const u8 *addr = iwl_eeprom_query_addr(priv,
|
||||
const u8 *addr = iwl_eeprom_query_addr(shrd,
|
||||
EEPROM_MAC_ADDRESS);
|
||||
memcpy(mac, addr, ETH_ALEN);
|
||||
}
|
||||
@ -582,6 +583,7 @@ iwl_eeprom_enh_txp_read_element(struct iwl_priv *priv,
|
||||
|
||||
void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_shared *shrd = priv->shrd;
|
||||
struct iwl_eeprom_enhanced_txpwr *txp_array, *txp;
|
||||
int idx, entries;
|
||||
__le16 *txp_len;
|
||||
@ -590,10 +592,10 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
|
||||
BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8);
|
||||
|
||||
/* the length is in 16-bit words, but we want entries */
|
||||
txp_len = (__le16 *) iwl_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS);
|
||||
txp_len = (__le16 *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_SZ_OFFS);
|
||||
entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN;
|
||||
|
||||
txp_array = (void *) iwl_eeprom_query_addr(priv, EEPROM_TXP_OFFS);
|
||||
txp_array = (void *) iwl_eeprom_query_addr(shrd, EEPROM_TXP_OFFS);
|
||||
|
||||
for (idx = 0; idx < entries; idx++) {
|
||||
txp = &txp_array[idx];
|
||||
@ -646,12 +648,13 @@ void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
|
||||
/**
|
||||
* iwl_eeprom_init - read EEPROM contents
|
||||
*
|
||||
* Load the EEPROM contents from adapter into priv->eeprom
|
||||
* Load the EEPROM contents from adapter into shrd->eeprom
|
||||
*
|
||||
* NOTE: This routine uses the non-debug IO access functions.
|
||||
*/
|
||||
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
|
||||
{
|
||||
struct iwl_shared *shrd = priv->shrd;
|
||||
__le16 *e;
|
||||
u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP);
|
||||
int sz;
|
||||
@ -666,12 +669,12 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
|
||||
/* allocate eeprom */
|
||||
sz = priv->cfg->base_params->eeprom_size;
|
||||
IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
|
||||
priv->eeprom = kzalloc(sz, GFP_KERNEL);
|
||||
if (!priv->eeprom) {
|
||||
shrd->eeprom = kzalloc(sz, GFP_KERNEL);
|
||||
if (!shrd->eeprom) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
e = (__le16 *)priv->eeprom;
|
||||
e = (__le16 *)shrd->eeprom;
|
||||
|
||||
iwl_apm_init(priv);
|
||||
|
||||
@ -746,7 +749,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
|
||||
IWL_DEBUG_EEPROM(priv, "NVM Type: %s, version: 0x%x\n",
|
||||
(trans(priv)->nvm_device_type == NVM_DEVICE_TYPE_OTP)
|
||||
? "OTP" : "EEPROM",
|
||||
iwl_eeprom_query16(priv, EEPROM_VERSION));
|
||||
iwl_eeprom_query16(shrd, EEPROM_VERSION));
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
@ -754,17 +757,17 @@ done:
|
||||
|
||||
err:
|
||||
if (ret)
|
||||
iwl_eeprom_free(priv);
|
||||
iwl_eeprom_free(priv->shrd);
|
||||
/* Reset chip to save power until we load uCode during "up". */
|
||||
iwl_apm_stop(priv);
|
||||
alloc_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_eeprom_free(struct iwl_priv *priv)
|
||||
void iwl_eeprom_free(struct iwl_shared *shrd)
|
||||
{
|
||||
kfree(priv->eeprom);
|
||||
priv->eeprom = NULL;
|
||||
kfree(shrd->eeprom);
|
||||
shrd->eeprom = NULL;
|
||||
}
|
||||
|
||||
static void iwl_init_band_reference(const struct iwl_priv *priv,
|
||||
@ -772,49 +775,50 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
|
||||
const struct iwl_eeprom_channel **eeprom_ch_info,
|
||||
const u8 **eeprom_ch_index)
|
||||
{
|
||||
struct iwl_shared *shrd = priv->shrd;
|
||||
u32 offset = priv->cfg->lib->
|
||||
eeprom_ops.regulatory_bands[eep_band - 1];
|
||||
switch (eep_band) {
|
||||
case 1: /* 2.4GHz band */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_1;
|
||||
break;
|
||||
case 2: /* 4.9GHz band */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_2;
|
||||
break;
|
||||
case 3: /* 5.2GHz band */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_3;
|
||||
break;
|
||||
case 4: /* 5.5GHz band */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_4;
|
||||
break;
|
||||
case 5: /* 5.7GHz band */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_5;
|
||||
break;
|
||||
case 6: /* 2.4GHz ht40 channels */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_6;
|
||||
break;
|
||||
case 7: /* 5 GHz ht40 channels */
|
||||
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
|
||||
*eeprom_ch_info = (struct iwl_eeprom_channel *)
|
||||
iwl_eeprom_query_addr(priv, offset);
|
||||
iwl_eeprom_query_addr(shrd, offset);
|
||||
*eeprom_ch_index = iwl_eeprom_band_7;
|
||||
break;
|
||||
default:
|
||||
@ -1064,7 +1068,7 @@ void iwl_rf_config(struct iwl_priv *priv)
|
||||
{
|
||||
u16 radio_cfg;
|
||||
|
||||
radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
|
||||
radio_cfg = iwl_eeprom_query16(priv->shrd, EEPROM_RADIO_CONFIG);
|
||||
|
||||
/* write radio config values to register */
|
||||
if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include <net/mac80211.h>
|
||||
|
||||
struct iwl_priv;
|
||||
struct iwl_shared;
|
||||
|
||||
/*
|
||||
* EEPROM access time values:
|
||||
@ -305,11 +306,11 @@ struct iwl_eeprom_ops {
|
||||
|
||||
|
||||
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
|
||||
void iwl_eeprom_free(struct iwl_priv *priv);
|
||||
void iwl_eeprom_free(struct iwl_shared *shrd);
|
||||
int iwl_eeprom_check_version(struct iwl_priv *priv);
|
||||
int iwl_eeprom_check_sku(struct iwl_priv *priv);
|
||||
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
|
||||
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
|
||||
const u8 *iwl_eeprom_query_addr(const struct iwl_shared *shrd, size_t offset);
|
||||
u16 iwl_eeprom_query16(const struct iwl_shared *shrd, size_t offset);
|
||||
int iwl_init_channel_map(struct iwl_priv *priv);
|
||||
void iwl_free_channel_map(struct iwl_priv *priv);
|
||||
const struct iwl_channel_info *iwl_get_channel_info(
|
||||
|
@ -427,7 +427,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
|
||||
iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR,
|
||||
CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
|
||||
|
||||
base = priv->device_pointers.error_event_table;
|
||||
base = priv->shrd->device_pointers.error_event_table;
|
||||
if (iwlagn_hw_valid_rtc_data_addr(base)) {
|
||||
spin_lock_irqsave(&bus(priv)->reg_lock, flags);
|
||||
ret = iwl_grab_nic_access_silent(bus(priv));
|
||||
@ -811,21 +811,9 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
|
||||
/* Configure HT40 channels */
|
||||
ctx->ht.enabled = conf_is_ht(conf);
|
||||
if (ctx->ht.enabled) {
|
||||
if (conf_is_ht40_minus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else if (conf_is_ht40_plus(conf)) {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
|
||||
ctx->ht.is_40mhz = true;
|
||||
} else {
|
||||
ctx->ht.extension_chan_offset =
|
||||
IEEE80211_HT_PARAM_CHA_SEC_NONE;
|
||||
ctx->ht.is_40mhz = false;
|
||||
}
|
||||
} else
|
||||
if (ctx->ht.enabled)
|
||||
iwlagn_config_ht40(conf, ctx);
|
||||
else
|
||||
ctx->ht.is_40mhz = false;
|
||||
|
||||
if ((le16_to_cpu(ctx->staging.channel) != ch))
|
||||
@ -1060,6 +1048,9 @@ static int iwlagn_mac_tx_sync(struct ieee80211_hw *hw,
|
||||
int ret;
|
||||
u8 sta_id;
|
||||
|
||||
if (ctx->ctxid != IWL_RXON_CTX_PAN)
|
||||
return 0;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
mutex_lock(&priv->shrd->mutex);
|
||||
|
||||
@ -1109,6 +1100,9 @@ static void iwlagn_mac_finish_tx_sync(struct ieee80211_hw *hw,
|
||||
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
|
||||
struct iwl_rxon_context *ctx = vif_priv->ctx;
|
||||
|
||||
if (ctx->ctxid != IWL_RXON_CTX_PAN)
|
||||
return;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
mutex_lock(&priv->shrd->mutex);
|
||||
|
||||
|
@ -97,6 +97,7 @@
|
||||
struct iwl_cfg;
|
||||
struct iwl_bus;
|
||||
struct iwl_priv;
|
||||
struct iwl_trans;
|
||||
struct iwl_sensitivity_ranges;
|
||||
struct iwl_trans_ops;
|
||||
|
||||
@ -294,7 +295,7 @@ enum iwl_ucode_type {
|
||||
struct iwl_notification_wait {
|
||||
struct list_head list;
|
||||
|
||||
void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
|
||||
void (*fn)(struct iwl_trans *trans, struct iwl_rx_packet *pkt,
|
||||
void *data);
|
||||
void *fn_data;
|
||||
|
||||
@ -323,6 +324,7 @@ struct iwl_notification_wait {
|
||||
* @notif_waits: things waiting for notification
|
||||
* @notif_wait_lock: lock protecting notification
|
||||
* @notif_waitq: head of notification wait queue
|
||||
* @device_pointers: pointers to ucode event tables
|
||||
*/
|
||||
struct iwl_shared {
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
@ -351,6 +353,9 @@ struct iwl_shared {
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
|
||||
/* eeprom -- this is in the card's little endian byte order */
|
||||
u8 *eeprom;
|
||||
|
||||
/* ucode related variables */
|
||||
enum iwl_ucode_type ucode_type;
|
||||
|
||||
@ -358,6 +363,12 @@ struct iwl_shared {
|
||||
struct list_head notif_waits;
|
||||
spinlock_t notif_wait_lock;
|
||||
wait_queue_head_t notif_waitq;
|
||||
|
||||
struct {
|
||||
u32 error_event_table;
|
||||
u32 log_event_table;
|
||||
} device_pointers;
|
||||
|
||||
};
|
||||
|
||||
/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */
|
||||
@ -507,7 +518,7 @@ void __acquires(wait_entry)
|
||||
iwl_init_notification_wait(struct iwl_shared *shrd,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
u8 cmd,
|
||||
void (*fn)(struct iwl_priv *priv,
|
||||
void (*fn)(struct iwl_trans *trans,
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data),
|
||||
void *fn_data);
|
||||
|
@ -77,6 +77,7 @@
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-testmode.h"
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-bus.h"
|
||||
|
||||
/* The TLVs used in the gnl message policy between the kernel module and
|
||||
* user space application. iwl_testmode_gnl_msg_policy is to be carried
|
||||
@ -110,6 +111,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
|
||||
[IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, },
|
||||
[IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, },
|
||||
[IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, },
|
||||
|
||||
[IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
|
||||
[IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
|
||||
};
|
||||
|
||||
/*
|
||||
@ -416,6 +420,8 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
struct sk_buff *skb;
|
||||
unsigned char *rsp_data_ptr = NULL;
|
||||
int status = 0, rsp_data_len = 0;
|
||||
char buf[32], *ptr = NULL;
|
||||
unsigned int num, devid;
|
||||
|
||||
switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
|
||||
case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
|
||||
@ -479,7 +485,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
break;
|
||||
|
||||
case IWL_TM_CMD_APP2DEV_GET_EEPROM:
|
||||
if (priv->eeprom) {
|
||||
if (priv->shrd->eeprom) {
|
||||
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
|
||||
priv->cfg->base_params->eeprom_size + 20);
|
||||
if (!skb) {
|
||||
@ -491,7 +497,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
IWL_TM_CMD_DEV2APP_EEPROM_RSP);
|
||||
NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
|
||||
priv->cfg->base_params->eeprom_size,
|
||||
priv->eeprom);
|
||||
priv->shrd->eeprom);
|
||||
status = cfg80211_testmode_reply(skb);
|
||||
if (status < 0)
|
||||
IWL_DEBUG_INFO(priv,
|
||||
@ -510,6 +516,43 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
|
||||
priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
|
||||
break;
|
||||
|
||||
case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
|
||||
IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver);
|
||||
|
||||
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
|
||||
if (!skb) {
|
||||
IWL_DEBUG_INFO(priv, "Error allocating memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver);
|
||||
status = cfg80211_testmode_reply(skb);
|
||||
if (status < 0)
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Error sending msg : %d\n", status);
|
||||
break;
|
||||
|
||||
case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
|
||||
bus_get_hw_id(bus(priv), buf, sizeof(buf));
|
||||
ptr = buf;
|
||||
strsep(&ptr, ":");
|
||||
sscanf(strsep(&ptr, ":"), "%x", &num);
|
||||
sscanf(strsep(&ptr, ":"), "%x", &devid);
|
||||
IWL_INFO(priv, "Device ID = 0x%04x, SubDevice ID= 0x%04x\n",
|
||||
num, devid);
|
||||
devid |= (num << 16);
|
||||
|
||||
skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
|
||||
if (!skb) {
|
||||
IWL_DEBUG_INFO(priv, "Error allocating memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
|
||||
status = cfg80211_testmode_reply(skb);
|
||||
if (status < 0)
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Error sending msg : %d\n", status);
|
||||
break;
|
||||
|
||||
default:
|
||||
IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
|
||||
return -ENOSYS;
|
||||
@ -842,6 +885,8 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
|
||||
case IWL_TM_CMD_APP2DEV_GET_EEPROM:
|
||||
case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
|
||||
case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
|
||||
case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
|
||||
case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
|
||||
IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
|
||||
result = iwl_testmode_driver(hw, tb);
|
||||
break;
|
||||
|
@ -118,6 +118,8 @@
|
||||
* commands from user applicaiton to read data in sram
|
||||
*
|
||||
* @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image
|
||||
* @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
|
||||
* @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
|
||||
*
|
||||
*/
|
||||
enum iwl_tm_cmd_t {
|
||||
@ -143,7 +145,9 @@ enum iwl_tm_cmd_t {
|
||||
IWL_TM_CMD_APP2DEV_READ_SRAM = 20,
|
||||
IWL_TM_CMD_APP2DEV_DUMP_SRAM = 21,
|
||||
IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22,
|
||||
IWL_TM_CMD_MAX = 23,
|
||||
IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23,
|
||||
IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24,
|
||||
IWL_TM_CMD_MAX = 25,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -225,6 +229,14 @@ enum iwl_tm_cmd_t {
|
||||
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_DUMP_SRAM,
|
||||
* IWL_TM_ATTR_SRAM_DUMP for the data in sram
|
||||
*
|
||||
* @IWL_TM_ATTR_FW_VERSION:
|
||||
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
|
||||
* IWL_TM_ATTR_FW_VERSION for the uCode version
|
||||
*
|
||||
* @IWL_TM_ATTR_DEVICE_ID:
|
||||
* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
|
||||
* IWL_TM_ATTR_DEVICE_ID for the device ID information
|
||||
*
|
||||
*/
|
||||
enum iwl_tm_attr_t {
|
||||
IWL_TM_ATTR_NOT_APPLICABLE = 0,
|
||||
@ -245,7 +257,9 @@ enum iwl_tm_attr_t {
|
||||
IWL_TM_ATTR_SRAM_ADDR = 15,
|
||||
IWL_TM_ATTR_SRAM_SIZE = 16,
|
||||
IWL_TM_ATTR_SRAM_DUMP = 17,
|
||||
IWL_TM_ATTR_MAX = 18,
|
||||
IWL_TM_ATTR_FW_VERSION = 18,
|
||||
IWL_TM_ATTR_DEVICE_ID = 19,
|
||||
IWL_TM_ATTR_MAX = 20,
|
||||
};
|
||||
|
||||
/* uCode trace buffer */
|
||||
|
@ -594,7 +594,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
base = priv->device_pointers.error_event_table;
|
||||
base = trans->shrd->device_pointers.error_event_table;
|
||||
if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
|
||||
if (!base)
|
||||
base = priv->init_errlog_ptr;
|
||||
@ -648,6 +648,21 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
|
||||
IWL_ERR(trans, "0x%08X | hw version\n", table.hw_ver);
|
||||
IWL_ERR(trans, "0x%08X | board version\n", table.brd_ver);
|
||||
IWL_ERR(trans, "0x%08X | hcmd\n", table.hcmd);
|
||||
|
||||
IWL_ERR(trans, "0x%08X | isr0\n", table.isr0);
|
||||
IWL_ERR(trans, "0x%08X | isr1\n", table.isr1);
|
||||
IWL_ERR(trans, "0x%08X | isr2\n", table.isr2);
|
||||
IWL_ERR(trans, "0x%08X | isr3\n", table.isr3);
|
||||
IWL_ERR(trans, "0x%08X | isr4\n", table.isr4);
|
||||
IWL_ERR(trans, "0x%08X | isr_pref\n", table.isr_pref);
|
||||
IWL_ERR(trans, "0x%08X | wait_event\n", table.wait_event);
|
||||
IWL_ERR(trans, "0x%08X | l2p_control\n", table.l2p_control);
|
||||
IWL_ERR(trans, "0x%08X | l2p_duration\n", table.l2p_duration);
|
||||
IWL_ERR(trans, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
|
||||
IWL_ERR(trans, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
|
||||
IWL_ERR(trans, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
|
||||
IWL_ERR(trans, "0x%08X | timestamp\n", table.u_timestamp);
|
||||
IWL_ERR(trans, "0x%08X | flow_handler\n", table.flow_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -709,7 +724,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
|
||||
if (num_events == 0)
|
||||
return pos;
|
||||
|
||||
base = priv->device_pointers.log_event_table;
|
||||
base = trans->shrd->device_pointers.log_event_table;
|
||||
if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
|
||||
if (!base)
|
||||
base = priv->init_evtlog_ptr;
|
||||
@ -823,7 +838,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
|
||||
size_t bufsz = 0;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
|
||||
base = priv->device_pointers.log_event_table;
|
||||
base = trans->shrd->device_pointers.log_event_table;
|
||||
if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
|
||||
logsize = priv->init_evtlog_size;
|
||||
if (!base)
|
||||
|
@ -1373,6 +1373,7 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid,
|
||||
|
||||
static void iwl_trans_pcie_free(struct iwl_trans *trans)
|
||||
{
|
||||
iwl_calib_free_results(trans);
|
||||
iwl_trans_pcie_tx_free(trans);
|
||||
iwl_trans_pcie_rx_free(trans);
|
||||
free_irq(bus(trans)->irq, trans);
|
||||
|
@ -220,6 +220,14 @@ struct fw_img {
|
||||
struct fw_desc data; /* firmware data image */
|
||||
};
|
||||
|
||||
/* Opaque calibration results */
|
||||
struct iwl_calib_result {
|
||||
struct list_head list;
|
||||
size_t cmd_len;
|
||||
struct iwl_calib_hdr hdr;
|
||||
/* data follows */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_trans - transport common data
|
||||
* @ops - pointer to iwl_trans_ops
|
||||
@ -229,6 +237,8 @@ struct fw_img {
|
||||
* @ucode_rt: run time ucode image
|
||||
* @ucode_init: init ucode image
|
||||
* @ucode_wowlan: wake on wireless ucode image (optional)
|
||||
* @nvm_device_type: indicates OTP or eeprom
|
||||
* @calib_results: list head for init calibration results
|
||||
*/
|
||||
struct iwl_trans {
|
||||
const struct iwl_trans_ops *ops;
|
||||
@ -243,6 +253,9 @@ struct iwl_trans {
|
||||
/* eeprom related variables */
|
||||
int nvm_device_type;
|
||||
|
||||
/* init calibration results */
|
||||
struct list_head calib_results;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
char trans_specific[0] __attribute__((__aligned__(sizeof(void *))));
|
||||
@ -379,4 +392,9 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc,
|
||||
const void *data, size_t len);
|
||||
void iwl_dealloc_ucode(struct iwl_trans *trans);
|
||||
|
||||
int iwl_send_calib_results(struct iwl_trans *trans);
|
||||
int iwl_calib_set(struct iwl_trans *trans,
|
||||
const struct iwl_calib_hdr *cmd, int len);
|
||||
void iwl_calib_free_results(struct iwl_trans *trans);
|
||||
|
||||
#endif /* __iwl_trans_h__ */
|
||||
|
@ -217,19 +217,20 @@ static int iwl_set_Xtal_calib(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_calib_xtal_freq_cmd cmd;
|
||||
__le16 *xtal_calib =
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_XTAL);
|
||||
(__le16 *)iwl_eeprom_query_addr(priv->shrd, EEPROM_XTAL);
|
||||
|
||||
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD);
|
||||
cmd.cap_pin1 = le16_to_cpu(xtal_calib[0]);
|
||||
cmd.cap_pin2 = le16_to_cpu(xtal_calib[1]);
|
||||
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||
return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_calib_temperature_offset_cmd cmd;
|
||||
__le16 *offset_calib =
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE);
|
||||
(__le16 *)iwl_eeprom_query_addr(priv->shrd,
|
||||
EEPROM_RAW_TEMPERATURE);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
|
||||
@ -239,21 +240,22 @@ static int iwl_set_temperature_offset_calib(struct iwl_priv *priv)
|
||||
|
||||
IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n",
|
||||
le16_to_cpu(cmd.radio_sensor_offset));
|
||||
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||
return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_calib_temperature_offset_v2_cmd cmd;
|
||||
__le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv,
|
||||
__le16 *offset_calib_high = (__le16 *)iwl_eeprom_query_addr(priv->shrd,
|
||||
EEPROM_KELVIN_TEMPERATURE);
|
||||
__le16 *offset_calib_low =
|
||||
(__le16 *)iwl_eeprom_query_addr(priv, EEPROM_RAW_TEMPERATURE);
|
||||
(__le16 *)iwl_eeprom_query_addr(priv->shrd,
|
||||
EEPROM_RAW_TEMPERATURE);
|
||||
struct iwl_eeprom_calib_hdr *hdr;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
iwl_set_calib_hdr(&cmd.hdr, IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD);
|
||||
hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
|
||||
hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv->shrd,
|
||||
EEPROM_CALIB_ALL);
|
||||
memcpy(&cmd.radio_sensor_offset_high, offset_calib_high,
|
||||
sizeof(*offset_calib_high));
|
||||
@ -274,7 +276,7 @@ static int iwl_set_temperature_offset_calib_v2(struct iwl_priv *priv)
|
||||
IWL_DEBUG_CALIB(priv, "Voltage Ref: %d\n",
|
||||
le16_to_cpu(cmd.burntVoltageRef));
|
||||
|
||||
return iwl_calib_set(priv, (void *)&cmd, sizeof(cmd));
|
||||
return iwl_calib_set(trans(priv), (void *)&cmd, sizeof(cmd));
|
||||
}
|
||||
|
||||
static int iwl_send_calib_cfg(struct iwl_trans *trans)
|
||||
@ -307,7 +309,7 @@ int iwlagn_rx_calib_result(struct iwl_priv *priv,
|
||||
/* reduce the size of the length field itself */
|
||||
len -= 4;
|
||||
|
||||
if (iwl_calib_set(priv, hdr, len))
|
||||
if (iwl_calib_set(trans(priv), hdr, len))
|
||||
IWL_ERR(priv, "Failed to record calibration data %d\n",
|
||||
hdr->op_code);
|
||||
|
||||
@ -457,7 +459,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return iwl_send_calib_results(priv);
|
||||
return iwl_send_calib_results(trans(priv));
|
||||
}
|
||||
|
||||
|
||||
@ -548,7 +550,7 @@ struct iwlagn_alive_data {
|
||||
u8 subtype;
|
||||
};
|
||||
|
||||
static void iwl_alive_fn(struct iwl_priv *priv,
|
||||
static void iwl_alive_fn(struct iwl_trans *trans,
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
@ -557,14 +559,14 @@ static void iwl_alive_fn(struct iwl_priv *priv,
|
||||
|
||||
palive = &pkt->u.alive_frame;
|
||||
|
||||
IWL_DEBUG_FW(priv, "Alive ucode status 0x%08X revision "
|
||||
IWL_DEBUG_FW(trans, "Alive ucode status 0x%08X revision "
|
||||
"0x%01X 0x%01X\n",
|
||||
palive->is_valid, palive->ver_type,
|
||||
palive->ver_subtype);
|
||||
|
||||
priv->device_pointers.error_event_table =
|
||||
trans->shrd->device_pointers.error_event_table =
|
||||
le32_to_cpu(palive->error_event_table_ptr);
|
||||
priv->device_pointers.log_event_table =
|
||||
trans->shrd->device_pointers.log_event_table =
|
||||
le32_to_cpu(palive->log_event_table_ptr);
|
||||
|
||||
alive_data->subtype = palive->ver_subtype;
|
||||
@ -575,7 +577,7 @@ static void iwl_alive_fn(struct iwl_priv *priv,
|
||||
void iwl_init_notification_wait(struct iwl_shared *shrd,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
u8 cmd,
|
||||
void (*fn)(struct iwl_priv *priv,
|
||||
void (*fn)(struct iwl_trans *trans,
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data),
|
||||
void *fn_data)
|
||||
|
@ -37,7 +37,8 @@ MODULE_AUTHOR("Jouni Malinen");
|
||||
MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
int wmediumd_pid;
|
||||
static u32 wmediumd_pid;
|
||||
|
||||
static int radios = 2;
|
||||
module_param(radios, int, 0444);
|
||||
MODULE_PARM_DESC(radios, "Number of simulated radios");
|
||||
@ -665,7 +666,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
bool ack;
|
||||
struct ieee80211_tx_info *txi;
|
||||
int _pid;
|
||||
u32 _pid;
|
||||
|
||||
mac80211_hwsim_monitor_rx(hw, skb);
|
||||
|
||||
@ -676,7 +677,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
_pid = ACCESS_ONCE(wmediumd_pid);
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
|
||||
@ -764,7 +765,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||
struct ieee80211_hw *hw = arg;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *info;
|
||||
int _pid;
|
||||
u32 _pid;
|
||||
|
||||
hwsim_check_magic(vif);
|
||||
|
||||
@ -781,7 +782,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac,
|
||||
mac80211_hwsim_monitor_rx(hw, skb);
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
_pid = ACCESS_ONCE(wmediumd_pid);
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(hw, skb, _pid);
|
||||
@ -1254,7 +1255,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_pspoll *pspoll;
|
||||
int _pid;
|
||||
u32 _pid;
|
||||
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
@ -1275,7 +1276,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
memcpy(pspoll->ta, mac, ETH_ALEN);
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
_pid = ACCESS_ONCE(wmediumd_pid);
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
|
||||
@ -1292,7 +1293,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int _pid;
|
||||
u32 _pid;
|
||||
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
@ -1314,7 +1315,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
|
||||
|
||||
/* wmediumd mode check */
|
||||
_pid = wmediumd_pid;
|
||||
_pid = ACCESS_ONCE(wmediumd_pid);
|
||||
|
||||
if (_pid)
|
||||
return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid);
|
||||
@ -1634,8 +1635,6 @@ static int hwsim_init_netlink(void)
|
||||
int rc;
|
||||
printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
|
||||
|
||||
wmediumd_pid = 0;
|
||||
|
||||
rc = genl_register_family_with_ops(&hwsim_genl_family,
|
||||
hwsim_ops, ARRAY_SIZE(hwsim_ops));
|
||||
if (rc)
|
||||
|
@ -751,17 +751,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
if (priv->disconnect)
|
||||
return -EBUSY;
|
||||
|
||||
priv->disconnect = 1;
|
||||
if (mwifiex_deauthenticate(priv, NULL))
|
||||
return -EFAULT;
|
||||
|
||||
wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
|
||||
" reason code %d\n", priv->cfg_bssid, reason_code);
|
||||
|
||||
queue_work(priv->workqueue, &priv->cfg_workqueue);
|
||||
memset(priv->cfg_bssid, 0, ETH_ALEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -981,27 +977,32 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (priv->assoc_request)
|
||||
return -EBUSY;
|
||||
|
||||
if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
|
||||
wiphy_err(wiphy, "received infra assoc request "
|
||||
"when station is in ibss mode\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
priv->assoc_request = -EINPROGRESS;
|
||||
|
||||
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
|
||||
(char *) sme->ssid, sme->bssid);
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
|
||||
priv->bss_mode, sme->channel, sme, 0);
|
||||
|
||||
priv->assoc_request = 1;
|
||||
done:
|
||||
priv->assoc_result = ret;
|
||||
queue_work(priv->workqueue, &priv->cfg_workqueue);
|
||||
if (!ret) {
|
||||
cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
|
||||
NULL, 0, WLAN_STATUS_SUCCESS,
|
||||
GFP_KERNEL);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: associated to bssid %pM successfully\n",
|
||||
priv->cfg_bssid);
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: association to bssid %pM failed\n",
|
||||
priv->cfg_bssid);
|
||||
memset(priv->cfg_bssid, 0, ETH_ALEN);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1018,28 +1019,29 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
|
||||
int ret = 0;
|
||||
|
||||
if (priv->ibss_join_request)
|
||||
return -EBUSY;
|
||||
|
||||
if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
|
||||
wiphy_err(wiphy, "request to join ibss received "
|
||||
"when station is not in ibss mode\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
priv->ibss_join_request = -EINPROGRESS;
|
||||
|
||||
wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
|
||||
(char *) params->ssid, params->bssid);
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
|
||||
params->bssid, priv->bss_mode,
|
||||
params->channel, NULL, params->privacy);
|
||||
|
||||
priv->ibss_join_request = 1;
|
||||
done:
|
||||
priv->ibss_join_result = ret;
|
||||
queue_work(priv->workqueue, &priv->cfg_workqueue);
|
||||
if (!ret) {
|
||||
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: joined/created adhoc network with bssid"
|
||||
" %pM successfully\n", priv->cfg_bssid);
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: failed creating/joining adhoc network\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1054,17 +1056,12 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
|
||||
|
||||
if (priv->disconnect)
|
||||
return -EBUSY;
|
||||
|
||||
priv->disconnect = 1;
|
||||
|
||||
wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
|
||||
priv->cfg_bssid);
|
||||
if (mwifiex_deauthenticate(priv, NULL))
|
||||
return -EFAULT;
|
||||
|
||||
queue_work(priv->workqueue, &priv->cfg_workqueue);
|
||||
memset(priv->cfg_bssid, 0, ETH_ALEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1081,15 +1078,42 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
int i;
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
|
||||
|
||||
if (priv->scan_request && priv->scan_request != request)
|
||||
return -EBUSY;
|
||||
|
||||
priv->scan_request = request;
|
||||
|
||||
queue_work(priv->workqueue, &priv->cfg_workqueue);
|
||||
priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!priv->user_scan_cfg) {
|
||||
dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (i = 0; i < request->n_ssids; i++) {
|
||||
memcpy(priv->user_scan_cfg->ssid_list[i].ssid,
|
||||
request->ssids[i].ssid, request->ssids[i].ssid_len);
|
||||
priv->user_scan_cfg->ssid_list[i].max_len =
|
||||
request->ssids[i].ssid_len;
|
||||
}
|
||||
for (i = 0; i < request->n_channels; i++) {
|
||||
chan = request->channels[i];
|
||||
priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
|
||||
priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
|
||||
|
||||
if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
priv->user_scan_cfg->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_PASSIVE;
|
||||
else
|
||||
priv->user_scan_cfg->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_ACTIVE;
|
||||
|
||||
priv->user_scan_cfg->chan_list[i].scan_time = 0;
|
||||
}
|
||||
if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1295,10 +1319,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
|
||||
|
||||
priv->media_connected = false;
|
||||
|
||||
cancel_work_sync(&priv->cfg_workqueue);
|
||||
flush_workqueue(priv->workqueue);
|
||||
destroy_workqueue(priv->workqueue);
|
||||
|
||||
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
|
||||
|
||||
return 0;
|
||||
@ -1376,9 +1396,6 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
|
||||
memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
|
||||
wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
|
||||
/* We are using custom domains */
|
||||
wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
|
||||
/* Reserve space for bss band information */
|
||||
wdev->wiphy->bss_priv_size = sizeof(u8);
|
||||
|
||||
@ -1407,100 +1424,3 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the result of different pending network operations.
|
||||
*
|
||||
* The following operations are handled and CFG802.11 subsystem is
|
||||
* notified accordingly -
|
||||
* - Scan request completion
|
||||
* - Association request completion
|
||||
* - IBSS join request completion
|
||||
* - Disconnect request completion
|
||||
*/
|
||||
void
|
||||
mwifiex_cfg80211_results(struct work_struct *work)
|
||||
{
|
||||
struct mwifiex_private *priv =
|
||||
container_of(work, struct mwifiex_private, cfg_workqueue);
|
||||
struct mwifiex_user_scan_cfg *scan_req;
|
||||
int ret = 0, i;
|
||||
struct ieee80211_channel *chan;
|
||||
|
||||
if (priv->scan_request) {
|
||||
scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!scan_req) {
|
||||
dev_err(priv->adapter->dev, "failed to alloc "
|
||||
"scan_req\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < priv->scan_request->n_ssids; i++) {
|
||||
memcpy(scan_req->ssid_list[i].ssid,
|
||||
priv->scan_request->ssids[i].ssid,
|
||||
priv->scan_request->ssids[i].ssid_len);
|
||||
scan_req->ssid_list[i].max_len =
|
||||
priv->scan_request->ssids[i].ssid_len;
|
||||
}
|
||||
for (i = 0; i < priv->scan_request->n_channels; i++) {
|
||||
chan = priv->scan_request->channels[i];
|
||||
scan_req->chan_list[i].chan_number = chan->hw_value;
|
||||
scan_req->chan_list[i].radio_type = chan->band;
|
||||
if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||
scan_req->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_PASSIVE;
|
||||
else
|
||||
scan_req->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_ACTIVE;
|
||||
scan_req->chan_list[i].scan_time = 0;
|
||||
}
|
||||
if (mwifiex_set_user_scan_ioctl(priv, scan_req))
|
||||
ret = -EFAULT;
|
||||
priv->scan_result_status = ret;
|
||||
dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
|
||||
__func__);
|
||||
cfg80211_scan_done(priv->scan_request,
|
||||
(priv->scan_result_status < 0));
|
||||
priv->scan_request = NULL;
|
||||
kfree(scan_req);
|
||||
}
|
||||
|
||||
if (priv->assoc_request == 1) {
|
||||
if (!priv->assoc_result) {
|
||||
cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
|
||||
NULL, 0, NULL, 0,
|
||||
WLAN_STATUS_SUCCESS,
|
||||
GFP_KERNEL);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: associated to bssid %pM successfully\n",
|
||||
priv->cfg_bssid);
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: association to bssid %pM failed\n",
|
||||
priv->cfg_bssid);
|
||||
memset(priv->cfg_bssid, 0, ETH_ALEN);
|
||||
}
|
||||
priv->assoc_request = 0;
|
||||
priv->assoc_result = 0;
|
||||
}
|
||||
|
||||
if (priv->ibss_join_request == 1) {
|
||||
if (!priv->ibss_join_result) {
|
||||
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
|
||||
GFP_KERNEL);
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: joined/created adhoc network with bssid"
|
||||
" %pM successfully\n", priv->cfg_bssid);
|
||||
} else {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"info: failed creating/joining adhoc network\n");
|
||||
}
|
||||
priv->ibss_join_request = 0;
|
||||
priv->ibss_join_result = 0;
|
||||
}
|
||||
|
||||
if (priv->disconnect) {
|
||||
memset(priv->cfg_bssid, 0, ETH_ALEN);
|
||||
priv->disconnect = 0;
|
||||
}
|
||||
}
|
||||
|
@ -26,5 +26,4 @@
|
||||
|
||||
int mwifiex_register_cfg80211(struct mwifiex_private *);
|
||||
|
||||
void mwifiex_cfg80211_results(struct work_struct *work);
|
||||
#endif
|
||||
|
@ -939,7 +939,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
|
||||
{
|
||||
struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
|
||||
unsigned long cmd_flags;
|
||||
unsigned long cmd_pending_q_flags;
|
||||
unsigned long scan_pending_q_flags;
|
||||
uint16_t cancel_scan_cmd = false;
|
||||
|
||||
@ -949,12 +948,9 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
|
||||
cmd_node = adapter->curr_cmd;
|
||||
cmd_node->wait_q_enabled = false;
|
||||
cmd_node->cmd_flag |= CMD_F_CANCELED;
|
||||
spin_lock_irqsave(&adapter->cmd_pending_q_lock,
|
||||
cmd_pending_q_flags);
|
||||
list_del(&cmd_node->list);
|
||||
spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
|
||||
cmd_pending_q_flags);
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
mwifiex_complete_cmd(adapter, adapter->curr_cmd);
|
||||
adapter->curr_cmd = NULL;
|
||||
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
|
||||
}
|
||||
|
||||
@ -981,7 +977,6 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
|
||||
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
|
||||
}
|
||||
adapter->cmd_wait_q.status = -1;
|
||||
mwifiex_complete_cmd(adapter, adapter->curr_cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -282,6 +282,45 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
|
||||
adapter->arp_filter_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets trans_start per tx_queue
|
||||
*/
|
||||
void mwifiex_set_trans_start(struct net_device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dev->num_tx_queues; i++)
|
||||
netdev_get_tx_queue(dev, i)->trans_start = jiffies;
|
||||
|
||||
dev->trans_start = jiffies;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function wakes up all queues in net_device
|
||||
*/
|
||||
void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
|
||||
struct mwifiex_adapter *adapter)
|
||||
{
|
||||
unsigned long dev_queue_flags;
|
||||
|
||||
spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
|
||||
netif_tx_wake_all_queues(netdev);
|
||||
spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function stops all queues in net_device
|
||||
*/
|
||||
void mwifiex_stop_net_dev_queue(struct net_device *netdev,
|
||||
struct mwifiex_adapter *adapter)
|
||||
{
|
||||
unsigned long dev_queue_flags;
|
||||
|
||||
spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function releases the lock variables and frees the locks and
|
||||
* associated locks.
|
||||
@ -359,6 +398,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
|
||||
spin_lock_init(&adapter->int_lock);
|
||||
spin_lock_init(&adapter->main_proc_lock);
|
||||
spin_lock_init(&adapter->mwifiex_cmd_lock);
|
||||
spin_lock_init(&adapter->queue_lock);
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
if (adapter->priv[i]) {
|
||||
priv = adapter->priv[i];
|
||||
|
@ -401,7 +401,7 @@ mwifiex_fill_buffer(struct sk_buff *skb)
|
||||
static int
|
||||
mwifiex_open(struct net_device *dev)
|
||||
{
|
||||
netif_start_queue(dev);
|
||||
netif_tx_start_all_queues(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -465,8 +465,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
atomic_inc(&priv->adapter->tx_pending);
|
||||
|
||||
if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
|
||||
netif_stop_queue(priv->netdev);
|
||||
dev->trans_start = jiffies;
|
||||
mwifiex_set_trans_start(dev);
|
||||
mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
|
||||
}
|
||||
|
||||
queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
|
||||
@ -533,7 +533,7 @@ mwifiex_tx_timeout(struct net_device *dev)
|
||||
|
||||
dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
|
||||
jiffies, priv->bss_index);
|
||||
dev->trans_start = jiffies;
|
||||
mwifiex_set_trans_start(dev);
|
||||
priv->num_tx_timeout++;
|
||||
}
|
||||
|
||||
@ -586,8 +586,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
|
||||
priv->media_connected = false;
|
||||
memset(&priv->nick_name, 0, sizeof(priv->nick_name));
|
||||
priv->num_tx_timeout = 0;
|
||||
priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
|
||||
INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
|
||||
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
|
||||
}
|
||||
|
||||
@ -793,7 +791,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev) {
|
||||
if (!netif_queue_stopped(priv->netdev))
|
||||
netif_stop_queue(priv->netdev);
|
||||
mwifiex_stop_net_dev_queue(priv->netdev,
|
||||
adapter);
|
||||
if (netif_carrier_ok(priv->netdev))
|
||||
netif_carrier_off(priv->netdev);
|
||||
}
|
||||
|
@ -453,15 +453,8 @@ struct mwifiex_private {
|
||||
u8 scan_pending_on_block;
|
||||
u8 report_scan_result;
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
int scan_result_status;
|
||||
int assoc_request;
|
||||
u16 assoc_result;
|
||||
int ibss_join_request;
|
||||
u16 ibss_join_result;
|
||||
bool disconnect;
|
||||
struct mwifiex_user_scan_cfg *user_scan_cfg;
|
||||
u8 cfg_bssid[6];
|
||||
struct workqueue_struct *workqueue;
|
||||
struct work_struct cfg_workqueue;
|
||||
u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
|
||||
struct wps wps;
|
||||
u8 scan_block;
|
||||
@ -655,10 +648,19 @@ struct mwifiex_adapter {
|
||||
struct mwifiex_wait_queue cmd_wait_q;
|
||||
u8 scan_wait_q_woken;
|
||||
struct cmd_ctrl_node *cmd_queued;
|
||||
spinlock_t queue_lock; /* lock for tx queues */
|
||||
};
|
||||
|
||||
int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
|
||||
|
||||
void mwifiex_set_trans_start(struct net_device *dev);
|
||||
|
||||
void mwifiex_stop_net_dev_queue(struct net_device *netdev,
|
||||
struct mwifiex_adapter *adapter);
|
||||
|
||||
void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
|
||||
struct mwifiex_adapter *adapter);
|
||||
|
||||
int mwifiex_init_fw(struct mwifiex_adapter *adapter);
|
||||
|
||||
int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user