brintos

brintos / linux-shallow public Read only

0
0
Text · 43.7 KiB · f80cce3 Raw
1548 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.5 * Copyright(c) 2015 Intel Deutschland GmbH6 *****************************************************************************/7 8#include <linux/etherdevice.h>9#include "iwl-trans.h"10#include "iwl-modparams.h"11#include "dev.h"12#include "agn.h"13#include "calib.h"14 15/*16 * initialize rxon structure with default values from eeprom17 */18void iwl_connection_init_rx_config(struct iwl_priv *priv,19				   struct iwl_rxon_context *ctx)20{21	memset(&ctx->staging, 0, sizeof(ctx->staging));22 23	if (!ctx->vif) {24		ctx->staging.dev_type = ctx->unused_devtype;25	} else26	switch (ctx->vif->type) {27	case NL80211_IFTYPE_AP:28		ctx->staging.dev_type = ctx->ap_devtype;29		break;30 31	case NL80211_IFTYPE_STATION:32		ctx->staging.dev_type = ctx->station_devtype;33		ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;34		break;35 36	case NL80211_IFTYPE_ADHOC:37		ctx->staging.dev_type = ctx->ibss_devtype;38		ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;39		ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |40						  RXON_FILTER_ACCEPT_GRP_MSK;41		break;42 43	case NL80211_IFTYPE_MONITOR:44		ctx->staging.dev_type = RXON_DEV_TYPE_SNIFFER;45		break;46 47	default:48		IWL_ERR(priv, "Unsupported interface type %d\n",49			ctx->vif->type);50		break;51	}52 53#if 054	/* TODO:  Figure out when short_preamble would be set and cache from55	 * that */56	if (!hw_to_local(priv->hw)->short_preamble)57		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;58	else59		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;60#endif61 62	ctx->staging.channel =63		cpu_to_le16(priv->hw->conf.chandef.chan->hw_value);64	priv->band = priv->hw->conf.chandef.chan->band;65 66	iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);67 68	/* clear both MIX and PURE40 mode flag */69	ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |70					RXON_FLG_CHANNEL_MODE_PURE_40);71	if (ctx->vif)72		memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);73 74	ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;75	ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;76	ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;77}78 79static int iwlagn_disable_bss(struct iwl_priv *priv,80			      struct iwl_rxon_context *ctx,81			      struct iwl_rxon_cmd *send)82{83	__le32 old_filter = send->filter_flags;84	int ret;85 86	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;87	ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,88				0, sizeof(*send), send);89 90	send->filter_flags = old_filter;91 92	if (ret)93		IWL_DEBUG_QUIET_RFKILL(priv,94			"Error clearing ASSOC_MSK on BSS (%d)\n", ret);95 96	return ret;97}98 99static int iwlagn_disable_pan(struct iwl_priv *priv,100			      struct iwl_rxon_context *ctx,101			      struct iwl_rxon_cmd *send)102{103	struct iwl_notification_wait disable_wait;104	__le32 old_filter = send->filter_flags;105	u8 old_dev_type = send->dev_type;106	int ret;107	static const u16 deactivate_cmd[] = {108		REPLY_WIPAN_DEACTIVATION_COMPLETE109	};110 111	iwl_init_notification_wait(&priv->notif_wait, &disable_wait,112				   deactivate_cmd, ARRAY_SIZE(deactivate_cmd),113				   NULL, NULL);114 115	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;116	send->dev_type = RXON_DEV_TYPE_P2P;117	ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,118				0, sizeof(*send), send);119 120	send->filter_flags = old_filter;121	send->dev_type = old_dev_type;122 123	if (ret) {124		IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);125		iwl_remove_notification(&priv->notif_wait, &disable_wait);126	} else {127		ret = iwl_wait_notification(&priv->notif_wait,128					    &disable_wait, HZ);129		if (ret)130			IWL_ERR(priv, "Timed out waiting for PAN disable\n");131	}132 133	return ret;134}135 136static int iwlagn_disconn_pan(struct iwl_priv *priv,137			      struct iwl_rxon_context *ctx,138			      struct iwl_rxon_cmd *send)139{140	__le32 old_filter = send->filter_flags;141	int ret;142 143	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;144	ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, 0,145				sizeof(*send), send);146 147	send->filter_flags = old_filter;148 149	return ret;150}151 152static void iwlagn_update_qos(struct iwl_priv *priv,153			      struct iwl_rxon_context *ctx)154{155	int ret;156 157	if (!ctx->is_active)158		return;159 160	ctx->qos_data.def_qos_parm.qos_flags = 0;161 162	if (ctx->qos_data.qos_active)163		ctx->qos_data.def_qos_parm.qos_flags |=164			QOS_PARAM_FLG_UPDATE_EDCA_MSK;165 166	if (ctx->ht.enabled)167		ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;168 169	IWL_DEBUG_INFO(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",170		      ctx->qos_data.qos_active,171		      ctx->qos_data.def_qos_parm.qos_flags);172 173	ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, 0,174			       sizeof(struct iwl_qosparam_cmd),175			       &ctx->qos_data.def_qos_parm);176	if (ret)177		IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n");178}179 180static int iwlagn_update_beacon(struct iwl_priv *priv,181				struct ieee80211_vif *vif)182{183	lockdep_assert_held(&priv->mutex);184 185	dev_kfree_skb(priv->beacon_skb);186	priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif, 0);187	if (!priv->beacon_skb)188		return -ENOMEM;189	return iwlagn_send_beacon_cmd(priv);190}191 192static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,193				  struct iwl_rxon_context *ctx)194{195	int ret = 0;196	struct iwl_rxon_assoc_cmd rxon_assoc;197	const struct iwl_rxon_cmd *rxon1 = &ctx->staging;198	const struct iwl_rxon_cmd *rxon2 = &ctx->active;199 200	if ((rxon1->flags == rxon2->flags) &&201	    (rxon1->filter_flags == rxon2->filter_flags) &&202	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&203	    (rxon1->ofdm_ht_single_stream_basic_rates ==204	     rxon2->ofdm_ht_single_stream_basic_rates) &&205	    (rxon1->ofdm_ht_dual_stream_basic_rates ==206	     rxon2->ofdm_ht_dual_stream_basic_rates) &&207	    (rxon1->ofdm_ht_triple_stream_basic_rates ==208	     rxon2->ofdm_ht_triple_stream_basic_rates) &&209	    (rxon1->acquisition_data == rxon2->acquisition_data) &&210	    (rxon1->rx_chain == rxon2->rx_chain) &&211	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {212		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");213		return 0;214	}215 216	rxon_assoc.flags = ctx->staging.flags;217	rxon_assoc.filter_flags = ctx->staging.filter_flags;218	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;219	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;220	rxon_assoc.reserved1 = 0;221	rxon_assoc.reserved2 = 0;222	rxon_assoc.reserved3 = 0;223	rxon_assoc.ofdm_ht_single_stream_basic_rates =224	    ctx->staging.ofdm_ht_single_stream_basic_rates;225	rxon_assoc.ofdm_ht_dual_stream_basic_rates =226	    ctx->staging.ofdm_ht_dual_stream_basic_rates;227	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;228	rxon_assoc.ofdm_ht_triple_stream_basic_rates =229		 ctx->staging.ofdm_ht_triple_stream_basic_rates;230	rxon_assoc.acquisition_data = ctx->staging.acquisition_data;231 232	ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,233				CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);234	return ret;235}236 237static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)238{239	u16 new_val;240	u16 beacon_factor;241 242	/*243	 * If mac80211 hasn't given us a beacon interval, program244	 * the default into the device (not checking this here245	 * would cause the adjustment below to return the maximum246	 * value, which may break PAN.)247	 */248	if (!beacon_val)249		return DEFAULT_BEACON_INTERVAL;250 251	/*252	 * If the beacon interval we obtained from the peer253	 * is too large, we'll have to wake up more often254	 * (and in IBSS case, we'll beacon too much)255	 *256	 * For example, if max_beacon_val is 4096, and the257	 * requested beacon interval is 7000, we'll have to258	 * use 3500 to be able to wake up on the beacons.259	 *260	 * This could badly influence beacon detection stats.261	 */262 263	beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;264	new_val = beacon_val / beacon_factor;265 266	if (!new_val)267		new_val = max_beacon_val;268 269	return new_val;270}271 272static int iwl_send_rxon_timing(struct iwl_priv *priv,273				struct iwl_rxon_context *ctx)274{275	u64 tsf;276	s32 interval_tm, rem;277	struct ieee80211_conf *conf = NULL;278	u16 beacon_int;279	struct ieee80211_vif *vif = ctx->vif;280 281	conf = &priv->hw->conf;282 283	lockdep_assert_held(&priv->mutex);284 285	memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));286 287	ctx->timing.timestamp = cpu_to_le64(priv->timestamp);288	ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);289 290	beacon_int = vif ? vif->bss_conf.beacon_int : 0;291 292	/*293	 * TODO: For IBSS we need to get atim_window from mac80211,294	 *	 for now just always use 0295	 */296	ctx->timing.atim_window = 0;297 298	if (ctx->ctxid == IWL_RXON_CTX_PAN &&299	    (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&300	    iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&301	    priv->contexts[IWL_RXON_CTX_BSS].vif &&302	    priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {303		ctx->timing.beacon_interval =304			priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;305		beacon_int = le16_to_cpu(ctx->timing.beacon_interval);306	} else if (ctx->ctxid == IWL_RXON_CTX_BSS &&307		   iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&308		   priv->contexts[IWL_RXON_CTX_PAN].vif &&309		   priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&310		   (!iwl_is_associated_ctx(ctx) || !ctx->vif ||311		    !ctx->vif->bss_conf.beacon_int)) {312		ctx->timing.beacon_interval =313			priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;314		beacon_int = le16_to_cpu(ctx->timing.beacon_interval);315	} else {316		beacon_int = iwl_adjust_beacon_interval(beacon_int,317			IWL_MAX_UCODE_BEACON_INTERVAL * TIME_UNIT);318		ctx->timing.beacon_interval = cpu_to_le16(beacon_int);319	}320 321	ctx->beacon_int = beacon_int;322 323	tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */324	interval_tm = beacon_int * TIME_UNIT;325	rem = do_div(tsf, interval_tm);326	ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);327 328	ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;329 330	IWL_DEBUG_ASSOC(priv,331			"beacon interval %d beacon timer %d beacon tim %d\n",332			le16_to_cpu(ctx->timing.beacon_interval),333			le32_to_cpu(ctx->timing.beacon_init_val),334			le16_to_cpu(ctx->timing.atim_window));335 336	return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd,337				0, sizeof(ctx->timing), &ctx->timing);338}339 340static int iwlagn_rxon_disconn(struct iwl_priv *priv,341			       struct iwl_rxon_context *ctx)342{343	int ret;344	struct iwl_rxon_cmd *active = (void *)&ctx->active;345 346	if (ctx->ctxid == IWL_RXON_CTX_BSS) {347		ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);348	} else {349		ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);350		if (ret)351			return ret;352		if (ctx->vif) {353			ret = iwl_send_rxon_timing(priv, ctx);354			if (ret) {355				IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);356				return ret;357			}358			ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging);359		}360	}361	if (ret)362		return ret;363 364	/*365	 * Un-assoc RXON clears the station table and WEP366	 * keys, so we have to restore those afterwards.367	 */368	iwl_clear_ucode_stations(priv, ctx);369	/* update -- might need P2P now */370	iwl_update_bcast_station(priv, ctx);371	iwl_restore_stations(priv, ctx);372	ret = iwl_restore_default_wep_keys(priv, ctx);373	if (ret) {374		IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);375		return ret;376	}377 378	memcpy(active, &ctx->staging, sizeof(*active));379	return 0;380}381 382static int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)383{384	int ret;385	s8 prev_tx_power;386	bool defer;387	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];388 389	if (priv->calib_disabled & IWL_TX_POWER_CALIB_DISABLED)390		return 0;391 392	lockdep_assert_held(&priv->mutex);393 394	if (priv->tx_power_user_lmt == tx_power && !force)395		return 0;396 397	if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) {398		IWL_WARN(priv,399			 "Requested user TXPOWER %d below lower limit %d.\n",400			 tx_power,401			 IWLAGN_TX_POWER_TARGET_POWER_MIN);402		return -EINVAL;403	}404 405	if (tx_power > DIV_ROUND_UP(priv->nvm_data->max_tx_pwr_half_dbm, 2)) {406		IWL_WARN(priv,407			"Requested user TXPOWER %d above upper limit %d.\n",408			 tx_power, priv->nvm_data->max_tx_pwr_half_dbm);409		return -EINVAL;410	}411 412	if (!iwl_is_ready_rf(priv))413		return -EIO;414 415	/* scan complete and commit_rxon use tx_power_next value,416	 * it always need to be updated for newest request */417	priv->tx_power_next = tx_power;418 419	/* do not set tx power when scanning or channel changing */420	defer = test_bit(STATUS_SCANNING, &priv->status) ||421		memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));422	if (defer && !force) {423		IWL_DEBUG_INFO(priv, "Deferring tx power set\n");424		return 0;425	}426 427	prev_tx_power = priv->tx_power_user_lmt;428	priv->tx_power_user_lmt = tx_power;429 430	ret = iwlagn_send_tx_power(priv);431 432	/* if fail to set tx_power, restore the orig. tx power */433	if (ret) {434		priv->tx_power_user_lmt = prev_tx_power;435		priv->tx_power_next = prev_tx_power;436	}437	return ret;438}439 440static int iwlagn_rxon_connect(struct iwl_priv *priv,441			       struct iwl_rxon_context *ctx)442{443	int ret;444	struct iwl_rxon_cmd *active = (void *)&ctx->active;445 446	/* RXON timing must be before associated RXON */447	if (ctx->ctxid == IWL_RXON_CTX_BSS) {448		ret = iwl_send_rxon_timing(priv, ctx);449		if (ret) {450			IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);451			return ret;452		}453	}454	/* QoS info may be cleared by previous un-assoc RXON */455	iwlagn_update_qos(priv, ctx);456 457	/*458	 * We'll run into this code path when beaconing is459	 * enabled, but then we also need to send the beacon460	 * to the device.461	 */462	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {463		ret = iwlagn_update_beacon(priv, ctx->vif);464		if (ret) {465			IWL_ERR(priv,466				"Error sending required beacon (%d)!\n",467				ret);468			return ret;469		}470	}471 472	priv->start_calib = 0;473	/*474	 * Apply the new configuration.475	 *476	 * Associated RXON doesn't clear the station table in uCode,477	 * so we don't need to restore stations etc. after this.478	 */479	ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, 0,480		      sizeof(struct iwl_rxon_cmd), &ctx->staging);481	if (ret) {482		IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);483		return ret;484	}485	memcpy(active, &ctx->staging, sizeof(*active));486 487	/* IBSS beacon needs to be sent after setting assoc */488	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))489		if (iwlagn_update_beacon(priv, ctx->vif))490			IWL_ERR(priv, "Error sending IBSS beacon\n");491	iwl_init_sensitivity(priv);492 493	/*494	 * If we issue a new RXON command which required a tune then495	 * we must send a new TXPOWER command or we won't be able to496	 * Tx any frames.497	 *498	 * It's expected we set power here if channel is changing.499	 */500	ret = iwl_set_tx_power(priv, priv->tx_power_next, true);501	if (ret) {502		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);503		return ret;504	}505 506	return 0;507}508 509int iwlagn_set_pan_params(struct iwl_priv *priv)510{511	struct iwl_wipan_params_cmd cmd;512	struct iwl_rxon_context *ctx_bss, *ctx_pan;513	int slot0 = 300, slot1 = 0;514	int ret;515 516	if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))517		return 0;518 519	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);520 521	lockdep_assert_held(&priv->mutex);522 523	ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];524	ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];525 526	/*527	 * If the PAN context is inactive, then we don't need528	 * to update the PAN parameters, the last thing we'll529	 * have done before it goes inactive is making the PAN530	 * parameters be WLAN-only.531	 */532	if (!ctx_pan->is_active)533		return 0;534 535	memset(&cmd, 0, sizeof(cmd));536 537	/* only 2 slots are currently allowed */538	cmd.num_slots = 2;539 540	cmd.slots[0].type = 0; /* BSS */541	cmd.slots[1].type = 1; /* PAN */542 543	if (ctx_bss->vif && ctx_pan->vif) {544		int bcnint = ctx_pan->beacon_int;545		int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;546 547		/* should be set, but seems unused?? */548		cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);549 550		if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&551		    bcnint &&552		    bcnint != ctx_bss->beacon_int) {553			IWL_ERR(priv,554				"beacon intervals don't match (%d, %d)\n",555				ctx_bss->beacon_int, ctx_pan->beacon_int);556		} else557			bcnint = max_t(int, bcnint,558				       ctx_bss->beacon_int);559		if (!bcnint)560			bcnint = DEFAULT_BEACON_INTERVAL;561		slot0 = bcnint / 2;562		slot1 = bcnint - slot0;563 564		if (test_bit(STATUS_SCAN_HW, &priv->status) ||565		    (!ctx_bss->vif->cfg.idle &&566		     !ctx_bss->vif->cfg.assoc)) {567			slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;568			slot1 = IWL_MIN_SLOT_TIME;569		} else if (!ctx_pan->vif->cfg.idle &&570			   !ctx_pan->vif->cfg.assoc) {571			slot1 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;572			slot0 = IWL_MIN_SLOT_TIME;573		}574	} else if (ctx_pan->vif) {575		slot0 = 0;576		slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *577					ctx_pan->beacon_int;578		slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);579 580		if (test_bit(STATUS_SCAN_HW, &priv->status)) {581			slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;582			slot1 = IWL_MIN_SLOT_TIME;583		}584	}585 586	cmd.slots[0].width = cpu_to_le16(slot0);587	cmd.slots[1].width = cpu_to_le16(slot1);588 589	ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, 0,590			sizeof(cmd), &cmd);591	if (ret)592		IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);593 594	return ret;595}596 597static void _iwl_set_rxon_ht(struct iwl_priv *priv,598			     struct iwl_ht_config *ht_conf,599			     struct iwl_rxon_context *ctx)600{601	struct iwl_rxon_cmd *rxon = &ctx->staging;602 603	if (!ctx->ht.enabled) {604		rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |605			RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |606			RXON_FLG_HT40_PROT_MSK |607			RXON_FLG_HT_PROT_MSK);608		return;609	}610 611	/* FIXME: if the definition of ht.protection changed, the "translation"612	 * will be needed for rxon->flags613	 */614	rxon->flags |= cpu_to_le32(ctx->ht.protection <<615				   RXON_FLG_HT_OPERATING_MODE_POS);616 617	/* Set up channel bandwidth:618	 * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */619	/* clear the HT channel mode before set the mode */620	rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |621			 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);622	if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) {623		/* pure ht40 */624		if (ctx->ht.protection ==625		    IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {626			rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;627			/*628			 * Note: control channel is opposite of extension629			 * channel630			 */631			switch (ctx->ht.extension_chan_offset) {632			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:633				rxon->flags &=634					~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;635				break;636			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:637				rxon->flags |=638					RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;639				break;640			}641		} else {642			/*643			 * Note: control channel is opposite of extension644			 * channel645			 */646			switch (ctx->ht.extension_chan_offset) {647			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:648				rxon->flags &=649					~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);650				rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;651				break;652			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:653				rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;654				rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;655				break;656			case IEEE80211_HT_PARAM_CHA_SEC_NONE:657			default:658				/*659				 * channel location only valid if in Mixed660				 * mode661				 */662				IWL_ERR(priv,663					"invalid extension channel offset\n");664				break;665			}666		}667	} else {668		rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;669	}670 671	iwlagn_set_rxon_chain(priv, ctx);672 673	IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "674			"extension channel offset 0x%x\n",675			le32_to_cpu(rxon->flags), ctx->ht.protection,676			ctx->ht.extension_chan_offset);677}678 679void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)680{681	struct iwl_rxon_context *ctx;682 683	for_each_context(priv, ctx)684		_iwl_set_rxon_ht(priv, ht_conf, ctx);685}686 687/*688 * iwl_set_rxon_channel - Set the band and channel values in staging RXON689 * @ch: requested channel as a pointer to struct ieee80211_channel690 691 * NOTE:  Does not commit to the hardware; it sets appropriate bit fields692 * in the staging RXON flag structure based on the ch->band693 */694void iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,695			 struct iwl_rxon_context *ctx)696{697	enum nl80211_band band = ch->band;698	u16 channel = ch->hw_value;699 700	if ((le16_to_cpu(ctx->staging.channel) == channel) &&701	    (priv->band == band))702		return;703 704	ctx->staging.channel = cpu_to_le16(channel);705	if (band == NL80211_BAND_5GHZ)706		ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;707	else708		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;709 710	priv->band = band;711 712	IWL_DEBUG_INFO(priv, "Staging channel set to %d [%d]\n", channel, band);713 714}715 716void iwl_set_flags_for_band(struct iwl_priv *priv,717			    struct iwl_rxon_context *ctx,718			    enum nl80211_band band,719			    struct ieee80211_vif *vif)720{721	if (band == NL80211_BAND_5GHZ) {722		ctx->staging.flags &=723		    ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK724		      | RXON_FLG_CCK_MSK);725		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;726	} else {727		/* Copied from iwl_post_associate() */728		if (vif && vif->bss_conf.use_short_slot)729			ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;730		else731			ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;732 733		ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;734		ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;735		ctx->staging.flags &= ~RXON_FLG_CCK_MSK;736	}737}738 739static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv,740				  struct iwl_rxon_context *ctx, int hw_decrypt)741{742	struct iwl_rxon_cmd *rxon = &ctx->staging;743 744	if (hw_decrypt)745		rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;746	else747		rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;748 749}750 751/* validate RXON structure is valid */752static int iwl_check_rxon_cmd(struct iwl_priv *priv,753			      struct iwl_rxon_context *ctx)754{755	struct iwl_rxon_cmd *rxon = &ctx->staging;756	u32 errors = 0;757 758	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {759		if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {760			IWL_WARN(priv, "check 2.4G: wrong narrow\n");761			errors |= BIT(0);762		}763		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {764			IWL_WARN(priv, "check 2.4G: wrong radar\n");765			errors |= BIT(1);766		}767	} else {768		if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {769			IWL_WARN(priv, "check 5.2G: not short slot!\n");770			errors |= BIT(2);771		}772		if (rxon->flags & RXON_FLG_CCK_MSK) {773			IWL_WARN(priv, "check 5.2G: CCK!\n");774			errors |= BIT(3);775		}776	}777	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {778		IWL_WARN(priv, "mac/bssid mcast!\n");779		errors |= BIT(4);780	}781 782	/* make sure basic rates 6Mbps and 1Mbps are supported */783	if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&784	    (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {785		IWL_WARN(priv, "neither 1 nor 6 are basic\n");786		errors |= BIT(5);787	}788 789	if (le16_to_cpu(rxon->assoc_id) > 2007) {790		IWL_WARN(priv, "aid > 2007\n");791		errors |= BIT(6);792	}793 794	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))795			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {796		IWL_WARN(priv, "CCK and short slot\n");797		errors |= BIT(7);798	}799 800	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))801			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {802		IWL_WARN(priv, "CCK and auto detect\n");803		errors |= BIT(8);804	}805 806	if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |807			    RXON_FLG_TGG_PROTECT_MSK)) ==808			    RXON_FLG_TGG_PROTECT_MSK) {809		IWL_WARN(priv, "TGg but no auto-detect\n");810		errors |= BIT(9);811	}812 813	if (rxon->channel == 0) {814		IWL_WARN(priv, "zero channel is invalid\n");815		errors |= BIT(10);816	}817 818	WARN(errors, "Invalid RXON (%#x), channel %d",819	     errors, le16_to_cpu(rxon->channel));820 821	return errors ? -EINVAL : 0;822}823 824/*825 * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed826 * @priv: staging_rxon is compared to active_rxon827 *828 * If the RXON structure is changing enough to require a new tune,829 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that830 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.831 */832static int iwl_full_rxon_required(struct iwl_priv *priv,833				  struct iwl_rxon_context *ctx)834{835	const struct iwl_rxon_cmd *staging = &ctx->staging;836	const struct iwl_rxon_cmd *active = &ctx->active;837 838#define CHK(cond)							\839	if ((cond)) {							\840		IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n");	\841		return 1;						\842	}843 844#define CHK_NEQ(c1, c2)						\845	if ((c1) != (c2)) {					\846		IWL_DEBUG_INFO(priv, "need full RXON - "	\847			       #c1 " != " #c2 " - %d != %d\n",	\848			       (c1), (c2));			\849		return 1;					\850	}851 852	/* These items are only settable from the full RXON command */853	CHK(!iwl_is_associated_ctx(ctx));854	CHK(!ether_addr_equal(staging->bssid_addr, active->bssid_addr));855	CHK(!ether_addr_equal(staging->node_addr, active->node_addr));856	CHK(!ether_addr_equal(staging->wlap_bssid_addr,857			      active->wlap_bssid_addr));858	CHK_NEQ(staging->dev_type, active->dev_type);859	CHK_NEQ(staging->channel, active->channel);860	CHK_NEQ(staging->air_propagation, active->air_propagation);861	CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,862		active->ofdm_ht_single_stream_basic_rates);863	CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,864		active->ofdm_ht_dual_stream_basic_rates);865	CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,866		active->ofdm_ht_triple_stream_basic_rates);867	CHK_NEQ(staging->assoc_id, active->assoc_id);868 869	/* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can870	 * be updated with the RXON_ASSOC command -- however only some871	 * flag transitions are allowed using RXON_ASSOC */872 873	/* Check if we are not switching bands */874	CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,875		active->flags & RXON_FLG_BAND_24G_MSK);876 877	/* Check if we are switching association toggle */878	CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,879		active->filter_flags & RXON_FILTER_ASSOC_MSK);880 881#undef CHK882#undef CHK_NEQ883 884	return 0;885}886 887#ifdef CONFIG_IWLWIFI_DEBUG888void iwl_print_rx_config_cmd(struct iwl_priv *priv,889			     enum iwl_rxon_context_id ctxid)890{891	struct iwl_rxon_context *ctx = &priv->contexts[ctxid];892	struct iwl_rxon_cmd *rxon = &ctx->staging;893 894	IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");895	iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));896	IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n",897			le16_to_cpu(rxon->channel));898	IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n",899			le32_to_cpu(rxon->flags));900	IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",901			le32_to_cpu(rxon->filter_flags));902	IWL_DEBUG_RADIO(priv, "u8 dev_type: 0x%x\n", rxon->dev_type);903	IWL_DEBUG_RADIO(priv, "u8 ofdm_basic_rates: 0x%02x\n",904			rxon->ofdm_basic_rates);905	IWL_DEBUG_RADIO(priv, "u8 cck_basic_rates: 0x%02x\n",906			rxon->cck_basic_rates);907	IWL_DEBUG_RADIO(priv, "u8[6] node_addr: %pM\n", rxon->node_addr);908	IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);909	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n",910			le16_to_cpu(rxon->assoc_id));911}912#endif913 914static void iwl_calc_basic_rates(struct iwl_priv *priv,915				 struct iwl_rxon_context *ctx)916{917	int lowest_present_ofdm = 100;918	int lowest_present_cck = 100;919	u8 cck = 0;920	u8 ofdm = 0;921 922	if (ctx->vif) {923		struct ieee80211_supported_band *sband;924		unsigned long basic = ctx->vif->bss_conf.basic_rates;925		int i;926 927		sband = priv->hw->wiphy->bands[priv->hw->conf.chandef.chan->band];928 929		for_each_set_bit(i, &basic, BITS_PER_LONG) {930			int hw = sband->bitrates[i].hw_value;931			if (hw >= IWL_FIRST_OFDM_RATE) {932				ofdm |= BIT(hw - IWL_FIRST_OFDM_RATE);933				if (lowest_present_ofdm > hw)934					lowest_present_ofdm = hw;935			} else {936				BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);937 938				cck |= BIT(hw);939				if (lowest_present_cck > hw)940					lowest_present_cck = hw;941			}942		}943	}944 945	/*946	 * Now we've got the basic rates as bitmaps in the ofdm and cck947	 * variables. This isn't sufficient though, as there might not948	 * be all the right rates in the bitmap. E.g. if the only basic949	 * rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps950	 * and 6 Mbps because the 802.11-2007 standard says in 9.6:951	 *952	 *    [...] a STA responding to a received frame shall transmit953	 *    its Control Response frame [...] at the highest rate in the954	 *    BSSBasicRateSet parameter that is less than or equal to the955	 *    rate of the immediately previous frame in the frame exchange956	 *    sequence ([...]) and that is of the same modulation class957	 *    ([...]) as the received frame. If no rate contained in the958	 *    BSSBasicRateSet parameter meets these conditions, then the959	 *    control frame sent in response to a received frame shall be960	 *    transmitted at the highest mandatory rate of the PHY that is961	 *    less than or equal to the rate of the received frame, and962	 *    that is of the same modulation class as the received frame.963	 *964	 * As a consequence, we need to add all mandatory rates that are965	 * lower than all of the basic rates to these bitmaps.966	 */967 968	if (IWL_RATE_24M_INDEX < lowest_present_ofdm)969		ofdm |= IWL_RATE_24M_MASK >> IWL_FIRST_OFDM_RATE;970	if (IWL_RATE_12M_INDEX < lowest_present_ofdm)971		ofdm |= IWL_RATE_12M_MASK >> IWL_FIRST_OFDM_RATE;972	/* 6M already there or needed so always add */973	ofdm |= IWL_RATE_6M_MASK >> IWL_FIRST_OFDM_RATE;974 975	/*976	 * CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.977	 * Note, however:978	 *  - if no CCK rates are basic, it must be ERP since there must979	 *    be some basic rates at all, so they're OFDM => ERP PHY980	 *    (or we're in 5 GHz, and the cck bitmap will never be used)981	 *  - if 11M is a basic rate, it must be ERP as well, so add 5.5M982	 *  - if 5.5M is basic, 1M and 2M are mandatory983	 *  - if 2M is basic, 1M is mandatory984	 *  - if 1M is basic, that's the only valid ACK rate.985	 * As a consequence, it's not as complicated as it sounds, just add986	 * any lower rates to the ACK rate bitmap.987	 */988	if (IWL_RATE_11M_INDEX < lowest_present_cck)989		cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;990	if (IWL_RATE_5M_INDEX < lowest_present_cck)991		cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;992	if (IWL_RATE_2M_INDEX < lowest_present_cck)993		cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;994	/* 1M already there or needed so always add */995	cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;996 997	IWL_DEBUG_RATE(priv, "Set basic rates cck:0x%.2x ofdm:0x%.2x\n",998		       cck, ofdm);999 1000	/* "basic_rates" is a misnomer here -- should be called ACK rates */1001	ctx->staging.cck_basic_rates = cck;1002	ctx->staging.ofdm_basic_rates = ofdm;1003}1004 1005/*1006 * iwlagn_commit_rxon - commit staging_rxon to hardware1007 *1008 * The RXON command in staging_rxon is committed to the hardware and1009 * the active_rxon structure is updated with the new data.  This1010 * function correctly transitions out of the RXON_ASSOC_MSK state if1011 * a HW tune is required based on the RXON structure changes.1012 *1013 * The connect/disconnect flow should be as the following:1014 *1015 * 1. make sure send RXON command with association bit unset if not connect1016 *	this should include the channel and the band for the candidate1017 *	to be connected to1018 * 2. Add Station before RXON association with the AP1019 * 3. RXON_timing has to send before RXON for connection1020 * 4. full RXON command - associated bit set1021 * 5. use RXON_ASSOC command to update any flags changes1022 */1023int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)1024{1025	/* cast away the const for active_rxon in this function */1026	struct iwl_rxon_cmd *active = (void *)&ctx->active;1027	bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);1028	int ret;1029 1030	lockdep_assert_held(&priv->mutex);1031 1032	if (!iwl_is_alive(priv))1033		return -EBUSY;1034 1035	/* This function hardcodes a bunch of dual-mode assumptions */1036	BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);1037 1038	if (!ctx->is_active)1039		return 0;1040 1041	/* always get timestamp with Rx frame */1042	ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;1043 1044	/* recalculate basic rates */1045	iwl_calc_basic_rates(priv, ctx);1046 1047	/*1048	 * force CTS-to-self frames protection if RTS-CTS is not preferred1049	 * one aggregation protection method1050	 */1051	if (!priv->hw_params.use_rts_for_aggregation)1052		ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;1053 1054	if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||1055	    !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))1056		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;1057	else1058		ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;1059 1060	iwl_print_rx_config_cmd(priv, ctx->ctxid);1061	ret = iwl_check_rxon_cmd(priv, ctx);1062	if (ret) {1063		IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");1064		return -EINVAL;1065	}1066 1067	/*1068	 * receive commit_rxon request1069	 * abort any previous channel switch if still in process1070	 */1071	if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&1072	    (priv->switch_channel != ctx->staging.channel)) {1073		IWL_DEBUG_11H(priv, "abort channel switch on %d\n",1074			      le16_to_cpu(priv->switch_channel));1075		iwl_chswitch_done(priv, false);1076	}1077 1078	/*1079	 * If we don't need to send a full RXON, we can use1080	 * iwl_rxon_assoc_cmd which is used to reconfigure filter1081	 * and other flags for the current radio configuration.1082	 */1083	if (!iwl_full_rxon_required(priv, ctx)) {1084		ret = iwlagn_send_rxon_assoc(priv, ctx);1085		if (ret) {1086			IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);1087			return ret;1088		}1089 1090		memcpy(active, &ctx->staging, sizeof(*active));1091		/*1092		 * We do not commit tx power settings while channel changing,1093		 * do it now if after settings changed.1094		 */1095		iwl_set_tx_power(priv, priv->tx_power_next, false);1096 1097		/* make sure we are in the right PS state */1098		iwl_power_update_mode(priv, true);1099 1100		return 0;1101	}1102 1103	iwl_set_rxon_hwcrypto(priv, ctx, !iwlwifi_mod_params.swcrypto);1104 1105	IWL_DEBUG_INFO(priv,1106		       "Going to commit RXON\n"1107		       "  * with%s RXON_FILTER_ASSOC_MSK\n"1108		       "  * channel = %d\n"1109		       "  * bssid = %pM\n",1110		       (new_assoc ? "" : "out"),1111		       le16_to_cpu(ctx->staging.channel),1112		       ctx->staging.bssid_addr);1113 1114	/*1115	 * Always clear associated first, but with the correct config.1116	 * This is required as for example station addition for the1117	 * AP station must be done after the BSSID is set to correctly1118	 * set up filters in the device.1119	 */1120	ret = iwlagn_rxon_disconn(priv, ctx);1121	if (ret)1122		return ret;1123 1124	ret = iwlagn_set_pan_params(priv);1125	if (ret)1126		return ret;1127 1128	if (new_assoc)1129		return iwlagn_rxon_connect(priv, ctx);1130 1131	return 0;1132}1133 1134void iwlagn_config_ht40(struct ieee80211_conf *conf,1135			struct iwl_rxon_context *ctx)1136{1137	if (conf_is_ht40_minus(conf)) {1138		ctx->ht.extension_chan_offset =1139			IEEE80211_HT_PARAM_CHA_SEC_BELOW;1140		ctx->ht.is_40mhz = true;1141	} else if (conf_is_ht40_plus(conf)) {1142		ctx->ht.extension_chan_offset =1143			IEEE80211_HT_PARAM_CHA_SEC_ABOVE;1144		ctx->ht.is_40mhz = true;1145	} else {1146		ctx->ht.extension_chan_offset =1147			IEEE80211_HT_PARAM_CHA_SEC_NONE;1148		ctx->ht.is_40mhz = false;1149	}1150}1151 1152int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)1153{1154	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);1155	struct iwl_rxon_context *ctx;1156	struct ieee80211_conf *conf = &hw->conf;1157	struct ieee80211_channel *channel = conf->chandef.chan;1158	int ret = 0;1159 1160	IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed);1161 1162	mutex_lock(&priv->mutex);1163 1164	if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {1165		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");1166		goto out;1167	}1168 1169	if (!iwl_is_ready(priv)) {1170		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");1171		goto out;1172	}1173 1174	if (changed & (IEEE80211_CONF_CHANGE_SMPS |1175		       IEEE80211_CONF_CHANGE_CHANNEL)) {1176		/* mac80211 uses static for non-HT which is what we want */1177		priv->current_ht_config.smps = conf->smps_mode;1178 1179		/*1180		 * Recalculate chain counts.1181		 *1182		 * If monitor mode is enabled then mac80211 will1183		 * set up the SM PS mode to OFF if an HT channel is1184		 * configured.1185		 */1186		for_each_context(priv, ctx)1187			iwlagn_set_rxon_chain(priv, ctx);1188	}1189 1190	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {1191		for_each_context(priv, ctx) {1192			/* Configure HT40 channels */1193			if (ctx->ht.enabled != conf_is_ht(conf))1194				ctx->ht.enabled = conf_is_ht(conf);1195 1196			if (ctx->ht.enabled) {1197				/* if HT40 is used, it should not change1198				 * after associated except channel switch */1199				if (!ctx->ht.is_40mhz ||1200						!iwl_is_associated_ctx(ctx))1201					iwlagn_config_ht40(conf, ctx);1202			} else1203				ctx->ht.is_40mhz = false;1204 1205			/*1206			 * Default to no protection. Protection mode will1207			 * later be set from BSS config in iwl_ht_conf1208			 */1209			ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;1210 1211			/* if we are switching from ht to 2.4 clear flags1212			 * from any ht related info since 2.4 does not1213			 * support ht */1214			if (le16_to_cpu(ctx->staging.channel) !=1215			    channel->hw_value)1216				ctx->staging.flags = 0;1217 1218			iwl_set_rxon_channel(priv, channel, ctx);1219			iwl_set_rxon_ht(priv, &priv->current_ht_config);1220 1221			iwl_set_flags_for_band(priv, ctx, channel->band,1222					       ctx->vif);1223		}1224 1225		iwl_update_bcast_stations(priv);1226	}1227 1228	if (changed & (IEEE80211_CONF_CHANGE_PS |1229			IEEE80211_CONF_CHANGE_IDLE)) {1230		ret = iwl_power_update_mode(priv, false);1231		if (ret)1232			IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");1233	}1234 1235	if (changed & IEEE80211_CONF_CHANGE_POWER) {1236		IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",1237			priv->tx_power_user_lmt, conf->power_level);1238 1239		iwl_set_tx_power(priv, conf->power_level, false);1240	}1241 1242	for_each_context(priv, ctx) {1243		if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))1244			continue;1245		iwlagn_commit_rxon(priv, ctx);1246	}1247 out:1248	mutex_unlock(&priv->mutex);1249	IWL_DEBUG_MAC80211(priv, "leave\n");1250 1251	return ret;1252}1253 1254static void iwlagn_check_needed_chains(struct iwl_priv *priv,1255				       struct iwl_rxon_context *ctx,1256				       struct ieee80211_bss_conf *bss_conf)1257{1258	struct ieee80211_vif *vif = ctx->vif;1259	struct iwl_rxon_context *tmp;1260	struct ieee80211_sta *sta;1261	struct iwl_ht_config *ht_conf = &priv->current_ht_config;1262	struct ieee80211_sta_ht_cap *ht_cap;1263	bool need_multiple;1264 1265	lockdep_assert_held(&priv->mutex);1266 1267	switch (vif->type) {1268	case NL80211_IFTYPE_STATION:1269		rcu_read_lock();1270		sta = ieee80211_find_sta(vif, bss_conf->bssid);1271		if (!sta) {1272			/*1273			 * If at all, this can only happen through a race1274			 * when the AP disconnects us while we're still1275			 * setting up the connection, in that case mac802111276			 * will soon tell us about that.1277			 */1278			need_multiple = false;1279			rcu_read_unlock();1280			break;1281		}1282 1283		ht_cap = &sta->deflink.ht_cap;1284 1285		need_multiple = true;1286 1287		/*1288		 * If the peer advertises no support for receiving 2 and 31289		 * stream MCS rates, it can't be transmitting them either.1290		 */1291		if (ht_cap->mcs.rx_mask[1] == 0 &&1292		    ht_cap->mcs.rx_mask[2] == 0) {1293			need_multiple = false;1294		} else if (!(ht_cap->mcs.tx_params &1295						IEEE80211_HT_MCS_TX_DEFINED)) {1296			/* If it can't TX MCS at all ... */1297			need_multiple = false;1298		} else if (ht_cap->mcs.tx_params &1299						IEEE80211_HT_MCS_TX_RX_DIFF) {1300			int maxstreams;1301 1302			/*1303			 * But if it can receive them, it might still not1304			 * be able to transmit them, which is what we need1305			 * to check here -- so check the number of streams1306			 * it advertises for TX (if different from RX).1307			 */1308 1309			maxstreams = (ht_cap->mcs.tx_params &1310				 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK);1311			maxstreams >>=1312				IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;1313			maxstreams += 1;1314 1315			if (maxstreams <= 1)1316				need_multiple = false;1317		}1318 1319		rcu_read_unlock();1320		break;1321	case NL80211_IFTYPE_ADHOC:1322		/* currently */1323		need_multiple = false;1324		break;1325	default:1326		/* only AP really */1327		need_multiple = true;1328		break;1329	}1330 1331	ctx->ht_need_multiple_chains = need_multiple;1332 1333	if (!need_multiple) {1334		/* check all contexts */1335		for_each_context(priv, tmp) {1336			if (!tmp->vif)1337				continue;1338			if (tmp->ht_need_multiple_chains) {1339				need_multiple = true;1340				break;1341			}1342		}1343	}1344 1345	ht_conf->single_chain_sufficient = !need_multiple;1346}1347 1348static void iwlagn_chain_noise_reset(struct iwl_priv *priv)1349{1350	struct iwl_chain_noise_data *data = &priv->chain_noise_data;1351	int ret;1352 1353	if (priv->calib_disabled & IWL_CHAIN_NOISE_CALIB_DISABLED)1354		return;1355 1356	if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&1357	    iwl_is_any_associated(priv)) {1358		struct iwl_calib_chain_noise_reset_cmd cmd;1359 1360		/* clear data for chain noise calibration algorithm */1361		data->chain_noise_a = 0;1362		data->chain_noise_b = 0;1363		data->chain_noise_c = 0;1364		data->chain_signal_a = 0;1365		data->chain_signal_b = 0;1366		data->chain_signal_c = 0;1367		data->beacon_count = 0;1368 1369		memset(&cmd, 0, sizeof(cmd));1370		iwl_set_calib_hdr(&cmd.hdr,1371			priv->phy_calib_chain_noise_reset_cmd);1372		ret = iwl_dvm_send_cmd_pdu(priv,1373					REPLY_PHY_CALIBRATION_CMD,1374					0, sizeof(cmd), &cmd);1375		if (ret)1376			IWL_ERR(priv,1377				"Could not send REPLY_PHY_CALIBRATION_CMD\n");1378		data->state = IWL_CHAIN_NOISE_ACCUMULATE;1379		IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");1380	}1381}1382 1383void iwlagn_bss_info_changed(struct ieee80211_hw *hw,1384			     struct ieee80211_vif *vif,1385			     struct ieee80211_bss_conf *bss_conf,1386			     u64 changes)1387{1388	struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);1389	struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);1390	int ret;1391	bool force = false;1392 1393	mutex_lock(&priv->mutex);1394 1395	if (changes & BSS_CHANGED_IDLE && vif->cfg.idle) {1396		/*1397		 * If we go idle, then clearly no "passive-no-rx"1398		 * workaround is needed any more, this is a reset.1399		 */1400		iwlagn_lift_passive_no_rx(priv);1401	}1402 1403	if (unlikely(!iwl_is_ready(priv))) {1404		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");1405		mutex_unlock(&priv->mutex);1406		return;1407        }1408 1409	if (unlikely(!ctx->vif)) {1410		IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");1411		mutex_unlock(&priv->mutex);1412		return;1413	}1414 1415	if (changes & BSS_CHANGED_BEACON_INT)1416		force = true;1417 1418	if (changes & BSS_CHANGED_QOS) {1419		ctx->qos_data.qos_active = bss_conf->qos;1420		iwlagn_update_qos(priv, ctx);1421	}1422 1423	ctx->staging.assoc_id = cpu_to_le16(vif->cfg.aid);1424	if (vif->bss_conf.use_short_preamble)1425		ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;1426	else1427		ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;1428 1429	if (changes & BSS_CHANGED_ASSOC) {1430		if (vif->cfg.assoc) {1431			priv->timestamp = bss_conf->sync_tsf;1432			ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;1433		} else {1434			ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;1435 1436			if (ctx->ctxid == IWL_RXON_CTX_BSS)1437				priv->have_rekey_data = false;1438		}1439 1440		iwlagn_bt_coex_rssi_monitor(priv);1441	}1442 1443	if (ctx->ht.enabled) {1444		ctx->ht.protection = bss_conf->ht_operation_mode &1445					IEEE80211_HT_OP_MODE_PROTECTION;1446		ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &1447					IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);1448		iwlagn_check_needed_chains(priv, ctx, bss_conf);1449		iwl_set_rxon_ht(priv, &priv->current_ht_config);1450	}1451 1452	iwlagn_set_rxon_chain(priv, ctx);1453 1454	if (bss_conf->use_cts_prot && (priv->band != NL80211_BAND_5GHZ))1455		ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;1456	else1457		ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;1458 1459	if (bss_conf->use_cts_prot)1460		ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;1461	else1462		ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;1463 1464	memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);1465 1466	if (vif->type == NL80211_IFTYPE_AP ||1467	    vif->type == NL80211_IFTYPE_ADHOC) {1468		if (vif->bss_conf.enable_beacon) {1469			ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;1470			priv->beacon_ctx = ctx;1471		} else {1472			ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;1473			priv->beacon_ctx = NULL;1474		}1475	}1476 1477	/*1478	 * If the ucode decides to do beacon filtering before1479	 * association, it will lose beacons that are needed1480	 * before sending frames out on passive channels. This1481	 * causes association failures on those channels. Enable1482	 * receiving beacons in such cases.1483	 */1484 1485	if (vif->type == NL80211_IFTYPE_STATION) {1486		if (!vif->cfg.assoc)1487			ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK;1488		else1489			ctx->staging.filter_flags &=1490						    ~RXON_FILTER_BCON_AWARE_MSK;1491	}1492 1493	if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))1494		iwlagn_commit_rxon(priv, ctx);1495 1496	if (changes & BSS_CHANGED_ASSOC && vif->cfg.assoc) {1497		/*1498		 * The chain noise calibration will enable PM upon1499		 * completion. If calibration has already been run1500		 * then we need to enable power management here.1501		 */1502		if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)1503			iwl_power_update_mode(priv, false);1504 1505		/* Enable RX differential gain and sensitivity calibrations */1506		iwlagn_chain_noise_reset(priv);1507		priv->start_calib = 1;1508	}1509 1510	if (changes & BSS_CHANGED_IBSS) {1511		ret = iwlagn_manage_ibss_station(priv, vif,1512						 vif->cfg.ibss_joined);1513		if (ret)1514			IWL_ERR(priv, "failed to %s IBSS station %pM\n",1515				vif->cfg.ibss_joined ? "add" : "remove",1516				bss_conf->bssid);1517	}1518 1519	if (changes & BSS_CHANGED_BEACON && priv->beacon_ctx == ctx) {1520		if (iwlagn_update_beacon(priv, vif))1521			IWL_ERR(priv, "Error updating beacon\n");1522	}1523 1524	mutex_unlock(&priv->mutex);1525}1526 1527void iwlagn_post_scan(struct iwl_priv *priv)1528{1529	struct iwl_rxon_context *ctx;1530 1531	/*1532	 * We do not commit power settings while scan is pending,1533	 * do it now if the settings changed.1534	 */1535	iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);1536	iwl_set_tx_power(priv, priv->tx_power_next, false);1537 1538	/*1539	 * Since setting the RXON may have been deferred while1540	 * performing the scan, fire one off if needed1541	 */1542	for_each_context(priv, ctx)1543		if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))1544			iwlagn_commit_rxon(priv, ctx);1545 1546	iwlagn_set_pan_params(priv);1547}1548