diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/dvm')
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/agn.h | 58 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/calib.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/commands.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/dev.h | 73 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/devices.c | 107 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/lib.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 37 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/main.c | 69 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/power.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rs.c | 51 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rx.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/scan.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/testmode.c | 471 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tt.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/ucode.c | 10 |
17 files changed, 281 insertions, 728 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile index 5ff76b204141..dce7ab2e0c4b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/Makefile +++ b/drivers/net/wireless/iwlwifi/dvm/Makefile @@ -8,6 +8,5 @@ iwldvm-objs += scan.o led.o iwldvm-objs += rxon.o devices.o iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o -iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 48545ab00311..18355110deff 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -76,13 +76,16 @@ #define IWL_INVALID_STATION 255 /* device operations */ -extern struct iwl_lib_ops iwl1000_lib; -extern struct iwl_lib_ops iwl2000_lib; -extern struct iwl_lib_ops iwl2030_lib; -extern struct iwl_lib_ops iwl5000_lib; -extern struct iwl_lib_ops iwl5150_lib; -extern struct iwl_lib_ops iwl6000_lib; -extern struct iwl_lib_ops iwl6030_lib; +extern const struct iwl_dvm_cfg iwl_dvm_1000_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_2000_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_105_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_2030_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_5000_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_5150_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_6000_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_6005_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_6050_cfg; +extern const struct iwl_dvm_cfg iwl_dvm_6030_cfg; #define TIME_UNIT 1024 @@ -291,8 +294,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) { - return priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist; + return priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist; } #ifdef CONFIG_IWLWIFI_DEBUG @@ -402,43 +405,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) extern int iwl_alive_start(struct iwl_priv *priv); -/* testmode support */ -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - -extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, - int len); -extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len); -extern void iwl_testmode_init(struct iwl_priv *priv); -extern void iwl_testmode_free(struct iwl_priv *priv); - -#else - -static inline -int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) -{ - return -ENOSYS; -} - -static inline -int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len) -{ - return -ENOSYS; -} - -static inline void iwl_testmode_init(struct iwl_priv *priv) -{ -} - -static inline void iwl_testmode_free(struct iwl_priv *priv) -{ -} -#endif - #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, enum iwl_rxon_context_id ctxid); diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index d6c4cf2ad7c5..1b0f0d502568 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c @@ -521,7 +521,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); - if (priv->cfg->base_params->hd_v2) { + if (priv->lib->hd_v2) { cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = @@ -895,7 +895,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, continue; } - delta_g = (priv->cfg->base_params->chain_noise_scale * + delta_g = (priv->lib->chain_noise_scale * ((s32)average_noise[default_chain] - (s32)average_noise[i])) / 1500; @@ -1051,8 +1051,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) return; /* Analyze signal for disconnected antenna */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { /* Disable disconnected antenna algorithm for advanced bt coex, assuming valid antennas are connected */ data->active_chains = priv->nvm_data->valid_rx_ant; diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 95ca026ecc9d..ebdac909f0cd 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -838,10 +838,6 @@ struct iwl_qosparam_cmd { #define STA_MODIFY_DELBA_TID_MSK 0x10 #define STA_MODIFY_SLEEP_TX_COUNT_MSK 0x20 -/* Receiver address (actually, Rx station's index into station table), - * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ -#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) - /* agn */ struct iwl_keyinfo { __le16 key_flags; @@ -1225,14 +1221,6 @@ struct iwl_rx_mpdu_res_start { #define TX_CMD_SEC_KEY128 0x08 /* - * security overhead sizes - */ -#define WEP_IV_LEN 4 -#define WEP_ICV_LEN 4 -#define CCMP_MIC_LEN 8 -#define TKIP_ICV_LEN 4 - -/* * REPLY_TX = 0x1c (command) */ diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 71ea77576d22..60a4e0d15715 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -52,8 +52,6 @@ #include "rs.h" #include "tt.h" -#include "iwl-test.h" - /* CT-KILL constants */ #define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ #define CT_KILL_THRESHOLD 114 /* in Celsius */ @@ -568,16 +566,61 @@ struct iwl_hw_params { const struct iwl_sensitivity_ranges *sens; }; -struct iwl_lib_ops { - /* set hw dependent parameters */ +/** + * struct iwl_dvm_bt_params - DVM specific BT (coex) parameters + * @advanced_bt_coexist: support advanced bt coexist + * @bt_init_traffic_load: specify initial bt traffic load + * @bt_prio_boost: default bt priority boost value + * @agg_time_limit: maximum number of uSec in aggregation + * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode + */ +struct iwl_dvm_bt_params { + bool advanced_bt_coexist; + u8 bt_init_traffic_load; + u32 bt_prio_boost; + u16 agg_time_limit; + bool bt_sco_disable; + bool bt_session_2; +}; + +/** + * struct iwl_dvm_cfg - DVM firmware specific device configuration + * @set_hw_params: set hardware parameters + * @set_channel_switch: send channel switch command + * @nic_config: apply device specific configuration + * @temperature: read temperature + * @adv_thermal_throttle: support advance thermal throttle + * @support_ct_kill_exit: support ct kill exit condition + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate + * @chain_noise_scale: default chain noise scale used for gain computation + * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up + * @no_idle_support: do not support idle mode + * @bt_params: pointer to BT parameters + * @need_temp_offset_calib: need to perform temperature offset calibration + * @no_xtal_calib: some devices do not need crystal calibration data, + * don't send it to those + * @temp_offset_v2: support v2 of temperature offset calibration + * @adv_pm: advanced power management + */ +struct iwl_dvm_cfg { void (*set_hw_params)(struct iwl_priv *priv); int (*set_channel_switch)(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch); - /* device specific configuration */ void (*nic_config)(struct iwl_priv *priv); - - /* temperature */ void (*temperature)(struct iwl_priv *priv); + + const struct iwl_dvm_bt_params *bt_params; + s32 chain_noise_scale; + u8 plcp_delta_threshold; + bool adv_thermal_throttle; + bool support_ct_kill_exit; + bool hd_v2; + bool no_idle_support; + bool need_temp_offset_calib; + bool no_xtal_calib; + bool temp_offset_v2; + bool adv_pm; }; struct iwl_wipan_noa_data { @@ -610,7 +653,7 @@ struct iwl_priv { struct device *dev; /* for debug prints only */ const struct iwl_cfg *cfg; const struct iwl_fw *fw; - const struct iwl_lib_ops *lib; + const struct iwl_dvm_cfg *lib; unsigned long status; spinlock_t sta_lock; @@ -646,10 +689,6 @@ struct iwl_priv { struct iwl_spectrum_notification measure_report; u8 measurement_status; -#define IWL_OWNERSHIP_DRIVER 0 -#define IWL_OWNERSHIP_TM 1 - u8 ucode_owner; - /* ucode beacon time */ u32 ucode_beacon_time; int missed_beacon_threshold; @@ -844,7 +883,7 @@ struct iwl_priv { #endif /* CONFIG_IWLWIFI_DEBUGFS */ struct iwl_nvm_data *nvm_data; - /* eeprom blob for debugfs/testmode */ + /* eeprom blob for debugfs */ u8 *eeprom_blob; size_t eeprom_blob_size; @@ -860,16 +899,14 @@ struct iwl_priv { unsigned long blink_on, blink_off; bool led_registered; -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - struct iwl_test tst; - u32 tm_fixed_rate; -#endif - /* WoWLAN GTK rekey data */ u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; __le64 replay_ctr; __le16 last_seq_ctl; bool have_rekey_data; +#ifdef CONFIG_PM_SLEEP + struct wiphy_wowlan_support wowlan_support; +#endif /* device_pointers: pointers to ucode event tables */ struct { diff --git a/drivers/net/wireless/iwlwifi/dvm/devices.c b/drivers/net/wireless/iwlwifi/dvm/devices.c index c48907c8ab43..352c6cb7b4f1 100644 --- a/drivers/net/wireless/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/iwlwifi/dvm/devices.c @@ -174,10 +174,13 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.sens = &iwl1000_sensitivity; } -struct iwl_lib_ops iwl1000_lib = { +const struct iwl_dvm_cfg iwl_dvm_1000_cfg = { .set_hw_params = iwl1000_hw_set_hw_params, .nic_config = iwl1000_nic_config, .temperature = iwlagn_temperature, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, }; @@ -232,16 +235,56 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.sens = &iwl2000_sensitivity; } -struct iwl_lib_ops iwl2000_lib = { +const struct iwl_dvm_cfg iwl_dvm_2000_cfg = { .set_hw_params = iwl2000_hw_set_hw_params, .nic_config = iwl2000_nic_config, .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .hd_v2 = true, + .need_temp_offset_calib = true, + .temp_offset_v2 = true, }; -struct iwl_lib_ops iwl2030_lib = { +const struct iwl_dvm_cfg iwl_dvm_105_cfg = { .set_hw_params = iwl2000_hw_set_hw_params, .nic_config = iwl2000_nic_config, .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .hd_v2 = true, + .need_temp_offset_calib = true, + .temp_offset_v2 = true, + .adv_pm = true, +}; + +static const struct iwl_dvm_bt_params iwl2030_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, + .bt_sco_disable = true, + .bt_session_2 = true, +}; + +const struct iwl_dvm_cfg iwl_dvm_2030_cfg = { + .set_hw_params = iwl2000_hw_set_hw_params, + .nic_config = iwl2000_nic_config, + .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .hd_v2 = true, + .bt_params = &iwl2030_bt_params, + .need_temp_offset_calib = true, + .temp_offset_v2 = true, + .adv_pm = true, }; /* @@ -420,16 +463,23 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, return iwl_dvm_send_cmd(priv, &hcmd); } -struct iwl_lib_ops iwl5000_lib = { +const struct iwl_dvm_cfg iwl_dvm_5000_cfg = { .set_hw_params = iwl5000_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, .temperature = iwlagn_temperature, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .no_idle_support = true, }; -struct iwl_lib_ops iwl5150_lib = { +const struct iwl_dvm_cfg iwl_dvm_5150_cfg = { .set_hw_params = iwl5150_hw_set_hw_params, .set_channel_switch = iwl5000_hw_channel_switch, .temperature = iwl5150_temperature, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .no_idle_support = true, + .no_xtal_calib = true, }; @@ -584,16 +634,59 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, return err; } -struct iwl_lib_ops iwl6000_lib = { +const struct iwl_dvm_cfg iwl_dvm_6000_cfg = { .set_hw_params = iwl6000_hw_set_hw_params, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, +}; + +const struct iwl_dvm_cfg iwl_dvm_6005_cfg = { + .set_hw_params = iwl6000_hw_set_hw_params, + .set_channel_switch = iwl6000_hw_channel_switch, + .nic_config = iwl6000_nic_config, + .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .need_temp_offset_calib = true, +}; + +const struct iwl_dvm_cfg iwl_dvm_6050_cfg = { + .set_hw_params = iwl6000_hw_set_hw_params, + .set_channel_switch = iwl6000_hw_channel_switch, + .nic_config = iwl6000_nic_config, + .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1500, +}; + +static const struct iwl_dvm_bt_params iwl6000_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, + .bt_sco_disable = true, }; -struct iwl_lib_ops iwl6030_lib = { +const struct iwl_dvm_cfg iwl_dvm_6030_cfg = { .set_hw_params = iwl6000_hw_set_hw_params, .set_channel_switch = iwl6000_hw_channel_switch, .nic_config = iwl6000_nic_config, .temperature = iwlagn_temperature, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .bt_params = &iwl6000_bt_params, + .need_temp_offset_calib = true, + .adv_pm = true, }; diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 54f553380aa8..3d5bdc4217a8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -254,23 +254,23 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != sizeof(basic.bt3_lookup_table)); - if (priv->cfg->bt_params) { + if (priv->lib->bt_params) { /* * newer generation of devices (2000 series and newer) * use the version 2 of the bt command * we need to make sure sending the host command * with correct data structure to avoid uCode assert */ - if (priv->cfg->bt_params->bt_session_2) { + if (priv->lib->bt_params->bt_session_2) { bt_cmd_v2.prio_boost = cpu_to_le32( - priv->cfg->bt_params->bt_prio_boost); + priv->lib->bt_params->bt_prio_boost); bt_cmd_v2.tx_prio_boost = 0; bt_cmd_v2.rx_prio_boost = 0; } else { /* older version only has 8 bits */ - WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF); + WARN_ON(priv->lib->bt_params->bt_prio_boost & ~0xFF); bt_cmd_v1.prio_boost = - priv->cfg->bt_params->bt_prio_boost; + priv->lib->bt_params->bt_prio_boost; bt_cmd_v1.tx_prio_boost = 0; bt_cmd_v1.rx_prio_boost = 0; } @@ -330,7 +330,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) priv->bt_full_concurrent ? "full concurrency" : "3-wire"); - if (priv->cfg->bt_params->bt_session_2) { + if (priv->lib->bt_params->bt_session_2) { memcpy(&bt_cmd_v2.basic, &basic, sizeof(basic)); ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, @@ -758,8 +758,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv) */ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist && (priv->bt_full_concurrent || priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { /* @@ -830,8 +830,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) else active_chains = priv->nvm_data->valid_rx_ant; - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist && (priv->bt_full_concurrent || priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { /* @@ -1288,12 +1288,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (!(cmd->flags & CMD_ASYNC)) lockdep_assert_held(&priv->mutex); - if (priv->ucode_owner == IWL_OWNERSHIP_TM && - !(cmd->flags & CMD_ON_DEMAND)) { - IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n"); - return -EIO; - } - return iwl_trans_send_cmd(priv->trans, cmd); } diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index cab23af0be9e..822f1a00efbb 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -208,20 +208,21 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, priv->trans->ops->d3_suspend && priv->trans->ops->d3_resume && device_can_wakeup(priv->trans->dev)) { - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | - WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_RFKILL_RELEASE; + priv->wowlan_support.flags = WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_EAP_IDENTITY_REQ | + WIPHY_WOWLAN_RFKILL_RELEASE; if (!iwlwifi_mod_params.sw_crypto) - hw->wiphy->wowlan.flags |= + priv->wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_GTK_REKEY_FAILURE; - hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; - hw->wiphy->wowlan.pattern_min_len = + priv->wowlan_support.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; + priv->wowlan_support.pattern_min_len = IWLAGN_WOWLAN_MIN_PATTERN_LEN; - hw->wiphy->wowlan.pattern_max_len = + priv->wowlan_support.pattern_max_len = IWLAGN_WOWLAN_MAX_PATTERN_LEN; + hw->wiphy->wowlan = &priv->wowlan_support; } #endif @@ -426,7 +427,11 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, if (ret) goto error; - iwl_trans_d3_suspend(priv->trans); + /* let the ucode operate on its own */ + iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + + iwl_trans_d3_suspend(priv->trans, false); goto out; @@ -500,7 +505,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) /* we'll clear ctx->vif during iwlagn_prepare_restart() */ vif = ctx->vif; - ret = iwl_trans_d3_resume(priv->trans, &d3_status); + ret = iwl_trans_d3_resume(priv->trans, &d3_status, false); if (ret) goto out_unlock; @@ -509,6 +514,10 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) goto out_unlock; } + /* uCode is no longer operating by itself */ + iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); + base = priv->device_pointers.error_event_table; if (!iwlagn_hw_valid_rtc_data_addr(base)) { IWL_WARN(priv, "Invalid error table during resume!\n"); @@ -1276,8 +1285,8 @@ static void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->mutex); - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { if (rssi_event == RSSI_EVENT_LOW) priv->bt_enable_pspoll = true; else if (rssi_event == RSSI_EVENT_HIGH) @@ -1387,7 +1396,7 @@ static int iwl_setup_interface(struct iwl_priv *priv, return err; } - if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist && + if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist && vif->type == NL80211_IFTYPE_ADHOC) { /* * pretend to have high BT traffic as long as we @@ -1757,8 +1766,6 @@ struct ieee80211_ops iwlagn_hw_ops = { .remain_on_channel = iwlagn_mac_remain_on_channel, .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, .rssi_callback = iwlagn_mac_rssi_callback, - CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd) - CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump) .set_tim = iwlagn_mac_set_tim, }; diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 74d7572e7091..1531a4fc0960 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -615,7 +615,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) priv->thermal_throttle.ct_kill_toggle = false; - if (priv->cfg->base_params->support_ct_kill_exit) { + if (priv->lib->support_ct_kill_exit) { adv_cmd.critical_temperature_enter = cpu_to_le32(priv->hw_params.ct_kill_threshold); adv_cmd.critical_temperature_exit = @@ -732,10 +732,10 @@ int iwl_alive_start(struct iwl_priv *priv) } /* download priority table before any calibration request */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { /* Configure Bluetooth device coexistence support */ - if (priv->cfg->bt_params->bt_sco_disable) + if (priv->lib->bt_params->bt_sco_disable) priv->bt_enable_pspoll = false; else priv->bt_enable_pspoll = true; @@ -758,7 +758,7 @@ int iwl_alive_start(struct iwl_priv *priv) BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); if (ret) return ret; - } else { + } else if (priv->lib->bt_params) { /* * default is 2-wire BT coexexistence support */ @@ -873,9 +873,9 @@ void iwl_down(struct iwl_priv *priv) priv->bt_status = 0; priv->cur_rssi_ctx = NULL; priv->bt_is_sco = 0; - if (priv->cfg->bt_params) + if (priv->lib->bt_params) priv->bt_traffic_load = - priv->cfg->bt_params->bt_init_traffic_load; + priv->lib->bt_params->bt_init_traffic_load; else priv->bt_traffic_load = 0; priv->bt_full_concurrent = false; @@ -1058,7 +1058,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) iwl_setup_scan_deferred_work(priv); - if (priv->cfg->bt_params) + if (priv->lib->bt_params) iwlagn_bt_setup_deferred_work(priv); init_timer(&priv->statistics_periodic); @@ -1072,7 +1072,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) void iwl_cancel_deferred_work(struct iwl_priv *priv) { - if (priv->cfg->bt_params) + if (priv->lib->bt_params) iwlagn_bt_cancel_deferred_work(priv); cancel_work_sync(&priv->run_time_calib_work); @@ -1098,16 +1098,13 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->band = IEEE80211_BAND_2GHZ; - priv->plcp_delta_threshold = - priv->cfg->base_params->plcp_delta_threshold; + priv->plcp_delta_threshold = priv->lib->plcp_delta_threshold; priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; priv->agg_tids_count = 0; - priv->ucode_owner = IWL_OWNERSHIP_DRIVER; - priv->rx_statistics_jiffies = jiffies; /* Choose which receivers/antennas to use */ @@ -1116,8 +1113,8 @@ static int iwl_init_drv(struct iwl_priv *priv) iwl_init_scan_params(priv); /* init bt coex */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; @@ -1173,12 +1170,6 @@ static void iwl_option_config(struct iwl_priv *priv) IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); #endif -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n"); -#else - IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n"); -#endif - #ifdef CONFIG_IWLWIFI_P2P IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n"); #else @@ -1264,31 +1255,37 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, switch (priv->cfg->device_family) { case IWL_DEVICE_FAMILY_1000: case IWL_DEVICE_FAMILY_100: - priv->lib = &iwl1000_lib; + priv->lib = &iwl_dvm_1000_cfg; break; case IWL_DEVICE_FAMILY_2000: + priv->lib = &iwl_dvm_2000_cfg; + break; case IWL_DEVICE_FAMILY_105: - priv->lib = &iwl2000_lib; + priv->lib = &iwl_dvm_105_cfg; break; case IWL_DEVICE_FAMILY_2030: case IWL_DEVICE_FAMILY_135: - priv->lib = &iwl2030_lib; + priv->lib = &iwl_dvm_2030_cfg; break; case IWL_DEVICE_FAMILY_5000: - priv->lib = &iwl5000_lib; + priv->lib = &iwl_dvm_5000_cfg; break; case IWL_DEVICE_FAMILY_5150: - priv->lib = &iwl5150_lib; + priv->lib = &iwl_dvm_5150_cfg; break; case IWL_DEVICE_FAMILY_6000: - case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6000i: + priv->lib = &iwl_dvm_6000_cfg; + break; + case IWL_DEVICE_FAMILY_6005: + priv->lib = &iwl_dvm_6005_cfg; + break; case IWL_DEVICE_FAMILY_6050: case IWL_DEVICE_FAMILY_6150: - priv->lib = &iwl6000_lib; + priv->lib = &iwl_dvm_6050_cfg; break; case IWL_DEVICE_FAMILY_6030: - priv->lib = &iwl6030_lib; + priv->lib = &iwl_dvm_6030_cfg; break; default: break; @@ -1350,8 +1347,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? true : false; - /* enable/disable bt channel inhibition */ - priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce; + /* bt channel inhibition enabled*/ + priv->bt_ch_announce = true; IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", (priv->bt_ch_announce) ? "On" : "Off"); @@ -1446,7 +1443,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ********************/ iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); - iwl_testmode_init(priv); iwl_power_initialize(priv); iwl_tt_initialize(priv); @@ -1483,7 +1479,6 @@ out_mac80211_unregister: iwlagn_mac_unregister(priv); out_destroy_workqueue: iwl_tt_exit(priv); - iwl_testmode_free(priv); iwl_cancel_deferred_work(priv); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; @@ -1505,7 +1500,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); - iwl_testmode_free(priv); iwlagn_mac_unregister(priv); iwl_tt_exit(priv); @@ -1854,14 +1848,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } -#ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; -#else - size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) - ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; -#endif IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", size); @@ -1905,10 +1894,8 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) unsigned int reload_msec; unsigned long reload_jiffies; -#ifdef CONFIG_IWLWIFI_DEBUG if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); -#endif /* uCode is no longer loaded. */ priv->ucode_loaded = false; diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c index bd69018d07a9..77cb59712235 100644 --- a/drivers/net/wireless/iwlwifi/dvm/power.c +++ b/drivers/net/wireless/iwlwifi/dvm/power.c @@ -163,7 +163,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, u8 skip; u32 slp_itrvl; - if (priv->cfg->adv_pm) { + if (priv->lib->adv_pm) { table = apm_range_2; if (period <= IWL_DTIM_RANGE_1_MAX) table = apm_range_1; @@ -217,7 +217,7 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, cmd->flags &= ~IWL_POWER_SHADOW_REG_ENA; if (iwl_advanced_bt_coexist(priv)) { - if (!priv->cfg->bt_params->bt_sco_disable) + if (!priv->lib->bt_params->bt_sco_disable) cmd->flags |= IWL_POWER_BT_SCO_ENA; else cmd->flags &= ~IWL_POWER_BT_SCO_ENA; @@ -293,7 +293,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, if (priv->wowlan) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); - else if (!priv->cfg->base_params->no_idle_support && + else if (!priv->lib->no_idle_support && priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (iwl_tt_is_low_power_state(priv)) { diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 10fbb176cc8e..1b693944123b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c @@ -351,12 +351,6 @@ static void rs_program_fix_rate(struct iwl_priv *priv, lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - /* testmode has higher priority to overwirte the fixed rate */ - if (priv->tm_fixed_rate) - lq_sta->dbg_fixed_rate = priv->tm_fixed_rate; -#endif - IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); @@ -419,23 +413,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, load = rs_tl_get_load(lq_data, tid); - if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { - IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", - sta->addr, tid); - ret = ieee80211_start_tx_ba_session(sta, tid, 5000); - if (ret == -EAGAIN) { - /* - * driver and mac80211 is out of sync - * this might be cause by reloading firmware - * stop the tx ba session here - */ - IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", - tid); - ieee80211_stop_tx_ba_session(sta, tid); - } - } else { - IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d " - "because load = %u\n", tid, load); + IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", + sta->addr, tid); + ret = ieee80211_start_tx_ba_session(sta, tid, 5000); + if (ret == -EAGAIN) { + /* + * driver and mac80211 is out of sync + * this might be cause by reloading firmware + * stop the tx ba session here + */ + IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", + tid); + ieee80211_stop_tx_ba_session(sta, tid); } return ret; } @@ -1083,12 +1072,7 @@ done: if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE) - if ((priv->tm_fixed_rate) && - (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) - rs_program_fix_rate(priv, lq_sta); -#endif - if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) + if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) rs_bt_update_lq(priv, ctx, lq_sta); } @@ -2913,9 +2897,6 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i if (sband->band == IEEE80211_BAND_5GHZ) lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_agg = 0; -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - priv->tm_fixed_rate = 0; -#endif #ifdef CONFIG_MAC80211_DEBUGFS lq_sta->dbg_fixed_rate = 0; #endif @@ -3064,11 +3045,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, * overwrite if needed, pass aggregation time limit * to uCode in uSec */ - if (priv && priv->cfg->bt_params && - priv->cfg->bt_params->agg_time_limit && + if (priv && priv->lib->bt_params && + priv->lib->bt_params->agg_time_limit && priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) lq_cmd->agg_params.agg_time_limit = - cpu_to_le16(priv->cfg->bt_params->agg_time_limit); + cpu_to_le16(priv->lib->bt_params->agg_time_limit); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index a4eed2055fdb..d71776dd1e6a 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -335,8 +335,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, if (msecs < 99) return; - if (iwlwifi_mod_params.plcp_check && - !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) + if (!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) iwl_force_rf_reset(priv, false); } @@ -1102,7 +1101,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) iwl_notification_wait_init(&priv->notif_wait); /* Set up BT Rx handlers */ - if (priv->cfg->bt_params) + if (priv->lib->bt_params) iwlagn_bt_rx_handler_setup(priv); } @@ -1120,32 +1119,17 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, */ iwl_notification_wait_notify(&priv->notif_wait, pkt); -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - /* - * RX data may be forwarded to userspace in one - * of two cases: the user owns the fw through testmode or when - * the user requested to monitor the rx w/o affecting the regular flow. - * In these cases the iwl_test object will handle forwarding the rx - * data to user space. - * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow - * continues. - */ - iwl_test_rx(&priv->tst, rxb); -#endif - - if (priv->ucode_owner != IWL_OWNERSHIP_TM) { - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - priv->rx_handlers_stats[pkt->hdr.cmd]++; - err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", - iwl_dvm_get_cmd_string(pkt->hdr.cmd), - pkt->hdr.cmd); - } + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + priv->rx_handlers_stats[pkt->hdr.cmd]++; + err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n", + iwl_dvm_get_cmd_string(pkt->hdr.cmd), + pkt->hdr.cmd); } return err; } diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index d69b55866714..8c686a5b90ac 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -801,8 +801,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) * Internal scans are passive, so we can indiscriminately set * the BT ignore flag on 2.4 GHz since it applies to TX only. */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; break; case IEEE80211_BAND_5GHZ: @@ -844,8 +844,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) band = priv->scan_band; if (band == IEEE80211_BAND_2GHZ && - priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { /* transmit 2.4 GHz probes only on first antenna */ scan_tx_antennas = first_antenna(scan_tx_antennas); } @@ -873,8 +873,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_ant = first_antenna(active_chains); } - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist && priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ rx_ant = first_antenna(rx_ant); diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c deleted file mode 100644 index b89b9d9b9969..000000000000 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ /dev/null @@ -1,471 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless <ilw@linux.intel.com> - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/dma-mapping.h> -#include <net/net_namespace.h> -#include <linux/netdevice.h> -#include <net/cfg80211.h> -#include <net/mac80211.h> -#include <net/netlink.h> - -#include "iwl-debug.h" -#include "iwl-trans.h" -#include "dev.h" -#include "agn.h" -#include "iwl-test.h" -#include "iwl-testmode.h" - -static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode, - struct iwl_host_cmd *cmd) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - return iwl_dvm_send_cmd(priv, cmd); -} - -static bool iwl_testmode_valid_hw_addr(u32 addr) -{ - if (iwlagn_hw_valid_rtc_data_addr(addr)) - return true; - - if (IWLAGN_RTC_INST_LOWER_BOUND <= addr && - addr < IWLAGN_RTC_INST_UPPER_BOUND) - return true; - - return false; -} - -static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - return priv->fw->ucode_ver; -} - -static struct sk_buff* -iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len); -} - -static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb) -{ - return cfg80211_testmode_reply(skb); -} - -static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode, - int len) -{ - struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode); - return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len, - GFP_ATOMIC); -} - -static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb) -{ - return cfg80211_testmode_event(skb, GFP_ATOMIC); -} - -static struct iwl_test_ops tst_ops = { - .send_cmd = iwl_testmode_send_cmd, - .valid_hw_addr = iwl_testmode_valid_hw_addr, - .get_fw_ver = iwl_testmode_get_fw_ver, - .alloc_reply = iwl_testmode_alloc_reply, - .reply = iwl_testmode_reply, - .alloc_event = iwl_testmode_alloc_event, - .event = iwl_testmode_event, -}; - -void iwl_testmode_init(struct iwl_priv *priv) -{ - iwl_test_init(&priv->tst, priv->trans, &tst_ops); -} - -void iwl_testmode_free(struct iwl_priv *priv) -{ - iwl_test_free(&priv->tst); -} - -static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv) -{ - struct iwl_notification_wait calib_wait; - static const u8 calib_complete[] = { - CALIBRATION_COMPLETE_NOTIFICATION - }; - int ret; - - iwl_init_notification_wait(&priv->notif_wait, &calib_wait, - calib_complete, ARRAY_SIZE(calib_complete), - NULL, NULL); - ret = iwl_init_alive_start(priv); - if (ret) { - IWL_ERR(priv, "Fail init calibration: %d\n", ret); - goto cfg_init_calib_error; - } - - ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ); - if (ret) - IWL_ERR(priv, "Error detecting" - " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret); - return ret; - -cfg_init_calib_error: - iwl_remove_notification(&priv->notif_wait, &calib_wait); - return ret; -} - -/* - * This function handles the user application commands for driver. - * - * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the - * handlers respectively. - * - * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned - * value of the actual command execution is replied to the user application. - * - * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP - * is used for carry the message while IWL_TM_ATTR_COMMAND must set to - * IWL_TM_CMD_DEV2APP_SYNC_RSP. - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - struct iwl_trans *trans = priv->trans; - struct sk_buff *skb; - unsigned char *rsp_data_ptr = NULL; - int status = 0, rsp_data_len = 0; - u32 inst_size = 0, data_size = 0; - const struct fw_img *img; - - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { - case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: - rsp_data_ptr = (unsigned char *)priv->cfg->name; - rsp_data_len = strlen(priv->cfg->name); - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - rsp_data_len + 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, - IWL_TM_CMD_DEV2APP_SYNC_RSP) || - nla_put(skb, IWL_TM_ATTR_SYNC_RSP, - rsp_data_len, rsp_data_ptr)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", status); - break; - - case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: - status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT); - if (status) - IWL_ERR(priv, "Error loading init ucode: %d\n", status); - break; - - case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: - iwl_testmode_cfg_init_calib(priv); - priv->ucode_loaded = false; - iwl_trans_stop_device(trans); - break; - - case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: - status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR); - if (status) { - IWL_ERR(priv, - "Error loading runtime ucode: %d\n", status); - break; - } - status = iwl_alive_start(priv); - if (status) - IWL_ERR(priv, - "Error starting the device: %d\n", status); - break; - - case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: - iwl_scan_cancel_timeout(priv, 200); - priv->ucode_loaded = false; - iwl_trans_stop_device(trans); - status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN); - if (status) { - IWL_ERR(priv, - "Error loading WOWLAN ucode: %d\n", status); - break; - } - status = iwl_alive_start(priv); - if (status) - IWL_ERR(priv, - "Error starting the device: %d\n", status); - break; - - case IWL_TM_CMD_APP2DEV_GET_EEPROM: - if (priv->eeprom_blob) { - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, - priv->eeprom_blob_size + 20); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND, - IWL_TM_CMD_DEV2APP_EEPROM_RSP) || - nla_put(skb, IWL_TM_ATTR_EEPROM, - priv->eeprom_blob_size, - priv->eeprom_blob)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", - status); - } else - return -ENODATA; - break; - - case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: - if (!tb[IWL_TM_ATTR_FIXRATE]) { - IWL_ERR(priv, "Missing fixrate setting\n"); - return -ENOMSG; - } - priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]); - break; - - case IWL_TM_CMD_APP2DEV_GET_FW_INFO: - skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); - if (!skb) { - IWL_ERR(priv, "Memory allocation fail\n"); - return -ENOMEM; - } - if (!priv->ucode_loaded) { - IWL_ERR(priv, "No uCode has not been loaded\n"); - return -EINVAL; - } else { - img = &priv->fw->img[priv->cur_ucode]; - inst_size = img->sec[IWL_UCODE_SECTION_INST].len; - data_size = img->sec[IWL_UCODE_SECTION_DATA].len; - } - if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) || - nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) || - nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size)) - goto nla_put_failure; - status = cfg80211_testmode_reply(skb); - if (status < 0) - IWL_ERR(priv, "Error sending msg : %d\n", status); - break; - - default: - IWL_ERR(priv, "Unknown testmode driver command ID\n"); - return -ENOSYS; - } - return status; - -nla_put_failure: - kfree_skb(skb); - return -EMSGSIZE; -} - -/* - * This function handles the user application switch ucode ownership. - * - * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and - * decide who the current owner of the uCode - * - * If the current owner is OWNERSHIP_TM, then the only host command - * can deliver to uCode is from testmode, all the other host commands - * will dropped. - * - * default driver is the owner of uCode in normal operational mode - * - * @hw: ieee80211_hw object that represents the device - * @tb: gnl message fields from the user space - */ -static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - u8 owner; - - if (!tb[IWL_TM_ATTR_UCODE_OWNER]) { - IWL_ERR(priv, "Missing ucode owner\n"); - return -ENOMSG; - } - - owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]); - if (owner == IWL_OWNERSHIP_DRIVER) { - priv->ucode_owner = owner; - iwl_test_enable_notifications(&priv->tst, false); - } else if (owner == IWL_OWNERSHIP_TM) { - priv->ucode_owner = owner; - iwl_test_enable_notifications(&priv->tst, true); - } else { - IWL_ERR(priv, "Invalid owner\n"); - return -EINVAL; - } - return 0; -} - -/* The testmode gnl message handler that takes the gnl message from the - * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then - * invoke the corresponding handlers. - * - * This function is invoked when there is user space application sending - * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated - * by nl80211. - * - * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before - * dispatching it to the corresponding handler. - * - * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application; - * -ENOSYS is replied to the user application if the command is unknown; - * Otherwise, the command is dispatched to the respective handler. - * - * @hw: ieee80211_hw object that represents the device - * @data: pointer to user space message - * @len: length in byte of @data - */ -int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) -{ - struct nlattr *tb[IWL_TM_ATTR_MAX]; - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - int result; - - result = iwl_test_parse(&priv->tst, tb, data, len); - if (result) - return result; - - /* in case multiple accesses to the device happens */ - mutex_lock(&priv->mutex); - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { - case IWL_TM_CMD_APP2DEV_UCODE: - case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32: - case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: - case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: - case IWL_TM_CMD_APP2DEV_END_TRACE: - case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ: - case IWL_TM_CMD_APP2DEV_NOTIFICATIONS: - case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: - case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: - case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE: - result = iwl_test_handle_cmd(&priv->tst, tb); - break; - - case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: - case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: - case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: - case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: - case IWL_TM_CMD_APP2DEV_GET_EEPROM: - case IWL_TM_CMD_APP2DEV_FIXRATE_REQ: - case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: - case IWL_TM_CMD_APP2DEV_GET_FW_INFO: - IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); - result = iwl_testmode_driver(hw, tb); - break; - - case IWL_TM_CMD_APP2DEV_OWNERSHIP: - IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n"); - result = iwl_testmode_ownership(hw, tb); - break; - - default: - IWL_ERR(priv, "Unknown testmode command\n"); - result = -ENOSYS; - break; - } - mutex_unlock(&priv->mutex); - - if (result) - IWL_ERR(priv, "Test cmd failed result=%d\n", result); - return result; -} - -int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, - struct netlink_callback *cb, - void *data, int len) -{ - struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); - int result; - u32 cmd; - - if (cb->args[3]) { - /* offset by 1 since commands start at 0 */ - cmd = cb->args[3] - 1; - } else { - struct nlattr *tb[IWL_TM_ATTR_MAX]; - - result = iwl_test_parse(&priv->tst, tb, data, len); - if (result) - return result; - - cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); - cb->args[3] = cmd + 1; - } - - /* in case multiple accesses to the device happens */ - mutex_lock(&priv->mutex); - result = iwl_test_dump(&priv->tst, cmd, skb, cb); - mutex_unlock(&priv->mutex); - return result; -} diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c index 03f9bc01c0cc..fbeee081ee2f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/iwlwifi/dvm/tt.c @@ -627,7 +627,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); - if (priv->cfg->base_params->adv_thermal_throttle) { + if (priv->lib->adv_thermal_throttle) { IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); tt->restriction = kcalloc(IWL_TI_STATE_MAX, sizeof(struct iwl_tt_restriction), diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index a900aaf47790..5ee983faa679 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -83,8 +83,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, else if (ieee80211_is_back_req(fc)) tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; else if (info->band == IEEE80211_BAND_2GHZ && - priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist && (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc) || skb->protocol == cpu_to_be16(ETH_P_PAE))) @@ -162,18 +162,6 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, if (ieee80211_is_data(fc)) { tx_cmd->initial_rate_index = 0; tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; -#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE - if (priv->tm_fixed_rate) { - /* - * rate overwrite by testmode - * we not only send lq command to change rate - * we also re-enforce per data pkt base. - */ - tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK; - memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate, - sizeof(tx_cmd->rate_n_flags)); - } -#endif return; } else if (ieee80211_is_back_req(fc)) tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; @@ -202,8 +190,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist && + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist && priv->bt_full_concurrent) { /* operated as 1x1 in full concurrency mode */ priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, @@ -986,8 +974,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, * notification again. */ if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && - priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); } diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 0a1cdc5e856b..86270b69cd02 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -132,8 +132,8 @@ int iwl_init_alive_start(struct iwl_priv *priv) { int ret; - if (priv->cfg->bt_params && - priv->cfg->bt_params->advanced_bt_coexist) { + if (priv->lib->bt_params && + priv->lib->bt_params->advanced_bt_coexist) { /* * Tell uCode we are ready to perform calibration * need to perform this before any calibration @@ -155,8 +155,8 @@ int iwl_init_alive_start(struct iwl_priv *priv) * temperature offset calibration is only needed for runtime ucode, * so prepare the value now. */ - if (priv->cfg->need_temp_offset_calib) { - if (priv->cfg->temp_offset_v2) + if (priv->lib->need_temp_offset_calib) { + if (priv->lib->temp_offset_v2) return iwl_set_temperature_offset_calib_v2(priv); else return iwl_set_temperature_offset_calib(priv); @@ -277,7 +277,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) if (ret) return ret; - if (!priv->cfg->no_xtal_calib) { + if (!priv->lib->no_xtal_calib) { ret = iwl_set_Xtal_calib(priv); if (ret) return ret; |