iwl-testmode.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  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. [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
  108. [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
  109. [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
  110. };
  111. /*
  112. * See the struct iwl_rx_packet in iwl-commands.h for the format of the
  113. * received events from the device
  114. */
  115. static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
  116. {
  117. struct iwl_rx_packet *pkt = rxb_addr(rxb);
  118. if (pkt)
  119. return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
  120. else
  121. return 0;
  122. }
  123. /*
  124. * This function multicasts the spontaneous messages from the device to the
  125. * user space. It is invoked whenever there is a received messages
  126. * from the device. This function is called within the ISR of the rx handlers
  127. * in iwlagn driver.
  128. *
  129. * The parsing of the message content is left to the user space application,
  130. * The message content is treated as unattacked raw data and is encapsulated
  131. * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
  132. *
  133. * @priv: the instance of iwlwifi device
  134. * @rxb: pointer to rx data content received by the ISR
  135. *
  136. * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
  137. * For the messages multicasting to the user application, the mandatory
  138. * TLV fields are :
  139. * IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
  140. * IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
  141. */
  142. static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
  143. struct iwl_rx_mem_buffer *rxb)
  144. {
  145. struct ieee80211_hw *hw = priv->hw;
  146. struct sk_buff *skb;
  147. void *data;
  148. int length;
  149. data = (void *)rxb_addr(rxb);
  150. length = get_event_length(rxb);
  151. if (!data || length == 0)
  152. return;
  153. skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
  154. GFP_ATOMIC);
  155. if (skb == NULL) {
  156. IWL_DEBUG_INFO(priv,
  157. "Run out of memory for messages to user space ?\n");
  158. return;
  159. }
  160. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
  161. NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
  162. cfg80211_testmode_event(skb, GFP_ATOMIC);
  163. return;
  164. nla_put_failure:
  165. kfree_skb(skb);
  166. IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
  167. }
  168. void iwl_testmode_init(struct iwl_priv *priv)
  169. {
  170. priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
  171. priv->testmode_trace.trace_enabled = false;
  172. priv->testmode_sram.sram_readed = false;
  173. }
  174. static void iwl_sram_cleanup(struct iwl_priv *priv)
  175. {
  176. if (priv->testmode_sram.sram_readed) {
  177. kfree(priv->testmode_sram.buff_addr);
  178. priv->testmode_sram.buff_addr = NULL;
  179. priv->testmode_sram.buff_size = 0;
  180. priv->testmode_sram.num_chunks = 0;
  181. priv->testmode_sram.sram_readed = false;
  182. }
  183. }
  184. static void iwl_trace_cleanup(struct iwl_priv *priv)
  185. {
  186. if (priv->testmode_trace.trace_enabled) {
  187. if (priv->testmode_trace.cpu_addr &&
  188. priv->testmode_trace.dma_addr)
  189. dma_free_coherent(bus(priv)->dev,
  190. priv->testmode_trace.total_size,
  191. priv->testmode_trace.cpu_addr,
  192. priv->testmode_trace.dma_addr);
  193. priv->testmode_trace.trace_enabled = false;
  194. priv->testmode_trace.cpu_addr = NULL;
  195. priv->testmode_trace.trace_addr = NULL;
  196. priv->testmode_trace.dma_addr = 0;
  197. priv->testmode_trace.buff_size = 0;
  198. priv->testmode_trace.total_size = 0;
  199. }
  200. }
  201. void iwl_testmode_cleanup(struct iwl_priv *priv)
  202. {
  203. iwl_trace_cleanup(priv);
  204. iwl_sram_cleanup(priv);
  205. }
  206. /*
  207. * This function handles the user application commands to the ucode.
  208. *
  209. * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
  210. * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
  211. * host command to the ucode.
  212. *
  213. * If any mandatory field is missing, -ENOMSG is replied to the user space
  214. * application; otherwise, the actual execution result of the host command to
  215. * ucode is replied.
  216. *
  217. * @hw: ieee80211_hw object that represents the device
  218. * @tb: gnl message fields from the user space
  219. */
  220. static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
  221. {
  222. struct iwl_priv *priv = hw->priv;
  223. struct iwl_host_cmd cmd;
  224. memset(&cmd, 0, sizeof(struct iwl_host_cmd));
  225. if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
  226. !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
  227. IWL_DEBUG_INFO(priv,
  228. "Error finding ucode command mandatory fields\n");
  229. return -ENOMSG;
  230. }
  231. cmd.flags = CMD_ON_DEMAND;
  232. cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
  233. cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
  234. cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
  235. cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
  236. IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
  237. " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
  238. /* ok, let's submit the command to ucode */
  239. return iwl_trans_send_cmd(trans(priv), &cmd);
  240. }
  241. /*
  242. * This function handles the user application commands for register access.
  243. *
  244. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  245. * handlers respectively.
  246. *
  247. * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
  248. * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
  249. * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
  250. * the success of the command execution.
  251. *
  252. * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
  253. * value is returned with IWL_TM_ATTR_REG_VALUE32.
  254. *
  255. * @hw: ieee80211_hw object that represents the device
  256. * @tb: gnl message fields from the user space
  257. */
  258. static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
  259. {
  260. struct iwl_priv *priv = hw->priv;
  261. u32 ofs, val32;
  262. u8 val8;
  263. struct sk_buff *skb;
  264. int status = 0;
  265. if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
  266. IWL_DEBUG_INFO(priv, "Error finding register offset\n");
  267. return -ENOMSG;
  268. }
  269. ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
  270. IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
  271. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  272. case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
  273. val32 = iwl_read_direct32(bus(priv), ofs);
  274. IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
  275. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  276. if (!skb) {
  277. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  278. return -ENOMEM;
  279. }
  280. NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
  281. status = cfg80211_testmode_reply(skb);
  282. if (status < 0)
  283. IWL_DEBUG_INFO(priv,
  284. "Error sending msg : %d\n", status);
  285. break;
  286. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
  287. if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
  288. IWL_DEBUG_INFO(priv,
  289. "Error finding value to write\n");
  290. return -ENOMSG;
  291. } else {
  292. val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
  293. IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
  294. iwl_write_direct32(bus(priv), ofs, val32);
  295. }
  296. break;
  297. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
  298. if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
  299. IWL_DEBUG_INFO(priv, "Error finding value to write\n");
  300. return -ENOMSG;
  301. } else {
  302. val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
  303. IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
  304. iwl_write8(bus(priv), ofs, val8);
  305. }
  306. break;
  307. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
  308. val32 = iwl_read_prph(bus(priv), ofs);
  309. IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
  310. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  311. if (!skb) {
  312. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  313. return -ENOMEM;
  314. }
  315. NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
  316. status = cfg80211_testmode_reply(skb);
  317. if (status < 0)
  318. IWL_DEBUG_INFO(priv,
  319. "Error sending msg : %d\n", status);
  320. break;
  321. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
  322. if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
  323. IWL_DEBUG_INFO(priv,
  324. "Error finding value to write\n");
  325. return -ENOMSG;
  326. } else {
  327. val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
  328. IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
  329. iwl_write_prph(bus(priv), ofs, val32);
  330. }
  331. break;
  332. default:
  333. IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
  334. return -ENOSYS;
  335. }
  336. return status;
  337. nla_put_failure:
  338. kfree_skb(skb);
  339. return -EMSGSIZE;
  340. }
  341. static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
  342. {
  343. struct iwl_notification_wait calib_wait;
  344. int ret;
  345. iwl_init_notification_wait(priv->shrd, &calib_wait,
  346. CALIBRATION_COMPLETE_NOTIFICATION,
  347. NULL, NULL);
  348. ret = iwl_init_alive_start(trans(priv));
  349. if (ret) {
  350. IWL_DEBUG_INFO(priv,
  351. "Error configuring init calibration: %d\n", ret);
  352. goto cfg_init_calib_error;
  353. }
  354. ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
  355. if (ret)
  356. IWL_DEBUG_INFO(priv, "Error detecting"
  357. " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
  358. return ret;
  359. cfg_init_calib_error:
  360. iwl_remove_notification(priv->shrd, &calib_wait);
  361. return ret;
  362. }
  363. /*
  364. * This function handles the user application commands for driver.
  365. *
  366. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  367. * handlers respectively.
  368. *
  369. * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
  370. * value of the actual command execution is replied to the user application.
  371. *
  372. * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
  373. * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
  374. * IWL_TM_CMD_DEV2APP_SYNC_RSP.
  375. *
  376. * @hw: ieee80211_hw object that represents the device
  377. * @tb: gnl message fields from the user space
  378. */
  379. static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
  380. {
  381. struct iwl_priv *priv = hw->priv;
  382. struct iwl_trans *trans = trans(priv);
  383. struct sk_buff *skb;
  384. unsigned char *rsp_data_ptr = NULL;
  385. int status = 0, rsp_data_len = 0;
  386. u32 devid, inst_size = 0, data_size = 0;
  387. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  388. case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
  389. rsp_data_ptr = (unsigned char *)cfg(priv)->name;
  390. rsp_data_len = strlen(cfg(priv)->name);
  391. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  392. rsp_data_len + 20);
  393. if (!skb) {
  394. IWL_DEBUG_INFO(priv,
  395. "Error allocating memory\n");
  396. return -ENOMEM;
  397. }
  398. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
  399. IWL_TM_CMD_DEV2APP_SYNC_RSP);
  400. NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
  401. rsp_data_len, rsp_data_ptr);
  402. status = cfg80211_testmode_reply(skb);
  403. if (status < 0)
  404. IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
  405. status);
  406. break;
  407. case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
  408. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
  409. if (status)
  410. IWL_DEBUG_INFO(priv,
  411. "Error loading init ucode: %d\n", status);
  412. break;
  413. case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
  414. iwl_testmode_cfg_init_calib(priv);
  415. iwl_trans_stop_device(trans);
  416. break;
  417. case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
  418. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
  419. if (status) {
  420. IWL_DEBUG_INFO(priv,
  421. "Error loading runtime ucode: %d\n", status);
  422. break;
  423. }
  424. status = iwl_alive_start(priv);
  425. if (status)
  426. IWL_DEBUG_INFO(priv,
  427. "Error starting the device: %d\n", status);
  428. break;
  429. case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
  430. iwl_scan_cancel_timeout(priv, 200);
  431. iwl_trans_stop_device(trans);
  432. status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
  433. if (status) {
  434. IWL_DEBUG_INFO(priv,
  435. "Error loading WOWLAN ucode: %d\n", status);
  436. break;
  437. }
  438. status = iwl_alive_start(priv);
  439. if (status)
  440. IWL_DEBUG_INFO(priv,
  441. "Error starting the device: %d\n", status);
  442. break;
  443. case IWL_TM_CMD_APP2DEV_GET_EEPROM:
  444. if (priv->shrd->eeprom) {
  445. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  446. cfg(priv)->base_params->eeprom_size + 20);
  447. if (!skb) {
  448. IWL_DEBUG_INFO(priv,
  449. "Error allocating memory\n");
  450. return -ENOMEM;
  451. }
  452. NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
  453. IWL_TM_CMD_DEV2APP_EEPROM_RSP);
  454. NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
  455. cfg(priv)->base_params->eeprom_size,
  456. priv->shrd->eeprom);
  457. status = cfg80211_testmode_reply(skb);
  458. if (status < 0)
  459. IWL_DEBUG_INFO(priv,
  460. "Error sending msg : %d\n",
  461. status);
  462. } else
  463. return -EFAULT;
  464. break;
  465. case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
  466. if (!tb[IWL_TM_ATTR_FIXRATE]) {
  467. IWL_DEBUG_INFO(priv,
  468. "Error finding fixrate setting\n");
  469. return -ENOMSG;
  470. }
  471. priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
  472. break;
  473. case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
  474. IWL_INFO(priv, "uCode version raw: 0x%x\n", priv->ucode_ver);
  475. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  476. if (!skb) {
  477. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  478. return -ENOMEM;
  479. }
  480. NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION, priv->ucode_ver);
  481. status = cfg80211_testmode_reply(skb);
  482. if (status < 0)
  483. IWL_DEBUG_INFO(priv,
  484. "Error sending msg : %d\n", status);
  485. break;
  486. case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
  487. devid = bus_get_hw_id(bus(priv));
  488. IWL_INFO(priv, "hw version: 0x%x\n", devid);
  489. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
  490. if (!skb) {
  491. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  492. return -ENOMEM;
  493. }
  494. NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
  495. status = cfg80211_testmode_reply(skb);
  496. if (status < 0)
  497. IWL_DEBUG_INFO(priv,
  498. "Error sending msg : %d\n", status);
  499. break;
  500. case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
  501. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
  502. if (!skb) {
  503. IWL_DEBUG_INFO(priv, "Error allocating memory\n");
  504. return -ENOMEM;
  505. }
  506. switch (priv->shrd->ucode_type) {
  507. case IWL_UCODE_REGULAR:
  508. inst_size = trans(priv)->ucode_rt.code.len;
  509. data_size = trans(priv)->ucode_rt.data.len;
  510. break;
  511. case IWL_UCODE_INIT:
  512. inst_size = trans(priv)->ucode_init.code.len;
  513. data_size = trans(priv)->ucode_init.data.len;
  514. break;
  515. case IWL_UCODE_WOWLAN:
  516. inst_size = trans(priv)->ucode_wowlan.code.len;
  517. data_size = trans(priv)->ucode_wowlan.data.len;
  518. break;
  519. case IWL_UCODE_NONE:
  520. IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n");
  521. break;
  522. default:
  523. IWL_DEBUG_INFO(priv, "Unsupported uCode type\n");
  524. break;
  525. }
  526. NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
  527. NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
  528. NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
  529. status = cfg80211_testmode_reply(skb);
  530. if (status < 0)
  531. IWL_DEBUG_INFO(priv,
  532. "Error sending msg : %d\n", status);
  533. break;
  534. default:
  535. IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
  536. return -ENOSYS;
  537. }
  538. return status;
  539. nla_put_failure:
  540. kfree_skb(skb);
  541. return -EMSGSIZE;
  542. }
  543. /*
  544. * This function handles the user application commands for uCode trace
  545. *
  546. * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
  547. * handlers respectively.
  548. *
  549. * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
  550. * value of the actual command execution is replied to the user application.
  551. *
  552. * @hw: ieee80211_hw object that represents the device
  553. * @tb: gnl message fields from the user space
  554. */
  555. static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
  556. {
  557. struct iwl_priv *priv = hw->priv;
  558. struct sk_buff *skb;
  559. int status = 0;
  560. struct device *dev = bus(priv)->dev;
  561. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  562. case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
  563. if (priv->testmode_trace.trace_enabled)
  564. return -EBUSY;
  565. if (!tb[IWL_TM_ATTR_TRACE_SIZE])
  566. priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF;
  567. else
  568. priv->testmode_trace.buff_size =
  569. nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
  570. if (!priv->testmode_trace.buff_size)
  571. return -EINVAL;
  572. if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN ||
  573. priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX)
  574. return -EINVAL;
  575. priv->testmode_trace.total_size =
  576. priv->testmode_trace.buff_size + TRACE_BUFF_PADD;
  577. priv->testmode_trace.cpu_addr =
  578. dma_alloc_coherent(dev,
  579. priv->testmode_trace.total_size,
  580. &priv->testmode_trace.dma_addr,
  581. GFP_KERNEL);
  582. if (!priv->testmode_trace.cpu_addr)
  583. return -ENOMEM;
  584. priv->testmode_trace.trace_enabled = true;
  585. priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
  586. priv->testmode_trace.cpu_addr, 0x100);
  587. memset(priv->testmode_trace.trace_addr, 0x03B,
  588. priv->testmode_trace.buff_size);
  589. skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
  590. sizeof(priv->testmode_trace.dma_addr) + 20);
  591. if (!skb) {
  592. IWL_DEBUG_INFO(priv,
  593. "Error allocating memory\n");
  594. iwl_trace_cleanup(priv);
  595. return -ENOMEM;
  596. }
  597. NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
  598. sizeof(priv->testmode_trace.dma_addr),
  599. (u64 *)&priv->testmode_trace.dma_addr);
  600. status = cfg80211_testmode_reply(skb);
  601. if (status < 0) {
  602. IWL_DEBUG_INFO(priv,
  603. "Error sending msg : %d\n",
  604. status);
  605. }
  606. priv->testmode_trace.num_chunks =
  607. DIV_ROUND_UP(priv->testmode_trace.buff_size,
  608. DUMP_CHUNK_SIZE);
  609. break;
  610. case IWL_TM_CMD_APP2DEV_END_TRACE:
  611. iwl_trace_cleanup(priv);
  612. break;
  613. default:
  614. IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
  615. return -ENOSYS;
  616. }
  617. return status;
  618. nla_put_failure:
  619. kfree_skb(skb);
  620. if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
  621. IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
  622. iwl_trace_cleanup(priv);
  623. return -EMSGSIZE;
  624. }
  625. static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  626. struct sk_buff *skb,
  627. struct netlink_callback *cb)
  628. {
  629. struct iwl_priv *priv = hw->priv;
  630. int idx, length;
  631. if (priv->testmode_trace.trace_enabled &&
  632. priv->testmode_trace.trace_addr) {
  633. idx = cb->args[4];
  634. if (idx >= priv->testmode_trace.num_chunks)
  635. return -ENOENT;
  636. length = DUMP_CHUNK_SIZE;
  637. if (((idx + 1) == priv->testmode_trace.num_chunks) &&
  638. (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE))
  639. length = priv->testmode_trace.buff_size %
  640. DUMP_CHUNK_SIZE;
  641. NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length,
  642. priv->testmode_trace.trace_addr +
  643. (DUMP_CHUNK_SIZE * idx));
  644. idx++;
  645. cb->args[4] = idx;
  646. return 0;
  647. } else
  648. return -EFAULT;
  649. nla_put_failure:
  650. return -ENOBUFS;
  651. }
  652. /*
  653. * This function handles the user application switch ucode ownership.
  654. *
  655. * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
  656. * decide who the current owner of the uCode
  657. *
  658. * If the current owner is OWNERSHIP_TM, then the only host command
  659. * can deliver to uCode is from testmode, all the other host commands
  660. * will dropped.
  661. *
  662. * default driver is the owner of uCode in normal operational mode
  663. *
  664. * @hw: ieee80211_hw object that represents the device
  665. * @tb: gnl message fields from the user space
  666. */
  667. static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
  668. {
  669. struct iwl_priv *priv = hw->priv;
  670. u8 owner;
  671. if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
  672. IWL_DEBUG_INFO(priv, "Error finding ucode owner\n");
  673. return -ENOMSG;
  674. }
  675. owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
  676. if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
  677. priv->shrd->ucode_owner = owner;
  678. else {
  679. IWL_DEBUG_INFO(priv, "Invalid owner\n");
  680. return -EINVAL;
  681. }
  682. return 0;
  683. }
  684. /*
  685. * This function handles the user application commands for SRAM data dump
  686. *
  687. * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and
  688. * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading
  689. *
  690. * Several error will be retured, -EBUSY if the SRAM data retrieved by
  691. * previous command has not been delivered to userspace, or -ENOMSG if
  692. * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE)
  693. * are missing, or -ENOMEM if the buffer allocation fails.
  694. *
  695. * Otherwise 0 is replied indicating the success of the SRAM reading.
  696. *
  697. * @hw: ieee80211_hw object that represents the device
  698. * @tb: gnl message fields from the user space
  699. */
  700. static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
  701. {
  702. struct iwl_priv *priv = hw->priv;
  703. u32 ofs, size, maxsize;
  704. if (priv->testmode_sram.sram_readed)
  705. return -EBUSY;
  706. if (!tb[IWL_TM_ATTR_SRAM_ADDR]) {
  707. IWL_DEBUG_INFO(priv, "Error finding SRAM offset address\n");
  708. return -ENOMSG;
  709. }
  710. ofs = nla_get_u32(tb[IWL_TM_ATTR_SRAM_ADDR]);
  711. if (!tb[IWL_TM_ATTR_SRAM_SIZE]) {
  712. IWL_DEBUG_INFO(priv, "Error finding size for SRAM reading\n");
  713. return -ENOMSG;
  714. }
  715. size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
  716. switch (priv->shrd->ucode_type) {
  717. case IWL_UCODE_REGULAR:
  718. maxsize = trans(priv)->ucode_rt.data.len;
  719. break;
  720. case IWL_UCODE_INIT:
  721. maxsize = trans(priv)->ucode_init.data.len;
  722. break;
  723. case IWL_UCODE_WOWLAN:
  724. maxsize = trans(priv)->ucode_wowlan.data.len;
  725. break;
  726. case IWL_UCODE_NONE:
  727. IWL_ERR(priv, "Error, uCode does not been loaded\n");
  728. return -ENOSYS;
  729. default:
  730. IWL_ERR(priv, "Error, unsupported uCode type\n");
  731. return -ENOSYS;
  732. }
  733. if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) {
  734. IWL_ERR(priv, "Invalid offset/size: out of range\n");
  735. return -EINVAL;
  736. }
  737. priv->testmode_sram.buff_size = (size / 4) * 4;
  738. priv->testmode_sram.buff_addr =
  739. kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);
  740. if (priv->testmode_sram.buff_addr == NULL) {
  741. IWL_ERR(priv, "Error allocating memory\n");
  742. return -ENOMEM;
  743. }
  744. _iwl_read_targ_mem_words(bus(priv), ofs,
  745. priv->testmode_sram.buff_addr,
  746. priv->testmode_sram.buff_size / 4);
  747. priv->testmode_sram.num_chunks =
  748. DIV_ROUND_UP(priv->testmode_sram.buff_size, DUMP_CHUNK_SIZE);
  749. priv->testmode_sram.sram_readed = true;
  750. return 0;
  751. }
  752. static int iwl_testmode_sram_dump(struct ieee80211_hw *hw, struct nlattr **tb,
  753. struct sk_buff *skb,
  754. struct netlink_callback *cb)
  755. {
  756. struct iwl_priv *priv = hw->priv;
  757. int idx, length;
  758. if (priv->testmode_sram.sram_readed) {
  759. idx = cb->args[4];
  760. if (idx >= priv->testmode_sram.num_chunks) {
  761. iwl_sram_cleanup(priv);
  762. return -ENOENT;
  763. }
  764. length = DUMP_CHUNK_SIZE;
  765. if (((idx + 1) == priv->testmode_sram.num_chunks) &&
  766. (priv->testmode_sram.buff_size % DUMP_CHUNK_SIZE))
  767. length = priv->testmode_sram.buff_size %
  768. DUMP_CHUNK_SIZE;
  769. NLA_PUT(skb, IWL_TM_ATTR_SRAM_DUMP, length,
  770. priv->testmode_sram.buff_addr +
  771. (DUMP_CHUNK_SIZE * idx));
  772. idx++;
  773. cb->args[4] = idx;
  774. return 0;
  775. } else
  776. return -EFAULT;
  777. nla_put_failure:
  778. return -ENOBUFS;
  779. }
  780. /* The testmode gnl message handler that takes the gnl message from the
  781. * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
  782. * invoke the corresponding handlers.
  783. *
  784. * This function is invoked when there is user space application sending
  785. * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
  786. * by nl80211.
  787. *
  788. * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
  789. * dispatching it to the corresponding handler.
  790. *
  791. * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
  792. * -ENOSYS is replied to the user application if the command is unknown;
  793. * Otherwise, the command is dispatched to the respective handler.
  794. *
  795. * @hw: ieee80211_hw object that represents the device
  796. * @data: pointer to user space message
  797. * @len: length in byte of @data
  798. */
  799. int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
  800. {
  801. struct nlattr *tb[IWL_TM_ATTR_MAX];
  802. struct iwl_priv *priv = hw->priv;
  803. int result;
  804. result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
  805. iwl_testmode_gnl_msg_policy);
  806. if (result != 0) {
  807. IWL_DEBUG_INFO(priv,
  808. "Error parsing the gnl message : %d\n", result);
  809. return result;
  810. }
  811. /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
  812. if (!tb[IWL_TM_ATTR_COMMAND]) {
  813. IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
  814. return -ENOMSG;
  815. }
  816. /* in case multiple accesses to the device happens */
  817. mutex_lock(&priv->shrd->mutex);
  818. switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
  819. case IWL_TM_CMD_APP2DEV_UCODE:
  820. IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
  821. result = iwl_testmode_ucode(hw, tb);
  822. break;
  823. case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
  824. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
  825. case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
  826. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32:
  827. case IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32:
  828. IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
  829. result = iwl_testmode_reg(hw, tb);
  830. break;
  831. case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
  832. case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
  833. case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
  834. case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
  835. case IWL_TM_CMD_APP2DEV_GET_EEPROM:
  836. case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
  837. case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
  838. case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
  839. case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
  840. case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
  841. IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
  842. result = iwl_testmode_driver(hw, tb);
  843. break;
  844. case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
  845. case IWL_TM_CMD_APP2DEV_END_TRACE:
  846. case IWL_TM_CMD_APP2DEV_READ_TRACE:
  847. IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
  848. result = iwl_testmode_trace(hw, tb);
  849. break;
  850. case IWL_TM_CMD_APP2DEV_OWNERSHIP:
  851. IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
  852. result = iwl_testmode_ownership(hw, tb);
  853. break;
  854. case IWL_TM_CMD_APP2DEV_READ_SRAM:
  855. IWL_DEBUG_INFO(priv, "testmode sram read cmd to driver\n");
  856. result = iwl_testmode_sram(hw, tb);
  857. break;
  858. default:
  859. IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
  860. result = -ENOSYS;
  861. break;
  862. }
  863. mutex_unlock(&priv->shrd->mutex);
  864. return result;
  865. }
  866. int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
  867. struct netlink_callback *cb,
  868. void *data, int len)
  869. {
  870. struct nlattr *tb[IWL_TM_ATTR_MAX];
  871. struct iwl_priv *priv = hw->priv;
  872. int result;
  873. u32 cmd;
  874. if (cb->args[3]) {
  875. /* offset by 1 since commands start at 0 */
  876. cmd = cb->args[3] - 1;
  877. } else {
  878. result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
  879. iwl_testmode_gnl_msg_policy);
  880. if (result) {
  881. IWL_DEBUG_INFO(priv,
  882. "Error parsing the gnl message : %d\n", result);
  883. return result;
  884. }
  885. /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
  886. if (!tb[IWL_TM_ATTR_COMMAND]) {
  887. IWL_DEBUG_INFO(priv,
  888. "Error finding testmode command type\n");
  889. return -ENOMSG;
  890. }
  891. cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
  892. cb->args[3] = cmd + 1;
  893. }
  894. /* in case multiple accesses to the device happens */
  895. mutex_lock(&priv->shrd->mutex);
  896. switch (cmd) {
  897. case IWL_TM_CMD_APP2DEV_READ_TRACE:
  898. IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
  899. result = iwl_testmode_trace_dump(hw, tb, skb, cb);
  900. break;
  901. case IWL_TM_CMD_APP2DEV_DUMP_SRAM:
  902. IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
  903. result = iwl_testmode_sram_dump(hw, tb, skb, cb);
  904. break;
  905. default:
  906. result = -EINVAL;
  907. break;
  908. }
  909. mutex_unlock(&priv->shrd->mutex);
  910. return result;
  911. }