iwl-sv-open.c 27 KB

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