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