X-Git-Url: https://git.archive.openwrt.org/?p=openwrt.git;a=blobdiff_plain;f=package%2Fkernel%2Fmac80211%2Fpatches%2F300-pending_work.patch;h=962c5e848b1199a4c7f70fa8099dd814f82a4110;hp=33f7264359db3ecc41fbde780694774bb07a4242;hb=8e517c0feae49a1c48b814cebf5e944ccad5fbf7;hpb=0db9741247f788efe8489be1fc8e115a458dc464 diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch index 33f7264359..962c5e848b 100644 --- a/package/kernel/mac80211/patches/300-pending_work.patch +++ b/package/kernel/mac80211/patches/300-pending_work.patch @@ -482,7 +482,15 @@ } --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -454,7 +454,6 @@ static void ath9k_hw_init_config(struct +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + #include "hw.h" +@@ -454,7 +455,6 @@ static void ath9k_hw_init_config(struct } ah->config.rx_intr_mitigation = true; @@ -490,6 +498,67 @@ /* * We need this for PCI devices only (Cardbus, PCI, miniPCI) +@@ -1502,8 +1502,9 @@ static bool ath9k_hw_channel_change(stru + int r; + + if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { +- band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); +- mode_diff = (chan->channelFlags != ah->curchan->channelFlags); ++ u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags; ++ band_switch = !!(flags_diff & CHANNEL_5GHZ); ++ mode_diff = !!(flags_diff & ~CHANNEL_HT); + } + + for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { +@@ -1815,7 +1816,7 @@ static int ath9k_hw_do_fastcc(struct ath + * If cross-band fcc is not supoprted, bail out if channelFlags differ. + */ + if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && +- chan->channelFlags != ah->curchan->channelFlags) ++ ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT)) + goto fail; + + if (!ath9k_hw_check_alive(ah)) +@@ -1856,10 +1857,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st + struct ath9k_hw_cal_data *caldata, bool fastcc) + { + struct ath_common *common = ath9k_hw_common(ah); ++ struct timespec ts; + u32 saveLedState; + u32 saveDefAntenna; + u32 macStaId1; + u64 tsf = 0; ++ s64 usec = 0; + int r; + bool start_mci_reset = false; + bool save_fullsleep = ah->chip_fullsleep; +@@ -1902,10 +1905,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st + + macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; + +- /* For chips on which RTC reset is done, save TSF before it gets cleared */ +- if (AR_SREV_9100(ah) || +- (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) +- tsf = ath9k_hw_gettsf64(ah); ++ /* Save TSF before chip reset, a cold reset clears it */ ++ tsf = ath9k_hw_gettsf64(ah); ++ getrawmonotonic(&ts); ++ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000; + + saveLedState = REG_READ(ah, AR_CFG_LED) & + (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | +@@ -1938,8 +1941,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st + } + + /* Restore TSF */ +- if (tsf) +- ath9k_hw_settsf64(ah, tsf); ++ getrawmonotonic(&ts); ++ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec; ++ ath9k_hw_settsf64(ah, tsf + usec); + + if (AR_SREV_9280_20_OR_LATER(ah)) + REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -283,7 +283,6 @@ struct ath9k_ops_config { @@ -3109,6 +3178,16 @@ /* check if we already stored this frame */ if (tid_agg_rx->reorder_buf[index]) { +@@ -911,7 +903,8 @@ static void ieee80211_rx_reorder_ampdu(s + u16 sc; + u8 tid, ack_policy; + +- if (!ieee80211_is_data_qos(hdr->frame_control)) ++ if (!ieee80211_is_data_qos(hdr->frame_control) || ++ is_multicast_ether_addr(hdr->addr1)) + goto dont_reorder; + + /* --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -526,7 +526,7 @@ static int __ieee80211_start_scan(struct @@ -4417,7 +4496,24 @@ --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -701,6 +701,54 @@ static int ar9550_hw_get_modes_txgain_in +@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struc + else + ah->enabled_cals &= ~TX_IQ_CAL; + +- if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) +- ah->enabled_cals |= TX_CL_CAL; +- else +- ah->enabled_cals &= ~TX_CL_CAL; + } ++ ++ if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) ++ ah->enabled_cals |= TX_CL_CAL; ++ else ++ ah->enabled_cals &= ~TX_CL_CAL; + } + + static void ar9003_hw_prog_ini(struct ath_hw *ah, +@@ -701,6 +702,54 @@ static int ar9550_hw_get_modes_txgain_in return ret; } @@ -4472,7 +4568,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan) { -@@ -726,6 +774,8 @@ static int ar9003_hw_process_ini(struct +@@ -726,6 +775,8 @@ static int ar9003_hw_process_ini(struct modesIndex); } @@ -4508,3 +4604,171 @@ #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ (((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280))) #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -181,6 +181,7 @@ static void rt2x00lib_autowakeup(struct + static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) + { ++ struct ieee80211_tx_control control = {}; + struct rt2x00_dev *rt2x00dev = data; + struct sk_buff *skb; + +@@ -195,7 +196,7 @@ static void rt2x00lib_bc_buffer_iter(voi + */ + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + while (skb) { +- rt2x00mac_tx(rt2x00dev->hw, NULL, skb); ++ rt2x00mac_tx(rt2x00dev->hw, &control, skb); + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + } + } +--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c +@@ -1040,8 +1040,8 @@ static void ar9003_hw_cl_cal_post_proc(s + } + } + +-static bool ar9003_hw_init_cal(struct ath_hw *ah, +- struct ath9k_channel *chan) ++static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, ++ struct ath9k_channel *chan) + { + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_cal_data *caldata = ah->caldata; +@@ -1228,13 +1228,109 @@ skip_tx_iqcal: + return true; + } + ++static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, ++ struct ath9k_channel *chan) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ struct ath9k_hw_cal_data *caldata = ah->caldata; ++ bool txiqcal_done = false; ++ bool is_reusable = true, status = true; ++ bool run_agc_cal = false, sep_iq_cal = false; ++ ++ /* Use chip chainmask only for calibration */ ++ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); ++ ++ if (ah->enabled_cals & TX_CL_CAL) { ++ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); ++ run_agc_cal = true; ++ } ++ ++ if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ++ goto skip_tx_iqcal; ++ ++ /* Do Tx IQ Calibration */ ++ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, ++ AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, ++ DELPT); ++ ++ /* ++ * For AR9485 or later chips, TxIQ cal runs as part of ++ * AGC calibration. Specifically, AR9550 in SoC chips. ++ */ ++ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { ++ txiqcal_done = true; ++ run_agc_cal = true; ++ } else { ++ sep_iq_cal = true; ++ run_agc_cal = true; ++ } ++ ++ /* ++ * In the SoC family, this will run for AR9300, AR9331 and AR9340. ++ */ ++ if (sep_iq_cal) { ++ txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); ++ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); ++ udelay(5); ++ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); ++ } ++ ++skip_tx_iqcal: ++ if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { ++ /* Calibrate the AGC */ ++ REG_WRITE(ah, AR_PHY_AGC_CONTROL, ++ REG_READ(ah, AR_PHY_AGC_CONTROL) | ++ AR_PHY_AGC_CONTROL_CAL); ++ ++ /* Poll for offset calibration complete */ ++ status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, ++ AR_PHY_AGC_CONTROL_CAL, ++ 0, AH_WAIT_TIMEOUT); ++ } ++ ++ if (!status) { ++ ath_dbg(common, CALIBRATE, ++ "offset calibration failed to complete in %d ms; noisy environment?\n", ++ AH_WAIT_TIMEOUT / 1000); ++ return false; ++ } ++ ++ if (txiqcal_done) ++ ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); ++ ++ /* Revert chainmask to runtime parameters */ ++ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ++ ++ /* Initialize list pointers */ ++ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; ++ ++ INIT_CAL(&ah->iq_caldata); ++ INSERT_CAL(ah, &ah->iq_caldata); ++ ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); ++ ++ /* Initialize current pointer to first element in list */ ++ ah->cal_list_curr = ah->cal_list; ++ ++ if (ah->cal_list_curr) ++ ath9k_hw_reset_calibration(ah, ah->cal_list_curr); ++ ++ if (caldata) ++ caldata->CalValid = 0; ++ ++ return true; ++} ++ + void ar9003_hw_attach_calib_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + struct ath_hw_ops *ops = ath9k_hw_ops(ah); + ++ if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah)) ++ priv_ops->init_cal = ar9003_hw_init_cal_pcoem; ++ else ++ priv_ops->init_cal = ar9003_hw_init_cal_soc; ++ + priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; +- priv_ops->init_cal = ar9003_hw_init_cal; + priv_ops->setup_calibration = ar9003_hw_setup_calibration; + + ops->calibrate = ar9003_hw_calibrate; +--- a/drivers/net/wireless/ath/ath9k/common.c ++++ b/drivers/net/wireless/ath/ath9k/common.c +@@ -98,10 +98,8 @@ struct ath9k_channel *ath9k_cmn_get_chan + { + struct ieee80211_channel *curchan = chandef->chan; + struct ath9k_channel *channel; +- u8 chan_idx; + +- chan_idx = curchan->hw_value; +- channel = &ah->channels[chan_idx]; ++ channel = &ah->channels[curchan->hw_value]; + ath9k_cmn_update_ichannel(channel, chandef); + + return channel; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_s + nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + + nsecs += minstrel_mcs_groups[group].duration[rate]; +- tp = 1000000 * ((mr->probability * 1000) / nsecs); ++ tp = 1000000 * ((prob * 1000) / nsecs); + + mr->cur_tp = MINSTREL_TRUNC(tp); + }