Пример #1
0
static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
{
	int i;
	struct iwl_rss_config_cmd cmd = {
		.flags = cpu_to_le32(IWL_RSS_ENABLE),
		.hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
			     IWL_RSS_HASH_TYPE_IPV4_UDP |
			     IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
			     IWL_RSS_HASH_TYPE_IPV6_TCP |
			     IWL_RSS_HASH_TYPE_IPV6_UDP |
			     IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
	};

	if (mvm->trans->num_rx_queues == 1)
		return 0;

	/* Do not direct RSS traffic to Q 0 which is our fallback queue */
	for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
		cmd.indirection_table[i] =
			1 + (i % (mvm->trans->num_rx_queues - 1));
	netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key));

	return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
}

static int iwl_configure_rxq(struct iwl_mvm *mvm)
{
	int i, num_queues, size;
	struct iwl_rfh_queue_config *cmd;

	/* Do not configure default queue, it is configured via context info */
	num_queues = mvm->trans->num_rx_queues - 1;

	size = sizeof(*cmd) + num_queues * sizeof(struct iwl_rfh_queue_data);

	cmd = kzalloc(size, GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	cmd->num_queues = num_queues;

	for (i = 0; i < num_queues; i++) {
		struct iwl_trans_rxq_dma_data data;

		cmd->data[i].q_num = i + 1;
		iwl_trans_get_rxq_dma_data(mvm->trans, i + 1, &data);

		cmd->data[i].fr_bd_cb = cpu_to_le64(data.fr_bd_cb);
		cmd->data[i].urbd_stts_wrptr =
			cpu_to_le64(data.urbd_stts_wrptr);
		cmd->data[i].ur_bd_cb = cpu_to_le64(data.ur_bd_cb);
		cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);
	}

	return iwl_mvm_send_cmd_pdu(mvm,
				    WIDE_ID(DATA_PATH_GROUP,
					    RFH_QUEUE_CONFIG_CMD),
				    0, size, cmd);
}
Пример #2
0
Файл: sta.c Проект: IDM350/linux
static int iwl_mvm_send_add_sta_cmd(struct iwl_mvm *mvm, u32 flags,
				    struct iwl_mvm_add_sta_cmd_v6 *cmd)
{
	struct iwl_mvm_add_sta_cmd_v5 cmd_v5;

	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
		return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags,
					    sizeof(*cmd), cmd);

	iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5);

	return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(cmd_v5),
				    &cmd_v5);
}
static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
					 struct ieee80211_vif *vif)
{
	int ret;
	bool ba_enable;
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION)
		return 0;

	if (vif->p2p &&
	    !(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PS))
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	iwl_mvm_power_log(mvm, &cmd);

	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC,
				   sizeof(cmd), &cmd);
	if (ret)
		return ret;

	ba_enable = !!(cmd.flags &
		       cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));

	return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
}
Пример #4
0
int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
			    const u8 *data, u32 count)
{
	struct iwl_rxq_sync_cmd *cmd;
	u32 data_size = sizeof(*cmd) + count;
	int ret;

	/* should be DWORD aligned */
	if (WARN_ON(count & 3 || count > IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE))
		return -EINVAL;

	cmd = kzalloc(data_size, GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	cmd->rxq_mask = cpu_to_le32(rxq_mask);
	cmd->count =  cpu_to_le32(count);
	cmd->flags = 0;
	memcpy(cmd->payload, data, count);

	ret = iwl_mvm_send_cmd_pdu(mvm,
				   WIDE_ID(DATA_PATH_GROUP,
					   TRIGGER_RX_QUEUES_NOTIF_CMD),
				   0, data_size, cmd);

	kfree(cmd);
	return ret;
}
static int _iwl_mvm_power_update_device(struct iwl_mvm *mvm, bool force_disable)
{
	struct iwl_device_power_cmd cmd = {
		.flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
	};

	if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD))
		return 0;

	if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM ||
	    force_disable)
		cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);

#ifdef CPTCFG_IWLWIFI_DEBUGFS
	if ((mvm->cur_ucode == IWL_UCODE_WOWLAN) ? mvm->disable_power_off_d3 :
	    mvm->disable_power_off)
		cmd.flags &=
			cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
