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

John W. Linville says:

====================
This is a batch of updates intended for the 3.13 stream...

The biggest item of interest in here is wcn36xx, the new mac80211
driver for Qualcomm WCN3660/WCN3680 hardware.

Regarding the mac80211 bits, Johannes says:

"We have an assortment of cleanups and new features, of which the
biggest one is probably the channel-switch support in IBSS. Nothing
else really stands out much."

On top of that, the ath9k and rt2x00 get a lot of update action from
Felix Fietkau and Gabor Juhos, respectively.  There are a handful of
updates to other drivers here and there as well.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2013-10-17 16:14:29 -04:00
89 changed files with 11952 additions and 1324 deletions

View File

@@ -6830,6 +6830,14 @@ L: linux-hexagon@vger.kernel.org
S: Supported
F: arch/hexagon/
QUALCOMM WCN36XX WIRELESS DRIVER
M: Eugene Krasnikov <k.eugene.e@gmail.com>
L: wcn36xx@lists.infradead.org
W: http://wireless.kernel.org/en/users/Drivers/wcn36xx
T: git git://github.com/KrasnikovEugene/wcn36xx.git
S: Supported
F: drivers/net/wireless/ath/wcn36xx/
QUICKCAM PARALLEL PORT WEBCAMS
M: Hans Verkuil <hverkuil@xs4all.nl>
L: linux-media@vger.kernel.org

View File

@@ -188,8 +188,11 @@ static int bcma_host_pci_probe(struct pci_dev *dev,
pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
/* SSB needed additional powering up, do we have any AMBA PCI cards? */
if (!pci_is_pcie(dev))
bcma_err(bus, "PCI card detected, report problems.\n");
if (!pci_is_pcie(dev)) {
bcma_err(bus, "PCI card detected, they are not supported.\n");
err = -ENXIO;
goto err_pci_release_regions;
}
/* Map MMIO */
err = -ENOMEM;
@@ -269,6 +272,7 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },

View File

@@ -32,5 +32,6 @@ source "drivers/net/wireless/ath/ath6kl/Kconfig"
source "drivers/net/wireless/ath/ar5523/Kconfig"
source "drivers/net/wireless/ath/wil6210/Kconfig"
source "drivers/net/wireless/ath/ath10k/Kconfig"
source "drivers/net/wireless/ath/wcn36xx/Kconfig"
endif

View File

@@ -5,6 +5,7 @@ obj-$(CONFIG_ATH6KL) += ath6kl/
obj-$(CONFIG_AR5523) += ar5523/
obj-$(CONFIG_WIL6210) += wil6210/
obj-$(CONFIG_ATH10K) += ath10k/
obj-$(CONFIG_WCN36XX) += wcn36xx/
obj-$(CONFIG_ATH_COMMON) += ath.o

View File

