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