#endif
	IWL_DEBUG_POWER(mvm,
			"Sending device power command with flags = 0x%X\n",
			cmd.flags);

	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, sizeof(cmd),
				    &cmd);
}
Пример #6
0
static int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
					  struct iwl_beacon_filter_cmd *cmd)
{
	int ret;

	ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, CMD_SYNC,
				   sizeof(struct iwl_beacon_filter_cmd), cmd);

	if (!ret) {
		IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
				cmd->ba_enable_beacon_abort);
		IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
				cmd->ba_escape_timer);
		IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
				cmd->bf_debug_flag);
		IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
				cmd->bf_enable_beacon_filter);
		IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
				cmd->bf_energy_delta);
		IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
				cmd->bf_escape_timer);
		IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
				cmd->bf_roaming_energy_delta);
		IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
				cmd->bf_roaming_state);
		IWL_DEBUG_POWER(mvm, "bf_temperature_delta is: %d\n",
				cmd->bf_temperature_delta);
	}
	return ret;
}
Пример #7
0
Файл: coex.c Проект: Lyude/linux
static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
				       bool enable)
{
	struct iwl_bt_coex_reduced_txp_update_cmd cmd = {};
	struct iwl_mvm_sta *mvmsta;
	u32 value;
	int ret;

	mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
	if (!mvmsta)
		return 0;

	/* nothing to do */
	if (mvmsta->bt_reduced_txpower == enable)
		return 0;

	value = mvmsta->sta_id;

	if (enable)
		value |= BT_REDUCED_TX_POWER_BIT;

	IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
		       enable ? "en" : "dis", sta_id);

	cmd.reduced_txp = cpu_to_le32(value);
	mvmsta->bt_reduced_txpower = enable;

	ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_REDUCED_TXP, CMD_ASYNC,
				   sizeof(cmd), &cmd);

	return ret;
}
Пример #8
0
Файл: power.c Проект: mbgg/linux
int iwl_mvm_power_disable(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
	struct iwl_powertable_cmd cmd = {};
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);

	if (!iwlwifi_mod_params.power_save) {
		IWL_DEBUG_POWER(mvm, "Power management is not allowed\n");
		return 0;
	}

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
							    mvmvif->color));
	cmd.action = cpu_to_le32(FW_CTXT_ACTION_MODIFY);

	IWL_DEBUG_POWER(mvm,
			"Sending power table command on mac id 0x%X for power level %d, flags = 0x%X\n",
			cmd.id_and_color, iwlmvm_mod_params.power_scheme,
			le16_to_cpu(cmd.flags));

	return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_ASYNC,
				    sizeof(cmd), &cmd);
}
Пример #9
0
static
int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
                                   struct iwl_beacon_filter_cmd *cmd,
                                   u32 flags)
{
    IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
                    le32_to_cpu(cmd->ba_enable_beacon_abort));
    IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
                    le32_to_cpu(cmd->ba_escape_timer));
    IWL_DEBUG_POWER(mvm, "bf_debug_flag is: %d\n",
                    le32_to_cpu(cmd->bf_debug_flag));
    IWL_DEBUG_POWER(mvm, "bf_enable_beacon_filter is: %d\n",
                    le32_to_cpu(cmd->bf_enable_beacon_filter));
    IWL_DEBUG_POWER(mvm, "bf_energy_delta is: %d\n",
                    le32_to_cpu(cmd->bf_energy_delta));
    IWL_DEBUG_POWER(mvm, "bf_escape_timer is: %d\n",
                    le32_to_cpu(cmd->bf_escape_timer));
    IWL_DEBUG_POWER(mvm, "bf_roaming_energy_delta is: %d\n",
                    le32_to_cpu(cmd->bf_roaming_energy_delta));
    IWL_DEBUG_POWER(mvm, "bf_roaming_state is: %d\n",
                    le32_to_cpu(cmd->bf_roaming_state));
    IWL_DEBUG_POWER(mvm, "bf_temp_threshold is: %d\n",
                    le32_to_cpu(cmd->bf_temp_threshold));
    IWL_DEBUG_POWER(mvm, "bf_temp_fast_filter is: %d\n",
                    le32_to_cpu(cmd->bf_temp_fast_filter));
    IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n",
                    le32_to_cpu(cmd->bf_temp_slow_filter));

    return iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, flags,
                                sizeof(struct iwl_beacon_filter_cmd), cmd);
}
Пример #10
0
int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
{
    struct iwl_device_power_cmd cmd = {
        .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK),
    };

    if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM)
        mvm->ps_disabled = true;

    if (mvm->ps_disabled)
        cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK);