@@ -338,10 +338,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
aniState->cckNoiseImmunityLevel !=
ATH9K_ANI_CCK_DEF_LEVEL) {
ath_dbg(common, ANI,
"Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
"Restore defaults: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
ah->opmode,
chan->channel,
chan->channelFlags,
is_scanning,
aniState->ofdmNoiseImmunityLevel,
aniState->cckNoiseImmunityLevel);
@@ -354,10 +353,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
* restore historical levels for this channel
*/
ath_dbg(common, ANI,
"Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
"Restore history: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n",
ah->opmode,
chan->channel,
chan->channelFlags,
is_scanning,
aniState->ofdmNoiseImmunityLevel,
aniState->cckNoiseImmunityLevel);

View File

@@ -666,14 +666,13 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
if (IS_CHAN_HT40(chan)) {
phymode |= AR_PHY_FC_DYN2040_EN;
if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
(chan->chanmode == CHANNEL_G_HT40PLUS))
if (IS_CHAN_HT40PLUS(chan))
phymode |= AR_PHY_FC_DYN2040_PRI_CH;
}
REG_WRITE(ah, AR_PHY_TURBO, phymode);
ath9k_hw_set11nmac2040(ah);
ath9k_hw_set11nmac2040(ah, chan);
ENABLE_REGWRITE_BUFFER(ah);
@@ -691,31 +690,12 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
int i, regWrites = 0;
u32 modesIndex, freqIndex;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
if (IS_CHAN_5GHZ(chan)) {
freqIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
freqIndex = 1;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
} else {
freqIndex = 2;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
freqIndex = 2;
break;
default:
return -EINVAL;
modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
}
/*
@@ -814,8 +794,10 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
if (chan == NULL)
return;
rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
if (IS_CHAN_2GHZ(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
else
rfMode |= AR_PHY_MODE_OFDM;
if (!AR_SREV_9280_20_OR_LATER(ah))
rfMode |= (IS_CHAN_5GHZ(chan)) ?
@@ -1218,12 +1200,11 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)
iniDef = &aniState->iniDef;
ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",
ah->hw_version.macVersion,
ah->hw_version.macRev,
ah->opmode,
chan->channel,
chan->channelFlags);
chan->channel);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);

View File

@@ -33,15 +33,12 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
bool supported = false;
switch (ah->supp_cals & cal_type) {
case IQ_MISMATCH_CAL:
/* Run IQ Mismatch for non-CCK only */
if (!IS_CHAN_B(chan))
supported = true;
supported = true;
break;
case ADC_GAIN_CAL:
case ADC_DC_CAL:
/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
if (!IS_CHAN_B(chan) &&
!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
if (!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) &&
IS_CHAN_HT20(chan)))
supported = true;
break;

View File

@@ -419,28 +419,10 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
u32 modesIndex;
int i;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
break;
default:
return;
}
if (IS_CHAN_5GHZ(chan))
modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
else
modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
ENABLE_REGWRITE_BUFFER(ah);

View File

