aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h4
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c17
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c64
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c267
4 files changed, 218 insertions, 134 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index e2588308e67..385b91911ab 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1183,7 +1183,7 @@ void ath5k_unregister_leds(struct ath5k_softc *sc);
1183int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); 1183int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
1184int ath5k_hw_on_hold(struct ath5k_hw *ah); 1184int ath5k_hw_on_hold(struct ath5k_hw *ah);
1185int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 1185int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1186 struct ieee80211_channel *channel, bool change_channel); 1186 struct ieee80211_channel *channel, bool fast, bool skip_pcu);
1187int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, 1187int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
1188 bool is_set); 1188 bool is_set);
1189/* Power management functions */ 1189/* Power management functions */
@@ -1324,7 +1324,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
1324int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); 1324int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1325/* Init function */ 1325/* Init function */
1326int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, 1326int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1327 u8 mode, u8 ee_mode, u8 freq); 1327 u8 mode, u8 ee_mode, u8 freq, bool fast);
1328 1328
1329/* 1329/*
1330 * Functions used internaly 1330 * Functions used internaly
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 526d8bc412c..33cd1bc4a71 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -80,7 +80,8 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
80MODULE_LICENSE("Dual BSD/GPL"); 80MODULE_LICENSE("Dual BSD/GPL");
81MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); 81MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
82 82
83static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); 83static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
84 bool skip_pcu);
84static int ath5k_beacon_update(struct ieee80211_hw *hw, 85static int ath5k_beacon_update(struct ieee80211_hw *hw,
85 struct ieee80211_vif *vif); 86 struct ieee80211_vif *vif);
86static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); 87static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
@@ -496,7 +497,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
496 * hardware at the new frequency, and then re-enable 497 * hardware at the new frequency, and then re-enable
497 * the relevant bits of the h/w. 498 * the relevant bits of the h/w.
498 */ 499 */
499 return ath5k_reset(sc, chan); 500 return ath5k_reset(sc, chan, true);
500} 501}
501 502
502static void 503static void
@@ -2327,7 +2328,7 @@ ath5k_tx_complete_poll_work(struct work_struct *work)
2327 if (needreset) { 2328 if (needreset) {
2328 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, 2329 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2329 "TX queues stuck, resetting\n"); 2330 "TX queues stuck, resetting\n");
2330 ath5k_reset(sc, sc->curchan); 2331 ath5k_reset(sc, NULL, true);
2331 } 2332 }
2332 2333
2333 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 2334 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
@@ -2407,7 +2408,7 @@ ath5k_init(struct ath5k_softc *sc)
2407 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | 2408 AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
2408 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; 2409 AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB;
2409 2410
2410 ret = ath5k_reset(sc, NULL); 2411 ret = ath5k_reset(sc, NULL, false);
2411 if (ret) 2412 if (ret)
2412 goto done; 2413 goto done;
2413 2414
@@ -2506,7 +2507,8 @@ ath5k_stop_hw(struct ath5k_softc *sc)
2506 * This should be called with sc->lock. 2507 * This should be called with sc->lock.
2507 */ 2508 */
2508static int 2509static int
2509ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) 2510ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan,
2511 bool skip_pcu)
2510{ 2512{
2511 struct ath5k_hw *ah = sc->ah; 2513 struct ath5k_hw *ah = sc->ah;
2512 int ret; 2514 int ret;
@@ -2523,7 +2525,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
2523 sc->curchan = chan; 2525 sc->curchan = chan;
2524 sc->curband = &sc->sbands[chan->band]; 2526 sc->curband = &sc->sbands[chan->band];
2525 } 2527 }
2526 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL); 2528 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
2529 skip_pcu);
2527 if (ret) { 2530 if (ret) {
2528 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); 2531 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
2529 goto err; 2532 goto err;
@@ -2569,7 +2572,7 @@ static void ath5k_reset_work(struct work_struct *work)
2569 reset_work); 2572 reset_work);
2570 2573
2571 mutex_lock(&sc->lock); 2574 mutex_lock(&sc->lock);
2572 ath5k_reset(sc, sc->curchan); 2575 ath5k_reset(sc, NULL, true);
2573 mutex_unlock(&sc->lock); 2576 mutex_unlock(&sc->lock);
2574} 2577}
2575 2578
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 9392320eb30..1b6fcf9e097 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -3223,7 +3223,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
3223\*************/ 3223\*************/
3224 3224
3225int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, 3225int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3226 u8 mode, u8 ee_mode, u8 freq) 3226 u8 mode, u8 ee_mode, u8 freq, bool fast)
3227{ 3227{
3228 struct ieee80211_channel *curr_channel; 3228 struct ieee80211_channel *curr_channel;
3229 int ret, i; 3229 int ret, i;
@@ -3232,11 +3232,37 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3232 ret = 0; 3232 ret = 0;
3233 3233
3234 /* 3234 /*
3235 * Sanity check for fast flag
3236 * Don't try fast channel change when changing modulation
3237 * mode/band. We check for chip compatibility on
3238 * ath5k_hw_reset.
3239 */
3240 curr_channel = ah->ah_current_channel;
3241 if (fast && (channel->hw_value != curr_channel->hw_value))
3242 return -EINVAL;
3243
3244 /*
3245 * On fast channel change we only set the synth parameters
3246 * while PHY is running, enable calibration and skip the rest.
3247 */
3248 if (fast) {
3249 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3250 AR5K_PHY_RFBUS_REQ_REQUEST);
3251 for (i = 0; i < 100; i++) {
3252 if (ath5k_hw_reg_read(ah, AR5K_PHY_RFBUS_GRANT))
3253 break;
3254 udelay(5);
3255 }
3256 /* Failed */
3257 if (i >= 100)
3258 return -EIO;
3259 }
3260
3261 /*
3235 * If we don't change channel/mode skip 3262 * If we don't change channel/mode skip
3236 * tx powertable calculation and use the 3263 * tx powertable calculation and use the
3237 * cached one. 3264 * cached one.
3238 */ 3265 */
3239 curr_channel = ah->ah_current_channel;
3240 if ((channel->hw_value == curr_channel->hw_value) && 3266 if ((channel->hw_value == curr_channel->hw_value) &&
3241 (channel->center_freq == curr_channel->center_freq)) 3267 (channel->center_freq == curr_channel->center_freq))
3242 fast_txp = true; 3268 fast_txp = true;
@@ -3262,7 +3288,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3262 * any settings (5210 also only supports 3288 * any settings (5210 also only supports
3263 * a/aturbo modes) 3289 * a/aturbo modes)
3264 */ 3290 */
3265 if (ah->ah_version != AR5K_AR5210) { 3291 if ((ah->ah_version != AR5K_AR5210) && !fast) {
3266 3292
3267 /* 3293 /*
3268 * Write initial RF gain settings 3294 * Write initial RF gain settings
@@ -3308,7 +3334,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3308 AR5K_TXCFG_B_MODE); 3334 AR5K_TXCFG_B_MODE);
3309 } 3335 }
3310 3336
3311 } else { 3337 } else if (ah->ah_version == AR5K_AR5210) {
3312 mdelay(1); 3338 mdelay(1);
3313 /* Disable phy and wait */ 3339 /* Disable phy and wait */
3314 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); 3340 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
@@ -3345,18 +3371,26 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3345 mdelay(1); 3371 mdelay(1);
3346 } 3372 }
3347 3373
3348 /* 3374 if (fast)
3349 * Perform ADC test to see if baseband is ready 3375 /*
3350 * Set TX hold and check ADC test register 3376 * Release RF Bus grant
3351 */ 3377 */
3352 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); 3378 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_RFBUS_REQ,
3353 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); 3379 AR5K_PHY_RFBUS_REQ_REQUEST);
3354 for (i = 0; i <= 20; i++) { 3380 else {
3355 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) 3381 /*
3356 break; 3382 * Perform ADC test to see if baseband is ready
3357 udelay(200); 3383 * Set tx hold and check adc test register
3384 */
3385 phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
3386 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
3387 for (i = 0; i <= 20; i++) {
3388 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
3389 break;
3390 udelay(200);
3391 }
3392 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
3358 } 3393 }
3359 ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
3360 3394
3361 /* 3395 /*
3362 * Start automatic gain control calibration 3396 * Start automatic gain control calibration
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index ec013103a6a..e02bcbbd7a8 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -938,7 +938,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
938\*********************/ 938\*********************/
939 939
940int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, 940int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
941 struct ieee80211_channel *channel, bool change_channel) 941 struct ieee80211_channel *channel, bool fast, bool skip_pcu)
942{ 942{
943 struct ath_common *common = ath5k_hw_common(ah); 943 struct ath_common *common = ath5k_hw_common(ah);
944 u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo; 944 u32 s_seq[10], s_led[3], staid1_flags, tsf_up, tsf_lo;
@@ -952,6 +952,20 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
952 freq = 0; 952 freq = 0;
953 mode = 0; 953 mode = 0;
954 954
955 /*
956 * Sanity check for fast flag
957 * Fast channel change only available
958 * on AR2413/AR5413.
959 */
960 if (fast && (ah->ah_radio != AR5K_RF2413) &&
961 (ah->ah_radio != AR5K_RF5413))
962 fast = 0;
963
964 /* Disable sleep clock operation
965 * to avoid register access delay on certain
966 * PHY registers */
967 if (ah->ah_version == AR5K_AR5212)
968 ath5k_hw_set_sleep_clock(ah, false);
955 969
956 /* 970 /*
957 * Stop PCU 971 * Stop PCU
@@ -964,111 +978,137 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
964 * Note: If DMA didn't stop continue 978 * Note: If DMA didn't stop continue
965 * since only a reset will fix it. 979 * since only a reset will fix it.
966 */ 980 */
967 ath5k_hw_dma_stop(ah); 981 ret = ath5k_hw_dma_stop(ah);
982
983 /* RF Bus grant won't work if we have pending
984 * frames */
985 if (ret && fast) {
986 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
987 "DMA didn't stop, falling back to normal reset\n");
988 fast = 0;
989 /* Non fatal, just continue with
990 * normal reset */
991 ret = 0;
992 }
968 993
969 /* 994 switch (channel->hw_value & CHANNEL_MODES) {
970 * Save some registers before a reset 995 case CHANNEL_A:
971 */ 996 mode = AR5K_MODE_11A;
972 /*DCU/Antenna selection not available on 5210*/ 997 freq = AR5K_INI_RFGAIN_5GHZ;
973 if (ah->ah_version != AR5K_AR5210) { 998 ee_mode = AR5K_EEPROM_MODE_11A;
999 break;
1000 case CHANNEL_G:
974 1001
975 switch (channel->hw_value & CHANNEL_MODES) { 1002 if (ah->ah_version <= AR5K_AR5211) {
976 case CHANNEL_A:
977 mode = AR5K_MODE_11A;
978 freq = AR5K_INI_RFGAIN_5GHZ;
979 ee_mode = AR5K_EEPROM_MODE_11A;
980 break;
981 case CHANNEL_G:
982 mode = AR5K_MODE_11G;
983 freq = AR5K_INI_RFGAIN_2GHZ;
984 ee_mode = AR5K_EEPROM_MODE_11G;
985 break;
986 case CHANNEL_B:
987 mode = AR5K_MODE_11B;
988 freq = AR5K_INI_RFGAIN_2GHZ;
989 ee_mode = AR5K_EEPROM_MODE_11B;
990 break;
991 case CHANNEL_T:
992 mode = AR5K_MODE_11A_TURBO;
993 freq = AR5K_INI_RFGAIN_5GHZ;
994 ee_mode = AR5K_EEPROM_MODE_11A;
995 break;
996 case CHANNEL_TG:
997 if (ah->ah_version == AR5K_AR5211) {
998 ATH5K_ERR(ah->ah_sc,
999 "TurboG mode not available on 5211");
1000 return -EINVAL;
1001 }
1002 mode = AR5K_MODE_11G_TURBO;
1003 freq = AR5K_INI_RFGAIN_2GHZ;
1004 ee_mode = AR5K_EEPROM_MODE_11G;
1005 break;
1006 case CHANNEL_XR:
1007 if (ah->ah_version == AR5K_AR5211) {
1008 ATH5K_ERR(ah->ah_sc,
1009 "XR mode not available on 5211");
1010 return -EINVAL;
1011 }
1012 mode = AR5K_MODE_XR;
1013 freq = AR5K_INI_RFGAIN_5GHZ;
1014 ee_mode = AR5K_EEPROM_MODE_11A;
1015 break;
1016 default:
1017 ATH5K_ERR(ah->ah_sc, 1003 ATH5K_ERR(ah->ah_sc,
1018 "invalid channel: %d\n", channel->center_freq); 1004 "G mode not available on 5210/5211");
1019 return -EINVAL; 1005 return -EINVAL;
1020 } 1006 }
1021 1007
1022 if (change_channel) { 1008 mode = AR5K_MODE_11G;
1023 /* 1009 freq = AR5K_INI_RFGAIN_2GHZ;
1024 * Save frame sequence count 1010 ee_mode = AR5K_EEPROM_MODE_11G;
1025 * For revs. after Oahu, only save 1011 break;
1026 * seq num for DCU 0 (Global seq num) 1012 case CHANNEL_B:
1027 */
1028 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1029
1030 for (i = 0; i < 10; i++)
1031 s_seq[i] = ath5k_hw_reg_read(ah,
1032 AR5K_QUEUE_DCU_SEQNUM(i));
1033 1013
1034 } else { 1014 if (ah->ah_version < AR5K_AR5211) {
1035 s_seq[0] = ath5k_hw_reg_read(ah, 1015 ATH5K_ERR(ah->ah_sc,
1036 AR5K_QUEUE_DCU_SEQNUM(0)); 1016 "B mode not available on 5210");
1037 } 1017 return -EINVAL;
1018 }
1038 1019
1039 /* TSF accelerates on AR5211 during reset 1020 mode = AR5K_MODE_11B;
1040 * As a workaround save it here and restore 1021 freq = AR5K_INI_RFGAIN_2GHZ;
1041 * it later so that it's back in time after 1022 ee_mode = AR5K_EEPROM_MODE_11B;
1042 * reset. This way it'll get re-synced on the 1023 break;
1043 * next beacon without breaking ad-hoc. 1024 case CHANNEL_T:
1044 * 1025 mode = AR5K_MODE_11A_TURBO;
1045 * On AR5212 TSF is almost preserved across a 1026 freq = AR5K_INI_RFGAIN_5GHZ;
1046 * reset so it stays back in time anyway and 1027 ee_mode = AR5K_EEPROM_MODE_11A;
1047 * we don't have to save/restore it. 1028 break;
1048 * 1029 case CHANNEL_TG:
1049 * XXX: Since this breaks power saving we have 1030 if (ah->ah_version == AR5K_AR5211) {
1050 * to disable power saving until we receive the 1031 ATH5K_ERR(ah->ah_sc,
1051 * next beacon, so we can resync beacon timers */ 1032 "TurboG mode not available on 5211");
1052 if (ah->ah_version == AR5K_AR5211) { 1033 return -EINVAL;
1053 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
1054 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
1055 }
1056 } 1034 }
1035 mode = AR5K_MODE_11G_TURBO;
1036 freq = AR5K_INI_RFGAIN_2GHZ;
1037 ee_mode = AR5K_EEPROM_MODE_11G;
1038 break;
1039 case CHANNEL_XR:
1040 if (ah->ah_version == AR5K_AR5211) {
1041 ATH5K_ERR(ah->ah_sc,
1042 "XR mode not available on 5211");
1043 return -EINVAL;
1044 }
1045 mode = AR5K_MODE_XR;
1046 freq = AR5K_INI_RFGAIN_5GHZ;
1047 ee_mode = AR5K_EEPROM_MODE_11A;
1048 break;
1049 default:
1050 ATH5K_ERR(ah->ah_sc,
1051 "invalid channel: %d\n", channel->center_freq);
1052 return -EINVAL;
1053 }
1057 1054
1058 if (ah->ah_version == AR5K_AR5212) { 1055 /*
1059 /* Restore normal 32/40MHz clock operation 1056 * If driver requested fast channel change and DMA has stopped
1060 * to avoid register access delay on certain 1057 * go on. If it fails continue with a normal reset.
1061 * PHY registers */ 1058 */
1062 ath5k_hw_set_sleep_clock(ah, false); 1059 if (fast) {
1060 ret = ath5k_hw_phy_init(ah, channel, mode,
1061 ee_mode, freq, true);
1062 if (ret) {
1063 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
1064 "fast chan change failed, falling back to normal reset\n");
1065 /* Non fatal, can happen eg.
1066 * on mode change */
1067 ret = 0;
1068 } else
1069 return 0;
1070 }
1063 1071
1064 /* Since we are going to write rf buffer 1072 /*
1065 * check if we have any pending gain_F 1073 * Save some registers before a reset
1066 * optimization settings */ 1074 */
1067 if (change_channel && ah->ah_rf_banks != NULL) 1075 if (ah->ah_version != AR5K_AR5210) {
1068 ath5k_hw_gainf_calibrate(ah); 1076 /*
1077 * Save frame sequence count
1078 * For revs. after Oahu, only save
1079 * seq num for DCU 0 (Global seq num)
1080 */
1081 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1082
1083 for (i = 0; i < 10; i++)
1084 s_seq[i] = ath5k_hw_reg_read(ah,
1085 AR5K_QUEUE_DCU_SEQNUM(i));
1086
1087 } else {
1088 s_seq[0] = ath5k_hw_reg_read(ah,
1089 AR5K_QUEUE_DCU_SEQNUM(0));
1090 }
1091
1092 /* TSF accelerates on AR5211 during reset
1093 * As a workaround save it here and restore
1094 * it later so that it's back in time after
1095 * reset. This way it'll get re-synced on the
1096 * next beacon without breaking ad-hoc.
1097 *
1098 * On AR5212 TSF is almost preserved across a
1099 * reset so it stays back in time anyway and
1100 * we don't have to save/restore it.
1101 *
1102 * XXX: Since this breaks power saving we have
1103 * to disable power saving until we receive the
1104 * next beacon, so we can resync beacon timers */
1105 if (ah->ah_version == AR5K_AR5211) {
1106 tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
1107 tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
1069 } 1108 }
1070 } 1109 }
1071 1110
1111
1072 /*GPIOs*/ 1112 /*GPIOs*/
1073 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & 1113 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1074 AR5K_PCICFG_LEDSTATE; 1114 AR5K_PCICFG_LEDSTATE;
@@ -1085,6 +1125,17 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1085 AR5K_STA_ID1_BASE_RATE_11B | 1125 AR5K_STA_ID1_BASE_RATE_11B |
1086 AR5K_STA_ID1_SELFGEN_DEF_ANT); 1126 AR5K_STA_ID1_SELFGEN_DEF_ANT);
1087 1127
1128 /*
1129 * Since we are going to write rf buffer
1130 * check if we have any pending gain_F
1131 * optimization settings
1132 */
1133 if (ah->ah_version == AR5K_AR5212 &&
1134 (ah->ah_radio <= AR5K_RF5112)) {
1135 if (!fast && ah->ah_rf_banks != NULL)
1136 ath5k_hw_gainf_calibrate(ah);
1137 }
1138
1088 /* Wakeup the device */ 1139 /* Wakeup the device */
1089 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); 1140 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
1090 if (ret) 1141 if (ret)
@@ -1098,7 +1149,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1098 AR5K_PHY(0)); 1149 AR5K_PHY(0));
1099 1150
1100 /* Write initial settings */ 1151 /* Write initial settings */
1101 ret = ath5k_hw_write_initvals(ah, mode, change_channel); 1152 ret = ath5k_hw_write_initvals(ah, mode, skip_pcu);
1102 if (ret) 1153 if (ret)
1103 return ret; 1154 return ret;
1104 1155
@@ -1120,24 +1171,20 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1120 * Restore saved values 1171 * Restore saved values
1121 */ 1172 */
1122 1173
1123 /*DCU/Antenna selection not available on 5210*/ 1174 /* Seqnum, TSF */
1124 if (ah->ah_version != AR5K_AR5210) { 1175 if (ah->ah_version != AR5K_AR5210) {
1176 if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
1177 for (i = 0; i < 10; i++)
1178 ath5k_hw_reg_write(ah, s_seq[i],
1179 AR5K_QUEUE_DCU_SEQNUM(i));
1180 } else {
1181 ath5k_hw_reg_write(ah, s_seq[0],
1182 AR5K_QUEUE_DCU_SEQNUM(0));
1183 }
1125 1184
1126 if (change_channel) { 1185 if (ah->ah_version == AR5K_AR5211) {
1127 if (ah->ah_mac_srev < AR5K_SREV_AR5211) { 1186 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1128 for (i = 0; i < 10; i++) 1187 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1129 ath5k_hw_reg_write(ah, s_seq[i],
1130 AR5K_QUEUE_DCU_SEQNUM(i));
1131 } else {
1132 ath5k_hw_reg_write(ah, s_seq[0],
1133 AR5K_QUEUE_DCU_SEQNUM(0));
1134 }
1135
1136
1137 if (ah->ah_version == AR5K_AR5211) {
1138 ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
1139 ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
1140 }
1141 } 1188 }
1142 } 1189 }
1143 1190
@@ -1165,7 +1212,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1165 /* 1212 /*
1166 * Initialize PHY 1213 * Initialize PHY
1167 */ 1214 */
1168 ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq); 1215 ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false);
1169 if (ret) { 1216 if (ret) {
1170 ATH5K_ERR(ah->ah_sc, 1217 ATH5K_ERR(ah->ah_sc,
1171 "failed to initialize PHY (%i) !\n", ret); 1218 "failed to initialize PHY (%i) !\n", ret);