Commit 03e304e4 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Johannes Berg
Browse files

iwlwifi: mvm: don't allocate BT_COEX cmd on stack



This command will change and be much bigger.
Prepare to that by stop allocating on the stack.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 8e0366f9
Loading
Loading
Loading
Loading
+92 −46
Original line number Diff line number Diff line
@@ -220,19 +220,41 @@ static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = {

int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
{
	struct iwl_bt_coex_cmd cmd = {
		.max_kill = 5,
		.bt3_time_t7_value = 1,
		.bt3_prio_sample_time = 2,
		.bt3_timer_t2_value = 0xc,
	struct iwl_bt_coex_cmd *bt_cmd;
	struct iwl_host_cmd cmd = {
		.id = BT_CONFIG,
		.len = { sizeof(*bt_cmd), },
		.dataflags = { IWL_HCMD_DFL_NOCOPY, },
		.flags = CMD_SYNC,
	};
	int ret;

	cmd.flags = iwlwifi_mod_params.bt_coex_active ?
	/* go to CALIB state in internal BT-Coex state machine */
	ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
			      BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
	if (ret)
		return ret;

	ret  = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
			       BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
	if (ret)
		return ret;

	bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
	if (!bt_cmd)
		return -ENOMEM;
	cmd.data[0] = bt_cmd;

	bt_cmd->max_kill = 5;
	bt_cmd->bt3_time_t7_value = 1;
	bt_cmd->bt3_prio_sample_time = 2;
	bt_cmd->bt3_timer_t2_value = 0xc;

	bt_cmd->flags = iwlwifi_mod_params.bt_coex_active ?
			BT_COEX_NW : BT_COEX_DISABLE;
	cmd.flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE;
	bt_cmd->flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE;

	cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
	bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE |
					    BT_VALID_BT_PRIO_BOOST |
					    BT_VALID_MAX_KILL |
					    BT_VALID_3W_TMRS |
@@ -242,44 +264,43 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
					    BT_VALID_LUT);

	if (mvm->cfg->bt_shared_single_ant)
		memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup,
		memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant_lookup,
		       sizeof(iwl_single_shared_ant_lookup));
	else if (is_loose_coex())
		memcpy(&cmd.decision_lut, iwl_loose_lookup,
		memcpy(&bt_cmd->decision_lut, iwl_loose_lookup,
		       sizeof(iwl_tight_lookup));
	else
		memcpy(&cmd.decision_lut, iwl_tight_lookup,
		memcpy(&bt_cmd->decision_lut, iwl_tight_lookup,
		       sizeof(iwl_tight_lookup));

	cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
	cmd.kill_ack_msk =
	bt_cmd->bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST);
	bt_cmd->kill_ack_msk =
		cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
	cmd.kill_cts_msk =
	bt_cmd->kill_cts_msk =
		cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);

	memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));

	/* go to CALIB state in internal BT-Coex state machine */
	ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN,
			      BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
	if (ret)
		return ret;
	ret = iwl_mvm_send_cmd(mvm, &cmd);

	ret  = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE,
			       BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
	if (ret)
	kfree(bt_cmd);
	return ret;

	return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
				    sizeof(cmd), &cmd);
}

static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
					   bool reduced_tx_power)
{
	enum iwl_bt_kill_msk bt_kill_msk;
	struct iwl_bt_coex_cmd cmd = {};
	struct iwl_bt_coex_cmd *bt_cmd;
	struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
	struct iwl_host_cmd cmd = {
		.id = BT_CONFIG,
		.data[0] = &bt_cmd,
		.len = { sizeof(*bt_cmd), },
		.dataflags = { IWL_HCMD_DFL_NOCOPY, },
		.flags = CMD_SYNC,
	};
	int ret = 0;

	lockdep_assert_held(&mvm->mutex);

@@ -308,24 +329,40 @@ static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
		return 0;

	mvm->bt_kill_msk = bt_kill_msk;
	cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
	cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
	cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);

	bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
	if (!bt_cmd)
		return -ENOMEM;
	cmd.data[0] = bt_cmd;

	bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
	bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
	bt_cmd->valid_bit_msk =
		cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);

	IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk);
	return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
				    sizeof(cmd), &cmd);

	ret = iwl_mvm_send_cmd(mvm, &cmd);

	kfree(bt_cmd);
	return ret;
}

static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
				       bool enable)
{
	struct iwl_bt_coex_cmd cmd = {
		.valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER),
		.bt_reduced_tx_power = sta_id,
	struct iwl_bt_coex_cmd *bt_cmd;
	/* Send ASYNC since this can be sent from an atomic context */
	struct iwl_host_cmd cmd = {
		.id = BT_CONFIG,
		.len = { sizeof(*bt_cmd), },
		.dataflags = { IWL_HCMD_DFL_DUP, },
		.flags = CMD_ASYNC,
	};

	struct ieee80211_sta *sta;
	struct iwl_mvm_sta *mvmsta;
	int ret;

	/* This can happen if the station has been removed right now */
	if (sta_id == IWL_MVM_STATION_COUNT)
@@ -339,17 +376,26 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
	if (mvmsta->bt_reduced_txpower == enable)
		return 0;

	bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC);
	if (!bt_cmd)
		return -ENOMEM;
	cmd.data[0] = bt_cmd;

	bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER),
	bt_cmd->bt_reduced_tx_power = sta_id;

	if (enable)
		cmd.bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
		bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;

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

	mvmsta->bt_reduced_txpower = enable;

	/* Send ASYNC since this can be sent from an atomic context */
	return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_ASYNC,
				    sizeof(cmd), &cmd);
	ret = iwl_mvm_send_cmd(mvm, &cmd);

	kfree(bt_cmd);
	return ret;
}

struct iwl_bt_iterator_data {