@@ -551,8 +551,7 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
if (IS_CHAN_HT40(chan)) {
phymode |= AR_PHY_GC_DYN2040_EN;
/* Configure control (primary) channel at +-10MHz */
if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
(chan->chanmode == CHANNEL_G_HT40PLUS))
if (IS_CHAN_HT40PLUS(chan))
phymode |= AR_PHY_GC_DYN2040_PRI_CH;
}
@@ -565,7 +564,7 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
/* Configure MAC for 20/40 operation */
ath9k_hw_set11nmac2040(ah);
ath9k_hw_set11nmac2040(ah, chan);
/* global transmit timeout (25 TUs default)*/
REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
@@ -682,42 +681,23 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
{
int ret;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
if (chan->channel <= 5350)
ret = 1;
else if ((chan->channel > 5350) && (chan->channel <= 5600))
ret = 3;
if (IS_CHAN_2GHZ(chan)) {
if (IS_CHAN_HT40(chan))
return 7;
else
ret = 5;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
if (chan->channel <= 5350)
ret = 2;
else if ((chan->channel > 5350) && (chan->channel <= 5600))
ret = 4;
else
ret = 6;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
ret = 8;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
ret = 7;
break;
default:
ret = -EINVAL;
return 8;
}
if (chan->channel <= 5350)
ret = 1;
else if ((chan->channel > 5350) && (chan->channel <= 5600))
ret = 3;
else
ret = 5;
if (IS_CHAN_HT40(chan))
ret++;
return ret;
}
@@ -727,28 +707,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
unsigned int regWrites = 0, i;
u32 modesIndex;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
break;
default:
return -EINVAL;
}
if (IS_CHAN_5GHZ(chan))
modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
else
modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
/*
* SOC, MAC, BB, RADIO initvals.
@@ -846,8 +808,10 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah,
if (chan == NULL)
return;
rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
if (IS_CHAN_2GHZ(chan))
rfMode |= AR_PHY_MODE_DYNAMIC;
else
rfMode |= AR_PHY_MODE_OFDM;
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
@@ -1273,12 +1237,11 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
aniState = &ah->ani;
iniDef = &aniState->iniDef;
ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",
ah->hw_version.macVersion,
ah->hw_version.macRev,
ah->opmode,
chan->channel,
chan->channelFlags);
chan->channel);
val = REG_READ(ah, AR_PHY_SFCORR);
iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
@@ -1536,28 +1499,10 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
unsigned int regWrites = 0;
u32 modesIndex;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
break;
default:
return -EINVAL;
}
if (IS_CHAN_5GHZ(chan))
modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
else
modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
if (modesIndex == ah->modes_index) {
*ini_reloaded = false;

View File

@@ -64,7 +64,6 @@ struct ath_node;
struct ath_config {
u16 txpowlimit;
u8 cabqReadytime;
};
/*************************/
@@ -207,6 +206,14 @@ struct ath_frame_info {
u8 baw_tracked : 1;
};
struct ath_rxbuf {
struct list_head list;
struct sk_buff *bf_mpdu;
void *bf_desc;
dma_addr_t bf_daddr;
dma_addr_t bf_buf_addr;
};
struct ath_buf_state {
u8 bf_type;
u8 bfs_paprd;
@@ -307,7 +314,7 @@ struct ath_rx {
struct ath_descdma rxdma;
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
struct ath_buf *buf_hold;
struct ath_rxbuf *buf_hold;
struct sk_buff *frag;
u32 ampdu_ref;
@@ -926,7 +933,6 @@ void ath9k_deinit_device(struct ath_softc *sc);
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
void ath9k_reload_chainmask_settings(struct ath_softc *sc);
bool ath9k_uses_beacons(int type);
void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw);
int ath9k_spectral_scan_config(struct ieee80211_hw *hw,
enum spectral_mode spectral_mode);

View File

@@ -186,7 +186,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (!ah->caldata)
@@ -208,7 +207,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
return true;
ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n",
currCal->calData->calType, conf->chandef.chan->center_freq);
currCal->calData->calType, ah->curchan->chan->center_freq);
ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
@@ -242,7 +241,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
int32_t val;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
if (ah->caldata)
@@ -252,7 +250,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
if (chainmask & (1 << i)) {
s16 nfval;
if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
continue;
if (h)
@@ -314,7 +312,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
ENABLE_REGWRITE_BUFFER(ah);
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
continue;
val = REG_READ(ah, ah->nf_regs[i]);
@@ -408,7 +406,6 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
ah->caldata->channel = chan->channel;
ah->caldata->channelFlags = chan->channelFlags;
ah->caldata->chanmode = chan->chanmode;
h = ah->caldata->nfCalHist;
default_nf = ath9k_hw_get_default_nf(ah, chan);
for (i = 0; i < NUM_NF_READINGS; i++) {

View File

@@ -49,103 +49,64 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
}
EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
static u32 ath9k_get_extchanmode(struct cfg80211_chan_def *chandef)
{
u32 chanmode = 0;
switch (chandef->chan->band) {
case IEEE80211_BAND_2GHZ:
switch (chandef->width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
chanmode = CHANNEL_G_HT20;
break;
case NL80211_CHAN_WIDTH_40:
if (chandef->center_freq1 > chandef->chan->center_freq)
chanmode = CHANNEL_G_HT40PLUS;
else
chanmode = CHANNEL_G_HT40MINUS;
break;
default:
break;
}
break;
case IEEE80211_BAND_5GHZ:
switch (chandef->width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
chanmode = CHANNEL_A_HT20;
break;
case NL80211_CHAN_WIDTH_40:
if (chandef->center_freq1 > chandef->chan->center_freq)
chanmode = CHANNEL_A_HT40PLUS;
else
chanmode = CHANNEL_A_HT40MINUS;
break;
default:
break;
}
break;
default:
break;
}
return chanmode;
}
/*
* Update internal channel flags.
*/
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
struct cfg80211_chan_def *chandef)
static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
struct cfg80211_chan_def *chandef)
{
ichan->channel = chandef->chan->center_freq;
ichan->chan = chandef->chan;
struct ieee80211_channel *chan = chandef->chan;
u16 flags = 0;
if (chandef->chan->band == IEEE80211_BAND_2GHZ) {
ichan->chanmode = CHANNEL_G;
ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
} else {
ichan->chanmode = CHANNEL_A;
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
}
ichan->channel = chan->center_freq;
ichan->chan = chan;
if (chan->band == IEEE80211_BAND_5GHZ)
flags |= CHANNEL_5GHZ;
switch (chandef->width) {
case NL80211_CHAN_WIDTH_5:
ichan->channelFlags |= CHANNEL_QUARTER;
flags |= CHANNEL_QUARTER;
break;
case NL80211_CHAN_WIDTH_10:
ichan->channelFlags |= CHANNEL_HALF;
flags |= CHANNEL_HALF;
break;
case NL80211_CHAN_WIDTH_20_NOHT:
break;
case NL80211_CHAN_WIDTH_20:
flags |= CHANNEL_HT;
break;
case NL80211_CHAN_WIDTH_40:
ichan->chanmode = ath9k_get_extchanmode(chandef);
if (chandef->center_freq1 > chandef->chan->center_freq)
flags |= CHANNEL_HT40PLUS | CHANNEL_HT;
else
flags |= CHANNEL_HT40MINUS | CHANNEL_HT;
break;
default:
WARN_ON(1);
}
ichan->channelFlags = flags;
}
EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
/*
* Get the internal channel reference.
*/
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah)
struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw,
struct ath_hw *ah,
struct cfg80211_chan_def *chandef)
{
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
struct ieee80211_channel *curchan = chandef->chan;
struct ath9k_channel *channel;
u8 chan_idx;
chan_idx = curchan->hw_value;
channel = &ah->channels[chan_idx];
ath9k_cmn_update_ichannel(channel, &hw->conf.chandef);
ath9k_cmn_update_ichannel(channel, chandef);
return channel;
}
EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
EXPORT_SYMBOL(ath9k_cmn_get_channel);
int ath9k_cmn_count_streams(unsigned int chainmask, int max)
{

View File

@@ -43,10 +43,9 @@
(((x) + ((mul)/2)) / (mul))
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
struct cfg80211_chan_def *chandef);
struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
struct ath_hw *ah);
struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw,
struct ath_hw *ah,
struct cfg80211_chan_def *chandef);
int ath9k_cmn_count_streams(unsigned int chainmask, int max);
void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
enum ath_stomp_type stomp_type);

