* fix ROC removal - avoids a firmware crash
* fix throughput regression on iwldvm devices * fix panic in BT Coex * fixes in rate control * fixes in scan -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJU+EkrAAoJEC0Llv5uNjIBJ8AP/A2YQHZgdQRrLukJmCLg5BrL +ztTI01w+d7h2FNfp3qqKX9mMDkVlxnPkXTOrgWYABfr0wV/IPxReOs7RLzguO4g 52YaD0s36QJKk+iuM8DSukmihRqm8wUlR10czM8BPiE9LBR5z095mtzEA/blbIpP TgiWWxq0GiFC+zU5kVE2OTkeamh/gLwNQUddsJ6hZHqmjLi/80R9XPg1hxu2ypRg VR4byv9VkcB5e0MTwTotYj45AK61skYKpdalITHlTApUfCD2+I4Qwjtyh1N/H6pe IIqzV8NF6PYqfhqZlDxgZC24HDcWQdAiI8VIlXJzfs9axPe8VYSpJ5EX3lnOkOTP F5oIGyzHte5bz2QungaUASOnCoU9KkriyKAXiWdFJC6xQwMWA5eAzYXHhZrRQFPq utVGa31eEavIaXcB3z269qnOXRt2lnj9BZlpYEY/46LNqvDKxoq6gCNyZE2qBJy7 ZgQ6DVMCEdmbiLIDxA8EovN3ansrBKcJu9Vn+BwsUfh1z2NEB+9V8i+24B4sJ9wf svO1vfbGp/QsxnrKHNQta+lH4jvklZnWtKkxR2oM2FC3bRig7ReCsbpPcc121C7N FSym2lyk/ADT7z5E7o1ApnHknmVKXT4PgUwlnZ8VZSz6f5oJ6n4+5Pd0Z17OlPXP cvQzSjpj5YQWLcVOu7ra =jQ7P -----END PGP SIGNATURE----- Merge tag 'iwlwifi-for-kalle-2015-03-05' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes * fix ROC removal - avoids a firmware crash * fix throughput regression on iwldvm devices * fix panic in BT Coex * fixes in rate control * fixes in scan
This commit is contained in:
commit
eb9f75d88e
10 changed files with 91 additions and 39 deletions
|
@ -95,7 +95,8 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = {
|
|||
.nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl1000_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
|
||||
|
@ -121,7 +122,8 @@ const struct iwl_cfg iwl1000_bg_cfg = {
|
|||
.base_params = &iwl1000_base_params, \
|
||||
.eeprom_params = &iwl1000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl100_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
|
||||
|
|
|
@ -123,7 +123,9 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
|
|||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
|
||||
const struct iwl_cfg iwl2000_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2200 BGN",
|
||||
|
@ -149,7 +151,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
|
|||
.nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl2030_2bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
|
||||
|
@ -170,7 +173,8 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
|
|||
.base_params = &iwl2000_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl105_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
|
||||
|
@ -197,7 +201,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
|
|||
.base_params = &iwl2030_base_params, \
|
||||
.eeprom_params = &iwl20x0_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
.rx_with_siso_diversity = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl135_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
|
||||
|
|
|
@ -93,7 +93,8 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = {
|
|||
.nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl5300_agn_cfg = {
|
||||
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
|
||||
|
@ -158,7 +159,8 @@ const struct iwl_cfg iwl5350_agn_cfg = {
|
|||
.base_params = &iwl5000_base_params, \
|
||||
.eeprom_params = &iwl5000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl5150_agn_cfg = {
|
||||
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
|
||||
|
|
|
@ -145,7 +145,8 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
|
|||
.nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6005_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
|
||||
|
@ -199,7 +200,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
|
|||
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6030_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
|
||||
|
@ -235,7 +237,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
|
|||
.nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_RF_STATE
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6035_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
|
||||
|
@ -290,7 +293,8 @@ const struct iwl_cfg iwl130_bg_cfg = {
|
|||
.nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
|
||||
.base_params = &iwl6000_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6000i_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
|
||||
|
@ -322,7 +326,8 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
|
|||
.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6050_2agn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
|
||||
|
@ -347,7 +352,8 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
|
|||
.base_params = &iwl6050_base_params, \
|
||||
.eeprom_params = &iwl6000_eeprom_params, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
.internal_wimax_coex = true
|
||||
.internal_wimax_coex = true, \
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
|
||||
|
||||
const struct iwl_cfg iwl6150_bgn_cfg = {
|
||||
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
|
||||
|
|
|
@ -793,7 +793,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
|
|||
if (!vif->bss_conf.assoc)
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
|
||||
if (mvmvif->phy_ctxt &&
|
||||
IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
|
||||
mvmvif->phy_ctxt->id))
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
|
|
|
@ -832,7 +832,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
|
|||
if (!vif->bss_conf.assoc)
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
if (data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id))
|
||||
if (mvmvif->phy_ctxt &&
|
||||
data->notif->rrc_enabled & BIT(mvmvif->phy_ctxt->id))
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
IWL_DEBUG_COEX(data->mvm,
|
||||
|
|
|
@ -405,7 +405,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
|
||||
&mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER)
|
||||
if ((mvm->fw->ucode_capa.capa[0] &
|
||||
IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
|
||||
(mvm->fw->ucode_capa.api[0] &
|
||||
IWL_UCODE_TLV_API_LQ_SS_PARAMS))
|
||||
hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |=
|
||||
IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
|
||||
}
|
||||
|
@ -2215,7 +2218,19 @@ static void iwl_mvm_mac_cancel_hw_scan(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_cancel_scan(mvm);
|
||||
/* Due to a race condition, it's possible that mac80211 asks
|
||||
* us to stop a hw_scan when it's already stopped. This can
|
||||
* happen, for instance, if we stopped the scan ourselves,
|
||||
* called ieee80211_scan_completed() and the userspace called
|
||||
* cancel scan scan before ieee80211_scan_work() could run.
|
||||
* To handle that, simply return if the scan is not running.
|
||||
*/
|
||||
/* FIXME: for now, we ignore this race for UMAC scans, since
|
||||
* they don't set the scan_status.
|
||||
*/
|
||||
if ((mvm->scan_status == IWL_MVM_SCAN_OS) ||
|
||||
(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
iwl_mvm_cancel_scan(mvm);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
@ -2559,12 +2574,29 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
|
|||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* Due to a race condition, it's possible that mac80211 asks
|
||||
* us to stop a sched_scan when it's already stopped. This
|
||||
* can happen, for instance, if we stopped the scan ourselves,
|
||||
* called ieee80211_sched_scan_stopped() and the userspace called
|
||||
* stop sched scan scan before ieee80211_sched_scan_stopped_work()
|
||||
* could run. To handle this, simply return if the scan is
|
||||
* not running.
|
||||
*/
|
||||
/* FIXME: for now, we ignore this race for UMAC scans, since
|
||||
* they don't set the scan_status.
|
||||
*/
|
||||
if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
|
||||
!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
|
||||
mutex_unlock(&mvm->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_scan_offload_stop(mvm, false);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
iwl_mvm_wait_for_async_handlers(mvm);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
||||
|
|
|
@ -134,9 +134,12 @@ enum rs_column_mode {
|
|||
#define MAX_NEXT_COLUMNS 7
|
||||
#define MAX_COLUMN_CHECKS 3
|
||||
|
||||
struct rs_tx_column;
|
||||
|
||||
typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl);
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
const struct rs_tx_column *next_col);
|
||||
|
||||
struct rs_tx_column {
|
||||
enum rs_column_mode mode;
|
||||
|
@ -147,13 +150,15 @@ struct rs_tx_column {
|
|||
};
|
||||
|
||||
static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
const struct rs_tx_column *next_col)
|
||||
{
|
||||
return iwl_mvm_bt_coex_is_ant_avail(mvm, tbl->rate.ant);
|
||||
return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant);
|
||||
}
|
||||
|
||||
static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
const struct rs_tx_column *next_col)
|
||||
{
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return false;
|
||||
|
@ -171,7 +176,8 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
}
|
||||
|
||||
static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
const struct rs_tx_column *next_col)
|
||||
{
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return false;
|
||||
|
@ -180,7 +186,8 @@ static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
|||
}
|
||||
|
||||
static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
const struct rs_tx_column *next_col)
|
||||
{
|
||||
struct rs_rate *rate = &tbl->rate;
|
||||
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
|
||||
|
@ -1590,7 +1597,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
|
|||
|
||||
for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
|
||||
allow_func = next_col->checks[j];
|
||||
if (allow_func && !allow_func(mvm, sta, tbl))
|
||||
if (allow_func && !allow_func(mvm, sta, tbl, next_col))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1128,8 +1128,10 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
|
|||
if (mvm->scan_status == IWL_MVM_SCAN_NONE)
|
||||
return 0;
|
||||
|
||||
if (iwl_mvm_is_radio_killed(mvm))
|
||||
if (iwl_mvm_is_radio_killed(mvm)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
|
||||
(!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
|
||||
|
@ -1148,16 +1150,14 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
|
|||
IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n",
|
||||
sched ? "offloaded " : "", ret);
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n",
|
||||
sched ? "offloaded " : "");
|
||||
|
||||
ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
out:
|
||||
/*
|
||||
* Clear the scan status so the next scan requests will succeed. This
|
||||
* also ensures the Rx handler doesn't do anything, as the scan was
|
||||
|
@ -1167,7 +1167,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
|
|||
if (mvm->scan_status == IWL_MVM_SCAN_OS)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
|
||||
|
||||
out:
|
||||
mvm->scan_status = IWL_MVM_SCAN_NONE;
|
||||
|
||||
if (notify) {
|
||||
|
@ -1177,7 +1176,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
|
|||
ieee80211_scan_completed(mvm->hw, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm,
|
||||
|
|
|
@ -750,8 +750,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
|
|||
* request
|
||||
*/
|
||||
list_for_each_entry(te_data, &mvm->time_event_list, list) {
|
||||
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE &&
|
||||
te_data->running) {
|
||||
if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||
is_p2p = true;
|
||||
goto remove_te;
|
||||
|
@ -766,10 +765,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm)
|
|||
* request
|
||||
*/
|
||||
list_for_each_entry(te_data, &mvm->aux_roc_te_list, list) {
|
||||
if (te_data->running) {
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||
goto remove_te;
|
||||
}
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
|
||||
goto remove_te;
|
||||
}
|
||||
|
||||
remove_te:
|
||||
|
|
Loading…
Reference in a new issue