Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[pandora-kernel.git] / drivers / net / wireless / iwlwifi / iwl-testmode.c
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 - 2012 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 - 2012 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
73 #include "iwl-wifi.h"
74 #include "iwl-dev.h"
75 #include "iwl-core.h"
76 #include "iwl-debug.h"
77 #include "iwl-io.h"
78 #include "iwl-agn.h"
79 #include "iwl-testmode.h"
80 #include "iwl-trans.h"
81 #include "iwl-fh.h"
82
83
84 /* Periphery registers absolute lower bound. This is used in order to
85  * differentiate registery access through HBUS_TARG_PRPH_* and
86  * HBUS_TARG_MEM_* accesses.
87  */
88 #define IWL_TM_ABS_PRPH_START (0xA00000)
89
90 /* The TLVs used in the gnl message policy between the kernel module and
91  * user space application. iwl_testmode_gnl_msg_policy is to be carried
92  * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
93  * See iwl-testmode.h
94  */
95 static
96 struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
97         [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
98
99         [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
100         [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
101
102         [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
103         [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
104         [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
105
106         [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
107         [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
108
109         [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
110
111         [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
112         [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
113         [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
114
115         [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
116
117         [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
118
119         [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
120         [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
121         [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
122
123         [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
124         [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
125         [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
126         [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
127         [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
128 };
129
130 /*
131  * See the struct iwl_rx_packet in iwl-commands.h for the format of the
132  * received events from the device
133  */
134 static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
135 {
136         struct iwl_rx_packet *pkt = rxb_addr(rxb);
137         if (pkt)
138                 return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
139         else
140                 return 0;
141 }
142
143
144 /*
145  * This function multicasts the spontaneous messages from the device to the
146  * user space. It is invoked whenever there is a received messages
147  * from the device. This function is called within the ISR of the rx handlers
148  * in iwlagn driver.
149  *
150  * The parsing of the message content is left to the user space application,
151  * The message content is treated as unattacked raw data and is encapsulated
152  * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
153  *
154  * @priv: the instance of iwlwifi device
155  * @rxb: pointer to rx data content received by the ISR
156  *
157  * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
158  * For the messages multicasting to the user application, the mandatory
159  * TLV fields are :
160  *      IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
161  *      IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
162  */
163
164 static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
165                                 struct iwl_rx_mem_buffer *rxb)
166 {
167         struct ieee80211_hw *hw = priv->hw;
168         struct sk_buff *skb;
169         void *data;
170         int length;
171
172         data = (void *)rxb_addr(rxb);
173         length = get_event_length(rxb);
174
175         if (!data || length == 0)
176                 return;
177
178         skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
179                                                                 GFP_ATOMIC);
180         if (skb == NULL) {
181                 IWL_ERR(priv,
182                          "Run out of memory for messages to user space ?\n");
183                 return;
184         }
185         NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
186         NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
187         cfg80211_testmode_event(skb, GFP_ATOMIC);
188         return;
189
190 nla_put_failure:
191         kfree_skb(skb);
192         IWL_ERR(priv, "Ouch, overran buffer, check allocation!\n");
193 }
194
195 void iwl_testmode_init(struct iwl_priv *priv)
196 {
197         priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
198         priv->testmode_trace.trace_enabled = false;
199         priv->testmode_mem.read_in_progress = false;
200 }
201
202 static void iwl_mem_cleanup(struct iwl_priv *priv)
203 {
204         if (priv->testmode_mem.read_in_progress) {
205                 kfree(priv->testmode_mem.buff_addr);
206                 priv->testmode_mem.buff_addr = NULL;
207                 priv->testmode_mem.buff_size = 0;
208                 priv->testmode_mem.num_chunks = 0;
209                 priv->testmode_mem.read_in_progress = false;
210         }
211 }
212
213 static void iwl_trace_cleanup(struct iwl_priv *priv)
214 {
215         if (priv->testmode_trace.trace_enabled) {
216                 if (priv->testmode_trace.cpu_addr &&
217                     priv->testmode_trace.dma_addr)
218                         dma_free_coherent(trans(priv)->dev,
219                                         priv->testmode_trace.total_size,
220                                         priv->testmode_trace.cpu_addr,
221                                         priv->testmode_trace.dma_addr);
222                 priv->testmode_trace.trace_enabled = false;
223                 priv->testmode_trace.cpu_addr = NULL;
224                 priv->testmode_trace.trace_addr = NULL;
225                 priv->testmode_trace.dma_addr = 0;
226                 priv->testmode_trace.buff_size = 0;
227                 priv->testmode_trace.total_size = 0;
228         }
229 }
230
231
232 void iwl_testmode_cleanup(struct iwl_priv *priv)
233 {
234         iwl_trace_cleanup(priv);
235         iwl_mem_cleanup(priv);
236 }
237
238
239 /*
240  * This function handles the user application commands to the ucode.
241  *
242  * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
243  * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
244  * host command to the ucode.
245  *
246  * If any mandatory field is missing, -ENOMSG is replied to the user space
247  * application; otherwise, waits for the host command to be sent and checks
248  * the return code. In case or error, it is returned, otherwise a reply is
249  * allocated and the reply RX packet
250  * is returned.
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_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
256 {
257         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
258         struct iwl_host_cmd cmd;
259         struct iwl_rx_packet *pkt;
260         struct sk_buff *skb;
261         void *reply_buf;
262         u32 reply_len;
263         int ret;
264         bool cmd_want_skb;
265
266         memset(&cmd, 0, sizeof(struct iwl_host_cmd));
267
268         if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
269             !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
270                 IWL_ERR(priv, "Missing ucode command mandatory fields\n");
271                 return -ENOMSG;
272         }
273
274         cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
275         cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
276         if (cmd_want_skb)
277                 cmd.flags |= CMD_WANT_SKB;
278
279         cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
280         cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
281         cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
282         cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
283         IWL_DEBUG_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
284                                 " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
285
286         ret = iwl_trans_send_cmd(trans(priv), &cmd);
287         if (ret) {
288                 IWL_ERR(priv, "Failed to send hcmd\n");
289                 return ret;
290         }
291         if (!cmd_want_skb)
292                 return ret;
293
294         /* Handling return of SKB to the user */
295         pkt = (struct iwl_rx_packet *)cmd.reply_page;
296         if (!pkt) {
297                 IWL_ERR(priv, "HCMD received a null response packet\n");
298                 return ret;
299         }
300
301         reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
302         skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, reply_len + 20);
303         reply_buf = kmalloc(reply_len, GFP_KERNEL);
304         if (!skb || !reply_buf) {
305                 kfree_skb(skb);
306                 kfree(reply_buf);
307                 return -ENOMEM;
308         }
309
310         /* The reply is in a page, that we cannot send to user space. */
311         memcpy(reply_buf, &(pkt->hdr), reply_len);
312         iwl_free_pages(priv->shrd, cmd.reply_page);
313
314         NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
315         NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf);
316         return cfg80211_testmode_reply(skb);
317
318 nla_put_failure:
319         IWL_DEBUG_INFO(priv, "Failed creating NL attributes\n");
320         return -ENOMSG;
321 }
322
323
324 /*
325  * This function handles the user application commands for register access.
326  *
327  * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
328  * handlers respectively.
329  *
330  * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
331  * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
332  * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
333  * the success of the command execution.
334  *
335  * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
336  * value is returned with IWL_TM_ATTR_REG_VALUE32.
337  *
338  * @hw: ieee80211_hw object that represents the device
339  * @tb: gnl message fields from the user space
340  */
341 static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
342 {
343         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
344         u32 ofs, val32, cmd;
345         u8 val8;
346         struct sk_buff *skb;
347         int status = 0;
348
349         if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
350                 IWL_ERR(priv, "Missing register offset\n");
351                 return -ENOMSG;
352         }
353         ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
354         IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
355
356         /* Allow access only to FH/CSR/HBUS in direct mode.
357         Since we don't have the upper bounds for the CSR and HBUS segments,
358         we will use only the upper bound of FH for sanity check. */
359         cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
360         if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 ||
361                 cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
362                 cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
363                 (ofs >= FH_MEM_UPPER_BOUND)) {
364                 IWL_ERR(priv, "offset out of segment (0x0 - 0x%x)\n",
365                         FH_MEM_UPPER_BOUND);
366                 return -EINVAL;
367         }
368
369         switch (cmd) {
370         case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
371                 val32 = iwl_read_direct32(trans(priv), ofs);
372                 IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
373
374                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
375                 if (!skb) {
376                         IWL_ERR(priv, "Memory allocation fail\n");
377                         return -ENOMEM;
378                 }
379                 NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
380                 status = cfg80211_testmode_reply(skb);
381                 if (status < 0)
382                         IWL_ERR(priv, "Error sending msg : %d\n", status);
383                 break;
384         case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
385                 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
386                         IWL_ERR(priv, "Missing value to write\n");
387                         return -ENOMSG;
388                 } else {
389                         val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
390                         IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
391                         iwl_write_direct32(trans(priv), ofs, val32);
392                 }
393                 break;
394         case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
395                 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
396                         IWL_ERR(priv, "Missing value to write\n");
397                         return -ENOMSG;
398                 } else {
399                         val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
400                         IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
401                         iwl_write8(trans(priv), ofs, val8);
402                 }
403                 break;
404         default:
405                 IWL_ERR(priv, "Unknown testmode register command ID\n");
406                 return -ENOSYS;
407         }
408
409         return status;
410
411 nla_put_failure:
412         kfree_skb(skb);
413         return -EMSGSIZE;
414 }
415
416
417 static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
418 {
419         struct iwl_notification_wait calib_wait;
420         int ret;
421
422         iwl_init_notification_wait(priv->shrd, &calib_wait,
423                                       CALIBRATION_COMPLETE_NOTIFICATION,
424                                       NULL, NULL);
425         ret = iwl_init_alive_start(trans(priv));
426         if (ret) {
427                 IWL_ERR(priv, "Fail init calibration: %d\n", ret);
428                 goto cfg_init_calib_error;
429         }
430
431         ret = iwl_wait_notification(priv->shrd, &calib_wait, 2 * HZ);
432         if (ret)
433                 IWL_ERR(priv, "Error detecting"
434                         " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
435         return ret;
436
437 cfg_init_calib_error:
438         iwl_remove_notification(priv->shrd, &calib_wait);
439         return ret;
440 }
441
442 /*
443  * This function handles the user application commands for driver.
444  *
445  * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
446  * handlers respectively.
447  *
448  * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
449  * value of the actual command execution is replied to the user application.
450  *
451  * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
452  * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
453  * IWL_TM_CMD_DEV2APP_SYNC_RSP.
454  *
455  * @hw: ieee80211_hw object that represents the device
456  * @tb: gnl message fields from the user space
457  */
458 static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
459 {
460         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
461         struct iwl_trans *trans = trans(priv);
462         struct sk_buff *skb;
463         unsigned char *rsp_data_ptr = NULL;
464         int status = 0, rsp_data_len = 0;
465         u32 devid, inst_size = 0, data_size = 0;
466
467         switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
468         case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
469                 rsp_data_ptr = (unsigned char *)cfg(priv)->name;
470                 rsp_data_len = strlen(cfg(priv)->name);
471                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
472                                                         rsp_data_len + 20);
473                 if (!skb) {
474                         IWL_ERR(priv, "Memory allocation fail\n");
475                         return -ENOMEM;
476                 }
477                 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
478                             IWL_TM_CMD_DEV2APP_SYNC_RSP);
479                 NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
480                         rsp_data_len, rsp_data_ptr);
481                 status = cfg80211_testmode_reply(skb);
482                 if (status < 0)
483                         IWL_ERR(priv, "Error sending msg : %d\n", status);
484                 break;
485
486         case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
487                 status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_INIT);
488                 if (status)
489                         IWL_ERR(priv, "Error loading init ucode: %d\n", status);
490                 break;
491
492         case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
493                 iwl_testmode_cfg_init_calib(priv);
494                 iwl_trans_stop_device(trans);
495                 break;
496
497         case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
498                 status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_REGULAR);
499                 if (status) {
500                         IWL_ERR(priv,
501                                 "Error loading runtime ucode: %d\n", status);
502                         break;
503                 }
504                 status = iwl_alive_start(priv);
505                 if (status)
506                         IWL_ERR(priv,
507                                 "Error starting the device: %d\n", status);
508                 break;
509
510         case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
511                 iwl_scan_cancel_timeout(priv, 200);
512                 iwl_trans_stop_device(trans);
513                 status = iwl_load_ucode_wait_alive(trans, IWL_UCODE_WOWLAN);
514                 if (status) {
515                         IWL_ERR(priv,
516                                 "Error loading WOWLAN ucode: %d\n", status);
517                         break;
518                 }
519                 status = iwl_alive_start(priv);
520                 if (status)
521                         IWL_ERR(priv,
522                                 "Error starting the device: %d\n", status);
523                 break;
524
525         case IWL_TM_CMD_APP2DEV_GET_EEPROM:
526                 if (priv->shrd->eeprom) {
527                         skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
528                                 cfg(priv)->base_params->eeprom_size + 20);
529                         if (!skb) {
530                                 IWL_ERR(priv, "Memory allocation fail\n");
531                                 return -ENOMEM;
532                         }
533                         NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
534                                 IWL_TM_CMD_DEV2APP_EEPROM_RSP);
535                         NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
536                                 cfg(priv)->base_params->eeprom_size,
537                                 priv->shrd->eeprom);
538                         status = cfg80211_testmode_reply(skb);
539                         if (status < 0)
540                                 IWL_ERR(priv, "Error sending msg : %d\n",
541                                         status);
542                 } else
543                         return -EFAULT;
544                 break;
545
546         case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
547                 if (!tb[IWL_TM_ATTR_FIXRATE]) {
548                         IWL_ERR(priv, "Missing fixrate setting\n");
549                         return -ENOMSG;
550                 }
551                 priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
552                 break;
553
554         case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
555                 IWL_INFO(priv, "uCode version raw: 0x%x\n",
556                          nic(priv)->fw.ucode_ver);
557
558                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
559                 if (!skb) {
560                         IWL_ERR(priv, "Memory allocation fail\n");
561                         return -ENOMEM;
562                 }
563                 NLA_PUT_U32(skb, IWL_TM_ATTR_FW_VERSION,
564                             nic(priv)->fw.ucode_ver);
565                 status = cfg80211_testmode_reply(skb);
566                 if (status < 0)
567                         IWL_ERR(priv, "Error sending msg : %d\n", status);
568                 break;
569
570         case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
571                 devid = trans(priv)->hw_id;
572                 IWL_INFO(priv, "hw version: 0x%x\n", devid);
573
574                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
575                 if (!skb) {
576                         IWL_ERR(priv, "Memory allocation fail\n");
577                         return -ENOMEM;
578                 }
579                 NLA_PUT_U32(skb, IWL_TM_ATTR_DEVICE_ID, devid);
580                 status = cfg80211_testmode_reply(skb);
581                 if (status < 0)
582                         IWL_ERR(priv, "Error sending msg : %d\n", status);
583                 break;
584
585         case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
586                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
587                 if (!skb) {
588                         IWL_ERR(priv, "Memory allocation fail\n");
589                         return -ENOMEM;
590                 }
591                 switch (priv->shrd->ucode_type) {
592                 case IWL_UCODE_REGULAR:
593                         inst_size = nic(priv)->fw.ucode_rt.code.len;
594                         data_size = nic(priv)->fw.ucode_rt.data.len;
595                         break;
596                 case IWL_UCODE_INIT:
597                         inst_size = nic(priv)->fw.ucode_init.code.len;
598                         data_size = nic(priv)->fw.ucode_init.data.len;
599                         break;
600                 case IWL_UCODE_WOWLAN:
601                         inst_size = nic(priv)->fw.ucode_wowlan.code.len;
602                         data_size = nic(priv)->fw.ucode_wowlan.data.len;
603                         break;
604                 case IWL_UCODE_NONE:
605                         IWL_ERR(priv, "No uCode has not been loaded\n");
606                         break;
607                 default:
608                         IWL_ERR(priv, "Unsupported uCode type\n");
609                         break;
610                 }
611                 NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type);
612                 NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
613                 NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
614                 status = cfg80211_testmode_reply(skb);
615                 if (status < 0)
616                         IWL_ERR(priv, "Error sending msg : %d\n", status);
617                 break;
618
619         default:
620                 IWL_ERR(priv, "Unknown testmode driver command ID\n");
621                 return -ENOSYS;
622         }
623         return status;
624
625 nla_put_failure:
626         kfree_skb(skb);
627         return -EMSGSIZE;
628 }
629
630
631 /*
632  * This function handles the user application commands for uCode trace
633  *
634  * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
635  * handlers respectively.
636  *
637  * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
638  * value of the actual command execution is replied to the user application.
639  *
640  * @hw: ieee80211_hw object that represents the device
641  * @tb: gnl message fields from the user space
642  */
643 static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
644 {
645         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
646         struct sk_buff *skb;
647         int status = 0;
648         struct device *dev = trans(priv)->dev;
649
650         switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
651         case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
652                 if (priv->testmode_trace.trace_enabled)
653                         return -EBUSY;
654
655                 if (!tb[IWL_TM_ATTR_TRACE_SIZE])
656                         priv->testmode_trace.buff_size = TRACE_BUFF_SIZE_DEF;
657                 else
658                         priv->testmode_trace.buff_size =
659                                 nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
660                 if (!priv->testmode_trace.buff_size)
661                         return -EINVAL;
662                 if (priv->testmode_trace.buff_size < TRACE_BUFF_SIZE_MIN ||
663                     priv->testmode_trace.buff_size > TRACE_BUFF_SIZE_MAX)
664                         return -EINVAL;
665
666                 priv->testmode_trace.total_size =
667                         priv->testmode_trace.buff_size + TRACE_BUFF_PADD;
668                 priv->testmode_trace.cpu_addr =
669                         dma_alloc_coherent(dev,
670                                            priv->testmode_trace.total_size,
671                                            &priv->testmode_trace.dma_addr,
672                                            GFP_KERNEL);
673                 if (!priv->testmode_trace.cpu_addr)
674                         return -ENOMEM;
675                 priv->testmode_trace.trace_enabled = true;
676                 priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
677                         priv->testmode_trace.cpu_addr, 0x100);
678                 memset(priv->testmode_trace.trace_addr, 0x03B,
679                         priv->testmode_trace.buff_size);
680                 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
681                         sizeof(priv->testmode_trace.dma_addr) + 20);
682                 if (!skb) {
683                         IWL_ERR(priv, "Memory allocation fail\n");
684                         iwl_trace_cleanup(priv);
685                         return -ENOMEM;
686                 }
687                 NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
688                         sizeof(priv->testmode_trace.dma_addr),
689                         (u64 *)&priv->testmode_trace.dma_addr);
690                 status = cfg80211_testmode_reply(skb);
691                 if (status < 0) {
692                         IWL_ERR(priv, "Error sending msg : %d\n", status);
693                 }
694                 priv->testmode_trace.num_chunks =
695                         DIV_ROUND_UP(priv->testmode_trace.buff_size,
696                                      DUMP_CHUNK_SIZE);
697                 break;
698
699         case IWL_TM_CMD_APP2DEV_END_TRACE:
700                 iwl_trace_cleanup(priv);
701                 break;
702         default:
703                 IWL_ERR(priv, "Unknown testmode mem command ID\n");
704                 return -ENOSYS;
705         }
706         return status;
707
708 nla_put_failure:
709         kfree_skb(skb);
710         if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
711             IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
712                 iwl_trace_cleanup(priv);
713         return -EMSGSIZE;
714 }
715
716 static int iwl_testmode_trace_dump(struct ieee80211_hw *hw, struct nlattr **tb,
717                                    struct sk_buff *skb,
718                                    struct netlink_callback *cb)
719 {
720         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
721         int idx, length;
722
723         if (priv->testmode_trace.trace_enabled &&
724             priv->testmode_trace.trace_addr) {
725                 idx = cb->args[4];
726                 if (idx >= priv->testmode_trace.num_chunks)
727                         return -ENOENT;
728                 length = DUMP_CHUNK_SIZE;
729                 if (((idx + 1) == priv->testmode_trace.num_chunks) &&
730                     (priv->testmode_trace.buff_size % DUMP_CHUNK_SIZE))
731                         length = priv->testmode_trace.buff_size %
732                                 DUMP_CHUNK_SIZE;
733
734                 NLA_PUT(skb, IWL_TM_ATTR_TRACE_DUMP, length,
735                         priv->testmode_trace.trace_addr +
736                         (DUMP_CHUNK_SIZE * idx));
737                 idx++;
738                 cb->args[4] = idx;
739                 return 0;
740         } else
741                 return -EFAULT;
742
743  nla_put_failure:
744         return -ENOBUFS;
745 }
746
747 /*
748  * This function handles the user application switch ucode ownership.
749  *
750  * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
751  * decide who the current owner of the uCode
752  *
753  * If the current owner is OWNERSHIP_TM, then the only host command
754  * can deliver to uCode is from testmode, all the other host commands
755  * will dropped.
756  *
757  * default driver is the owner of uCode in normal operational mode
758  *
759  * @hw: ieee80211_hw object that represents the device
760  * @tb: gnl message fields from the user space
761  */
762 static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
763 {
764         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
765         u8 owner;
766
767         if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
768                 IWL_ERR(priv, "Missing ucode owner\n");
769                 return -ENOMSG;
770         }
771
772         owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
773         if ((owner == IWL_OWNERSHIP_DRIVER) || (owner == IWL_OWNERSHIP_TM))
774                 priv->shrd->ucode_owner = owner;
775         else {
776                 IWL_ERR(priv, "Invalid owner\n");
777                 return -EINVAL;
778         }
779         return 0;
780 }
781
782 static int iwl_testmode_indirect_read(struct iwl_priv *priv, u32 addr, u32 size)
783 {
784         struct iwl_trans *trans = trans(priv);
785         unsigned long flags;
786         int i;
787
788         if (size & 0x3)
789                 return -EINVAL;
790         priv->testmode_mem.buff_size = size;
791         priv->testmode_mem.buff_addr =
792                 kmalloc(priv->testmode_mem.buff_size, GFP_KERNEL);
793         if (priv->testmode_mem.buff_addr == NULL)
794                 return -ENOMEM;
795
796         /* Hard-coded periphery absolute address */
797         if (IWL_TM_ABS_PRPH_START <= addr &&
798                 addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
799                         spin_lock_irqsave(&trans->reg_lock, flags);
800                         iwl_grab_nic_access(trans);
801                         iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
802                                 addr | (3 << 24));
803                         for (i = 0; i < size; i += 4)
804                                 *(u32 *)(priv->testmode_mem.buff_addr + i) =
805                                         iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
806                         iwl_release_nic_access(trans);
807                         spin_unlock_irqrestore(&trans->reg_lock, flags);
808         } else { /* target memory (SRAM) */
809                 _iwl_read_targ_mem_words(trans, addr,
810                         priv->testmode_mem.buff_addr,
811                         priv->testmode_mem.buff_size / 4);
812         }
813
814         priv->testmode_mem.num_chunks =
815                 DIV_ROUND_UP(priv->testmode_mem.buff_size, DUMP_CHUNK_SIZE);
816         priv->testmode_mem.read_in_progress = true;
817         return 0;
818
819 }
820
821 static int iwl_testmode_indirect_write(struct iwl_priv *priv, u32 addr,
822         u32 size, unsigned char *buf)
823 {
824         struct iwl_trans *trans = trans(priv);
825         u32 val, i;
826         unsigned long flags;
827
828         if (IWL_TM_ABS_PRPH_START <= addr &&
829                 addr < IWL_TM_ABS_PRPH_START + PRPH_END) {
830                         /* Periphery writes can be 1-3 bytes long, or DWORDs */
831                         if (size < 4) {
832                                 memcpy(&val, buf, size);
833                                 spin_lock_irqsave(&trans->reg_lock, flags);
834                                 iwl_grab_nic_access(trans);
835                                 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
836                                             (addr & 0x0000FFFF) |
837                                             ((size - 1) << 24));
838                                 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
839                                 iwl_release_nic_access(trans);
840                                 /* needed after consecutive writes w/o read */
841                                 mmiowb();
842                                 spin_unlock_irqrestore(&trans->reg_lock, flags);
843                         } else {
844                                 if (size % 4)
845                                         return -EINVAL;
846                                 for (i = 0; i < size; i += 4)
847                                         iwl_write_prph(trans, addr+i,
848                                                 *(u32 *)(buf+i));
849                         }
850         } else if (iwlagn_hw_valid_rtc_data_addr(addr) ||
851                 (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
852                 addr < IWLAGN_RTC_INST_UPPER_BOUND)) {
853                         _iwl_write_targ_mem_words(trans, addr, buf, size/4);
854         } else
855                 return -EINVAL;
856         return 0;
857 }
858
859 /*
860  * This function handles the user application commands for SRAM data dump
861  *
862  * It retrieves the mandatory fields IWL_TM_ATTR_SRAM_ADDR and
863  * IWL_TM_ATTR_SRAM_SIZE to decide the memory area for SRAM data reading
864  *
865  * Several error will be retured, -EBUSY if the SRAM data retrieved by
866  * previous command has not been delivered to userspace, or -ENOMSG if
867  * the mandatory fields (IWL_TM_ATTR_SRAM_ADDR,IWL_TM_ATTR_SRAM_SIZE)
868  * are missing, or -ENOMEM if the buffer allocation fails.
869  *
870  * Otherwise 0 is replied indicating the success of the SRAM reading.
871  *
872  * @hw: ieee80211_hw object that represents the device
873  * @tb: gnl message fields from the user space
874  */
875 static int iwl_testmode_indirect_mem(struct ieee80211_hw *hw,
876         struct nlattr **tb)
877 {
878         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
879         u32 addr, size, cmd;
880         unsigned char *buf;
881
882         /* Both read and write should be blocked, for atomicity */
883         if (priv->testmode_mem.read_in_progress)
884                 return -EBUSY;
885
886         cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
887         if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
888                 IWL_ERR(priv, "Error finding memory offset address\n");
889                 return -ENOMSG;
890         }
891         addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
892         if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
893                 IWL_ERR(priv, "Error finding size for memory reading\n");
894                 return -ENOMSG;
895         }
896         size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
897
898         if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ)
899                 return iwl_testmode_indirect_read(priv, addr,  size);
900         else {
901                 if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
902                         return -EINVAL;
903                 buf = (unsigned char *) nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
904                 return iwl_testmode_indirect_write(priv, addr, size, buf);
905         }
906 }
907
908 static int iwl_testmode_buffer_dump(struct ieee80211_hw *hw, struct nlattr **tb,
909                                    struct sk_buff *skb,
910                                    struct netlink_callback *cb)
911 {
912         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
913         int idx, length;
914
915         if (priv->testmode_mem.read_in_progress) {
916                 idx = cb->args[4];
917                 if (idx >= priv->testmode_mem.num_chunks) {
918                         iwl_mem_cleanup(priv);
919                         return -ENOENT;
920                 }
921                 length = DUMP_CHUNK_SIZE;
922                 if (((idx + 1) == priv->testmode_mem.num_chunks) &&
923                     (priv->testmode_mem.buff_size % DUMP_CHUNK_SIZE))
924                         length = priv->testmode_mem.buff_size %
925                                 DUMP_CHUNK_SIZE;
926
927                 NLA_PUT(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
928                         priv->testmode_mem.buff_addr +
929                         (DUMP_CHUNK_SIZE * idx));
930                 idx++;
931                 cb->args[4] = idx;
932                 return 0;
933         } else
934                 return -EFAULT;
935
936  nla_put_failure:
937         return -ENOBUFS;
938 }
939
940
941 /* The testmode gnl message handler that takes the gnl message from the
942  * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
943  * invoke the corresponding handlers.
944  *
945  * This function is invoked when there is user space application sending
946  * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
947  * by nl80211.
948  *
949  * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
950  * dispatching it to the corresponding handler.
951  *
952  * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
953  * -ENOSYS is replied to the user application if the command is unknown;
954  * Otherwise, the command is dispatched to the respective handler.
955  *
956  * @hw: ieee80211_hw object that represents the device
957  * @data: pointer to user space message
958  * @len: length in byte of @data
959  */
960 int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
961 {
962         struct nlattr *tb[IWL_TM_ATTR_MAX];
963         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
964         int result;
965
966         result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
967                         iwl_testmode_gnl_msg_policy);
968         if (result != 0) {
969                 IWL_ERR(priv, "Error parsing the gnl message : %d\n", result);
970                 return result;
971         }
972
973         /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
974         if (!tb[IWL_TM_ATTR_COMMAND]) {
975                 IWL_ERR(priv, "Missing testmode command type\n");
976                 return -ENOMSG;
977         }
978         /* in case multiple accesses to the device happens */
979         mutex_lock(&priv->shrd->mutex);
980
981         switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
982         case IWL_TM_CMD_APP2DEV_UCODE:
983                 IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
984                 result = iwl_testmode_ucode(hw, tb);
985                 break;
986         case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
987         case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
988         case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
989                 IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
990                 result = iwl_testmode_reg(hw, tb);
991                 break;
992         case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
993         case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
994         case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
995         case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
996         case IWL_TM_CMD_APP2DEV_GET_EEPROM:
997         case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
998         case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
999         case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
1000         case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
1001         case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
1002                 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
1003                 result = iwl_testmode_driver(hw, tb);
1004                 break;
1005
1006         case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
1007         case IWL_TM_CMD_APP2DEV_END_TRACE:
1008         case IWL_TM_CMD_APP2DEV_READ_TRACE:
1009                 IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
1010                 result = iwl_testmode_trace(hw, tb);
1011                 break;
1012
1013         case IWL_TM_CMD_APP2DEV_OWNERSHIP:
1014                 IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
1015                 result = iwl_testmode_ownership(hw, tb);
1016                 break;
1017
1018         case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
1019         case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
1020                 IWL_DEBUG_INFO(priv, "testmode indirect memory cmd "
1021                         "to driver\n");
1022                 result = iwl_testmode_indirect_mem(hw, tb);
1023                 break;
1024
1025         default:
1026                 IWL_ERR(priv, "Unknown testmode command\n");
1027                 result = -ENOSYS;
1028                 break;
1029         }
1030
1031         mutex_unlock(&priv->shrd->mutex);
1032         return result;
1033 }
1034
1035 int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
1036                       struct netlink_callback *cb,
1037                       void *data, int len)
1038 {
1039         struct nlattr *tb[IWL_TM_ATTR_MAX];
1040         struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1041         int result;
1042         u32 cmd;
1043
1044         if (cb->args[3]) {
1045                 /* offset by 1 since commands start at 0 */
1046                 cmd = cb->args[3] - 1;
1047         } else {
1048                 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
1049                                 iwl_testmode_gnl_msg_policy);
1050                 if (result) {
1051                         IWL_ERR(priv,
1052                                 "Error parsing the gnl message : %d\n", result);
1053                         return result;
1054                 }
1055
1056                 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
1057                 if (!tb[IWL_TM_ATTR_COMMAND]) {
1058                         IWL_ERR(priv, "Missing testmode command type\n");
1059                         return -ENOMSG;
1060                 }
1061                 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
1062                 cb->args[3] = cmd + 1;
1063         }
1064
1065         /* in case multiple accesses to the device happens */
1066         mutex_lock(&priv->shrd->mutex);
1067         switch (cmd) {
1068         case IWL_TM_CMD_APP2DEV_READ_TRACE:
1069                 IWL_DEBUG_INFO(priv, "uCode trace cmd to driver\n");
1070                 result = iwl_testmode_trace_dump(hw, tb, skb, cb);
1071                 break;
1072         case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
1073                 IWL_DEBUG_INFO(priv, "testmode sram dump cmd to driver\n");
1074                 result = iwl_testmode_buffer_dump(hw, tb, skb, cb);
1075                 break;
1076         default:
1077                 result = -EINVAL;
1078                 break;
1079         }
1080
1081         mutex_unlock(&priv->shrd->mutex);
1082         return result;
1083 }