View File

@@ -24,30 +24,10 @@
static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
struct ath9k_channel *ichan)
{
enum htc_phymode mode;
if (IS_CHAN_5GHZ(ichan))
return HTC_MODE_11NA;
mode = -EINVAL;
switch (ichan->chanmode) {
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
mode = HTC_MODE_11NG;
break;
case CHANNEL_A:
case CHANNEL_A_HT20:
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
mode = HTC_MODE_11NA;
break;
default:
break;
}
WARN_ON(mode < 0);
return mode;
return HTC_MODE_11NG;
}
bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
@@ -926,7 +906,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
WMI_CMD(WMI_FLUSH_RECV_CMDID);
/* setup initial channel */
init_channel = ath9k_cmn_get_curchannel(hw, ah);
init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (ret) {
@@ -1208,9 +1188,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
ath_dbg(common, CONFIG, "Set channel: %d MHz\n",
curchan->center_freq);
ath9k_cmn_update_ichannel(&priv->ah->channels[pos],
&hw->conf.chandef);
ath9k_cmn_get_channel(hw, priv->ah, &hw->conf.chandef);
if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
ath_err(common, "Unable to set channel\n");
ret = -EINVAL;

View File

@@ -130,29 +130,29 @@ void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause)
static void ath9k_hw_set_clockrate(struct ath_hw *ah)
{
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
unsigned int clockrate;
/* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */
if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah))
clockrate = 117;
else if (!ah->curchan) /* should really check for CCK instead */
else if (!chan) /* should really check for CCK instead */
clockrate = ATH9K_CLOCK_RATE_CCK;
else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ)
else if (IS_CHAN_2GHZ(chan))
clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM;
else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)
clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM;
else
clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM;
if (conf_is_ht40(conf))
if (IS_CHAN_HT40(chan))
clockrate *= 2;
if (ah->curchan) {
if (IS_CHAN_HALF_RATE(ah->curchan))
if (IS_CHAN_HALF_RATE(chan))
clockrate /= 2;
if (IS_CHAN_QUARTER_RATE(ah->curchan))
if (IS_CHAN_QUARTER_RATE(chan))
clockrate /= 4;
}
@@ -190,10 +190,7 @@ EXPORT_SYMBOL(ath9k_hw_wait);
void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
int hw_delay)
{
if (IS_CHAN_B(chan))
hw_delay = (4 * hw_delay) / 22;
else
hw_delay /= 10;
hw_delay /= 10;
if (IS_CHAN_HALF_RATE(chan))
hw_delay *= 2;
@@ -294,8 +291,7 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah,
return;
}
if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
(chan->chanmode == CHANNEL_G_HT40PLUS)) {
if (IS_CHAN_HT40PLUS(chan)) {
centers->synth_center =
chan->channel + HT40_CHANNEL_CENTER_SHIFT;
extoff = 1;
@@ -1042,7 +1038,6 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
void ath9k_hw_init_global_settings(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
const struct ath9k_channel *chan = ah->curchan;
int acktimeout, ctstimeout, ack_offset = 0;
int slottime;
@@ -1117,8 +1112,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
* BA frames in some implementations, but it has been found to fix ACK
* timeout issues in other cases as well.
*/
if (conf->chandef.chan &&
conf->chandef.chan->band == IEEE80211_BAND_2GHZ &&
if (IS_CHAN_2GHZ(chan) &&
!IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
acktimeout += 64 - sifstime - ah->slottime;
ctstimeout += 48 - sifstime - ah->slottime;
@@ -1160,9 +1154,7 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan)
{
u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
if (IS_CHAN_B(chan))
ctl |= CTL_11B;
else if (IS_CHAN_G(chan))
if (IS_CHAN_2GHZ(chan))
ctl |= CTL_11G;
else
ctl |= CTL_11A;
@@ -1510,10 +1502,8 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
int r;
if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
u32 cur = ah->curchan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
u32 new = chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
band_switch = (cur != new);
mode_diff = (chan->chanmode != ah->curchan->chanmode);
band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan);
mode_diff = (chan->channelFlags != ah->curchan->channelFlags);
}
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1552,9 +1542,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_set_clockrate(ah);
ath9k_hw_apply_txpower(ah, chan, false);
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
ath9k_hw_set_delta_slope(ah, chan);
ath9k_hw_spur_mitigate_freq(ah, chan);
if (band_switch || ini_reloaded)
@@ -1824,20 +1812,11 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
goto fail;
/*
* If cross-band fcc is not supoprted, bail out if
* either channelFlags or chanmode differ.
*
* chanmode will be different if the HT operating mode
* changes because of CSA.
* If cross-band fcc is not supoprted, bail out if channelFlags differ.
*/
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH)) {
if ((chan->channelFlags & CHANNEL_ALL) !=
(ah->curchan->channelFlags & CHANNEL_ALL))
goto fail;
if (chan->chanmode != ah->curchan->chanmode)
goto fail;
}
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
chan->channelFlags != ah->curchan->channelFlags)
goto fail;
if (!ath9k_hw_check_alive(ah))
goto fail;
@@ -1899,8 +1878,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ah->caldata = caldata;
if (caldata && (chan->channel != caldata->channel ||
chan->channelFlags != caldata->channelFlags ||
chan->chanmode != caldata->chanmode)) {
chan->channelFlags != caldata->channelFlags)) {
/* Operating channel changed, reset channel calibration data */
memset(caldata, 0, sizeof(*caldata));
ath9k_init_nfcal_hist_buffer(ah, chan);
@@ -1989,9 +1967,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_mfp(ah);
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
ath9k_hw_set_delta_slope(ah, chan);
ath9k_hw_set_delta_slope(ah, chan);
ath9k_hw_spur_mitigate_freq(ah, chan);
ah->eep_ops->set_board_values(ah, chan);
@@ -2968,12 +2944,11 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set)
}
EXPORT_SYMBOL(ath9k_hw_set_tsfadjust);
void ath9k_hw_set11nmac2040(struct ath_hw *ah)
void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
u32 macmode;
if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca)
if (IS_CHAN_HT40(chan) && !ah->config.cwm_ignore_extcca)
macmode = AR_2040_JOINED_RX_CLEAR;
else
macmode = 0;