#ifdef CONFIG_IWLWIFI_DEBUGFS
    if ((mvm->cur_ucode == IWL_UCODE_WOWLAN) ? mvm->disable_power_off_d3 :
            mvm->disable_power_off)
        cmd.flags &=
            cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
#endif
    IWL_DEBUG_POWER(mvm,
                    "Sending device power command with flags = 0x%X\n",
                    cmd.flags);

    return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, 0, sizeof(cmd),
                                &cmd);
}
Пример #11
0
Файл: sta.c Проект: IDM350/linux
static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm,
					u32 flags,
					struct iwl_mvm_add_sta_key_cmd *cmd,
					u32 mac_id_n_color)
{
	struct iwl_mvm_add_sta_cmd_v5 sta_cmd;

	if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD)
		return iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, flags,
					    sizeof(*cmd), cmd);

	iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color);

	return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(sta_cmd),
				    &sta_cmd);
}
Пример #12
0
static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm,
				     enum iwl_fw_dbg_conf conf_id)
{
	u8 *ptr;
	int ret;
	int i;

	if (WARN_ONCE(conf_id >= ARRAY_SIZE(mvm->fw->dbg_conf_tlv),
		      "Invalid configuration %d\n", conf_id))
		return -EINVAL;

	if (!mvm->fw->dbg_conf_tlv[conf_id])
		return -EINVAL;

	if (mvm->fw_dbg_conf != FW_DBG_INVALID)
		IWL_WARN(mvm, "FW already configured (%d) - re-configuring\n",
			 mvm->fw_dbg_conf);

	/* Send all HCMDs for configuring the FW debug */
	ptr = (void *)&mvm->fw->dbg_conf_tlv[conf_id]->hcmd;
	for (i = 0; i < mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) {
		struct iwl_fw_dbg_conf_hcmd *cmd = (void *)ptr;

		ret = iwl_mvm_send_cmd_pdu(mvm, cmd->id, 0,
					   le16_to_cpu(cmd->len), cmd->data);
		if (ret)
			return ret;

		ptr += sizeof(*cmd);
		ptr += le16_to_cpu(cmd->len);
	}

	mvm->fw_dbg_conf = conf_id;
	return ret;
}
Пример #13
0
static int iwl_mvm_power_mac_update_mode(struct iwl_mvm *mvm,
					 struct ieee80211_vif *vif)
{
	int ret;
	bool ba_enable;
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	/*
	 * TODO: The following vif_count verification is temporary condition.
	 * Avoid power mode update if more than one interface is currently
	 * active. Remove this condition when FW will support power management
	 * on multiple MACs.
	 */
	IWL_DEBUG_POWER(mvm, "Currently %d interfaces active\n",
			mvm->vif_count);
	if (mvm->vif_count > 1)
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	iwl_mvm_power_log(mvm, &cmd);

	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_SYNC,
				   sizeof(cmd), &cmd);
	if (ret)
		return ret;

	ba_enable = !!(cmd.flags &
		       cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK));

	return iwl_mvm_update_beacon_abort(mvm, vif, ba_enable);
}
Пример #14
0
static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm,
				     struct ieee80211_vif *vif)
{
	struct iwl_mac_power_cmd cmd = {};
	struct iwl_mvm_vif *mvmvif __maybe_unused =
		iwl_mvm_vif_from_mac80211(vif);

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	cmd.id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
							   mvmvif->color));

	if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
		cmd.flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);

#ifdef CPTCFG_IWLWIFI_DEBUGFS
	if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_DISABLE_POWER_OFF &&
	    mvmvif->dbgfs_pm.disable_power_off)
		cmd.flags &= cpu_to_le16(~POWER_FLAGS_POWER_SAVE_ENA_MSK);
#endif
	iwl_mvm_power_log(mvm, &cmd);

	return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, CMD_ASYNC,
				    sizeof(cmd), &cmd);
}
Пример #15
0
Файл: sf.c Проект: 020gzh/linux
static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
			     enum iwl_sf_state new_state)
{
	struct iwl_sf_cfg_cmd sf_cmd = {
		.state = cpu_to_le32(SF_FULL_ON),
	};
	struct ieee80211_sta *sta;
	int ret = 0;

	if (IWL_UCODE_API(mvm->fw->ucode_ver) < 13)
		sf_cmd.state = cpu_to_le32(new_state);

