iwl-testmode.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  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) 2010 - 2011 Intel Corporation. All rights reserved.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of version 2 of the GNU General Public License as
  12. * published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful, but
  15. * WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  22. * USA
  23. *
  24. * The full GNU General Public License is included in this distribution
  25. * in the file called LICENSE.GPL.
  26. *
  27. * Contact Information:
  28. * Intel Linux Wireless <ilw@linux.intel.com>
  29. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  30. *
  31. * BSD LICENSE
  32. *
  33. * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
  34. * All rights reserved.
  35. *
  36. * Redistribution and use in source and binary forms, with or without
  37. * modification, are permitted provided that the following conditions
  38. * are met:
  39. *
  40. * * Redistributions of source code must retain the above copyright
  41. * notice, this list of conditions and the following disclaimer.
  42. * * Redistributions in binary form must reproduce the above copyright
  43. * notice, this list of conditions and the following disclaimer in
  44. * the documentation and/or other materials provided with the
  45. * distribution.
  46. * * Neither the name Intel Corporation nor the names of its
  47. * contributors may be used to endorse or promote products derived
  48. * from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  51. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  52. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  53. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  54. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  55. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  56. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  57. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  58. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  60. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61. *
  62. *****************************************************************************/
  63. #include <linux/init.h>
  64. #include <linux/kernel.h>
  65. #include <linux/module.h>
  66. #include <linux/dma-mapping.h>
  67. #include <net/net_namespace.h>
  68. #include <linux/netdevice.h>
  69. #include <net/cfg80211.h>
  70. #include <net/mac80211.h>
  71. #include <net/netlink.h>
  72. #include "iwl-wifi.h"
  73. #include "iwl-dev.h"
  74. #include "iwl-core.h"
  75. #include "iwl-debug.h"
  76. #include "iwl-io.h"
  77. #include "iwl-agn.h"
  78. #include "iwl-testmode.h"
  79. #include "iwl-trans.h"
  80. #include "iwl-bus.h"
  81. /* The TLVs used in the gnl message policy between the kernel module and
  82. * user space application. iwl_testmode_gnl_msg_policy is to be carried
  83. * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
  84. * See iwl-testmode.h
  85. */
  86. static
  87. struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
  88. [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
  89. [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
  90. [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
  91. [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
  92. [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
  93. [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
  94. [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
  95. [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
  96. [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
  97. [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
  98. [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
  99. [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
  100. [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
  101. [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
  102. [IWL_TM_ATTR_SRAM_ADDR] = { .type = NLA_U32, },
  103. [IWL_TM_ATTR_SRAM_SIZE] = { .type = NLA_U32, },
  104. [IWL_TM_ATTR_SRAM_DUMP] = { .type = NLA_UNSPEC, },
  105. [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
  106. [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
  107. };
  108. /*
  109. * See the struct iwl_rx_packet in iwl-commands.h for the format of the
  110. * received events from the device
  111. */
  112. static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
  113. {
  114. struct iwl_rx_packet *pkt = rxb_addr(rxb);
  115. if (pkt)
  116. return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
  117. else
  118. return 0;
  119. }
  120. /*
  121. * This function multicasts the spontaneous messages from the device to the
  122. * user space. It is invoked whenever there is a received messages
  123. * from the device. This function is called within the ISR of the rx handlers
  124. * in iwlagn driver.
  125. *
  126. * The parsing of the message content is left to the user space application,
  127. * The message content is treated as unattacked raw data and is encapsulated
  128. * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
  129. *
  130. * @priv: the instance of iwlwifi device
  131. * @rxb: pointer to rx data content received by the ISR
  132. *
  133. * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
  134. * For the messages multicasting to the user application, the mandatory
  135. * TLV fields are :
  136. * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
  137. * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
  138. */
  139. static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
  140. struct iwl_rx_mem_buffer *rxb)
  141. {
  142. struct ieee80211_hw *hw = priv->hw;
  143. struct sk_buff *skb;
  144. void *data;
  145. int length;
  146. data = (void *)rxb_addr(rxb);
  147. length = get_event_length(rxb);
  148. if (!data || length == 0)
  149. return;
  150. skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
  151. GFP_ATOMIC);
  152. if (skb == NULL) {
  153. IWL_DEBUG_INFO(priv,
  154. "Run out of memory for messages to user space ?\n");
  155. return;
  156. }
  157. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
  158. NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
  159. cfg80211_testmode_event(skb, GFP_ATOMIC);
  160. return;
  161. nla_put_failure:
  162. kfree_skb(skb);
  163. IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
  164. }
  165. void iwl_testmode_init(struct iwl_priv *priv)
  166. {
  167. priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
  168. priv->testmode_trace.trace_enabled = false;
  169. priv->testmode_sram.sram_readed = false;
  170. }
  171. static void iwl_sram_cleanup(struct iwl_priv *priv)
  172. {
  173. if (priv->testmode_sram.sram_readed) {
  174. kfree(priv->testmode_sram.buff_addr);
  175. priv->testmode_sram.buff_addr = NULL;
  176. priv->testmode_sram.buff_size = 0;
  177. priv->testmode_sram.num_chunks = 0;
  178. priv->testmode_sram.sram_readed = false;
  179. }
  180. }
  181. static void iwl_trace_cleanup(struct iwl_priv *priv)
  182. {
  183. if (priv->testmode_trace.trace_enabled) {
  184. if (priv->testmode_trace.cpu_addr &&
  185. priv->testmode_trace.dma_addr)
  186. dma_free_coherent(bus(priv)->dev,
  187. priv->testmode_trace.total_size,
  188. priv->testmode_trace.cpu_addr,
  189. priv->testmode_trace.dma_addr);
  190. priv->testmode_trace.trace_enabled = false;
  191. priv->testmode_trace.cpu_addr = NULL;
  192. priv->testmode_trace.trace_addr = NULL;
  193. priv->testmode_trace.dma_addr = 0;
  194. priv->testmode_trace.buff_size = 0;
  195. priv->testmode_trace.total_size = 0;
  196. }
  197. }
  198. void iwl_testmode_cleanup(struct iwl_priv *priv)
  199. {
  200. iwl_trace_cleanup(priv);
  201. iwl_sram_cleanup(priv);
  202. }
  203. /*
  204. * This function handles the user application commands to the ucode.
  205. *
  206. * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
  207. * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
  208. * host command to the ucode.
  209. *
  210. * If any mandatory field is missing, -ENOMSG is replied to the user space
  211. * application; otherwise, the actual execution result of the host command to
  212. * ucode is replied.
  213. *
  214. * @hw: ieee80211_hw object that represents the device
  215. * @tb: gnl message fields from the user space
  216. */
  217. static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
  218. {
  219. struct iwl_priv *priv = hw->priv;
  220. struct iwl_host_cmd cmd;
  221. memset(&cmd, 0, sizeof(struct iwl_host_cmd));
  222. if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
  223. !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
  224. IWL_DEBUG_INFO(priv,
  225. "Error finding ucode command mandatory fields\n");
  226. return -ENOMSG;
  227. }
  228. cmd.flags = CMD_ON_DEMAND;
  229. cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
  230. cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
  231. cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
  232. cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
  233. IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
  234. " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
  235. /* ok, let's submit the command to ucode */
  236. return iwl_trans_send_cmd(trans(priv), &cmd);
  237. }
  238. /*
  239. * This function handles the user application commands for register access.
  240. *
  241. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  242. * handlers respectively.
  243. *
  244. * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
  245. * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
  246. * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
  247. * the success of the command execution.
  248. *
  249. * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
  250. * value is returned with IWL_TM_ATTR_REG_VALUE32.
  251. *
  252. * @hw: ieee80211_hw object that represents the device
  253. * @tb: gnl message fields from the user space
  254. */
  255. static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
  256. {
  257. struct iwl_priv *priv = hw->priv;
  258. u32 ofs, val32;
  259. u8 val8;
  260. struct sk_buff *skb;
  261. int status = 0;
  262. if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
  263. IWL_DEBUG_INFO(priv, "Error finding register offset\n");
  264. return -ENOMSG;
  265. }
  266. ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
  267. IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
  268. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  269. case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
  270. val32 = iwl_read32(bus(priv), ofs);
  271. IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
  272. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  273. if (!skb) {
  274. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  275. return -ENOMEM;
  276. }
  277. NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
  278. status = cfg80211_testmode_reply(skb);
  279. if (status < 0)
  280. IWL_DEBUG_INFO(priv,
  281. "Error sending msg : %d\n", status);
  282. break;
  283. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
  284. if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
  285. IWL_DEBUG_INFO(priv,
  286. "Error finding value to write\n");
  287. return -ENOMSG;
  288. } else {
  289. val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
  290. IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
  291. iwl_write32(bus(priv), ofs, val32);
  292. }
  293. break;
  294. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
  295. if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
  296. IWL_DEBUG_INFO(priv, "Error finding value to write\n");
  297. return -ENOMSG;
  298. } else {
  299. val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
  300. IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
  301. iwl_write8(bus(priv), ofs, val8);
  302. }
  303. break;
  304. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
  305. val32 = iwl_read_prph(bus(priv), ofs);
  306. IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
  307. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  308. if (!skb) {
  309. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  310. return -ENOMEM;
  311. }
  312. NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
  313. status = cfg80211_testmode_reply(skb);
  314. if (status < 0)
  315. IWL_DEBUG_INFO(priv,
  316. "Error sending msg : %d\n", status);
  317. break;
  318. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
  319. if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
  320. IWL_DEBUG_INFO(priv,
  321. "Error finding value to write\n");
  322. return -ENOMSG;
  323. } else {
  324. val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
  325. IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
  326. iwl_write_prph(bus(priv), ofs, val32);
  327. }
  328. break;
  329. default:
  330. IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
  331. return -ENOSYS;
  332. }
  333. return status;
  334. nla_put_failure:
  335. kfree_skb(skb);
  336. return -EMSGSIZE;
  337. }
  338. static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
  339. {
  340. struct iwl_notification_wait calib_wait;
  341. int ret;
  342. iwl_init_notification_wait(priv->shrd, &calib_wait,
  343. CALIBRATION_COMPLETE_NOTIFICATION,
  344. NULL, NULL);
  345. ret = iwl_init_alive_start(trans(priv));
  346. if (ret) {
  347. IWL_DEBUG_INFO(priv,
  348. "Error configuring init calibration: %d\n", ret);
  349. goto cfg_init_calib_error;
  350. }
  351. ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
  352. if (ret)
  353. IWL_DEBUG_INFO(priv, "Error detecting"
  354. " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
  355. return ret;
  356. cfg_init_calib_error:
  357. iwl_remove_notification(priv->shrd, &calib_wait);
  358. return ret;
  359. }
  360. /*
  361. * This function handles the user application commands for driver.
  362. *
  363. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  364. * handlers respectively.
  365. *
  366. * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
  367. * value of the actual command execution is replied to the user application.
  368. *
  369. * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
  370. * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
  371. * IWL_TM_CMD_DEV2APP_SYNC_RSP.
  372. *
  373. * @hw: ieee80211_hw object that represents the device
  374. * @tb: gnl message fields from the user space
  375. */
  376. static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
  377. {
  378. struct iwl_priv *priv = hw->priv;
  379. struct iwl_trans *trans = trans(priv);
  380. struct sk_buff *skb;
  381. unsigned char *rsp_data_ptr = NULL;
  382. int status = 0, rsp_data_len = 0;
  383. char buf[32], *ptr = NULL;
  384. unsigned int num, devid;
  385. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  386. case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
  387. rsp_data_ptr = (unsigned char *)cfg(priv)->name;
  388. rsp_data_len = strlen(cfg(priv)->name);
  389. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  390. rsp_data_len + 20);
  391. if (!skb) {
  392. IWL_DEBUG_INFO(priv,
  393. "Error allocating memory\n");
  394. return -ENOMEM;
  395. }
  396. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
  397. IWL_TM_CMD_DEV2APP_SYNC_RSP);
  398. NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
  399. rsp_data_len, rsp_data_ptr);
  400. status = cfg80211_testmode_reply(skb);
  401. if (status < 0)
  402. IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
  403. status);
  404. break;
  405. case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
  406. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
  407. if (status)
  408. IWL_DEBUG_INFO(priv,
  409. "Error loading init ucode: %d\n", status);
  410. break;
  411. case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
  412. iwl_testmode_cfg_init_calib(priv);
  413. iwl_trans_stop_device(trans);
  414. break;
  415. case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
  416. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
  417. if (status) {
  418. IWL_DEBUG_INFO(priv,
  419. "Error loading runtime ucode: %d\n", status);
  420. break;
  421. }
  422. status = iwl_alive_start(priv);
  423. if (status)
  424. IWL_DEBUG_INFO(priv,
  425. "Error starting the device: %d\n", status);
  426. break;
  427. case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
  428. iwl_scan_cancel_timeout(priv, 200);
  429. iwl_trans_stop_device(trans);
  430. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
  431. if (status) {
  432. IWL_DEBUG_INFO(priv,
  433. "Error loading WOWLAN ucode: %d\n", status);
  434. break;
  435. }
  436. status = iwl_alive_start(priv);
  437. if (status)
  438. IWL_DEBUG_INFO(priv,
  439. "Error starting the device: %d\n", status);
  440. break;
  441. case IWL_TM_CMD_APP2DEV_GET_EEPROM:
  442. if (priv->shrd->eeprom) {
  443. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  444. cfg(priv)->base_params->eeprom_size + 20);
  445. if (!skb) {
  446. IWL_DEBUG_INFO(priv,
  447. "Error allocating memory\n");
  448. return -ENOMEM;
  449. }
  450. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
  451. IWL_TM_CMD_DEV2APP_EEPROM_RSP);
  452. NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
  453. cfg(priv)->base_params->eeprom_size,
  454. priv->shrd->eeprom);
  455. status = cfg80211_testmode_reply(skb);
  456. if (status < 0)
  457. IWL_DEBUG_INFO(priv,
  458. "Error sending msg : %d\n",
  459. status);
  460. } else
  461. return -EFAULT;
  462. break;
  463. case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
  464. if (!tb[IWL_TM_ATTR_FIXRATE]) {
  465. IWL_DEBUG_INFO(priv,
  466. "Error finding fixrate setting\n");
  467. return -ENOMSG;
  468. }
  469. priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
  470. break;
  471. case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
  472. IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver);
  473. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  474. if (!skb) {
  475. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  476. return -ENOMEM;
  477. }
  478. NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver);
  479. status = cfg80211_testmode_reply(skb);
  480. if (status < 0)
  481. IWL_DEBUG_INFO(priv,
  482. "Error sending msg : %d\n", status);
  483. break;
  484. case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
  485. bus_get_hw_id(bus(priv), buf, sizeof(buf));
  486. ptr = buf;
  487. strsep(&ptr, ":");
  488. sscanf(strsep(&ptr, ":"), "%x", &num);
  489. sscanf(strsep(&ptr, ":"), "%x", &devid);
  490. IWL_INFO(priv, "Device ID = 0x%04x, SubDevice ID= 0x%04x\n",
  491. num, devid);
  492. devid |= (num << 16);
  493. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  494. if (!skb) {
  495. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  496. return -ENOMEM;
  497. }
  498. NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
  499. status = cfg80211_testmode_reply(skb);
  500. if (status < 0)
  501. IWL_DEBUG_INFO(priv,
  502. "Error sending msg : %d\n", status);
  503. break;
  504. default:
  505. IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
  506. return -ENOSYS;
  507. }
  508. return status;
  509. nla_put_failure:
  510. kfree_skb(skb);
  511. return -EMSGSIZE;
  512. }
  513. /*
  514. * This function handles the user application commands for uCode trace
  515. *
  516. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  517. * handlers respectively.
  518. *
  519. * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
  520. * value of the actual command execution is replied to the user application.
  521. *
  522. * @hw: ieee80211_hw object that represents the device
  523. * @tb: gnl message fields from the user space
  524. */
  525. static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
  526. {
  527. struct iwl_priv *priv = hw->priv;
  528. struct sk_buff *skb;
  529. int status = 0;
  530. struct device *dev = bus(priv)->dev;
  531. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  532. case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
  533. if (priv->testmode_trace.trace_enabled)
  534. return -EBUSY;
  535. if (!tb[IWL_TM_ATTR_TRACE_SIZE])
  536. priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF;
  537. else
  538. priv->testmode_trace.buff_size =
  539. nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
  540. if (!priv->testmode_trace.buff_size)
  541. return -EINVAL;
  542. if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN ||
  543. priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX)
  544. return -EINVAL;
  545. priv->testmode_trace.total_size =
  546. priv->testmode_trace.buff_size + TRACE_BUFF_PADD;
  547. priv->testmode_trace.cpu_addr =
  548. dma_alloc_coherent(dev,
  549. priv->testmode_trace.total_size,
  550. &priv->testmode_trace.dma_addr,
  551. GFP_KERNEL);
  552. if (!priv->testmode_trace.cpu_addr)
  553. return -ENOMEM;
  554. priv->testmode_trace.trace_enabled = true;
  555. priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
  556. priv->testmode_trace.cpu_addr, 0x100);
  557. memset(priv->testmode_trace.trace_addr, 0x03B,
  558. priv->testmode_trace.buff_size);
  559. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  560. sizeof(priv->testmode_trace.dma_addr) + 20);
  561. if (!skb) {
  562. IWL_DEBUG_INFO(priv,
  563. "Error allocating memory\n");
  564. iwl_trace_cleanup(priv);
  565. return -ENOMEM;
  566. }
  567. NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
  568. sizeof(priv->testmode_trace.dma_addr),
  569. (u64 *)&priv->testmode_trace.dma_addr);
  570. status = cfg80211_testmode_reply(skb);
  571. if (status < 0) {
  572. IWL_DEBUG_INFO(priv,
  573. "Error sending msg : %d\n",
  574. status);
  575. }
  576. priv->testmode_trace.num_chunks =
  577. DIV_ROUND_UP(priv->testmode_trace.buff_size,
  578. DUMP_CHUNK_SIZE);
  579. break;
  580. case IWL_TM_CMD_APP2DEV_END_TRACE:
  581. iwl_trace_cleanup(priv);
  582. break;
  583. default:
  584. IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
  585. return -ENOSYS;
  586. }
  587. return status;
  588. nla_put_failure:
  589. kfree_skb(skb);
  590. if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
  591. IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
  592. iwl_trace_cleanup(priv);
  593. return -EMSGSIZE;
  594. }
  595. static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  596. struct sk_buff *skb,
  597. struct netlink_callback *cb)
  598. {
  599. struct iwl_priv *priv = hw->priv;
  600. int idx, length;
  601. if (priv->testmode_trace.trace_enabled &&
  602. priv->testmode_trace.trace_addr) {
  603. idx = cb->args[4];
  604. if (idx >= priv->testmode_trace.num_chunks)
  605. return -ENOENT;
  606. length = DUMP_CHUNK_SIZE;
  607. if (((idx + 1) == priv->testmode_trace.num_chunks) &&
  608. (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE))
  609. length = priv->testmode_trace.buff_size %
  610. DUMP_CHUNK_SIZE;
  611. NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length,
  612. priv->testmode_trace.trace_addr +
  613. (DUMP_CHUNK_SIZE * idx));
  614. idx++;
  615. cb->args[4] = idx;
  616. return 0;
  617. } else
  618. return -EFAULT;
  619. nla_put_failure:
  620. return -ENOBUFS;
  621. }
  622. /*
  623. * This function handles the user application switch ucode ownership.
  624. *
  625. * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
  626. * decide who the current owner of the uCode
  627. *
  628. * If the current owner is OWNERSHIP_TM, then the only host command
  629. * can deliver to uCode is from testmode, all the other host commands
  630. * will dropped.
  631. *
  632. * default driver is the owner of uCode in normal operational mode
  633. *
  634. * @hw: ieee80211_hw object that represents the device
  635. * @tb: gnl message fields from the user space
  636. */
  637. static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
  638. {
  639. struct iwl_priv *priv = hw->priv;
  640. u8 owner;
  641. if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
  642. IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
  643. return -ENOMSG;
  644. }
  645. owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
  646. if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
  647. priv->shrd->ucode_owner = owner;
  648. else {
  649. IWL_DEBUG_INFO(priv, "Invalid owner\n");
  650. return -EINVAL;
  651. }
  652. return 0;
  653. }
  654. /*
  655. * This function handles the user application commands for SRAM data dump
  656. *
  657. * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and
  658. * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading
  659. *
  660. * Several error will be retured, -EBUSY if the SRAM data retrieved by
  661. * previous command has not been delivered to userspace, or -ENOMSG if
  662. * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE)
  663. * are missing, or -ENOMEM if the buffer allocation fails.
  664. *
  665. * Otherwise 0 is replied indicating the success of the SRAM reading.
  666. *
  667. * @hw: ieee80211_hw object that represents the device
  668. * @tb: gnl message fields from the user space
  669. */
  670. static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
  671. {
  672. struct iwl_priv *priv = hw->priv;
  673. u32 base, ofs, size, maxsize;
  674. if (priv->testmode_sram.sram_readed)
  675. return -EBUSY;
  676. if (!tb[IWL_TM_ATTR_SRAM_ADDR]) {
  677. IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n");
  678. return -ENOMSG;
  679. }
  680. ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]);
  681. if (!tb[IWL_TM_ATTR_SRAM_SIZE]) {
  682. IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n");
  683. return -ENOMSG;
  684. }
  685. size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
  686. switch (priv->shrd->ucode_type) {
  687. case IWL_UCODE_REGULAR:
  688. maxsize = trans(priv)->ucode_rt.data.len;
  689. break;
  690. case IWL_UCODE_INIT:
  691. maxsize = trans(priv)->ucode_init.data.len;
  692. break;
  693. case IWL_UCODE_WOWLAN:
  694. maxsize = trans(priv)->ucode_wowlan.data.len;
  695. break;
  696. case IWL_UCODE_NONE:
  697. IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
  698. return -ENOSYS;
  699. default:
  700. IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
  701. return -ENOSYS;
  702. }
  703. if ((ofs + size) > maxsize) {
  704. IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
  705. return -EINVAL;
  706. }
  707. priv->testmode_sram.buff_size = (size / 4) * 4;
  708. priv->testmode_sram.buff_addr =
  709. kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
  710. if (priv->testmode_sram.buff_addr == NULL) {
  711. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  712. return -ENOMEM;
  713. }
  714. base = 0x800000;
  715. _iwl_read_targ_mem_words(bus(priv), base + ofs,
  716. priv->testmode_sram.buff_addr,
  717. priv->testmode_sram.buff_size / 4);
  718. priv->testmode_sram.num_chunks =
  719. DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE);
  720. priv->testmode_sram.sram_readed = true;
  721. return 0;
  722. }
  723. static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  724. struct sk_buff *skb,
  725. struct netlink_callback *cb)
  726. {
  727. struct iwl_priv *priv = hw->priv;
  728. int idx, length;
  729. if (priv->testmode_sram.sram_readed) {
  730. idx = cb->args[4];
  731. if (idx >= priv->testmode_sram.num_chunks) {
  732. iwl_sram_cleanup(priv);
  733. return -ENOENT;
  734. }
  735. length = DUMP_CHUNK_SIZE;
  736. if (((idx + 1) == priv->testmode_sram.num_chunks) &&
  737. (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE))
  738. length = priv->testmode_sram.buff_size %
  739. DUMP_CHUNK_SIZE;
  740. NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length,
  741. priv->testmode_sram.buff_addr +
  742. (DUMP_CHUNK_SIZE * idx));
  743. idx++;
  744. cb->args[4] = idx;
  745. return 0;
  746. } else
  747. return -EFAULT;
  748. nla_put_failure:
  749. return -ENOBUFS;
  750. }
  751. /* The testmode gnl message handler that takes the gnl message from the
  752. * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
  753. * invoke the corresponding handlers.
  754. *
  755. * This function is invoked when there is user space application sending
  756. * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
  757. * by nl80211.
  758. *
  759. * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
  760. * dispatching it to the corresponding handler.
  761. *
  762. * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
  763. * -ENOSYS is replied to the user application if the command is unknown;
  764. * Otherwise, the command is dispatched to the respective handler.
  765. *
  766. * @hw: ieee80211_hw object that represents the device
  767. * @data: pointer to user space message
  768. * @len: length in byte of @data
  769. */
  770. int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
  771. {
  772. struct nlattr *tb[IWL_TM_ATTR_MAX];
  773. struct iwl_priv *priv = hw->priv;
  774. int result;
  775. result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
  776. iwl_testmode_gnl_msg_policy);
  777. if (result != 0) {
  778. IWL_DEBUG_INFO(priv,
  779. "Error parsing the gnl message : %d\n", result);
  780. return result;
  781. }
  782. /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
  783. if (!tb[IWL_TM_ATTR_COMMAND]) {
  784. IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
  785. return -ENOMSG;
  786. }
  787. /* in case multiple accesses to the device happens */
  788. mutex_lock(&priv->shrd->mutex);
  789. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  790. case IWL_TM_CMD_APP2DEV_UCODE:
  791. IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
  792. result = iwl_testmode_ucode(hw, tb);
  793. break;
  794. case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
  795. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
  796. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
  797. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
  798. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
  799. IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
  800. result = iwl_testmode_reg(hw, tb);
  801. break;
  802. case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
  803. case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
  804. case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
  805. case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
  806. case IWL_TM_CMD_APP2DEV_GET_EEPROM:
  807. case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
  808. case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
  809. case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
  810. case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
  811. IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
  812. result = iwl_testmode_driver(hw, tb);
  813. break;
  814. case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
  815. case IWL_TM_CMD_APP2DEV_END_TRACE:
  816. case IWL_TM_CMD_APP2DEV_READ_TRACE:
  817. IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
  818. result = iwl_testmode_trace(hw, tb);
  819. break;
  820. case IWL_TM_CMD_APP2DEV_OWNERSHIP:
  821. IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
  822. result = iwl_testmode_ownership(hw, tb);
  823. break;
  824. case IWL_TM_CMD_APP2DEV_READ_SRAM:
  825. IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n");
  826. result = iwl_testmode_sram(hw, tb);
  827. break;
  828. default:
  829. IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
  830. result = -ENOSYS;
  831. break;
  832. }
  833. mutex_unlock(&priv->shrd->mutex);
  834. return result;
  835. }
  836. int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  837. struct netlink_callback *cb,
  838. void *data, int len)
  839. {
  840. struct nlattr *tb[IWL_TM_ATTR_MAX];
  841. struct iwl_priv *priv = hw->priv;
  842. int result;
  843. u32 cmd;
  844. if (cb->args[3]) {
  845. /* offset by 1 since commands start at 0 */
  846. cmd = cb->args[3] - 1;
  847. } else {
  848. result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
  849. iwl_testmode_gnl_msg_policy);
  850. if (result) {
  851. IWL_DEBUG_INFO(priv,
  852. "Error parsing the gnl message : %d\n", result);
  853. return result;
  854. }
  855. /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
  856. if (!tb[IWL_TM_ATTR_COMMAND]) {
  857. IWL_DEBUG_INFO(priv,
  858. "Error finding testmode command type\n");
  859. return -ENOMSG;
  860. }
  861. cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
  862. cb->args[3] = cmd + 1;
  863. }
  864. /* in case multiple accesses to the device happens */
  865. mutex_lock(&priv->shrd->mutex);
  866. switch (cmd) {
  867. case IWL_TM_CMD_APP2DEV_READ_TRACE:
  868. IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
  869. result = iwl_testmode_trace_dump(hw, tb, skb, cb);
  870. break;
  871. case IWL_TM_CMD_APP2DEV_DUMP_SRAM:
  872. IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
  873. result = iwl_testmode_sram_dump(hw, tb, skb, cb);
  874. break;
  875. default:
  876. result = -EINVAL;
  877. break;
  878. }
  879. mutex_unlock(&priv->shrd->mutex);
  880. return result;
  881. }