iwl-agn-rxon.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. * The full GNU General Public License is included in this distribution in the
  19. * file called LICENSE.
  20. *
  21. * Contact Information:
  22. * Intel Linux Wireless <ilw@linux.intel.com>
  23. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  24. *
  25. *****************************************************************************/
  26. #include <linux/etherdevice.h>
  27. #include "iwl-dev.h"
  28. #include "iwl-agn.h"
  29. #include "iwl-core.h"
  30. #include "iwl-agn-calib.h"
  31. #include "iwl-trans.h"
  32. #include "iwl-shared.h"
  33. static int iwlagn_disable_bss(struct iwl_priv *priv,
  34. struct iwl_rxon_context *ctx,
  35. struct iwl_rxon_cmd *send)
  36. {
  37. __le32 old_filter = send->filter_flags;
  38. int ret;
  39. send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
  40. ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
  41. CMD_SYNC, sizeof(*send), send);
  42. send->filter_flags = old_filter;
  43. if (ret)
  44. IWL_DEBUG_QUIET_RFKILL(priv,
  45. "Error clearing ASSOC_MSK on BSS (%d)\n", ret);
  46. return ret;
  47. }
  48. static int iwlagn_disable_pan(struct iwl_priv *priv,
  49. struct iwl_rxon_context *ctx,
  50. struct iwl_rxon_cmd *send)
  51. {
  52. struct iwl_notification_wait disable_wait;
  53. __le32 old_filter = send->filter_flags;
  54. u8 old_dev_type = send->dev_type;
  55. int ret;
  56. static const u8 deactivate_cmd[] = {
  57. REPLY_WIPAN_DEACTIVATION_COMPLETE
  58. };
  59. iwl_init_notification_wait(&priv->notif_wait, &disable_wait,
  60. deactivate_cmd, ARRAY_SIZE(deactivate_cmd),
  61. NULL, NULL);
  62. send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
  63. send->dev_type = RXON_DEV_TYPE_P2P;
  64. ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd,
  65. CMD_SYNC, sizeof(*send), send);
  66. send->filter_flags = old_filter;
  67. send->dev_type = old_dev_type;
  68. if (ret) {
  69. IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
  70. iwl_remove_notification(&priv->notif_wait, &disable_wait);
  71. } else {
  72. ret = iwl_wait_notification(&priv->notif_wait,
  73. &disable_wait, HZ);
  74. if (ret)
  75. IWL_ERR(priv, "Timed out waiting for PAN disable\n");
  76. }
  77. return ret;
  78. }
  79. static int iwlagn_disconn_pan(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. send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
  86. ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
  87. sizeof(*send), send);
  88. send->filter_flags = old_filter;
  89. return ret;
  90. }
  91. static void iwlagn_update_qos(struct iwl_priv *priv,
  92. struct iwl_rxon_context *ctx)
  93. {
  94. int ret;
  95. if (!ctx->is_active)
  96. return;
  97. ctx->qos_data.def_qos_parm.qos_flags = 0;
  98. if (ctx->qos_data.qos_active)
  99. ctx->qos_data.def_qos_parm.qos_flags |=
  100. QOS_PARAM_FLG_UPDATE_EDCA_MSK;
  101. if (ctx->ht.enabled)
  102. ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
  103. IWL_DEBUG_INFO(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
  104. ctx->qos_data.qos_active,
  105. ctx->qos_data.def_qos_parm.qos_flags);
  106. ret = iwl_dvm_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
  107. sizeof(struct iwl_qosparam_cmd),
  108. &ctx->qos_data.def_qos_parm);
  109. if (ret)
  110. IWL_DEBUG_QUIET_RFKILL(priv, "Failed to update QoS\n");
  111. }
  112. static int iwlagn_update_beacon(struct iwl_priv *priv,
  113. struct ieee80211_vif *vif)
  114. {
  115. lockdep_assert_held(&priv->mutex);
  116. dev_kfree_skb(priv->beacon_skb);
  117. priv->beacon_skb = ieee80211_beacon_get(priv->hw, vif);
  118. if (!priv->beacon_skb)
  119. return -ENOMEM;
  120. return iwlagn_send_beacon_cmd(priv);
  121. }
  122. static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
  123. struct iwl_rxon_context *ctx)
  124. {
  125. int ret = 0;
  126. struct iwl_rxon_assoc_cmd rxon_assoc;
  127. const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
  128. const struct iwl_rxon_cmd *rxon2 = &ctx->active;
  129. if ((rxon1->flags == rxon2->flags) &&
  130. (rxon1->filter_flags == rxon2->filter_flags) &&
  131. (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
  132. (rxon1->ofdm_ht_single_stream_basic_rates ==
  133. rxon2->ofdm_ht_single_stream_basic_rates) &&
  134. (rxon1->ofdm_ht_dual_stream_basic_rates ==
  135. rxon2->ofdm_ht_dual_stream_basic_rates) &&
  136. (rxon1->ofdm_ht_triple_stream_basic_rates ==
  137. rxon2->ofdm_ht_triple_stream_basic_rates) &&
  138. (rxon1->acquisition_data == rxon2->acquisition_data) &&
  139. (rxon1->rx_chain == rxon2->rx_chain) &&
  140. (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
  141. IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
  142. return 0;
  143. }
  144. rxon_assoc.flags = ctx->staging.flags;
  145. rxon_assoc.filter_flags = ctx->staging.filter_flags;
  146. rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
  147. rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
  148. rxon_assoc.reserved1 = 0;
  149. rxon_assoc.reserved2 = 0;
  150. rxon_assoc.reserved3 = 0;
  151. rxon_assoc.ofdm_ht_single_stream_basic_rates =
  152. ctx->staging.ofdm_ht_single_stream_basic_rates;
  153. rxon_assoc.ofdm_ht_dual_stream_basic_rates =
  154. ctx->staging.ofdm_ht_dual_stream_basic_rates;
  155. rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
  156. rxon_assoc.ofdm_ht_triple_stream_basic_rates =
  157. ctx->staging.ofdm_ht_triple_stream_basic_rates;
  158. rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
  159. ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
  160. CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
  161. return ret;
  162. }
  163. static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
  164. {
  165. u16 new_val;
  166. u16 beacon_factor;
  167. /*
  168. * If mac80211 hasn't given us a beacon interval, program
  169. * the default into the device (not checking this here
  170. * would cause the adjustment below to return the maximum
  171. * value, which may break PAN.)
  172. */
  173. if (!beacon_val)
  174. return DEFAULT_BEACON_INTERVAL;
  175. /*
  176. * If the beacon interval we obtained from the peer
  177. * is too large, we'll have to wake up more often
  178. * (and in IBSS case, we'll beacon too much)
  179. *
  180. * For example, if max_beacon_val is 4096, and the
  181. * requested beacon interval is 7000, we'll have to
  182. * use 3500 to be able to wake up on the beacons.
  183. *
  184. * This could badly influence beacon detection stats.
  185. */
  186. beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val;
  187. new_val = beacon_val / beacon_factor;
  188. if (!new_val)
  189. new_val = max_beacon_val;
  190. return new_val;
  191. }
  192. static int iwl_send_rxon_timing(struct iwl_priv *priv,
  193. struct iwl_rxon_context *ctx)
  194. {
  195. u64 tsf;
  196. s32 interval_tm, rem;
  197. struct ieee80211_conf *conf = NULL;
  198. u16 beacon_int;
  199. struct ieee80211_vif *vif = ctx->vif;
  200. conf = &priv->hw->conf;
  201. lockdep_assert_held(&priv->mutex);
  202. memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
  203. ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
  204. ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
  205. beacon_int = vif ? vif->bss_conf.beacon_int : 0;
  206. /*
  207. * TODO: For IBSS we need to get atim_window from mac80211,
  208. * for now just always use 0
  209. */
  210. ctx->timing.atim_window = 0;
  211. if (ctx->ctxid == IWL_RXON_CTX_PAN &&
  212. (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) &&
  213. iwl_is_associated(priv, IWL_RXON_CTX_BSS) &&
  214. priv->contexts[IWL_RXON_CTX_BSS].vif &&
  215. priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) {
  216. ctx->timing.beacon_interval =
  217. priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval;
  218. beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
  219. } else if (ctx->ctxid == IWL_RXON_CTX_BSS &&
  220. iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
  221. priv->contexts[IWL_RXON_CTX_PAN].vif &&
  222. priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int &&
  223. (!iwl_is_associated_ctx(ctx) || !ctx->vif ||
  224. !ctx->vif->bss_conf.beacon_int)) {
  225. ctx->timing.beacon_interval =
  226. priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval;
  227. beacon_int = le16_to_cpu(ctx->timing.beacon_interval);
  228. } else {
  229. beacon_int = iwl_adjust_beacon_interval(beacon_int,
  230. IWL_MAX_UCODE_BEACON_INTERVAL * TIME_UNIT);
  231. ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
  232. }
  233. ctx->beacon_int = beacon_int;
  234. tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
  235. interval_tm = beacon_int * TIME_UNIT;
  236. rem = do_div(tsf, interval_tm);
  237. ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
  238. ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1;
  239. IWL_DEBUG_ASSOC(priv,
  240. "beacon interval %d beacon timer %d beacon tim %d\n",
  241. le16_to_cpu(ctx->timing.beacon_interval),
  242. le32_to_cpu(ctx->timing.beacon_init_val),
  243. le16_to_cpu(ctx->timing.atim_window));
  244. return iwl_dvm_send_cmd_pdu(priv, ctx->rxon_timing_cmd,
  245. CMD_SYNC, sizeof(ctx->timing), &ctx->timing);
  246. }
  247. static int iwlagn_rxon_disconn(struct iwl_priv *priv,
  248. struct iwl_rxon_context *ctx)
  249. {
  250. int ret;
  251. struct iwl_rxon_cmd *active = (void *)&ctx->active;
  252. if (ctx->ctxid == IWL_RXON_CTX_BSS) {
  253. ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
  254. } else {
  255. ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
  256. if (ret)
  257. return ret;
  258. if (ctx->vif) {
  259. ret = iwl_send_rxon_timing(priv, ctx);
  260. if (ret) {
  261. IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
  262. return ret;
  263. }
  264. ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging);
  265. }
  266. }
  267. if (ret)
  268. return ret;
  269. /*
  270. * Un-assoc RXON clears the station table and WEP
  271. * keys, so we have to restore those afterwards.
  272. */
  273. iwl_clear_ucode_stations(priv, ctx);
  274. /* update -- might need P2P now */
  275. iwl_update_bcast_station(priv, ctx);
  276. iwl_restore_stations(priv, ctx);
  277. ret = iwl_restore_default_wep_keys(priv, ctx);
  278. if (ret) {
  279. IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
  280. return ret;
  281. }
  282. memcpy(active, &ctx->staging, sizeof(*active));
  283. return 0;
  284. }
  285. static int iwlagn_rxon_connect(struct iwl_priv *priv,
  286. struct iwl_rxon_context *ctx)
  287. {
  288. int ret;
  289. struct iwl_rxon_cmd *active = (void *)&ctx->active;
  290. /* RXON timing must be before associated RXON */
  291. if (ctx->ctxid == IWL_RXON_CTX_BSS) {
  292. ret = iwl_send_rxon_timing(priv, ctx);
  293. if (ret) {
  294. IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
  295. return ret;
  296. }
  297. }
  298. /* QoS info may be cleared by previous un-assoc RXON */
  299. iwlagn_update_qos(priv, ctx);
  300. /*
  301. * We'll run into this code path when beaconing is
  302. * enabled, but then we also need to send the beacon
  303. * to the device.
  304. */
  305. if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
  306. ret = iwlagn_update_beacon(priv, ctx->vif);
  307. if (ret) {
  308. IWL_ERR(priv,
  309. "Error sending required beacon (%d)!\n",
  310. ret);
  311. return ret;
  312. }
  313. }
  314. priv->start_calib = 0;
  315. /*
  316. * Apply the new configuration.
  317. *
  318. * Associated RXON doesn't clear the station table in uCode,
  319. * so we don't need to restore stations etc. after this.
  320. */
  321. ret = iwl_dvm_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
  322. sizeof(struct iwl_rxon_cmd), &ctx->staging);
  323. if (ret) {
  324. IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
  325. return ret;
  326. }
  327. memcpy(active, &ctx->staging, sizeof(*active));
  328. /* IBSS beacon needs to be sent after setting assoc */
  329. if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
  330. if (iwlagn_update_beacon(priv, ctx->vif))
  331. IWL_ERR(priv, "Error sending IBSS beacon\n");
  332. iwl_init_sensitivity(priv);
  333. /*
  334. * If we issue a new RXON command which required a tune then
  335. * we must send a new TXPOWER command or we won't be able to
  336. * Tx any frames.
  337. *
  338. * It's expected we set power here if channel is changing.
  339. */
  340. ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
  341. if (ret) {
  342. IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
  343. return ret;
  344. }
  345. if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION &&
  346. cfg(priv)->ht_params && cfg(priv)->ht_params->smps_mode)
  347. ieee80211_request_smps(ctx->vif,
  348. cfg(priv)->ht_params->smps_mode);
  349. return 0;
  350. }
  351. int iwlagn_set_pan_params(struct iwl_priv *priv)
  352. {
  353. struct iwl_wipan_params_cmd cmd;
  354. struct iwl_rxon_context *ctx_bss, *ctx_pan;
  355. int slot0 = 300, slot1 = 0;
  356. int ret;
  357. if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
  358. return 0;
  359. BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
  360. lockdep_assert_held(&priv->mutex);
  361. ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
  362. ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
  363. /*
  364. * If the PAN context is inactive, then we don't need
  365. * to update the PAN parameters, the last thing we'll
  366. * have done before it goes inactive is making the PAN
  367. * parameters be WLAN-only.
  368. */
  369. if (!ctx_pan->is_active)
  370. return 0;
  371. memset(&cmd, 0, sizeof(cmd));
  372. /* only 2 slots are currently allowed */
  373. cmd.num_slots = 2;
  374. cmd.slots[0].type = 0; /* BSS */
  375. cmd.slots[1].type = 1; /* PAN */
  376. if (priv->hw_roc_setup) {
  377. /* both contexts must be used for this to happen */
  378. slot1 = IWL_MIN_SLOT_TIME;
  379. slot0 = 3000;
  380. } else if (ctx_bss->vif && ctx_pan->vif) {
  381. int bcnint = ctx_pan->beacon_int;
  382. int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
  383. /* should be set, but seems unused?? */
  384. cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE);
  385. if (ctx_pan->vif->type == NL80211_IFTYPE_AP &&
  386. bcnint &&
  387. bcnint != ctx_bss->beacon_int) {
  388. IWL_ERR(priv,
  389. "beacon intervals don't match (%d, %d)\n",
  390. ctx_bss->beacon_int, ctx_pan->beacon_int);
  391. } else
  392. bcnint = max_t(int, bcnint,
  393. ctx_bss->beacon_int);
  394. if (!bcnint)
  395. bcnint = DEFAULT_BEACON_INTERVAL;
  396. slot0 = bcnint / 2;
  397. slot1 = bcnint - slot0;
  398. if (test_bit(STATUS_SCAN_HW, &priv->status) ||
  399. (!ctx_bss->vif->bss_conf.idle &&
  400. !ctx_bss->vif->bss_conf.assoc)) {
  401. slot0 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
  402. slot1 = IWL_MIN_SLOT_TIME;
  403. } else if (!ctx_pan->vif->bss_conf.idle &&
  404. !ctx_pan->vif->bss_conf.assoc) {
  405. slot1 = dtim * bcnint * 3 - IWL_MIN_SLOT_TIME;
  406. slot0 = IWL_MIN_SLOT_TIME;
  407. }
  408. } else if (ctx_pan->vif) {
  409. slot0 = 0;
  410. slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) *
  411. ctx_pan->beacon_int;
  412. slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1);
  413. if (test_bit(STATUS_SCAN_HW, &priv->status)) {
  414. slot0 = slot1 * 3 - IWL_MIN_SLOT_TIME;
  415. slot1 = IWL_MIN_SLOT_TIME;
  416. }
  417. }
  418. cmd.slots[0].width = cpu_to_le16(slot0);
  419. cmd.slots[1].width = cpu_to_le16(slot1);
  420. ret = iwl_dvm_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, CMD_SYNC,
  421. sizeof(cmd), &cmd);
  422. if (ret)
  423. IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret);
  424. return ret;
  425. }
  426. static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv,
  427. struct iwl_rxon_context *ctx, int hw_decrypt)
  428. {
  429. struct iwl_rxon_cmd *rxon = &ctx->staging;
  430. if (hw_decrypt)
  431. rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
  432. else
  433. rxon->filter_flags |= RXON_FILTER_DIS_DECRYPT_MSK;
  434. }
  435. /* validate RXON structure is valid */
  436. static int iwl_check_rxon_cmd(struct iwl_priv *priv,
  437. struct iwl_rxon_context *ctx)
  438. {
  439. struct iwl_rxon_cmd *rxon = &ctx->staging;
  440. u32 errors = 0;
  441. if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
  442. if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
  443. IWL_WARN(priv, "check 2.4G: wrong narrow\n");
  444. errors |= BIT(0);
  445. }
  446. if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
  447. IWL_WARN(priv, "check 2.4G: wrong radar\n");
  448. errors |= BIT(1);
  449. }
  450. } else {
  451. if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
  452. IWL_WARN(priv, "check 5.2G: not short slot!\n");
  453. errors |= BIT(2);
  454. }
  455. if (rxon->flags & RXON_FLG_CCK_MSK) {
  456. IWL_WARN(priv, "check 5.2G: CCK!\n");
  457. errors |= BIT(3);
  458. }
  459. }
  460. if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
  461. IWL_WARN(priv, "mac/bssid mcast!\n");
  462. errors |= BIT(4);
  463. }
  464. /* make sure basic rates 6Mbps and 1Mbps are supported */
  465. if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
  466. (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
  467. IWL_WARN(priv, "neither 1 nor 6 are basic\n");
  468. errors |= BIT(5);
  469. }
  470. if (le16_to_cpu(rxon->assoc_id) > 2007) {
  471. IWL_WARN(priv, "aid > 2007\n");
  472. errors |= BIT(6);
  473. }
  474. if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
  475. == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
  476. IWL_WARN(priv, "CCK and short slot\n");
  477. errors |= BIT(7);
  478. }
  479. if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
  480. == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
  481. IWL_WARN(priv, "CCK and auto detect");
  482. errors |= BIT(8);
  483. }
  484. if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
  485. RXON_FLG_TGG_PROTECT_MSK)) ==
  486. RXON_FLG_TGG_PROTECT_MSK) {
  487. IWL_WARN(priv, "TGg but no auto-detect\n");
  488. errors |= BIT(9);
  489. }
  490. if (rxon->channel == 0) {
  491. IWL_WARN(priv, "zero channel is invalid\n");
  492. errors |= BIT(10);
  493. }
  494. WARN(errors, "Invalid RXON (%#x), channel %d",
  495. errors, le16_to_cpu(rxon->channel));
  496. return errors ? -EINVAL : 0;
  497. }
  498. /**
  499. * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed
  500. * @priv: staging_rxon is compared to active_rxon
  501. *
  502. * If the RXON structure is changing enough to require a new tune,
  503. * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
  504. * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
  505. */
  506. static int iwl_full_rxon_required(struct iwl_priv *priv,
  507. struct iwl_rxon_context *ctx)
  508. {
  509. const struct iwl_rxon_cmd *staging = &ctx->staging;
  510. const struct iwl_rxon_cmd *active = &ctx->active;
  511. #define CHK(cond) \
  512. if ((cond)) { \
  513. IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \
  514. return 1; \
  515. }
  516. #define CHK_NEQ(c1, c2) \
  517. if ((c1) != (c2)) { \
  518. IWL_DEBUG_INFO(priv, "need full RXON - " \
  519. #c1 " != " #c2 " - %d != %d\n", \
  520. (c1), (c2)); \
  521. return 1; \
  522. }
  523. /* These items are only settable from the full RXON command */
  524. CHK(!iwl_is_associated_ctx(ctx));
  525. CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
  526. CHK(compare_ether_addr(staging->node_addr, active->node_addr));
  527. CHK(compare_ether_addr(staging->wlap_bssid_addr,
  528. active->wlap_bssid_addr));
  529. CHK_NEQ(staging->dev_type, active->dev_type);
  530. CHK_NEQ(staging->channel, active->channel);
  531. CHK_NEQ(staging->air_propagation, active->air_propagation);
  532. CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,
  533. active->ofdm_ht_single_stream_basic_rates);
  534. CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,
  535. active->ofdm_ht_dual_stream_basic_rates);
  536. CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,
  537. active->ofdm_ht_triple_stream_basic_rates);
  538. CHK_NEQ(staging->assoc_id, active->assoc_id);
  539. /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
  540. * be updated with the RXON_ASSOC command -- however only some
  541. * flag transitions are allowed using RXON_ASSOC */
  542. /* Check if we are not switching bands */
  543. CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
  544. active->flags & RXON_FLG_BAND_24G_MSK);
  545. /* Check if we are switching association toggle */
  546. CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
  547. active->filter_flags & RXON_FILTER_ASSOC_MSK);
  548. #undef CHK
  549. #undef CHK_NEQ
  550. return 0;
  551. }
  552. /**
  553. * iwlagn_commit_rxon - commit staging_rxon to hardware
  554. *
  555. * The RXON command in staging_rxon is committed to the hardware and
  556. * the active_rxon structure is updated with the new data. This
  557. * function correctly transitions out of the RXON_ASSOC_MSK state if
  558. * a HW tune is required based on the RXON structure changes.
  559. *
  560. * The connect/disconnect flow should be as the following:
  561. *
  562. * 1. make sure send RXON command with association bit unset if not connect
  563. * this should include the channel and the band for the candidate
  564. * to be connected to
  565. * 2. Add Station before RXON association with the AP
  566. * 3. RXON_timing has to send before RXON for connection
  567. * 4. full RXON command - associated bit set
  568. * 5. use RXON_ASSOC command to update any flags changes
  569. */
  570. int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
  571. {
  572. /* cast away the const for active_rxon in this function */
  573. struct iwl_rxon_cmd *active = (void *)&ctx->active;
  574. bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
  575. int ret;
  576. lockdep_assert_held(&priv->mutex);
  577. if (!iwl_is_alive(priv))
  578. return -EBUSY;
  579. /* This function hardcodes a bunch of dual-mode assumptions */
  580. BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
  581. if (!ctx->is_active)
  582. return 0;
  583. /* always get timestamp with Rx frame */
  584. ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
  585. /*
  586. * force CTS-to-self frames protection if RTS-CTS is not preferred
  587. * one aggregation protection method
  588. */
  589. if (!hw_params(priv).use_rts_for_aggregation)
  590. ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
  591. if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
  592. !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
  593. ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
  594. else
  595. ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
  596. iwl_print_rx_config_cmd(priv, ctx->ctxid);
  597. ret = iwl_check_rxon_cmd(priv, ctx);
  598. if (ret) {
  599. IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
  600. return -EINVAL;
  601. }
  602. /*
  603. * receive commit_rxon request
  604. * abort any previous channel switch if still in process
  605. */
  606. if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
  607. (priv->switch_channel != ctx->staging.channel)) {
  608. IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
  609. le16_to_cpu(priv->switch_channel));
  610. iwl_chswitch_done(priv, false);
  611. }
  612. /*
  613. * If we don't need to send a full RXON, we can use
  614. * iwl_rxon_assoc_cmd which is used to reconfigure filter
  615. * and other flags for the current radio configuration.
  616. */
  617. if (!iwl_full_rxon_required(priv, ctx)) {
  618. ret = iwlagn_send_rxon_assoc(priv, ctx);
  619. if (ret) {
  620. IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
  621. return ret;
  622. }
  623. memcpy(active, &ctx->staging, sizeof(*active));
  624. /*
  625. * We do not commit tx power settings while channel changing,
  626. * do it now if after settings changed.
  627. */
  628. iwl_set_tx_power(priv, priv->tx_power_next, false);
  629. /* make sure we are in the right PS state */
  630. iwl_power_update_mode(priv, true);
  631. return 0;
  632. }
  633. iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
  634. IWL_DEBUG_INFO(priv,
  635. "Going to commit RXON\n"
  636. " * with%s RXON_FILTER_ASSOC_MSK\n"
  637. " * channel = %d\n"
  638. " * bssid = %pM\n",
  639. (new_assoc ? "" : "out"),
  640. le16_to_cpu(ctx->staging.channel),
  641. ctx->staging.bssid_addr);
  642. /*
  643. * Always clear associated first, but with the correct config.
  644. * This is required as for example station addition for the
  645. * AP station must be done after the BSSID is set to correctly
  646. * set up filters in the device.
  647. */
  648. ret = iwlagn_rxon_disconn(priv, ctx);
  649. if (ret)
  650. return ret;
  651. ret = iwlagn_set_pan_params(priv);
  652. if (ret)
  653. return ret;
  654. if (new_assoc)
  655. return iwlagn_rxon_connect(priv, ctx);
  656. return 0;
  657. }
  658. void iwlagn_config_ht40(struct ieee80211_conf *conf,
  659. struct iwl_rxon_context *ctx)
  660. {
  661. if (conf_is_ht40_minus(conf)) {
  662. ctx->ht.extension_chan_offset =
  663. IEEE80211_HT_PARAM_CHA_SEC_BELOW;
  664. ctx->ht.is_40mhz = true;
  665. } else if (conf_is_ht40_plus(conf)) {
  666. ctx->ht.extension_chan_offset =
  667. IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
  668. ctx->ht.is_40mhz = true;
  669. } else {
  670. ctx->ht.extension_chan_offset =
  671. IEEE80211_HT_PARAM_CHA_SEC_NONE;
  672. ctx->ht.is_40mhz = false;
  673. }
  674. }
  675. int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
  676. {
  677. struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
  678. struct iwl_rxon_context *ctx;
  679. struct ieee80211_conf *conf = &hw->conf;
  680. struct ieee80211_channel *channel = conf->channel;
  681. const struct iwl_channel_info *ch_info;
  682. int ret = 0;
  683. IWL_DEBUG_MAC80211(priv, "enter: changed %#x\n", changed);
  684. mutex_lock(&priv->mutex);
  685. if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
  686. IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
  687. goto out;
  688. }
  689. if (!iwl_is_ready(priv)) {
  690. IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
  691. goto out;
  692. }
  693. if (changed & (IEEE80211_CONF_CHANGE_SMPS |
  694. IEEE80211_CONF_CHANGE_CHANNEL)) {
  695. /* mac80211 uses static for non-HT which is what we want */
  696. priv->current_ht_config.smps = conf->smps_mode;
  697. /*
  698. * Recalculate chain counts.
  699. *
  700. * If monitor mode is enabled then mac80211 will
  701. * set up the SM PS mode to OFF if an HT channel is
  702. * configured.
  703. */
  704. for_each_context(priv, ctx)
  705. iwlagn_set_rxon_chain(priv, ctx);
  706. }
  707. if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
  708. ch_info = iwl_get_channel_info(priv, channel->band,
  709. channel->hw_value);
  710. if (!is_channel_valid(ch_info)) {
  711. IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
  712. ret = -EINVAL;
  713. goto out;
  714. }
  715. for_each_context(priv, ctx) {
  716. /* Configure HT40 channels */
  717. if (ctx->ht.enabled != conf_is_ht(conf))
  718. ctx->ht.enabled = conf_is_ht(conf);
  719. if (ctx->ht.enabled) {
  720. /* if HT40 is used, it should not change
  721. * after associated except channel switch */
  722. if (!ctx->ht.is_40mhz ||
  723. !iwl_is_associated_ctx(ctx))
  724. iwlagn_config_ht40(conf, ctx);
  725. } else
  726. ctx->ht.is_40mhz = false;
  727. /*
  728. * Default to no protection. Protection mode will
  729. * later be set from BSS config in iwl_ht_conf
  730. */
  731. ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
  732. /* if we are switching from ht to 2.4 clear flags
  733. * from any ht related info since 2.4 does not
  734. * support ht */
  735. if (le16_to_cpu(ctx->staging.channel) !=
  736. channel->hw_value)
  737. ctx->staging.flags = 0;
  738. iwl_set_rxon_channel(priv, channel, ctx);
  739. iwl_set_rxon_ht(priv, &priv->current_ht_config);
  740. iwl_set_flags_for_band(priv, ctx, channel->band,
  741. ctx->vif);
  742. }
  743. iwl_update_bcast_stations(priv);
  744. /*
  745. * The list of supported rates and rate mask can be different
  746. * for each band; since the band may have changed, reset
  747. * the rate mask to what mac80211 lists.
  748. */
  749. iwl_set_rate(priv);
  750. }
  751. if (changed & (IEEE80211_CONF_CHANGE_PS |
  752. IEEE80211_CONF_CHANGE_IDLE)) {
  753. ret = iwl_power_update_mode(priv, false);
  754. if (ret)
  755. IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
  756. }
  757. if (changed & IEEE80211_CONF_CHANGE_POWER) {
  758. IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
  759. priv->tx_power_user_lmt, conf->power_level);
  760. iwl_set_tx_power(priv, conf->power_level, false);
  761. }
  762. for_each_context(priv, ctx) {
  763. if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
  764. continue;
  765. iwlagn_commit_rxon(priv, ctx);
  766. }
  767. out:
  768. mutex_unlock(&priv->mutex);
  769. IWL_DEBUG_MAC80211(priv, "leave\n");
  770. return ret;
  771. }
  772. static void iwlagn_check_needed_chains(struct iwl_priv *priv,
  773. struct iwl_rxon_context *ctx,
  774. struct ieee80211_bss_conf *bss_conf)
  775. {
  776. struct ieee80211_vif *vif = ctx->vif;
  777. struct iwl_rxon_context *tmp;
  778. struct ieee80211_sta *sta;
  779. struct iwl_ht_config *ht_conf = &priv->current_ht_config;
  780. struct ieee80211_sta_ht_cap *ht_cap;
  781. bool need_multiple;
  782. lockdep_assert_held(&priv->mutex);
  783. switch (vif->type) {
  784. case NL80211_IFTYPE_STATION:
  785. rcu_read_lock();
  786. sta = ieee80211_find_sta(vif, bss_conf->bssid);
  787. if (!sta) {
  788. /*
  789. * If at all, this can only happen through a race
  790. * when the AP disconnects us while we're still
  791. * setting up the connection, in that case mac80211
  792. * will soon tell us about that.
  793. */
  794. need_multiple = false;
  795. rcu_read_unlock();
  796. break;
  797. }
  798. ht_cap = &sta->ht_cap;
  799. need_multiple = true;
  800. /*
  801. * If the peer advertises no support for receiving 2 and 3
  802. * stream MCS rates, it can't be transmitting them either.
  803. */
  804. if (ht_cap->mcs.rx_mask[1] == 0 &&
  805. ht_cap->mcs.rx_mask[2] == 0) {
  806. need_multiple = false;
  807. } else if (!(ht_cap->mcs.tx_params &
  808. IEEE80211_HT_MCS_TX_DEFINED)) {
  809. /* If it can't TX MCS at all ... */
  810. need_multiple = false;
  811. } else if (ht_cap->mcs.tx_params &
  812. IEEE80211_HT_MCS_TX_RX_DIFF) {
  813. int maxstreams;
  814. /*
  815. * But if it can receive them, it might still not
  816. * be able to transmit them, which is what we need
  817. * to check here -- so check the number of streams
  818. * it advertises for TX (if different from RX).
  819. */
  820. maxstreams = (ht_cap->mcs.tx_params &
  821. IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK);
  822. maxstreams >>=
  823. IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
  824. maxstreams += 1;
  825. if (maxstreams <= 1)
  826. need_multiple = false;
  827. }
  828. rcu_read_unlock();
  829. break;
  830. case NL80211_IFTYPE_ADHOC:
  831. /* currently */
  832. need_multiple = false;
  833. break;
  834. default:
  835. /* only AP really */
  836. need_multiple = true;
  837. break;
  838. }
  839. ctx->ht_need_multiple_chains = need_multiple;
  840. if (!need_multiple) {
  841. /* check all contexts */
  842. for_each_context(priv, tmp) {
  843. if (!tmp->vif)
  844. continue;
  845. if (tmp->ht_need_multiple_chains) {
  846. need_multiple = true;
  847. break;
  848. }
  849. }
  850. }
  851. ht_conf->single_chain_sufficient = !need_multiple;
  852. }
  853. static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
  854. {
  855. struct iwl_chain_noise_data *data = &priv->chain_noise_data;
  856. int ret;
  857. if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
  858. iwl_is_any_associated(priv)) {
  859. struct iwl_calib_chain_noise_reset_cmd cmd;
  860. /* clear data for chain noise calibration algorithm */
  861. data->chain_noise_a = 0;
  862. data->chain_noise_b = 0;
  863. data->chain_noise_c = 0;
  864. data->chain_signal_a = 0;
  865. data->chain_signal_b = 0;
  866. data->chain_signal_c = 0;
  867. data->beacon_count = 0;
  868. memset(&cmd, 0, sizeof(cmd));
  869. iwl_set_calib_hdr(&cmd.hdr,
  870. priv->phy_calib_chain_noise_reset_cmd);
  871. ret = iwl_dvm_send_cmd_pdu(priv,
  872. REPLY_PHY_CALIBRATION_CMD,
  873. CMD_SYNC, sizeof(cmd), &cmd);
  874. if (ret)
  875. IWL_ERR(priv,
  876. "Could not send REPLY_PHY_CALIBRATION_CMD\n");
  877. data->state = IWL_CHAIN_NOISE_ACCUMULATE;
  878. IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
  879. }
  880. }
  881. void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
  882. struct ieee80211_vif *vif,
  883. struct ieee80211_bss_conf *bss_conf,
  884. u32 changes)
  885. {
  886. struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
  887. struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
  888. int ret;
  889. bool force = false;
  890. mutex_lock(&priv->mutex);
  891. if (unlikely(!iwl_is_ready(priv))) {
  892. IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
  893. mutex_unlock(&priv->mutex);
  894. return;
  895. }
  896. if (unlikely(!ctx->vif)) {
  897. IWL_DEBUG_MAC80211(priv, "leave - vif is NULL\n");
  898. mutex_unlock(&priv->mutex);
  899. return;
  900. }
  901. if (changes & BSS_CHANGED_BEACON_INT)
  902. force = true;
  903. if (changes & BSS_CHANGED_QOS) {
  904. ctx->qos_data.qos_active = bss_conf->qos;
  905. iwlagn_update_qos(priv, ctx);
  906. }
  907. ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
  908. if (vif->bss_conf.use_short_preamble)
  909. ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
  910. else
  911. ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
  912. if (changes & BSS_CHANGED_ASSOC) {
  913. if (bss_conf->assoc) {
  914. priv->timestamp = bss_conf->last_tsf;
  915. ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
  916. } else {
  917. /*
  918. * If we disassociate while there are pending
  919. * frames, just wake up the queues and let the
  920. * frames "escape" ... This shouldn't really
  921. * be happening to start with, but we should
  922. * not get stuck in this case either since it
  923. * can happen if userspace gets confused.
  924. */
  925. iwlagn_lift_passive_no_rx(priv);
  926. ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
  927. if (ctx->ctxid == IWL_RXON_CTX_BSS)
  928. priv->have_rekey_data = false;
  929. }
  930. iwlagn_bt_coex_rssi_monitor(priv);
  931. }
  932. if (ctx->ht.enabled) {
  933. ctx->ht.protection = bss_conf->ht_operation_mode &
  934. IEEE80211_HT_OP_MODE_PROTECTION;
  935. ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode &
  936. IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
  937. iwlagn_check_needed_chains(priv, ctx, bss_conf);
  938. iwl_set_rxon_ht(priv, &priv->current_ht_config);
  939. }
  940. iwlagn_set_rxon_chain(priv, ctx);
  941. if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
  942. ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
  943. else
  944. ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
  945. if (bss_conf->use_cts_prot)
  946. ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
  947. else
  948. ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
  949. memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
  950. if (vif->type == NL80211_IFTYPE_AP ||
  951. vif->type == NL80211_IFTYPE_ADHOC) {
  952. if (vif->bss_conf.enable_beacon) {
  953. ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
  954. priv->beacon_ctx = ctx;
  955. } else {
  956. ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
  957. priv->beacon_ctx = NULL;
  958. }
  959. }
  960. /*
  961. * If the ucode decides to do beacon filtering before
  962. * association, it will lose beacons that are needed
  963. * before sending frames out on passive channels. This
  964. * causes association failures on those channels. Enable
  965. * receiving beacons in such cases.
  966. */
  967. if (vif->type == NL80211_IFTYPE_STATION) {
  968. if (!bss_conf->assoc)
  969. ctx->staging.filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
  970. else
  971. ctx->staging.filter_flags &=
  972. ~RXON_FILTER_BCON_AWARE_MSK;
  973. }
  974. if (force || memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
  975. iwlagn_commit_rxon(priv, ctx);
  976. if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc) {
  977. /*
  978. * The chain noise calibration will enable PM upon
  979. * completion. If calibration has already been run
  980. * then we need to enable power management here.
  981. */
  982. if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
  983. iwl_power_update_mode(priv, false);
  984. /* Enable RX differential gain and sensitivity calibrations */
  985. if (!priv->disable_chain_noise_cal)
  986. iwlagn_chain_noise_reset(priv);
  987. priv->start_calib = 1;
  988. }
  989. if (changes & BSS_CHANGED_IBSS) {
  990. ret = iwlagn_manage_ibss_station(priv, vif,
  991. bss_conf->ibss_joined);
  992. if (ret)
  993. IWL_ERR(priv, "failed to %s IBSS station %pM\n",
  994. bss_conf->ibss_joined ? "add" : "remove",
  995. bss_conf->bssid);
  996. }
  997. if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_ADHOC &&
  998. priv->beacon_ctx) {
  999. if (iwlagn_update_beacon(priv, vif))
  1000. IWL_ERR(priv, "Error sending IBSS beacon\n");
  1001. }
  1002. mutex_unlock(&priv->mutex);
  1003. }
  1004. void iwlagn_post_scan(struct iwl_priv *priv)
  1005. {
  1006. struct iwl_rxon_context *ctx;
  1007. /*
  1008. * We do not commit power settings while scan is pending,
  1009. * do it now if the settings changed.
  1010. */
  1011. iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
  1012. iwl_set_tx_power(priv, priv->tx_power_next, false);
  1013. /*
  1014. * Since setting the RXON may have been deferred while
  1015. * performing the scan, fire one off if needed
  1016. */
  1017. for_each_context(priv, ctx)
  1018. if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
  1019. iwlagn_commit_rxon(priv, ctx);
  1020. iwlagn_set_pan_params(priv);
  1021. }