diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2015-10-23 13:30:20 +0200 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2015-10-23 13:30:20 +0200 |
commit | e7549b926dd3ceec048f5689df90d4ec970c9419 (patch) | |
tree | c8645e0b4343c309aac1a3838a17cfcf0893d7b5 /drivers/net/wireless/ath/ath9k/init.c | |
parent | 499ba610c2829adafbf393c2f3773d73ae4445f3 (diff) | |
download | kernel_samsung_smdk4412-e7549b926dd3ceec048f5689df90d4ec970c9419.zip kernel_samsung_smdk4412-e7549b926dd3ceec048f5689df90d4ec970c9419.tar.gz kernel_samsung_smdk4412-e7549b926dd3ceec048f5689df90d4ec970c9419.tar.bz2 |
more driver stuff from 3.2.72
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/init.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 138 |
1 files changed, 67 insertions, 71 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index d6059a2..1355d71 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -14,8 +14,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <linux/dma-mapping.h> #include <linux/slab.h> #include <linux/ath9k_platform.h> +#include <linux/module.h> #include "ath9k.h" @@ -42,6 +44,10 @@ static int ath9k_btcoex_enable; module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); +static int ath9k_ps_enable; +module_param_named(ps_enable, ath9k_ps_enable, int, 0444); +MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); + bool is_ath9k_unloaded; /* We use the hw_value as an index into our private channel structure */ @@ -196,6 +202,19 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset) return val; } +static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset, + u32 set, u32 clr) +{ + u32 val; + + val = ioread32(sc->mem + reg_offset); + val &= ~clr; + val |= set; + iowrite32(val, sc->mem + reg_offset); + + return val; +} + static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) { struct ath_hw *ah = (struct ath_hw *) hw_priv; @@ -204,16 +223,12 @@ static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 cl unsigned long uninitialized_var(flags); u32 val; - if (ah->config.serialize_regmode == SER_REG_MODE_ON) + if (ah->config.serialize_regmode == SER_REG_MODE_ON) { spin_lock_irqsave(&sc->sc_serial_rw, flags); - - val = ioread32(sc->mem + reg_offset); - val &= ~clr; - val |= set; - iowrite32(val, sc->mem + reg_offset); - - if (ah->config.serialize_regmode == SER_REG_MODE_ON) + val = __ath9k_reg_rmw(sc, reg_offset, set, clr); spin_unlock_irqrestore(&sc->sc_serial_rw, flags); + } else + val = __ath9k_reg_rmw(sc, reg_offset, set, clr); return val; } @@ -245,7 +260,7 @@ static void setup_ht_cap(struct ath_softc *sc, ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - if (AR_SREV_9485(ah)) + if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) max_streams = 1; else if (AR_SREV_9300_20_OR_LATER(ah)) max_streams = 3; @@ -260,8 +275,8 @@ static void setup_ht_cap(struct ath_softc *sc, /* set up supported mcs set */ memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); - tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams); - rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams); + tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams); + rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams); ath_dbg(common, ATH_DBG_CONFIG, "TX streams %d, RX streams: %d\n", @@ -298,10 +313,6 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, struct list_head *head, const char *name, int nbuf, int ndesc, bool is_tx) { -#define DS2PHYS(_dd, _ds) \ - ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) -#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) -#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) struct ath_common *common = ath9k_hw_common(sc->sc_ah); u8 *ds; struct ath_buf *bf; @@ -396,34 +407,6 @@ fail2: fail: memset(dd, 0, sizeof(*dd)); return error; -#undef ATH_DESC_4KB_BOUND_CHECK -#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED -#undef DS2PHYS -} - -void ath9k_init_crypto(struct ath_softc *sc) -{ - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - int i = 0; - - /* Get the hardware key cache size. */ - common->keymax = AR_KEYTABLE_SIZE; - - /* - * Reset the key cache since some parts do not - * reset the contents on initial power up. - */ - for (i = 0; i < common->keymax; i++) - ath_hw_keyreset(common, (u16) i); - - /* - * Check whether the separate key cache entries - * are required to handle both tx+rx MIC keys. - * With split mic keys the number of stations is limited - * to 27 otherwise 59. - */ - if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) - common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; } static int ath9k_init_btcoex(struct ath_softc *sc) @@ -519,7 +502,6 @@ static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; @@ -529,10 +511,6 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->sc_flags |= SC_OP_RXAGGR; } - common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; - common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; - - ath9k_hw_set_diversity(sc->sc_ah, true); sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); @@ -546,7 +524,7 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; } -static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, +static int ath9k_init_softc(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { struct ath9k_platform_data *pdata = sc->dev->platform_data; @@ -561,10 +539,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, ah->hw = sc->hw; ah->hw_version.devid = devid; - ah->hw_version.subsysid = subsysid; ah->reg_ops.read = ath9k_ioread32; ah->reg_ops.write = ath9k_iowrite32; ah->reg_ops.rmw = ath9k_reg_rmw; + atomic_set(&ah->intr_ref_cnt, -1); sc->sc_ah = ah; if (!pdata) { @@ -575,6 +553,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, sc->sc_ah->gpio_val = pdata->gpio_val; sc->sc_ah->led_pin = pdata->led_pin; ah->is_clk_25mhz = pdata->is_clk_25mhz; + ah->get_mac_revision = pdata->get_mac_revision; + ah->external_reset = pdata->external_reset; } common = ath9k_hw_common(ah); @@ -585,6 +565,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, common->priv = sc; common->debug_mask = ath9k_debug; common->btcoex_enabled = ath9k_btcoex_enable == 1; + common->disable_ani = false; spin_lock_init(&common->cc_lock); spin_lock_init(&sc->sc_serial_rw); @@ -592,6 +573,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, mutex_init(&sc->mutex); #ifdef CONFIG_ATH9K_DEBUGFS spin_lock_init(&sc->nodes_lock); + spin_lock_init(&sc->debug.samp_lock); INIT_LIST_HEAD(&sc->nodes); #endif tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); @@ -625,7 +607,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_btcoex; - ath9k_init_crypto(sc); + ath9k_cmn_init_crypto(sc->sc_ah); ath9k_init_misc(sc); return 0; @@ -649,7 +631,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) struct ieee80211_supported_band *sband; struct ieee80211_channel *chan; struct ath_hw *ah = sc->sc_ah; - struct ath_regulatory *reg = ath9k_hw_regulatory(ah); int i; sband = &sc->sbands[band]; @@ -658,17 +639,14 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) ah->curchan = &ah->channels[chan->hw_value]; ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); - chan->max_power = reg->max_power_level / 2; } } static void ath9k_init_txpower_limits(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_channel *curchan = ah->curchan; - ah->txchainmask = common->tx_chainmask; if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) @@ -677,18 +655,33 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc) ah->curchan = curchan; } +void ath9k_reload_chainmask_settings(struct ath_softc *sc) +{ + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)) + return; + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) + setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) + setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); +} + + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) { - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_REPORTS_TX_ACK_STATUS; + if (ath9k_ps_enable) + hw->flags |= IEEE80211_HW_SUPPORTS_PS; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; @@ -716,9 +709,15 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); -#ifdef CONFIG_ATH9K_RATE_CONTROL - hw->rate_control_algorithm = "ath9k_rate_control"; -#endif + hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; + hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1; + + /* single chain devices with rx diversity */ + if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + hw->wiphy->available_antennas_rx = BIT(0) | BIT(1); + + sc->ant_rx = hw->wiphy->available_antennas_rx; + sc->ant_tx = hw->wiphy->available_antennas_tx; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = @@ -727,17 +726,12 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &sc->sbands[IEEE80211_BAND_5GHZ]; - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) - setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) - setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); - } + ath9k_reload_chainmask_settings(sc); SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } -int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, +int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; @@ -747,7 +741,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, struct ath_regulatory *reg; /* Bring up device */ - error = ath9k_init_softc(devid, sc, subsysid, bus_ops); + error = ath9k_init_softc(devid, sc, bus_ops); if (error != 0) goto error_init; @@ -782,6 +776,11 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ARRAY_SIZE(ath9k_tpt_blink)); #endif + INIT_WORK(&sc->hw_reset_work, ath_reset_work); + INIT_WORK(&sc->hw_check_work, ath_hw_check); + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); + INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); + /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) @@ -800,9 +799,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, goto error_world; } - INIT_WORK(&sc->hw_check_work, ath_hw_check); - INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); sc->last_rssi = ATH_RSSI_DUMMY_MARKER; ath_init_leds(sc); |