aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/csr/putest.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/putest.c')
-rw-r--r--drivers/staging/csr/putest.c685
1 files changed, 0 insertions, 685 deletions
diff --git a/drivers/staging/csr/putest.c b/drivers/staging/csr/putest.c
deleted file mode 100644
index 5613cf0e16b0..000000000000
--- a/drivers/staging/csr/putest.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * ***************************************************************************
- * FILE: putest.c
- *
- * PURPOSE: putest related functions.
- *
- * Copyright (C) 2008-2009 by Cambridge Silicon Radio Ltd.
- *
- * Refer to LICENSE.txt included with this source code for details on
- * the license terms.
- *
- * ***************************************************************************
- */
-
-#include <linux/vmalloc.h>
-#include <linux/firmware.h>
-
-#include "unifi_priv.h"
-#include "csr_wifi_hip_chiphelper.h"
-
-#define UNIFI_PROC_BOTH 3
-
-
-int unifi_putest_cmd52_read(unifi_priv_t *priv, unsigned char *arg)
-{
- struct unifi_putest_cmd52 cmd52_params;
- u8 *arg_pos;
- unsigned int cmd_param_size;
- int r;
- CsrResult csrResult;
- unsigned char ret_buffer[32];
- u8 *ret_buffer_pos;
- u8 retries;
-
- arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
- if (get_user(cmd_param_size, (int*)arg_pos)) {
- unifi_error(priv,
- "unifi_putest_cmd52_read: Failed to get the argument\n");
- return -EFAULT;
- }
-
- if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
- unifi_error(priv,
- "unifi_putest_cmd52_read: cmd52 struct mismatch\n");
- return -EINVAL;
- }
-
- arg_pos += sizeof(unsigned int);
- if (copy_from_user(&cmd52_params,
- (void*)arg_pos,
- sizeof(struct unifi_putest_cmd52))) {
- unifi_error(priv,
- "unifi_putest_cmd52_read: Failed to get the cmd52 params\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "cmd52r: func=%d addr=0x%x ",
- cmd52_params.funcnum, cmd52_params.addr);
-
- retries = 3;
- CsrSdioClaim(priv->sdio);
- do {
- if (cmd52_params.funcnum == 0) {
- csrResult = CsrSdioF0Read8(priv->sdio, cmd52_params.addr, &cmd52_params.data);
- } else {
- csrResult = CsrSdioRead8(priv->sdio, cmd52_params.addr, &cmd52_params.data);
- }
- } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT)));
- CsrSdioRelease(priv->sdio);
-
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "\nunifi_putest_cmd52_read: Read8() failed (csrResult=0x%x)\n", csrResult);
- return -EFAULT;
- }
- unifi_trace(priv, UDBG2, "data=%d\n", cmd52_params.data);
-
- /* Copy the info to the out buffer */
- *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_CMD52_READ;
- ret_buffer_pos = (u8*)(((unifi_putest_command_t*)ret_buffer) + 1);
- *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_cmd52);
- ret_buffer_pos += sizeof(unsigned int);
- memcpy(ret_buffer_pos, &cmd52_params, sizeof(struct unifi_putest_cmd52));
- ret_buffer_pos += sizeof(struct unifi_putest_cmd52);
-
- r = copy_to_user((void*)arg,
- ret_buffer,
- ret_buffer_pos - ret_buffer);
- if (r) {
- unifi_error(priv,
- "unifi_putest_cmd52_read: Failed to return the data\n");
- return -EFAULT;
- }
-
- return 0;
-}
-
-
-int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg)
-{
- struct unifi_putest_cmd52 cmd52_params;
- u8 *arg_pos;
- unsigned int cmd_param_size;
- CsrResult csrResult;
- u8 retries;
-
- arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
- if (get_user(cmd_param_size, (int*)arg_pos)) {
- unifi_error(priv,
- "unifi_putest_cmd52_write: Failed to get the argument\n");
- return -EFAULT;
- }
-
- if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) {
- unifi_error(priv,
- "unifi_putest_cmd52_write: cmd52 struct mismatch\n");
- return -EINVAL;
- }
-
- arg_pos += sizeof(unsigned int);
- if (copy_from_user(&cmd52_params,
- (void*)(arg_pos),
- sizeof(struct unifi_putest_cmd52))) {
- unifi_error(priv,
- "unifi_putest_cmd52_write: Failed to get the cmd52 params\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "cmd52w: func=%d addr=0x%x data=%d\n",
- cmd52_params.funcnum, cmd52_params.addr, cmd52_params.data);
-
- retries = 3;
- CsrSdioClaim(priv->sdio);
- do {
- if (cmd52_params.funcnum == 0) {
- csrResult = CsrSdioF0Write8(priv->sdio, cmd52_params.addr, cmd52_params.data);
- } else {
- csrResult = CsrSdioWrite8(priv->sdio, cmd52_params.addr, cmd52_params.data);
- }
- } while (--retries && ((csrResult == CSR_SDIO_RESULT_CRC_ERROR) || (csrResult == CSR_SDIO_RESULT_TIMEOUT)));
- CsrSdioRelease(priv->sdio);
-
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_cmd52_write: Write8() failed (csrResult=0x%x)\n", csrResult);
- return -EFAULT;
- }
-
- return 0;
-}
-
-int unifi_putest_gp_read16(unifi_priv_t *priv, unsigned char *arg)
-{
- struct unifi_putest_gp_rw16 gp_r16_params;
- u8 *arg_pos;
- unsigned int cmd_param_size;
- int r;
- CsrResult csrResult;
- unsigned char ret_buffer[32];
- u8 *ret_buffer_pos;
-
- arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
- if (get_user(cmd_param_size, (int*)arg_pos)) {
- unifi_error(priv,
- "unifi_putest_gp_read16: Failed to get the argument\n");
- return -EFAULT;
- }
-
- if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) {
- unifi_error(priv,
- "unifi_putest_gp_read16: struct mismatch\n");
- return -EINVAL;
- }
-
- arg_pos += sizeof(unsigned int);
- if (copy_from_user(&gp_r16_params,
- (void*)arg_pos,
- sizeof(struct unifi_putest_gp_rw16))) {
- unifi_error(priv,
- "unifi_putest_gp_read16: Failed to get the params\n");
- return -EFAULT;
- }
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_card_read16(priv->card, gp_r16_params.addr, &gp_r16_params.data);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_gp_read16: unifi_card_read16() GP=0x%x failed (csrResult=0x%x)\n", gp_r16_params.addr, csrResult);
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "gp_r16: GP=0x%08x, data=0x%04x\n", gp_r16_params.addr, gp_r16_params.data);
-
- /* Copy the info to the out buffer */
- *(unifi_putest_command_t*)ret_buffer = UNIFI_PUTEST_GP_READ16;
- ret_buffer_pos = (u8*)(((unifi_putest_command_t*)ret_buffer) + 1);
- *(unsigned int*)ret_buffer_pos = sizeof(struct unifi_putest_gp_rw16);
- ret_buffer_pos += sizeof(unsigned int);
- memcpy(ret_buffer_pos, &gp_r16_params, sizeof(struct unifi_putest_gp_rw16));
- ret_buffer_pos += sizeof(struct unifi_putest_gp_rw16);
-
- r = copy_to_user((void*)arg,
- ret_buffer,
- ret_buffer_pos - ret_buffer);
- if (r) {
- unifi_error(priv,
- "unifi_putest_gp_read16: Failed to return the data\n");
- return -EFAULT;
- }
-
- return 0;
-}
-
-int unifi_putest_gp_write16(unifi_priv_t *priv, unsigned char *arg)
-{
- struct unifi_putest_gp_rw16 gp_w16_params;
- u8 *arg_pos;
- unsigned int cmd_param_size;
- CsrResult csrResult;
-
- arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
- if (get_user(cmd_param_size, (int*)arg_pos)) {
- unifi_error(priv,
- "unifi_putest_gp_write16: Failed to get the argument\n");
- return -EFAULT;
- }
-
- if (cmd_param_size != sizeof(struct unifi_putest_gp_rw16)) {
- unifi_error(priv,
- "unifi_putest_gp_write16: struct mismatch\n");
- return -EINVAL;
- }
-
- arg_pos += sizeof(unsigned int);
- if (copy_from_user(&gp_w16_params,
- (void*)(arg_pos),
- sizeof(struct unifi_putest_gp_rw16))) {
- unifi_error(priv,
- "unifi_putest_gp_write16: Failed to get the params\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "gp_w16: GP=0x%08x, data=0x%04x\n", gp_w16_params.addr, gp_w16_params.data);
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_card_write16(priv->card, gp_w16_params.addr, gp_w16_params.data);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_gp_write16: unifi_card_write16() GP=%x failed (csrResult=0x%x)\n", gp_w16_params.addr, csrResult);
- return -EFAULT;
- }
-
- return 0;
-}
-
-int unifi_putest_set_sdio_clock(unifi_priv_t *priv, unsigned char *arg)
-{
- int sdio_clock_speed;
- CsrResult csrResult;
-
- if (get_user(sdio_clock_speed, (int*)(((unifi_putest_command_t*)arg) + 1))) {
- unifi_error(priv,
- "unifi_putest_set_sdio_clock: Failed to get the argument\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "set sdio clock: %d KHz\n", sdio_clock_speed);
-
- CsrSdioClaim(priv->sdio);
- csrResult = CsrSdioMaxBusClockFrequencySet(priv->sdio, sdio_clock_speed * 1000);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_set_sdio_clock: Set clock failed (csrResult=0x%x)\n", csrResult);
- return -EFAULT;
- }
-
- return 0;
-}
-
-
-int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg)
-{
- int r;
- CsrResult csrResult;
- int already_in_test = priv->ptest_mode;
-
- /* Ensure that sme_sys_suspend() doesn't power down the chip because:
- * 1) Power is needed anyway for ptest.
- * 2) The app code uses the START ioctl as a reset, so it gets called
- * multiple times. If the app stops the XAPs, but the power_down/up
- * sequence doesn't actually power down the chip, there can be problems
- * resetting, because part of the power_up sequence disables function 1
- */
- priv->ptest_mode = 1;
-
- /* Suspend the SME and UniFi */
- if (priv->sme_cli) {
- r = sme_sys_suspend(priv);
- if (r) {
- unifi_error(priv,
- "unifi_putest_start: failed to suspend UniFi\n");
- return r;
- }
- }
-
- /* Application may have stopped the XAPs, but they are needed for reset */
- if (already_in_test) {
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_start_processors(priv->card);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
- }
- } else {
- /* Ensure chip is powered for the case where there's no unifi_helper */
- CsrSdioClaim(priv->sdio);
- csrResult = CsrSdioPowerOn(priv->sdio);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "CsrSdioPowerOn csrResult = %d\n", csrResult);
- }
- }
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_init(priv->card);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_start: failed to init UniFi\n");
- return CsrHipResultToStatus(csrResult);
- }
-
- return 0;
-}
-
-
-int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg)
-{
- int r = 0;
- CsrResult csrResult;
-
- /* Application may have stopped the XAPs, but they are needed for reset */
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_start_processors(priv->card);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
- }
-
- /* PUTEST_STOP is also used to resume the XAPs after SME coredump.
- * Don't power off the chip, leave that to the normal wifi-off which is
- * about to carry on. No need to resume the SME either, as it wasn't suspended.
- */
- if (priv->coredump_mode) {
- priv->coredump_mode = 0;
- return 0;
- }
-
- /* At this point function 1 is enabled and the XAPs are running, so it is
- * safe to let the card power down. Power is restored later, asynchronously,
- * during the wifi_on requested by the SME.
- */
- CsrSdioClaim(priv->sdio);
- CsrSdioPowerOff(priv->sdio);
- CsrSdioRelease(priv->sdio);
-
- /* Resume the SME and UniFi */
- if (priv->sme_cli) {
- r = sme_sys_resume(priv);
- if (r) {
- unifi_error(priv,
- "unifi_putest_stop: failed to resume SME\n");
- }
- }
- priv->ptest_mode = 0;
-
- return r;
-}
-
-
-int unifi_putest_dl_fw(unifi_priv_t *priv, unsigned char *arg)
-{
-#define UF_PUTEST_MAX_FW_FILE_NAME 16
-#define UNIFI_MAX_FW_PATH_LEN 32
- unsigned int fw_name_length;
- unsigned char fw_name[UF_PUTEST_MAX_FW_FILE_NAME+1];
- unsigned char *name_buffer;
- int postfix;
- char fw_path[UNIFI_MAX_FW_PATH_LEN];
- const struct firmware *fw_entry;
- struct dlpriv temp_fw_sta;
- int r;
- CsrResult csrResult;
-
- /* Get the f/w file name length */
- if (get_user(fw_name_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) {
- unifi_error(priv,
- "unifi_putest_dl_fw: Failed to get the length argument\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file name size = %d\n", fw_name_length);
-
- /* Sanity check for the f/w file name length */
- if (fw_name_length > UF_PUTEST_MAX_FW_FILE_NAME) {
- unifi_error(priv,
- "unifi_putest_dl_fw: F/W file name is too long\n");
- return -EINVAL;
- }
-
- /* Get the f/w file name */
- name_buffer = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int);
- if (copy_from_user(fw_name, (void*)name_buffer, fw_name_length)) {
- unifi_error(priv, "unifi_putest_dl_fw: Failed to get the file name\n");
- return -EFAULT;
- }
- fw_name[fw_name_length] = '\0';
- unifi_trace(priv, UDBG2, "unifi_putest_dl_fw: file = %s\n", fw_name);
-
- /* Keep the existing f/w to a temp, we need to restore it later */
- temp_fw_sta = priv->fw_sta;
-
- /* Get the putest f/w */
- postfix = priv->instance;
- scnprintf(fw_path, UNIFI_MAX_FW_PATH_LEN, "unifi-sdio-%d/%s",
- postfix, fw_name);
- r = request_firmware(&fw_entry, fw_path, priv->unifi_device);
- if (r == 0) {
- priv->fw_sta.fw_desc = (void *)fw_entry;
- priv->fw_sta.dl_data = fw_entry->data;
- priv->fw_sta.dl_len = fw_entry->size;
- } else {
- unifi_error(priv, "Firmware file not available\n");
- return -EINVAL;
- }
-
- /* Application may have stopped the XAPs, but they are needed for reset */
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_start_processors(priv->card);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
- }
-
- /* Download the f/w. On UF6xxx this will cause the f/w file to convert
- * into patch format and download via the ROM boot loader
- */
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_download(priv->card, 0x0c00);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_dl_fw: failed to download the f/w\n");
- goto free_fw;
- }
-
- /* Free the putest f/w... */
-free_fw:
- uf_release_firmware(priv, &priv->fw_sta);
- /* ... and restore the original f/w */
- priv->fw_sta = temp_fw_sta;
-
- return CsrHipResultToStatus(csrResult);
-}
-
-
-int unifi_putest_dl_fw_buff(unifi_priv_t *priv, unsigned char *arg)
-{
- unsigned int fw_length;
- unsigned char *fw_buf = NULL;
- unsigned char *fw_user_ptr;
- struct dlpriv temp_fw_sta;
- CsrResult csrResult;
-
- /* Get the f/w buffer length */
- if (get_user(fw_length, (unsigned int*)(((unifi_putest_command_t*)arg) + 1))) {
- unifi_error(priv,
- "unifi_putest_dl_fw_buff: Failed to get the length arg\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "unifi_putest_dl_fw_buff: size = %d\n", fw_length);
-
- /* Sanity check for the buffer length */
- if (fw_length == 0 || fw_length > 0xfffffff) {
- unifi_error(priv,
- "unifi_putest_dl_fw_buff: buffer length bad %u\n", fw_length);
- return -EINVAL;
- }
-
- /* Buffer for kernel copy of the f/w image */
- fw_buf = kmalloc(fw_length, GFP_KERNEL);
- if (!fw_buf) {
- unifi_error(priv, "unifi_putest_dl_fw_buff: malloc fail\n");
- return -ENOMEM;
- }
-
- /* Get the f/w image */
- fw_user_ptr = ((unsigned char*)arg) + sizeof(unifi_putest_command_t) + sizeof(unsigned int);
- if (copy_from_user(fw_buf, (void*)fw_user_ptr, fw_length)) {
- unifi_error(priv, "unifi_putest_dl_fw_buff: Failed to get the buffer\n");
- kfree(fw_buf);
- return -EFAULT;
- }
-
- /* Save the existing f/w to a temp, we need to restore it later */
- temp_fw_sta = priv->fw_sta;
-
- /* Setting fw_desc NULL indicates to the core that no f/w file was loaded
- * via the kernel request_firmware() mechanism. This indicates to the core
- * that it shouldn't call release_firmware() after the download is done.
- */
- priv->fw_sta.fw_desc = NULL; /* No OS f/w resource */
- priv->fw_sta.dl_data = fw_buf;
- priv->fw_sta.dl_len = fw_length;
-
- /* Application may have stopped the XAPs, but they are needed for reset */
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_start_processors(priv->card);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to start XAPs. Hard reset required.\n");
- }
-
- /* Download the f/w. On UF6xxx this will cause the f/w file to convert
- * into patch format and download via the ROM boot loader
- */
- CsrSdioClaim(priv->sdio);
- csrResult = unifi_download(priv->card, 0x0c00);
- CsrSdioRelease(priv->sdio);
- if (csrResult != CSR_RESULT_SUCCESS) {
- unifi_error(priv,
- "unifi_putest_dl_fw_buff: failed to download the f/w\n");
- goto free_fw;
- }
-
-free_fw:
- /* Finished with the putest f/w, so restore the station f/w */
- priv->fw_sta = temp_fw_sta;
- kfree(fw_buf);
-
- return CsrHipResultToStatus(csrResult);
-}
-
-
-int unifi_putest_coredump_prepare(unifi_priv_t *priv, unsigned char *arg)
-{
- u16 data_u16;
- s32 i;
- CsrResult r;
-
- unifi_info(priv, "Preparing for SDIO coredump\n");
-#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE)
- unifi_debug_buf_dump();
-#endif
-
- /* Sanity check that userspace hasn't called a PUTEST_START, because that
- * would have reset UniFi, potentially power cycling it and losing context
- */
- if (priv->ptest_mode) {
- unifi_error(priv, "PUTEST_START shouldn't be used before a coredump\n");
- }
-
- /* Flag that the userspace has requested coredump. Even if this preparation
- * fails, the SME will call PUTEST_STOP to tidy up.
- */
- priv->coredump_mode = 1;
-
- for (i = 0; i < 3; i++) {
- CsrSdioClaim(priv->sdio);
- r = CsrSdioRead16(priv->sdio, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION*2, &data_u16);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_info(priv, "Failed to read chip version! Try %d\n", i);
-
- /* First try, re-enable function which may have been disabled by f/w panic */
- if (i == 0) {
- unifi_info(priv, "Try function enable\n");
- CsrSdioClaim(priv->sdio);
- r = CsrSdioFunctionEnable(priv->sdio);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "CsrSdioFunctionEnable failed %d\n", r);
- }
- continue;
- }
-
- /* Subsequent tries, reset */
-
- /* Set clock speed low */
- CsrSdioClaim(priv->sdio);
- r = CsrSdioMaxBusClockFrequencySet(priv->sdio, UNIFI_SDIO_CLOCK_SAFE_HZ);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "CsrSdioMaxBusClockFrequencySet() failed %d\n", r);
- }
-
- /* Card software reset */
- CsrSdioClaim(priv->sdio);
- r = unifi_card_hard_reset(priv->card);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "unifi_card_hard_reset() failed %d\n", r);
- }
- } else {
- unifi_info(priv, "Read chip version of 0x%04x\n", data_u16);
- break;
- }
- }
-
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to prepare chip\n");
- return -EIO;
- }
-
- /* Stop the XAPs for coredump. The PUTEST_STOP must be called, e.g. at
- * Raw SDIO deinit, to resume them.
- */
- CsrSdioClaim(priv->sdio);
- r = unifi_card_stop_processor(priv->card, UNIFI_PROC_BOTH);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "Failed to stop processors\n");
- }
-
- return 0;
-}
-
-int unifi_putest_cmd52_block_read(unifi_priv_t *priv, unsigned char *arg)
-{
- struct unifi_putest_block_cmd52_r block_cmd52;
- u8 *arg_pos;
- unsigned int cmd_param_size;
- CsrResult r;
- u8 *block_local_buffer;
-
- arg_pos = (u8*)(((unifi_putest_command_t*)arg) + 1);
- if (get_user(cmd_param_size, (int*)arg_pos)) {
- unifi_error(priv,
- "cmd52r_block: Failed to get the argument\n");
- return -EFAULT;
- }
-
- if (cmd_param_size != sizeof(struct unifi_putest_block_cmd52_r)) {
- unifi_error(priv,
- "cmd52r_block: cmd52 struct mismatch\n");
- return -EINVAL;
- }
-
- arg_pos += sizeof(unsigned int);
- if (copy_from_user(&block_cmd52,
- (void*)arg_pos,
- sizeof(struct unifi_putest_block_cmd52_r))) {
- unifi_error(priv,
- "cmd52r_block: Failed to get the cmd52 params\n");
- return -EFAULT;
- }
-
- unifi_trace(priv, UDBG2, "cmd52r_block: func=%d addr=0x%x len=0x%x ",
- block_cmd52.funcnum, block_cmd52.addr, block_cmd52.length);
-
- block_local_buffer = vmalloc(block_cmd52.length);
- if (block_local_buffer == NULL) {
- unifi_error(priv, "cmd52r_block: Failed to allocate buffer\n");
- return -ENOMEM;
- }
-
- CsrSdioClaim(priv->sdio);
- r = unifi_card_readn(priv->card, block_cmd52.addr, block_local_buffer, block_cmd52.length);
- CsrSdioRelease(priv->sdio);
- if (r != CSR_RESULT_SUCCESS) {
- unifi_error(priv, "cmd52r_block: unifi_readn failed\n");
- return -EIO;
- }
-
- if (copy_to_user((void*)block_cmd52.data,
- block_local_buffer,
- block_cmd52.length)) {
- unifi_error(priv,
- "cmd52r_block: Failed to return the data\n");
- return -EFAULT;
- }
-
- return 0;
-}