	if (mvm->cfg->disable_dummy_notification)
		sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF);

	/*
	 * If an associated AP sta changed its antenna configuration, the state
	 * will remain FULL_ON but SF parameters need to be reconsidered.
	 */
	if (new_state != SF_FULL_ON && mvm->sf_state == new_state)
		return 0;

	switch (new_state) {
	case SF_UNINIT:
		if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 13)
			iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
		break;
	case SF_FULL_ON:
		if (sta_id == IWL_MVM_STATION_COUNT) {
			IWL_ERR(mvm,
				"No station: Cannot switch SF to FULL_ON\n");
			return -EINVAL;
		}
		rcu_read_lock();
		sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
		if (IS_ERR_OR_NULL(sta)) {
			IWL_ERR(mvm, "Invalid station id\n");
			rcu_read_unlock();
			return -EINVAL;
		}
		iwl_mvm_fill_sf_command(mvm, &sf_cmd, sta);
		rcu_read_unlock();
		break;
	case SF_INIT_OFF:
		iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
		break;
	default:
		WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n",
			  new_state);
		return -EINVAL;
	}

	ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_SF_CFG_CMD, CMD_ASYNC,
				   sizeof(sf_cmd), &sf_cmd);
	if (!ret)
		mvm->sf_state = new_state;

	return ret;
}
Пример #16
0
Файл: coex.c Проект: 7799/linux
int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
{
	if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX))
		return 0;

	return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC,
				    sizeof(struct iwl_bt_coex_prio_tbl_cmd),
				    &iwl_bt_prio_tbl);
}
Пример #17
0
Файл: tt.c Проект: 19Dan01/linux
static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
{
	struct iwl_dts_measurement_cmd cmd = {
		.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
	};

	return iwl_mvm_send_cmd_pdu(mvm, CMD_DTS_MEASUREMENT_TRIGGER, 0,
				    sizeof(cmd), &cmd);
}
Пример #18
0
static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
{
	if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
		return 0;

	return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, 0,
				    sizeof(struct iwl_bt_coex_prio_tbl_cmd),
				    &iwl_bt_prio_tbl);
}
Пример #19
0
static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
{
	struct iwl_tx_ant_cfg_cmd tx_ant_cmd = {
		.valid = cpu_to_le32(valid_tx_ant),
	};

	IWL_DEBUG_FW(mvm, "select valid tx ant: %u\n", valid_tx_ant);
	return iwl_mvm_send_cmd_pdu(mvm, TX_ANT_CONFIGURATION_CMD, 0,
				    sizeof(tx_ant_cmd), &tx_ant_cmd);
}
Пример #20
0
Файл: tt.c Проект: Lyude/linux
static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
{
	struct iwl_dts_measurement_cmd cmd = {
		.flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
	};
	struct iwl_ext_dts_measurement_cmd extcmd = {
		.control_mode = cpu_to_le32(DTS_AUTOMATIC),
	};
	u32 cmdid;

	cmdid = iwl_cmd_id(CMD_DTS_MEASUREMENT_TRIGGER_WIDE,
			   PHY_OPS_GROUP, 0);

	if (!fw_has_capa(&mvm->fw->ucode_capa,
			 IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE))
		return iwl_mvm_send_cmd_pdu(mvm, cmdid, 0, sizeof(cmd), &cmd);

	return iwl_mvm_send_cmd_pdu(mvm, cmdid, 0, sizeof(extcmd), &extcmd);
}
Пример #21
0
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
                                   struct ieee80211_vif *vif,
                                   bool enable, u32 flags)
{
    int ret;
    struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
    struct iwl_mac_power_cmd cmd = {};

    if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
        return 0;

    if (!vif->bss_conf.assoc)
        return 0;

    iwl_mvm_power_build_cmd(mvm, vif, &cmd);
    if (enable) {
        /* configure skip over dtim up to 306TU - 314 msec */
        int dtimper = vif->bss_conf.dtim_period ?: 1;
        int dtimper_tu = dtimper * vif->bss_conf.beacon_int;
        bool radar_detect = iwl_mvm_power_is_radar(vif);

        if (WARN_ON(!dtimper_tu))
            return 0;

        /* Check skip over DTIM conditions */
        /* TODO: check that multicast wake lock is off */
        if (!radar_detect && (dtimper < 10)) {
            cmd.skip_dtim_periods = 306 / dtimper_tu;
            if (cmd.skip_dtim_periods)
                cmd.flags |= cpu_to_le16(
                                 POWER_FLAGS_SKIP_OVER_DTIM_MSK);
        }
    }
    iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
    memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif
    ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
                               sizeof(cmd), &cmd);
    if (ret)
        return ret;

    /* configure beacon filtering */
    if (mvmvif != mvm->bf_allowed_vif)
        return 0;

    if (enable) {
        struct iwl_beacon_filter_cmd cmd_bf = {
            IWL_BF_CMD_CONFIG_D0I3,
            .bf_enable_beacon_filter = cpu_to_le32(1),
        };
        ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
                                            flags, true);
    } else {
        if (mvmvif->bf_data.bf_enabled)
Пример #22
0
static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
{
	struct iwl_ltr_config_cmd cmd = {
		.flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
	};

	if (!mvm->trans->ltr_enabled)
		return 0;

	return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
				    sizeof(cmd), &cmd);
}
Пример #23
0
static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type)
{
	struct iwl_bt_coex_prot_env_cmd env_cmd;
	int ret;

	env_cmd.action = action;
	env_cmd.type = type;
	ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC,
				   sizeof(env_cmd), &env_cmd);
	if (ret)
		IWL_ERR(mvm, "failed to send BT env command\n");
	return ret;
}
Пример #24
0
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
				   struct ieee80211_vif *vif,
				   bool enable, u32 flags)
{
	int ret;
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mac_power_cmd cmd = {};

	if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
		return 0;

	if (!vif->bss_conf.assoc)
		return 0;

	iwl_mvm_power_build_cmd(mvm, vif, &cmd);
	if (enable) {
		/* configure skip over dtim up to 300 msec */
		int dtimper = mvm->hw->conf.ps_dtim_period ?: 1;
		int dtimper_msec = dtimper * vif->bss_conf.beacon_int;

		if (WARN_ON(!dtimper_msec))
			return 0;

		cmd.skip_dtim_periods = 300 / dtimper_msec;
		if (cmd.skip_dtim_periods)
			cmd.flags |=
				cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK);
	}
	iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
	memcpy(&mvmvif->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif
	ret = iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, flags,
				   sizeof(cmd), &cmd);
	if (ret)
		return ret;

	/* configure beacon filtering */
	if (mvmvif != mvm->bf_allowed_vif)
		return 0;

	if (enable) {
		struct iwl_beacon_filter_cmd cmd_bf = {
			IWL_BF_CMD_CONFIG_D0I3,
			.bf_enable_beacon_filter = cpu_to_le32(1),
		};
		ret = _iwl_mvm_enable_beacon_filter(mvm, vif, &cmd_bf,
						    flags, true);
	} else {
		if (mvmvif->bf_data.bf_enabled)
Пример #25
0
static int iwl_mvm_power_send_cmd(struct iwl_mvm *mvm,
                                  struct ieee80211_vif *vif)
{
    struct iwl_mac_power_cmd cmd = {};

    iwl_mvm_power_build_cmd(mvm, vif, &cmd);
    iwl_mvm_power_log(mvm, &cmd);
#ifdef CONFIG_IWLWIFI_DEBUGFS
    memcpy(&iwl_mvm_vif_from_mac80211(vif)->mac_pwr_cmd, &cmd, sizeof(cmd));
#endif

    return iwl_mvm_send_cmd_pdu(mvm, MAC_PM_POWER_TABLE, 0,
                                sizeof(cmd), &cmd);
}
Пример #26
0
static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm)
{
	struct iwl_dqa_enable_cmd dqa_cmd = {
		.cmd_queue = cpu_to_le32(IWL_MVM_DQA_CMD_QUEUE),
	};
	u32 cmd_id = iwl_cmd_id(DQA_ENABLE_CMD, DATA_PATH_GROUP, 0);
	int ret;

	ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(dqa_cmd), &dqa_cmd);
	if (ret)
		IWL_ERR(mvm, "Failed to send DQA enabling command: %d\n", ret);
	else
		IWL_DEBUG_FW(mvm, "Working in DQA mode\n");

	return ret;
}
Пример #27
0
/* set device type and latency */
static int iwl_set_soc_latency(struct iwl_mvm *mvm)
{
	struct iwl_soc_configuration_cmd cmd;
	int ret;

	cmd.device_type = (mvm->trans->cfg->integrated) ?
		cpu_to_le32(SOC_CONFIG_CMD_INTEGRATED) :
		cpu_to_le32(SOC_CONFIG_CMD_DISCRETE);
	cmd.soc_latency = cpu_to_le32(mvm->trans->cfg->soc_latency);

	ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SOC_CONFIGURATION_CMD,
						   SYSTEM_GROUP, 0), 0,
				   sizeof(cmd), &cmd);
	if (ret)
		IWL_ERR(mvm, "Failed to set soc latency: %d\n", ret);
	return ret;
}
Пример #28
0
static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
{
	struct iwl_phy_cfg_cmd phy_cfg_cmd;
	enum iwl_ucode_type ucode_type = mvm->cur_ucode;

	/* Set parameters */
	phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
	phy_cfg_cmd.calib_control.event_trigger =
		mvm->fw->default_calib[ucode_type].event_trigger;
	phy_cfg_cmd.calib_control.flow_trigger =
		mvm->fw->default_calib[ucode_type].flow_trigger;

	IWL_DEBUG_INFO(mvm, "Sending Phy CFG command: 0x%x\n",
		       phy_cfg_cmd.phy_cfg);

	return iwl_mvm_send_cmd_pdu(mvm, PHY_CONFIGURATION_CMD, 0,
				    sizeof(phy_cfg_cmd), &phy_cfg_cmd);
}
Пример #29
0
Файл: fw.c Проект: 020gzh/linux
static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
{
	int i;
	struct iwl_rss_config_cmd cmd = {
		.flags = cpu_to_le32(IWL_RSS_ENABLE),
		.hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP |
			     IWL_RSS_HASH_TYPE_IPV4_PAYLOAD |
			     IWL_RSS_HASH_TYPE_IPV6_TCP |
			     IWL_RSS_HASH_TYPE_IPV6_PAYLOAD,
	};

	for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
		cmd.indirection_table[i] = i % mvm->trans->num_rx_queues;
	memcpy(cmd.secret_key, mvm->secret_key, sizeof(cmd.secret_key));

	return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
}

