Linux Audio

Check our new training course

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