View File

@@ -369,36 +369,6 @@ enum ath9k_int {
ATH9K_INT_NOCARD = 0xffffffff
};
#define CHANNEL_CCK 0x00020
#define CHANNEL_OFDM 0x00040
#define CHANNEL_2GHZ 0x00080
#define CHANNEL_5GHZ 0x00100
#define CHANNEL_PASSIVE 0x00200
#define CHANNEL_DYN 0x00400
#define CHANNEL_HALF 0x04000
#define CHANNEL_QUARTER 0x08000
#define CHANNEL_HT20 0x10000
#define CHANNEL_HT40PLUS 0x20000
#define CHANNEL_HT40MINUS 0x40000
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
#define CHANNEL_ALL \
(CHANNEL_OFDM| \
CHANNEL_CCK| \
CHANNEL_2GHZ | \
CHANNEL_5GHZ | \
CHANNEL_HT20 | \
CHANNEL_HT40PLUS | \
CHANNEL_HT40MINUS)
#define MAX_RTT_TABLE_ENTRY 6
#define MAX_IQCAL_MEASUREMENT 8
#define MAX_CL_TAB_ENTRY 16
@@ -417,8 +387,7 @@ enum ath9k_cal_flags {
struct ath9k_hw_cal_data {
u16 channel;
u32 channelFlags;
u32 chanmode;
u16 channelFlags;
unsigned long cal_flags;
int32_t CalValid;
int8_t iCoff;
@@ -436,33 +405,34 @@ struct ath9k_hw_cal_data {
struct ath9k_channel {
struct ieee80211_channel *chan;
u16 channel;
u32 channelFlags;
u32 chanmode;
u16 channelFlags;
s16 noisefloor;
};
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
(((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
(((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
(((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
#define IS_CHAN_A_FAST_CLOCK(_ah, _c) \
((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
#define CHANNEL_5GHZ BIT(0)
#define CHANNEL_HALF BIT(1)
#define CHANNEL_QUARTER BIT(2)
#define CHANNEL_HT BIT(3)
#define CHANNEL_HT40PLUS BIT(4)
#define CHANNEL_HT40MINUS BIT(5)
/* These macros check chanmode and not channelFlags */
#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
((_c)->chanmode == CHANNEL_G_HT20))
#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
((_c)->chanmode == CHANNEL_G_HT40MINUS))
#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
#define IS_CHAN_5GHZ(_c) (!!((_c)->channelFlags & CHANNEL_5GHZ))
#define IS_CHAN_2GHZ(_c) (!IS_CHAN_5GHZ(_c))
#define IS_CHAN_HALF_RATE(_c) (!!((_c)->channelFlags & CHANNEL_HALF))
#define IS_CHAN_QUARTER_RATE(_c) (!!((_c)->channelFlags & CHANNEL_QUARTER))
#define IS_CHAN_A_FAST_CLOCK(_ah, _c) \
(IS_CHAN_5GHZ(_c) && ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
#define IS_CHAN_HT(_c) ((_c)->channelFlags & CHANNEL_HT)
#define IS_CHAN_HT20(_c) (IS_CHAN_HT(_c) && !IS_CHAN_HT40(_c))
#define IS_CHAN_HT40(_c) \
(!!((_c)->channelFlags & (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)))
#define IS_CHAN_HT40PLUS(_c) ((_c)->channelFlags & CHANNEL_HT40PLUS)
#define IS_CHAN_HT40MINUS(_c) ((_c)->channelFlags & CHANNEL_HT40MINUS)
enum ath9k_power_mode {
ATH9K_PM_AWAKE = 0,
@@ -1033,7 +1003,7 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set);
void ath9k_hw_init_global_settings(struct ath_hw *ah);
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
void ath9k_hw_set11nmac2040(struct ath_hw *ah);
void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
const struct ath9k_beacon_state *bs);

View File

@@ -347,7 +347,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
u8 *ds;
struct ath_buf *bf;
int i, bsize, desc_len;
ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
@@ -399,33 +398,68 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
/* allocate buffers */
bsize = sizeof(struct ath_buf) * nbuf;
bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
if (!bf)
return -ENOMEM;
if (is_tx) {
struct ath_buf *bf;
for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
bsize = sizeof(struct ath_buf) * nbuf;
bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
if (!bf)
return -ENOMEM;
if (!(sc->sc_ah->caps.hw_caps &
ATH9K_HW_CAP_4KB_SPLITTRANS)) {
/*
* Skip descriptor addresses which can cause 4KB
* boundary crossing (addr + length) with a 32 dword
* descriptor fetch.
*/
while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
BUG_ON((caddr_t) bf->bf_desc >=
((caddr_t) dd->dd_desc +
dd->dd_desc_len));
for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
ds += (desc_len * ndesc);
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
if (!(sc->sc_ah->caps.hw_caps &
ATH9K_HW_CAP_4KB_SPLITTRANS)) {
/*
* Skip descriptor addresses which can cause 4KB
* boundary crossing (addr + length) with a 32 dword
* descriptor fetch.
*/
while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
BUG_ON((caddr_t) bf->bf_desc >=
((caddr_t) dd->dd_desc +
dd->dd_desc_len));
ds += (desc_len * ndesc);
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
}
}
list_add_tail(&bf->list, head);
}
} else {
struct ath_rxbuf *bf;
bsize = sizeof(struct ath_rxbuf) * nbuf;
bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
if (!bf)
return -ENOMEM;
for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
if (!(sc->sc_ah->caps.hw_caps &
ATH9K_HW_CAP_4KB_SPLITTRANS)) {
/*
* Skip descriptor addresses which can cause 4KB
* boundary crossing (addr + length) with a 32 dword
* descriptor fetch.
*/
while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
BUG_ON((caddr_t) bf->bf_desc >=
((caddr_t) dd->dd_desc +
dd->dd_desc_len));
ds += (desc_len * ndesc);
bf->bf_desc = ds;
bf->bf_daddr = DS2PHYS(dd, ds);
}
}
list_add_tail(&bf->list, head);
}
list_add_tail(&bf->list, head);
}
return 0;
}
@@ -437,7 +471,6 @@ static int ath9k_init_queues(struct ath_softc *sc)
sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
ath_cabq_update(sc);
sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
@@ -768,7 +801,7 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
chan = &sband->channels[i];
ah->curchan = &ah->channels[chan->hw_value];
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
ath9k_cmn_update_ichannel(ah->curchan, &chandef);
ath9k_cmn_get_channel(sc->hw, ah, &chandef);
ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
}
}

View File

@@ -374,7 +374,6 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);
bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ath9k_tx_queue_info *qi;
u32 cwMin, chanCwMin, value;
@@ -387,10 +386,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan))
chanCwMin = INIT_CWMIN_11B;
else
chanCwMin = INIT_CWMIN;
chanCwMin = INIT_CWMIN;
for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
} else

View File

@@ -603,8 +603,6 @@ enum ath9k_tx_queue_flags {
#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
#define ATH9K_DECOMP_MASK_SIZE 128
#define ATH9K_READY_TIME_LO_BOUND 50
#define ATH9K_READY_TIME_HI_BOUND 96
enum ath9k_pkt_type {
ATH9K_PKT_TYPE_NORMAL = 0,

View File

@@ -302,17 +302,91 @@ out:
* by reseting the chip. To accomplish this we must first cleanup any pending
* DMA, then restart stuff.
*/
static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
struct ath9k_channel *hchan)
static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_hw *hw = sc->hw;
struct ath9k_channel *hchan;
struct ieee80211_channel *chan = chandef->chan;
unsigned long flags;
bool offchannel;
int pos = chan->hw_value;
int old_pos = -1;
int r;
if (test_bit(SC_OP_INVALID, &sc->sc_flags))
return -EIO;
r = ath_reset_internal(sc, hchan);
offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
return r;
if (ah->curchan)
old_pos = ah->curchan - &ah->channels[0];
ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
chan->center_freq, chandef->width);
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
ath_update_survey_stats(sc);
spin_unlock_irqrestore(&common->cc_lock, flags);
ath9k_cmn_get_channel(hw, ah, chandef);
/*
* If the operating channel changes, change the survey in-use flags
* along with it.
* Reset the survey data for the new channel, unless we're switching
* back to the operating channel from an off-channel operation.
*/
if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
if (sc->cur_survey)
sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
sc->cur_survey = &sc->survey[pos];
memset(sc->cur_survey, 0, sizeof(struct survey_info));
sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}
hchan = &sc->sc_ah->channels[pos];
r = ath_reset_internal(sc, hchan);
if (r)
return r;
/*
* The most recent snapshot of channel->noisefloor for the old
* channel is only available after the hardware reset. Copy it to
* the survey stats now.
*/
if (old_pos >= 0)
ath_update_survey_nf(sc, old_pos);
/*
* Enable radar pulse detection if on a DFS channel. Spectral
* scanning and radar detection can not be used concurrently.
*/
if (hw->conf.radar_enabled) {
u32 rxfilter;
/* set HW specific DFS configuration */
ath9k_hw_set_radar_params(ah);
rxfilter = ath9k_hw_getrxfilter(ah);
rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
ATH9K_RX_FILTER_PHYERR;
ath9k_hw_setrxfilter(ah, rxfilter);
ath_dbg(common, DFS, "DFS enabled at freq %d\n",
chan->center_freq);
} else {
/* perform spectral scan if requested. */
if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
sc->spectral_mode == SPECTRAL_CHANSCAN)
ath9k_spectral_scan_trigger(hw);
}
return 0;
}
static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
@@ -601,7 +675,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
init_channel = ath9k_cmn_get_curchannel(hw, ah);
init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
/* Reset SERDES registers */
ath9k_hw_configpcipowersave(ah, false);
@@ -804,7 +878,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
}
if (!ah->curchan)
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef);
ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
ath9k_hw_phy_disable(ah);
@@ -823,7 +897,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath_dbg(common, CONFIG, "Driver halt\n");
}
bool ath9k_uses_beacons(int type)
static bool ath9k_uses_beacons(int type)
{
switch (type) {
case NL80211_IFTYPE_AP:
@@ -1208,81 +1282,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
}
if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) {
struct ieee80211_channel *curchan = hw->conf.chandef.chan;
int pos = curchan->hw_value;
int old_pos = -1;
unsigned long flags;
if (ah->curchan)
old_pos = ah->curchan - &ah->channels[0];
ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
curchan->center_freq, hw->conf.chandef.width);
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
ath_update_survey_stats(sc);
spin_unlock_irqrestore(&common->cc_lock, flags);
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
&conf->chandef);
/*
* If the operating channel changes, change the survey in-use flags
* along with it.
* Reset the survey data for the new channel, unless we're switching
* back to the operating channel from an off-channel operation.
*/
if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) &&
sc->cur_survey != &sc->survey[pos]) {
if (sc->cur_survey)
sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
sc->cur_survey = &sc->survey[pos];
memset(sc->cur_survey, 0, sizeof(struct survey_info));
sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
if (ath_set_channel(sc, &hw->conf.chandef) < 0) {
ath_err(common, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
return -EINVAL;
}
/*
* The most recent snapshot of channel->noisefloor for the old
* channel is only available after the hardware reset. Copy it to
* the survey stats now.
*/
if (old_pos >= 0)
ath_update_survey_nf(sc, old_pos);
/*
* Enable radar pulse detection if on a DFS channel. Spectral
* scanning and radar detection can not be used concurrently.
*/
if (hw->conf.radar_enabled) {
u32 rxfilter;
/* set HW specific DFS configuration */
ath9k_hw_set_radar_params(ah);
rxfilter = ath9k_hw_getrxfilter(ah);
rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
ATH9K_RX_FILTER_PHYERR;
ath9k_hw_setrxfilter(ah, rxfilter);
ath_dbg(common, DFS, "DFS enabled at freq %d\n",
curchan->center_freq);
} else {
/* perform spectral scan if requested. */
if (test_bit(SC_OP_SCANNING, &sc->sc_flags) &&
sc->spectral_mode == SPECTRAL_CHANSCAN)
ath9k_spectral_scan_trigger(hw);
}
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {

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