utils.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /******************************************************************************
  2. *
  3. * This file is provided under a dual BSD/GPLv2 license. When using or
  4. * redistributing this file, you may do so under either license.
  5. *
  6. * GPL LICENSE SUMMARY
  7. *
  8. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  9. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of version 2 of the GNU General Public License as
  13. * published by the Free Software Foundation.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  23. * USA
  24. *
  25. * The full GNU General Public License is included in this distribution
  26. * in the file called COPYING.
  27. *
  28. * Contact Information:
  29. * Intel Linux Wireless <ilw@linux.intel.com>
  30. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  31. *
  32. * BSD LICENSE
  33. *
  34. * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  35. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  36. * All rights reserved.
  37. *
  38. * Redistribution and use in source and binary forms, with or without
  39. * modification, are permitted provided that the following conditions
  40. * are met:
  41. *
  42. * * Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * * Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in
  46. * the documentation and/or other materials provided with the
  47. * distribution.
  48. * * Neither the name Intel Corporation nor the names of its
  49. * contributors may be used to endorse or promote products derived
  50. * from this software without specific prior written permission.
  51. *
  52. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  53. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  54. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  55. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  56. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  57. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  58. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  59. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  60. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  61. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  62. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63. *
  64. *****************************************************************************/
  65. #include <net/mac80211.h>
  66. #include "iwl-debug.h"
  67. #include "iwl-io.h"
  68. #include "iwl-prph.h"
  69. #include "mvm.h"
  70. #include "fw-api-rs.h"
  71. /*
  72. * Will return 0 even if the cmd failed when RFKILL is asserted unless
  73. * CMD_WANT_SKB is set in cmd->flags.
  74. */
  75. int iwl_mvm_send_cmd(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd)
  76. {
  77. int ret;
  78. #if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
  79. if (WARN_ON(mvm->d3_test_active))
  80. return -EIO;
  81. #endif
  82. /*
  83. * Synchronous commands from this op-mode must hold
  84. * the mutex, this ensures we don't try to send two
  85. * (or more) synchronous commands at a time.
  86. */
  87. if (!(cmd->flags & CMD_ASYNC))
  88. lockdep_assert_held(&mvm->mutex);
  89. ret = iwl_trans_send_cmd(mvm->trans, cmd);
  90. /*
  91. * If the caller wants the SKB, then don't hide any problems, the
  92. * caller might access the response buffer which will be NULL if
  93. * the command failed.
  94. */
  95. if (cmd->flags & CMD_WANT_SKB)
  96. return ret;
  97. /* Silently ignore failures if RFKILL is asserted */
  98. if (!ret || ret == -ERFKILL)
  99. return 0;
  100. return ret;
  101. }
  102. int iwl_mvm_send_cmd_pdu(struct iwl_mvm *mvm, u32 id,
  103. u32 flags, u16 len, const void *data)
  104. {
  105. struct iwl_host_cmd cmd = {
  106. .id = id,
  107. .len = { len, },
  108. .data = { data, },
  109. .flags = flags,
  110. };
  111. return iwl_mvm_send_cmd(mvm, &cmd);
  112. }
  113. /*
  114. * We assume that the caller set the status to the success value
  115. */
  116. int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
  117. u32 *status)
  118. {
  119. struct iwl_rx_packet *pkt;
  120. struct iwl_cmd_response *resp;
  121. int ret, resp_len;
  122. lockdep_assert_held(&mvm->mutex);
  123. #if defined(CONFIG_IWLWIFI_DEBUGFS) && defined(CONFIG_PM_SLEEP)
  124. if (WARN_ON(mvm->d3_test_active))
  125. return -EIO;
  126. #endif
  127. /*
  128. * Only synchronous commands can wait for status,
  129. * we use WANT_SKB so the caller can't.
  130. */
  131. if (WARN_ONCE(cmd->flags & (CMD_ASYNC | CMD_WANT_SKB),
  132. "cmd flags %x", cmd->flags))
  133. return -EINVAL;
  134. cmd->flags |= CMD_WANT_SKB;
  135. ret = iwl_trans_send_cmd(mvm->trans, cmd);
  136. if (ret == -ERFKILL) {
  137. /*
  138. * The command failed because of RFKILL, don't update
  139. * the status, leave it as success and return 0.
  140. */
  141. return 0;
  142. } else if (ret) {
  143. return ret;
  144. }
  145. pkt = cmd->resp_pkt;
  146. /* Can happen if RFKILL is asserted */
  147. if (!pkt) {
  148. ret = 0;
  149. goto out_free_resp;
  150. }
  151. resp_len = iwl_rx_packet_payload_len(pkt);
  152. if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
  153. ret = -EIO;
  154. goto out_free_resp;
  155. }
  156. resp = (void *)pkt->data;
  157. *status = le32_to_cpu(resp->status);
  158. out_free_resp:
  159. iwl_free_resp(cmd);
  160. return ret;
  161. }
  162. /*
  163. * We assume that the caller set the status to the sucess value
  164. */
  165. int iwl_mvm_send_cmd_pdu_status(struct iwl_mvm *mvm, u32 id, u16 len,
  166. const void *data, u32 *status)
  167. {
  168. struct iwl_host_cmd cmd = {
  169. .id = id,
  170. .len = { len, },
  171. .data = { data, },
  172. };
  173. return iwl_mvm_send_cmd_status(mvm, &cmd, status);
  174. }
  175. #define IWL_DECLARE_RATE_INFO(r) \
  176. [IWL_RATE_##r##M_INDEX] = IWL_RATE_##r##M_PLCP
  177. /*
  178. * Translate from fw_rate_index (IWL_RATE_XXM_INDEX) to PLCP
  179. */
  180. static const u8 fw_rate_idx_to_plcp[IWL_RATE_COUNT] = {
  181. IWL_DECLARE_RATE_INFO(1),
  182. IWL_DECLARE_RATE_INFO(2),
  183. IWL_DECLARE_RATE_INFO(5),
  184. IWL_DECLARE_RATE_INFO(11),
  185. IWL_DECLARE_RATE_INFO(6),
  186. IWL_DECLARE_RATE_INFO(9),
  187. IWL_DECLARE_RATE_INFO(12),
  188. IWL_DECLARE_RATE_INFO(18),
  189. IWL_DECLARE_RATE_INFO(24),
  190. IWL_DECLARE_RATE_INFO(36),
  191. IWL_DECLARE_RATE_INFO(48),
  192. IWL_DECLARE_RATE_INFO(54),
  193. };
  194. int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags,
  195. enum ieee80211_band band)
  196. {
  197. int rate = rate_n_flags & RATE_LEGACY_RATE_MSK;
  198. int idx;
  199. int band_offset = 0;
  200. /* Legacy rate format, search for match in table */
  201. if (band == IEEE80211_BAND_5GHZ)
  202. band_offset = IWL_FIRST_OFDM_RATE;
  203. for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
  204. if (fw_rate_idx_to_plcp[idx] == rate)
  205. return idx - band_offset;
  206. return -1;
  207. }
  208. u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx)
  209. {
  210. /* Get PLCP rate for tx_cmd->rate_n_flags */
  211. return fw_rate_idx_to_plcp[rate_idx];
  212. }
  213. void iwl_mvm_rx_fw_error(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
  214. {
  215. struct iwl_rx_packet *pkt = rxb_addr(rxb);
  216. struct iwl_error_resp *err_resp = (void *)pkt->data;
  217. IWL_ERR(mvm, "FW Error notification: type 0x%08X cmd_id 0x%02X\n",
  218. le32_to_cpu(err_resp->error_type), err_resp->cmd_id);
  219. IWL_ERR(mvm, "FW Error notification: seq 0x%04X service 0x%08X\n",
  220. le16_to_cpu(err_resp->bad_cmd_seq_num),
  221. le32_to_cpu(err_resp->error_service));
  222. IWL_ERR(mvm, "FW Error notification: timestamp 0x%16llX\n",
  223. le64_to_cpu(err_resp->timestamp));
  224. }
  225. /*
  226. * Returns the first antenna as ANT_[ABC], as defined in iwl-config.h.
  227. * The parameter should also be a combination of ANT_[ABC].
  228. */
  229. u8 first_antenna(u8 mask)
  230. {
  231. BUILD_BUG_ON(ANT_A != BIT(0)); /* using ffs is wrong if not */
  232. if (WARN_ON_ONCE(!mask)) /* ffs will return 0 if mask is zeroed */
  233. return BIT(0);
  234. return BIT(ffs(mask) - 1);
  235. }
  236. /*
  237. * Toggles between TX antennas to send the probe request on.
  238. * Receives the bitmask of valid TX antennas and the *index* used
  239. * for the last TX, and returns the next valid *index* to use.
  240. * In order to set it in the tx_cmd, must do BIT(idx).
  241. */
  242. u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx)
  243. {
  244. u8 ind = last_idx;
  245. int i;
  246. for (i = 0; i < RATE_MCS_ANT_NUM; i++) {
  247. ind = (ind + 1) % RATE_MCS_ANT_NUM;
  248. if (valid & BIT(ind))
  249. return ind;
  250. }
  251. WARN_ONCE(1, "Failed to toggle between antennas 0x%x", valid);
  252. return last_idx;
  253. }
  254. static const struct {
  255. const char *name;
  256. u8 num;
  257. } advanced_lookup[] = {
  258. { "NMI_INTERRUPT_WDG", 0x34 },
  259. { "SYSASSERT", 0x35 },
  260. { "UCODE_VERSION_MISMATCH", 0x37 },
  261. { "BAD_COMMAND", 0x38 },
  262. { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
  263. { "FATAL_ERROR", 0x3D },
  264. { "NMI_TRM_HW_ERR", 0x46 },
  265. { "NMI_INTERRUPT_TRM", 0x4C },
  266. { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
  267. { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
  268. { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
  269. { "NMI_INTERRUPT_HOST", 0x66 },
  270. { "NMI_INTERRUPT_ACTION_PT", 0x7C },
  271. { "NMI_INTERRUPT_UNKNOWN", 0x84 },
  272. { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
  273. { "ADVANCED_SYSASSERT", 0 },
  274. };
  275. static const char *desc_lookup(u32 num)
  276. {
  277. int i;
  278. for (i = 0; i < ARRAY_SIZE(advanced_lookup) - 1; i++)
  279. if (advanced_lookup[i].num == num)
  280. return advanced_lookup[i].name;
  281. /* No entry matches 'num', so it is the last: ADVANCED_SYSASSERT */
  282. return advanced_lookup[i].name;
  283. }
  284. /*
  285. * Note: This structure is read from the device with IO accesses,
  286. * and the reading already does the endian conversion. As it is
  287. * read with u32-sized accesses, any members with a different size
  288. * need to be ordered correctly though!
  289. */
  290. struct iwl_error_event_table_v1 {
  291. u32 valid; /* (nonzero) valid, (0) log is empty */
  292. u32 error_id; /* type of error */
  293. u32 pc; /* program counter */
  294. u32 blink1; /* branch link */
  295. u32 blink2; /* branch link */
  296. u32 ilink1; /* interrupt link */
  297. u32 ilink2; /* interrupt link */
  298. u32 data1; /* error-specific data */
  299. u32 data2; /* error-specific data */
  300. u32 data3; /* error-specific data */
  301. u32 bcon_time; /* beacon timer */
  302. u32 tsf_low; /* network timestamp function timer */
  303. u32 tsf_hi; /* network timestamp function timer */
  304. u32 gp1; /* GP1 timer register */
  305. u32 gp2; /* GP2 timer register */
  306. u32 gp3; /* GP3 timer register */
  307. u32 ucode_ver; /* uCode version */
  308. u32 hw_ver; /* HW Silicon version */
  309. u32 brd_ver; /* HW board version */
  310. u32 log_pc; /* log program counter */
  311. u32 frame_ptr; /* frame pointer */
  312. u32 stack_ptr; /* stack pointer */
  313. u32 hcmd; /* last host command header */
  314. u32 isr0; /* isr status register LMPM_NIC_ISR0:
  315. * rxtx_flag */
  316. u32 isr1; /* isr status register LMPM_NIC_ISR1:
  317. * host_flag */
  318. u32 isr2; /* isr status register LMPM_NIC_ISR2:
  319. * enc_flag */
  320. u32 isr3; /* isr status register LMPM_NIC_ISR3:
  321. * time_flag */
  322. u32 isr4; /* isr status register LMPM_NIC_ISR4:
  323. * wico interrupt */
  324. u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
  325. u32 wait_event; /* wait event() caller address */
  326. u32 l2p_control; /* L2pControlField */
  327. u32 l2p_duration; /* L2pDurationField */
  328. u32 l2p_mhvalid; /* L2pMhValidBits */
  329. u32 l2p_addr_match; /* L2pAddrMatchStat */
  330. u32 lmpm_pmg_sel; /* indicate which clocks are turned on
  331. * (LMPM_PMG_SEL) */
  332. u32 u_timestamp; /* indicate when the date and time of the
  333. * compilation */
  334. u32 flow_handler; /* FH read/write pointers, RX credit */
  335. } __packed /* LOG_ERROR_TABLE_API_S_VER_1 */;
  336. struct iwl_error_event_table {
  337. u32 valid; /* (nonzero) valid, (0) log is empty */
  338. u32 error_id; /* type of error */
  339. u32 pc; /* program counter */
  340. u32 blink1; /* branch link */
  341. u32 blink2; /* branch link */
  342. u32 ilink1; /* interrupt link */
  343. u32 ilink2; /* interrupt link */
  344. u32 data1; /* error-specific data */
  345. u32 data2; /* error-specific data */
  346. u32 data3; /* error-specific data */
  347. u32 bcon_time; /* beacon timer */
  348. u32 tsf_low; /* network timestamp function timer */
  349. u32 tsf_hi; /* network timestamp function timer */
  350. u32 gp1; /* GP1 timer register */
  351. u32 gp2; /* GP2 timer register */
  352. u32 gp3; /* GP3 timer register */
  353. u32 major; /* uCode version major */
  354. u32 minor; /* uCode version minor */
  355. u32 hw_ver; /* HW Silicon version */
  356. u32 brd_ver; /* HW board version */
  357. u32 log_pc; /* log program counter */
  358. u32 frame_ptr; /* frame pointer */
  359. u32 stack_ptr; /* stack pointer */
  360. u32 hcmd; /* last host command header */
  361. u32 isr0; /* isr status register LMPM_NIC_ISR0:
  362. * rxtx_flag */
  363. u32 isr1; /* isr status register LMPM_NIC_ISR1:
  364. * host_flag */
  365. u32 isr2; /* isr status register LMPM_NIC_ISR2:
  366. * enc_flag */
  367. u32 isr3; /* isr status register LMPM_NIC_ISR3:
  368. * time_flag */
  369. u32 isr4; /* isr status register LMPM_NIC_ISR4:
  370. * wico interrupt */
  371. u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
  372. u32 wait_event; /* wait event() caller address */
  373. u32 l2p_control; /* L2pControlField */
  374. u32 l2p_duration; /* L2pDurationField */
  375. u32 l2p_mhvalid; /* L2pMhValidBits */
  376. u32 l2p_addr_match; /* L2pAddrMatchStat */
  377. u32 lmpm_pmg_sel; /* indicate which clocks are turned on
  378. * (LMPM_PMG_SEL) */
  379. u32 u_timestamp; /* indicate when the date and time of the
  380. * compilation */
  381. u32 flow_handler; /* FH read/write pointers, RX credit */
  382. } __packed /* LOG_ERROR_TABLE_API_S_VER_2 */;
  383. /*
  384. * UMAC error struct - relevant starting from family 8000 chip.
  385. * Note: This structure is read from the device with IO accesses,
  386. * and the reading already does the endian conversion. As it is
  387. * read with u32-sized accesses, any members with a different size
  388. * need to be ordered correctly though!
  389. */
  390. struct iwl_umac_error_event_table {
  391. u32 valid; /* (nonzero) valid, (0) log is empty */
  392. u32 error_id; /* type of error */
  393. u32 blink1; /* branch link */
  394. u32 blink2; /* branch link */
  395. u32 ilink1; /* interrupt link */
  396. u32 ilink2; /* interrupt link */
  397. u32 data1; /* error-specific data */
  398. u32 data2; /* error-specific data */
  399. u32 data3; /* error-specific data */
  400. u32 umac_major;
  401. u32 umac_minor;
  402. u32 frame_pointer; /* core register 27*/
  403. u32 stack_pointer; /* core register 28 */
  404. u32 cmd_header; /* latest host cmd sent to UMAC */
  405. u32 nic_isr_pref; /* ISR status register */
  406. } __packed;
  407. #define ERROR_START_OFFSET (1 * sizeof(u32))
  408. #define ERROR_ELEM_SIZE (7 * sizeof(u32))
  409. static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
  410. {
  411. struct iwl_trans *trans = mvm->trans;
  412. struct iwl_umac_error_event_table table;
  413. u32 base;
  414. base = mvm->umac_error_event_table;
  415. if (base < 0x800000) {
  416. IWL_ERR(mvm,
  417. "Not valid error log pointer 0x%08X for %s uCode\n",
  418. base,
  419. (mvm->cur_ucode == IWL_UCODE_INIT)
  420. ? "Init" : "RT");
  421. return;
  422. }
  423. iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
  424. if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
  425. IWL_ERR(trans, "Start IWL Error Log Dump:\n");
  426. IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
  427. mvm->status, table.valid);
  428. }
  429. IWL_ERR(mvm, "0x%08X | %s\n", table.error_id,
  430. desc_lookup(table.error_id));
  431. IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1);
  432. IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2);
  433. IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1);
  434. IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2);
  435. IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
  436. IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
  437. IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
  438. IWL_ERR(mvm, "0x%08X | umac major\n", table.umac_major);
  439. IWL_ERR(mvm, "0x%08X | umac minor\n", table.umac_minor);
  440. IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
  441. IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
  442. IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
  443. IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
  444. }
  445. static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm)
  446. {
  447. struct iwl_trans *trans = mvm->trans;
  448. struct iwl_error_event_table_v1 table;
  449. u32 base;
  450. base = mvm->error_event_table;
  451. if (mvm->cur_ucode == IWL_UCODE_INIT) {
  452. if (!base)
  453. base = mvm->fw->init_errlog_ptr;
  454. } else {
  455. if (!base)
  456. base = mvm->fw->inst_errlog_ptr;
  457. }
  458. if (base < 0x800000) {
  459. IWL_ERR(mvm,
  460. "Not valid error log pointer 0x%08X for %s uCode\n",
  461. base,
  462. (mvm->cur_ucode == IWL_UCODE_INIT)
  463. ? "Init" : "RT");
  464. return;
  465. }
  466. iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
  467. if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
  468. IWL_ERR(trans, "Start IWL Error Log Dump:\n");
  469. IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
  470. mvm->status, table.valid);
  471. }
  472. /* Do not change this output - scripts rely on it */
  473. IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
  474. trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
  475. table.data1, table.data2, table.data3,
  476. table.blink1, table.blink2, table.ilink1,
  477. table.ilink2, table.bcon_time, table.gp1,
  478. table.gp2, table.gp3, table.ucode_ver, 0,
  479. table.hw_ver, table.brd_ver);
  480. IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
  481. desc_lookup(table.error_id));
  482. IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
  483. IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
  484. IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
  485. IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
  486. IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
  487. IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
  488. IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
  489. IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
  490. IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
  491. IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
  492. IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
  493. IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
  494. IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
  495. IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
  496. IWL_ERR(mvm, "0x%08X | uCode version\n", table.ucode_ver);
  497. IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
  498. IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
  499. IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
  500. IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
  501. IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
  502. IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
  503. IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
  504. IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
  505. IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
  506. IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
  507. IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
  508. IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
  509. IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
  510. IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
  511. IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
  512. IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
  513. IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
  514. if (mvm->support_umac_log)
  515. iwl_mvm_dump_umac_error_log(mvm);
  516. }
  517. void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
  518. {
  519. struct iwl_trans *trans = mvm->trans;
  520. struct iwl_error_event_table table;
  521. u32 base;
  522. if (!fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_NEW_VERSION)) {
  523. iwl_mvm_dump_nic_error_log_old(mvm);
  524. return;
  525. }
  526. base = mvm->error_event_table;
  527. if (mvm->cur_ucode == IWL_UCODE_INIT) {
  528. if (!base)
  529. base = mvm->fw->init_errlog_ptr;
  530. } else {
  531. if (!base)
  532. base = mvm->fw->inst_errlog_ptr;
  533. }
  534. if (base < 0x800000) {
  535. IWL_ERR(mvm,
  536. "Not valid error log pointer 0x%08X for %s uCode\n",
  537. base,
  538. (mvm->cur_ucode == IWL_UCODE_INIT)
  539. ? "Init" : "RT");
  540. return;
  541. }
  542. iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
  543. if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
  544. IWL_ERR(trans, "Start IWL Error Log Dump:\n");
  545. IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
  546. mvm->status, table.valid);
  547. }
  548. /* Do not change this output - scripts rely on it */
  549. IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
  550. trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
  551. table.data1, table.data2, table.data3,
  552. table.blink1, table.blink2, table.ilink1,
  553. table.ilink2, table.bcon_time, table.gp1,
  554. table.gp2, table.gp3, table.major,
  555. table.minor, table.hw_ver, table.brd_ver);
  556. IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
  557. desc_lookup(table.error_id));
  558. IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
  559. IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
  560. IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
  561. IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
  562. IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
  563. IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
  564. IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
  565. IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
  566. IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
  567. IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
  568. IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
  569. IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
  570. IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
  571. IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
  572. IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major);
  573. IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor);
  574. IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
  575. IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
  576. IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
  577. IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
  578. IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
  579. IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
  580. IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
  581. IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
  582. IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
  583. IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
  584. IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
  585. IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
  586. IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
  587. IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
  588. IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
  589. IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
  590. IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
  591. if (mvm->support_umac_log)
  592. iwl_mvm_dump_umac_error_log(mvm);
  593. }
  594. void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
  595. const struct iwl_trans_txq_scd_cfg *cfg,
  596. unsigned int wdg_timeout)
  597. {
  598. struct iwl_scd_txq_cfg_cmd cmd = {
  599. .scd_queue = queue,
  600. .enable = 1,
  601. .window = cfg->frame_limit,
  602. .sta_id = cfg->sta_id,
  603. .ssn = cpu_to_le16(ssn),
  604. .tx_fifo = cfg->fifo,
  605. .aggregate = cfg->aggregate,
  606. .tid = cfg->tid,
  607. };
  608. if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
  609. iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg,
  610. wdg_timeout);
  611. return;
  612. }
  613. iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
  614. WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
  615. "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo);
  616. }
  617. void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags)
  618. {
  619. struct iwl_scd_txq_cfg_cmd cmd = {
  620. .scd_queue = queue,
  621. .enable = 0,
  622. };
  623. int ret;
  624. if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
  625. iwl_trans_txq_disable(mvm->trans, queue, true);
  626. return;
  627. }
  628. iwl_trans_txq_disable(mvm->trans, queue, false);
  629. ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags,
  630. sizeof(cmd), &cmd);
  631. if (ret)
  632. IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
  633. queue, ret);
  634. }
  635. /**
  636. * iwl_mvm_send_lq_cmd() - Send link quality command
  637. * @init: This command is sent as part of station initialization right
  638. * after station has been added.
  639. *
  640. * The link quality command is sent as the last step of station creation.
  641. * This is the special case in which init is set and we call a callback in
  642. * this case to clear the state indicating that station creation is in
  643. * progress.
  644. */
  645. int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
  646. {
  647. struct iwl_host_cmd cmd = {
  648. .id = LQ_CMD,
  649. .len = { sizeof(struct iwl_lq_cmd), },
  650. .flags = init ? 0 : CMD_ASYNC,
  651. .data = { lq, },
  652. };
  653. if (WARN_ON(lq->sta_id == IWL_MVM_STATION_COUNT))
  654. return -EINVAL;
  655. return iwl_mvm_send_cmd(mvm, &cmd);
  656. }
  657. /**
  658. * iwl_mvm_update_smps - Get a request to change the SMPS mode
  659. * @req_type: The part of the driver who call for a change.
  660. * @smps_requests: The request to change the SMPS mode.
  661. *
  662. * Get a requst to change the SMPS mode,
  663. * and change it according to all other requests in the driver.
  664. */
  665. void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  666. enum iwl_mvm_smps_type_request req_type,
  667. enum ieee80211_smps_mode smps_request)
  668. {
  669. struct iwl_mvm_vif *mvmvif;
  670. enum ieee80211_smps_mode smps_mode;
  671. int i;
  672. lockdep_assert_held(&mvm->mutex);
  673. /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
  674. if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
  675. return;
  676. if (vif->type == NL80211_IFTYPE_AP)
  677. smps_mode = IEEE80211_SMPS_OFF;
  678. else
  679. smps_mode = IEEE80211_SMPS_AUTOMATIC;
  680. mvmvif = iwl_mvm_vif_from_mac80211(vif);
  681. mvmvif->smps_requests[req_type] = smps_request;
  682. for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
  683. if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC) {
  684. smps_mode = IEEE80211_SMPS_STATIC;
  685. break;
  686. }
  687. if (mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
  688. smps_mode = IEEE80211_SMPS_DYNAMIC;
  689. }
  690. ieee80211_request_smps(vif, smps_mode);
  691. }
  692. int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear)
  693. {
  694. struct iwl_statistics_cmd scmd = {
  695. .flags = clear ? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR) : 0,
  696. };
  697. struct iwl_host_cmd cmd = {
  698. .id = STATISTICS_CMD,
  699. .len[0] = sizeof(scmd),
  700. .data[0] = &scmd,
  701. .flags = CMD_WANT_SKB,
  702. };
  703. int ret;
  704. ret = iwl_mvm_send_cmd(mvm, &cmd);
  705. if (ret)
  706. return ret;
  707. iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt);
  708. iwl_free_resp(&cmd);
  709. if (clear)
  710. iwl_mvm_accu_radio_stats(mvm);
  711. return 0;
  712. }
  713. void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm)
  714. {
  715. mvm->accu_radio_stats.rx_time += mvm->radio_stats.rx_time;
  716. mvm->accu_radio_stats.tx_time += mvm->radio_stats.tx_time;
  717. mvm->accu_radio_stats.on_time_rf += mvm->radio_stats.on_time_rf;
  718. mvm->accu_radio_stats.on_time_scan += mvm->radio_stats.on_time_scan;
  719. }
  720. static void iwl_mvm_diversity_iter(void *_data, u8 *mac,
  721. struct ieee80211_vif *vif)
  722. {
  723. struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  724. bool *result = _data;
  725. int i;
  726. for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
  727. if (mvmvif->smps_requests[i] == IEEE80211_SMPS_STATIC ||
  728. mvmvif->smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
  729. *result = false;
  730. }
  731. }
  732. bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
  733. {
  734. bool result = true;
  735. lockdep_assert_held(&mvm->mutex);
  736. if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
  737. return false;
  738. if (mvm->cfg->rx_with_siso_diversity)
  739. return false;
  740. ieee80211_iterate_active_interfaces_atomic(
  741. mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
  742. iwl_mvm_diversity_iter, &result);
  743. return result;
  744. }
  745. int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  746. bool value)
  747. {
  748. struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  749. int res;
  750. lockdep_assert_held(&mvm->mutex);
  751. if (mvmvif->low_latency == value)
  752. return 0;
  753. mvmvif->low_latency = value;
  754. res = iwl_mvm_update_quotas(mvm, false, NULL);
  755. if (res)
  756. return res;
  757. iwl_mvm_bt_coex_vif_change(mvm);
  758. return iwl_mvm_power_update_mac(mvm);
  759. }
  760. static void iwl_mvm_ll_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
  761. {
  762. bool *result = _data;
  763. if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(vif)))
  764. *result = true;
  765. }
  766. bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
  767. {
  768. bool result = false;
  769. ieee80211_iterate_active_interfaces_atomic(
  770. mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
  771. iwl_mvm_ll_iter, &result);
  772. return result;
  773. }
  774. struct iwl_bss_iter_data {
  775. struct ieee80211_vif *vif;
  776. bool error;
  777. };
  778. static void iwl_mvm_bss_iface_iterator(void *_data, u8 *mac,
  779. struct ieee80211_vif *vif)
  780. {
  781. struct iwl_bss_iter_data *data = _data;
  782. if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
  783. return;
  784. if (data->vif) {
  785. data->error = true;
  786. return;
  787. }
  788. data->vif = vif;
  789. }
  790. struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm)
  791. {
  792. struct iwl_bss_iter_data bss_iter_data = {};
  793. ieee80211_iterate_active_interfaces_atomic(
  794. mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
  795. iwl_mvm_bss_iface_iterator, &bss_iter_data);
  796. if (bss_iter_data.error) {
  797. IWL_ERR(mvm, "More than one managed interface active!\n");
  798. return ERR_PTR(-EINVAL);
  799. }
  800. return bss_iter_data.vif;
  801. }
  802. unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
  803. struct ieee80211_vif *vif,
  804. bool tdls, bool cmd_q)
  805. {
  806. struct iwl_fw_dbg_trigger_tlv *trigger;
  807. struct iwl_fw_dbg_trigger_txq_timer *txq_timer;
  808. unsigned int default_timeout =
  809. cmd_q ? IWL_DEF_WD_TIMEOUT : mvm->cfg->base_params->wd_timeout;
  810. if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS))
  811. return iwlmvm_mod_params.tfd_q_hang_detect ?
  812. default_timeout : IWL_WATCHDOG_DISABLED;
  813. trigger = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_TXQ_TIMERS);
  814. txq_timer = (void *)trigger->data;
  815. if (tdls)
  816. return le32_to_cpu(txq_timer->tdls);
  817. if (cmd_q)
  818. return le32_to_cpu(txq_timer->command_queue);
  819. if (WARN_ON(!vif))
  820. return default_timeout;
  821. switch (ieee80211_vif_type_p2p(vif)) {
  822. case NL80211_IFTYPE_ADHOC:
  823. return le32_to_cpu(txq_timer->ibss);
  824. case NL80211_IFTYPE_STATION:
  825. return le32_to_cpu(txq_timer->bss);
  826. case NL80211_IFTYPE_AP:
  827. return le32_to_cpu(txq_timer->softap);
  828. case NL80211_IFTYPE_P2P_CLIENT:
  829. return le32_to_cpu(txq_timer->p2p_client);
  830. case NL80211_IFTYPE_P2P_GO:
  831. return le32_to_cpu(txq_timer->p2p_go);
  832. case NL80211_IFTYPE_P2P_DEVICE:
  833. return le32_to_cpu(txq_timer->p2p_device);
  834. default:
  835. WARN_ON(1);
  836. return mvm->cfg->base_params->wd_timeout;
  837. }
  838. }
  839. void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  840. const char *errmsg)
  841. {
  842. struct iwl_fw_dbg_trigger_tlv *trig;
  843. struct iwl_fw_dbg_trigger_mlme *trig_mlme;
  844. if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME))
  845. goto out;
  846. trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME);
  847. trig_mlme = (void *)trig->data;
  848. if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig))
  849. goto out;
  850. if (trig_mlme->stop_connection_loss &&
  851. --trig_mlme->stop_connection_loss)
  852. goto out;
  853. iwl_mvm_fw_dbg_collect_trig(mvm, trig, "%s", errmsg);
  854. out:
  855. ieee80211_connection_loss(vif);
  856. }