void iwl_free_fw_paging(struct iwl_mvm *mvm)
{
	int i;

	if (!mvm->fw_paging_db[0].fw_paging_block)
		return;

	for (i = 0; i < NUM_OF_FW_PAGING_BLOCKS; i++) {
		if (!mvm->fw_paging_db[i].fw_paging_block) {
			IWL_DEBUG_FW(mvm,
				     "Paging: block %d already freed, continue to next page\n",
				     i);

			continue;
		}

		__free_pages(mvm->fw_paging_db[i].fw_paging_block,
			     get_order(mvm->fw_paging_db[i].fw_paging_size));
	}
	kfree(mvm->trans->paging_download_buf);
	mvm->trans->paging_download_buf = NULL;

	memset(mvm->fw_paging_db, 0, sizeof(mvm->fw_paging_db));
}
Пример #30
0
int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
{
	u8 *ptr;
	int ret;
	int i;

	if (WARN_ONCE(conf_id >= ARRAY_SIZE(mvm->fw->dbg_conf_tlv),
		      "Invalid configuration %d\n", conf_id))
		return -EINVAL;

	/* EARLY START - firmware's configuration is hard coded */
	if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
	     !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
	    conf_id == FW_DBG_START_FROM_ALIVE) {
		iwl_mvm_restart_early_start(mvm);
		return 0;
	}

	if (!mvm->fw->dbg_conf_tlv[conf_id])
		return -EINVAL;

	if (mvm->fw_dbg_conf != FW_DBG_INVALID)
		IWL_WARN(mvm, "FW already configured (%d) - re-configuring\n",
			 mvm->fw_dbg_conf);

	/* Send all HCMDs for configuring the FW debug */
	ptr = (void *)&mvm->fw->dbg_conf_tlv[conf_id]->hcmd;
	for (i = 0; i < mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) {
		struct iwl_fw_dbg_conf_hcmd *cmd = (void *)ptr;

		ret = iwl_mvm_send_cmd_pdu(mvm, cmd->id, 0,
					   le16_to_cpu(cmd->len), cmd->data);
		if (ret)
			return ret;

		ptr += sizeof(*cmd);
		ptr += le16_to_cpu(cmd->len);
	}

	mvm->fw_dbg_conf = conf_id;
	return ret;
}