aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl')
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/bmi.c548
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/bmi.h247
-rw-r--r--drivers/net/wireless/ath/ath6kl/btc.h76
-rw-r--r--drivers/net/wireless/ath/ath6kl/c210.c152
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/cfg80211.c3623
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/cfg80211.h60
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.c205
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.h30
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/common.h87
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/core.h932
-rw-r--r--drivers/net/wireless/ath/ath6kl/dbglog.c168
-rw-r--r--drivers/net/wireless/ath/ath6kl/dbglog.h24
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/debug.c2022
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/debug.h161
-rw-r--r--drivers/net/wireless/ath/ath6kl/debugfs_pri.c246
-rw-r--r--drivers/net/wireless/ath/ath6kl/debugfs_pri.h43
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/hif-ops.h157
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/hif.c791
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/hif.h315
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/htc.c2888
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/htc.h621
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/init.c2330
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/main.c1324
-rw-r--r--drivers/net/wireless/ath/ath6kl/msm.c425
-rw-r--r--drivers/net/wireless/ath/ath6kl/pm.c258
-rw-r--r--drivers/net/wireless/ath/ath6kl/pm.h24
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/sdio.c1534
-rw-r--r--drivers/net/wireless/ath/ath6kl/softmac.c265
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/target.h360
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/testmode.c124
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/testmode.h37
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c1853
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/usb.c433
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/wmi.c3947
-rwxr-xr-xdrivers/net/wireless/ath/ath6kl/wmi.h2602
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi_btcoex.c627
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi_btcoex.h125
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmiconfig.c88
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmiconfig.h25
39 files changed, 0 insertions, 29777 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
deleted file mode 100755
index 05d1d89..0000000
--- a/drivers/net/wireless/ath/ath6kl/bmi.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "hif-ops.h"
-#include "target.h"
-#include "debug.h"
-
-int ath6kl_bmi_done(struct ath6kl *ar)
-{
- int ret;
- u32 cid = BMI_DONE;
-
- if (ar->bmi.done_sent) {
- ath6kl_dbg(ATH6KL_DBG_BMI, "bmi done skipped\n");
- return 0;
- }
-
- ar->bmi.done_sent = true;
-
- ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid));
- if (ret) {
- ath6kl_err("Unable to send bmi done: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_get_target_info(struct ath6kl *ar,
- struct ath6kl_bmi_target_info *targ_info)
-{
- int ret;
- u32 cid = BMI_GET_TARGET_INFO;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- ret = ath6kl_hif_bmi_write(ar, (u8 *)&cid, sizeof(cid));
- if (ret) {
- ath6kl_err("Unable to send get target info: %d\n", ret);
- return ret;
- }
-
- if (ar->hif_type == ATH6KL_HIF_TYPE_USB) {
- ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info,
- sizeof(*targ_info));
- } else {
- ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version,
- sizeof(targ_info->version));
- }
-
- if (ret) {
- ath6kl_err("Unable to recv target info: %d\n", ret);
- return ret;
- }
-
- if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
- /* Determine how many bytes are in the Target's targ_info */
- ret = ath6kl_hif_bmi_read(ar,
- (u8 *)&targ_info->byte_count,
- sizeof(targ_info->byte_count));
- if (ret) {
- ath6kl_err("unable to read target info byte count: %d\n",
- ret);
- return ret;
- }
-
- /*
- * The target's targ_info doesn't match the host's targ_info.
- * We need to do some backwards compatibility to make this work.
- */
- if (le32_to_cpu(targ_info->byte_count) != sizeof(*targ_info)) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- /* Read the remainder of the targ_info */
- ret = ath6kl_hif_bmi_read(ar,
- ((u8 *)targ_info) +
- sizeof(targ_info->byte_count),
- sizeof(*targ_info) -
- sizeof(targ_info->byte_count));
-
- if (ret) {
- ath6kl_err("Unable to read target info (%d bytes): %d\n",
- targ_info->byte_count, ret);
- return ret;
- }
- }
-
- ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n",
- targ_info->version, targ_info->type);
-
- return 0;
-}
-
-int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
-{
- u32 cid = BMI_READ_MEMORY;
- int ret;
- u32 offset;
- u32 len_remain, rx_len;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = ar->bmi.max_data_size + sizeof(cid) + sizeof(addr) + sizeof(len);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI,
- "bmi read memory: device: addr: 0x%x, len: %d\n",
- addr, len);
-
- len_remain = len;
-
- while (len_remain) {
- rx_len = (len_remain < ar->bmi.max_data_size) ?
- len_remain : ar->bmi.max_data_size;
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
- memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
- offset += sizeof(len);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n",
- ret);
- return ret;
- }
- ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, rx_len);
- if (ret) {
- ath6kl_err("Unable to read from the device: %d\n",
- ret);
- return ret;
- }
- memcpy(&buf[len - len_remain], ar->bmi.cmd_buf, rx_len);
- len_remain -= rx_len; addr += rx_len;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
-{
- u32 cid = BMI_WRITE_MEMORY;
- int ret;
- u32 offset;
- u32 len_remain, tx_len;
- const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len);
- u8 aligned_buf[400];
- u8 *src;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- if ((ar->bmi.max_data_size + header) > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (WARN_ON(ar->bmi.max_data_size > sizeof(aligned_buf)))
- return -E2BIG;
-
- memset(ar->bmi.cmd_buf, 0, ar->bmi.max_data_size + header);
-
- ath6kl_dbg(ATH6KL_DBG_BMI,
- "bmi write memory: addr: 0x%x, len: %d\n", addr, len);
-
- len_remain = len;
- while (len_remain) {
- src = &buf[len - len_remain];
-
- if (len_remain < (ar->bmi.max_data_size - header)) {
- if (len_remain & 3) {
- /* align it with 4 bytes */
- len_remain = len_remain +
- (4 - (len_remain & 3));
- memcpy(aligned_buf, src, len_remain);
- src = aligned_buf;
- }
- tx_len = len_remain;
- } else {
- tx_len = (ar->bmi.max_data_size - header);
- }
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
- memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
- offset += sizeof(tx_len);
- memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
- offset += tx_len;
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n",
- ret);
- return ret;
- }
- len_remain -= tx_len; addr += tx_len;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
-{
- u32 cid = BMI_EXECUTE;
- int ret;
- u32 offset;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = sizeof(cid) + sizeof(addr) + sizeof(param);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI, "bmi execute: addr: 0x%x, param: %d)\n",
- addr, *param);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
- memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
- offset += sizeof(*param);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n", ret);
- return ret;
- }
-
- ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
- if (ret) {
- ath6kl_err("Unable to read from the device: %d\n", ret);
- return ret;
- }
-
- memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
-
- return 0;
-}
-
-int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
-{
- u32 cid = BMI_SET_APP_START;
- int ret;
- u32 offset;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = sizeof(cid) + sizeof(addr);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI, "bmi set app start: addr: 0x%x\n", addr);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
-{
- u32 cid = BMI_READ_SOC_REGISTER;
- int ret;
- u32 offset;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = sizeof(cid) + sizeof(addr);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI, "bmi read SOC reg: addr: 0x%x\n", addr);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n", ret);
- return ret;
- }
-
- ret = ath6kl_hif_bmi_read(ar, ar->bmi.cmd_buf, sizeof(*param));
- if (ret) {
- ath6kl_err("Unable to read from the device: %d\n", ret);
- return ret;
- }
- memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
-
- return 0;
-}
-
-int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
-{
- u32 cid = BMI_WRITE_SOC_REGISTER;
- int ret;
- u32 offset;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = sizeof(cid) + sizeof(addr) + sizeof(param);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI,
- "bmi write SOC reg: addr: 0x%x, param: %d\n",
- addr, param);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
- memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
- offset += sizeof(param);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
-{
- u32 cid = BMI_LZ_DATA;
- int ret;
- u32 offset;
- u32 len_remain, tx_len;
- const u32 header = sizeof(cid) + sizeof(len);
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = ar->bmi.max_data_size + header;
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI, "bmi send LZ data: len: %d)\n",
- len);
-
- len_remain = len;
- while (len_remain) {
- tx_len = (len_remain < (ar->bmi.max_data_size - header)) ?
- len_remain : (ar->bmi.max_data_size - header);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
- offset += sizeof(tx_len);
- memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain],
- tx_len);
- offset += tx_len;
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to write to the device: %d\n",
- ret);
- return ret;
- }
-
- len_remain -= tx_len;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
-{
- u32 cid = BMI_LZ_STREAM_START;
- int ret;
- u32 offset;
- u16 size;
-
- if (ar->bmi.done_sent) {
- ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
- return -EACCES;
- }
-
- size = sizeof(cid) + sizeof(addr);
- if (size > ar->bmi.max_cmd_size) {
- WARN_ON(1);
- return -EINVAL;
- }
- memset(ar->bmi.cmd_buf, 0, size);
-
- ath6kl_dbg(ATH6KL_DBG_BMI,
- "bmi LZ stream start: addr: 0x%x)\n",
- addr);
-
- offset = 0;
- memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
- offset += sizeof(cid);
- memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
- offset += sizeof(addr);
-
- ret = ath6kl_hif_bmi_write(ar, ar->bmi.cmd_buf, offset);
- if (ret) {
- ath6kl_err("Unable to start LZ stream to the device: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
-{
- int ret;
- u32 last_word = 0;
- u32 last_word_offset = len & ~0x3;
- u32 unaligned_bytes = len & 0x3;
-
- ret = ath6kl_bmi_lz_stream_start(ar, addr);
- if (ret)
- return ret;
-
- if (unaligned_bytes) {
- /* copy the last word into a zero padded buffer */
- memcpy(&last_word, &buf[last_word_offset], unaligned_bytes);
- }
-
- ret = ath6kl_bmi_lz_data(ar, buf, last_word_offset);
- if (ret)
- return ret;
-
- if (unaligned_bytes)
- ret = ath6kl_bmi_lz_data(ar, (u8 *)&last_word, 4);
-
- if (!ret) {
- /* Close compressed stream and open a new (fake) one.
- * This serves mainly to flush Target caches. */
- ret = ath6kl_bmi_lz_stream_start(ar, 0x00);
- }
- return ret;
-}
-
-void ath6kl_bmi_reset(struct ath6kl *ar)
-{
- ar->bmi.done_sent = false;
-}
-
-int ath6kl_bmi_init(struct ath6kl *ar)
-{
- if (WARN_ON(ar->bmi.max_data_size == 0))
- return -EINVAL;
-
- /* cmd + addr + len + data_size */
- ar->bmi.max_cmd_size = ar->bmi.max_data_size + (sizeof(u32) * 3);
-
- ar->bmi.cmd_buf = kzalloc(ar->bmi.max_cmd_size, GFP_ATOMIC);
- if (!ar->bmi.cmd_buf)
- return -ENOMEM;
-
- return 0;
-}
-
-void ath6kl_bmi_cleanup(struct ath6kl *ar)
-{
- kfree(ar->bmi.cmd_buf);
- ar->bmi.cmd_buf = NULL;
-}
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
deleted file mode 100755
index 114f7b2..0000000
--- a/drivers/net/wireless/ath/ath6kl/bmi.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef BMI_H
-#define BMI_H
-
-/*
- * Bootloader Messaging Interface (BMI)
- *
- * BMI is a very simple messaging interface used during initialization
- * to read memory, write memory, execute code, and to define an
- * application entry PC.
- *
- * It is used to download an application to ATH6KL, to provide
- * patches to code that is already resident on ATH6KL, and generally
- * to examine and modify state. The Host has an opportunity to use
- * BMI only once during bootup. Once the Host issues a BMI_DONE
- * command, this opportunity ends.
- *
- * The Host writes BMI requests to mailbox0, and reads BMI responses
- * from mailbox0. BMI requests all begin with a command
- * (see below for specific commands), and are followed by
- * command-specific data.
- *
- * Flow control:
- * The Host can only issue a command once the Target gives it a
- * "BMI Command Credit", using ATH6KL Counter #4. As soon as the
- * Target has completed a command, it issues another BMI Command
- * Credit (so the Host can issue the next command).
- *
- * BMI handles all required Target-side cache flushing.
- */
-
-/* BMI Commands */
-
-#define BMI_NO_COMMAND 0
-
-#define BMI_DONE 1
-/*
- * Semantics: Host is done using BMI
- * Request format:
- * u32 command (BMI_DONE)
- * Response format: none
- */
-
-#define BMI_READ_MEMORY 2
-/*
- * Semantics: Host reads ATH6KL memory
- * Request format:
- * u32 command (BMI_READ_MEMORY)
- * u32 address
- * u32 length, at most BMI_DATASZ_MAX
- * Response format:
- * u8 data[length]
- */
-
-#define BMI_WRITE_MEMORY 3
-/*
- * Semantics: Host writes ATH6KL memory
- * Request format:
- * u32 command (BMI_WRITE_MEMORY)
- * u32 address
- * u32 length, at most BMI_DATASZ_MAX
- * u8 data[length]
- * Response format: none
- */
-
-#define BMI_EXECUTE 4
-/*
- * Semantics: Causes ATH6KL to execute code
- * Request format:
- * u32 command (BMI_EXECUTE)
- * u32 address
- * u32 parameter
- * Response format:
- * u32 return value
- */
-
-#define BMI_SET_APP_START 5
-/*
- * Semantics: Set Target application starting address
- * Request format:
- * u32 command (BMI_SET_APP_START)
- * u32 address
- * Response format: none
- */
-
-#define BMI_READ_SOC_REGISTER 6
-/*
- * Semantics: Read a 32-bit Target SOC register.
- * Request format:
- * u32 command (BMI_READ_REGISTER)
- * u32 address
- * Response format:
- * u32 value
- */
-
-#define BMI_WRITE_SOC_REGISTER 7
-/*
- * Semantics: Write a 32-bit Target SOC register.
- * Request format:
- * u32 command (BMI_WRITE_REGISTER)
- * u32 address
- * u32 value
- *
- * Response format: none
- */
-
-#define BMI_GET_TARGET_ID 8
-#define BMI_GET_TARGET_INFO 8
-/*
- * Semantics: Fetch the 4-byte Target information
- * Request format:
- * u32 command (BMI_GET_TARGET_ID/INFO)
- * Response format1 (old firmware):
- * u32 TargetVersionID
- * Response format2 (newer firmware):
- * u32 TARGET_VERSION_SENTINAL
- * struct bmi_target_info;
- */
-
-#define TARGET_VERSION_SENTINAL 0xffffffff
-#define TARGET_TYPE_AR6003 3
-#define TARGET_TYPE_AR6004 5
-#define BMI_ROMPATCH_INSTALL 9
-/*
- * Semantics: Install a ROM Patch.
- * Request format:
- * u32 command (BMI_ROMPATCH_INSTALL)
- * u32 Target ROM Address
- * u32 Target RAM Address or Value (depending on Target Type)
- * u32 Size, in bytes
- * u32 Activate? 1-->activate;
- * 0-->install but do not activate
- * Response format:
- * u32 PatchID
- */
-
-#define BMI_ROMPATCH_UNINSTALL 10
-/*
- * Semantics: Uninstall a previously-installed ROM Patch,
- * automatically deactivating, if necessary.
- * Request format:
- * u32 command (BMI_ROMPATCH_UNINSTALL)
- * u32 PatchID
- *
- * Response format: none
- */
-
-#define BMI_ROMPATCH_ACTIVATE 11
-/*
- * Semantics: Activate a list of previously-installed ROM Patches.
- * Request format:
- * u32 command (BMI_ROMPATCH_ACTIVATE)
- * u32 rompatch_count
- * u32 PatchID[rompatch_count]
- *
- * Response format: none
- */
-
-#define BMI_ROMPATCH_DEACTIVATE 12
-/*
- * Semantics: Deactivate a list of active ROM Patches.
- * Request format:
- * u32 command (BMI_ROMPATCH_DEACTIVATE)
- * u32 rompatch_count
- * u32 PatchID[rompatch_count]
- *
- * Response format: none
- */
-
-
-#define BMI_LZ_STREAM_START 13
-/*
- * Semantics: Begin an LZ-compressed stream of input
- * which is to be uncompressed by the Target to an
- * output buffer at address. The output buffer must
- * be sufficiently large to hold the uncompressed
- * output from the compressed input stream. This BMI
- * command should be followed by a series of 1 or more
- * BMI_LZ_DATA commands.
- * u32 command (BMI_LZ_STREAM_START)
- * u32 address
- * Note: Not supported on all versions of ROM firmware.
- */
-
-#define BMI_LZ_DATA 14
-/*
- * Semantics: Host writes ATH6KL memory with LZ-compressed
- * data which is uncompressed by the Target. This command
- * must be preceded by a BMI_LZ_STREAM_START command. A series
- * of BMI_LZ_DATA commands are considered part of a single
- * input stream until another BMI_LZ_STREAM_START is issued.
- * Request format:
- * u32 command (BMI_LZ_DATA)
- * u32 length (of compressed data),
- * at most BMI_DATASZ_MAX
- * u8 CompressedData[length]
- * Response format: none
- * Note: Not supported on all versions of ROM firmware.
- */
-
-#define BMI_COMMUNICATION_TIMEOUT 1000 /* in msec */
-
-struct ath6kl;
-struct ath6kl_bmi_target_info {
- __le32 byte_count; /* size of this structure */
- __le32 version; /* target version id */
- __le32 type; /* target type */
-} __packed;
-
-int ath6kl_bmi_init(struct ath6kl *ar);
-void ath6kl_bmi_cleanup(struct ath6kl *ar);
-void ath6kl_bmi_reset(struct ath6kl *ar);
-
-int ath6kl_bmi_done(struct ath6kl *ar);
-int ath6kl_bmi_get_target_info(struct ath6kl *ar,
- struct ath6kl_bmi_target_info *targ_info);
-int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
-int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
-int ath6kl_bmi_execute(struct ath6kl *ar,
- u32 addr, u32 *param);
-int ath6kl_bmi_set_app_start(struct ath6kl *ar,
- u32 addr);
-int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param);
-int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param);
-int ath6kl_bmi_lz_data(struct ath6kl *ar,
- u8 *buf, u32 len);
-int ath6kl_bmi_lz_stream_start(struct ath6kl *ar,
- u32 addr);
-int ath6kl_bmi_fast_download(struct ath6kl *ar,
- u32 addr, u8 *buf, u32 len);
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/btc.h b/drivers/net/wireless/ath/ath6kl/btc.h
deleted file mode 100644
index 71075a8..0000000
--- a/drivers/net/wireless/ath/ath6kl/btc.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef BTC_H
-#define BTC_H
-#include <net/iw_handler.h>
-
-#define EVENT_ID_LEN 2
-
-void cfg80211_send_genevent_to_app(struct net_device *dev,
- u16 event_id,
- u8 *datap, int len)
-{
- char *buf;
- u16 size;
- union iwreq_data wrqu;
-
- size = len + EVENT_ID_LEN;
-
- if (size > IW_GENERIC_IE_MAX)
- return;
-
- buf = kmalloc(size, GFP_ATOMIC);
- if (buf == NULL)
- return;
-
- memset(buf, 0, size);
- memcpy(buf, &event_id, EVENT_ID_LEN);
- memcpy(buf + EVENT_ID_LEN, datap, len);
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = size;
- wireless_send_event(dev, IWEVGENIE, &wrqu, buf);
- kfree(buf);
-}
-
-void cfg80211_send_event_to_app(struct net_device *dev,
- u16 event_id,
- u8 *datap, int len)
-{
- char *buf;
- u16 size;
- union iwreq_data wrqu;
-
- size = len + EVENT_ID_LEN;
-
- if (size > IW_CUSTOM_MAX)
- return;
-
- buf = kmalloc(size, GFP_ATOMIC);
- if (buf == NULL)
- return;
-
- memset(buf, 0, size);
- memcpy(buf, &event_id, EVENT_ID_LEN);
- memcpy(buf + EVENT_ID_LEN, datap, len);
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = size;
- wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
- kfree(buf);
-}
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/c210.c b/drivers/net/wireless/ath/ath6kl/c210.c
deleted file mode 100644
index bb5f189..0000000
--- a/drivers/net/wireless/ath/ath6kl/c210.c
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <linux/device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/gpio.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-
-#include "core.h"
-
-typedef int A_BOOL;
-typedef unsigned char A_UCHAR;
-typedef unsigned long A_ATH_TIMER;
-typedef int8_t A_INT8;
-typedef int16_t A_INT16;
-typedef int32_t A_INT32;
-typedef u_int8_t A_UINT8;
-typedef u_int16_t A_UINT16;
-typedef u_int32_t A_UINT32;
-
-#define WMI_MAX_SSID_LEN 32
-#define ATH_MAC_LEN 6 /* length of mac in bytes */
-
-#define __ATTRIB_PACK
-#define POSTPACK __ATTRIB_PACK
-#define PREPACK
-
-typedef PREPACK struct {
- PREPACK union {
- A_UINT8 ie[17];
- A_INT32 wac_status;
- } POSTPACK info;
-} POSTPACK WMI_GET_WAC_INFO;
-
-struct ar_wep_key {
- A_UINT8 arKeyIndex;
- A_UINT8 arKeyLen;
- A_UINT8 arKey[64];
-} ;
-
-#define A_MDELAY(msecs) mdelay(msecs)
-
-#define WMI_MAX_RATE_MASK 2
-
-#define GET_INODE_FROM_FILEP(filp) \
- (filp)->f_path.dentry->d_inode
-typedef char A_CHAR;
-int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length)
-{
- int ret = 0;
- struct file *filp = (struct file *)-ENOENT;
- mm_segment_t oldfs;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- do {
- int mode = (wbuf) ? O_RDWR|O_CREAT : O_RDONLY;
- filp = filp_open(filename, mode,
- S_IRUSR | S_IWUSR | S_IRGRP |
- S_IWGRP | S_IROTH | S_IWOTH);
-
- if (IS_ERR(filp) || !filp->f_op) {
- ret = -ENOENT;
- break;
- }
-
- if (length == 0) {
- /* Read the length of the file only */
- struct inode *inode;
-
- inode = GET_INODE_FROM_FILEP(filp);
- if (!inode) {
- printk(KERN_INFO "android_readwrite_file: Error 2\n");
- ret = -ENOENT;
- break;
- }
- ret = i_size_read(inode->i_mapping->host);
- break;
- }
-
- if (wbuf) {
- if ((ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_INFO "android_readwrite_file: Error 3\n");
- break;
- }
- } else {
- if ((ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_INFO "android_readwrite_file: Error 4\n");
- break;
- }
- }
- } while (0);
-
- if (!IS_ERR(filp)) {
- filp_close(filp, NULL);
- }
-
- set_fs(oldfs);
- printk(KERN_INFO "android_readwrite_file: ret=%d\n", ret);
-
- return ret;
-}
-
-extern void wlan_setup_power(int on, int detect);
-
-static int ath6kl_pm_probe(struct platform_device *pdev)
-{
- wlan_setup_power(1,1);
- return 0;
-}
-
-static int ath6kl_pm_remove(struct platform_device *pdev)
-{
- wlan_setup_power(0,1);
- return 0;
-}
-
-static int ath6kl_pm_suspend(struct platform_device *pdev, pm_message_t state)
-{
- return 0;
-}
-
-static inline void *ar6k_priv(struct net_device *dev)
-{
- return (wdev_priv(dev->ieee80211_ptr));
-}
-
-static int ath6kl_pm_resume(struct platform_device *pdev)
-{
- return 0;
-}
-
-
-static struct platform_driver ath6kl_pm_device = {
- .probe = ath6kl_pm_probe,
- .remove = ath6kl_pm_remove,
- .suspend = ath6kl_pm_suspend,
- .resume = ath6kl_pm_resume,
- .driver = {
- .name = "wlan_ar6000_pm_dev",
- },
-};
-
-void __init ath6kl_sdio_init_c210(void)
-{
- platform_driver_register(&ath6kl_pm_device);
- A_MDELAY(50);
-}
-
-void __exit ath6kl_sdio_exit_c210(void)
-{
- platform_driver_unregister(&ath6kl_pm_device);
- A_MDELAY(1000);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
deleted file mode 100755
index cceb9fd..0000000
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ /dev/null
@@ -1,3623 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/moduleparam.h>
-#include <linux/inetdevice.h>
-
-#include "core.h"
-#include "cfg80211.h"
-#include "debug.h"
-#include "hif-ops.h"
-#include "testmode.h"
-#include "cfg80211_btcoex.h"
-#include "pm.h"
-
-#ifdef CONFIG_MACH_PX
-#include <mach/gpio.h>
-#define GPIO_WLAN_nRST EXYNOS4_GPL0(4)
-#else
-#define GPIO_WLAN_nRST 0
-#endif
-
-static unsigned int ath6kl_p2p = 1;
-static unsigned int ath6kl_first_2g_only = 1;
-
-module_param(ath6kl_p2p, uint, 0644);
-module_param(ath6kl_first_2g_only, uint, 0644);
-
-#define RATETAB_ENT(_rate, _rateid, _flags) { \
- .bitrate = (_rate), \
- .flags = (_flags), \
- .hw_value = (_rateid), \
-}
-
-#define CHAN2G(_channel, _freq, _flags) { \
- .band = IEEE80211_BAND_2GHZ, \
- .hw_value = (_channel), \
- .center_freq = (_freq), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-#define CHAN5G(_channel, _flags) { \
- .band = IEEE80211_BAND_5GHZ, \
- .hw_value = (_channel), \
- .center_freq = 5000 + (5 * (_channel)), \
- .flags = (_flags), \
- .max_antenna_gain = 0, \
- .max_power = 30, \
-}
-
-static struct ieee80211_rate ath6kl_rates[] = {
- RATETAB_ENT(10, 0x1, 0),
- RATETAB_ENT(20, 0x2, 0),
- RATETAB_ENT(55, 0x4, 0),
- RATETAB_ENT(110, 0x8, 0),
- RATETAB_ENT(60, 0x10, 0),
- RATETAB_ENT(90, 0x20, 0),
- RATETAB_ENT(120, 0x40, 0),
- RATETAB_ENT(180, 0x80, 0),
- RATETAB_ENT(240, 0x100, 0),
- RATETAB_ENT(360, 0x200, 0),
- RATETAB_ENT(480, 0x400, 0),
- RATETAB_ENT(540, 0x800, 0),
-};
-
-#define ath6kl_a_rates (ath6kl_rates + 4)
-#define ath6kl_a_rates_size 8
-#define ath6kl_g_rates (ath6kl_rates + 0)
-#define ath6kl_g_rates_size 12
-
-
-static struct ieee80211_channel ath6kl_2ghz_channels[] = {
- CHAN2G(1, 2412, 0),
- CHAN2G(2, 2417, 0),
- CHAN2G(3, 2422, 0),
- CHAN2G(4, 2427, 0),
- CHAN2G(5, 2432, 0),
- CHAN2G(6, 2437, 0),
- CHAN2G(7, 2442, 0),
- CHAN2G(8, 2447, 0),
- CHAN2G(9, 2452, 0),
- CHAN2G(10, 2457, 0),
- CHAN2G(11, 2462, 0),
- CHAN2G(12, 2467, 0),
- CHAN2G(13, 2472, 0),
- CHAN2G(14, 2484, 0),
-};
-
-static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
- CHAN5G(34, 0), CHAN5G(36, 0),
- CHAN5G(38, 0), CHAN5G(40, 0),
- CHAN5G(42, 0), CHAN5G(44, 0),
- CHAN5G(46, 0), CHAN5G(48, 0),
- CHAN5G(52, 0), CHAN5G(56, 0),
- CHAN5G(60, 0), CHAN5G(64, 0),
- CHAN5G(100, 0), CHAN5G(104, 0),
- CHAN5G(108, 0), CHAN5G(112, 0),
- CHAN5G(116, 0), CHAN5G(120, 0),
- CHAN5G(124, 0), CHAN5G(128, 0),
- CHAN5G(132, 0), CHAN5G(136, 0),
- CHAN5G(140, 0), CHAN5G(149, 0),
- CHAN5G(153, 0), CHAN5G(157, 0),
- CHAN5G(161, 0), CHAN5G(165, 0),
- CHAN5G(184, 0), CHAN5G(188, 0),
- CHAN5G(192, 0), CHAN5G(196, 0),
- CHAN5G(200, 0), CHAN5G(204, 0),
- CHAN5G(208, 0), CHAN5G(212, 0),
- CHAN5G(216, 0),
-};
-
-static struct ieee80211_supported_band ath6kl_band_2ghz = {
- .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
- .channels = ath6kl_2ghz_channels,
- .n_bitrates = ath6kl_g_rates_size,
- .bitrates = ath6kl_g_rates,
-
-};
-
-static struct ieee80211_supported_band ath6kl_band_5ghz = {
- .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
- .channels = ath6kl_5ghz_a_channels,
- .n_bitrates = ath6kl_a_rates_size,
- .bitrates = ath6kl_a_rates,
-
-};
-
-#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
-
-/* returns true if scheduled scan was stopped */
-static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = vif->ar;
-
- if (ar->state != ATH6KL_STATE_SCHED_SCAN)
- return false;
-
- del_timer_sync(&vif->sched_scan_timer);
-
- ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_HOST_MODE_AWAKE);
-
- ar->state = ATH6KL_STATE_ON;
-
- return true;
-}
-
-static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = vif->ar;
- bool stopped;
-
- stopped = __ath6kl_cfg80211_sscan_stop(vif);
-
- if (!stopped)
- return;
-
- cfg80211_sched_scan_stopped(ar->wiphy);
-}
-
-static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
- enum nl80211_wpa_versions wpa_version)
-{
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
-
- if (!wpa_version) {
- vif->auth_mode = NONE_AUTH;
- } else if (wpa_version & NL80211_WPA_VERSION_2) {
- vif->auth_mode = WPA2_AUTH;
- } else if (wpa_version & NL80211_WPA_VERSION_1) {
- vif->auth_mode = WPA_AUTH;
- } else {
- ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
- enum nl80211_auth_type auth_type)
-{
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
-
- switch (auth_type) {
- case NL80211_AUTHTYPE_OPEN_SYSTEM:
- vif->dot11_auth_mode = OPEN_AUTH;
- break;
- case NL80211_AUTHTYPE_SHARED_KEY:
- vif->dot11_auth_mode = SHARED_AUTH;
- break;
- case NL80211_AUTHTYPE_NETWORK_EAP:
- vif->dot11_auth_mode = LEAP_AUTH;
- break;
-
- case NL80211_AUTHTYPE_AUTOMATIC:
- vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
- break;
-
- default:
- ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
-{
- u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
- u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
- &vif->grp_crypto_len;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
- __func__, cipher, ucast);
-
- switch (cipher) {
- case 0:
- /* our own hack to use value 0 as no crypto used */
- *ar_cipher = NONE_CRYPT;
- *ar_cipher_len = 0;
- break;
- case WLAN_CIPHER_SUITE_WEP40:
- *ar_cipher = WEP_CRYPT;
- *ar_cipher_len = 5;
- break;
- case WLAN_CIPHER_SUITE_WEP104:
- *ar_cipher = WEP_CRYPT;
- *ar_cipher_len = 13;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- *ar_cipher = TKIP_CRYPT;
- *ar_cipher_len = 0;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- *ar_cipher = AES_CRYPT;
- *ar_cipher_len = 0;
- break;
- case WLAN_CIPHER_SUITE_SMS4:
- *ar_cipher = WAPI_CRYPT;
- *ar_cipher_len = 0;
- break;
- default:
- ath6kl_err("cipher 0x%x not supported\n", cipher);
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
-{
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
-
- if (key_mgmt == WLAN_AKM_SUITE_PSK) {
- if (vif->auth_mode == WPA_AUTH)
- vif->auth_mode = WPA_PSK_AUTH;
- else if (vif->auth_mode == WPA2_AUTH)
- vif->auth_mode = WPA2_PSK_AUTH;
- } else if (key_mgmt == 0x00409600) {
- if (vif->auth_mode == WPA_AUTH)
- vif->auth_mode = WPA_AUTH_CCKM;
- else if (vif->auth_mode == WPA2_AUTH)
- vif->auth_mode = WPA2_AUTH_CCKM;
- } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
- vif->auth_mode = NONE_AUTH;
- }
-}
-
-static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = vif->ar;
-
- if (!test_bit(WMI_READY, &ar->flag)) {
- ath6kl_err("wmi is not ready\n");
- return false;
- }
-
- if (!test_bit(WLAN_ENABLED, &vif->flags)) {
- ath6kl_err("wlan disabled\n");
- return false;
- }
-
- return true;
-}
-
-static bool ath6kl_is_wpa_ie(const u8 *pos)
-{
- return pos[0] == WLAN_EID_WPA && pos[1] >= 4 &&
- pos[2] == 0x00 && pos[3] == 0x50 &&
- pos[4] == 0xf2 && pos[5] == 0x01;
-}
-
-static bool ath6kl_is_rsn_ie(const u8 *pos)
-{
- return pos[0] == WLAN_EID_RSN;
-}
-
-static bool ath6kl_is_wps_ie(const u8 *pos)
-{
- return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
- pos[1] >= 4 &&
- pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
- pos[5] == 0x04);
-}
-
-static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
- size_t ies_len)
-{
- struct ath6kl *ar = vif->ar;
- const u8 *pos;
- u8 *buf = NULL;
- size_t len = 0;
- int ret;
-
- /*
- * Clear previously set flag
- */
-
- ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
-
- /*
- * Filter out RSN/WPA IE(s)
- */
-
- if (ies && ies_len) {
- buf = kmalloc(ies_len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- pos = ies;
-
- while (pos + 1 < ies + ies_len) {
- if (pos + 2 + pos[1] > ies + ies_len)
- break;
- if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
- memcpy(buf + len, pos, 2 + pos[1]);
- len += 2 + pos[1];
- }
-
- if (ath6kl_is_wps_ie(pos))
- ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
-
- pos += 2 + pos[1];
- }
- }
-
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_ASSOC_REQ, buf, len);
- kfree(buf);
- return ret;
-}
-
-static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
-{
- switch (type) {
- case NL80211_IFTYPE_STATION:
- *nw_type = INFRA_NETWORK;
- break;
- case NL80211_IFTYPE_ADHOC:
- *nw_type = ADHOC_NETWORK;
- break;
- case NL80211_IFTYPE_AP:
- *nw_type = AP_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- *nw_type = INFRA_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_GO:
- *nw_type = AP_NETWORK;
- break;
- default:
- ath6kl_err("invalid interface type %u\n", type);
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
- u8 *if_idx, u8 *nw_type)
-{
- int i;
-
- if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
- return false;
-
- if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
- ar->num_vif))
- return false;
-
- if (type == NL80211_IFTYPE_STATION ||
- type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
- for (i = 0; i < ar->vif_max; i++) {
- if ((ar->avail_idx_map >> i) & BIT(0)) {
- *if_idx = i;
- return true;
- }
- }
- }
-
- if (type == NL80211_IFTYPE_P2P_CLIENT ||
- type == NL80211_IFTYPE_P2P_GO) {
- for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
- if ((ar->avail_idx_map >> i) & BIT(0)) {
- *if_idx = i;
- return true;
- }
- }
- }
-
- return false;
-}
-
-static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_connect_params *sme)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- int status;
- u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
- u16 interval;
-
- ath6kl_cfg80211_sscan_disable(vif);
-
- vif->sme_state = SME_CONNECTING;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
- ath6kl_err("destroy in progress\n");
- return -EBUSY;
- }
-
- if (test_bit(SKIP_SCAN, &ar->flag) &&
- ((sme->channel && sme->channel->center_freq == 0) ||
- (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
- ath6kl_err("SkipScan: channel or bssid invalid\n");
- return -EINVAL;
- }
-
- if (down_interruptible(&ar->sem)) {
- ath6kl_err("busy, couldn't get access\n");
- return -ERESTARTSYS;
- }
-
- if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
- ath6kl_err("busy, destroy in progress\n");
- up(&ar->sem);
- return -EBUSY;
- }
-
- if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
- /*
- * sleep until the command queue drains
- */
- wait_event_interruptible_timeout(ar->event_wq,
- ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
- WMI_TIMEOUT);
- if (signal_pending(current)) {
- ath6kl_err("cmd queue drain timeout\n");
- up(&ar->sem);
- return -EINTR;
- }
- }
-
- status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
- if (status) {
- up(&ar->sem);
- return status;
- }
-
- if (sme->ie == NULL || sme->ie_len == 0)
- ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
-
- if (test_bit(CONNECTED, &vif->flags) &&
- vif->ssid_len == sme->ssid_len &&
- !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
- vif->reconnect_flag = true;
- status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
- vif->req_bssid,
- vif->ch_hint);
-
- up(&ar->sem);
- if (status) {
- ath6kl_err("wmi_reconnect_cmd failed\n");
- return -EIO;
- }
- return 0;
- } else if (vif->ssid_len == sme->ssid_len &&
- !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
- ath6kl_disconnect(vif);
- }
-
- memset(vif->ssid, 0, sizeof(vif->ssid));
- vif->ssid_len = sme->ssid_len;
- memcpy(vif->ssid, sme->ssid, sme->ssid_len);
-
- if (sme->channel)
- vif->ch_hint = sme->channel->center_freq;
-
- memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
- if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
- memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
-
- ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
-
- status = ath6kl_set_auth_type(vif, sme->auth_type);
- if (status) {
- up(&ar->sem);
- return status;
- }
-
- if (sme->crypto.n_ciphers_pairwise)
- ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
- else
- ath6kl_set_cipher(vif, 0, true);
-
- ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
-
- if (sme->crypto.n_akm_suites)
- ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
-
- if ((sme->key_len) &&
- (vif->auth_mode == NONE_AUTH) &&
- (vif->prwise_crypto == WEP_CRYPT)) {
- struct ath6kl_key *key = NULL;
-
- if (sme->key_idx > WMI_MAX_KEY_INDEX) {
- ath6kl_err("key index %d out of bounds\n",
- sme->key_idx);
- up(&ar->sem);
- return -ENOENT;
- }
-
- key = &vif->keys[sme->key_idx];
- key->key_len = sme->key_len;
- memcpy(key->key, sme->key, key->key_len);
- key->cipher = vif->prwise_crypto;
- vif->def_txkey_index = sme->key_idx;
-
- ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
- vif->prwise_crypto,
- GROUP_USAGE | TX_USAGE,
- key->key_len,
- NULL, 0,
- key->key, KEY_OP_INIT_VAL, NULL,
- NO_SYNC_WMIFLAG);
- }
-
- if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- ALL_BSS_FILTER, 0) != 0) {
- ath6kl_err("couldn't set bss filtering\n");
- up(&ar->sem);
- return -EIO;
- }
- }
-
- vif->nw_type = vif->next_mode;
-
- if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
- nw_subtype = SUBTYPE_P2PCLIENT;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: connect called with authmode %d dot11 auth %d"
- " PW crypto %d PW crypto len %d GRP crypto %d"
- " GRP crypto len %d channel hint %u\n",
- __func__,
- vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
- vif->prwise_crypto_len, vif->grp_crypto,
- vif->grp_crypto_len, vif->ch_hint);
-
- vif->reconnect_flag = 0;
-
- if (vif->nw_type == INFRA_NETWORK) {
- interval = max(vif->listen_intvl_t,
- (u16) ATH6KL_MAX_WOW_LISTEN_INTL);
- status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
- interval,
- 0);
- if (status) {
- ath6kl_err("couldn't set listen intervel\n");
- up(&ar->sem);
- return status;
- }
- }
-
- status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
- vif->dot11_auth_mode, vif->auth_mode,
- vif->prwise_crypto,
- vif->prwise_crypto_len,
- vif->grp_crypto, vif->grp_crypto_len,
- vif->ssid_len, vif->ssid,
- vif->req_bssid, vif->ch_hint,
- ar->connect_ctrl_flags, nw_subtype);
-
- up(&ar->sem);
-
- if (status == -EINVAL) {
- memset(vif->ssid, 0, sizeof(vif->ssid));
- vif->ssid_len = 0;
- ath6kl_err("invalid request\n");
- return -ENOENT;
- } else if (status) {
- ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
- return -EIO;
- }
-
- if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
- ((vif->auth_mode == WPA_PSK_AUTH)
- || (vif->auth_mode == WPA2_PSK_AUTH))) {
- mod_timer(&vif->disconnect_timer,
- jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
- }
-
- ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
- set_bit(CONNECT_PEND, &vif->flags);
-
- return 0;
-}
-
-static struct cfg80211_bss *
-ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
- enum network_type nw_type,
- const u8 *bssid,
- struct ieee80211_channel *chan,
- const u8 *beacon_ie,
- size_t beacon_ie_len)
-{
- struct ath6kl *ar = vif->ar;
- struct cfg80211_bss *bss;
- u16 cap_mask, cap_val;
- u8 *ie;
-
- if (nw_type & ADHOC_NETWORK) {
- cap_mask = WLAN_CAPABILITY_IBSS;
- cap_val = WLAN_CAPABILITY_IBSS;
- } else {
- cap_mask = WLAN_CAPABILITY_ESS;
- cap_val = WLAN_CAPABILITY_ESS;
- }
-
- bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
- vif->ssid, vif->ssid_len,
- cap_mask, cap_val);
- if (bss == NULL) {
- /*
- * Since cfg80211 may not yet know about the BSS,
- * generate a partial entry until the first BSS info
- * event becomes available.
- *
- * Prepend SSID element since it is not included in the Beacon
- * IEs from the target.
- */
- ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
- if (ie == NULL)
- return NULL;
- ie[0] = WLAN_EID_SSID;
- ie[1] = vif->ssid_len;
- memcpy(ie + 2, vif->ssid, vif->ssid_len);
- memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
- bss = cfg80211_inform_bss(ar->wiphy, chan,
- bssid, 0, cap_val, 100,
- ie, 2 + vif->ssid_len + beacon_ie_len,
- 0, GFP_KERNEL);
- if (bss)
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %s to "
- "cfg80211\n", sec_conv_mac(bssid));
- kfree(ie);
- } else
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
-
- return bss;
-}
-
-void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
- u8 *bssid, u16 listen_intvl,
- u16 beacon_intvl,
- enum network_type nw_type,
- u8 beacon_ie_len, u8 assoc_req_len,
- u8 assoc_resp_len, u8 *assoc_info)
-{
- struct ieee80211_channel *chan;
- struct ath6kl *ar = vif->ar;
- struct cfg80211_bss *bss;
-
- /* capinfo + listen interval */
- u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
-
- /* capinfo + status code + associd */
- u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
-
- u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
- u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
- assoc_resp_ie_offset;
-
- assoc_req_len -= assoc_req_ie_offset;
- assoc_resp_len -= assoc_resp_ie_offset;
-
- /*
- * Store Beacon interval here; DTIM period will be available only once
- * a Beacon frame from the AP is seen.
- */
- vif->assoc_bss_beacon_int = beacon_intvl;
- clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
-
- if (nw_type & ADHOC_NETWORK) {
- if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in ibss mode\n", __func__);
- return;
- }
- }
-
- if (nw_type & INFRA_NETWORK) {
- if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
- vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in station mode\n", __func__);
- return;
- }
- }
-
- chan = ieee80211_get_channel(ar->wiphy, (int) channel);
-
- bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
- assoc_info, beacon_ie_len);
- if (!bss) {
- ath6kl_err("could not add cfg80211 bss entry\n");
- return;
- }
-
- if (nw_type & ADHOC_NETWORK) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
- nw_type & ADHOC_CREATOR ? "creator" : "joiner");
- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- cfg80211_put_bss(bss);
- return;
- }
-
- if (vif->sme_state == SME_CONNECTING) {
- /* inform connect result to cfg80211 */
- vif->sme_state = SME_CONNECTED;
- cfg80211_connect_result(vif->ndev, bssid,
- assoc_req_ie, assoc_req_len,
- assoc_resp_ie, assoc_resp_len,
- WLAN_STATUS_SUCCESS, GFP_KERNEL);
- cfg80211_put_bss(bss);
- } else if (vif->sme_state == SME_CONNECTED) {
- /* inform roam event to cfg80211 */
- cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
- assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
- }
-}
-
-static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
- struct net_device *dev, u16 reason_code)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
- reason_code);
-
- ath6kl_cfg80211_sscan_disable(vif);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
- ath6kl_err("busy, destroy in progress\n");
- return -EBUSY;
- }
-
- if (down_interruptible(&ar->sem)) {
- ath6kl_err("busy, couldn't get access\n");
- return -ERESTARTSYS;
- }
-
- vif->reconnect_flag = 0;
- ath6kl_disconnect(vif);
- memset(vif->ssid, 0, sizeof(vif->ssid));
- vif->ssid_len = 0;
-
- if (!test_bit(SKIP_SCAN, &ar->flag))
- memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
-
- up(&ar->sem);
-
- vif->sme_state = SME_DISCONNECTED;
-
- return 0;
-}
-
-void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
- u8 *bssid, u8 assoc_resp_len,
- u8 *assoc_info, u16 proto_reason)
-{
- struct ath6kl *ar = vif->ar;
-
- if (vif->scan_req) {
- cfg80211_scan_done(vif->scan_req, true);
- vif->scan_req = NULL;
- }
-
- if (vif->nw_type & ADHOC_NETWORK) {
- if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in ibss mode\n", __func__);
- return;
- }
- memset(bssid, 0, ETH_ALEN);
- cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
- return;
- }
-
- if (vif->nw_type & INFRA_NETWORK) {
- if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
- vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: ath6k not in station mode\n", __func__);
- return;
- }
- }
-
- /*
- * Send a disconnect command to target when a disconnect event is
- * received with reason code other than 3 (DISCONNECT_CMD - disconnect
- * request from host) to make the firmware stop trying to connect even
- * after giving disconnect event. There will be one more disconnect
- * event for this disconnect command with reason code DISCONNECT_CMD
- * which will be notified to cfg80211.
- */
- if (is_zero_ether_addr((const u8 *) bssid) ||
- memcmp(bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0) {
-
- if (reason != DISCONNECT_CMD) {
- ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
- return;
- }
- }
-
- clear_bit(CONNECT_PEND, &vif->flags);
-
- if (vif->sme_state == SME_CONNECTING) {
- cfg80211_connect_result(vif->ndev,
- bssid, NULL, 0,
- NULL, 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE,
- GFP_KERNEL);
- } else if (vif->sme_state == SME_CONNECTED) {
- cfg80211_disconnected(vif->ndev, reason,
- NULL, 0, GFP_KERNEL);
- }
-
- vif->sme_state = SME_DISCONNECTED;
-}
-
-static int ath6kl_set_probed_ssids(struct ath6kl *ar,
- struct ath6kl_vif *vif,
- struct cfg80211_ssid *ssids, int n_ssids)
-{
- u8 i;
-
- if (n_ssids > MAX_PROBED_SSIDS)
- return -EINVAL;
-
- for (i = 0; i < n_ssids; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
- ssids[i].ssid_len ?
- SPECIFIC_SSID_FLAG : ANY_SSID_FLAG,
- ssids[i].ssid_len,
- ssids[i].ssid);
- }
-
- /* Make sure no old entries are left behind */
- for (i = n_ssids; i < MAX_PROBED_SSIDS; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
- DISABLE_SSID_FLAG, 0, NULL);
- }
-
- return 0;
-}
-
-
-static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_scan_request *request)
-{
- struct ath6kl *ar = ath6kl_priv(ndev);
- struct ath6kl_vif *vif = netdev_priv(ndev);
- s8 n_channels = 0;
- u16 *channels = NULL;
- int ret = 0;
- u32 force_fg_scan = 0;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_cfg80211_sscan_disable(vif);
-
- if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ret = ath6kl_wmi_bssfilter_cmd(
- ar->wmi, vif->fw_vif_idx,
- (test_bit(CONNECTED, &vif->flags) ?
- ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
- if (ret) {
- ath6kl_err("couldn't set bss filtering\n");
- return ret;
- }
- }
-
- ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
- request->n_ssids);
- if (ret < 0)
- return ret;
-
- /* this also clears IE in fw if it's not set */
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_PROBE_REQ,
- request->ie, request->ie_len);
- if (ret) {
- ath6kl_err("failed to set Probe Request appie for "
- "scan");
- return ret;
- }
-
- /*
- * Scan only the requested channels if the request specifies a set of
- * channels. If the list is longer than the target supports, do not
- * configure the list and instead, scan all available channels.
- */
- ath6kl_err("channel num %d \n",request->n_channels);
-#ifdef CONFIG_MACH_PX
- if (request->n_channels > 0) {
-#else
- if (request->n_channels > 0 &&
- request->n_channels <= WMI_MAX_CHANNELS) {
-#endif
- u8 i;
-
- n_channels = request->n_channels;
-
- channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
- if (channels == NULL) {
- ath6kl_warn("failed to set scan channels, "
- "scan all channels");
- n_channels = 0;
- }
-
- for (i = 0; i < n_channels; i++) {
-#if 0
- ath6kl_err("scanning channel %d\n",request->channels[i]->center_freq);
-#endif
- if (ath6kl_first_2g_only
- && request->channels[i]->center_freq > 5000) {
- ath6kl_err("skip 5ghz channel %d %d\n",
- ath6kl_first_2g_only,
- request->channels[i]->center_freq);
- continue;
- }
-
- channels[i] = request->channels[i]->center_freq;
- }
- }
-
- if (ath6kl_first_2g_only)
- ath6kl_first_2g_only = 0;
-
- if (test_bit(CONNECTED, &vif->flags))
- force_fg_scan = 1;
-
- vif->scan_req = request;
-
- if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
- ar->fw_capabilities)) {
- /*
- * If capable of doing P2P mgmt operations using
- * station interface, send additional information like
- * supported rates to advertise and xmit rates for
- * probe requests
- */
- if (request->no_cck) {
-#ifdef CONFIG_HAS_WAKELOCK
- ath6kl_p2p_release_wakelock(ar);
- ath6kl_p2p_acquire_wakelock(ar , n_channels * 200);
-#endif
- }
- ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_LONG_SCAN, force_fg_scan,
- false, 0,
- ATH6KL_FG_SCAN_INTERVAL,
- n_channels, channels,
- request->no_cck,
- request->rates);
- } else {
- ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_LONG_SCAN, force_fg_scan,
- false, 0,
- ATH6KL_FG_SCAN_INTERVAL,
- n_channels, channels);
- }
- if (ret) {
- ath6kl_err("wmi_startscan_cmd failed\n");
- vif->scan_req = NULL;
- }
-
- kfree(channels);
-
- return ret;
-}
-
-void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
-{
- struct ath6kl *ar = vif->ar;
- int i;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
- aborted ? " aborted" : "");
-
- if (!vif->scan_req)
- return;
-
- if (aborted)
- goto out;
-
- if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
- for (i = 0; i < vif->scan_req->n_ssids; i++) {
- ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
- i + 1, DISABLE_SSID_FLAG,
- 0, NULL);
- }
- }
-
-out:
- cfg80211_scan_done(vif->scan_req, aborted);
- vif->scan_req = NULL;
-}
-
-static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise,
- const u8 *mac_addr,
- struct key_params *params)
-{
- struct ath6kl *ar = ath6kl_priv(ndev);
- struct ath6kl_vif *vif = netdev_priv(ndev);
- struct ath6kl_key *key = NULL;
- int seq_len = 0;
- u8 key_usage;
- u8 key_type;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
- if (params->key_len != WMI_KRK_LEN)
- return -EINVAL;
- return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
- params->key);
- }
-
- if (key_index > WMI_MAX_KEY_INDEX) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: key index %d out of bounds\n", __func__,
- key_index);
- return -ENOENT;
- }
-
- key = &vif->keys[key_index];
- memset(key, 0, sizeof(struct ath6kl_key));
-
- if (pairwise)
- key_usage = PAIRWISE_USAGE;
- else
- key_usage = GROUP_USAGE;
-
- seq_len = params->seq_len;
- if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
- seq_len > ATH6KL_KEY_SEQ_LEN) {
- /* Only first half of the WPI PN is configured */
- seq_len = ATH6KL_KEY_SEQ_LEN;
- }
- if (params->key_len > WLAN_MAX_KEY_LEN ||
- seq_len > sizeof(key->seq))
- return -EINVAL;
-
- key->key_len = params->key_len;
- memcpy(key->key, params->key, key->key_len);
- key->seq_len = seq_len;
- memcpy(key->seq, params->seq, key->seq_len);
- key->cipher = params->cipher;
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- key_type = WEP_CRYPT;
- break;
-
- case WLAN_CIPHER_SUITE_TKIP:
- key_type = TKIP_CRYPT;
- break;
-
- case WLAN_CIPHER_SUITE_CCMP:
- key_type = AES_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_SMS4:
- key_type = WAPI_CRYPT;
- break;
-
- default:
- return -ENOTSUPP;
- }
-
- if (((vif->auth_mode == WPA_PSK_AUTH)
- || (vif->auth_mode == WPA2_PSK_AUTH))
- && (key_usage & GROUP_USAGE))
- del_timer(&vif->disconnect_timer);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
- __func__, key_index, key->key_len, key_type,
- key_usage, key->seq_len);
-
- if (vif->nw_type == AP_NETWORK && !pairwise &&
- (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
- key_type == WAPI_CRYPT)) {
- ar->ap_mode_bkey.valid = true;
- ar->ap_mode_bkey.key_index = key_index;
- ar->ap_mode_bkey.key_type = key_type;
- ar->ap_mode_bkey.key_len = key->key_len;
- memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
- if (!test_bit(CONNECTED, &vif->flags)) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
- "key configuration until AP mode has been "
- "started\n");
- /*
- * The key will be set in ath6kl_connect_ap_mode() once
- * the connected event is received from the target.
- */
- return 0;
- }
- }
-
- if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
- !test_bit(CONNECTED, &vif->flags)) {
- /*
- * Store the key locally so that it can be re-configured after
- * the AP mode has properly started
- * (ath6kl_install_statioc_wep_keys).
- */
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
- "until AP mode has been started\n");
- vif->wep_key_list[key_index].key_len = key->key_len;
- memcpy(vif->wep_key_list[key_index].key, key->key,
- key->key_len);
- return 0;
- }
-
- return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
- key_type, key_usage, key->key_len,
- key->seq, key->seq_len, key->key,
- KEY_OP_INIT_VAL,
- (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
-}
-
-static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise,
- const u8 *mac_addr)
-{
- struct ath6kl *ar = ath6kl_priv(ndev);
- struct ath6kl_vif *vif = netdev_priv(ndev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (key_index > WMI_MAX_KEY_INDEX) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: key index %d out of bounds\n", __func__,
- key_index);
- return -ENOENT;
- }
-
- if (!vif->keys[key_index].key_len) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: index %d is empty\n", __func__, key_index);
- return 0;
- }
-
- vif->keys[key_index].key_len = 0;
-
- return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
-}
-
-static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
- u8 key_index, bool pairwise,
- const u8 *mac_addr, void *cookie,
- void (*callback) (void *cookie,
- struct key_params *))
-{
- struct ath6kl_vif *vif = netdev_priv(ndev);
- struct ath6kl_key *key = NULL;
- struct key_params params;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (key_index > WMI_MAX_KEY_INDEX) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: key index %d out of bounds\n", __func__,
- key_index);
- return -ENOENT;
- }
-
- key = &vif->keys[key_index];
- memset(&params, 0, sizeof(params));
- params.cipher = key->cipher;
- params.key_len = key->key_len;
- params.seq_len = key->seq_len;
- params.seq = key->seq;
- params.key = key->key;
-
- callback(cookie, &params);
-
- return key->key_len ? 0 : -ENOENT;
-}
-
-static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
- struct net_device *ndev,
- u8 key_index, bool unicast,
- bool multicast)
-{
- struct ath6kl *ar = ath6kl_priv(ndev);
- struct ath6kl_vif *vif = netdev_priv(ndev);
- struct ath6kl_key *key = NULL;
- u8 key_usage;
- enum crypto_type key_type = NONE_CRYPT;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (key_index > WMI_MAX_KEY_INDEX) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: key index %d out of bounds\n",
- __func__, key_index);
- return -ENOENT;
- }
-
- if (!vif->keys[key_index].key_len) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
- __func__, key_index);
- return -EINVAL;
- }
-
- vif->def_txkey_index = key_index;
- key = &vif->keys[vif->def_txkey_index];
- key_usage = GROUP_USAGE;
- if (vif->prwise_crypto == WEP_CRYPT)
- key_usage |= TX_USAGE;
- if (unicast)
- key_type = vif->prwise_crypto;
- if (multicast)
- key_type = vif->grp_crypto;
-
- if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
- return 0; /* Delay until AP mode has been started */
-
- return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
- vif->def_txkey_index,
- key_type, key_usage,
- key->key_len, key->seq, key->seq_len,
- key->key,
- KEY_OP_INIT_VAL, NULL,
- SYNC_BOTH_WMIFLAG);
-}
-
-void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
- bool ismcast)
-{
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
-
- cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
- (ismcast ? NL80211_KEYTYPE_GROUP :
- NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
- GFP_KERNEL);
-}
-
-static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
- changed);
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
- ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
- if (ret != 0) {
- ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
- return -EIO;
- }
- }
-
- return 0;
-}
-
-/*
- * The type nl80211_tx_power_setting replaces the following
- * data type from 2.6.36 onwards
-*/
-static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
- enum nl80211_tx_power_setting type,
- int mbm)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
- u8 ath6kl_dbm;
- int dbm = MBM_TO_DBM(mbm);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
- type, dbm);
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- switch (type) {
- case NL80211_TX_POWER_AUTOMATIC:
- return 0;
- case NL80211_TX_POWER_LIMITED:
- ar->tx_pwr = ath6kl_dbm = dbm;
- break;
- default:
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
- __func__, type);
- return -EOPNOTSUPP;
- }
-
- ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
-
- return 0;
-}
-
-static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (test_bit(CONNECTED, &vif->flags)) {
- ar->tx_pwr = 0;
-
- if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
- ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
- return -EIO;
- }
-
- wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
- 5 * HZ);
-
- if (signal_pending(current)) {
- ath6kl_err("target did not respond\n");
- return -EINTR;
- }
- }
-
- *dbm = ar->tx_pwr;
- return 0;
-}
-
-static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
- struct net_device *dev,
- bool pmgmt, int timeout)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct wmi_power_mode_cmd mode;
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
- __func__, pmgmt, timeout);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (pmgmt) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
- mode.pwr_mode = REC_POWER;
- } else {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
- mode.pwr_mode = MAX_PERF_POWER;
- }
-
- if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
- mode.pwr_mode) != 0) {
- ath6kl_err("wmi_powermode_cmd failed\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
- char *name,
- enum nl80211_iftype type,
- u32 *flags,
- struct vif_params *params)
-{
- struct ath6kl *ar = wiphy_priv(wiphy);
- struct net_device *ndev;
- u8 if_idx, nw_type;
-
- if (ar->num_vif == ar->vif_max) {
- ath6kl_err("Reached maximum number of supported vif\n");
- return ERR_PTR(-EINVAL);
- }
-
- if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
- ath6kl_err("Not a supported interface type\n");
- return ERR_PTR(-EINVAL);
- }
-
- ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
- if (!ndev)
- return ERR_PTR(-ENOMEM);
-
- ar->num_vif++;
-
- return ndev;
-}
-
-static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
- struct net_device *ndev)
-{
- struct ath6kl *ar = wiphy_priv(wiphy);
- struct ath6kl_vif *vif = netdev_priv(ndev);
-
- spin_lock_bh(&ar->list_lock);
- list_del(&vif->list);
- spin_unlock_bh(&ar->list_lock);
-
- ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
-
- ath6kl_deinit_if_data(vif);
-
- return 0;
-}
-
-static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
- struct net_device *ndev,
- enum nl80211_iftype type, u32 *flags,
- struct vif_params *params)
-{
- struct ath6kl_vif *vif = netdev_priv(ndev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
-
- switch (type) {
- case NL80211_IFTYPE_STATION:
- vif->next_mode = INFRA_NETWORK;
- break;
- case NL80211_IFTYPE_ADHOC:
- vif->next_mode = ADHOC_NETWORK;
- break;
- case NL80211_IFTYPE_AP:
- vif->next_mode = AP_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_CLIENT:
- vif->next_mode = INFRA_NETWORK;
- break;
- case NL80211_IFTYPE_P2P_GO:
- vif->next_mode = AP_NETWORK;
- break;
- default:
- ath6kl_err("invalid interface type %u\n", type);
- return -EOPNOTSUPP;
- }
-
- vif->wdev.iftype = type;
-
- return 0;
-}
-
-static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
- struct net_device *dev,
- struct cfg80211_ibss_params *ibss_param)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- int status;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- vif->ssid_len = ibss_param->ssid_len;
- memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
-
- if (ibss_param->channel)
- vif->ch_hint = ibss_param->channel->center_freq;
-
- if (ibss_param->channel_fixed) {
- /*
- * TODO: channel_fixed: The channel should be fixed, do not
- * search for IBSSs to join on other channels. Target
- * firmware does not support this feature, needs to be
- * updated.
- */
- return -EOPNOTSUPP;
- }
-
- memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
- if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
- memcpy(vif->req_bssid, ibss_param->bssid,
- sizeof(vif->req_bssid));
-
- ath6kl_set_wpa_version(vif, 0);
-
- status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
- if (status)
- return status;
-
- if (ibss_param->privacy) {
- ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
- ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
- } else {
- ath6kl_set_cipher(vif, 0, true);
- ath6kl_set_cipher(vif, 0, false);
- }
-
- vif->nw_type = vif->next_mode;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "%s: connect called with authmode %d dot11 auth %d"
- " PW crypto %d PW crypto len %d GRP crypto %d"
- " GRP crypto len %d channel hint %u\n",
- __func__,
- vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
- vif->prwise_crypto_len, vif->grp_crypto,
- vif->grp_crypto_len, vif->ch_hint);
-
- status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
- vif->dot11_auth_mode, vif->auth_mode,
- vif->prwise_crypto,
- vif->prwise_crypto_len,
- vif->grp_crypto, vif->grp_crypto_len,
- vif->ssid_len, vif->ssid,
- vif->req_bssid, vif->ch_hint,
- ar->connect_ctrl_flags, SUBTYPE_NONE);
- set_bit(CONNECT_PEND, &vif->flags);
-
- return 0;
-}
-
-static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
- struct net_device *dev)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_disconnect(vif);
- memset(vif->ssid, 0, sizeof(vif->ssid));
- vif->ssid_len = 0;
-
- return 0;
-}
-
-static const u32 cipher_suites[] = {
- WLAN_CIPHER_SUITE_WEP40,
- WLAN_CIPHER_SUITE_WEP104,
- WLAN_CIPHER_SUITE_TKIP,
- WLAN_CIPHER_SUITE_CCMP,
- CCKM_KRK_CIPHER_SUITE,
- WLAN_CIPHER_SUITE_SMS4,
-};
-
-static bool is_rate_legacy(s32 rate)
-{
- static const s32 legacy[] = { 1000, 2000, 5500, 11000,
- 6000, 9000, 12000, 18000, 24000,
- 36000, 48000, 54000
- };
- u8 i;
-
- for (i = 0; i < ARRAY_SIZE(legacy); i++)
- if (rate == legacy[i])
- return true;
-
- return false;
-}
-
-static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
-{
- static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
- 52000, 58500, 65000, 72200
- };
- u8 i;
-
- for (i = 0; i < ARRAY_SIZE(ht20); i++) {
- if (rate == ht20[i]) {
- if (i == ARRAY_SIZE(ht20) - 1)
- /* last rate uses sgi */
- *sgi = true;
- else
- *sgi = false;
-
- *mcs = i;
- return true;
- }
- }
- return false;
-}
-
-static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
-{
- static const s32 ht40[] = { 13500, 27000, 40500, 54000,
- 81000, 108000, 121500, 135000,
- 150000
- };
- u8 i;
-
- for (i = 0; i < ARRAY_SIZE(ht40); i++) {
- if (rate == ht40[i]) {
- if (i == ARRAY_SIZE(ht40) - 1)
- /* last rate uses sgi */
- *sgi = true;
- else
- *sgi = false;
-
- *mcs = i;
- return true;
- }
- }
-
- return false;
-}
-
-static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
- u8 *mac, struct station_info *sinfo)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- long left;
- bool sgi;
- s32 rate;
- int ret;
- u8 mcs;
-
- if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
- return -ENOENT;
-
- if (down_interruptible(&ar->sem))
- return -EBUSY;
-
- set_bit(STATS_UPDATE_PEND, &vif->flags);
-
- ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
-
- if (ret != 0) {
- up(&ar->sem);
- return -EIO;
- }
-
- left = wait_event_interruptible_timeout(ar->event_wq,
- !test_bit(STATS_UPDATE_PEND,
- &vif->flags),
- WMI_TIMEOUT);
-
- up(&ar->sem);
-
- if (left == 0)
- return -ETIMEDOUT;
- else if (left < 0)
- return left;
-
- if (vif->target_stats.rx_byte) {
- sinfo->rx_bytes = vif->target_stats.rx_byte;
- sinfo->filled |= STATION_INFO_RX_BYTES;
- sinfo->rx_packets = vif->target_stats.rx_pkt;
- sinfo->filled |= STATION_INFO_RX_PACKETS;
- }
-
- if (vif->target_stats.tx_byte) {
- sinfo->tx_bytes = vif->target_stats.tx_byte;
- sinfo->filled |= STATION_INFO_TX_BYTES;
- sinfo->tx_packets = vif->target_stats.tx_pkt;
- sinfo->filled |= STATION_INFO_TX_PACKETS;
- }
-
- sinfo->signal = vif->target_stats.cs_rssi;
- sinfo->filled |= STATION_INFO_SIGNAL;
-
- rate = vif->target_stats.tx_ucast_rate;
-
- if (is_rate_legacy(rate)) {
- sinfo->txrate.legacy = rate / 100;
- } else if (is_rate_ht20(rate, &mcs, &sgi)) {
- if (sgi) {
- sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- sinfo->txrate.mcs = mcs - 1;
- } else {
- sinfo->txrate.mcs = mcs;
- }
-
- sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
- } else if (is_rate_ht40(rate, &mcs, &sgi)) {
- if (sgi) {
- sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- sinfo->txrate.mcs = mcs - 1;
- } else {
- sinfo->txrate.mcs = mcs;
- }
-
- sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
- sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
- } else {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "invalid rate from stats: %d\n", rate);
- ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
- return 0;
- }
-
- sinfo->filled |= STATION_INFO_TX_BITRATE;
-
- if (test_bit(CONNECTED, &vif->flags) &&
- test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
- vif->nw_type == INFRA_NETWORK) {
- sinfo->filled |= STATION_INFO_BSS_PARAM;
- sinfo->bss_param.flags = 0;
- sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
- sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
- }
-
- return 0;
-}
-
-static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
- struct cfg80211_pmksa *pmksa)
-{
- struct ath6kl *ar = ath6kl_priv(netdev);
- struct ath6kl_vif *vif = netdev_priv(netdev);
-
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
- pmksa->pmkid, true);
-}
-
-static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
- struct cfg80211_pmksa *pmksa)
-{
- struct ath6kl *ar = ath6kl_priv(netdev);
- struct ath6kl_vif *vif = netdev_priv(netdev);
-
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
- pmksa->pmkid, false);
-}
-
-static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
-{
- struct ath6kl *ar = ath6kl_priv(netdev);
- struct ath6kl_vif *vif = netdev_priv(netdev);
-
- if (test_bit(CONNECTED, &vif->flags))
- return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
- vif->bssid, NULL, false);
- return 0;
-}
-
-static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
- struct cfg80211_wowlan *wow, u32 *filter)
-{
- int ret, pos;
- u8 mask[WOW_MASK_SIZE];
- u16 i;
-
- /* Configure the patterns that we received from the user. */
- for (i = 0; i < wow->n_patterns; i++) {
-
- /*
- * Convert given nl80211 specific mask value to equivalent
- * driver specific mask value and send it to the chip along
- * with patterns. For example, If the mask value defined in
- * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
- * then equivalent driver specific mask value is
- * "0xFF 0x00 0xFF 0x00".
- */
- memset(&mask, 0, sizeof(mask));
- for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
- if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
- mask[pos] = 0xFF;
- }
- /*
- * Note: Pattern's offset is not passed as part of wowlan
- * parameter from CFG layer. So it's always passed as ZERO
- * to the firmware. It means, given WOW patterns are always
- * matched from the first byte of received pkt in the firmware.
- */
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- wow->patterns[i].pattern_len,
- 0 /* pattern offset */,
- wow->patterns[i].pattern, mask);
- if (ret)
- return ret;
- }
-
- if (wow->disconnect)
- *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
-
- if (wow->magic_pkt)
- *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
-
- if (wow->gtk_rekey_failure)
- *filter |= WOW_FILTER_OPTION_GTK_ERROR;
-
- if (wow->eap_identity_req)
- *filter |= WOW_FILTER_OPTION_EAP_REQ;
-
- if (wow->four_way_handshake)
- *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
-
- return 0;
-}
-
-static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
-{
- static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x08 };
- static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7f };
- u8 unicst_offset = 0;
- static const u8 arp_pattern[] = { 0x08, 0x06 };
- static const u8 arp_mask[] = { 0xff, 0xff };
- u8 arp_offset = 20;
- static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
- static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
- u8 discvr_offset = 38;
- static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
- static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
- u8 dhcp_offset = 0;
- int ret;
-
- /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- sizeof(unicst_pattern), unicst_offset,
- unicst_pattern, unicst_mask);
- if (ret) {
- ath6kl_err("failed to add WOW unicast IP pattern\n");
- return ret;
- }
-
- /* Setup all ARP pkt pattern */
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- sizeof(arp_pattern), arp_offset,
- arp_pattern, arp_mask);
- if (ret) {
- ath6kl_err("failed to add WOW ARP pattern\n");
- return ret;
- }
-
- /*
- * Setup multicast pattern for mDNS 224.0.0.251,
- * SSDP 239.255.255.250 and LLMNR 224.0.0.252
- */
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- sizeof(discvr_pattern), discvr_offset,
- discvr_pattern, discvr_mask);
- if (ret) {
- ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
- return ret;
- }
-
- /* Setup all DHCP broadcast pkt pattern */
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- sizeof(dhcp_pattern), dhcp_offset,
- dhcp_pattern, dhcp_mask);
- if (ret) {
- ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
-{
- struct net_device *ndev = vif->ndev;
- static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
- static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
- u8 discvr_offset = 38;
- u8 mac_mask[ETH_ALEN];
- int ret;
-
- /* Setup unicast pkt pattern */
- memset(mac_mask, 0xff, ETH_ALEN);
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- ETH_ALEN, 0, ndev->dev_addr,
- mac_mask);
- if (ret) {
- ath6kl_err("failed to add WOW unicast pattern\n");
- return ret;
- }
-
- /*
- * Setup multicast pattern for mDNS 224.0.0.251,
- * SSDP 239.255.255.250 and LLMNR 224.0.0.252
- */
- if ((ndev->flags & IFF_ALLMULTI) ||
- (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
- ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
- vif->fw_vif_idx, WOW_LIST_ID,
- sizeof(discvr_pattern), discvr_offset,
- discvr_pattern, discvr_mask);
- if (ret) {
- ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
- "pattern\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
-{
- return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
-}
-
-static bool is_ctrl_ep_empty(struct ath6kl *ar)
-{
- return !ar->tx_pending[ar->ctrl_ep];
-}
-
-static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
-{
- int ret, left;
-
- clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
-
- ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_HOST_MODE_ASLEEP);
- if (ret)
- return ret;
-
- left = wait_event_interruptible_timeout(ar->event_wq,
- is_hsleep_mode_procsed(vif),
- WMI_TIMEOUT);
- if (left == 0) {
- ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
- ret = -ETIMEDOUT;
- } else if (left < 0) {
- ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
- left);
- ret = left;
- }
-
- if (ar->tx_pending[ar->ctrl_ep]) {
- left = wait_event_interruptible_timeout(ar->event_wq,
- is_ctrl_ep_empty(ar),
- WMI_TIMEOUT);
- if (left == 0) {
- ath6kl_warn("clear wmi ctrl data timeout\n");
- ret = -ETIMEDOUT;
- } else if (left < 0) {
- ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
- ret = left;
- }
- }
-
- return ret;
-}
-
-static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
-{
- struct in_device *in_dev;
- struct in_ifaddr *ifa;
- struct ath6kl_vif *vif;
- int ret;
- u32 filter = 0;
- u16 i, bmiss_time;
- u8 index = 0;
- __be32 ips[MAX_IP_ADDRS];
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (!test_bit(CONNECTED, &vif->flags))
- return -ENOTCONN;
-
- if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
- return -EINVAL;
-
- /* Clear existing WOW patterns */
- for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
- ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
- WOW_LIST_ID, i);
-
- /*
- * Skip the default WOW pattern configuration
- * if the driver receives any WOW patterns from
- * the user.
- */
- if (wow)
- ret = ath6kl_wow_usr(ar, vif, wow, &filter);
- else if (vif->nw_type == AP_NETWORK)
- ret = ath6kl_wow_ap(ar, vif);
- else
- ret = ath6kl_wow_sta(ar, vif);
-
- if (ret)
- return ret;
-
- netif_stop_queue(vif->ndev);
-
- if (vif->nw_type != AP_NETWORK) {
- ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_MAX_WOW_LISTEN_INTL,
- 0);
- if (ret)
- return ret;
-
- /* Set listen interval x 15 times as bmiss time */
- bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
- if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
- bmiss_time = ATH6KL_MAX_BMISS_TIME;
-
- ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
- bmiss_time, 0);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
- 0xFFFF, 0, 0xFFFF, 0, 0, 0,
- 0, 0, 0, 0);
- if (ret)
- return ret;
- }
-
- ar->state = ATH6KL_STATE_SUSPENDING;
-
- /* Setup own IP addr for ARP agent. */
- in_dev = __in_dev_get_rtnl(vif->ndev);
- if (!in_dev)
- goto skip_arp;
-
- ifa = in_dev->ifa_list;
- memset(&ips, 0, sizeof(ips));
-
- /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
- while (index < MAX_IP_ADDRS && ifa) {
- ips[index] = ifa->ifa_local;
- ifa = ifa->ifa_next;
- index++;
- }
-
- if (ifa) {
- ath6kl_err("total IP addr count is exceeding fw limit\n");
- return -EINVAL;
- }
-
- ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
- if (ret) {
- ath6kl_err("fail to setup ip for arp agent\n");
- return ret;
- }
-
-skip_arp:
- ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_WOW_MODE_ENABLE,
- filter,
- WOW_HOST_REQ_DELAY);
- if (ret)
- return ret;
-
- ret = ath6kl_cfg80211_host_sleep(ar, vif);
- if (ret)
- return ret;
-
-
- ret = ath6kl_hif_wait_for_pending_recv(ar);
-
- return ret;
-}
-
-static int ath6kl_wow_resume(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif;
- int ret;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (ar->state == ATH6KL_STATE_RESUMING)
- return 0;
-
- ar->state = ATH6KL_STATE_RESUMING;
-
-#ifdef CONFIG_HAS_WAKELOCK
- wake_lock_timeout(&ar->wake_lock, 5 * HZ);
-#endif
- ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_HOST_MODE_AWAKE);
- if (ret) {
- ath6kl_warn("Failed to configure host sleep mode for "
- "wow resume: %d\n", ret);
- ar->state = ATH6KL_STATE_WOW;
- return ret;
- }
-
- if (vif->nw_type != AP_NETWORK) {
- ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
- 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
- vif->listen_intvl_t, 0);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
- vif->bmiss_time_t, 0);
- if (ret)
- return ret;
- }
-
- ar->state = ATH6KL_STATE_ON;
-
- netif_wake_queue(vif->ndev);
-
- return 0;
-}
-
-static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif;
- int ret;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_cfg80211_stop_all(ar);
-
- /* Save the current power mode before enabling power save */
- ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
-
- ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
- if (ret)
- return ret;
-
- /* Disable WOW mode */
- ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_WOW_MODE_DISABLE,
- 0, 0);
- if (ret)
- return ret;
-
- /* Flush all non control pkts in TX path */
- ath6kl_tx_data_cleanup(ar);
-
- ret = ath6kl_cfg80211_host_sleep(ar, vif);
- if (ret)
- return ret;
-
-
- ret = ath6kl_hif_wait_for_pending_recv(ar);
-
- return ret;
-}
-
-static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif;
- int ret;
-
- vif = ath6kl_vif_first(ar);
-
- if (!vif)
- return -EIO;
-
- if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
- ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
- ar->wmi->saved_pwr_mode);
- if (ret)
- return ret;
- }
-
- ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_HOST_MODE_AWAKE);
- if (ret)
- return ret;
-
- ar->state = ATH6KL_STATE_ON;
-
- /* Reset scan parameter to default values */
- ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
- 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int ath6kl_cfg80211_suspend(struct ath6kl *ar,
- enum ath6kl_cfg_suspend_mode mode,
- struct cfg80211_wowlan *wow)
-{
- enum ath6kl_state prev_state;
- int ret;
- struct ath6kl_vif *vif;
-
- switch (mode) {
- case ATH6KL_CFG_SUSPEND_WOW:
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
-
- /* Flush all non control pkts in TX path */
- ath6kl_tx_data_cleanup(ar);
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
- false);
- if (ret)
- return ret;
-
- prev_state = ar->state;
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_wow_suspend()+ check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- ret = ath6kl_wow_suspend(ar, wow);
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_wow_suspend()- check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- if (ret) {
- ath6kl_err("wow suspend failed: %d\n", ret);
- ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
- vif->fw_vif_idx, true);
- ar->state = prev_state;
- return ret;
- }
- set_bit(WOW_RESUME_PRINT, &ar->flag);
- ar->state = ATH6KL_STATE_WOW;
- break;
-
- case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deepsleep mode suspend\n");
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_deepsleep_suspend()+ check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- ret = ath6kl_cfg80211_deepsleep_suspend(ar);
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_deepsleep_suspend()- check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
-
- if (ret) {
- ath6kl_err("deepsleep suspend failed: %d\n", ret);
- return ret;
- }
-
- ar->state = ATH6KL_STATE_DEEPSLEEP;
-
- break;
-
- case ATH6KL_CFG_SUSPEND_CUTPOWER:
-
- ath6kl_cfg80211_stop_all(ar);
-
- if (ar->state == ATH6KL_STATE_OFF) {
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "suspend hw off, no action for cutpower\n");
- break;
- }
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
-
- ret = ath6kl_init_hw_stop(ar);
- if (ret) {
- ath6kl_warn("failed to stop hw during suspend: %d\n",
- ret);
- }
-
- ar->state = ATH6KL_STATE_CUTPOWER;
-
- break;
-
- case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
- /*
- * Nothing needed for schedule scan, firmware is already in
- * wow mode and sleeping most of the time.
- */
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-int ath6kl_cfg80211_resume(struct ath6kl *ar)
-{
- int ret;
- struct ath6kl_vif *vif;
-
- switch (ar->state) {
- case ATH6KL_STATE_WOW:
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_wow_resume()+ check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- ret = ath6kl_wow_resume(ar);
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_wow_resume()- check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- if (ret) {
- ath6kl_warn("wow mode resume failed: %d\n", ret);
- return ret;
- }
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
- true);
-
- if (ret)
- return ret;
-
- break;
-
- case ATH6KL_STATE_DEEPSLEEP:
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
-
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_deepsleep_resume()+ check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- ret = ath6kl_cfg80211_deepsleep_resume(ar);
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "ath6kl_deepsleep_resume()- check GPIO_WLAN_nRST - %d\n",
- GPIO_WLAN_nRST ? gpio_get_value(GPIO_WLAN_nRST) : 0xFF);
- if (ret) {
- ath6kl_warn("deep sleep resume failed: %d\n", ret);
- return ret;
- }
- break;
-
- case ATH6KL_STATE_CUTPOWER:
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
-
- ret = ath6kl_init_hw_start(ar);
- if (ret) {
- ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
- return ret;
- }
- break;
-
- case ATH6KL_STATE_SCHED_SCAN:
-#ifdef CONFIG_HAS_WAKELOCK
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan 30s wake lock\n");
- wake_lock_timeout(&ar->wake_lock, 30 * HZ);
-#endif
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-
-/* hif layer decides what suspend mode to use */
-static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
- struct cfg80211_wowlan *wow)
-{
-#ifdef CONFIG_MACH_PX
- return 0;
-#else
- struct ath6kl *ar = wiphy_priv(wiphy);
-
- return ath6kl_hif_suspend(ar, wow);
-#endif
-}
-
-static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
-{
-#ifdef CONFIG_MACH_PX
- return 0;
-#else
- struct ath6kl *ar = wiphy_priv(wiphy);
-
- return ath6kl_hif_resume(ar);
-#endif
-}
-
-/*
- * FIXME: WOW suspend mode is selected if the host sdio controller supports
- * both sdio irq wake up and keep power. The target pulls sdio data line to
- * wake up the host when WOW pattern matches. This causes sdio irq handler
- * is being called in the host side which internally hits ath6kl's RX path.
- *
- * Since sdio interrupt is not disabled, RX path executes even before
- * the host executes the actual resume operation from PM module.
- *
- * In the current scenario, WOW resume should happen before start processing
- * any data from the target. So It's required to perform WOW resume in RX path.
- * Ideally we should perform WOW resume only in the actual platform
- * resume path. This area needs bit rework to avoid WOW resume in RX path.
- *
- * ath6kl_check_wow_status() is called from ath6kl_rx().
- */
-void ath6kl_check_wow_status(struct ath6kl *ar, struct sk_buff *skb,
- bool is_event_pkt)
-{
-
- if (in_interrupt()) {
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "%s() called in sw interrupt context\n", __func__);
- return;
- }
-
- if (ar->state == ATH6KL_STATE_SUSPENDING) {
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "%s() received IRQ while we are WoW suspending\n",
- __func__);
- return;
- }
-
- ath6kl_config_suspend_wake_lock(ar, skb, is_event_pkt);
-
- if (ar->state == ATH6KL_STATE_WOW || ar->state == ATH6KL_STATE_SCHED_SCAN)
- ath6kl_cfg80211_resume(ar);
-
-}
-
-#else
-
-void ath6kl_check_wow_status(struct ath6kl *ar, struct sk_buff *skb,
- bool is_event_pkt)
-{
-}
-#endif
-
-static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
-{
- struct ath6kl_vif *vif;
-
- /*
- * 'dev' could be NULL if a channel change is required for the hardware
- * device itself, instead of a particular VIF.
- *
- * FIXME: To be handled properly when monitor mode is supported.
- */
- if (!dev)
- return -EBUSY;
-
- vif = netdev_priv(dev);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
- __func__, chan->center_freq, chan->hw_value);
- vif->next_chan = chan->center_freq;
-
- return 0;
-}
-
-static int ath6kl_priv_cmd(struct wiphy *wiphy, struct net_device *dev,
- char *priv_cmd)
-{
- struct ath6kl_vif *vif;
- struct ath6kl *ar;
-
- if (!dev)
- return -EBUSY;
-
- vif = netdev_priv(dev);
- ar = wiphy_priv(wiphy);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: priv_cmd %s\n",
- __func__, priv_cmd);
-
- if (strcasecmp(priv_cmd, "STOP") == 0) {
-
- /* assume that sleep policy is deep-sleep mode
- ath6kl will support cutpower-mode as well in generlized way */
- if (down_interruptible(&ar->sem)) {
- ath6kl_err("busy, couldn't get access\n");
- return -ERESTARTSYS;
- }
-
- if (test_bit(CONNECTED, &vif->flags) ||
- test_bit(CONNECT_PEND, &vif->flags)) {
- vif->reconnect_flag = 0;
- ath6kl_disconnect(vif);
- memset(vif->ssid, 0, sizeof(vif->ssid));
- vif->ssid_len = 0;
-
- if (!test_bit(SKIP_SCAN, &ar->flag))
- memset(vif->req_bssid, 0,
- sizeof(vif->req_bssid));
- }
-
- up(&ar->sem);
-
- if (vif->scan_req) {
- cfg80211_scan_done(vif->scan_req, true);
- vif->scan_req = NULL;
- }
-
- set_bit(SLEEP_POLICY_ENABLED, &vif->flags);
- ath6kl_hif_suspend(ar, NULL);
- } else if (strcasecmp(priv_cmd, "START") == 0) {
- ath6kl_hif_resume(ar);
- clear_bit(SLEEP_POLICY_ENABLED, &vif->flags);
- }
-
- return 0;
-
-}
-
-static bool ath6kl_is_p2p_ie(const u8 *pos)
-{
- return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
- pos[2] == 0x50 && pos[3] == 0x6f &&
- pos[4] == 0x9a && pos[5] == 0x09;
-}
-
-static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
- const u8 *ies, size_t ies_len)
-{
- struct ath6kl *ar = vif->ar;
- const u8 *pos;
- u8 *buf = NULL;
- size_t len = 0;
- int ret;
-
- /*
- * Filter out P2P IE(s) since they will be included depending on
- * the Probe Request frame in ath6kl_send_go_probe_resp().
- */
-
- if (ies && ies_len) {
- buf = kmalloc(ies_len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- pos = ies;
- while (pos + 1 < ies + ies_len) {
- if (pos + 2 + pos[1] > ies + ies_len)
- break;
- if (!ath6kl_is_p2p_ie(pos)) {
- memcpy(buf + len, pos, 2 + pos[1]);
- len += 2 + pos[1];
- }
- pos += 2 + pos[1];
- }
- }
-
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_PROBE_RESP, buf, len);
- kfree(buf);
- return ret;
-}
-
-static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
- struct beacon_parameters *info, bool add)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- struct ieee80211_mgmt *mgmt;
- bool hidden = false;
- u8 *ies;
- int ies_len;
- struct wmi_connect_cmd p;
- int res;
- int i, ret;
- u8 *rsn_ie;
- int rsn_ie_len;
- u16 cnt;
- u16 rsn_capb;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
-
- if (!ath6kl_cfg80211_ready(vif))
- return -EIO;
-
- if (vif->next_mode != AP_NETWORK)
- return -EOPNOTSUPP;
-
- /* this also clears IE in fw if it's not set */
- res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_BEACON,
- info->beacon_ies,
- info->beacon_ies_len);
- if (res)
- return res;
-
- /* this also clears IE in fw if it's not set */
- res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
- info->proberesp_ies_len);
- if (res)
- return res;
-
- /* this also clears IE in fw if it's not set */
- res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_ASSOC_RESP,
- info->assocresp_ies,
- info->assocresp_ies_len);
- if (res)
- return res;
-
- if (!add)
- return 0;
-
- ar->ap_mode_bkey.valid = false;
-
- /* TODO:
- * info->interval
- * info->dtim_period
- */
-
- if (info->head == NULL)
- return -EINVAL;
- mgmt = (struct ieee80211_mgmt *) info->head;
- ies = mgmt->u.beacon.variable;
- if (ies > info->head + info->head_len)
- return -EINVAL;
- ies_len = info->head + info->head_len - ies;
-
- if (info->ssid == NULL)
- return -EINVAL;
- memcpy(vif->ssid, info->ssid, info->ssid_len);
- vif->ssid_len = info->ssid_len;
- if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
- hidden = true;
-
- res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
- if (res)
- return res;
-
- ret = ath6kl_set_auth_type(vif, info->auth_type);
- if (ret)
- return ret;
-
- memset(&p, 0, sizeof(p));
-
- for (i = 0; i < info->crypto.n_akm_suites; i++) {
- switch (info->crypto.akm_suites[i]) {
- case WLAN_AKM_SUITE_8021X:
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
- p.auth_mode |= WPA_AUTH;
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- p.auth_mode |= WPA2_AUTH;
- break;
- case WLAN_AKM_SUITE_PSK:
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
- p.auth_mode |= WPA_PSK_AUTH;
- if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
- p.auth_mode |= WPA2_PSK_AUTH;
- break;
- }
- }
- if (p.auth_mode == 0)
- p.auth_mode = NONE_AUTH;
- vif->auth_mode = p.auth_mode;
-
- for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
- switch (info->crypto.ciphers_pairwise[i]) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- p.prwise_crypto_type |= WEP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- p.prwise_crypto_type |= TKIP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- p.prwise_crypto_type |= AES_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_SMS4:
- p.prwise_crypto_type |= WAPI_CRYPT;
- break;
- }
- }
- if (p.prwise_crypto_type == 0) {
- p.prwise_crypto_type = NONE_CRYPT;
- ath6kl_set_cipher(vif, 0, true);
- } else if (info->crypto.n_ciphers_pairwise == 1)
- ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
-
- switch (info->crypto.cipher_group) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- p.grp_crypto_type = WEP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- p.grp_crypto_type = TKIP_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- p.grp_crypto_type = AES_CRYPT;
- break;
- case WLAN_CIPHER_SUITE_SMS4:
- p.grp_crypto_type = WAPI_CRYPT;
- break;
- default:
- p.grp_crypto_type = NONE_CRYPT;
- break;
- }
- ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
-
- p.nw_type = AP_NETWORK;
- vif->nw_type = vif->next_mode;
-
- p.ssid_len = vif->ssid_len;
- memcpy(p.ssid, vif->ssid, vif->ssid_len);
- p.dot11_auth_mode = vif->dot11_auth_mode;
- p.ch = cpu_to_le16(vif->next_chan);
-
- /*
- * Get the PTKSA replay counter in the RSN IE. Supplicant
- * will use the RSN IE in M3 message and firmware has to
- * advertise the same in beacon/probe response. Send
- * the complete RSN IE capability field to firmware
- */
- if ((p.auth_mode & (WPA2_AUTH | WPA2_PSK_AUTH)) && (info->tail) &&
- test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
- ar->fw_capabilities)) {
- rsn_capb = 0;
- rsn_ie = (u8 *)cfg80211_find_ie(WLAN_EID_RSN, info->tail,
- info->tail_len);
- if (rsn_ie) {
- rsn_ie_len = *(rsn_ie + 1);
- rsn_ie += 2; /* skip element id and length */
- do {
- /* skip version, group cipher */
- if (rsn_ie_len < 6)
- break;
- rsn_ie += 6;
- rsn_ie_len -= 6;
- /* skip pairwise cipher suite */
- if (rsn_ie_len < 2)
- break;
- cnt = *((u16 *)rsn_ie);
- rsn_ie += (2 + cnt * 4);
- rsn_ie_len -= (2 + cnt * 4);
- /* skip akm suite */
- if (rsn_ie_len < 2)
- break;
- cnt = *((u16 *)rsn_ie);
- rsn_ie += (2 + cnt * 4);
- rsn_ie_len -= (2 + cnt * 4);
- if (rsn_ie_len < 2)
- break;
- rsn_capb = *((u16 *)rsn_ie);
- } while (0);
- rsn_capb = cpu_to_le16(rsn_capb);
- res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
- WLAN_EID_RSN, WMI_RSN_IE_CAPB,
- (const u8 *)&rsn_capb, sizeof(rsn_capb));
- if (res < 0)
- return res;
- }
- }
-
- /* Enable uAPSD support by default */
- res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
- if (res < 0)
- return res;
-
- if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
- p.nw_subtype = SUBTYPE_P2PGO;
- } else {
- /*
- * Due to firmware limitation, it is not possible to
- * do P2P mgmt operations in AP mode
- */
- p.nw_subtype = SUBTYPE_NONE;
- }
-
- res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
- if (res < 0)
- return res;
-
- return 0;
-}
-
-static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
- struct beacon_parameters *info)
-{
- return ath6kl_ap_beacon(wiphy, dev, info, true);
-}
-
-static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
- struct beacon_parameters *info)
-{
- return ath6kl_ap_beacon(wiphy, dev, info, false);
-}
-
-static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- if (vif->nw_type != AP_NETWORK)
- return -EOPNOTSUPP;
- if (!test_bit(CONNECTED, &vif->flags))
- return -ENOTCONN;
-
- ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
- clear_bit(CONNECTED, &vif->flags);
-
- return 0;
-}
-
-static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
- u8 *mac)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- const u8 *addr = mac ? mac : bcast_addr;
-
- return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
- addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
-}
-
-static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
- u8 *mac, struct station_parameters *params)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- if (vif->nw_type != AP_NETWORK)
- return -EOPNOTSUPP;
-
- /* Use this only for authorizing/unauthorizing a station */
- if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
- return -EOPNOTSUPP;
-
- if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
- return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
- WMI_AP_MLME_AUTHORIZE, mac, 0);
- return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
- WMI_AP_MLME_UNAUTHORIZE, mac, 0);
-}
-
-static int ath6kl_remain_on_channel(struct wiphy *wiphy,
- struct net_device *dev,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
- unsigned int duration,
- u64 *cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- u32 id;
-#ifdef CONFIG_HAS_WAKELOCK
- ath6kl_p2p_release_wakelock(ar);
- ath6kl_p2p_acquire_wakelock(ar , duration + 100);
-#endif
- /* TODO: if already pending or ongoing remain-on-channel,
- * return -EBUSY */
- id = ++vif->last_roc_id;
- if (id == 0) {
- /* Do not use 0 as the cookie value */
- id = ++vif->last_roc_id;
- }
- *cookie = id;
-
- return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
- chan->center_freq, duration);
-}
-
-static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
- struct net_device *dev,
- u64 cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- if (cookie != vif->last_roc_id)
- return -ENOENT;
- vif->last_cancel_roc_id = cookie;
-
- return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
-}
-
-static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
- const u8 *buf, size_t len,
- unsigned int freq)
-{
- struct ath6kl *ar = vif->ar;
- const u8 *pos;
- u8 *p2p;
- int p2p_len;
- int ret;
- const struct ieee80211_mgmt *mgmt;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
-
- /* Include P2P IE(s) from the frame generated in user space. */
-
- p2p = kmalloc(len, GFP_KERNEL);
- if (p2p == NULL)
- return -ENOMEM;
- p2p_len = 0;
-
- pos = mgmt->u.probe_resp.variable;
- while (pos + 1 < buf + len) {
- if (pos + 2 + pos[1] > buf + len)
- break;
- if (ath6kl_is_p2p_ie(pos)) {
- memcpy(p2p + p2p_len, pos, 2 + pos[1]);
- p2p_len += 2 + pos[1];
- }
- pos += 2 + pos[1];
- }
-
- ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
- mgmt->da, p2p, p2p_len);
- kfree(p2p);
- return ret;
-}
-
-static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
- u32 id,
- u32 freq,
- u32 wait,
- const u8 *buf,
- size_t len,
- bool *more_data,
- bool no_cck)
-{
- struct ieee80211_mgmt *mgmt;
- struct ath6kl_sta *conn;
- bool is_psq_empty = false;
- struct ath6kl_mgmt_buff *mgmt_buf;
- size_t mgmt_buf_size;
- struct ath6kl *ar = vif->ar;
-
- mgmt = (struct ieee80211_mgmt *) buf;
- if (is_multicast_ether_addr(mgmt->da))
- return false;
-
- conn = ath6kl_find_sta(vif, mgmt->da);
- if (!conn)
- return false;
-
- if (conn->sta_flags & STA_PS_SLEEP) {
- if (!(conn->sta_flags & STA_PS_POLLED)) {
- /* Queue the frames if the STA is sleeping */
- mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
- mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
- if (!mgmt_buf)
- return false;
-
- INIT_LIST_HEAD(&mgmt_buf->list);
- mgmt_buf->id = id;
- mgmt_buf->freq = freq;
- mgmt_buf->wait = wait;
- mgmt_buf->len = len;
- mgmt_buf->no_cck = no_cck;
- memcpy(mgmt_buf->buf, buf, len);
- spin_lock_bh(&conn->psq_lock);
- is_psq_empty = skb_queue_empty(&conn->psq) &&
- (conn->mgmt_psq_len == 0);
- list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
- conn->mgmt_psq_len++;
- spin_unlock_bh(&conn->psq_lock);
-
- /*
- * If this is the first pkt getting queued
- * for this STA, update the PVB for this
- * STA.
- */
- if (is_psq_empty)
- ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
- conn->aid, 1);
- return true;
- }
-
- /*
- * This tx is because of a PsPoll.
- * Determine if MoreData bit has to be set.
- */
- spin_lock_bh(&conn->psq_lock);
- if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
- *more_data = true;
- spin_unlock_bh(&conn->psq_lock);
- }
-
- return false;
-}
-
-/* Check if SSID length is greater than DIRECT- */
-static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- mgmt = (const struct ieee80211_mgmt *) buf;
-
- /* variable[1] contains the SSID tag length */
- if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
- (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
- return true;
- }
-
- return false;
-}
-
-static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
- struct ieee80211_channel *chan, bool offchan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- bool dont_wait_for_ack, u64 *cookie)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- u32 id;
- const struct ieee80211_mgmt *mgmt;
- bool more_data, queued;
-
- mgmt = (const struct ieee80211_mgmt *) buf;
- if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
- ieee80211_is_probe_resp(mgmt->frame_control) &&
- ath6kl_is_p2p_go_ssid(buf, len)) {
- /*
- * Send Probe Response frame in GO mode using a separate WMI
- * command to allow the target to fill in the generic IEs.
- */
- *cookie = 0; /* TX status not supported */
- return ath6kl_send_go_probe_resp(vif, buf, len,
- chan->center_freq);
- }
-
- id = vif->send_action_id++;
- if (id == 0) {
- /*
- * 0 is a reserved value in the WMI command and shall not be
- * used for the command.
- */
- id = vif->send_action_id++;
- }
-
- *cookie = id;
-
- /* AP mode Power saving processing */
- if (vif->nw_type == AP_NETWORK) {
- queued = ath6kl_mgmt_powersave_ap(vif,
- id, chan->center_freq,
- wait, buf,
- len, &more_data, no_cck);
- if (queued)
- return 0;
- }
-
- return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
- chan->center_freq, wait,
- buf, len, no_cck);
-}
-
-static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
- struct net_device *dev,
- u16 frame_type, bool reg)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
- __func__, frame_type, reg);
- if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
- /*
- * Note: This notification callback is not allowed to sleep, so
- * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
- * hardcode target to report Probe Request frames all the time.
- */
- vif->probe_req_report = reg;
- }
-}
-
-static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
- struct net_device *dev,
- struct cfg80211_sched_scan_request *request)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_vif *vif = netdev_priv(dev);
- u16 interval;
- int ret;
-
- if (ar->state != ATH6KL_STATE_ON)
- return -EIO;
-
- if (vif->sme_state != SME_DISCONNECTED)
- return -EBUSY;
-
- ath6kl_cfg80211_scan_complete_event(vif, true);
-
- ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
- request->n_ssids);
- if (ret < 0)
- return ret;
-
-
- /* fw uses seconds, also make sure that it's >0 */
- interval = max_t(u16, 1, request->interval / 1000);
-
- ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
- interval, interval,
- 10, 0, 0, 0, 3, 0, 0, 0);
-
- ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_WOW_MODE_ENABLE,
- WOW_FILTER_SSID,
- WOW_HOST_REQ_DELAY);
- if (ret) {
- ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
- return ret;
- }
-
- /* this also clears IE in fw if it's not set */
- ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
- WMI_FRAME_PROBE_REQ,
- request->ie, request->ie_len);
- if (ret) {
- ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
- ret);
- return ret;
- }
-
- ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
- ATH6KL_HOST_MODE_ASLEEP);
- if (ret) {
- ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
- ret);
- return ret;
- }
-
- ar->state = ATH6KL_STATE_SCHED_SCAN;
-
- return ret;
-}
-
-static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
- struct net_device *dev)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
- bool stopped;
-
- stopped = __ath6kl_cfg80211_sscan_stop(vif);
-
- if (!stopped)
- return -EIO;
-
- return 0;
-}
-
-
-static int ath6kl_notify_p2p_flush(struct wiphy *wiphy)
-{
- ath6kl_err("%s() Enter - steven", __func__);
-
- cfg80211_unlink_allbss(wiphy);
-
- return 0;
-}
-
-static const struct ieee80211_txrx_stypes
-ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
- [NL80211_IFTYPE_STATION] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_AP] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_CLIENT] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
- [NL80211_IFTYPE_P2P_GO] = {
- .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
- .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
- },
-};
-
-static struct cfg80211_ops ath6kl_cfg80211_ops = {
- .add_virtual_intf = ath6kl_cfg80211_add_iface,
- .del_virtual_intf = ath6kl_cfg80211_del_iface,
- .change_virtual_intf = ath6kl_cfg80211_change_iface,
- .scan = ath6kl_cfg80211_scan,
- .connect = ath6kl_cfg80211_connect,
- .disconnect = ath6kl_cfg80211_disconnect,
- .add_key = ath6kl_cfg80211_add_key,
- .get_key = ath6kl_cfg80211_get_key,
- .del_key = ath6kl_cfg80211_del_key,
- .set_default_key = ath6kl_cfg80211_set_default_key,
- .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
- .set_tx_power = ath6kl_cfg80211_set_txpower,
- .get_tx_power = ath6kl_cfg80211_get_txpower,
- .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
- .join_ibss = ath6kl_cfg80211_join_ibss,
- .leave_ibss = ath6kl_cfg80211_leave_ibss,
- .get_station = ath6kl_get_station,
- .set_pmksa = ath6kl_set_pmksa,
- .del_pmksa = ath6kl_del_pmksa,
- .flush_pmksa = ath6kl_flush_pmksa,
- CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
-#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
- .suspend = __ath6kl_cfg80211_suspend,
- .resume = __ath6kl_cfg80211_resume,
-#endif
- .set_channel = ath6kl_set_channel,
- .add_beacon = ath6kl_add_beacon,
- .set_beacon = ath6kl_set_beacon,
- .del_beacon = ath6kl_del_beacon,
- .del_station = ath6kl_del_station,
- .change_station = ath6kl_change_station,
- .remain_on_channel = ath6kl_remain_on_channel,
- .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
- .mgmt_tx = ath6kl_mgmt_tx,
- .mgmt_frame_register = ath6kl_mgmt_frame_register,
- .notify_btcoex_inq_status = ath6kl_notify_btcoex_inq_status,
- .notify_btcoex_sco_status = ath6kl_notify_btcoex_sco_status,
- .notify_btcoex_a2dp_status = ath6kl_notify_btcoex_a2dp_status,
- .notify_btcoex_acl_info = ath6kl_notify_btcoex_acl_info,
- .notify_btcoex_antenna_config = ath6kl_notify_btcoex_antenna_config,
- .notify_btcoex_bt_vendor = ath6kl_notify_btcoex_bt_vendor,
- .notify_btcoex = ath6kl_notify_btcoex,
- .notify_p2p_flush = ath6kl_notify_p2p_flush,
- .sched_scan_start = ath6kl_cfg80211_sscan_start,
- .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
- .priv_cmd = ath6kl_priv_cmd,
-};
-
-void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
-{
- ath6kl_cfg80211_sscan_disable(vif);
-
- switch (vif->sme_state) {
- case SME_DISCONNECTED:
- break;
- case SME_CONNECTING:
- cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
- NULL, 0,
- WLAN_STATUS_UNSPECIFIED_FAILURE,
- GFP_KERNEL);
- break;
- case SME_CONNECTED:
- cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
- break;
- }
-
- if (test_bit(CONNECTED, &vif->flags) ||
- test_bit(CONNECT_PEND, &vif->flags))
- ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
-
- vif->sme_state = SME_DISCONNECTED;
- clear_bit(CONNECTED, &vif->flags);
- clear_bit(CONNECT_PEND, &vif->flags);
-
- /* disable scanning */
- if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
- 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
- ath6kl_warn("failed to disable scan during stop\n");
-
- ath6kl_cfg80211_scan_complete_event(vif, true);
-}
-
-void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif) {
- /* save the current power mode before enabling power save */
- ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
-
- if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
- ath6kl_warn("ath6kl_deep_sleep_enable: "
- "wmi_powermode_cmd failed\n");
- return;
- }
-
- /*
- * FIXME: we should take ar->list_lock to protect changes in the
- * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
- * sleeps.
- */
- list_for_each_entry(vif, &ar->vif_list, list)
- ath6kl_cfg80211_stop(vif);
-}
-
-struct ath6kl *ath6kl_core_alloc(struct device *dev)
-{
- struct ath6kl *ar;
- struct wiphy *wiphy;
- u8 ctr;
-
- /* create a new wiphy for use with cfg80211 */
- wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
-
- if (!wiphy) {
- ath6kl_err("couldn't allocate wiphy device\n");
- return NULL;
- }
-
- ar = wiphy_priv(wiphy);
- ar->p2p = !!ath6kl_p2p;
- ar->wiphy = wiphy;
- ar->dev = dev;
-
- ar->vif_max = 1;
-
- ar->max_norm_iface = 1;
-
- spin_lock_init(&ar->lock);
- spin_lock_init(&ar->mcastpsq_lock);
- spin_lock_init(&ar->list_lock);
-
- init_waitqueue_head(&ar->event_wq);
- sema_init(&ar->sem, 1);
-
- INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
- INIT_LIST_HEAD(&ar->vif_list);
-
- clear_bit(WMI_ENABLED, &ar->flag);
- clear_bit(SKIP_SCAN, &ar->flag);
- clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
-
- ar->tx_pwr = 0;
- ar->intra_bss = 1;
- ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
-
- ar->state = ATH6KL_STATE_OFF;
-
- memset((u8 *)ar->sta_list, 0,
- AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
-
- /* Init the PS queues */
- for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
- spin_lock_init(&ar->sta_list[ctr].psq_lock);
- skb_queue_head_init(&ar->sta_list[ctr].psq);
- skb_queue_head_init(&ar->sta_list[ctr].apsdq);
- ar->sta_list[ctr].mgmt_psq_len = 0;
- INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq);
- ar->sta_list[ctr].aggr_conn =
- kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
- if (!ar->sta_list[ctr].aggr_conn) {
- ath6kl_err("Failed to allocate memory for sta aggregation information\n");
- ath6kl_core_cleanup(ar);
- return NULL;
- }
- }
-
- skb_queue_head_init(&ar->mcastpsq);
-
- memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
-
- return ar;
-}
-
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
-{
- struct wiphy *wiphy = ar->wiphy;
- int ret;
-
- wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
-
- wiphy->max_remain_on_channel_duration = 5000;
-
- /* set device pointer for wiphy */
- set_wiphy_dev(wiphy, ar->dev);
-
- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_ADHOC) |
- BIT(NL80211_IFTYPE_AP);
- if (ar->p2p) {
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT);
- }
-
- /* max num of ssids that can be probed during scanning */
- wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
- wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
- wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
- wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
- wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
-
- wiphy->cipher_suites = cipher_suites;
- wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
-
- wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
- WIPHY_WOWLAN_DISCONNECT |
- WIPHY_WOWLAN_GTK_REKEY_FAILURE |
- WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
- WIPHY_WOWLAN_EAP_IDENTITY_REQ |
- WIPHY_WOWLAN_4WAY_HANDSHAKE;
- wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
- wiphy->wowlan.pattern_min_len = 1;
- wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
-
- wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
-
- ath6kl_setup_android_resource(ar);
-
- ret = wiphy_register(wiphy);
- if (ret < 0) {
- ath6kl_err("couldn't register wiphy device\n");
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_init_if_data(struct ath6kl_vif *vif)
-{
- vif->aggr_cntxt = aggr_init(vif);
- if (!vif->aggr_cntxt) {
- ath6kl_err("failed to initialize aggr\n");
- return -ENOMEM;
- }
-
- setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
- (unsigned long) vif->ndev);
- setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
- (unsigned long) vif);
-
- set_bit(WMM_ENABLED, &vif->flags);
- spin_lock_init(&vif->if_lock);
-
- INIT_LIST_HEAD(&vif->mc_filter);
-
- return 0;
-}
-
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = vif->ar;
- struct ath6kl_mc_filter *mc_filter, *tmp;
-
- aggr_module_destroy(vif->aggr_cntxt);
-
- ar->avail_idx_map |= BIT(vif->fw_vif_idx);
-
- if (vif->nw_type == ADHOC_NETWORK)
- ar->ibss_if_active = false;
-
- list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
- list_del(&mc_filter->list);
- kfree(mc_filter);
- }
-
- unregister_netdevice(vif->ndev);
-
- ar->num_vif--;
-}
-
-struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
- enum nl80211_iftype type, u8 fw_vif_idx,
- u8 nw_type)
-{
- struct net_device *ndev;
- struct ath6kl_vif *vif;
-
- ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
- if (!ndev)
- return NULL;
-
- vif = netdev_priv(ndev);
- ndev->ieee80211_ptr = &vif->wdev;
- vif->wdev.wiphy = ar->wiphy;
- vif->ar = ar;
- vif->ndev = ndev;
- SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
- vif->wdev.netdev = ndev;
- vif->wdev.iftype = type;
- vif->fw_vif_idx = fw_vif_idx;
- vif->nw_type = vif->next_mode = nw_type;
- vif->bg_scan_period = 0;
- vif->scan_ctrl_flag = 0;
- vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
- vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
-
- memset((u8 *)&vif->scparams, 0, sizeof(vif->scparams));
- vif->scparams.bg_period = WLAN_CONFIG_BG_SCAN_INTERVAL;
- vif->scparams.maxact_chdwell_time = WLAN_CONFIG_MAXACT_CHDWELL_TIME;
- vif->scparams.pas_chdwell_time = WLAN_CONFIG_PASSIVE_CHDWELL_TIME;
- vif->scparams.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
- vif->scparams.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
-
- vif->pspoll_num = WLAN_CONFIG_PSPOLL_NUM;
- vif->mcastrate = WLAN_CONFIG_MCAST_RATE;
- vif->force_reload = false;
- vif->sdio_remove = false;
-
- memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
- if (fw_vif_idx != 0)
- ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
- 0x2;
-
- init_netdev(ndev);
-
- ath6kl_init_control_info(vif);
-
- /* TODO: Pass interface specific pointer instead of ar */
- if (ath6kl_init_if_data(vif))
- goto err;
-
- if (register_netdevice(ndev))
- goto err;
-
- ar->avail_idx_map &= ~BIT(fw_vif_idx);
- vif->sme_state = SME_DISCONNECTED;
- set_bit(WLAN_ENABLED, &vif->flags);
- ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
- set_bit(NETDEV_REGISTERED, &vif->flags);
-
- if (type == NL80211_IFTYPE_ADHOC)
- ar->ibss_if_active = true;
-
- spin_lock_bh(&ar->list_lock);
- list_add_tail(&vif->list, &ar->vif_list);
- spin_unlock_bh(&ar->list_lock);
-
- return ndev;
-
-err:
- aggr_module_destroy(vif->aggr_cntxt);
- free_netdev(ndev);
- return NULL;
-}
-
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
-{
- int i;
-
- ath6kl_cleanup_android_resource(ar);
-
- for (i = 0; i < AP_MAX_NUM_STA; i++)
- kfree(ar->sta_list[i].aggr_conn);
-
- wiphy_unregister(ar->wiphy);
- wiphy_free(ar->wiphy);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
deleted file mode 100755
index ae375b6..0000000
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef ATH6KL_CFG80211_H
-#define ATH6KL_CFG80211_H
-
-enum ath6kl_cfg_suspend_mode {
- ATH6KL_CFG_SUSPEND_DEEPSLEEP,
- ATH6KL_CFG_SUSPEND_CUTPOWER,
- ATH6KL_CFG_SUSPEND_WOW,
- ATH6KL_CFG_SUSPEND_SCHED_SCAN,
-};
-
-struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
- enum nl80211_iftype type,
- u8 fw_vif_idx, u8 nw_type);
-int ath6kl_register_ieee80211_hw(struct ath6kl *ar);
-struct ath6kl *ath6kl_core_alloc(struct device *dev);
-void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar);
-
-void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted);
-
-void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
- u8 *bssid, u16 listen_intvl,
- u16 beacon_intvl,
- enum network_type nw_type,
- u8 beacon_ie_len, u8 assoc_req_len,
- u8 assoc_resp_len, u8 *assoc_info);
-
-void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
- u8 *bssid, u8 assoc_resp_len,
- u8 *assoc_info, u16 proto_reason);
-
-void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
- bool ismcast);
-
-int ath6kl_cfg80211_suspend(struct ath6kl *ar,
- enum ath6kl_cfg_suspend_mode mode,
- struct cfg80211_wowlan *wow);
-
-int ath6kl_cfg80211_resume(struct ath6kl *ar);
-
-void ath6kl_cfg80211_stop(struct ath6kl_vif *vif);
-void ath6kl_cfg80211_stop_all(struct ath6kl *ar);
-
-#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.c b/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.c
deleted file mode 100644
index 399ffd7..0000000
--- a/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/moduleparam.h>
-#include <linux/inetdevice.h>
-
-#ifdef CONFIG_HAS_WAKELOCK
-#include <linux/wakelock.h>
-#endif
-
-#include "core.h"
-#include "cfg80211.h"
-#include "debug.h"
-#include "hif-ops.h"
-#include "testmode.h"
-#include "cfg80211_btcoex.h"
-
-bool ath6kl_btcoex_cfg80211_ready(struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = vif->ar;
-
- if (!test_bit(WMI_READY, &ar->flag)) {
- ath6kl_err("wmi is not ready\n");
- return false;
- }
-
- if (!test_bit(WLAN_ENABLED, &vif->flags)) {
- ath6kl_err("wlan disabled\n");
- return false;
- }
-
- return true;
-}
-#define OP_TYPE_SCO 0x01
-#define OP_TYPE_A2DP 0x02
-#define OP_TYPE_INQUIRY 0x03
-#define OP_TYPE_ESCO 0x04
-
-int ath6kl_notify_btcoex_inq_status(struct wiphy *wiphy, bool status)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "BT coex scan status:%d\n", status);
-
- if (!ath6kl_btcoex_cfg80211_ready(vif))
- return -EIO;
-
- return ath6kl_wmi_set_btcoex_bt_op_status(ar->wmi, OP_TYPE_INQUIRY,
- status);
-}
-
-int ath6kl_notify_btcoex_sco_status(struct wiphy *wiphy, bool status,
- bool esco, u32 tx_interval,
- u32 tx_pkt_len)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_btcoex_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
- "BT Coex sco status:%d sco type %s tx interval %d tx pk len %d\n",
- status, esco ? "ESCO" : "SCO", tx_interval, tx_pkt_len);
-
- if (status)
- ath6kl_wmi_set_btcoex_sco_op(ar->wmi, esco, tx_interval,
- tx_pkt_len);
-
- return ath6kl_wmi_set_btcoex_bt_op_status(ar->wmi, OP_TYPE_SCO,
- status);
-}
-
-int ath6kl_notify_btcoex_a2dp_status(struct wiphy *wiphy, bool status)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- if (!ath6kl_btcoex_cfg80211_ready(vif))
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "BT coex A2DP status:%d\n", status);
-
- if (status)
- ath6kl_wmi_set_btcoex_a2dp_op(ar->wmi,
- ar->btcoex_info.acl_role,
- ar->btcoex_info.remote_lmp_ver,
- ar->btcoex_info.bt_vendor);
-
- return ath6kl_wmi_set_btcoex_bt_op_status(ar->wmi, OP_TYPE_A2DP,
- status);
-}
-
-#define MAX_LMP_VER 6
-int ath6kl_notify_btcoex_acl_info(struct wiphy *wiphy,
- enum nl80211_btcoex_acl_role role,
- u32 lmp_ver)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
-
- if (lmp_ver > MAX_LMP_VER)
- return -EINVAL;
-
- if (role > NL80211_BTCOEX_ACL_ROLE_SLAVE)
- return -EINVAL;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "BT coex ACL role:%d Lmp ver %d\n",
- role, lmp_ver);
-
- ar->btcoex_info.acl_role = role;
- ar->btcoex_info.remote_lmp_ver = lmp_ver;
-
- return 0;
-}
-
-#define BTCOEX_COLOCATED_BT_DEFAULT 1
-#define BTCOEX_COLOCATED_BT_QCOM 2
-
-inline int get_bt_vendor_id(enum nl80211_btcoex_vendor_list vendor)
-{
- switch (vendor) {
- case NL80211_BTCOEX_VENDOR_DEFAULT:
- return BTCOEX_COLOCATED_BT_DEFAULT;
- case NL80211_BTCOEX_VENDOR_QCOM:
- return BTCOEX_COLOCATED_BT_QCOM;
- }
-
- return BTCOEX_COLOCATED_BT_DEFAULT;
-}
-
-int ath6kl_notify_btcoex_antenna_config(struct wiphy *wiphy,
- enum nl80211_btcoex_antenna_config config)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
-
- if (config > NL80211_BTCOEX_ANTENNA_SA)
- return -EINVAL;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "BT coex Antenna configuration:%d\n",
- config);
- ath6kl_wmi_set_btcoex_set_colocated_bt(ar->wmi,
- get_bt_vendor_id
- (ar->btcoex_info.bt_vendor));
-
- return ath6kl_wmi_set_btcoex_set_fe_antenna(ar->wmi, config);
-}
-int ath6kl_notify_btcoex_bt_vendor(struct wiphy *wiphy,
- enum nl80211_btcoex_vendor_list vendor)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
-
- if (vendor > NL80211_BTCOEX_VENDOR_QCOM)
- return -EINVAL;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "vendor :%d\n", vendor);
-
- ar->btcoex_info.bt_vendor = vendor;
-
- return 0;
-}
-
-int ath6kl_notify_btcoex(struct wiphy *wiphy, u8 *buf,
- int len)
-{
- struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "BT coex wmi command:%p\n", buf);
-
- if (!ath6kl_btcoex_cfg80211_ready(vif))
- return -EIO;
-
- return ath6kl_wmi_send_btcoex_cmd(ar->wmi, buf,
- len);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.h b/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.h
deleted file mode 100644
index 01c6181..0000000
--- a/drivers/net/wireless/ath/ath6kl/cfg80211_btcoex.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-int ath6kl_notify_btcoex_inq_status(struct wiphy *wiphy, bool status);
-int ath6kl_notify_btcoex_sco_status(struct wiphy *wiphy, bool status,
- bool esco, u32 tx_interval,
- u32 tx_pkt_len);
-int ath6kl_notify_btcoex_a2dp_status(struct wiphy *wiphy, bool status);
-int ath6kl_notify_btcoex_acl_info(struct wiphy *wiphy,
- enum nl80211_btcoex_acl_role role,
- u32 lmp_ver);
-int ath6kl_notify_btcoex_antenna_config(struct wiphy *wiphy,
- enum nl80211_btcoex_antenna_config config);
-int ath6kl_notify_btcoex_bt_vendor(struct wiphy *wiphy,
- enum nl80211_btcoex_vendor_list vendor);
-int ath6kl_notify_btcoex(struct wiphy *wiphy, u8 *buf,
- int len);
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
deleted file mode 100755
index 88a5459..0000000
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef COMMON_H
-#define COMMON_H
-
-#include <linux/netdevice.h>
-
-#define ATH6KL_MAX_IE 256
-
-extern int ath6kl_printk(const char *level, const char *fmt, ...);
-
-/*
- * Reflects the version of binary interface exposed by ATH6KL target
- * firmware. Needs to be incremented by 1 for any change in the firmware
- * that requires upgrade of the driver on the host side for the change to
- * work correctly
- */
-#define ATH6KL_ABI_VERSION 1
-
-#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
-
-enum {
- SIGNAL_QUALITY_METRICS_SNR = 0,
- SIGNAL_QUALITY_METRICS_RSSI,
- SIGNAL_QUALITY_METRICS_ALL,
-};
-
-/*
- * Data Path
- */
-
-#define WMI_MAX_TX_DATA_FRAME_LENGTH \
- (1500 + sizeof(struct wmi_data_hdr) + \
- sizeof(struct ethhdr) + \
- sizeof(struct ath6kl_llc_snap_hdr))
-
-/* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
-#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH \
- (3840 + sizeof(struct wmi_data_hdr) + \
- sizeof(struct ethhdr) + \
- sizeof(struct ath6kl_llc_snap_hdr))
-
-#define EPPING_ALIGNMENT_PAD \
- (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) \
- - sizeof(struct htc_frame_hdr))
-
-struct ath6kl_llc_snap_hdr {
- u8 dsap;
- u8 ssap;
- u8 cntl;
- u8 org_code[3];
- __be16 eth_type;
-} __packed;
-
-enum crypto_type {
- NONE_CRYPT = 0x01,
- WEP_CRYPT = 0x02,
- TKIP_CRYPT = 0x04,
- AES_CRYPT = 0x08,
- WAPI_CRYPT = 0x10,
-};
-
-struct htc_endpoint_credit_dist;
-struct ath6kl;
-enum htc_credit_dist_reason;
-struct ath6kl_htc_credit_info;
-
-struct ath6kl *ath6kl_core_alloc(struct device *sdev);
-int ath6kl_core_init(struct ath6kl *ar);
-void ath6kl_core_cleanup(struct ath6kl *ar);
-struct sk_buff *ath6kl_buf_alloc(int size);
-#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
deleted file mode 100755
index 97c1ae5..0000000
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef CORE_H
-#define CORE_H
-
-#include <linux/etherdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include <linux/circ_buf.h>
-#include <net/cfg80211.h>
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-#ifdef CONFIG_HAS_WAKELOCK
-#include <linux/wakelock.h>
-#endif
-#include "htc.h"
-#include "wmi.h"
-#include "bmi.h"
-#include "target.h"
-#include "wmi_btcoex.h"
-
-#define MAX_ATH6KL 1
-#define ATH6KL_MAX_RX_BUFFERS 16
-#define ATH6KL_BUFFER_SIZE 1664
-#define ATH6KL_MAX_AMSDU_RX_BUFFERS 4
-#define ATH6KL_AMSDU_REFILL_THRESHOLD 3
-#define ATH6KL_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
-#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
-#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
-
-#define USER_SAVEDKEYS_STAT_INIT 0
-#define USER_SAVEDKEYS_STAT_RUN 1
-
-#define ATH6KL_TX_TIMEOUT 10
-#define ATH6KL_MAX_ENDPOINTS 4
-#define MAX_NODE_NUM 15
-
-#define ATH6KL_APSD_ALL_FRAME 0xFFFF
-#define ATH6KL_APSD_NUM_OF_AC 0x4
-#define ATH6KL_APSD_FRAME_MASK 0xF
-
-/* Extra bytes for htc header alignment */
-#define ATH6KL_HTC_ALIGN_BYTES 3
-
-/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
-#define MAX_DEF_COOKIE_NUM 180
-#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
-#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
-
-#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
-
-#define DISCON_TIMER_INTVAL 10000 /* in msec */
-
-/* Channel dwell time in fg scan */
-#define ATH6KL_FG_SCAN_INTERVAL 60 /* in ms */
-
-/*
- * background scan interval (sec)
- * disable background scan interval: 65535
- * default: 60 sec
- * to restore the default value: 0
- *
- * For P2P and PMKID cache, bg scan should be enabled.
- */
-#ifdef CONFIG_MACH_PX
-#define WLAN_CONFIG_BG_SCAN_INTERVAL 65535
-#else
-#define WLAN_CONFIG_BG_SCAN_INTERVAL 0
-#endif
-/*
- * maximum active dwell time (ms)
- * default: 20 ms
- * to restore the default value: 0
- */
-#ifdef CONFIG_MACH_PX
-#define WLAN_CONFIG_MAXACT_CHDWELL_TIME 60
-#else
-#define WLAN_CONFIG_MAXACT_CHDWELL_TIME 20
-#endif
-/*
- * passive dwell time (ms)
- * default: 50 ms
- * to restore the default value: 0
- */
-#ifdef CONFIG_MACH_PX
-#define WLAN_CONFIG_PASSIVE_CHDWELL_TIME 120
-#else
-#define WLAN_CONFIG_PASSIVE_CHDWELL_TIME 50
-#endif
-#define WMI_SHORTSCANRATIO_DEFAULT 3
-#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS | \
- SCAN_CONNECTED_CTRL_FLAGS | ACTIVE_SCAN_CTRL_FLAGS | \
- ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS)
-
-/*
- * 0: to disable sending ps-poll in TIM interrupt
- * 1: to send one ps-poll (the default)
- */
-#ifdef CONFIG_MACH_PX
-#define WLAN_CONFIG_PSPOLL_NUM 0
-#else
-#define WLAN_CONFIG_PSPOLL_NUM 1
-#endif
-
-#define WLAN_CONFIG_MCAST_RATE 60
-
-/* includes also the null byte */
-#define ATH6KL_FIRMWARE_MAGIC "QCA-ATH6KL"
-
-enum ath6kl_fw_ie_type {
- ATH6KL_FW_IE_FW_VERSION = 0,
- ATH6KL_FW_IE_TIMESTAMP = 1,
- ATH6KL_FW_IE_OTP_IMAGE = 2,
- ATH6KL_FW_IE_FW_IMAGE = 3,
- ATH6KL_FW_IE_PATCH_IMAGE = 4,
- ATH6KL_FW_IE_RESERVED_RAM_SIZE = 5,
- ATH6KL_FW_IE_CAPABILITIES = 6,
- ATH6KL_FW_IE_PATCH_ADDR = 7,
- ATH6KL_FW_IE_BOARD_ADDR = 8,
- ATH6KL_FW_IE_VIF_MAX = 9,
-};
-
-enum ath6kl_fw_capability {
- ATH6KL_FW_CAPABILITY_HOST_P2P = 0,
- ATH6KL_FW_CAPABILITY_SCHED_SCAN = 1,
-
- /*
- * Firmware is capable of supporting P2P mgmt operations on a
- * station interface. After group formation, the station
- * interface will become a P2P client/GO interface as the case may be
- */
- ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
-
- ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
-
- ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
-
- /* this needs to be last */
- ATH6KL_FW_CAPABILITY_MAX,
-};
-
-#define ATH6KL_CAPABILITY_LEN (ALIGN(ATH6KL_FW_CAPABILITY_MAX, 32) / 32)
-
-struct ath6kl_fw_ie {
- __le32 id;
- __le32 len;
- u8 data[0];
-};
-
-#define ATH6KL_FW_API2_FILE "fw-2.bin"
-#define ATH6KL_FW_API3_FILE "fw-3.bin"
-
-/* AR6003 1.0 definitions */
-#define AR6003_HW_1_0_VERSION 0x300002ba
-
-/* AR6003 2.0 definitions */
-#define AR6003_HW_2_0_VERSION 0x30000384
-#define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910
-#define AR6003_HW_2_0_FW_DIR "ath6k/AR6003/hw2.0"
-#define AR6003_HW_2_0_OTP_FILE "otp.bin.z77"
-#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77"
-#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin"
-#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin"
-#define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
-#define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \
- "ath6k/AR6003/hw2.0/bdata.SD31.bin"
-
-/* AR6003 3.0 definitions */
-#define AR6003_HW_2_1_1_VERSION 0x30000582
-#define AR6003_HW_2_1_1_FW_DIR "ath6k/AR6003/hw2.1.1"
-#define AR6003_HW_2_1_1_OTP_FILE "otp.bin"
-#define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin"
-#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin"
-#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin"
-#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin"
-#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin"
-#define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
-#define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \
- "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
-
-#ifdef CONFIG_MACH_PX
-#define AR6003_HW_2_1_1_TCMD_BOARD_DATA_FILE \
- "ath6k/AR6003/hw2.1.1/bdata.tcmd.bin"
-#endif
-
-/* AR6004 1.0 definitions */
-#define AR6004_HW_1_0_VERSION 0x30000623
-#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0"
-#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin"
-#define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin"
-#define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \
- "ath6k/AR6004/hw1.0/bdata.DB132.bin"
-
-/* AR6004 1.1 definitions */
-#define AR6004_HW_1_1_VERSION 0x30000001
-#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1"
-#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin"
-#define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin"
-#define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \
- "ath6k/AR6004/hw1.1/bdata.DB132.bin"
-
-/* Per STA data, used in AP mode */
-#define STA_PS_AWAKE BIT(0)
-#define STA_PS_SLEEP BIT(1)
-#define STA_PS_POLLED BIT(2)
-#define STA_PS_APSD_TRIGGER BIT(3)
-#define STA_PS_APSD_EOSP BIT(4)
-
-/* HTC TX packet tagging definitions */
-#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
-#define ATH6KL_DATA_PKT_TAG (ATH6KL_CONTROL_PKT_TAG + 1)
-
-#define AR6003_CUST_DATA_SIZE 16
-
-#define AGGR_WIN_IDX(x, y) ((x) % (y))
-#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x) + 1), (y))
-#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x) - 1), (y))
-#define ATH6KL_MAX_SEQ_NO 0xFFF
-#define ATH6KL_NEXT_SEQ_NO(x) (((x) + 1) & ATH6KL_MAX_SEQ_NO)
-
-#define NUM_OF_TIDS 8
-#define AGGR_SZ_DEFAULT 8
-
-#define AGGR_WIN_SZ_MIN 2
-#define AGGR_WIN_SZ_MAX 8
-
-#define TID_WINDOW_SZ(_x) ((_x) << 1)
-
-#define AGGR_NUM_OF_FREE_NETBUFS 16
-
-#ifdef CONFIG_MACH_PX
-#define AGGR_RX_TIMEOUT 100 /* in ms */
-#else
-#define AGGR_RX_TIMEOUT 400 /* in ms */
-#endif
-
-#define WMI_TIMEOUT (2 * HZ)
-
-#define MBOX_YIELD_LIMIT 99
-
-#define ATH6KL_DEFAULT_LISTEN_INTVAL 100 /* in TUs */
-#define ATH6KL_DEFAULT_BMISS_TIME 1500
-#define ATH6KL_MAX_WOW_LISTEN_INTL 300 /* in TUs */
-#define ATH6KL_MAX_BMISS_TIME 5000
-
-/* configuration lags */
-/*
- * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in
- * ERP IE of beacon to determine the short premable support when
- * sending (Re)Assoc req.
- * ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN: Don't send the power
- * module state transition failure events which happen during
- * scan, to the host.
- */
-#define ATH6KL_CONF_IGNORE_ERP_BARKER BIT(0)
-#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1)
-#define ATH6KL_CONF_ENABLE_11N BIT(2)
-#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
-#define ATH6KL_CONF_UART_DEBUG BIT(4)
-
-#define P2P_WILDCARD_SSID_LEN 7 /* DIRECT- */
-
-enum wlan_low_pwr_state {
- WLAN_POWER_STATE_ON,
- WLAN_POWER_STATE_CUT_PWR,
- WLAN_POWER_STATE_DEEP_SLEEP,
- WLAN_POWER_STATE_WOW
-};
-
-enum sme_state {
- SME_DISCONNECTED,
- SME_CONNECTING,
- SME_CONNECTED
-};
-
-struct skb_hold_q {
- struct sk_buff *skb;
- bool is_amsdu;
- u16 seq_no;
-};
-
-struct rxtid {
- bool aggr;
- bool progress;
- bool timer_mon;
- u16 win_sz;
- u16 seq_next;
- u32 hold_q_sz;
- struct skb_hold_q *hold_q;
- struct sk_buff_head q;
- spinlock_t lock;
-};
-
-struct rxtid_stats {
- u32 num_into_aggr;
- u32 num_dups;
- u32 num_oow;
- u32 num_mpdu;
- u32 num_amsdu;
- u32 num_delivered;
- u32 num_timeouts;
- u32 num_hole;
- u32 num_bar;
-};
-
-struct aggr_info_conn {
- u8 aggr_sz;
- u8 timer_scheduled;
- struct timer_list timer;
- struct net_device *dev;
- struct rxtid rx_tid[NUM_OF_TIDS];
- struct rxtid_stats stat[NUM_OF_TIDS];
- struct aggr_info *aggr_info;
-};
-
-struct aggr_info {
- struct aggr_info_conn *aggr_conn;
- struct sk_buff_head rx_amsdu_freeq;
-};
-
-struct ath6kl_wep_key {
- u8 key_index;
- u8 key_len;
- u8 key[64];
-};
-
-#define ATH6KL_KEY_SEQ_LEN 8
-
-struct ath6kl_key {
- u8 key[WLAN_MAX_KEY_LEN];
- u8 key_len;
- u8 seq[ATH6KL_KEY_SEQ_LEN];
- u8 seq_len;
- u32 cipher;
-};
-
-struct ath6kl_node_mapping {
- u8 mac_addr[ETH_ALEN];
- u8 ep_id;
- u8 tx_pend;
-};
-
-struct ath6kl_cookie {
- struct sk_buff *skb;
- u32 map_no;
- struct htc_packet htc_pkt;
- struct ath6kl_cookie *arc_list_next;
-};
-
-struct ath6kl_mgmt_buff {
- struct list_head list;
- u32 freq;
- u32 wait;
- u32 id;
- bool no_cck;
- size_t len;
- u8 buf[0];
-};
-
-struct ath6kl_sta {
- u16 sta_flags;
- u8 mac[ETH_ALEN];
- u8 aid;
- u8 keymgmt;
- u8 ucipher;
- u8 auth;
- u8 wpa_ie[ATH6KL_MAX_IE];
- struct sk_buff_head psq;
- spinlock_t psq_lock;
- struct list_head mgmt_psq;
- size_t mgmt_psq_len;
- u8 apsd_info;
- struct sk_buff_head apsdq;
- struct aggr_info_conn *aggr_conn;
-};
-
-struct ath6kl_version {
- u32 target_ver;
- u32 wlan_ver;
- u32 abi_ver;
-};
-
-struct ath6kl_bmi {
- u32 cmd_credits;
- bool done_sent;
- u8 *cmd_buf;
- u32 max_data_size;
- u32 max_cmd_size;
-};
-
-struct target_stats {
- u64 tx_pkt;
- u64 tx_byte;
- u64 tx_ucast_pkt;
- u64 tx_ucast_byte;
- u64 tx_mcast_pkt;
- u64 tx_mcast_byte;
- u64 tx_bcast_pkt;
- u64 tx_bcast_byte;
- u64 tx_rts_success_cnt;
- u64 tx_pkt_per_ac[4];
-
- u64 tx_err;
- u64 tx_fail_cnt;
- u64 tx_retry_cnt;
- u64 tx_mult_retry_cnt;
- u64 tx_rts_fail_cnt;
-
- u64 rx_pkt;
- u64 rx_byte;
- u64 rx_ucast_pkt;
- u64 rx_ucast_byte;
- u64 rx_mcast_pkt;
- u64 rx_mcast_byte;
- u64 rx_bcast_pkt;
- u64 rx_bcast_byte;
- u64 rx_frgment_pkt;
-
- u64 rx_err;
- u64 rx_crc_err;
- u64 rx_key_cache_miss;
- u64 rx_decrypt_err;
- u64 rx_dupl_frame;
-
- u64 tkip_local_mic_fail;
- u64 tkip_cnter_measures_invoked;
- u64 tkip_replays;
- u64 tkip_fmt_err;
- u64 ccmp_fmt_err;
- u64 ccmp_replays;
-
- u64 pwr_save_fail_cnt;
-
- u64 cs_bmiss_cnt;
- u64 cs_low_rssi_cnt;
- u64 cs_connect_cnt;
- u64 cs_discon_cnt;
-
- s32 tx_ucast_rate;
- s32 rx_ucast_rate;
-
- u32 lq_val;
-
- u32 wow_pkt_dropped;
- u16 wow_evt_discarded;
-
- s16 noise_floor_calib;
- s16 cs_rssi;
- s16 cs_ave_beacon_rssi;
- u8 cs_ave_beacon_snr;
- u8 cs_last_roam_msec;
- u8 cs_snr;
-
- u8 wow_host_pkt_wakeups;
- u8 wow_host_evt_wakeups;
-
- u32 arp_received;
- u32 arp_matched;
- u32 arp_replied;
-};
-
-struct ath6kl_mbox_info {
- u32 htc_addr;
- u32 htc_ext_addr;
- u32 htc_ext_sz;
-
- u32 block_size;
-
- u32 gmbox_addr;
-
- u32 gmbox_sz;
-};
-
-/*
- * 802.11i defines an extended IV for use with non-WEP ciphers.
- * When the EXTIV bit is set in the key id byte an additional
- * 4 bytes immediately follow the IV for TKIP. For CCMP the
- * EXTIV bit is likewise set but the 8 bytes represent the
- * CCMP header rather than IV+extended-IV.
- */
-
-#define ATH6KL_KEYBUF_SIZE 16
-#define ATH6KL_MICBUF_SIZE (8+8) /* space for both tx and rx */
-
-#define ATH6KL_KEY_XMIT 0x01
-#define ATH6KL_KEY_RECV 0x02
-#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
-
-/* Initial group key for AP mode */
-struct ath6kl_req_key {
- bool valid;
- u8 key_index;
- int key_type;
- u8 key[WLAN_MAX_KEY_LEN];
- u8 key_len;
-};
-
-/*
- * Bluetooth WiFi co-ex information.
- * This structure keeps track of the Bluetooth related status.
- * This involves the Bluetooth ACL link role, Bluetooth remote lmp version.
- */
-struct ath6kl_btcoex {
- u32 acl_role; /* Master/slave role of Bluetooth ACL link */
- u32 remote_lmp_ver; /* LMP version of the remote device. */
- u32 bt_vendor; /* Keeps track of the Bluetooth chip vendor */
-};
-enum ath6kl_hif_type {
- ATH6KL_HIF_TYPE_SDIO,
- ATH6KL_HIF_TYPE_USB,
-};
-
-/* Max number of filters that hw supports */
-#define ATH6K_MAX_MC_FILTERS_PER_LIST 7
-struct ath6kl_mc_filter {
- struct list_head list;
- char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
-};
-
-/*
- * Driver's maximum limit, note that some firmwares support only one vif
- * and the runtime (current) limit must be checked from ar->vif_max.
- */
-#define ATH6KL_VIF_MAX 3
-
-/* vif flags info */
-enum ath6kl_vif_state {
- CONNECTED,
- CONNECT_PEND,
- WMM_ENABLED,
- NETQ_STOPPED,
- DTIM_EXPIRED,
- NETDEV_REGISTERED,
- CLEAR_BSSFILTER_ON_BEACON,
- DTIM_PERIOD_AVAIL,
- WLAN_ENABLED,
- STATS_UPDATE_PEND,
- HOST_SLEEP_MODE_CMD_PROCESSED,
- SLEEP_POLICY_ENABLED,
-};
-
-struct ath6kl_vif {
- struct list_head list;
- struct wireless_dev wdev;
- struct net_device *ndev;
- struct ath6kl *ar;
- /* Lock to protect vif specific net_stats and flags */
- spinlock_t if_lock;
- u8 fw_vif_idx;
- unsigned long flags;
- int ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- u8 dot11_auth_mode;
- u8 auth_mode;
- u8 prwise_crypto;
- u8 prwise_crypto_len;
- u8 grp_crypto;
- u8 grp_crypto_len;
- u8 def_txkey_index;
- u8 next_mode;
- u8 nw_type;
- u8 bssid[ETH_ALEN];
- u8 req_bssid[ETH_ALEN];
- u16 ch_hint;
- u16 bss_ch;
- struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
- struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
- struct aggr_info *aggr_cntxt;
-
- struct timer_list disconnect_timer;
- struct timer_list sched_scan_timer;
-
- struct cfg80211_scan_request *scan_req;
- enum sme_state sme_state;
- int reconnect_flag;
- u32 last_roc_id;
- u32 last_cancel_roc_id;
- u32 send_action_id;
- bool probe_req_report;
- u16 next_chan;
- u16 assoc_bss_beacon_int;
- u16 bg_scan_period;
- u8 scan_ctrl_flag;
- u16 listen_intvl_t;
- u16 bmiss_time_t;
- u8 assoc_bss_dtim_period;
- struct net_device_stats net_stats;
- struct target_stats target_stats;
-
- struct list_head mc_filter;
-
- struct wmi_scan_params_cmd scparams;
- unsigned int pspoll_num;
- u16 mcastrate;
- bool force_reload;
- bool sdio_remove;
-};
-
-#define WOW_LIST_ID 0
-#define WOW_HOST_REQ_DELAY 500 /* ms */
-
-#define ATH6KL_SCHED_SCAN_RESULT_DELAY 5000 /* ms */
-
-/* Flag info */
-enum ath6kl_dev_state {
- WMI_ENABLED,
- WMI_READY,
- WMI_CTRL_EP_FULL,
- TESTMODE,
- DESTROY_IN_PROGRESS,
- SKIP_SCAN,
- ROAM_TBL_PEND,
- FIRST_BOOT,
- WOW_RESUME_PRINT,
-};
-
-enum ath6kl_state {
- ATH6KL_STATE_OFF,
- ATH6KL_STATE_ON,
- ATH6KL_STATE_SUSPENDING,
- ATH6KL_STATE_RESUMING,
- ATH6KL_STATE_DEEPSLEEP,
- ATH6KL_STATE_CUTPOWER,
- ATH6KL_STATE_WOW,
- ATH6KL_STATE_SCHED_SCAN,
-};
-
-struct ath6kl {
- struct device *dev;
- struct wiphy *wiphy;
-
- enum ath6kl_state state;
-
- struct ath6kl_bmi bmi;
- const struct ath6kl_hif_ops *hif_ops;
- struct wmi *wmi;
- int tx_pending[ENDPOINT_MAX];
- int total_tx_data_pend;
- struct htc_target *htc_target;
- enum ath6kl_hif_type hif_type;
- void *hif_priv;
- struct list_head vif_list;
- /* Lock to avoid race in vif_list entries among add/del/traverse */
- spinlock_t list_lock;
- u8 num_vif;
- unsigned int vif_max;
- u8 max_norm_iface;
- u8 avail_idx_map;
- spinlock_t lock;
- struct semaphore sem;
- u8 lrssi_roam_threshold;
- struct ath6kl_version version;
- u32 target_type;
- u8 tx_pwr;
- struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
- u8 ibss_ps_enable;
- bool ibss_if_active;
- u8 node_num;
- u8 next_ep_id;
- struct ath6kl_cookie *cookie_list;
- u32 cookie_count;
- enum htc_endpoint_id ac2ep_map[WMM_NUM_AC];
- bool ac_stream_active[WMM_NUM_AC];
- u8 ac_stream_pri_map[WMM_NUM_AC];
- u8 hiac_stream_active_pri;
- u8 ep2ac_map[ENDPOINT_MAX];
- enum htc_endpoint_id ctrl_ep;
- struct ath6kl_htc_credit_info credit_state_info;
- u32 connect_ctrl_flags;
- u32 user_key_ctrl;
- u8 usr_bss_filter;
- struct ath6kl_sta sta_list[AP_MAX_NUM_STA];
- u8 sta_list_index;
- struct ath6kl_req_key ap_mode_bkey;
- struct sk_buff_head mcastpsq;
- spinlock_t mcastpsq_lock;
- u8 intra_bss;
- struct wmi_ap_mode_stat ap_stats;
- u8 ap_country_code[3];
- struct list_head amsdu_rx_buffer_queue;
- u8 rx_meta_ver;
- enum wlan_low_pwr_state wlan_pwr_state;
- u8 mac_addr[ETH_ALEN];
-#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
- struct {
- void *rx_report;
- size_t rx_report_len;
- } tm;
-
- struct ath6kl_hw {
- u32 id;
- const char *name;
- u32 dataset_patch_addr;
- u32 app_load_addr;
- u32 app_start_override_addr;
- u32 board_ext_data_addr;
- u32 reserved_ram_size;
- u32 board_addr;
- u32 refclk_hz;
- u32 uarttx_pin;
- u32 testscript_addr;
-
- struct ath6kl_hw_fw {
- const char *dir;
- const char *otp;
- const char *fw;
- const char *tcmd;
- const char *patch;
- const char *utf;
- const char *testscript;
- } fw;
-
- const char *fw_board;
- const char *fw_default_board;
- } hw;
-
- u16 conf_flags;
- u16 suspend_mode;
- u16 wow_suspend_mode;
- wait_queue_head_t event_wq;
- struct ath6kl_mbox_info mbox_info;
-
- struct ath6kl_cookie cookie_mem[MAX_COOKIE_NUM];
- unsigned long flag;
-
- u8 *fw_board;
- size_t fw_board_len;
-
- u8 *fw_otp;
- size_t fw_otp_len;
-
- u8 *fw;
- size_t fw_len;
-
- u8 *fw_patch;
- size_t fw_patch_len;
-
- u8 *fw_testscript;
- size_t fw_testscript_len;
-
- unsigned int fw_api;
- unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN];
-
- struct workqueue_struct *ath6kl_wq;
-
- struct dentry *debugfs_phy;
-
- bool p2p;
-
- struct ath6kl_btcoex btcoex_info;
-
- unsigned int psminfo;
-
-#ifdef CONFIG_ATH6KL_DEBUG
- struct {
- struct sk_buff_head fwlog_queue;
- struct completion fwlog_completion;
- bool fwlog_open;
-
- u32 fwlog_mask;
-
- unsigned int dbgfs_diag_reg;
- u32 diag_reg_addr_wr;
- u32 diag_reg_val_wr;
-
- struct {
- unsigned int invalid_rate;
- } war_stats;
-
- u8 *roam_tbl;
- unsigned int roam_tbl_len;
-
- u8 keepalive;
- u8 disc_timeout;
- } debug;
-#endif /* CONFIG_ATH6KL_DEBUG */
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- struct early_suspend early_suspend;
- bool screen_off;
-#endif /* CONFIG_HAS_EARLYSUSPEND */
-
-#ifdef CONFIG_HAS_WAKELOCK
- struct wake_lock wake_lock;
- struct wake_lock p2p_wake_lock;
-#endif /* CONFIG_HAS_WAKELOCK */
-
-};
-
-#ifdef CONFIG_MACH_PX
-/*
- For this 3.2.0.4402 image:
- 00561734 g O .bss 00000004 epc1
- 00561738 g O .bss 00000004 epc2
- 0056173c g O .bss 00000004 epc3
- 00561740 g O .bss 00000004 epc4
-
- For this 3.2.0.64 image:
- 00561fa4 g O .bss 00000004 epc1
-*/
-
-#define EPC1_ADDR 0x00
-
-void ath6kl_print_ar6k_registers(struct ath6kl *ar);
-#endif
-
-static inline struct ath6kl *ath6kl_priv(struct net_device *dev)
-{
- return ((struct ath6kl_vif *) netdev_priv(dev))->ar;
-}
-
-static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
- u32 item_offset)
-{
- u32 addr = 0;
-
- if (ar->target_type == TARGET_TYPE_AR6003)
- addr = ATH6KL_AR6003_HI_START_ADDR + item_offset;
- else if (ar->target_type == TARGET_TYPE_AR6004)
- addr = ATH6KL_AR6004_HI_START_ADDR + item_offset;
-
- return addr;
-}
-
-int ath6kl_configure_target(struct ath6kl *ar);
-void ath6kl_detect_error(unsigned long ptr);
-void disconnect_timer_handler(unsigned long ptr);
-void init_netdev(struct net_device *dev);
-void ath6kl_cookie_init(struct ath6kl *ar);
-void ath6kl_cookie_cleanup(struct ath6kl *ar);
-void ath6kl_rx(struct htc_target *target, struct htc_packet *packet);
-void ath6kl_tx_complete(void *context, struct list_head *packet_queue);
-enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
- struct htc_packet *packet);
-void ath6kl_stop_txrx(struct ath6kl *ar);
-void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
-int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value);
-int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length);
-int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value);
-int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length);
-int ath6kl_read_fwlogs(struct ath6kl *ar);
-void ath6kl_init_profile_info(struct ath6kl_vif *vif);
-void ath6kl_tx_data_cleanup(struct ath6kl *ar);
-
-struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
-void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
-int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
-
-struct aggr_info *aggr_init(struct ath6kl_vif *vif);
-void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
- struct aggr_info_conn *aggr_conn);
-void ath6kl_rx_refill(struct htc_target *target,
- enum htc_endpoint_id endpoint);
-void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
-struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
- enum htc_endpoint_id endpoint,
- int len);
-void aggr_module_destroy(struct aggr_info *aggr_info);
-void aggr_reset_state(struct aggr_info_conn *aggr_conn);
-
-struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr);
-struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
-
-void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
-int ath6kl_control_tx(void *devt, struct sk_buff *skb,
- enum htc_endpoint_id eid);
-void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
- u8 *bssid, u16 listen_int,
- u16 beacon_int, enum network_type net_type,
- u8 beacon_ie_len, u8 assoc_req_len,
- u8 assoc_resp_len, u8 *assoc_info);
-void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
-void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
- u8 keymgmt, u8 ucipher, u8 auth,
- u8 assoc_req_len, u8 *assoc_info, u8 apsd_info);
-void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
- u8 *bssid, u8 assoc_resp_len,
- u8 *assoc_info, u16 prot_reason_status);
-void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast);
-void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr);
-void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status);
-void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len);
-void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active);
-enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);
-
-void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid);
-
-void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif);
-void ath6kl_disconnect(struct ath6kl_vif *vif);
-void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid);
-void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
- u8 win_sz);
-void ath6kl_wakeup_event(void *dev);
-
-void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
- bool wait_fot_compltn, bool cold_reset);
-void ath6kl_init_control_info(struct ath6kl_vif *vif);
-void ath6kl_deinit_if_data(struct ath6kl_vif *vif);
-void ath6kl_core_free(struct ath6kl *ar);
-struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
-void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready);
-int ath6kl_init_hw_start(struct ath6kl *ar);
-int ath6kl_init_hw_stop(struct ath6kl *ar);
-void ath6kl_check_wow_status(struct ath6kl *ar, struct sk_buff *skb,
- bool is_event_pkt);
-#ifdef CONFIG_MACH_PX
-void ath6kl_sdio_init_c210(void);
-void ath6kl_sdio_exit_c210(void);
-#else
-void ath6kl_sdio_init_msm(void);
-void ath6kl_sdio_exit_msm(void);
-#endif
-void ath6kl_mangle_mac_address(struct ath6kl *ar);
-
-#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/dbglog.c b/drivers/net/wireless/ath/ath6kl/dbglog.c
deleted file mode 100644
index 3498aac..0000000
--- a/drivers/net/wireless/ath/ath6kl/dbglog.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (c) 2011 Qualcomm Atheros
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <linux/circ_buf.h>
-#include "core.h"
-#include "debug.h"
-#include "dbglog.h"
-
-#define DEVICE_NAME "ath6kl-dbglog"
-#define DBGLOG_BUFSIZ 8192
-static int major_num;
-static int num_readers;
-static struct circ_buf dbglog_buf;
-static spinlock_t dbglog_lock;
-static wait_queue_head_t dbglog_wait;
-static struct class *dbglog_class;
-static struct device *dbglog_dev;
-
-
-void ath6kl_dbglog_add(const u8 *buf, size_t len)
-{
- size_t i;
- int added = 0;
- int cspace;
-
- if (major_num < 0 || dbglog_buf.buf == NULL)
- return;
-
- spin_lock_bh(&dbglog_lock);
- i = 0;
- while (i < len) {
- if (CIRC_SPACE(dbglog_buf.head, dbglog_buf.tail,
- DBGLOG_BUFSIZ) == 0) {
- spin_unlock_bh(&dbglog_lock);
- if (num_readers)
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "dbglog buffer overflow");
- return;
- }
- cspace = CIRC_SPACE_TO_END(dbglog_buf.head, dbglog_buf.tail,
- DBGLOG_BUFSIZ);
- if ((size_t) cspace > len - i)
- cspace = len - i;
- memcpy(&dbglog_buf.buf[dbglog_buf.head], &buf[i], cspace);
- dbglog_buf.head = (dbglog_buf.head + cspace) &
- (DBGLOG_BUFSIZ - 1);
- i += cspace;
- added++;
- }
- spin_unlock_bh(&dbglog_lock);
- if (added)
- wake_up(&dbglog_wait);
-}
-
-static int ath6kl_dbglog_open(struct inode *inode, struct file *filp)
-{
- if (major_num < 0 || dbglog_buf.buf == NULL)
- return -EOPNOTSUPP;
-
- if (num_readers)
- return -EBUSY;
-
- num_readers++;
- try_module_get(THIS_MODULE);
-
- return 0;
-}
-
-static int ath6kl_dbglog_release(struct inode *inode, struct file *filp)
-{
- num_readers--;
- module_put(THIS_MODULE);
- return 0;
-}
-
-static bool ath6kl_dbglog_empty(void)
-{
- return CIRC_CNT(dbglog_buf.head, dbglog_buf.tail, DBGLOG_BUFSIZ) == 0;
-}
-
-static ssize_t ath6kl_dbglog_read(struct file *filp, char *buf, size_t len,
- loff_t *offset)
-{
- char *pos = buf;
-
- wait_event_interruptible(dbglog_wait, !ath6kl_dbglog_empty());
- spin_lock_bh(&dbglog_lock);
- while (len &&
- CIRC_CNT(dbglog_buf.head, dbglog_buf.tail, DBGLOG_BUFSIZ) > 0) {
- int ccnt = CIRC_CNT_TO_END(dbglog_buf.head, dbglog_buf.tail,
- DBGLOG_BUFSIZ);
- spin_unlock_bh(&dbglog_lock);
- if ((size_t) ccnt > len)
- ccnt = len;
- if (copy_to_user(pos, &dbglog_buf.buf[dbglog_buf.tail], ccnt))
- return -EFAULT;
- pos += ccnt;
- spin_lock_bh(&dbglog_lock);
- dbglog_buf.tail = (dbglog_buf.tail + ccnt) &
- (DBGLOG_BUFSIZ - 1);
- len -= ccnt;
- }
- spin_unlock_bh(&dbglog_lock);
-
- return pos - buf;
-}
-
-static ssize_t ath6kl_dbglog_write(struct file *filp, const char *buf,
- size_t len, loff_t *off)
-{
- return -EOPNOTSUPP;
-}
-
-static struct file_operations fops = {
- .open = ath6kl_dbglog_open,
- .release = ath6kl_dbglog_release,
- .read = ath6kl_dbglog_read,
- .write = ath6kl_dbglog_write,
-};
-
-int ath6kl_dbglog_init(void)
-{
- major_num = -1;
- dbglog_buf.buf = kmalloc(DBGLOG_BUFSIZ, GFP_KERNEL);
- if (dbglog_buf.buf == NULL)
- return -ENOMEM;
-
- dbglog_buf.head = dbglog_buf.tail = 0;
-
- major_num = register_chrdev(0, DEVICE_NAME, &fops);
- if (major_num < 0) {
- ath6kl_err("Failed to register chrdev for dbglog: %d\n",
- major_num);
- return major_num;
- }
-
- dbglog_class = class_create(THIS_MODULE, DEVICE_NAME);
- dbglog_dev = device_create(dbglog_class, NULL, MKDEV(major_num, 0),
- NULL, DEVICE_NAME);
-
- spin_lock_init(&dbglog_lock);
- init_waitqueue_head(&dbglog_wait);
-
- return 0;
-}
-
-void ath6kl_dbglog_deinit(void)
-{
- device_destroy(dbglog_class, MKDEV(major_num, 0));
- class_unregister(dbglog_class);
- class_destroy(dbglog_class);
- unregister_chrdev(major_num, DEVICE_NAME);
- kfree(dbglog_buf.buf);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/dbglog.h b/drivers/net/wireless/ath/ath6kl/dbglog.h
deleted file mode 100644
index 9c244be..0000000
--- a/drivers/net/wireless/ath/ath6kl/dbglog.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2011 Qualcomm Atheros
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef DBGLOG_H
-#define DBGLOG_H
-
-void ath6kl_dbglog_add(const u8 *buf, size_t len);
-int ath6kl_dbglog_init(void);
-void ath6kl_dbglog_deinit(void);
-
-#endif /* DBGLOG_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
deleted file mode 100755
index 28b3e77..0000000
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ /dev/null
@@ -1,2022 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-
-#include <linux/skbuff.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-
-#include "debug.h"
-#include "debugfs_pri.h"
-#include "target.h"
-
-struct ath6kl_fwlog_slot {
- __le32 timestamp;
- __le32 length;
-
- /* max ATH6KL_FWLOG_PAYLOAD_SIZE bytes */
- u8 payload[0];
-};
-
-#define ATH6KL_FWLOG_MAX_ENTRIES 20
-
-#define ATH6KL_FWLOG_VALID_MASK 0x1ffff
-
-int ath6kl_printk(const char *level, const char *fmt, ...)
-{
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
- struct va_format vaf;
-#endif
- va_list args;
- int rtn;
-
- va_start(args, fmt);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
- vaf.fmt = fmt;
- vaf.va = &args;
-
- rtn = printk("%sath6kl: %pV", level, &vaf);
-#else
- printk("%sath6kl: ", level);
- rtn = vprintk(fmt, args);
-#endif
-
- va_end(args);
-
- return rtn;
-}
-
-char *sec_conv_mac(const u8 *mac)
-{
- static char ret_mac[16];
- char *p = ret_mac;
-
- p = pack_hex_byte(p, mac[0]);
- *p++ = '_';
- p = pack_hex_byte(p, mac[4]);
- *p++ = ':';
- p = pack_hex_byte(p, mac[5]);
- *p++ = '\0';
-
- return ret_mac;
-}
-
-#ifdef CONFIG_ATH6KL_DEBUG
-
-#define REG_OUTPUT_LEN_PER_LINE 25
-#define REGTYPE_STR_LEN 100
-
-struct ath6kl_diag_reg_info {
- u32 reg_start;
- u32 reg_end;
- const char *reg_info;
-};
-
-static const struct ath6kl_diag_reg_info diag_reg[] = {
- { 0x20000, 0x200fc, "General DMA and Rx registers" },
- { 0x28000, 0x28900, "MAC PCU register & keycache" },
- { 0x20800, 0x20a40, "QCU" },
- { 0x21000, 0x212f0, "DCU" },
- { 0x4000, 0x42e4, "RTC" },
- { 0x540000, 0x540000 + (256 * 1024), "RAM" },
- { 0x29800, 0x2B210, "Base Band" },
- { 0x1C000, 0x1C748, "Analog" },
-};
-
-void ath6kl_dump_registers(struct ath6kl_device *dev,
- struct ath6kl_irq_proc_registers *irq_proc_reg,
- struct ath6kl_irq_enable_reg *irq_enable_reg)
-{
-
- ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
-
- if (irq_proc_reg != NULL) {
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Host Int status: 0x%x\n",
- irq_proc_reg->host_int_status);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "CPU Int status: 0x%x\n",
- irq_proc_reg->cpu_int_status);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Error Int status: 0x%x\n",
- irq_proc_reg->error_int_status);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Counter Int status: 0x%x\n",
- irq_proc_reg->counter_int_status);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Mbox Frame: 0x%x\n",
- irq_proc_reg->mbox_frame);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Rx Lookahead Valid: 0x%x\n",
- irq_proc_reg->rx_lkahd_valid);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Rx Lookahead 0: 0x%x\n",
- irq_proc_reg->rx_lkahd[0]);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Rx Lookahead 1: 0x%x\n",
- irq_proc_reg->rx_lkahd[1]);
-
- if (dev->ar->mbox_info.gmbox_addr != 0) {
- /*
- * If the target supports GMBOX hardware, dump some
- * additional state.
- */
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "GMBOX Host Int status 2: 0x%x\n",
- irq_proc_reg->host_int_status2);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "GMBOX RX Avail: 0x%x\n",
- irq_proc_reg->gmbox_rx_avail);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "GMBOX lookahead alias 0: 0x%x\n",
- irq_proc_reg->rx_gmbox_lkahd_alias[0]);
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "GMBOX lookahead alias 1: 0x%x\n",
- irq_proc_reg->rx_gmbox_lkahd_alias[1]);
- }
-
- }
-
- if (irq_enable_reg != NULL) {
- ath6kl_dbg(ATH6KL_DBG_ANY,
- "Int status Enable: 0x%x\n",
- irq_enable_reg->int_status_en);
- ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
- irq_enable_reg->cntr_int_status_en);
- }
- ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
-}
-
-static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
-{
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "--- endpoint: %d svc_id: 0x%X ---\n",
- ep_dist->endpoint, ep_dist->svc_id);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " dist_flags : 0x%X\n",
- ep_dist->dist_flags);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_norm : %d\n",
- ep_dist->cred_norm);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_min : %d\n",
- ep_dist->cred_min);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " credits : %d\n",
- ep_dist->credits);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_assngd : %d\n",
- ep_dist->cred_assngd);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " seek_cred : %d\n",
- ep_dist->seek_cred);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_sz : %d\n",
- ep_dist->cred_sz);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_per_msg : %d\n",
- ep_dist->cred_per_msg);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_to_dist : %d\n",
- ep_dist->cred_to_dist);
- ath6kl_dbg(ATH6KL_DBG_CREDIT, " txq_depth : %d\n",
- get_queue_depth(&ep_dist->htc_ep->txq));
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "----------------------------------\n");
-}
-
-/* FIXME: move to htc.c */
-void dump_cred_dist_stats(struct htc_target *target)
-{
- struct htc_endpoint_credit_dist *ep_list;
-
- if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT))
- return;
-
- list_for_each_entry(ep_list, &target->cred_dist_list, list)
- dump_cred_dist(ep_list);
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "credit distribution total %d free %d\n",
- target->credit_info->total_avail_credits,
- target->credit_info->cur_free_credits);
-}
-
-static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
-{
- switch (war) {
- case ATH6KL_WAR_INVALID_RATE:
- ar->debug.war_stats.invalid_rate++;
- break;
- }
-}
-
-static ssize_t read_file_war_stats(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char *buf;
- unsigned int len = 0, buf_len = 1500;
- ssize_t ret_cnt;
-
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Workaround stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10u\n",
- "Invalid rates", ar->debug.war_stats.invalid_rate);
-
- if (WARN_ON(len > buf_len))
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-
- kfree(buf);
- return ret_cnt;
-}
-
-static const struct file_operations fops_war_stats = {
- .read = read_file_war_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len)
-{
- struct ath6kl_fwlog_slot *slot;
- struct sk_buff *skb;
- size_t slot_len;
-
- if (WARN_ON(len > ATH6KL_FWLOG_PAYLOAD_SIZE))
- return;
-
- slot_len = sizeof(*slot) + ATH6KL_FWLOG_PAYLOAD_SIZE;
-
- skb = alloc_skb(slot_len, GFP_KERNEL);
- if (!skb)
- return;
-
- slot = (struct ath6kl_fwlog_slot *) skb_put(skb, slot_len);
- slot->timestamp = cpu_to_le32(jiffies);
- slot->length = cpu_to_le32(len);
- memcpy(slot->payload, buf, len);
-
- /* Need to pad each record to fixed length ATH6KL_FWLOG_PAYLOAD_SIZE */
- memset(slot->payload + len, 0, ATH6KL_FWLOG_PAYLOAD_SIZE - len);
-
- spin_lock(&ar->debug.fwlog_queue.lock);
-
- __skb_queue_tail(&ar->debug.fwlog_queue, skb);
- complete(&ar->debug.fwlog_completion);
-
- /* drop oldest entries */
- while (skb_queue_len(&ar->debug.fwlog_queue) >
- ATH6KL_FWLOG_MAX_ENTRIES) {
- skb = __skb_dequeue(&ar->debug.fwlog_queue);
- kfree_skb(skb);
- }
-
- spin_unlock(&ar->debug.fwlog_queue.lock);
-
- return;
-}
-
-static int ath6kl_fwlog_open(struct inode *inode, struct file *file)
-{
- struct ath6kl *ar = inode->i_private;
-
- if (ar->debug.fwlog_open)
- return -EBUSY;
-
- ar->debug.fwlog_open = true;
-
- file->private_data = inode->i_private;
- return 0;
-}
-
-static int ath6kl_fwlog_release(struct inode *inode, struct file *file)
-{
- struct ath6kl *ar = inode->i_private;
-
- ar->debug.fwlog_open = false;
-
- return 0;
-}
-
-static ssize_t ath6kl_fwlog_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct sk_buff *skb;
- ssize_t ret_cnt;
- size_t len = 0;
- char *buf;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
-
- /* read undelivered logs from firmware */
- ath6kl_read_fwlogs(ar);
-
- spin_lock(&ar->debug.fwlog_queue.lock);
-
- while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) {
- if (skb->len > count - len) {
- /* not enough space, put skb back and leave */
- __skb_queue_head(&ar->debug.fwlog_queue, skb);
- break;
- }
-
-
- memcpy(buf + len, skb->data, skb->len);
- len += skb->len;
-
- kfree_skb(skb);
- }
-
- spin_unlock(&ar->debug.fwlog_queue.lock);
-
- /* FIXME: what to do if len == 0? */
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-
- vfree(buf);
-
- return ret_cnt;
-}
-
-static const struct file_operations fops_fwlog = {
- .open = ath6kl_fwlog_open,
- .release = ath6kl_fwlog_release,
- .read = ath6kl_fwlog_read,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_fwlog_block_read(struct file *file,
- char __user *user_buf,
- size_t count,
- loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct sk_buff *skb;
- ssize_t ret_cnt;
- size_t len = 0, not_copied;
- char *buf;
- int ret;
-
- buf = vmalloc(count);
- if (!buf)
- return -ENOMEM;
-
- spin_lock(&ar->debug.fwlog_queue.lock);
-
- if (skb_queue_len(&ar->debug.fwlog_queue) == 0) {
- /* we must init under queue lock */
- init_completion(&ar->debug.fwlog_completion);
-
- spin_unlock(&ar->debug.fwlog_queue.lock);
-
- ret = wait_for_completion_interruptible(
- &ar->debug.fwlog_completion);
- if (ret == -ERESTARTSYS) {
- vfree(buf);
- return ret;
- }
-
- spin_lock(&ar->debug.fwlog_queue.lock);
- }
-
- while ((skb = __skb_dequeue(&ar->debug.fwlog_queue))) {
- if (skb->len > count - len) {
- /* not enough space, put skb back and leave */
- __skb_queue_head(&ar->debug.fwlog_queue, skb);
- break;
- }
-
-
- memcpy(buf + len, skb->data, skb->len);
- len += skb->len;
-
- kfree_skb(skb);
- }
-
- spin_unlock(&ar->debug.fwlog_queue.lock);
-
- /* FIXME: what to do if len == 0? */
-
- not_copied = copy_to_user(user_buf, buf, len);
- if (not_copied != 0) {
- ret_cnt = -EFAULT;
- goto out;
- }
-
- *ppos = *ppos + len;
-
- ret_cnt = len;
-
-out:
- vfree(buf);
-
- return ret_cnt;
-}
-
-static const struct file_operations fops_fwlog_block = {
- .open = ath6kl_fwlog_open,
- .release = ath6kl_fwlog_release,
- .read = ath6kl_fwlog_block_read,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_fwlog_mask_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[16];
- int len;
-
- len = snprintf(buf, sizeof(buf), "0x%x\n", ar->debug.fwlog_mask);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_fwlog_mask_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
-
- ret = kstrtou32_from_user(user_buf, count, 0, &ar->debug.fwlog_mask);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_config_debug_module_cmd(ar->wmi,
- ATH6KL_FWLOG_VALID_MASK,
- ar->debug.fwlog_mask);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_fwlog_mask = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_fwlog_mask_read,
- .write = ath6kl_fwlog_mask_write,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- struct target_stats *tgt_stats;
- char *buf;
- unsigned int len = 0, buf_len = 1500;
- int i;
- long left;
- ssize_t ret_cnt;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- tgt_stats = &vif->target_stats;
-
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (down_interruptible(&ar->sem)) {
- kfree(buf);
- return -EBUSY;
- }
-
- set_bit(STATS_UPDATE_PEND, &vif->flags);
-
- if (ath6kl_wmi_get_stats_cmd(ar->wmi, 0)) {
- up(&ar->sem);
- kfree(buf);
- return -EIO;
- }
-
- left = wait_event_interruptible_timeout(ar->event_wq,
- !test_bit(STATS_UPDATE_PEND,
- &vif->flags), WMI_TIMEOUT);
-
- up(&ar->sem);
-
- if (left <= 0) {
- kfree(buf);
- return -ETIMEDOUT;
- }
-
- len += scnprintf(buf + len, buf_len - len, "\n");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Target Tx stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast packets", tgt_stats->tx_ucast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast packets", tgt_stats->tx_bcast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast byte", tgt_stats->tx_ucast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast byte", tgt_stats->tx_bcast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Rts success cnt", tgt_stats->tx_rts_success_cnt);
- for (i = 0; i < 4; i++)
- len += scnprintf(buf + len, buf_len - len,
- "%18s %d %10llu\n", "PER on ac",
- i, tgt_stats->tx_pkt_per_ac[i]);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Error", tgt_stats->tx_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Fail count", tgt_stats->tx_fail_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Retry count", tgt_stats->tx_retry_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Multi retry cnt", tgt_stats->tx_mult_retry_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Rts fail cnt", tgt_stats->tx_rts_fail_cnt);
- len += scnprintf(buf + len, buf_len - len, "%25s %10llu\n\n",
- "TKIP counter measure used",
- tgt_stats->tkip_cnter_measures_invoked);
-
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Target Rx stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "=================");
-
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast packets", tgt_stats->rx_ucast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "Ucast Rate", tgt_stats->rx_ucast_rate);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast packets", tgt_stats->rx_bcast_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Ucast byte", tgt_stats->rx_ucast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Bcast byte", tgt_stats->rx_bcast_byte);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Fragmented pkt", tgt_stats->rx_frgment_pkt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Error", tgt_stats->rx_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "CRC Err", tgt_stats->rx_crc_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Key chache miss", tgt_stats->rx_key_cache_miss);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Decrypt Err", tgt_stats->rx_decrypt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Duplicate frame", tgt_stats->rx_dupl_frame);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Tkip Mic failure", tgt_stats->tkip_local_mic_fail);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "TKIP format err", tgt_stats->tkip_fmt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "CCMP format Err", tgt_stats->ccmp_fmt_err);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n\n",
- "CCMP Replay Err", tgt_stats->ccmp_replays);
-
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "Misc Target stats");
- len += scnprintf(buf + len, buf_len - len, "%25s\n",
- "=================");
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Beacon Miss count", tgt_stats->cs_bmiss_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Num Connects", tgt_stats->cs_connect_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10llu\n",
- "Num disconnects", tgt_stats->cs_discon_cnt);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "Beacon avg rssi", tgt_stats->cs_ave_beacon_rssi);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "ARP pkt received", tgt_stats->arp_received);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "ARP pkt matched", tgt_stats->arp_matched);
- len += scnprintf(buf + len, buf_len - len, "%20s %10d\n",
- "ARP pkt replied", tgt_stats->arp_replied);
-
- if (len > buf_len)
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-
- kfree(buf);
- return ret_cnt;
-}
-
-static const struct file_operations fops_tgt_stats = {
- .read = read_file_tgt_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-#define print_credit_info(fmt_str, ep_list_field) \
- (len += scnprintf(buf + len, buf_len - len, fmt_str, \
- ep_list->ep_list_field))
-#define CREDIT_INFO_DISPLAY_STRING_LEN 200
-#define CREDIT_INFO_LEN 128
-
-static ssize_t read_file_credit_dist_stats(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct htc_target *target = ar->htc_target;
- struct htc_endpoint_credit_dist *ep_list;
- char *buf;
- unsigned int buf_len, len = 0;
- ssize_t ret_cnt;
-
- buf_len = CREDIT_INFO_DISPLAY_STRING_LEN +
- get_queue_depth(&target->cred_dist_list) * CREDIT_INFO_LEN;
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
- "Total Avail Credits: ",
- target->credit_info->total_avail_credits);
- len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
- "Free credits :",
- target->credit_info->cur_free_credits);
-
- len += scnprintf(buf + len, buf_len - len,
- " Epid Flags Cred_norm Cred_min Credits Cred_assngd"
- " Seek_cred Cred_sz Cred_per_msg Cred_to_dist"
- " qdepth\n");
-
- list_for_each_entry(ep_list, &target->cred_dist_list, list) {
- print_credit_info(" %2d", endpoint);
- print_credit_info("%10x", dist_flags);
- print_credit_info("%8d", cred_norm);
- print_credit_info("%9d", cred_min);
- print_credit_info("%9d", credits);
- print_credit_info("%10d", cred_assngd);
- print_credit_info("%13d", seek_cred);
- print_credit_info("%12d", cred_sz);
- print_credit_info("%9d", cred_per_msg);
- print_credit_info("%14d", cred_to_dist);
- len += scnprintf(buf + len, buf_len - len, "%12d\n",
- get_queue_depth(&ep_list->htc_ep->txq));
- }
-
- if (len > buf_len)
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
- kfree(buf);
- return ret_cnt;
-}
-
-static const struct file_operations fops_credit_dist_stats = {
- .read = read_file_credit_dist_stats,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static unsigned int print_endpoint_stat(struct htc_target *target, char *buf,
- unsigned int buf_len, unsigned int len,
- int offset, const char *name)
-{
- int i;
- struct htc_endpoint_stats *ep_st;
- u32 *counter;
-
- len += scnprintf(buf + len, buf_len - len, "%s:", name);
- for (i = 0; i < ENDPOINT_MAX; i++) {
- ep_st = &target->endpoint[i].ep_st;
- counter = ((u32 *) ep_st) + (offset / 4);
- len += scnprintf(buf + len, buf_len - len, " %u", *counter);
- }
- len += scnprintf(buf + len, buf_len - len, "\n");
-
- return len;
-}
-
-static ssize_t ath6kl_endpoint_stats_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct htc_target *target = ar->htc_target;
- char *buf;
- unsigned int buf_len, len = 0;
- ssize_t ret_cnt;
-
- buf_len = sizeof(struct htc_endpoint_stats) / sizeof(u32) *
- (25 + ENDPOINT_MAX * 11);
- buf = kmalloc(buf_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
-#define EPSTAT(name) \
- len = print_endpoint_stat(target, buf, buf_len, len, \
- offsetof(struct htc_endpoint_stats, name), \
- #name)
- EPSTAT(cred_low_indicate);
- EPSTAT(tx_issued);
- EPSTAT(tx_pkt_bundled);
- EPSTAT(tx_bundles);
- EPSTAT(tx_dropped);
- EPSTAT(tx_cred_rpt);
- EPSTAT(cred_rpt_from_rx);
- EPSTAT(cred_rpt_from_other);
- EPSTAT(cred_rpt_ep0);
- EPSTAT(cred_from_rx);
- EPSTAT(cred_from_other);
- EPSTAT(cred_from_ep0);
- EPSTAT(cred_cosumd);
- EPSTAT(cred_retnd);
- EPSTAT(rx_pkts);
- EPSTAT(rx_lkahds);
- EPSTAT(rx_bundl);
- EPSTAT(rx_bundle_lkahd);
- EPSTAT(rx_bundle_from_hdr);
- EPSTAT(rx_alloc_thresh_hit);
- EPSTAT(rxalloc_thresh_byte);
-#undef EPSTAT
-
- if (len > buf_len)
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
- kfree(buf);
- return ret_cnt;
-}
-
-static ssize_t ath6kl_endpoint_stats_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct htc_target *target = ar->htc_target;
- int ret, i;
- u32 val;
- struct htc_endpoint_stats *ep_st;
-
- ret = kstrtou32_from_user(user_buf, count, 0, &val);
- if (ret)
- return ret;
- if (val == 0) {
- for (i = 0; i < ENDPOINT_MAX; i++) {
- ep_st = &target->endpoint[i].ep_st;
- memset(ep_st, 0, sizeof(*ep_st));
- }
- }
-
- return count;
-}
-
-static const struct file_operations fops_endpoint_stats = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_endpoint_stats_read,
- .write = ath6kl_endpoint_stats_write,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static unsigned long ath6kl_get_num_reg(void)
-{
- int i;
- unsigned long n_reg = 0;
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++)
- n_reg = n_reg +
- (diag_reg[i].reg_end - diag_reg[i].reg_start) / 4 + 1;
-
- return n_reg;
-}
-
-static bool ath6kl_dbg_is_diag_reg_valid(u32 reg_addr)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
- if (reg_addr >= diag_reg[i].reg_start &&
- reg_addr <= diag_reg[i].reg_end)
- return true;
- }
-
- return false;
-}
-
-static ssize_t ath6kl_regread_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[50];
- unsigned int len = 0;
-
- if (ar->debug.dbgfs_diag_reg)
- len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n",
- ar->debug.dbgfs_diag_reg);
- else
- len += scnprintf(buf + len, sizeof(buf) - len,
- "All diag registers\n");
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_regread_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[50];
- unsigned int len;
- unsigned long reg_addr;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
-
- if (strict_strtoul(buf, 0, &reg_addr))
- return -EINVAL;
-
- if ((reg_addr % 4) != 0)
- return -EINVAL;
-
- if (reg_addr && !ath6kl_dbg_is_diag_reg_valid(reg_addr))
- return -EINVAL;
-
- ar->debug.dbgfs_diag_reg = reg_addr;
-
- return count;
-}
-
-static const struct file_operations fops_diag_reg_read = {
- .read = ath6kl_regread_read,
- .write = ath6kl_regread_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static int ath6kl_regdump_open(struct inode *inode, struct file *file)
-{
- struct ath6kl *ar = inode->i_private;
- u8 *buf;
- unsigned long int reg_len;
- unsigned int len = 0, n_reg;
- u32 addr;
- __le32 reg_val;
- int i, status;
-
- /* Dump all the registers if no register is specified */
- if (!ar->debug.dbgfs_diag_reg)
- n_reg = ath6kl_get_num_reg();
- else
- n_reg = 1;
-
- reg_len = n_reg * REG_OUTPUT_LEN_PER_LINE;
- if (n_reg > 1)
- reg_len += REGTYPE_STR_LEN;
-
- buf = vmalloc(reg_len);
- if (!buf)
- return -ENOMEM;
-
- if (n_reg == 1) {
- addr = ar->debug.dbgfs_diag_reg;
-
- status = ath6kl_diag_read32(ar,
- TARG_VTOP(ar->target_type, addr),
- (u32 *)&reg_val);
- if (status)
- goto fail_reg_read;
-
- len += scnprintf(buf + len, reg_len - len,
- "0x%06x 0x%08x\n", addr, le32_to_cpu(reg_val));
- goto done;
- }
-
- for (i = 0; i < ARRAY_SIZE(diag_reg); i++) {
- len += scnprintf(buf + len, reg_len - len,
- "%s\n", diag_reg[i].reg_info);
- for (addr = diag_reg[i].reg_start;
- addr <= diag_reg[i].reg_end; addr += 4) {
- status = ath6kl_diag_read32(ar,
- TARG_VTOP(ar->target_type, addr),
- (u32 *)&reg_val);
- if (status)
- goto fail_reg_read;
-
- len += scnprintf(buf + len, reg_len - len,
- "0x%06x 0x%08x\n",
- addr, le32_to_cpu(reg_val));
- }
- }
-
-done:
- file->private_data = buf;
- return 0;
-
-fail_reg_read:
- ath6kl_warn("Unable to read memory:%u\n", addr);
- vfree(buf);
- return -EIO;
-}
-
-static ssize_t ath6kl_regdump_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- u8 *buf = file->private_data;
- return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
-}
-
-static int ath6kl_regdump_release(struct inode *inode, struct file *file)
-{
- vfree(file->private_data);
- return 0;
-}
-
-static const struct file_operations fops_reg_dump = {
- .open = ath6kl_regdump_open,
- .read = ath6kl_regdump_read,
- .release = ath6kl_regdump_release,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_lrssi_roam_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- unsigned long lrssi_roam_threshold;
- char buf[32];
- ssize_t len;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (strict_strtoul(buf, 0, &lrssi_roam_threshold))
- return -EINVAL;
-
- ar->lrssi_roam_threshold = lrssi_roam_threshold;
-
- ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, ar->lrssi_roam_threshold);
-
- return count;
-}
-
-static ssize_t ath6kl_lrssi_roam_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[32];
- unsigned int len;
-
- len = snprintf(buf, sizeof(buf), "%u\n", ar->lrssi_roam_threshold);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_lrssi_roam_threshold = {
- .read = ath6kl_lrssi_roam_read,
- .write = ath6kl_lrssi_roam_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_regwrite_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[32];
- unsigned int len = 0;
-
- len = scnprintf(buf, sizeof(buf), "Addr: 0x%x Val: 0x%x\n",
- ar->debug.diag_reg_addr_wr, ar->debug.diag_reg_val_wr);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_regwrite_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[32];
- char *sptr, *token;
- unsigned int len = 0;
- u32 reg_addr, reg_val;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, "=");
- if (!token)
- return -EINVAL;
-
- if (kstrtou32(token, 0, &reg_addr))
- return -EINVAL;
-
- if (!ath6kl_dbg_is_diag_reg_valid(reg_addr))
- return -EINVAL;
-
- if (kstrtou32(sptr, 0, &reg_val))
- return -EINVAL;
-
- ar->debug.diag_reg_addr_wr = reg_addr;
- ar->debug.diag_reg_val_wr = reg_val;
-
- if (ath6kl_diag_write32(ar, ar->debug.diag_reg_addr_wr,
- cpu_to_le32(ar->debug.diag_reg_val_wr)))
- return -EIO;
-
- return count;
-}
-
-static const struct file_operations fops_diag_reg_write = {
- .read = ath6kl_regwrite_read,
- .write = ath6kl_regwrite_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf,
- size_t len)
-{
- const struct wmi_target_roam_tbl *tbl;
- u16 num_entries;
-
- if (len < sizeof(*tbl))
- return -EINVAL;
-
- tbl = (const struct wmi_target_roam_tbl *) buf;
- num_entries = le16_to_cpu(tbl->num_entries);
- if (sizeof(*tbl) + num_entries * sizeof(struct wmi_bss_roam_info) >
- len)
- return -EINVAL;
-
- if (ar->debug.roam_tbl == NULL ||
- ar->debug.roam_tbl_len < (unsigned int) len) {
- kfree(ar->debug.roam_tbl);
- ar->debug.roam_tbl = kmalloc(len, GFP_ATOMIC);
- if (ar->debug.roam_tbl == NULL)
- return -ENOMEM;
- }
-
- memcpy(ar->debug.roam_tbl, buf, len);
- ar->debug.roam_tbl_len = len;
-
- if (test_bit(ROAM_TBL_PEND, &ar->flag)) {
- clear_bit(ROAM_TBL_PEND, &ar->flag);
- wake_up(&ar->event_wq);
- }
-
- return 0;
-}
-
-static ssize_t ath6kl_roam_table_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- long left;
- struct wmi_target_roam_tbl *tbl;
- u16 num_entries, i;
- char *buf;
- unsigned int len, buf_len;
- ssize_t ret_cnt;
-
- if (down_interruptible(&ar->sem))
- return -EBUSY;
-
- set_bit(ROAM_TBL_PEND, &ar->flag);
-
- ret = ath6kl_wmi_get_roam_tbl_cmd(ar->wmi);
- if (ret) {
- up(&ar->sem);
- return ret;
- }
-
- left = wait_event_interruptible_timeout(
- ar->event_wq, !test_bit(ROAM_TBL_PEND, &ar->flag), WMI_TIMEOUT);
- up(&ar->sem);
-
- if (left <= 0)
- return -ETIMEDOUT;
-
- if (ar->debug.roam_tbl == NULL)
- return -ENOMEM;
-
- tbl = (struct wmi_target_roam_tbl *) ar->debug.roam_tbl;
- num_entries = le16_to_cpu(tbl->num_entries);
-
- buf_len = 100 + num_entries * 100;
- buf = kzalloc(buf_len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- len = 0;
- len += scnprintf(buf + len, buf_len - len,
- "roam_mode=%u\n\n"
- "# roam_util bssid rssi rssidt last_rssi util bias\n",
- le16_to_cpu(tbl->roam_mode));
-
- for (i = 0; i < num_entries; i++) {
- struct wmi_bss_roam_info *info = &tbl->info[i];
- len += scnprintf(buf + len, buf_len - len,
- "%d %pM %d %d %d %d %d\n",
- a_sle32_to_cpu(info->roam_util), info->bssid,
- info->rssi, info->rssidt, info->last_rssi,
- info->util, info->bias);
- }
-
- if (len > buf_len)
- len = buf_len;
-
- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
-
- kfree(buf);
- return ret_cnt;
-}
-
-static const struct file_operations fops_roam_table = {
- .read = ath6kl_roam_table_read,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_force_roam_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- char buf[20];
- size_t len;
- u8 bssid[ETH_ALEN];
- int i;
- int addr[ETH_ALEN];
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
-
- if (sscanf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5])
- != ETH_ALEN)
- return -EINVAL;
- for (i = 0; i < ETH_ALEN; i++)
- bssid[i] = addr[i];
-
- ret = ath6kl_wmi_force_roam_cmd(ar->wmi, bssid);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_force_roam = {
- .write = ath6kl_force_roam_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_roam_mode_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- char buf[20];
- size_t len;
- enum wmi_roam_mode mode;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- if (len > 0 && buf[len - 1] == '\n')
- buf[len - 1] = '\0';
-
- if (strcasecmp(buf, "default") == 0)
- mode = WMI_DEFAULT_ROAM_MODE;
- else if (strcasecmp(buf, "bssbias") == 0)
- mode = WMI_HOST_BIAS_ROAM_MODE;
- else if (strcasecmp(buf, "lock") == 0)
- mode = WMI_LOCK_BSS_MODE;
- else
- return -EINVAL;
-
- ret = ath6kl_wmi_set_roam_mode_cmd(ar->wmi, mode);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_roam_mode = {
- .write = ath6kl_roam_mode_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive)
-{
- ar->debug.keepalive = keepalive;
-}
-
-static ssize_t ath6kl_keepalive_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[16];
- int len;
-
- len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.keepalive);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_keepalive_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- u8 val;
-
- ret = kstrtou8_from_user(user_buf, count, 0, &val);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_set_keepalive_cmd(ar->wmi, 0, val);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_keepalive = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_keepalive_read,
- .write = ath6kl_keepalive_write,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout)
-{
- ar->debug.disc_timeout = timeout;
-}
-
-static ssize_t ath6kl_disconnect_timeout_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- char buf[16];
- int len;
-
- len = snprintf(buf, sizeof(buf), "%u\n", ar->debug.disc_timeout);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath6kl_disconnect_timeout_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- u8 val;
-
- ret = kstrtou8_from_user(user_buf, count, 0, &val);
- if (ret)
- return ret;
-
- ret = ath6kl_wmi_disctimeout_cmd(ar->wmi, 0, val);
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_disconnect_timeout = {
- .open = ath6kl_debugfs_open,
- .read = ath6kl_disconnect_timeout_read,
- .write = ath6kl_disconnect_timeout_write,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_create_qos_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
-
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- char buf[200];
- ssize_t len;
- char *sptr, *token;
- struct wmi_create_pstream_cmd pstream;
- u32 val32;
- u16 val16;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.user_pri))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.traffic_direc))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.traffic_class))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.traffic_type))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.voice_psc_cap))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.min_service_int = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.max_service_int = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.inactivity_int = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.suspension_int = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.service_start_time = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &pstream.tsid))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &val16))
- return -EINVAL;
- pstream.nominal_msdu = cpu_to_le16(val16);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &val16))
- return -EINVAL;
- pstream.max_msdu = cpu_to_le16(val16);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.min_data_rate = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.mean_data_rate = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.peak_data_rate = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.max_burst_size = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.delay_bound = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.min_phy_rate = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.sba = cpu_to_le32(val32);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou32(token, 0, &val32))
- return -EINVAL;
- pstream.medium_time = cpu_to_le32(val32);
-
- pstream.nominal_phy = ((le32_to_cpu(pstream.min_phy_rate) / 1000) / 1000);
-
- ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream);
-
- return count;
-}
-
-static const struct file_operations fops_create_qos = {
- .write = ath6kl_create_qos_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_delete_qos_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
-
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- char buf[100];
- ssize_t len;
- char *sptr, *token;
- u8 traffic_class;
- u8 tsid;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &traffic_class))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &tsid))
- return -EINVAL;
-
- ath6kl_wmi_delete_pstream_cmd(ar->wmi, vif->fw_vif_idx,
- traffic_class, tsid);
-
- return count;
-}
-
-static const struct file_operations fops_delete_qos = {
- .write = ath6kl_delete_qos_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_bgscan_int_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- u16 bgscan_int;
- char buf[32];
- ssize_t len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (kstrtou16(buf, 0, &bgscan_int))
- return -EINVAL;
-
- if (bgscan_int == 0)
- bgscan_int = 0xffff;
-
- vif->bg_scan_period = bgscan_int;
- ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, bgscan_int, 0, 0, 0, 3,
- vif->scan_ctrl_flag, 0, 0);
-
- return count;
-}
-
-static const struct file_operations fops_bgscan_int = {
- .write = ath6kl_bgscan_int_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_listen_int_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- u16 listen_interval;
- char buf[32];
- ssize_t len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (kstrtou16(buf, 0, &listen_interval))
- return -EINVAL;
-
- if ((listen_interval < 15) || (listen_interval > 3000))
- return -EINVAL;
-
- vif->listen_intvl_t = listen_interval;
- ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
- vif->listen_intvl_t, 0);
-
- return count;
-}
-
-static ssize_t ath6kl_listen_int_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- char buf[32];
- int len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = scnprintf(buf, sizeof(buf), "%u\n", vif->listen_intvl_t);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_listen_int = {
- .read = ath6kl_listen_int_read,
- .write = ath6kl_listen_int_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_mcastrate_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- u16 mcastrate;
- char buf[32];
- ssize_t len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (kstrtou16(buf, 0, &mcastrate))
- return -EINVAL;
-
- vif->mcastrate = mcastrate;
- ath6kl_wmi_mcastrate_cmd(ar->wmi, vif->fw_vif_idx,
- vif->mcastrate);
-
- return count;
-}
-
-static ssize_t ath6kl_mcastrate_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- char buf[32];
- int len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = scnprintf(buf, sizeof(buf), "%u\n", vif->mcastrate);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_mcastrate = {
- .read = ath6kl_mcastrate_read,
- .write = ath6kl_mcastrate_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_power_params_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- u8 buf[100];
- unsigned int len = 0;
- char *sptr, *token;
- u16 idle_period, ps_poll_num, dtim,
- tx_wakeup, num_tx;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &idle_period))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &ps_poll_num))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &dtim))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &tx_wakeup))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &num_tx))
- return -EINVAL;
-
- ath6kl_wmi_pmparams_cmd(ar->wmi, 0, idle_period, ps_poll_num,
- dtim, tx_wakeup, num_tx, 0);
-
- return count;
-}
-
-static const struct file_operations fops_power_params = {
- .write = ath6kl_power_params_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_lrssi_roam_config_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct low_rssi_scan_params lrssi_params;
- char buf[32];
- ssize_t len;
- char *sptr, *token;
- u16 val16;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &val16))
- return -EINVAL;
- lrssi_params.lrssi_scan_period = cpu_to_le16(val16);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &val16))
- return -EINVAL;
- lrssi_params.lrssi_scan_threshold = cpu_to_le16(val16);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou16(token, 0, &val16))
- return -EINVAL;
- lrssi_params.lrssi_roam_threshold = cpu_to_le16(val16);
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &lrssi_params.roam_rssi_floor))
- return -EINVAL;
-
- ath6kl_wmi_set_roam_lrssi_config_cmd(ar->wmi, &lrssi_params);
-
- return count;
-}
-
-static const struct file_operations fops_lrssi_roam_config = {
- .write = ath6kl_lrssi_roam_config_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_ht_cap_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- struct wmi_set_ht_cap_cmd ht_cap;
- char buf[32];
- ssize_t len;
- char *sptr, *token;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- sptr = buf;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.band))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.enable))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.chan_width_40m_supported))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.short_gi_20mhz))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.short_gi_40mhz))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.intolerance_40mhz))
- return -EINVAL;
-
- token = strsep(&sptr, " ");
- if (!token)
- return -EINVAL;
- if (kstrtou8(token, 0, &ht_cap.max_ampdu_len_exp))
- return -EINVAL;
-
- ath6kl_wmi_set_ht_cap_cmd(ar->wmi, vif->fw_vif_idx, &ht_cap);
-
- return count;
-}
-
-static const struct file_operations fops_ht_cap = {
- .write = ath6kl_ht_cap_write,
- .open = ath6kl_debugfs_open,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-int ath6kl_debug_init(struct ath6kl *ar)
-{
- skb_queue_head_init(&ar->debug.fwlog_queue);
- init_completion(&ar->debug.fwlog_completion);
-
- /*
- * Actually we are lying here but don't know how to read the mask
- * value from the firmware.
- */
- ar->debug.fwlog_mask = 0;
-
- ar->debugfs_phy = debugfs_create_dir("ath6kl",
- ar->wiphy->debugfsdir);
- if (!ar->debugfs_phy)
- return -ENOMEM;
-
- debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_tgt_stats);
-
- debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_credit_dist_stats);
-
- debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_endpoint_stats);
-
- debugfs_create_file("fwlog", S_IRUSR, ar->debugfs_phy, ar,
- &fops_fwlog);
-
- debugfs_create_file("fwlog_block", S_IRUSR, ar->debugfs_phy, ar,
- &fops_fwlog_block);
-
- debugfs_create_file("fwlog_mask", S_IRUSR | S_IWUSR, ar->debugfs_phy,
- ar, &fops_fwlog_mask);
-
- debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
- &fops_diag_reg_read);
-
- debugfs_create_file("reg_dump", S_IRUSR, ar->debugfs_phy, ar,
- &fops_reg_dump);
-
- debugfs_create_file("lrssi_roam_threshold", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_lrssi_roam_threshold);
-
- debugfs_create_file("reg_write", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_diag_reg_write);
-
- debugfs_create_file("war_stats", S_IRUSR, ar->debugfs_phy, ar,
- &fops_war_stats);
-
- debugfs_create_file("roam_table", S_IRUSR, ar->debugfs_phy, ar,
- &fops_roam_table);
-
- debugfs_create_file("force_roam", S_IWUSR, ar->debugfs_phy, ar,
- &fops_force_roam);
-
- debugfs_create_file("roam_mode", S_IWUSR, ar->debugfs_phy, ar,
- &fops_roam_mode);
-
- debugfs_create_file("keepalive", S_IRUSR | S_IWUSR, ar->debugfs_phy, ar,
- &fops_keepalive);
-
- debugfs_create_file("disconnect_timeout", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_disconnect_timeout);
-
- debugfs_create_file("create_qos", S_IWUSR, ar->debugfs_phy, ar,
- &fops_create_qos);
-
- debugfs_create_file("delete_qos", S_IWUSR, ar->debugfs_phy, ar,
- &fops_delete_qos);
-
- debugfs_create_file("bgscan_interval", S_IWUSR,
- ar->debugfs_phy, ar, &fops_bgscan_int);
-
- debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_listen_int);
-
- debugfs_create_file("mcast_rate", S_IRUSR | S_IWUSR,
- ar->debugfs_phy, ar, &fops_mcastrate);
-
- debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
- &fops_power_params);
-
- debugfs_create_file("lrssi_roam_config", S_IRUSR, ar->debugfs_phy, ar,
- &fops_lrssi_roam_config);
-
- debugfs_create_file("ht_cap", S_IRUSR, ar->debugfs_phy, ar,
- &fops_ht_cap);
-
- return ath6kl_init_debugfs_pri(ar);
-}
-
-void ath6kl_debug_cleanup(struct ath6kl *ar)
-{
- skb_queue_purge(&ar->debug.fwlog_queue);
- kfree(ar->debug.roam_tbl);
-}
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
deleted file mode 100755
index aaecb5d..0000000
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include "hif.h"
-
-enum ATH6K_DEBUG_MASK {
- ATH6KL_DBG_CREDIT = BIT(0),
- /* hole */
- ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */
- ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */
- ATH6KL_DBG_BMI = BIT(4), /* bmi tracing */
- ATH6KL_DBG_HTC = BIT(5),
- ATH6KL_DBG_HIF = BIT(6),
- ATH6KL_DBG_IRQ = BIT(7), /* interrupt processing */
- /* hole */
- /* hole */
- ATH6KL_DBG_WMI = BIT(10), /* wmi tracing */
- ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
- ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
- ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
- ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx frames */
- ATH6KL_DBG_AGGR = BIT(15), /* aggregation */
- ATH6KL_DBG_SDIO = BIT(16),
- ATH6KL_DBG_SDIO_DUMP = BIT(17),
- ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */
- ATH6KL_DBG_WMI_DUMP = BIT(19),
- ATH6KL_DBG_SUSPEND = BIT(20),
- ATH6KL_DBG_USB = BIT(21),
- ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
-};
-
-extern unsigned int debug_mask;
-extern __printf(2, 3)
-int ath6kl_printk(const char *level, const char *fmt, ...);
-char *sec_conv_mac(const u8 *mac);
-
-#define ath6kl_info(fmt, ...) \
- ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
-#define ath6kl_err(fmt, ...) \
- ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
-#define ath6kl_warn(fmt, ...) \
- ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
-
-#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
-
-enum ath6kl_war {
- ATH6KL_WAR_INVALID_RATE,
-};
-
-#ifdef CONFIG_ATH6KL_DEBUG
-#define ath6kl_dbg(mask, fmt, ...) \
- ({ \
- int rtn; \
- if (debug_mask & mask) \
- rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \
- else \
- rtn = 0; \
- \
- rtn; \
- })
-
-static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
- const char *msg, const char *prefix,
- const void *buf, size_t len)
-{
- if (debug_mask & mask) {
- if (msg)
- ath6kl_dbg(mask, "%s\n", msg);
-
- print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
- }
-}
-
-void ath6kl_dump_registers(struct ath6kl_device *dev,
- struct ath6kl_irq_proc_registers *irq_proc_reg,
- struct ath6kl_irq_enable_reg *irq_en_reg);
-void dump_cred_dist_stats(struct htc_target *target);
-void ath6kl_debug_fwlog_event(struct ath6kl *ar, const void *buf, size_t len);
-void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war);
-int ath6kl_debug_roam_tbl_event(struct ath6kl *ar, const void *buf,
- size_t len);
-void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive);
-void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar, u8 timeout);
-int ath6kl_debug_init(struct ath6kl *ar);
-void ath6kl_debug_cleanup(struct ath6kl *ar);
-
-#else
-static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
- const char *fmt, ...)
-{
- return 0;
-}
-
-static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
- const char *msg, const char *prefix,
- const void *buf, size_t len)
-{
-}
-
-static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
- struct ath6kl_irq_proc_registers *irq_proc_reg,
- struct ath6kl_irq_enable_reg *irq_en_reg)
-{
-
-}
-static inline void dump_cred_dist_stats(struct htc_target *target)
-{
-}
-
-static inline void ath6kl_debug_fwlog_event(struct ath6kl *ar,
- const void *buf, size_t len)
-{
-}
-
-static inline void ath6kl_debug_war(struct ath6kl *ar, enum ath6kl_war war)
-{
-}
-
-static inline int ath6kl_debug_roam_tbl_event(struct ath6kl *ar,
- const void *buf, size_t len)
-{
- return 0;
-}
-
-static inline void ath6kl_debug_set_keepalive(struct ath6kl *ar, u8 keepalive)
-{
-}
-
-static inline void ath6kl_debug_set_disconnect_timeout(struct ath6kl *ar,
- u8 timeout)
-{
-}
-
-static inline int ath6kl_debug_init(struct ath6kl *ar)
-{
- return 0;
-}
-
-static inline void ath6kl_debug_cleanup(struct ath6kl *ar)
-{
-}
-
-#endif
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debugfs_pri.c b/drivers/net/wireless/ath/ath6kl/debugfs_pri.c
deleted file mode 100644
index 1130cb2..0000000
--- a/drivers/net/wireless/ath/ath6kl/debugfs_pri.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (c) 2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef CONFIG_ATH6KL_DEBUG
-
-#include <linux/skbuff.h>
-#include <linux/export.h>
-#include "core.h"
-#include "wmi.h"
-#include "debug.h"
-#include "debugfs_pri.h"
-
-struct wmi_set_inact_period_cmd {
- __le32 inact_period;
- u8 num_null_func;
-} __packed;
-
-static inline struct sk_buff *ath6kl_wmi_get_new_buf_pri(u32 size)
-{
- struct sk_buff *skb;
-
- skb = ath6kl_buf_alloc(size);
- if (!skb)
- return NULL;
-
- skb_put(skb, size);
- if (size)
- memset(skb->data, 0, size);
-
- return skb;
-}
-
-static int ath6kl_wmi_inact_period_cmd(struct wmi *wmi, u32 inact_period,
- u8 num_null_func)
-{
- struct sk_buff *skb;
- struct wmi_set_inact_period_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf_pri(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_inact_period_cmd *) skb->data;
- cmd->inact_period = cpu_to_le32(inact_period);
- cmd->num_null_func = num_null_func;
-
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_AP_CONN_INACT_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-static int ath6kl_wmi_set_err_report_bitmask(struct wmi *wmi, u8 if_idx,
- u32 mask)
-{
- struct sk_buff *skb;
- struct wmi_tgt_err_report_mask *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf_pri(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_tgt_err_report_mask *) skb->data;
- cmd->mask = cpu_to_le32(mask);
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
- WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_error_report_event(struct wmi *wmi, u8 *data, int len)
-{
- struct wmi_tgt_err_report_evt *report;
-
- if (len < sizeof(*report))
- return -EINVAL;
-
- report = (struct wmi_tgt_err_report_evt *) data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "Reason for error report: 0x%x\n",
- report->err_val);
-
- return 0;
-}
-
-static int ath6kl_debugfs_open_pri(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t ath6kl_inact_period_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- int ret;
- char buf[32];
- u32 inact_period;
- size_t len;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (kstrtou32(buf, 0, &inact_period))
- return -EINVAL;
-
- ret = ath6kl_wmi_inact_period_cmd(ar->wmi, inact_period, 0);
-
- if (ret)
- return ret;
-
- return count;
-}
-
-static const struct file_operations fops_inact_period = {
- .write = ath6kl_inact_period_write,
- .open = ath6kl_debugfs_open_pri,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_bmisstime_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- u16 bmiss_time;
- char buf[32];
- ssize_t len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, len))
- return -EFAULT;
-
- buf[len] = '\0';
- if (kstrtou16(buf, 0, &bmiss_time))
- return -EINVAL;
-
- vif->bmiss_time_t = bmiss_time;
-
- /* Enable error report event for bmiss */
- ath6kl_wmi_set_err_report_bitmask(ar->wmi, vif->fw_vif_idx,
- ATH6KL_ERR_REPORT_BMISS_MASK);
-
- ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
- vif->bmiss_time_t, 0);
- return count;
-}
-
-static ssize_t ath6kl_bmisstime_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- char buf[32];
- int len;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- len = scnprintf(buf, sizeof(buf), "%u\n", vif->bmiss_time_t);
-
- return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_bmisstime = {
- .read = ath6kl_bmisstime_read,
- .write = ath6kl_bmisstime_write,
- .open = ath6kl_debugfs_open_pri,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-static ssize_t ath6kl_scan_ctrl_flag_write(struct file *file,
- const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct ath6kl *ar = file->private_data;
- struct ath6kl_vif *vif;
- u8 ctrl_flag;
- int ret;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return -EIO;
-
- ret = kstrtou8_from_user(user_buf, count, 0, &ctrl_flag);
- if (ret)
- return ret;
-
- if (ctrl_flag > ATH6KL_MAX_SCAN_CTRL_FLAGS)
- ctrl_flag = ATH6KL_DEFAULT_SCAN_CTRL_FLAGS;
-
- vif->scan_ctrl_flag = ctrl_flag;
- ath6kl_wmi_scanparams_cmd(ar->wmi, 0, 0, 0, vif->bg_scan_period, 0, 0,
- 0, 3, ctrl_flag, 0, 0);
-
- return count;
-}
-
-static const struct file_operations fops_scanctrl_flag = {
- .write = ath6kl_scan_ctrl_flag_write,
- .open = ath6kl_debugfs_open_pri,
- .owner = THIS_MODULE,
- .llseek = default_llseek,
-};
-
-int ath6kl_init_debugfs_pri(struct ath6kl *ar)
-{
- debugfs_create_file("inactivity_period", S_IWUSR, ar->debugfs_phy, ar,
- &fops_inact_period);
-
- debugfs_create_file("bmiss_time", S_IRUSR | S_IWUSR, ar->debugfs_phy,
- ar, &fops_bmisstime);
-
- debugfs_create_file("scan_ctrl_flag", S_IRUSR, ar->debugfs_phy, ar,
- &fops_scanctrl_flag);
-
- return 0;
-}
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debugfs_pri.h b/drivers/net/wireless/ath/ath6kl/debugfs_pri.h
deleted file mode 100644
index de862f2..0000000
--- a/drivers/net/wireless/ath/ath6kl/debugfs_pri.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef DEBUG_PRI_H
-#define DEBUG_PRI_H
-
-#ifdef CONFIG_ATH6KL_DEBUG
-
-#define ATH6KL_ERR_REPORT_BMISS_MASK BIT(3)
-
-struct wmi_tgt_err_report_mask {
- __le32 mask;
-};
-
-struct wmi_tgt_err_report_evt {
- __le32 err_val;
-} __packed;
-
-#define ATH6KL_DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS | \
- SCAN_CONNECTED_CTRL_FLAGS | \
- ACTIVE_SCAN_CTRL_FLAGS | \
- ROAM_SCAN_CTRL_FLAGS | \
- ENABLE_AUTO_CTRL_FLAGS)
-
-#define ATH6KL_MAX_SCAN_CTRL_FLAGS 0x7F
-
-int ath6kl_wmi_error_report_event(struct wmi *wmi, u8 *data, int len);
-int ath6kl_init_debugfs_pri(struct ath6kl *ar);
-#endif
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
deleted file mode 100755
index fb2b196..0000000
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef HIF_OPS_H
-#define HIF_OPS_H
-
-#include "hif.h"
-#include "debug.h"
-
-static inline int hif_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
- u32 len, u32 request)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF,
- "hif %s sync addr 0x%x buf 0x%p len %d request 0x%x\n",
- (request & HIF_WRITE) ? "write" : "read",
- addr, buf, len, request);
-
- return ar->hif_ops->read_write_sync(ar, addr, buf, len, request);
-}
-
-static inline int hif_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
- u32 length, u32 request,
- struct htc_packet *packet)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF,
- "hif write async addr 0x%x buf 0x%p len %d request 0x%x\n",
- address, buffer, length, request);
-
- return ar->hif_ops->write_async(ar, address, buffer, length,
- request, packet);
-}
-static inline void ath6kl_hif_irq_enable(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif irq enable\n");
-
- return ar->hif_ops->irq_enable(ar);
-}
-
-static inline void ath6kl_hif_irq_disable(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif irq disable\n");
-
- return ar->hif_ops->irq_disable(ar);
-}
-
-static inline struct hif_scatter_req *hif_scatter_req_get(struct ath6kl *ar)
-{
- return ar->hif_ops->scatter_req_get(ar);
-}
-
-static inline void hif_scatter_req_add(struct ath6kl *ar,
- struct hif_scatter_req *s_req)
-{
- return ar->hif_ops->scatter_req_add(ar, s_req);
-}
-
-static inline int ath6kl_hif_enable_scatter(struct ath6kl *ar)
-{
- return ar->hif_ops->enable_scatter(ar);
-}
-
-static inline int ath6kl_hif_scat_req_rw(struct ath6kl *ar,
- struct hif_scatter_req *scat_req)
-{
- return ar->hif_ops->scat_req_rw(ar, scat_req);
-}
-
-static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
-{
- return ar->hif_ops->cleanup_scatter(ar);
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-static inline int ath6kl_hif_suspend(struct ath6kl *ar,
- struct cfg80211_wowlan *wow)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif suspend\n");
-
- return ar->hif_ops->suspend(ar, wow);
-}
-#endif
-
-/*
- * Read from the ATH6KL through its diagnostic window. No cooperation from
- * the Target is required for this.
- */
-static inline int ath6kl_hif_diag_read32(struct ath6kl *ar, u32 address,
- u32 *value)
-{
- return ar->hif_ops->diag_read32(ar, address, value);
-}
-
-/*
- * Write to the ATH6KL through its diagnostic window. No cooperation from
- * the Target is required for this.
- */
-static inline int ath6kl_hif_diag_write32(struct ath6kl *ar, u32 address,
- __le32 value)
-{
- return ar->hif_ops->diag_write32(ar, address, value);
-}
-
-static inline int ath6kl_hif_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
-{
- return ar->hif_ops->bmi_read(ar, buf, len);
-}
-
-static inline int ath6kl_hif_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
-{
- return ar->hif_ops->bmi_write(ar, buf, len);
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-static inline int ath6kl_hif_resume(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif resume\n");
-
- return ar->hif_ops->resume(ar);
-}
-#endif
-
-static inline int ath6kl_hif_power_on(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif power on\n");
-
- return ar->hif_ops->power_on(ar);
-}
-
-static inline int ath6kl_hif_power_off(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif power off\n");
-
- return ar->hif_ops->power_off(ar);
-}
-
-static inline void ath6kl_hif_stop(struct ath6kl *ar)
-{
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif stop\n");
-
- ar->hif_ops->stop(ar);
-}
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
deleted file mode 100755
index 2793ab6..0000000
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * Copyright (c) 2007-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#include "hif.h"
-
-#include "core.h"
-#include "target.h"
-#include "hif-ops.h"
-#include "debug.h"
-
-#define MAILBOX_FOR_BLOCK_SIZE 1
-
-#define ATH6KL_TIME_QUANTUM 10 /* in ms */
-
-static int ath6kl_hif_cp_scat_dma_buf(struct hif_scatter_req *req,
- bool from_dma)
-{
- u8 *buf;
- int i;
-
- buf = req->virt_dma_buf;
-
- for (i = 0; i < req->scat_entries; i++) {
-
- if (from_dma)
- memcpy(req->scat_list[i].buf, buf,
- req->scat_list[i].len);
- else
- memcpy(buf, req->scat_list[i].buf,
- req->scat_list[i].len);
-
- buf += req->scat_list[i].len;
- }
-
- return 0;
-}
-
-int ath6kl_hif_rw_comp_handler(void *context, int status)
-{
- struct htc_packet *packet = context;
-
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif rw completion pkt 0x%p status %d\n",
- packet, status);
-
- packet->status = status;
- packet->completion(packet->context, packet);
-
- return 0;
-}
-#define REG_DUMP_COUNT_AR6003 60
-#define REGISTER_DUMP_LEN_MAX 60
-
-static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
-{
- __le32 regdump_val[REGISTER_DUMP_LEN_MAX];
- u32 i, address, regdump_addr = 0;
- int ret;
-
- if (ar->target_type != TARGET_TYPE_AR6003)
- return;
-
- /* the reg dump pointer is copied to the host interest area */
- address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
- address = TARG_VTOP(ar->target_type, address);
-
- /* read RAM location through diagnostic window */
- ret = ath6kl_diag_read32(ar, address, &regdump_addr);
-
- if (ret || !regdump_addr) {
- ath6kl_warn("failed to get ptr to register dump area: %d\n",
- ret);
- return;
- }
-
- ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n",
- regdump_addr);
- regdump_addr = TARG_VTOP(ar->target_type, regdump_addr);
-
- /* fetch register dump data */
- ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)&regdump_val[0],
- REG_DUMP_COUNT_AR6003 * (sizeof(u32)));
- if (ret) {
- ath6kl_warn("failed to get register dump: %d\n", ret);
- return;
- }
-
- ath6kl_info("crash dump:\n");
- ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version,
- ar->wiphy->fw_version);
-
- BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4);
-
- for (i = 0; i < REG_DUMP_COUNT_AR6003; i += 4) {
- ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
- i,
- le32_to_cpu(regdump_val[i]),
- le32_to_cpu(regdump_val[i + 1]),
- le32_to_cpu(regdump_val[i + 2]),
- le32_to_cpu(regdump_val[i + 3]));
- }
-
-}
-
-static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
-{
- u32 dummy;
- int ret;
- struct ath6kl_vif *vif;
-
- vif = ath6kl_vif_first(dev->ar);
-
- ath6kl_warn("firmware crashed\n");
-
- /*
- * read counter to clear the interrupt, the debug error interrupt is
- * counter 0.
- */
- ret = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
- (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
- if (ret)
- ath6kl_warn("Failed to clear debug interrupt: %d\n", ret);
-
- ath6kl_hif_dump_fw_crash(dev->ar);
- ath6kl_read_fwlogs(dev->ar);
-
- cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
-
- return ret;
-}
-
-/* mailbox recv message polling */
-int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd,
- int timeout)
-{
- struct ath6kl_irq_proc_registers *rg;
- int status = 0, i;
- u8 htc_mbox = 1 << HTC_MAILBOX;
-
- for (i = timeout / ATH6KL_TIME_QUANTUM; i > 0; i--) {
- /* this is the standard HIF way, load the reg table */
- status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
- (u8 *) &dev->irq_proc_reg,
- sizeof(dev->irq_proc_reg),
- HIF_RD_SYNC_BYTE_INC);
-
- if (status) {
- ath6kl_err("failed to read reg table\n");
- return status;
- }
-
- /* check for MBOX data and valid lookahead */
- if (dev->irq_proc_reg.host_int_status & htc_mbox) {
- if (dev->irq_proc_reg.rx_lkahd_valid &
- htc_mbox) {
- /*
- * Mailbox has a message and the look ahead
- * is valid.
- */
- rg = &dev->irq_proc_reg;
- *lk_ahd =
- le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
- break;
- }
- }
-
- /* delay a little */
- mdelay(ATH6KL_TIME_QUANTUM);
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif retry mbox poll try %d\n", i);
- }
-
- if (i == 0) {
- ath6kl_err("timeout waiting for recv message\n");
- status = -ETIME;
- /* check if the target asserted */
- if (dev->irq_proc_reg.counter_int_status &
- ATH6KL_TARGET_DEBUG_INTR_MASK)
- /*
- * Target failure handler will be called in case of
- * an assert.
- */
- ath6kl_hif_proc_dbg_intr(dev);
- }
-
- return status;
-}
-
-/*
- * Disable packet reception (used in case the host runs out of buffers)
- * using the interrupt enable registers through the host I/F
- */
-int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx)
-{
- struct ath6kl_irq_enable_reg regs;
- int status = 0;
-
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif rx %s\n",
- enable_rx ? "enable" : "disable");
-
- /* take the lock to protect interrupt enable shadows */
- spin_lock_bh(&dev->lock);
-
- if (enable_rx)
- dev->irq_en_reg.int_status_en |=
- SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
- else
- dev->irq_en_reg.int_status_en &=
- ~SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
-
- memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
-
- spin_unlock_bh(&dev->lock);
-
- status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
- &regs.int_status_en,
- sizeof(struct ath6kl_irq_enable_reg),
- HIF_WR_SYNC_BYTE_INC);
-
- return status;
-}
-
-int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev,
- struct hif_scatter_req *scat_req, bool read)
-{
- int status = 0;
-
- if (read) {
- scat_req->req = HIF_RD_SYNC_BLOCK_FIX;
- scat_req->addr = dev->ar->mbox_info.htc_addr;
- } else {
- scat_req->req = HIF_WR_ASYNC_BLOCK_INC;
-
- scat_req->addr =
- (scat_req->len > HIF_MBOX_WIDTH) ?
- dev->ar->mbox_info.htc_ext_addr :
- dev->ar->mbox_info.htc_addr;
- }
-
- ath6kl_dbg(ATH6KL_DBG_HIF,
- "hif submit scatter request entries %d len %d mbox 0x%x %s %s\n",
- scat_req->scat_entries, scat_req->len,
- scat_req->addr, !read ? "async" : "sync",
- (read) ? "rd" : "wr");
-
- if (!read && scat_req->virt_scat) {
- status = ath6kl_hif_cp_scat_dma_buf(scat_req, false);
- if (status) {
- scat_req->status = status;
- scat_req->complete(dev->ar->htc_target, scat_req);
- return 0;
- }
- }
-
- status = ath6kl_hif_scat_req_rw(dev->ar, scat_req);
-
- if (read) {
- /* in sync mode, we can touch the scatter request */
- scat_req->status = status;
- if (!status && scat_req->virt_scat)
- scat_req->status =
- ath6kl_hif_cp_scat_dma_buf(scat_req, true);
- }
-
- return status;
-}
-
-static int ath6kl_hif_proc_counter_intr(struct ath6kl_device *dev)
-{
- u8 counter_int_status;
-
- ath6kl_dbg(ATH6KL_DBG_IRQ, "counter interrupt\n");
-
- counter_int_status = dev->irq_proc_reg.counter_int_status &
- dev->irq_en_reg.cntr_int_status_en;
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
- counter_int_status);
-
- /*
- * NOTE: other modules like GMBOX may use the counter interrupt for
- * credit flow control on other counters, we only need to check for
- * the debug assertion counter interrupt.
- */
- if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK)
- return ath6kl_hif_proc_dbg_intr(dev);
-
- return 0;
-}
-
-static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev)
-{
- int status;
- u8 error_int_status;
- u8 reg_buf[4];
-
- ath6kl_dbg(ATH6KL_DBG_IRQ, "error interrupt\n");
-
- error_int_status = dev->irq_proc_reg.error_int_status & 0x0F;
- if (!error_int_status) {
- WARN_ON(1);
- return -EIO;
- }
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
- error_int_status);
-
- if (MS(ERROR_INT_STATUS_WAKEUP, error_int_status))
- ath6kl_dbg(ATH6KL_DBG_IRQ, "error : wakeup\n");
-
- if (MS(ERROR_INT_STATUS_RX_UNDERFLOW, error_int_status))
- ath6kl_err("rx underflow\n");
-
- if (MS(ERROR_INT_STATUS_TX_OVERFLOW, error_int_status))
- ath6kl_err("tx overflow\n");
-
- /* Clear the interrupt */
- dev->irq_proc_reg.error_int_status &= ~error_int_status;
-
- /* set W1C value to clear the interrupt, this hits the register first */
- reg_buf[0] = error_int_status;
- reg_buf[1] = 0;
- reg_buf[2] = 0;
- reg_buf[3] = 0;
-
- status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
- reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
-
- if (status)
- WARN_ON(1);
-
- return status;
-}
-
-static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev)
-{
- int status;
- u8 cpu_int_status;
- u8 reg_buf[4];
-
- ath6kl_dbg(ATH6KL_DBG_IRQ, "cpu interrupt\n");
-
- cpu_int_status = dev->irq_proc_reg.cpu_int_status &
- dev->irq_en_reg.cpu_int_status_en;
- if (!cpu_int_status) {
- WARN_ON(1);
- return -EIO;
- }
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
- cpu_int_status);
-
- /* Clear the interrupt */
- dev->irq_proc_reg.cpu_int_status &= ~cpu_int_status;
-
- /*
- * Set up the register transfer buffer to hit the register 4 times ,
- * this is done to make the access 4-byte aligned to mitigate issues
- * with host bus interconnects that restrict bus transfer lengths to
- * be a multiple of 4-bytes.
- */
-
- /* set W1C value to clear the interrupt, this hits the register first */
- reg_buf[0] = cpu_int_status;
- /* the remaining are set to zero which have no-effect */
- reg_buf[1] = 0;
- reg_buf[2] = 0;
- reg_buf[3] = 0;
-
- status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
- reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
-
- if (status)
- WARN_ON(1);
-
- return status;
-}
-
-/* process pending interrupts synchronously */
-static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
-{
- struct ath6kl_irq_proc_registers *rg;
- int status = 0;
- u8 host_int_status = 0;
- u32 lk_ahd = 0;
- u8 htc_mbox = 1 << HTC_MAILBOX;
- struct ath6kl_vif *vif;
- vif = ath6kl_vif_first(dev->ar);
- ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);
-
- /*
- * NOTE: HIF implementation guarantees that the context of this
- * call allows us to perform SYNCHRONOUS I/O, that is we can block,
- * sleep or call any API that can block or switch thread/task
- * contexts. This is a fully schedulable context.
- */
-#ifdef CONFIG_MACH_PX
- if (vif->sdio_remove == true) {
- *done = true;
- goto out;
- }
-#endif
- /*
- * Process pending intr only when int_status_en is clear, it may
- * result in unnecessary bus transaction otherwise. Target may be
- * unresponsive at the time.
- */
- if (dev->irq_en_reg.int_status_en) {
- /*
- * Read the first 28 bytes of the HTC register table. This
- * will yield us the value of different int status
- * registers and the lookahead registers.
- *
- * length = sizeof(int_status) + sizeof(cpu_int_status)
- * + sizeof(error_int_status) +
- * sizeof(counter_int_status) +
- * sizeof(mbox_frame) + sizeof(rx_lkahd_valid)
- * + sizeof(hole) + sizeof(rx_lkahd) +
- * sizeof(int_status_en) +
- * sizeof(cpu_int_status_en) +
- * sizeof(err_int_status_en) +
- * sizeof(cntr_int_status_en);
- */
- status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
- (u8 *) &dev->irq_proc_reg,
- sizeof(dev->irq_proc_reg),
- HIF_RD_SYNC_BYTE_INC);
- if (status)
- goto out;
-
- if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
- ath6kl_dump_registers(dev, &dev->irq_proc_reg,
- &dev->irq_en_reg);
-
- /* Update only those registers that are enabled */
- host_int_status = dev->irq_proc_reg.host_int_status &
- dev->irq_en_reg.int_status_en;
-
- /* Look at mbox status */
- if (host_int_status & htc_mbox) {
- /*
- * Mask out pending mbox value, we use "lookAhead as
- * the real flag for mbox processing.
- */
- host_int_status &= ~htc_mbox;
- if (dev->irq_proc_reg.rx_lkahd_valid &
- htc_mbox) {
- rg = &dev->irq_proc_reg;
- lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
-
- if (vif->force_reload == true) {
- lk_ahd = 0;
- }
- if (!lk_ahd) {
- ath6kl_err("lookAhead is zero! force_reload = %d\n", vif->force_reload);
-#ifdef CONFIG_MACH_PX
- cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
- ath6kl_hif_rx_control(dev, false);
- ssleep(3);
- status = -ENOMEM;
-#endif
- }
- }
- }
- }
-
- if (!host_int_status && !lk_ahd) {
- *done = true;
- goto out;
- }
-
- if (lk_ahd) {
- int fetched = 0;
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "pending mailbox msg, lk_ahd: 0x%X\n", lk_ahd);
- /*
- * Mailbox Interrupt, the HTC layer may issue async
- * requests to empty the mailbox. When emptying the recv
- * mailbox we use the async handler above called from the
- * completion routine of the callers read request. This can
- * improve performance by reducing context switching when
- * we rapidly pull packets.
- */
- status = ath6kl_htc_rxmsg_pending_handler(dev->htc_cnxt,
- lk_ahd, &fetched);
-#ifdef CONFIG_MACH_PX
- if (status && status != -ECANCELED) {
- cfg80211_priv_event(vif->ndev, "HANG", GFP_ATOMIC);
- ath6kl_hif_rx_control(dev, false);
- ssleep(3);
- goto out;
- }
-#else
- if (status)
- goto out;
-#endif
- if (!fetched)
- /*
- * HTC could not pull any messages out due to lack
- * of resources.
- */
- dev->htc_cnxt->chk_irq_status_cnt = 0;
- }
-
- /* now handle the rest of them */
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "valid interrupt source(s) for other interrupts: 0x%x\n",
- host_int_status);
-
- if (MS(HOST_INT_STATUS_CPU, host_int_status)) {
- /* CPU Interrupt */
- status = ath6kl_hif_proc_cpu_intr(dev);
- if (status)
- goto out;
- }
-
- if (MS(HOST_INT_STATUS_ERROR, host_int_status)) {
- /* Error Interrupt */
- status = ath6kl_hif_proc_err_intr(dev);
- if (status)
- goto out;
- }
-
- if (MS(HOST_INT_STATUS_COUNTER, host_int_status))
- /* Counter Interrupt */
- status = ath6kl_hif_proc_counter_intr(dev);
-
-out:
- /*
- * An optimization to bypass reading the IRQ status registers
- * unecessarily which can re-wake the target, if upper layers
- * determine that we are in a low-throughput mode, we can rely on
- * taking another interrupt rather than re-checking the status
- * registers which can re-wake the target.
- *
- * NOTE : for host interfaces that makes use of detecting pending
- * mbox messages at hif can not use this optimization due to
- * possible side effects, SPI requires the host to drain all
- * messages from the mailbox before exiting the ISR routine.
- */
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "bypassing irq status re-check, forcing done\n");
-
- if (!dev->htc_cnxt->chk_irq_status_cnt)
- *done = true;
-
- ath6kl_dbg(ATH6KL_DBG_IRQ,
- "proc_pending_irqs: (done:%d, status=%d\n", *done, status);
-
- return status;
-}
-
-/* interrupt handler, kicks off all interrupt processing */
-int ath6kl_hif_intr_bh_handler(struct ath6kl *ar)
-{
-#ifdef CONFIG_MACH_PX
- struct ath6kl_device *dev;
- unsigned long timeout;
- int status = 0;
- bool done = false;
-
- if ((ar != NULL) && (ar->htc_target != NULL) && (ar->htc_target->dev != NULL))
- dev = ar->htc_target->dev;
- else
- return status;
-#else
- struct ath6kl_device *dev = ar->htc_target->dev;
- unsigned long timeout;
- int status = 0;
- bool done = false;
-#endif
-
- /*
- * Reset counter used to flag a re-scan of IRQ status registers on
- * the target.
- */
- dev->htc_cnxt->chk_irq_status_cnt = 0;
-
- /*
- * IRQ processing is synchronous, interrupt status registers can be
- * re-read.
- */
- timeout = jiffies + msecs_to_jiffies(ATH6KL_HIF_COMMUNICATION_TIMEOUT);
-#ifdef CONFIG_MACH_PX
- while (time_before(jiffies, timeout) && !done && (dev != NULL))
-#else
- while (time_before(jiffies, timeout) && !done)
-#endif
- {
- status = proc_pending_irqs(dev, &done);
- if (status)
- break;
- }
-
- return status;
-}
-
-static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev)
-{
- struct ath6kl_irq_enable_reg regs;
- int status;
-
- spin_lock_bh(&dev->lock);
-
- /* Enable all but ATH6KL CPU interrupts */
- dev->irq_en_reg.int_status_en =
- SM(INT_STATUS_ENABLE_ERROR, 0x01) |
- SM(INT_STATUS_ENABLE_CPU, 0x01) |
- SM(INT_STATUS_ENABLE_COUNTER, 0x01);
-
- /*
- * NOTE: There are some cases where HIF can do detection of
- * pending mbox messages which is disabled now.
- */
- dev->irq_en_reg.int_status_en |= SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
-
- /* Set up the CPU Interrupt status Register */
- dev->irq_en_reg.cpu_int_status_en = 0;
-
- /* Set up the Error Interrupt status Register */
- dev->irq_en_reg.err_int_status_en =
- SM(ERROR_STATUS_ENABLE_RX_UNDERFLOW, 0x01) |
- SM(ERROR_STATUS_ENABLE_TX_OVERFLOW, 0x1);
-
- /*
- * Enable Counter interrupt status register to get fatal errors for
- * debugging.
- */
- dev->irq_en_reg.cntr_int_status_en = SM(COUNTER_INT_STATUS_ENABLE_BIT,
- ATH6KL_TARGET_DEBUG_INTR_MASK);
- memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
-
- spin_unlock_bh(&dev->lock);
-
- status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
- &regs.int_status_en, sizeof(regs),
- HIF_WR_SYNC_BYTE_INC);
-
- if (status)
- ath6kl_err("failed to update interrupt ctl reg err: %d\n",
- status);
-
- return status;
-}
-
-int ath6kl_hif_disable_intrs(struct ath6kl_device *dev)
-{
- struct ath6kl_irq_enable_reg regs;
-
- spin_lock_bh(&dev->lock);
- /* Disable all interrupts */
- dev->irq_en_reg.int_status_en = 0;
- dev->irq_en_reg.cpu_int_status_en = 0;
- dev->irq_en_reg.err_int_status_en = 0;
- dev->irq_en_reg.cntr_int_status_en = 0;
- memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
- spin_unlock_bh(&dev->lock);
-
- return hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
- &regs.int_status_en, sizeof(regs),
- HIF_WR_SYNC_BYTE_INC);
-}
-
-/* enable device interrupts */
-int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev)
-{
- int status = 0;
-
- /*
- * Make sure interrupt are disabled before unmasking at the HIF
- * layer. The rationale here is that between device insertion
- * (where we clear the interrupts the first time) and when HTC
- * is finally ready to handle interrupts, other software can perform
- * target "soft" resets. The ATH6KL interrupt enables reset back to an
- * "enabled" state when this happens.
- */
- ath6kl_hif_disable_intrs(dev);
-
- /* unmask the host controller interrupts */
- ath6kl_hif_irq_enable(dev->ar);
- status = ath6kl_hif_enable_intrs(dev);
-
- return status;
-}
-
-/* disable all device interrupts */
-int ath6kl_hif_mask_intrs(struct ath6kl_device *dev)
-{
- /*
- * Mask the interrupt at the HIF layer to avoid any stray interrupt
- * taken while we zero out our shadow registers in
- * ath6kl_hif_disable_intrs().
- */
- ath6kl_hif_irq_disable(dev->ar);
-
- return ath6kl_hif_disable_intrs(dev);
-}
-
-int ath6kl_hif_setup(struct ath6kl_device *dev)
-{
- int status = 0;
-
- spin_lock_init(&dev->lock);
-
- /*
- * NOTE: we actually get the block size of a mailbox other than 0,
- * for SDIO the block size on mailbox 0 is artificially set to 1.
- * So we use the block size that is set for the other 3 mailboxes.
- */
- dev->htc_cnxt->block_sz = dev->ar->mbox_info.block_size;
-
- /* must be a power of 2 */
- if ((dev->htc_cnxt->block_sz & (dev->htc_cnxt->block_sz - 1)) != 0) {
- WARN_ON(1);
- status = -EINVAL;
- goto fail_setup;
- }
-
- /* assemble mask, used for padding to a block */
- dev->htc_cnxt->block_mask = dev->htc_cnxt->block_sz - 1;
-
- ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",
- dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);
-
- /* usb doesn't support enabling interrupts */
- /* FIXME: remove check once USB support is implemented */
- if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)
- return 0;
-
- status = ath6kl_hif_disable_intrs(dev);
-
-fail_setup:
- return status;
-
-}
-
-int ath6kl_hif_wait_for_pending_recv(struct ath6kl *ar)
-{
- int loop_cnt = 5;
- u8 host_int_status;
- int status = 0;
-
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
-
- do {
- int irq_cnt = 10;
- while (atomic_read(&ar_sdio->irq_handling) && --irq_cnt > 0) {
- /* wait until irq handler finished all the jobs */
- schedule_timeout_interruptible(HZ / 10);
- }
- /* check if there is any pending irq due to force done */
- host_int_status = 0;
- status = hif_read_write_sync(ar, HOST_INT_STATUS_ADDRESS,
- (u8 *)&host_int_status, sizeof(host_int_status),
- HIF_RD_SYNC_BYTE_INC);
- /* force it to query again due to resources issue*/
- if (status)
- host_int_status = 1;
- else
- host_int_status = (host_int_status & (1 << 0));
-
- if (host_int_status) {
- /* Wait until irq handler finishes its job */
- schedule_timeout_interruptible(1);
- }
- } while (host_int_status && --loop_cnt > 0);
-
- if (host_int_status || loop_cnt == 0) {
- ath6kl_err("%s(), Unable clear up pending IRQ"
- "before the system suspended\n", __func__);
- return -1;
- }
-
- return 0;
-}
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
deleted file mode 100755
index 92ec268..0000000
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef HIF_H
-#define HIF_H
-
-#include "common.h"
-#include "core.h"
-
-#include <linux/scatterlist.h>
-
-#define BUS_REQUEST_MAX_NUM 64
-#define HIF_MBOX_BLOCK_SIZE 128
-#define HIF_MBOX0_BLOCK_SIZE 1
-
-#define HIF_DMA_BUFFER_SIZE (32 * 1024)
-#define CMD53_FIXED_ADDRESS 1
-#define CMD53_INCR_ADDRESS 2
-
-#define MAX_SCATTER_REQUESTS 4
-#define MAX_SCATTER_ENTRIES_PER_REQ 16
-#define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024)
-
-#define MANUFACTURER_ID_AR6003_BASE 0x300
-#define MANUFACTURER_ID_AR6004_BASE 0x400
- /* SDIO manufacturer ID and Codes */
-#define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00
-#define MANUFACTURER_CODE 0x271 /* Atheros */
-
-/* Mailbox address in SDIO address space */
-#define HIF_MBOX_BASE_ADDR 0x800
-#define HIF_MBOX_WIDTH 0x800
-
-#define HIF_MBOX_END_ADDR (HTC_MAILBOX_NUM_MAX * HIF_MBOX_WIDTH - 1)
-
-/* version 1 of the chip has only a 12K extended mbox range */
-#define HIF_MBOX0_EXT_BASE_ADDR 0x4000
-#define HIF_MBOX0_EXT_WIDTH (12*1024)
-
-/* GMBOX addresses */
-#define HIF_GMBOX_BASE_ADDR 0x7000
-#define HIF_GMBOX_WIDTH 0x4000
-
-/* interrupt mode register */
-#define CCCR_SDIO_IRQ_MODE_REG 0xF0
-
-/* mode to enable special 4-bit interrupt assertion without clock */
-#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0)
-
-/* HTC runs over mailbox 0 */
-#define HTC_MAILBOX 0
-
-#define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01
-
-/* FIXME: are these duplicates with MAX_SCATTER_ values in hif.h? */
-#define ATH6KL_SCATTER_ENTRIES_PER_REQ 16
-#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024)
-#define ATH6KL_SCATTER_REQS 4
-
-#define ATH6KL_HIF_COMMUNICATION_TIMEOUT 1000
-
-struct bus_request {
- struct list_head list;
-
- /* request data */
- u32 address;
-
- u8 *buffer;
- u32 length;
- u32 request;
- struct htc_packet *packet;
- int status;
-
- /* this is a scatter request */
- struct hif_scatter_req *scat_req;
-};
-
-/* direction of transfer (read/write) */
-#define HIF_READ 0x00000001
-#define HIF_WRITE 0x00000002
-#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
-
-/*
- * emode - This indicates the whether the command is to be executed in a
- * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
- * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
- * implemented using the asynchronous mode allowing the the bus
- * driver to indicate the completion of operation through the
- * registered callback routine. The requirement primarily comes
- * from the contexts these operations get called from (a driver's
- * transmit context or the ISR context in case of receive).
- * Support for both of these modes is essential.
- */
-#define HIF_SYNCHRONOUS 0x00000010
-#define HIF_ASYNCHRONOUS 0x00000020
-#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
-
-/*
- * dmode - An interface may support different kinds of commands based on
- * the tradeoff between the amount of data it can carry and the
- * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
- * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
- * to the nearest block size by padding. The size of the block is
- * configurable at compile time using the HIF_BLOCK_SIZE and is
- * negotiated with the target during initialization after the
- * ATH6KL interrupts are enabled.
- */
-#define HIF_BYTE_BASIS 0x00000040
-#define HIF_BLOCK_BASIS 0x00000080
-#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
-
-/*
- * amode - This indicates if the address has to be incremented on ATH6KL
- * after every read/write operation (HIF?FIXED_ADDRESS/
- * HIF_INCREMENTAL_ADDRESS).
- */
-#define HIF_FIXED_ADDRESS 0x00000100
-#define HIF_INCREMENTAL_ADDRESS 0x00000200
-#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_WR_ASYNC_BYTE_INC \
- (HIF_WRITE | HIF_ASYNCHRONOUS | \
- HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_WR_ASYNC_BLOCK_INC \
- (HIF_WRITE | HIF_ASYNCHRONOUS | \
- HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_WR_SYNC_BYTE_FIX \
- (HIF_WRITE | HIF_SYNCHRONOUS | \
- HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-
-#define HIF_WR_SYNC_BYTE_INC \
- (HIF_WRITE | HIF_SYNCHRONOUS | \
- HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_WR_SYNC_BLOCK_INC \
- (HIF_WRITE | HIF_SYNCHRONOUS | \
- HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_RD_SYNC_BYTE_INC \
- (HIF_READ | HIF_SYNCHRONOUS | \
- HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
-
-#define HIF_RD_SYNC_BYTE_FIX \
- (HIF_READ | HIF_SYNCHRONOUS | \
- HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
-
-#define HIF_RD_ASYNC_BLOCK_FIX \
- (HIF_READ | HIF_ASYNCHRONOUS | \
- HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-
-#define HIF_RD_SYNC_BLOCK_FIX \
- (HIF_READ | HIF_SYNCHRONOUS | \
- HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
-
-struct hif_scatter_item {
- u8 *buf;
- int len;
- struct htc_packet *packet;
-};
-
-struct hif_scatter_req {
- struct list_head list;
- /* address for the read/write operation */
- u32 addr;
-
- /* request flags */
- u32 req;
-
- /* total length of entire transfer */
- u32 len;
-
- bool virt_scat;
-
- void (*complete) (struct htc_target *, struct hif_scatter_req *);
- int status;
- int scat_entries;
-
- struct bus_request *busrequest;
- struct scatterlist *sgentries;
-
- /* bounce buffer for upper layers to copy to/from */
- u8 *virt_dma_buf;
-
- struct hif_scatter_item scat_list[1];
-
- u32 scat_q_depth;
-};
-
-struct ath6kl_irq_proc_registers {
- u8 host_int_status;
- u8 cpu_int_status;
- u8 error_int_status;
- u8 counter_int_status;
- u8 mbox_frame;
- u8 rx_lkahd_valid;
- u8 host_int_status2;
- u8 gmbox_rx_avail;
- __le32 rx_lkahd[2];
- __le32 rx_gmbox_lkahd_alias[2];
-} __packed;
-
-struct ath6kl_irq_enable_reg {
- u8 int_status_en;
- u8 cpu_int_status_en;
- u8 err_int_status_en;
- u8 cntr_int_status_en;
-} __packed;
-
-struct ath6kl_device {
- spinlock_t lock;
- struct ath6kl_irq_proc_registers irq_proc_reg;
- struct ath6kl_irq_enable_reg irq_en_reg;
- struct htc_target *htc_cnxt;
- struct ath6kl *ar;
-};
-
-struct ath6kl_sdio {
- struct sdio_func *func;
-
- spinlock_t lock;
-
- /* free list */
- struct list_head bus_req_freeq;
-
- /* available bus requests */
- struct bus_request bus_req[BUS_REQUEST_MAX_NUM];
-
- struct ath6kl *ar;
-
- u8 *dma_buffer;
-
- /* protects access to dma_buffer */
- struct mutex dma_buffer_mutex;
-
- /* scatter request list head */
- struct list_head scat_req;
-
- atomic_t irq_handling;
- wait_queue_head_t irq_wq;
-
- spinlock_t scat_lock;
- bool scatter_enabled;
-
- bool is_disabled;
- const struct sdio_device_id *id;
- struct work_struct wr_async_work;
- struct list_head wr_asyncq;
- spinlock_t wr_async_lock;
-};
-
-static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar)
-{
- return ar->hif_priv;
-}
-
-struct ath6kl_hif_ops {
- int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf,
- u32 len, u32 request);
- int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer,
- u32 length, u32 request, struct htc_packet *packet);
-
- void (*irq_enable)(struct ath6kl *ar);
- void (*irq_disable)(struct ath6kl *ar);
-
- struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar);
- void (*scatter_req_add)(struct ath6kl *ar,
- struct hif_scatter_req *s_req);
- int (*enable_scatter)(struct ath6kl *ar);
- int (*scat_req_rw) (struct ath6kl *ar,
- struct hif_scatter_req *scat_req);
- void (*cleanup_scatter)(struct ath6kl *ar);
- int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow);
- int (*resume)(struct ath6kl *ar);
- int (*diag_read32)(struct ath6kl *ar, u32 address, u32 *value);
- int (*diag_write32)(struct ath6kl *ar, u32 address, __le32 value);
- int (*bmi_read)(struct ath6kl *ar, u8 *buf, u32 len);
- int (*bmi_write)(struct ath6kl *ar, u8 *buf, u32 len);
- int (*power_on)(struct ath6kl *ar);
- int (*power_off)(struct ath6kl *ar);
- void (*stop)(struct ath6kl *ar);
-};
-
-int ath6kl_hif_setup(struct ath6kl_device *dev);
-int ath6kl_hif_unmask_intrs(struct ath6kl_device *dev);
-int ath6kl_hif_mask_intrs(struct ath6kl_device *dev);
-int ath6kl_hif_poll_mboxmsg_rx(struct ath6kl_device *dev,
- u32 *lk_ahd, int timeout);
-int ath6kl_hif_rx_control(struct ath6kl_device *dev, bool enable_rx);
-int ath6kl_hif_disable_intrs(struct ath6kl_device *dev);
-
-int ath6kl_hif_rw_comp_handler(void *context, int status);
-int ath6kl_hif_intr_bh_handler(struct ath6kl *ar);
-
-/* Scatter Function and Definitions */
-int ath6kl_hif_submit_scat_req(struct ath6kl_device *dev,
- struct hif_scatter_req *scat_req, bool read);
-
-int ath6kl_hif_wait_for_pending_recv(struct ath6kl *ar);
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
deleted file mode 100755
index 16729fb..0000000
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ /dev/null
@@ -1,2888 +0,0 @@
-/*
- * Copyright (c) 2007-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "hif.h"
-#include "debug.h"
-#include "hif-ops.h"
-#include <asm/unaligned.h>
-
-#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
-
-/* threshold to re-enable Tx bundling for an AC*/
-#define TX_RESUME_BUNDLE_THRESHOLD 1500
-
-/* Functions for Tx credit handling */
-static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist,
- int credits)
-{
- ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit deposit ep %d credits %d\n",
- ep_dist->endpoint, credits);
-
- ep_dist->credits += credits;
- ep_dist->cred_assngd += credits;
- cred_info->cur_free_credits -= credits;
-}
-
-static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *ep_list,
- int tot_credits)
-{
- struct htc_endpoint_credit_dist *cur_ep_dist;
- int count;
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit init total %d\n", tot_credits);
-
- cred_info->cur_free_credits = tot_credits;
- cred_info->total_avail_credits = tot_credits;
-
- list_for_each_entry(cur_ep_dist, ep_list, list) {
- if (cur_ep_dist->endpoint == ENDPOINT_0)
- continue;
-
- cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
-
- if (tot_credits > 4) {
- if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
- (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
- ath6kl_credit_deposit(cred_info,
- cur_ep_dist,
- cur_ep_dist->cred_min);
- cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
- }
- }
-
- if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
- ath6kl_credit_deposit(cred_info, cur_ep_dist,
- cur_ep_dist->cred_min);
- /*
- * Control service is always marked active, it
- * never goes inactive EVER.
- */
- cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
- } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
- /* this is the lowest priority data endpoint */
- /* FIXME: this looks fishy, check */
- cred_info->lowestpri_ep_dist = cur_ep_dist->list;
-
- /*
- * Streams have to be created (explicit | implicit) for all
- * kinds of traffic. BE endpoints are also inactive in the
- * beginning. When BE traffic starts it creates implicit
- * streams that redistributes credits.
- *
- * Note: all other endpoints have minimums set but are
- * initially given NO credits. credits will be distributed
- * as traffic activity demands
- */
- }
-
- WARN_ON(cred_info->cur_free_credits <= 0);
-
- list_for_each_entry(cur_ep_dist, ep_list, list) {
- if (cur_ep_dist->endpoint == ENDPOINT_0)
- continue;
-
- if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
- cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
- else {
- /*
- * For the remaining data endpoints, we assume that
- * each cred_per_msg are the same. We use a simple
- * calculation here, we take the remaining credits
- * and determine how many max messages this can
- * cover and then set each endpoint's normal value
- * equal to 3/4 this amount.
- */
- count = (cred_info->cur_free_credits /
- cur_ep_dist->cred_per_msg)
- * cur_ep_dist->cred_per_msg;
- count = (count * 3) >> 2;
- count = max(count, cur_ep_dist->cred_per_msg);
- cur_ep_dist->cred_norm = count;
-
- }
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "credit ep %d svc_id %d credits %d per_msg %d norm %d min %d\n",
- cur_ep_dist->endpoint,
- cur_ep_dist->svc_id,
- cur_ep_dist->credits,
- cur_ep_dist->cred_per_msg,
- cur_ep_dist->cred_norm,
- cur_ep_dist->cred_min);
- }
-}
-
-/* initialize and setup credit distribution */
-int ath6kl_credit_setup(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info)
-{
- u16 servicepriority[5];
-
- memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info));
-
- servicepriority[0] = WMI_CONTROL_SVC; /* highest */
- servicepriority[1] = WMI_DATA_VO_SVC;
- servicepriority[2] = WMI_DATA_VI_SVC;
- servicepriority[3] = WMI_DATA_BE_SVC;
- servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
-
- /* set priority list */
- ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
-
- return 0;
-}
-
-/* reduce an ep's credits back to a set limit */
-static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist,
- int limit)
-{
- int credits;
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit reduce ep %d limit %d\n",
- ep_dist->endpoint, limit);
-
- ep_dist->cred_assngd = limit;
-
- if (ep_dist->credits <= limit)
- return;
-
- credits = ep_dist->credits - limit;
- ep_dist->credits -= credits;
- cred_info->cur_free_credits += credits;
-}
-
-static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *epdist_list)
-{
- struct htc_endpoint_credit_dist *cur_dist_list;
-
- list_for_each_entry(cur_dist_list, epdist_list, list) {
- if (cur_dist_list->endpoint == ENDPOINT_0)
- continue;
-
- if (cur_dist_list->cred_to_dist > 0) {
- cur_dist_list->credits +=
- cur_dist_list->cred_to_dist;
- cur_dist_list->cred_to_dist = 0;
- if (cur_dist_list->credits >
- cur_dist_list->cred_assngd)
- ath6kl_credit_reduce(cred_info,
- cur_dist_list,
- cur_dist_list->cred_assngd);
-
- if (cur_dist_list->credits >
- cur_dist_list->cred_norm)
- ath6kl_credit_reduce(cred_info, cur_dist_list,
- cur_dist_list->cred_norm);
-
- if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
- if (cur_dist_list->txq_depth == 0)
- ath6kl_credit_reduce(cred_info,
- cur_dist_list, 0);
- }
- }
- }
-}
-
-/*
- * HTC has an endpoint that needs credits, ep_dist is the endpoint in
- * question.
- */
-static void ath6kl_credit_seek(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist)
-{
- struct htc_endpoint_credit_dist *curdist_list;
- int credits = 0;
- int need;
-
- if (ep_dist->svc_id == WMI_CONTROL_SVC)
- goto out;
-
- if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
- (ep_dist->svc_id == WMI_DATA_VO_SVC))
- if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
- goto out;
-
- /*
- * For all other services, we follow a simple algorithm of:
- *
- * 1. checking the free pool for credits
- * 2. checking lower priority endpoints for credits to take
- */
-
- credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
-
- if (credits >= ep_dist->seek_cred)
- goto out;
-
- /*
- * We don't have enough in the free pool, try taking away from
- * lower priority services The rule for taking away credits:
- *
- * 1. Only take from lower priority endpoints
- * 2. Only take what is allocated above the minimum (never
- * starve an endpoint completely)
- * 3. Only take what you need.
- */
-
- list_for_each_entry_reverse(curdist_list,
- &cred_info->lowestpri_ep_dist,
- list) {
- if (curdist_list == ep_dist)
- break;
-
- need = ep_dist->seek_cred - cred_info->cur_free_credits;
-
- if ((curdist_list->cred_assngd - need) >=
- curdist_list->cred_min) {
- /*
- * The current one has been allocated more than
- * it's minimum and it has enough credits assigned
- * above it's minimum to fulfill our need try to
- * take away just enough to fulfill our need.
- */
- ath6kl_credit_reduce(cred_info, curdist_list,
- curdist_list->cred_assngd - need);
-
- if (cred_info->cur_free_credits >=
- ep_dist->seek_cred)
- break;
- }
-
- if (curdist_list->endpoint == ENDPOINT_0)
- break;
- }
-
- credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
-
-out:
- /* did we find some credits? */
- if (credits)
- ath6kl_credit_deposit(cred_info, ep_dist, credits);
-
- ep_dist->seek_cred = 0;
-}
-
-/* redistribute credits based on activity change */
-static void ath6kl_credit_redistribute(struct ath6kl_htc_credit_info *info,
- struct list_head *ep_dist_list)
-{
- struct htc_endpoint_credit_dist *curdist_list;
-
- list_for_each_entry(curdist_list, ep_dist_list, list) {
- if (curdist_list->endpoint == ENDPOINT_0)
- continue;
-
- if ((curdist_list->svc_id == WMI_DATA_BK_SVC) ||
- (curdist_list->svc_id == WMI_DATA_BE_SVC))
- curdist_list->dist_flags |= HTC_EP_ACTIVE;
-
- if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
- !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
- if (curdist_list->txq_depth == 0)
- ath6kl_credit_reduce(info, curdist_list, 0);
- else
- ath6kl_credit_reduce(info,
- curdist_list,
- curdist_list->cred_min);
- }
- }
-}
-
-/*
- *
- * This function is invoked whenever endpoints require credit
- * distributions. A lock is held while this function is invoked, this
- * function shall NOT block. The ep_dist_list is a list of distribution
- * structures in prioritized order as defined by the call to the
- * htc_set_credit_dist() api.
- */
-static void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *ep_dist_list,
- enum htc_credit_dist_reason reason)
-{
- switch (reason) {
- case HTC_CREDIT_DIST_SEND_COMPLETE:
- ath6kl_credit_update(cred_info, ep_dist_list);
- break;
- case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
- ath6kl_credit_redistribute(cred_info, ep_dist_list);
- break;
- default:
- break;
- }
-
- WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
- WARN_ON(cred_info->cur_free_credits < 0);
-}
-
-static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len)
-{
- u8 *align_addr;
-
- if (!IS_ALIGNED((unsigned long) *buf, 4)) {
- align_addr = PTR_ALIGN(*buf - 4, 4);
- memmove(align_addr, *buf, len);
- *buf = align_addr;
- }
-}
-
-static void ath6kl_htc_tx_prep_pkt(struct htc_packet *packet, u8 flags,
- int ctrl0, int ctrl1)
-{
- struct htc_frame_hdr *hdr;
-
- packet->buf -= HTC_HDR_LENGTH;
- hdr = (struct htc_frame_hdr *)packet->buf;
-
- /* Endianess? */
- put_unaligned((u16)packet->act_len, &hdr->payld_len);
- hdr->flags = flags;
- hdr->eid = packet->endpoint;
- hdr->ctrl[0] = ctrl0;
- hdr->ctrl[1] = ctrl1;
-}
-
-static void htc_reclaim_txctrl_buf(struct htc_target *target,
- struct htc_packet *pkt)
-{
- spin_lock_bh(&target->htc_lock);
- list_add_tail(&pkt->list, &target->free_ctrl_txbuf);
- spin_unlock_bh(&target->htc_lock);
-}
-
-static struct htc_packet *htc_get_control_buf(struct htc_target *target,
- bool tx)
-{
- struct htc_packet *packet = NULL;
- struct list_head *buf_list;
-
- buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf;
-
- spin_lock_bh(&target->htc_lock);
-
- if (list_empty(buf_list)) {
- spin_unlock_bh(&target->htc_lock);
- return NULL;
- }
-
- packet = list_first_entry(buf_list, struct htc_packet, list);
- list_del(&packet->list);
- spin_unlock_bh(&target->htc_lock);
-
- if (tx)
- packet->buf = packet->buf_start + HTC_HDR_LENGTH;
-
- return packet;
-}
-
-static void htc_tx_comp_update(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct htc_packet *packet)
-{
- packet->completion = NULL;
- packet->buf += HTC_HDR_LENGTH;
-
- if (!packet->status)
- return;
-
- ath6kl_err("req failed (status:%d, ep:%d, len:%d creds:%d)\n",
- packet->status, packet->endpoint, packet->act_len,
- packet->info.tx.cred_used);
-
- /* on failure to submit, reclaim credits for this packet */
- spin_lock_bh(&target->tx_lock);
- endpoint->cred_dist.cred_to_dist +=
- packet->info.tx.cred_used;
- endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);
-
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx ctxt 0x%p dist 0x%p\n",
- target->credit_info, &target->cred_dist_list);
-
- ath6kl_credit_distribute(target->credit_info,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_SEND_COMPLETE);
-
- spin_unlock_bh(&target->tx_lock);
-}
-
-static void htc_tx_complete(struct htc_endpoint *endpoint,
- struct list_head *txq)
-{
- if (list_empty(txq))
- return;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx complete ep %d pkts %d\n",
- endpoint->eid, get_queue_depth(txq));
-
- ath6kl_tx_complete(endpoint->target->dev->ar, txq);
-}
-
-static void htc_tx_comp_handler(struct htc_target *target,
- struct htc_packet *packet)
-{
- struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint];
- struct list_head container;
-
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx complete seqno %d\n",
- packet->info.tx.seqno);
-
- htc_tx_comp_update(target, endpoint, packet);
- INIT_LIST_HEAD(&container);
- list_add_tail(&packet->list, &container);
- /* do completion */
- htc_tx_complete(endpoint, &container);
-}
-
-static void htc_async_tx_scat_complete(struct htc_target *target,
- struct hif_scatter_req *scat_req)
-{
- struct htc_endpoint *endpoint;
- struct htc_packet *packet;
- struct list_head tx_compq;
- int i;
-
- INIT_LIST_HEAD(&tx_compq);
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx scat complete len %d entries %d\n",
- scat_req->len, scat_req->scat_entries);
-
- if (scat_req->status)
- ath6kl_err("send scatter req failed: %d\n", scat_req->status);
-
- packet = scat_req->scat_list[0].packet;
- endpoint = &target->endpoint[packet->endpoint];
-
- /* walk through the scatter list and process */
- for (i = 0; i < scat_req->scat_entries; i++) {
- packet = scat_req->scat_list[i].packet;
- if (!packet) {
- WARN_ON(1);
- return;
- }
-
- packet->status = scat_req->status;
- htc_tx_comp_update(target, endpoint, packet);
- list_add_tail(&packet->list, &tx_compq);
- }
-
- /* free scatter request */
- hif_scatter_req_add(target->dev->ar, scat_req);
-
- /* complete all packets */
- htc_tx_complete(endpoint, &tx_compq);
-}
-
-static int ath6kl_htc_tx_issue(struct htc_target *target,
- struct htc_packet *packet)
-{
- int status;
- bool sync = false;
- u32 padded_len, send_len;
-
- if (!packet->completion)
- sync = true;
-
- send_len = packet->act_len + HTC_HDR_LENGTH;
-
- padded_len = CALC_TXRX_PADDED_LEN(target, send_len);
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx issue len %d seqno %d padded_len %d mbox 0x%X %s\n",
- send_len, packet->info.tx.seqno, padded_len,
- target->dev->ar->mbox_info.htc_addr,
- sync ? "sync" : "async");
-
- if (sync) {
- status = hif_read_write_sync(target->dev->ar,
- target->dev->ar->mbox_info.htc_addr,
- packet->buf, padded_len,
- HIF_WR_SYNC_BLOCK_INC);
-
- packet->status = status;
- packet->buf += HTC_HDR_LENGTH;
- } else
- status = hif_write_async(target->dev->ar,
- target->dev->ar->mbox_info.htc_addr,
- packet->buf, padded_len,
- HIF_WR_ASYNC_BLOCK_INC, packet);
-
- return status;
-}
-
-static int htc_check_credits(struct htc_target *target,
- struct htc_endpoint *ep, u8 *flags,
- enum htc_endpoint_id eid, unsigned int len,
- int *req_cred)
-{
-
- *req_cred = (len > target->tgt_cred_sz) ?
- DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit check need %d got %d\n",
- *req_cred, ep->cred_dist.credits);
-
- if (ep->cred_dist.credits < *req_cred) {
- if (eid == ENDPOINT_0)
- return -EINVAL;
-
- /* Seek more credits */
- ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
-
- ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
-
- ep->cred_dist.seek_cred = 0;
-
- if (ep->cred_dist.credits < *req_cred) {
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "credit not found for ep %d\n",
- eid);
- return -EINVAL;
- }
- }
-
- ep->cred_dist.credits -= *req_cred;
- ep->ep_st.cred_cosumd += *req_cred;
-
- /* When we are getting low on credits, ask for more */
- if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
- ep->cred_dist.seek_cred =
- ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
-
- ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
-
- /* see if we were successful in getting more */
- if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
- /* tell the target we need credits ASAP! */
- *flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
- ep->ep_st.cred_low_indicate += 1;
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "credit we need credits asap\n");
- }
- }
-
- return 0;
-}
-
-static void ath6kl_htc_tx_pkts_get(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct list_head *queue)
-{
- int req_cred;
- u8 flags;
- struct htc_packet *packet;
- unsigned int len;
-
- while (true) {
-
- flags = 0;
-
- if (list_empty(&endpoint->txq))
- break;
- packet = list_first_entry(&endpoint->txq, struct htc_packet,
- list);
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx got packet 0x%p queue depth %d\n",
- packet, get_queue_depth(&endpoint->txq));
-
- len = CALC_TXRX_PADDED_LEN(target,
- packet->act_len + HTC_HDR_LENGTH);
-
- if (htc_check_credits(target, endpoint, &flags,
- packet->endpoint, len, &req_cred))
- break;
-
- /* now we can fully move onto caller's queue */
- packet = list_first_entry(&endpoint->txq, struct htc_packet,
- list);
- list_move_tail(&packet->list, queue);
-
- /* save the number of credits this packet consumed */
- packet->info.tx.cred_used = req_cred;
-
- /* all TX packets are handled asynchronously */
- packet->completion = htc_tx_comp_handler;
- packet->context = target;
- endpoint->ep_st.tx_issued += 1;
-
- /* save send flags */
- packet->info.tx.flags = flags;
- packet->info.tx.seqno = endpoint->seqno;
- endpoint->seqno++;
- }
-}
-
-/* See if the padded tx length falls on a credit boundary */
-static int htc_get_credit_padding(unsigned int cred_sz, int *len,
- struct htc_endpoint *ep)
-{
- int rem_cred, cred_pad;
-
- rem_cred = *len % cred_sz;
-
- /* No padding needed */
- if (!rem_cred)
- return 0;
-
- if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN))
- return -1;
-
- /*
- * The transfer consumes a "partial" credit, this
- * packet cannot be bundled unless we add
- * additional "dummy" padding (max 255 bytes) to
- * consume the entire credit.
- */
- cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;
-
- if ((cred_pad > 0) && (cred_pad <= 255))
- *len += cred_pad;
- else
- /* The amount of padding is too large, send as non-bundled */
- return -1;
-
- return cred_pad;
-}
-
-static int ath6kl_htc_tx_setup_scat_list(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct hif_scatter_req *scat_req,
- int n_scat,
- struct list_head *queue)
-{
- struct htc_packet *packet;
- int i, len, rem_scat, cred_pad;
- int status = 0;
-
- rem_scat = target->max_tx_bndl_sz;
-
- for (i = 0; i < n_scat; i++) {
- scat_req->scat_list[i].packet = NULL;
-
- if (list_empty(queue))
- break;
-
- packet = list_first_entry(queue, struct htc_packet, list);
- len = CALC_TXRX_PADDED_LEN(target,
- packet->act_len + HTC_HDR_LENGTH);
-
- cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
- &len, endpoint);
- if (cred_pad < 0 || rem_scat < len) {
- status = -ENOSPC;
- break;
- }
-
- rem_scat -= len;
- /* now remove it from the queue */
- list_del(&packet->list);
-
- scat_req->scat_list[i].packet = packet;
- /* prepare packet and flag message as part of a send bundle */
- ath6kl_htc_tx_prep_pkt(packet,
- packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
- cred_pad, packet->info.tx.seqno);
- /* Make sure the buffer is 4-byte aligned */
- ath6kl_htc_tx_buf_align(&packet->buf,
- packet->act_len + HTC_HDR_LENGTH);
- scat_req->scat_list[i].buf = packet->buf;
- scat_req->scat_list[i].len = len;
-
- scat_req->len += len;
- scat_req->scat_entries++;
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx adding (%d) pkt 0x%p seqno %d len %d remaining %d\n",
- i, packet, packet->info.tx.seqno, len, rem_scat);
- }
-
- /* Roll back scatter setup in case of any failure */
- if (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE) {
- for (i = scat_req->scat_entries - 1; i >= 0; i--) {
- packet = scat_req->scat_list[i].packet;
- if (packet) {
- packet->buf += HTC_HDR_LENGTH;
- list_add(&packet->list, queue);
- }
- }
- return -EAGAIN;
- }
-
- return status;
-}
-
-/*
- * Drain a queue and send as bundles this function may return without fully
- * draining the queue when
- *
- * 1. scatter resources are exhausted
- * 2. a message that will consume a partial credit will stop the
- * bundling process early
- * 3. we drop below the minimum number of messages for a bundle
- */
-static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
- struct list_head *queue,
- int *sent_bundle, int *n_bundle_pkts)
-{
- struct htc_target *target = endpoint->target;
- struct hif_scatter_req *scat_req = NULL;
- int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
- int status;
- u32 txb_mask;
- u8 ac = WMM_NUM_AC;
-
- if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
- (WMI_CONTROL_SVC != endpoint->svc_id))
- ac = target->dev->ar->ep2ac_map[endpoint->eid];
-
- while (true) {
- status = 0;
- n_scat = get_queue_depth(queue);
- n_scat = min(n_scat, target->msg_per_bndl_max);
-
- if (n_scat < HTC_MIN_HTC_MSGS_TO_BUNDLE)
- /* not enough to bundle */
- break;
-
- scat_req = hif_scatter_req_get(target->dev->ar);
-
- if (!scat_req) {
- /* no scatter resources */
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx no more scatter resources\n");
- break;
- }
-
- if ((ac < WMM_NUM_AC) && (ac != WMM_AC_BK)) {
- if (WMM_AC_BE == ac)
- /*
- * BE, BK have priorities and bit
- * positions reversed
- */
- txb_mask = (1 << WMM_AC_BK);
- else
- /*
- * any AC with priority lower than
- * itself
- */
- txb_mask = ((1 << ac) - 1);
- /*
- * when the scatter request resources drop below a
- * certain threshold, disable Tx bundling for all
- * AC's with priority lower than the current requesting
- * AC. Otherwise re-enable Tx bundling for them
- */
- if (scat_req->scat_q_depth < ATH6KL_SCATTER_REQS)
- target->tx_bndl_mask &= ~txb_mask;
- else
- target->tx_bndl_mask |= txb_mask;
- }
-
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx pkts to scatter: %d\n",
- n_scat);
-
- scat_req->len = 0;
- scat_req->scat_entries = 0;
-
- status = ath6kl_htc_tx_setup_scat_list(target, endpoint,
- scat_req, n_scat,
- queue);
- if (status == -EAGAIN) {
- hif_scatter_req_add(target->dev->ar, scat_req);
- break;
- }
-
- /* send path is always asynchronous */
- scat_req->complete = htc_async_tx_scat_complete;
- n_sent_bundle++;
- tot_pkts_bundle += scat_req->scat_entries;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx scatter bytes %d entries %d\n",
- scat_req->len, scat_req->scat_entries);
- ath6kl_hif_submit_scat_req(target->dev, scat_req, false);
-
- if (status)
- break;
- }
-
- *sent_bundle = n_sent_bundle;
- *n_bundle_pkts = tot_pkts_bundle;
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx bundle sent %d pkts\n",
- n_sent_bundle);
-
- return;
-}
-
-static void ath6kl_htc_tx_from_queue(struct htc_target *target,
- struct htc_endpoint *endpoint)
-{
- struct list_head txq;
- struct htc_packet *packet;
- int bundle_sent;
- int n_pkts_bundle;
- u8 ac = WMM_NUM_AC;
-
- spin_lock_bh(&target->tx_lock);
-
- endpoint->tx_proc_cnt++;
- if (endpoint->tx_proc_cnt > 1) {
- endpoint->tx_proc_cnt--;
- spin_unlock_bh(&target->tx_lock);
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx busy\n");
- return;
- }
-
- /*
- * drain the endpoint TX queue for transmission as long
- * as we have enough credits.
- */
- INIT_LIST_HEAD(&txq);
-
- if ((HTC_CTRL_RSVD_SVC != endpoint->svc_id) ||
- (WMI_CONTROL_SVC != endpoint->svc_id))
- ac = target->dev->ar->ep2ac_map[endpoint->eid];
-
- while (true) {
-
- if (list_empty(&endpoint->txq))
- break;
-
- ath6kl_htc_tx_pkts_get(target, endpoint, &txq);
-
- if (list_empty(&txq))
- break;
-
- spin_unlock_bh(&target->tx_lock);
-
- bundle_sent = 0;
- n_pkts_bundle = 0;
-
- while (true) {
- /* try to send a bundle on each pass */
- if ((target->tx_bndl_mask) &&
- (get_queue_depth(&txq) >=
- HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
- int temp1 = 0, temp2 = 0;
-
- /* check if bundling is enabled for an AC */
- if (target->tx_bndl_mask & (1 << ac)) {
- ath6kl_htc_tx_bundle(endpoint, &txq,
- &temp1, &temp2);
- bundle_sent += temp1;
- n_pkts_bundle += temp2;
- }
- }
-
- if (list_empty(&txq))
- break;
-
- packet = list_first_entry(&txq, struct htc_packet,
- list);
- list_del(&packet->list);
-
- ath6kl_htc_tx_prep_pkt(packet, packet->info.tx.flags,
- 0, packet->info.tx.seqno);
- ath6kl_htc_tx_issue(target, packet);
- }
-
- spin_lock_bh(&target->tx_lock);
-
- endpoint->ep_st.tx_bundles += bundle_sent;
- endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
-
- /*
- * if an AC has bundling disabled and no tx bundling
- * has occured continously for a certain number of TX,
- * enable tx bundling for this AC
- */
- if (!bundle_sent) {
- if (!(target->tx_bndl_mask & (1 << ac)) &&
- (ac < WMM_NUM_AC)) {
- if (++target->ac_tx_count[ac] >=
- TX_RESUME_BUNDLE_THRESHOLD) {
- target->ac_tx_count[ac] = 0;
- target->tx_bndl_mask |= (1 << ac);
- }
- }
- } else {
- /* tx bundling will reset the counter */
- if (ac < WMM_NUM_AC)
- target->ac_tx_count[ac] = 0;
- }
- }
-
- endpoint->tx_proc_cnt = 0;
- spin_unlock_bh(&target->tx_lock);
-}
-
-static bool ath6kl_htc_tx_try(struct htc_target *target,
- struct htc_endpoint *endpoint,
- struct htc_packet *tx_pkt)
-{
- struct htc_ep_callbacks ep_cb;
- int txq_depth;
- bool overflow = false;
-
- ep_cb = endpoint->ep_cb;
-
- spin_lock_bh(&target->tx_lock);
- txq_depth = get_queue_depth(&endpoint->txq);
- spin_unlock_bh(&target->tx_lock);
-
- if (txq_depth >= endpoint->max_txq_depth)
- overflow = true;
-
- if (overflow)
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx overflow ep %d depth %d max %d\n",
- endpoint->eid, txq_depth,
- endpoint->max_txq_depth);
-
- if (overflow && ep_cb.tx_full) {
- if (ep_cb.tx_full(endpoint->target, tx_pkt) ==
- HTC_SEND_FULL_DROP) {
- endpoint->ep_st.tx_dropped += 1;
- return false;
- }
- }
-
- spin_lock_bh(&target->tx_lock);
- list_add_tail(&tx_pkt->list, &endpoint->txq);
- spin_unlock_bh(&target->tx_lock);
-
- ath6kl_htc_tx_from_queue(target, endpoint);
-
- return true;
-}
-
-static void htc_chk_ep_txq(struct htc_target *target)
-{
- struct htc_endpoint *endpoint;
- struct htc_endpoint_credit_dist *cred_dist;
-
- /*
- * Run through the credit distribution list to see if there are
- * packets queued. NOTE: no locks need to be taken since the
- * distribution list is not dynamic (cannot be re-ordered) and we
- * are not modifying any state.
- */
- list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
- endpoint = cred_dist->htc_ep;
-
- spin_lock_bh(&target->tx_lock);
- if (!list_empty(&endpoint->txq)) {
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc creds ep %d credits %d pkts %d\n",
- cred_dist->endpoint,
- endpoint->cred_dist.credits,
- get_queue_depth(&endpoint->txq));
- spin_unlock_bh(&target->tx_lock);
- /*
- * Try to start the stalled queue, this list is
- * ordered by priority. If there are credits
- * available the highest priority queue will get a
- * chance to reclaim credits from lower priority
- * ones.
- */
- ath6kl_htc_tx_from_queue(target, endpoint);
- spin_lock_bh(&target->tx_lock);
- }
- spin_unlock_bh(&target->tx_lock);
- }
-}
-
-static int htc_setup_tx_complete(struct htc_target *target)
-{
- struct htc_packet *send_pkt = NULL;
- int status;
-
- send_pkt = htc_get_control_buf(target, true);
-
- if (!send_pkt)
- return -ENOMEM;
-
- if (target->htc_tgt_ver >= HTC_VERSION_2P1) {
- struct htc_setup_comp_ext_msg *setup_comp_ext;
- u32 flags = 0;
-
- setup_comp_ext =
- (struct htc_setup_comp_ext_msg *)send_pkt->buf;
- memset(setup_comp_ext, 0, sizeof(*setup_comp_ext));
- setup_comp_ext->msg_id =
- cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);
-
- if (target->msg_per_bndl_max > 0) {
- /* Indicate HTC bundling to the target */
- flags |= HTC_SETUP_COMP_FLG_RX_BNDL_EN;
- setup_comp_ext->msg_per_rxbndl =
- target->msg_per_bndl_max;
- }
-
- memcpy(&setup_comp_ext->flags, &flags,
- sizeof(setup_comp_ext->flags));
- set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
- sizeof(struct htc_setup_comp_ext_msg),
- ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
-
- } else {
- struct htc_setup_comp_msg *setup_comp;
- setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf;
- memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
- setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
- set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
- sizeof(struct htc_setup_comp_msg),
- ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
- }
-
- /* we want synchronous operation */
- send_pkt->completion = NULL;
- ath6kl_htc_tx_prep_pkt(send_pkt, 0, 0, 0);
- status = ath6kl_htc_tx_issue(target, send_pkt);
-
- if (send_pkt != NULL)
- htc_reclaim_txctrl_buf(target, send_pkt);
-
- return status;
-}
-
-void ath6kl_htc_set_credit_dist(struct htc_target *target,
- struct ath6kl_htc_credit_info *credit_info,
- u16 srvc_pri_order[], int list_len)
-{
- struct htc_endpoint *endpoint;
- int i, ep;
-
- target->credit_info = credit_info;
-
- list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
- &target->cred_dist_list);
-
- for (i = 0; i < list_len; i++) {
- for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
- endpoint = &target->endpoint[ep];
- if (endpoint->svc_id == srvc_pri_order[i]) {
- list_add_tail(&endpoint->cred_dist.list,
- &target->cred_dist_list);
- break;
- }
- }
- if (ep >= ENDPOINT_MAX) {
- WARN_ON(1);
- return;
- }
- }
-}
-
-int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet)
-{
- struct htc_endpoint *endpoint;
- struct list_head queue;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx ep id %d buf 0x%p len %d\n",
- packet->endpoint, packet->buf, packet->act_len);
-
- if (packet->endpoint >= ENDPOINT_MAX) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- endpoint = &target->endpoint[packet->endpoint];
-
- if (!ath6kl_htc_tx_try(target, endpoint, packet)) {
- packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
- -ECANCELED : -ENOSPC;
- INIT_LIST_HEAD(&queue);
- list_add(&packet->list, &queue);
- htc_tx_complete(endpoint, &queue);
- }
-
- return 0;
-}
-
-/* flush endpoint TX queue */
-void ath6kl_htc_flush_txep(struct htc_target *target,
- enum htc_endpoint_id eid, u16 tag)
-{
- struct htc_packet *packet, *tmp_pkt;
- struct list_head discard_q, container;
- struct htc_endpoint *endpoint = &target->endpoint[eid];
-
- if (!endpoint->svc_id) {
- WARN_ON(1);
- return;
- }
-
- /* initialize the discard queue */
- INIT_LIST_HEAD(&discard_q);
-
- spin_lock_bh(&target->tx_lock);
-
- list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) {
- if ((tag == HTC_TX_PACKET_TAG_ALL) ||
- (tag == packet->info.tx.tag))
- list_move_tail(&packet->list, &discard_q);
- }
-
- spin_unlock_bh(&target->tx_lock);
-
- list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) {
- packet->status = -ECANCELED;
- list_del(&packet->list);
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx flushing pkt 0x%p len %d ep %d tag 0x%x\n",
- packet, packet->act_len,
- packet->endpoint, packet->info.tx.tag);
-
- INIT_LIST_HEAD(&container);
- list_add_tail(&packet->list, &container);
- htc_tx_complete(endpoint, &container);
- }
-
-}
-
-static void ath6kl_htc_flush_txep_all(struct htc_target *target)
-{
- struct htc_endpoint *endpoint;
- int i;
-
- dump_cred_dist_stats(target);
-
- for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
- endpoint = &target->endpoint[i];
- if (endpoint->svc_id == 0)
- /* not in use.. */
- continue;
- ath6kl_htc_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
- }
-}
-
-void ath6kl_htc_indicate_activity_change(struct htc_target *target,
- enum htc_endpoint_id eid, bool active)
-{
- struct htc_endpoint *endpoint = &target->endpoint[eid];
- bool dist = false;
-
- if (endpoint->svc_id == 0) {
- WARN_ON(1);
- return;
- }
-
- spin_lock_bh(&target->tx_lock);
-
- if (active) {
- if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) {
- endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE;
- dist = true;
- }
- } else {
- if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) {
- endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE;
- dist = true;
- }
- }
-
- if (dist) {
- endpoint->cred_dist.txq_depth =
- get_queue_depth(&endpoint->txq);
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc tx activity ctxt 0x%p dist 0x%p\n",
- target->credit_info, &target->cred_dist_list);
-
- ath6kl_credit_distribute(target->credit_info,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_ACTIVITY_CHANGE);
- }
-
- spin_unlock_bh(&target->tx_lock);
-
- if (dist && !active)
- htc_chk_ep_txq(target);
-}
-
-/* HTC Rx */
-
-static inline void ath6kl_htc_rx_update_stats(struct htc_endpoint *endpoint,
- int n_look_ahds)
-{
- endpoint->ep_st.rx_pkts++;
- if (n_look_ahds == 1)
- endpoint->ep_st.rx_lkahds++;
- else if (n_look_ahds > 1)
- endpoint->ep_st.rx_bundle_lkahd++;
-}
-
-static inline bool htc_valid_rx_frame_len(struct htc_target *target,
- enum htc_endpoint_id eid, int len)
-{
- return (eid == target->dev->ar->ctrl_ep) ?
- len <= ATH6KL_BUFFER_SIZE : len <= ATH6KL_AMSDU_BUFFER_SIZE;
-}
-
-static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
-{
- struct list_head queue;
-
- INIT_LIST_HEAD(&queue);
- list_add_tail(&packet->list, &queue);
- return ath6kl_htc_add_rxbuf_multiple(target, &queue);
-}
-
-static void htc_reclaim_rxbuf(struct htc_target *target,
- struct htc_packet *packet,
- struct htc_endpoint *ep)
-{
- if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) {
- htc_rxpkt_reset(packet);
- packet->status = -ECANCELED;
- ep->ep_cb.rx(ep->target, packet);
- } else {
- htc_rxpkt_reset(packet);
- htc_add_rxbuf((void *)(target), packet);
- }
-}
-
-static void reclaim_rx_ctrl_buf(struct htc_target *target,
- struct htc_packet *packet)
-{
- spin_lock_bh(&target->htc_lock);
- list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
- spin_unlock_bh(&target->htc_lock);
-}
-
-static int ath6kl_htc_rx_packet(struct htc_target *target,
- struct htc_packet *packet,
- u32 rx_len)
-{
- struct ath6kl_device *dev = target->dev;
- u32 padded_len;
- int status;
-
- padded_len = CALC_TXRX_PADDED_LEN(target, rx_len);
-
- if (padded_len > packet->buf_len) {
- ath6kl_err("not enough receive space for packet - padlen %d recvlen %d bufferlen %d\n",
- padded_len, rx_len, packet->buf_len);
- return -ENOMEM;
- }
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx 0x%p hdr x%x len %d mbox 0x%x\n",
- packet, packet->info.rx.exp_hdr,
- padded_len, dev->ar->mbox_info.htc_addr);
-
- status = hif_read_write_sync(dev->ar,
- dev->ar->mbox_info.htc_addr,
- packet->buf, padded_len,
- HIF_RD_SYNC_BLOCK_FIX);
-
- packet->status = status;
-
- return status;
-}
-
-/*
- * optimization for recv packets, we can indicate a
- * "hint" that there are more single-packets to fetch
- * on this endpoint.
- */
-static void ath6kl_htc_rx_set_indicate(u32 lk_ahd,
- struct htc_endpoint *endpoint,
- struct htc_packet *packet)
-{
- struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
-
- if (htc_hdr->eid == packet->endpoint) {
- if (!list_empty(&endpoint->rx_bufq))
- packet->info.rx.indicat_flags |=
- HTC_RX_FLAGS_INDICATE_MORE_PKTS;
- }
-}
-
-static void ath6kl_htc_rx_chk_water_mark(struct htc_endpoint *endpoint)
-{
- struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
-
- if (ep_cb.rx_refill_thresh > 0) {
- spin_lock_bh(&endpoint->target->rx_lock);
- if (get_queue_depth(&endpoint->rx_bufq)
- < ep_cb.rx_refill_thresh) {
- spin_unlock_bh(&endpoint->target->rx_lock);
- ep_cb.rx_refill(endpoint->target, endpoint->eid);
- return;
- }
- spin_unlock_bh(&endpoint->target->rx_lock);
- }
-}
-
-/* This function is called with rx_lock held */
-static int ath6kl_htc_rx_setup(struct htc_target *target,
- struct htc_endpoint *ep,
- u32 *lk_ahds, struct list_head *queue, int n_msg)
-{
- struct htc_packet *packet;
- /* FIXME: type of lk_ahds can't be right */
- struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)lk_ahds;
- struct htc_ep_callbacks ep_cb;
- int status = 0, j, full_len;
- bool no_recycle;
-
- full_len = CALC_TXRX_PADDED_LEN(target,
- le16_to_cpu(htc_hdr->payld_len) +
- sizeof(*htc_hdr));
-
- if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
- ath6kl_warn("Rx buffer requested with invalid length"
- " htc_hdr : eid - %d, flags = 0x%x, len - %d\n",
- htc_hdr->eid, htc_hdr->flags, le16_to_cpu(htc_hdr->payld_len));
- return -EINVAL;
- }
-
- ep_cb = ep->ep_cb;
- for (j = 0; j < n_msg; j++) {
-
- /*
- * Reset flag, any packets allocated using the
- * rx_alloc() API cannot be recycled on
- * cleanup,they must be explicitly returned.
- */
- no_recycle = false;
-
- if (ep_cb.rx_allocthresh &&
- (full_len > ep_cb.rx_alloc_thresh)) {
- ep->ep_st.rx_alloc_thresh_hit += 1;
- ep->ep_st.rxalloc_thresh_byte +=
- le16_to_cpu(htc_hdr->payld_len);
-
- spin_unlock_bh(&target->rx_lock);
- no_recycle = true;
-
- packet = ep_cb.rx_allocthresh(ep->target, ep->eid,
- full_len);
- spin_lock_bh(&target->rx_lock);
- } else {
- /* refill handler is being used */
- if (list_empty(&ep->rx_bufq)) {
- if (ep_cb.rx_refill) {
- spin_unlock_bh(&target->rx_lock);
- ep_cb.rx_refill(ep->target, ep->eid);
- spin_lock_bh(&target->rx_lock);
- }
- }
-
- if (list_empty(&ep->rx_bufq))
- packet = NULL;
- else {
- packet = list_first_entry(&ep->rx_bufq,
- struct htc_packet, list);
- list_del(&packet->list);
- }
- }
-
- if (!packet) {
- target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS;
- target->ep_waiting = ep->eid;
- return -ENOSPC;
- }
-
- /* clear flags */
- packet->info.rx.rx_flags = 0;
- packet->info.rx.indicat_flags = 0;
- packet->status = 0;
-
- if (no_recycle)
- /*
- * flag that these packets cannot be
- * recycled, they have to be returned to
- * the user
- */
- packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE;
-
- /* Caller needs to free this upon any failure */
- list_add_tail(&packet->list, queue);
-
- if (target->htc_flags & HTC_OP_STATE_STOPPING) {
- status = -ECANCELED;
- break;
- }
-
- if (j) {
- packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR;
- packet->info.rx.exp_hdr = 0xFFFFFFFF;
- } else
- /* set expected look ahead */
- packet->info.rx.exp_hdr = *lk_ahds;
-
- packet->act_len = le16_to_cpu(htc_hdr->payld_len) +
- HTC_HDR_LENGTH;
- }
-
- return status;
-}
-
-static int ath6kl_htc_rx_alloc(struct htc_target *target,
- u32 lk_ahds[], int msg,
- struct htc_endpoint *endpoint,
- struct list_head *queue)
-{
- int status = 0;
- struct htc_packet *packet, *tmp_pkt;
- struct htc_frame_hdr *htc_hdr;
- int i, n_msg;
- struct ath6kl_vif *vif;
- vif = ath6kl_vif_first(target->dev->ar);
-
- spin_lock_bh(&target->rx_lock);
-
- for (i = 0; i < msg; i++) {
-
- htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
-
- if (htc_hdr->eid >= ENDPOINT_MAX) {
- ath6kl_err("invalid ep in look-ahead: %d\n",
- htc_hdr->eid);
- status = -ENOMEM;
- break;
- }
-
- if (htc_hdr->eid != endpoint->eid) {
- ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n",
- htc_hdr->eid, endpoint->eid, i);
- status = -ENOMEM;
- break;
- }
-
- if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) {
- ath6kl_err("payload len %d exceeds max htc : %d !\n",
- htc_hdr->payld_len,
- (u32) HTC_MAX_PAYLOAD_LENGTH);
- status = -ENOMEM;
- break;
- }
-
- if (endpoint->svc_id == 0) {
- ath6kl_err("ep %d is not connected !\n", htc_hdr->eid);
- status = -ENOMEM;
- break;
- }
-
- if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) {
- /*
- * HTC header indicates that every packet to follow
- * has the same padded length so that it can be
- * optimally fetched as a full bundle.
- */
- n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >>
- HTC_FLG_RX_BNDL_CNT_S;
-
- /* the count doesn't include the starter frame */
- n_msg++;
- if (n_msg > target->msg_per_bndl_max) {
- status = -ENOMEM;
- break;
- }
-
- endpoint->ep_st.rx_bundle_from_hdr += 1;
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx bundle pkts %d\n",
- n_msg);
- } else
- /* HTC header only indicates 1 message to fetch */
- n_msg = 1;
-
- /* Setup packet buffers for each message */
- status = ath6kl_htc_rx_setup(target, endpoint, &lk_ahds[i],
- queue, n_msg);
-
- /*
- * This is due to unavailabilty of buffers to rx entire data.
- * Return no error so that free buffers from queue can be used
- * to receive partial data.
- */
- if (status == -ENOSPC) {
- spin_unlock_bh(&target->rx_lock);
- return 0;
- }
-
- if (status)
- break;
- }
-
- spin_unlock_bh(&target->rx_lock);
-
- if (status) {
- list_for_each_entry_safe(packet, tmp_pkt, queue, list) {
- list_del(&packet->list);
- htc_reclaim_rxbuf(target, packet,
- &target->endpoint[packet->endpoint]);
- }
- }
-
- return status;
-}
-
-static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
-{
- if (packets->endpoint != ENDPOINT_0) {
- WARN_ON(1);
- return;
- }
-
- if (packets->status == -ECANCELED) {
- reclaim_rx_ctrl_buf(context, packets);
- return;
- }
-
- if (packets->act_len > 0) {
- ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
- packets->act_len + HTC_HDR_LENGTH);
-
- ath6kl_dbg_dump(ATH6KL_DBG_HTC,
- "htc rx unexpected endpoint 0 message", "",
- packets->buf - HTC_HDR_LENGTH,
- packets->act_len + HTC_HDR_LENGTH);
- }
-
- htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
-}
-
-static void htc_proc_cred_rpt(struct htc_target *target,
- struct htc_credit_report *rpt,
- int n_entries,
- enum htc_endpoint_id from_ep)
-{
- struct htc_endpoint *endpoint;
- int tot_credits = 0, i;
- bool dist = false;
-
- spin_lock_bh(&target->tx_lock);
-
- for (i = 0; i < n_entries; i++, rpt++) {
- if (rpt->eid >= ENDPOINT_MAX) {
- WARN_ON(1);
- spin_unlock_bh(&target->tx_lock);
- return;
- }
-
- endpoint = &target->endpoint[rpt->eid];
-
- ath6kl_dbg(ATH6KL_DBG_CREDIT,
- "credit report ep %d credits %d\n",
- rpt->eid, rpt->credits);
-
- endpoint->ep_st.tx_cred_rpt += 1;
- endpoint->ep_st.cred_retnd += rpt->credits;
-
- if (from_ep == rpt->eid) {
- /*
- * This credit report arrived on the same endpoint
- * indicating it arrived in an RX packet.
- */
- endpoint->ep_st.cred_from_rx += rpt->credits;
- endpoint->ep_st.cred_rpt_from_rx += 1;
- } else if (from_ep == ENDPOINT_0) {
- /* credit arrived on endpoint 0 as a NULL message */
- endpoint->ep_st.cred_from_ep0 += rpt->credits;
- endpoint->ep_st.cred_rpt_ep0 += 1;
- } else {
- endpoint->ep_st.cred_from_other += rpt->credits;
- endpoint->ep_st.cred_rpt_from_other += 1;
- }
-
- if (rpt->eid == ENDPOINT_0)
- /* always give endpoint 0 credits back */
- endpoint->cred_dist.credits += rpt->credits;
- else {
- endpoint->cred_dist.cred_to_dist += rpt->credits;
- dist = true;
- }
-
- /*
- * Refresh tx depth for distribution function that will
- * recover these credits NOTE: this is only valid when
- * there are credits to recover!
- */
- endpoint->cred_dist.txq_depth =
- get_queue_depth(&endpoint->txq);
-
- tot_credits += rpt->credits;
- }
-
- if (dist) {
- /*
- * This was a credit return based on a completed send
- * operations note, this is done with the lock held
- */
- ath6kl_credit_distribute(target->credit_info,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_SEND_COMPLETE);
- }
-
- spin_unlock_bh(&target->tx_lock);
-
- if (tot_credits)
- htc_chk_ep_txq(target);
-}
-
-static int htc_parse_trailer(struct htc_target *target,
- struct htc_record_hdr *record,
- u8 *record_buf, u32 *next_lk_ahds,
- enum htc_endpoint_id endpoint,
- int *n_lk_ahds)
-{
- struct htc_bundle_lkahd_rpt *bundle_lkahd_rpt;
- struct htc_lookahead_report *lk_ahd;
- int len;
-
- switch (record->rec_id) {
- case HTC_RECORD_CREDITS:
- len = record->len / sizeof(struct htc_credit_report);
- if (!len) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- htc_proc_cred_rpt(target,
- (struct htc_credit_report *) record_buf,
- len, endpoint);
- break;
- case HTC_RECORD_LOOKAHEAD:
- len = record->len / sizeof(*lk_ahd);
- if (!len) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- lk_ahd = (struct htc_lookahead_report *) record_buf;
- if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF))
- && next_lk_ahds) {
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx lk_ahd found pre_valid 0x%x post_valid 0x%x\n",
- lk_ahd->pre_valid, lk_ahd->post_valid);
-
- /* look ahead bytes are valid, copy them over */
- memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
-
- ath6kl_dbg_dump(ATH6KL_DBG_HTC,
- "htc rx next look ahead",
- "", next_lk_ahds, 4);
-
- if (n_lk_ahds)
- *n_lk_ahds = 1;
- }
- break;
- case HTC_RECORD_LOOKAHEAD_BUNDLE:
- len = record->len / sizeof(*bundle_lkahd_rpt);
- if (!len || (len > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
- WARN_ON(1);
- return -EINVAL;
- }
-
- if (next_lk_ahds) {
- int i;
-
- bundle_lkahd_rpt =
- (struct htc_bundle_lkahd_rpt *) record_buf;
-
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bundle lk_ahd",
- "", record_buf, record->len);
-
- for (i = 0; i < len; i++) {
- memcpy((u8 *)&next_lk_ahds[i],
- bundle_lkahd_rpt->lk_ahd, 4);
- bundle_lkahd_rpt++;
- }
-
- if (n_lk_ahds)
- *n_lk_ahds = i;
- }
- break;
- default:
- ath6kl_err("unhandled record: id:%d len:%d\n",
- record->rec_id, record->len);
- break;
- }
-
- return 0;
-
-}
-
-static int htc_proc_trailer(struct htc_target *target,
- u8 *buf, int len, u32 *next_lk_ahds,
- int *n_lk_ahds, enum htc_endpoint_id endpoint)
-{
- struct htc_record_hdr *record;
- int orig_len;
- int status;
- u8 *record_buf;
- u8 *orig_buf;
-
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc rx trailer len %d\n", len);
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, NULL, "", buf, len);
-
- orig_buf = buf;
- orig_len = len;
- status = 0;
-
- while (len > 0) {
-
- if (len < sizeof(struct htc_record_hdr)) {
- status = -ENOMEM;
- break;
- }
- /* these are byte aligned structs */
- record = (struct htc_record_hdr *) buf;
- len -= sizeof(struct htc_record_hdr);
- buf += sizeof(struct htc_record_hdr);
-
- if (record->len > len) {
- ath6kl_err("invalid record len: %d (id:%d) buf has: %d bytes left\n",
- record->len, record->rec_id, len);
- status = -ENOMEM;
- break;
- }
- record_buf = buf;
-
- status = htc_parse_trailer(target, record, record_buf,
- next_lk_ahds, endpoint, n_lk_ahds);
-
- if (status)
- break;
-
- /* advance buffer past this record for next time around */
- buf += record->len;
- len -= record->len;
- }
-
- if (status)
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad trailer",
- "", orig_buf, orig_len);
-
- return status;
-}
-
-static int ath6kl_htc_rx_process_hdr(struct htc_target *target,
- struct htc_packet *packet,
- u32 *next_lkahds, int *n_lkahds)
-{
- int status = 0;
- u16 payload_len;
- u32 lk_ahd;
- struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf;
-
- if (n_lkahds != NULL)
- *n_lkahds = 0;
-
- /*
- * NOTE: we cannot assume the alignment of buf, so we use the safe
- * macros to retrieve 16 bit fields.
- */
- payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
-
- memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd));
-
- if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) {
- /*
- * Refresh the expected header and the actual length as it
- * was unknown when this packet was grabbed as part of the
- * bundle.
- */
- packet->info.rx.exp_hdr = lk_ahd;
- packet->act_len = payload_len + HTC_HDR_LENGTH;
-
- /* validate the actual header that was refreshed */
- if (packet->act_len > packet->buf_len) {
- ath6kl_err("refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
- payload_len, lk_ahd);
- /*
- * Limit this to max buffer just to print out some
- * of the buffer.
- */
- packet->act_len = min(packet->act_len, packet->buf_len);
- status = -ENOMEM;
- goto fail_rx;
- }
-
- if (packet->endpoint != htc_hdr->eid) {
- ath6kl_err("refreshed hdr ep (%d) does not match expected ep (%d)\n",
- htc_hdr->eid, packet->endpoint);
- status = -ENOMEM;
- goto fail_rx;
- }
- }
-
- if (lk_ahd != packet->info.rx.exp_hdr) {
- ath6kl_err("%s(): lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
- __func__, packet, packet->info.rx.rx_flags);
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx expected lk_ahd",
- "", &packet->info.rx.exp_hdr, 4);
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx current header",
- "", (u8 *)&lk_ahd, sizeof(lk_ahd));
- status = -ENOMEM;
- goto fail_rx;
- }
-
- if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
- if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
- htc_hdr->ctrl[0] > payload_len) {
- ath6kl_err("%s(): invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
- __func__, payload_len, htc_hdr->ctrl[0]);
- status = -ENOMEM;
- goto fail_rx;
- }
-
- if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
- next_lkahds = NULL;
- n_lkahds = NULL;
- }
-
- status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH
- + payload_len - htc_hdr->ctrl[0],
- htc_hdr->ctrl[0], next_lkahds,
- n_lkahds, packet->endpoint);
-
- if (status)
- goto fail_rx;
-
- packet->act_len -= htc_hdr->ctrl[0];
- }
-
- packet->buf += HTC_HDR_LENGTH;
- packet->act_len -= HTC_HDR_LENGTH;
-
-fail_rx:
- if (status)
- ath6kl_dbg_dump(ATH6KL_DBG_HTC, "htc rx bad packet",
- "", packet->buf, packet->act_len);
-
- return status;
-}
-
-static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
- struct htc_packet *packet)
-{
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx complete ep %d packet 0x%p\n",
- endpoint->eid, packet);
- endpoint->ep_cb.rx(endpoint->target, packet);
-}
-
-static int ath6kl_htc_rx_bundle(struct htc_target *target,
- struct list_head *rxq,
- struct list_head *sync_compq,
- int *n_pkt_fetched, bool part_bundle)
-{
- struct hif_scatter_req *scat_req;
- struct htc_packet *packet;
- int rem_space = target->max_rx_bndl_sz;
- int n_scat_pkt, status = 0, i, len;
-
- n_scat_pkt = get_queue_depth(rxq);
- n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max);
-
- if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
- /*
- * We were forced to split this bundle receive operation
- * all packets in this partial bundle must have their
- * lookaheads ignored.
- */
- part_bundle = true;
-
- /*
- * This would only happen if the target ignored our max
- * bundle limit.
- */
- ath6kl_warn("%s(): partial bundle detected num:%d , %d\n",
- __func__, get_queue_depth(rxq), n_scat_pkt);
- }
-
- len = 0;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx bundle depth %d pkts %d\n",
- get_queue_depth(rxq), n_scat_pkt);
-
- scat_req = hif_scatter_req_get(target->dev->ar);
-
- if (scat_req == NULL)
- goto fail_rx_pkt;
-
- for (i = 0; i < n_scat_pkt; i++) {
- int pad_len;
-
- packet = list_first_entry(rxq, struct htc_packet, list);
- list_del(&packet->list);
-
- pad_len = CALC_TXRX_PADDED_LEN(target,
- packet->act_len);
-
- if ((rem_space - pad_len) < 0) {
- list_add(&packet->list, rxq);
- break;
- }
-
- rem_space -= pad_len;
-
- if (part_bundle || (i < (n_scat_pkt - 1)))
- /*
- * Packet 0..n-1 cannot be checked for look-aheads
- * since we are fetching a bundle the last packet
- * however can have it's lookahead used
- */
- packet->info.rx.rx_flags |=
- HTC_RX_PKT_IGNORE_LOOKAHEAD;
-
- /* NOTE: 1 HTC packet per scatter entry */
- scat_req->scat_list[i].buf = packet->buf;
- scat_req->scat_list[i].len = pad_len;
-
- packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE;
-
- list_add_tail(&packet->list, sync_compq);
-
- WARN_ON(!scat_req->scat_list[i].len);
- len += scat_req->scat_list[i].len;
- }
-
- scat_req->len = len;
- scat_req->scat_entries = i;
-
- status = ath6kl_hif_submit_scat_req(target->dev, scat_req, true);
-
- if (!status)
- *n_pkt_fetched = i;
-
- /* free scatter request */
- hif_scatter_req_add(target->dev->ar, scat_req);
-
-fail_rx_pkt:
-
- return status;
-}
-
-static int ath6kl_htc_rx_process_packets(struct htc_target *target,
- struct list_head *comp_pktq,
- u32 lk_ahds[],
- int *n_lk_ahd)
-{
- struct htc_packet *packet, *tmp_pkt;
- struct htc_endpoint *ep;
- int status = 0;
-
- list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
- ep = &target->endpoint[packet->endpoint];
-
- /* process header for each of the recv packet */
- status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
- n_lk_ahd);
- if (status)
- return status;
-
- list_del(&packet->list);
-
- if (list_empty(comp_pktq)) {
- /*
- * Last packet's more packet flag is set
- * based on the lookahead.
- */
- if (*n_lk_ahd > 0)
- ath6kl_htc_rx_set_indicate(lk_ahds[0],
- ep, packet);
- } else
- /*
- * Packets in a bundle automatically have
- * this flag set.
- */
- packet->info.rx.indicat_flags |=
- HTC_RX_FLAGS_INDICATE_MORE_PKTS;
-
- ath6kl_htc_rx_update_stats(ep, *n_lk_ahd);
-
- if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
- ep->ep_st.rx_bundl += 1;
-
- ath6kl_htc_rx_complete(ep, packet);
- }
-
- return status;
-}
-
-static int ath6kl_htc_rx_fetch(struct htc_target *target,
- struct list_head *rx_pktq,
- struct list_head *comp_pktq)
-{
- int fetched_pkts;
- bool part_bundle = false;
- int status = 0;
- struct list_head tmp_rxq;
- struct htc_packet *packet, *tmp_pkt;
-
- /* now go fetch the list of HTC packets */
- while (!list_empty(rx_pktq)) {
- fetched_pkts = 0;
-
- INIT_LIST_HEAD(&tmp_rxq);
-
- if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) {
- /*
- * There are enough packets to attempt a
- * bundle transfer and recv bundling is
- * allowed.
- */
- status = ath6kl_htc_rx_bundle(target, rx_pktq,
- &tmp_rxq,
- &fetched_pkts,
- part_bundle);
- if (status)
- goto fail_rx;
-
- if (!list_empty(rx_pktq))
- part_bundle = true;
-
- list_splice_tail_init(&tmp_rxq, comp_pktq);
- }
-
- if (!fetched_pkts) {
-
- packet = list_first_entry(rx_pktq, struct htc_packet,
- list);
-
- /* fully synchronous */
- packet->completion = NULL;
-
- if (!list_is_singular(rx_pktq))
- /*
- * look_aheads in all packet
- * except the last one in the
- * bundle must be ignored
- */
- packet->info.rx.rx_flags |=
- HTC_RX_PKT_IGNORE_LOOKAHEAD;
-
- /* go fetch the packet */
- status = ath6kl_htc_rx_packet(target, packet,
- packet->act_len);
-
- list_move_tail(&packet->list, &tmp_rxq);
-
- if (status)
- goto fail_rx;
-
- list_splice_tail_init(&tmp_rxq, comp_pktq);
- }
- }
-
- return 0;
-
-fail_rx:
-
- /*
- * Cleanup any packets we allocated but didn't use to
- * actually fetch any packets.
- */
-
- list_for_each_entry_safe(packet, tmp_pkt, rx_pktq, list) {
- list_del(&packet->list);
- htc_reclaim_rxbuf(target, packet,
- &target->endpoint[packet->endpoint]);
- }
-
- list_for_each_entry_safe(packet, tmp_pkt, &tmp_rxq, list) {
- list_del(&packet->list);
- htc_reclaim_rxbuf(target, packet,
- &target->endpoint[packet->endpoint]);
- }
-
- return status;
-}
-
-int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
- u32 msg_look_ahead, int *num_pkts)
-{
- struct htc_packet *packets, *tmp_pkt;
- struct htc_endpoint *endpoint;
- struct list_head rx_pktq, comp_pktq;
- int status = 0;
- u32 look_aheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
- int num_look_ahead = 1;
- enum htc_endpoint_id id;
- int n_fetched = 0;
- struct ath6kl_vif *vif;
- vif = ath6kl_vif_first(target->dev->ar);
-
- INIT_LIST_HEAD(&comp_pktq);
- *num_pkts = 0;
-
- /*
- * On first entry copy the look_aheads into our temp array for
- * processing
- */
- look_aheads[0] = msg_look_ahead;
-
- while (true) {
-
- /*
- * First lookahead sets the expected endpoint IDs for all
- * packets in a bundle.
- */
- id = ((struct htc_frame_hdr *)&look_aheads[0])->eid;
- endpoint = &target->endpoint[id];
-
- if (id >= ENDPOINT_MAX) {
- ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n",
- id);
- status = -ENOMEM;
- break;
- }
-
- INIT_LIST_HEAD(&rx_pktq);
- INIT_LIST_HEAD(&comp_pktq);
-
- /*
- * Try to allocate as many HTC RX packets indicated by the
- * look_aheads.
- */
- status = ath6kl_htc_rx_alloc(target, look_aheads,
- num_look_ahead, endpoint,
- &rx_pktq);
- if (status)
- break;
-
- if (get_queue_depth(&rx_pktq) >= 2)
- /*
- * A recv bundle was detected, force IRQ status
- * re-check again
- */
- target->chk_irq_status_cnt = 1;
-
- n_fetched += get_queue_depth(&rx_pktq);
-
- num_look_ahead = 0;
-
- status = ath6kl_htc_rx_fetch(target, &rx_pktq, &comp_pktq);
-
- if (!status)
- ath6kl_htc_rx_chk_water_mark(endpoint);
-
- /* Process fetched packets */
- status = ath6kl_htc_rx_process_packets(target, &comp_pktq,
- look_aheads,
- &num_look_ahead);
-
- if (!num_look_ahead || status)
- break;
-
- /*
- * For SYNCH processing, if we get here, we are running
- * through the loop again due to a detected lookahead. Set
- * flag that we should re-check IRQ status registers again
- * before leaving IRQ processing, this can net better
- * performance in high throughput situations.
- */
- target->chk_irq_status_cnt = 1;
- }
-
- if (status) {
- ath6kl_err("failed to get pending recv messages: %d\n",
- status);
-
- /* cleanup any packets in sync completion queue */
- list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) {
- list_del(&packets->list);
- htc_reclaim_rxbuf(target, packets,
- &target->endpoint[packets->endpoint]);
- }
-
- if (target->htc_flags & HTC_OP_STATE_STOPPING) {
- ath6kl_warn("host is going to stop blocking receiver for htc_stop\n");
- ath6kl_hif_rx_control(target->dev, false);
- }
- }
-
- /*
- * Before leaving, check to see if host ran out of buffers and
- * needs to stop the receiver.
- */
- if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
- ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n");
- ath6kl_hif_rx_control(target->dev, false);
- }
- *num_pkts = n_fetched;
-
- return status;
-}
-
-/*
- * Synchronously wait for a control message from the target,
- * This function is used at initialization time ONLY. At init messages
- * on ENDPOINT 0 are expected.
- */
-static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
-{
- struct htc_packet *packet = NULL;
- struct htc_frame_hdr *htc_hdr;
- u32 look_ahead;
-
- if (ath6kl_hif_poll_mboxmsg_rx(target->dev, &look_ahead,
- HTC_TARGET_RESPONSE_TIMEOUT))
- return NULL;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx wait ctrl look_ahead 0x%X\n", look_ahead);
-
- htc_hdr = (struct htc_frame_hdr *)&look_ahead;
-
- if (htc_hdr->eid != ENDPOINT_0)
- return NULL;
-
- packet = htc_get_control_buf(target, false);
-
- if (!packet)
- return NULL;
-
- packet->info.rx.rx_flags = 0;
- packet->info.rx.exp_hdr = look_ahead;
- packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;
-
- if (packet->act_len > packet->buf_len)
- goto fail_ctrl_rx;
-
- /* we want synchronous operation */
- packet->completion = NULL;
-
- /* get the message from the device, this will block */
- if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
- goto fail_ctrl_rx;
-
- /* process receive header */
- packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
-
- if (packet->status) {
- ath6kl_err("htc_wait_for_ctrl_msg, ath6kl_htc_rx_process_hdr failed (status = %d)\n",
- packet->status);
- goto fail_ctrl_rx;
- }
-
- return packet;
-
-fail_ctrl_rx:
- if (packet != NULL) {
- htc_rxpkt_reset(packet);
- reclaim_rx_ctrl_buf(target, packet);
- }
-
- return NULL;
-}
-
-int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
- struct list_head *pkt_queue)
-{
- struct htc_endpoint *endpoint;
- struct htc_packet *first_pkt;
- bool rx_unblock = false;
- int status = 0, depth;
-
- if (list_empty(pkt_queue))
- return -ENOMEM;
-
- first_pkt = list_first_entry(pkt_queue, struct htc_packet, list);
-
- if (first_pkt->endpoint >= ENDPOINT_MAX)
- return status;
-
- depth = get_queue_depth(pkt_queue);
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx add multiple ep id %d cnt %d len %d\n",
- first_pkt->endpoint, depth, first_pkt->buf_len);
-
- endpoint = &target->endpoint[first_pkt->endpoint];
-
- if (target->htc_flags & HTC_OP_STATE_STOPPING) {
- struct htc_packet *packet, *tmp_pkt;
-
- /* walk through queue and mark each one canceled */
- list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
- packet->status = -ECANCELED;
- list_del(&packet->list);
- ath6kl_htc_rx_complete(endpoint, packet);
- }
-
- return status;
- }
-
- spin_lock_bh(&target->rx_lock);
-
- list_splice_tail_init(pkt_queue, &endpoint->rx_bufq);
-
- /* check if we are blocked waiting for a new buffer */
- if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
- if (target->ep_waiting == first_pkt->endpoint) {
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx blocked on ep %d, unblocking\n",
- target->ep_waiting);
- target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
- target->ep_waiting = ENDPOINT_MAX;
- rx_unblock = true;
- }
- }
-
- spin_unlock_bh(&target->rx_lock);
-
- if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING))
- /* TODO : implement a buffer threshold count? */
- ath6kl_hif_rx_control(target->dev, true);
-
- return status;
-}
-
-void ath6kl_htc_flush_rx_buf(struct htc_target *target)
-{
- struct htc_endpoint *endpoint;
- struct htc_packet *packet, *tmp_pkt;
- int i;
-
- for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
- endpoint = &target->endpoint[i];
- if (!endpoint->svc_id)
- /* not in use.. */
- continue;
-
- spin_lock_bh(&target->rx_lock);
- list_for_each_entry_safe(packet, tmp_pkt,
- &endpoint->rx_bufq, list) {
- list_del(&packet->list);
- spin_unlock_bh(&target->rx_lock);
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc rx flush pkt 0x%p len %d ep %d\n",
- packet, packet->buf_len,
- packet->endpoint);
- /*
- * packets in rx_bufq of endpoint 0 have originally
- * been queued from target->free_ctrl_rxbuf where
- * packet and packet->buf_start are allocated
- * separately using kmalloc(). For other endpoint
- * rx_bufq, it is allocated as skb where packet is
- * skb->head. Take care of this difference while freeing
- * the memory.
- */
- if (packet->endpoint == ENDPOINT_0) {
- kfree(packet->buf_start);
- kfree(packet);
- } else {
- dev_kfree_skb(packet->pkt_cntxt);
- }
- spin_lock_bh(&target->rx_lock);
- }
- spin_unlock_bh(&target->rx_lock);
- }
-}
-
-int ath6kl_htc_conn_service(struct htc_target *target,
- struct htc_service_connect_req *conn_req,
- struct htc_service_connect_resp *conn_resp)
-{
- struct htc_packet *rx_pkt = NULL;
- struct htc_packet *tx_pkt = NULL;
- struct htc_conn_service_resp *resp_msg;
- struct htc_conn_service_msg *conn_msg;
- struct htc_endpoint *endpoint;
- enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
- unsigned int max_msg_sz = 0;
- int status = 0;
-
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc connect service target 0x%p service id 0x%x\n",
- target, conn_req->svc_id);
-
- if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
- /* special case for pseudo control service */
- assigned_ep = ENDPOINT_0;
- max_msg_sz = HTC_MAX_CTRL_MSG_LEN;
- } else {
- /* allocate a packet to send to the target */
- tx_pkt = htc_get_control_buf(target, true);
-
- if (!tx_pkt)
- return -ENOMEM;
-
- conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf;
- memset(conn_msg, 0, sizeof(*conn_msg));
- conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
- conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
- conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags);
-
- set_htc_pkt_info(tx_pkt, NULL, (u8 *) conn_msg,
- sizeof(*conn_msg) + conn_msg->svc_meta_len,
- ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
-
- /* we want synchronous operation */
- tx_pkt->completion = NULL;
- ath6kl_htc_tx_prep_pkt(tx_pkt, 0, 0, 0);
- status = ath6kl_htc_tx_issue(target, tx_pkt);
-
- if (status)
- goto fail_tx;
-
- /* wait for response */
- rx_pkt = htc_wait_for_ctrl_msg(target);
-
- if (!rx_pkt) {
- status = -ENOMEM;
- goto fail_tx;
- }
-
- resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
-
- if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID)
- || (rx_pkt->act_len < sizeof(*resp_msg))) {
- status = -ENOMEM;
- goto fail_tx;
- }
-
- conn_resp->resp_code = resp_msg->status;
- /* check response status */
- if (resp_msg->status != HTC_SERVICE_SUCCESS) {
- ath6kl_err("target failed service 0x%X connect request (status:%d)\n",
- resp_msg->svc_id, resp_msg->status);
- status = -ENOMEM;
- goto fail_tx;
- }
-
- assigned_ep = (enum htc_endpoint_id)resp_msg->eid;
- max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
- }
-
- if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
- status = -ENOMEM;
- goto fail_tx;
- }
-
- endpoint = &target->endpoint[assigned_ep];
- endpoint->eid = assigned_ep;
- if (endpoint->svc_id) {
- status = -ENOMEM;
- goto fail_tx;
- }
-
- /* return assigned endpoint to caller */
- conn_resp->endpoint = assigned_ep;
- conn_resp->len_max = max_msg_sz;
-
- /* setup the endpoint */
-
- /* this marks the endpoint in use */
- endpoint->svc_id = conn_req->svc_id;
-
- endpoint->max_txq_depth = conn_req->max_txq_depth;
- endpoint->len_max = max_msg_sz;
- endpoint->ep_cb = conn_req->ep_cb;
- endpoint->cred_dist.svc_id = conn_req->svc_id;
- endpoint->cred_dist.htc_ep = endpoint;
- endpoint->cred_dist.endpoint = assigned_ep;
- endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
-
- if (conn_req->max_rxmsg_sz) {
- /*
- * Override cred_per_msg calculation, this optimizes
- * the credit-low indications since the host will actually
- * issue smaller messages in the Send path.
- */
- if (conn_req->max_rxmsg_sz > max_msg_sz) {
- status = -ENOMEM;
- goto fail_tx;
- }
- endpoint->cred_dist.cred_per_msg =
- conn_req->max_rxmsg_sz / target->tgt_cred_sz;
- } else
- endpoint->cred_dist.cred_per_msg =
- max_msg_sz / target->tgt_cred_sz;
-
- if (!endpoint->cred_dist.cred_per_msg)
- endpoint->cred_dist.cred_per_msg = 1;
-
- /* save local connection flags */
- endpoint->conn_flags = conn_req->flags;
-
-fail_tx:
- if (tx_pkt)
- htc_reclaim_txctrl_buf(target, tx_pkt);
-
- if (rx_pkt) {
- htc_rxpkt_reset(rx_pkt);
- reclaim_rx_ctrl_buf(target, rx_pkt);
- }
-
- return status;
-}
-
-static void reset_ep_state(struct htc_target *target)
-{
- struct htc_endpoint *endpoint;
- int i;
-
- for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
- endpoint = &target->endpoint[i];
- memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist));
- endpoint->svc_id = 0;
- endpoint->len_max = 0;
- endpoint->max_txq_depth = 0;
- memset(&endpoint->ep_st, 0,
- sizeof(endpoint->ep_st));
- INIT_LIST_HEAD(&endpoint->rx_bufq);
- INIT_LIST_HEAD(&endpoint->txq);
- endpoint->target = target;
- }
-
- /* reset distribution list */
- /* FIXME: free existing entries */
- INIT_LIST_HEAD(&target->cred_dist_list);
-}
-
-int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
- enum htc_endpoint_id endpoint)
-{
- int num;
-
- spin_lock_bh(&target->rx_lock);
- num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
- spin_unlock_bh(&target->rx_lock);
- return num;
-}
-
-static void htc_setup_msg_bndl(struct htc_target *target)
-{
- /* limit what HTC can handle */
- target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE,
- target->msg_per_bndl_max);
-
- if (ath6kl_hif_enable_scatter(target->dev->ar)) {
- target->msg_per_bndl_max = 0;
- return;
- }
-
- /* limit bundle what the device layer can handle */
- target->msg_per_bndl_max = min(target->max_scat_entries,
- target->msg_per_bndl_max);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "htc bundling allowed msg_per_bndl_max %d\n",
- target->msg_per_bndl_max);
-
- /* Max rx bundle size is limited by the max tx bundle size */
- target->max_rx_bndl_sz = target->max_xfer_szper_scatreq;
- /* Max tx bundle size if limited by the extended mbox address range */
- target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
- target->max_xfer_szper_scatreq);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n",
- target->max_rx_bndl_sz, target->max_tx_bndl_sz);
-
- if (target->max_tx_bndl_sz)
- /* tx_bndl_mask is enabled per AC, each has 1 bit */
- target->tx_bndl_mask = (1 << WMM_NUM_AC) - 1;
-
- if (target->max_rx_bndl_sz)
- target->rx_bndl_enable = true;
-
- if ((target->tgt_cred_sz % target->block_sz) != 0) {
- ath6kl_warn("credit size: %d is not block aligned! Disabling send bundling\n",
- target->tgt_cred_sz);
-
- /*
- * Disallow send bundling since the credit size is
- * not aligned to a block size the I/O block
- * padding will spill into the next credit buffer
- * which is fatal.
- */
- target->tx_bndl_mask = 0;
- }
-}
-
-int ath6kl_htc_wait_target(struct htc_target *target)
-{
- struct htc_packet *packet = NULL;
- struct htc_ready_ext_msg *rdy_msg;
- struct htc_service_connect_req connect;
- struct htc_service_connect_resp resp;
- int status;
-
- /* FIXME: remove once USB support is implemented */
- if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {
- ath6kl_err("HTC doesn't support USB yet. Patience!\n");
- return -EOPNOTSUPP;
- }
-
- /* we should be getting 1 control message that the target is ready */
- packet = htc_wait_for_ctrl_msg(target);
-
- if (!packet)
- return -ENOMEM;
-
- /* we controlled the buffer creation so it's properly aligned */
- rdy_msg = (struct htc_ready_ext_msg *)packet->buf;
-
- if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) ||
- (packet->act_len < sizeof(struct htc_ready_msg))) {
- status = -ENOMEM;
- goto fail_wait_target;
- }
-
- if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) {
- status = -ENOMEM;
- goto fail_wait_target;
- }
-
- target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
- target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "htc target ready credits %d size %d\n",
- target->tgt_creds, target->tgt_cred_sz);
-
- /* check if this is an extended ready message */
- if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) {
- /* this is an extended message */
- target->htc_tgt_ver = rdy_msg->htc_ver;
- target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl;
- } else {
- /* legacy */
- target->htc_tgt_ver = HTC_VERSION_2P0;
- target->msg_per_bndl_max = 0;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n",
- (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
- target->htc_tgt_ver);
-
- if (target->msg_per_bndl_max > 0)
- htc_setup_msg_bndl(target);
-
- /* setup our pseudo HTC control endpoint connection */
- memset(&connect, 0, sizeof(connect));
- memset(&resp, 0, sizeof(resp));
- connect.ep_cb.rx = htc_ctrl_rx;
- connect.ep_cb.rx_refill = NULL;
- connect.ep_cb.tx_full = NULL;
- connect.max_txq_depth = NUM_CONTROL_BUFFERS;
- connect.svc_id = HTC_CTRL_RSVD_SVC;
-
- /* connect fake service */
- status = ath6kl_htc_conn_service((void *)target, &connect, &resp);
-
- if (status)
- /*
- * FIXME: this call doesn't make sense, the caller should
- * call ath6kl_htc_cleanup() when it wants remove htc
- */
- ath6kl_hif_cleanup_scatter(target->dev->ar);
-
-fail_wait_target:
- if (packet) {
- htc_rxpkt_reset(packet);
- reclaim_rx_ctrl_buf(target, packet);
- }
-
- return status;
-}
-
-/*
- * Start HTC, enable interrupts and let the target know
- * host has finished setup.
- */
-int ath6kl_htc_start(struct htc_target *target)
-{
- struct htc_packet *packet;
- int status;
-
- memset(&target->dev->irq_proc_reg, 0,
- sizeof(target->dev->irq_proc_reg));
-
- /* Disable interrupts at the chip level */
- ath6kl_hif_disable_intrs(target->dev);
-
- target->htc_flags = 0;
- target->rx_st_flags = 0;
-
- /* Push control receive buffers into htc control endpoint */
- while ((packet = htc_get_control_buf(target, false)) != NULL) {
- status = htc_add_rxbuf(target, packet);
- if (status)
- return status;
- }
-
- /* NOTE: the first entry in the distribution list is ENDPOINT_0 */
- ath6kl_credit_init(target->credit_info, &target->cred_dist_list,
- target->tgt_creds);
-
- dump_cred_dist_stats(target);
-
- /* Indicate to the target of the setup completion */
- status = htc_setup_tx_complete(target);
-
- if (status)
- return status;
-
- /* unmask interrupts */
- status = ath6kl_hif_unmask_intrs(target->dev);
-
- if (status)
- ath6kl_htc_stop(target);
-
- return status;
-}
-
-static int ath6kl_htc_reset(struct htc_target *target)
-{
- u32 block_size, ctrl_bufsz;
- struct htc_packet *packet;
- int i;
-
- reset_ep_state(target);
-
- block_size = target->dev->ar->mbox_info.block_size;
-
- ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ?
- (block_size + HTC_HDR_LENGTH) :
- (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH);
-
- for (i = 0; i < NUM_CONTROL_BUFFERS; i++) {
- packet = kzalloc(sizeof(*packet), GFP_KERNEL);
- if (!packet)
- return -ENOMEM;
-
- packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL);
- if (!packet->buf_start) {
- kfree(packet);
- return -ENOMEM;
- }
-
- packet->buf_len = ctrl_bufsz;
- if (i < NUM_CONTROL_RX_BUFFERS) {
- packet->act_len = 0;
- packet->buf = packet->buf_start;
- packet->endpoint = ENDPOINT_0;
- list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
- } else
- list_add_tail(&packet->list, &target->free_ctrl_txbuf);
- }
-
- return 0;
-}
-
-/* htc_stop: stop interrupt reception, and flush all queued buffers */
-void ath6kl_htc_stop(struct htc_target *target)
-{
- spin_lock_bh(&target->htc_lock);
- target->htc_flags |= HTC_OP_STATE_STOPPING;
- spin_unlock_bh(&target->htc_lock);
-
- /*
- * Masking interrupts is a synchronous operation, when this
- * function returns all pending HIF I/O has completed, we can
- * safely flush the queues.
- */
- ath6kl_hif_mask_intrs(target->dev);
-
- ath6kl_htc_flush_txep_all(target);
-
- ath6kl_htc_flush_rx_buf(target);
-
- ath6kl_htc_reset(target);
-}
-
-void *ath6kl_htc_create(struct ath6kl *ar)
-{
- struct htc_target *target = NULL;
- int status = 0;
-
- target = kzalloc(sizeof(*target), GFP_KERNEL);
- if (!target) {
- ath6kl_err("unable to allocate memory\n");
- return NULL;
- }
-
- target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
- if (!target->dev) {
- ath6kl_err("unable to allocate memory\n");
- status = -ENOMEM;
- goto err_htc_cleanup;
- }
-
- spin_lock_init(&target->htc_lock);
- spin_lock_init(&target->rx_lock);
- spin_lock_init(&target->tx_lock);
-
- INIT_LIST_HEAD(&target->free_ctrl_txbuf);
- INIT_LIST_HEAD(&target->free_ctrl_rxbuf);
- INIT_LIST_HEAD(&target->cred_dist_list);
-
- target->dev->ar = ar;
- target->dev->htc_cnxt = target;
- target->ep_waiting = ENDPOINT_MAX;
-
- status = ath6kl_hif_setup(target->dev);
- if (status)
- goto err_htc_cleanup;
-
- status = ath6kl_htc_reset(target);
- if (status)
- goto err_htc_cleanup;
-
- return target;
-
-err_htc_cleanup:
- ath6kl_htc_cleanup(target);
-
- return NULL;
-}
-
-/* cleanup the HTC instance */
-void ath6kl_htc_cleanup(struct htc_target *target)
-{
- struct htc_packet *packet, *tmp_packet;
-
- /* FIXME: remove check once USB support is implemented */
- if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)
- ath6kl_hif_cleanup_scatter(target->dev->ar);
-
- list_for_each_entry_safe(packet, tmp_packet,
- &target->free_ctrl_txbuf, list) {
- list_del(&packet->list);
- kfree(packet->buf_start);
- kfree(packet);
- }
-
- list_for_each_entry_safe(packet, tmp_packet,
- &target->free_ctrl_rxbuf, list) {
- list_del(&packet->list);
- kfree(packet->buf_start);
- kfree(packet);
- }
-
- kfree(target->dev);
- kfree(target);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
deleted file mode 100755
index 5197665..0000000
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef HTC_H
-#define HTC_H
-
-#include "common.h"
-
-/* frame header flags */
-
-/* send direction */
-#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
-#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
-
-/* receive direction */
-#define HTC_FLG_RX_UNUSED (1 << 0)
-#define HTC_FLG_RX_TRAILER (1 << 1)
-/* Bundle count maske and shift */
-#define HTC_FLG_RX_BNDL_CNT (0xF0)
-#define HTC_FLG_RX_BNDL_CNT_S 4
-
-#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
-#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
-
-/* HTC control message IDs */
-
-#define HTC_MSG_READY_ID 1
-#define HTC_MSG_CONN_SVC_ID 2
-#define HTC_MSG_CONN_SVC_RESP_ID 3
-#define HTC_MSG_SETUP_COMPLETE_ID 4
-#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
-
-#define HTC_MAX_CTRL_MSG_LEN 256
-
-#define HTC_VERSION_2P0 0x00
-#define HTC_VERSION_2P1 0x01
-
-#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
-
-#define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x0
-#define HTC_CONN_FLGS_THRESH_LVL_HALF 0x1
-#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
-#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
-#define HTC_CONN_FLGS_THRESH_MASK 0x3
-
-/* connect response status codes */
-#define HTC_SERVICE_SUCCESS 0
-#define HTC_SERVICE_NOT_FOUND 1
-#define HTC_SERVICE_FAILED 2
-
-/* no resources (i.e. no more endpoints) */
-#define HTC_SERVICE_NO_RESOURCES 3
-
-/* specific service is not allowing any more endpoints */
-#define HTC_SERVICE_NO_MORE_EP 4
-
-/* report record IDs */
-#define HTC_RECORD_NULL 0
-#define HTC_RECORD_CREDITS 1
-#define HTC_RECORD_LOOKAHEAD 2
-#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
-
-#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
-
-#define MAKE_SERVICE_ID(group, index) \
- (int)(((int)group << 8) | (int)(index))
-
-/* NOTE: service ID of 0x0000 is reserved and should never be used */
-#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
-#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
-#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
-#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
-#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
-#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
-#define WMI_MAX_SERVICES 5
-
-#define WMM_NUM_AC 4
-
-/* reserved and used to flush ALL packets */
-#define HTC_TX_PACKET_TAG_ALL 0
-#define HTC_SERVICE_TX_PACKET_TAG 1
-#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9)
-
-/* more packets on this endpoint are being fetched */
-#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0)
-
-/* TODO.. for BMI */
-#define ENDPOINT1 0
-/* TODO -remove me, but we have to fix BMI first */
-#define HTC_MAILBOX_NUM_MAX 4
-
-/* enable send bundle padding for this endpoint */
-#define HTC_FLGS_TX_BNDL_PAD_EN (1 << 0)
-#define HTC_EP_ACTIVE ((u32) (1u << 31))
-
-/* HTC operational parameters */
-#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
-#define HTC_TARGET_DEBUG_INTR_MASK 0x01
-#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
-
-#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
-#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
-
-/* packet flags */
-
-#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
-#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
-#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
-#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
-
-#define NUM_CONTROL_BUFFERS 8
-#define NUM_CONTROL_TX_BUFFERS 2
-#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
-
-#define HTC_RECV_WAIT_BUFFERS (1 << 0)
-#define HTC_OP_STATE_STOPPING (1 << 0)
-
-/*
- * The frame header length and message formats defined herein were selected
- * to accommodate optimal alignment for target processing. This reduces
- * code size and improves performance. Any changes to the header length may
- * alter the alignment and cause exceptions on the target. When adding to
- * the messagestructures insure that fields are properly aligned.
- */
-
-/* HTC frame header
- *
- * NOTE: do not remove or re-arrange the fields, these are minimally
- * required to take advantage of 4-byte lookaheads in some hardware
- * implementations.
- */
-struct htc_frame_hdr {
- u8 eid;
- u8 flags;
-
- /* length of data (including trailer) that follows the header */
- __le16 payld_len;
-
- /* end of 4-byte lookahead */
-
- u8 ctrl[2];
-} __packed;
-
-/* HTC ready message */
-struct htc_ready_msg {
- __le16 msg_id;
- __le16 cred_cnt;
- __le16 cred_sz;
- u8 max_ep;
- u8 pad;
-} __packed;
-
-/* extended HTC ready message */
-struct htc_ready_ext_msg {
- struct htc_ready_msg ver2_0_info;
- u8 htc_ver;
- u8 msg_per_htc_bndl;
-} __packed;
-
-/* connect service */
-struct htc_conn_service_msg {
- __le16 msg_id;
- __le16 svc_id;
- __le16 conn_flags;
- u8 svc_meta_len;
- u8 pad;
-} __packed;
-
-/* connect response */
-struct htc_conn_service_resp {
- __le16 msg_id;
- __le16 svc_id;
- u8 status;
- u8 eid;
- __le16 max_msg_sz;
- u8 svc_meta_len;
- u8 pad;
-} __packed;
-
-struct htc_setup_comp_msg {
- __le16 msg_id;
-} __packed;
-
-/* extended setup completion message */
-struct htc_setup_comp_ext_msg {
- __le16 msg_id;
- __le32 flags;
- u8 msg_per_rxbndl;
- u8 Rsvd[3];
-} __packed;
-
-struct htc_record_hdr {
- u8 rec_id;
- u8 len;
-} __packed;
-
-struct htc_credit_report {
- u8 eid;
- u8 credits;
-} __packed;
-
-/*
- * NOTE: The lk_ahd array is guarded by a pre_valid
- * and Post Valid guard bytes. The pre_valid bytes must
- * equal the inverse of the post_valid byte.
- */
-struct htc_lookahead_report {
- u8 pre_valid;
- u8 lk_ahd[4];
- u8 post_valid;
-} __packed;
-
-struct htc_bundle_lkahd_rpt {
- u8 lk_ahd[4];
-} __packed;
-
-/* Current service IDs */
-
-enum htc_service_grp_ids {
- RSVD_SERVICE_GROUP = 0,
- WMI_SERVICE_GROUP = 1,
-
- HTC_TEST_GROUP = 254,
- HTC_SERVICE_GROUP_LAST = 255
-};
-
-/* ------ endpoint IDS ------ */
-
-enum htc_endpoint_id {
- ENDPOINT_UNUSED = -1,
- ENDPOINT_0 = 0,
- ENDPOINT_1 = 1,
- ENDPOINT_2 = 2,
- ENDPOINT_3,
- ENDPOINT_4,
- ENDPOINT_5,
- ENDPOINT_6,
- ENDPOINT_7,
- ENDPOINT_8,
- ENDPOINT_MAX,
-};
-
-struct htc_tx_packet_info {
- u16 tag;
- int cred_used;
- u8 flags;
- int seqno;
-};
-
-struct htc_rx_packet_info {
- u32 exp_hdr;
- u32 rx_flags;
- u32 indicat_flags;
-};
-
-struct htc_target;
-
-/* wrapper around endpoint-specific packets */
-struct htc_packet {
- struct list_head list;
-
- /* caller's per packet specific context */
- void *pkt_cntxt;
-
- /*
- * the true buffer start , the caller can store the real
- * buffer start here. In receive callbacks, the HTC layer
- * sets buf to the start of the payload past the header.
- * This field allows the caller to reset buf when it recycles
- * receive packets back to HTC.
- */
- u8 *buf_start;
-
- /*
- * Pointer to the start of the buffer. In the transmit
- * direction this points to the start of the payload. In the
- * receive direction, however, the buffer when queued up
- * points to the start of the HTC header but when returned
- * to the caller points to the start of the payload
- */
- u8 *buf;
- u32 buf_len;
-
- /* actual length of payload */
- u32 act_len;
-
- /* endpoint that this packet was sent/recv'd from */
- enum htc_endpoint_id endpoint;
-
- /* completion status */
-
- int status;
- union {
- struct htc_tx_packet_info tx;
- struct htc_rx_packet_info rx;
- } info;
-
- void (*completion) (struct htc_target *, struct htc_packet *);
- struct htc_target *context;
-};
-
-enum htc_send_full_action {
- HTC_SEND_FULL_KEEP = 0,
- HTC_SEND_FULL_DROP = 1,
-};
-
-struct htc_ep_callbacks {
- void (*rx) (struct htc_target *, struct htc_packet *);
- void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint);
- enum htc_send_full_action (*tx_full) (struct htc_target *,
- struct htc_packet *);
- struct htc_packet *(*rx_allocthresh) (struct htc_target *,
- enum htc_endpoint_id, int);
- int rx_alloc_thresh;
- int rx_refill_thresh;
-};
-
-/* service connection information */
-struct htc_service_connect_req {
- u16 svc_id;
- u16 conn_flags;
- struct htc_ep_callbacks ep_cb;
- int max_txq_depth;
- u32 flags;
- unsigned int max_rxmsg_sz;
-};
-
-/* service connection response information */
-struct htc_service_connect_resp {
- u8 buf_len;
- u8 act_len;
- enum htc_endpoint_id endpoint;
- unsigned int len_max;
- u8 resp_code;
-};
-
-/* endpoint distributionstructure */
-struct htc_endpoint_credit_dist {
- struct list_head list;
-
- /* Service ID (set by HTC) */
- u16 svc_id;
-
- /* endpoint for this distributionstruct (set by HTC) */
- enum htc_endpoint_id endpoint;
-
- u32 dist_flags;
-
- /*
- * credits for normal operation, anything above this
- * indicates the endpoint is over-subscribed.
- */
- int cred_norm;
-
- /* floor for credit distribution */
- int cred_min;
-
- int cred_assngd;
-
- /* current credits available */
- int credits;
-
- /*
- * pending credits to distribute on this endpoint, this
- * is set by HTC when credit reports arrive. The credit
- * distribution functions sets this to zero when it distributes
- * the credits.
- */
- int cred_to_dist;
-
- /*
- * the number of credits that the current pending TX packet needs
- * to transmit. This is set by HTC when endpoint needs credits in
- * order to transmit.
- */
- int seek_cred;
-
- /* size in bytes of each credit */
- int cred_sz;
-
- /* credits required for a maximum sized messages */
- int cred_per_msg;
-
- /* reserved for HTC use */
- struct htc_endpoint *htc_ep;
-
- /*
- * current depth of TX queue , i.e. messages waiting for credits
- * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
- * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
- * that has non-zero credits to recover.
- */
- int txq_depth;
-};
-
-/*
- * credit distibution code that is passed into the distrbution function,
- * there are mandatory and optional codes that must be handled
- */
-enum htc_credit_dist_reason {
- HTC_CREDIT_DIST_SEND_COMPLETE = 0,
- HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1,
- HTC_CREDIT_DIST_SEEK_CREDITS,
-};
-
-struct ath6kl_htc_credit_info {
- int total_avail_credits;
- int cur_free_credits;
-
- /* list of lowest priority endpoints */
- struct list_head lowestpri_ep_dist;
-};
-
-/* endpoint statistics */
-struct htc_endpoint_stats {
- /*
- * number of times the host set the credit-low flag in a send
- * message on this endpoint
- */
- u32 cred_low_indicate;
-
- u32 tx_issued;
- u32 tx_pkt_bundled;
- u32 tx_bundles;
- u32 tx_dropped;
-
- /* running count of total credit reports received for this endpoint */
- u32 tx_cred_rpt;
-
- /* credit reports received from this endpoint's RX packets */
- u32 cred_rpt_from_rx;
-
- /* credit reports received from RX packets of other endpoints */
- u32 cred_rpt_from_other;
-
- /* credit reports received from endpoint 0 RX packets */
- u32 cred_rpt_ep0;
-
- /* count of credits received via Rx packets on this endpoint */
- u32 cred_from_rx;
-
- /* count of credits received via another endpoint */
- u32 cred_from_other;
-
- /* count of credits received via another endpoint */
- u32 cred_from_ep0;
-
- /* count of consummed credits */
- u32 cred_cosumd;
-
- /* count of credits returned */
- u32 cred_retnd;
-
- u32 rx_pkts;
-
- /* count of lookahead records found in Rx msg */
- u32 rx_lkahds;
-
- /* count of recv packets received in a bundle */
- u32 rx_bundl;
-
- /* count of number of bundled lookaheads */
- u32 rx_bundle_lkahd;
-
- /* count of the number of bundle indications from the HTC header */
- u32 rx_bundle_from_hdr;
-
- /* the number of times the recv allocation threshold was hit */
- u32 rx_alloc_thresh_hit;
-
- /* total number of bytes */
- u32 rxalloc_thresh_byte;
-};
-
-struct htc_endpoint {
- enum htc_endpoint_id eid;
- u16 svc_id;
- struct list_head txq;
- struct list_head rx_bufq;
- struct htc_endpoint_credit_dist cred_dist;
- struct htc_ep_callbacks ep_cb;
- int max_txq_depth;
- int len_max;
- int tx_proc_cnt;
- int rx_proc_cnt;
- struct htc_target *target;
- u8 seqno;
- u32 conn_flags;
- struct htc_endpoint_stats ep_st;
-};
-
-struct htc_control_buffer {
- struct htc_packet packet;
- u8 *buf;
-};
-
-struct ath6kl_device;
-
-/* our HTC target state */
-struct htc_target {
- struct htc_endpoint endpoint[ENDPOINT_MAX];
-
- /* contains struct htc_endpoint_credit_dist */
- struct list_head cred_dist_list;
-
- struct list_head free_ctrl_txbuf;
- struct list_head free_ctrl_rxbuf;
- struct ath6kl_htc_credit_info *credit_info;
- int tgt_creds;
- unsigned int tgt_cred_sz;
- spinlock_t htc_lock;
- spinlock_t rx_lock;
- spinlock_t tx_lock;
- struct ath6kl_device *dev;
- u32 htc_flags;
- u32 rx_st_flags;
- enum htc_endpoint_id ep_waiting;
- u8 htc_tgt_ver;
-
- /* max messages per bundle for HTC */
- int msg_per_bndl_max;
-
- u32 tx_bndl_mask;
- int rx_bndl_enable;
- int max_rx_bndl_sz;
- int max_tx_bndl_sz;
-
- u32 block_sz;
- u32 block_mask;
-
- int max_scat_entries;
- int max_xfer_szper_scatreq;
-
- int chk_irq_status_cnt;
-
- /* counts the number of Tx without bundling continously per AC */
- u32 ac_tx_count[WMM_NUM_AC];
-};
-
-void *ath6kl_htc_create(struct ath6kl *ar);
-void ath6kl_htc_set_credit_dist(struct htc_target *target,
- struct ath6kl_htc_credit_info *cred_info,
- u16 svc_pri_order[], int len);
-int ath6kl_htc_wait_target(struct htc_target *target);
-int ath6kl_htc_start(struct htc_target *target);
-int ath6kl_htc_conn_service(struct htc_target *target,
- struct htc_service_connect_req *req,
- struct htc_service_connect_resp *resp);
-int ath6kl_htc_tx(struct htc_target *target, struct htc_packet *packet);
-void ath6kl_htc_stop(struct htc_target *target);
-void ath6kl_htc_cleanup(struct htc_target *target);
-void ath6kl_htc_flush_txep(struct htc_target *target,
- enum htc_endpoint_id endpoint, u16 tag);
-void ath6kl_htc_flush_rx_buf(struct htc_target *target);
-void ath6kl_htc_indicate_activity_change(struct htc_target *target,
- enum htc_endpoint_id endpoint,
- bool active);
-int ath6kl_htc_get_rxbuf_num(struct htc_target *target,
- enum htc_endpoint_id endpoint);
-int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
- struct list_head *pktq);
-int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
- u32 msg_look_ahead, int *n_pkts);
-
-int ath6kl_credit_setup(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info);
-
-static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
- u8 *buf, unsigned int len,
- enum htc_endpoint_id eid, u16 tag)
-{
- packet->pkt_cntxt = context;
- packet->buf = buf;
- packet->act_len = len;
- packet->endpoint = eid;
- packet->info.tx.tag = tag;
-}
-
-static inline void htc_rxpkt_reset(struct htc_packet *packet)
-{
- packet->buf = packet->buf_start;
- packet->act_len = 0;
-}
-
-static inline void set_htc_rxpkt_info(struct htc_packet *packet, void *context,
- u8 *buf, unsigned long len,
- enum htc_endpoint_id eid)
-{
- packet->pkt_cntxt = context;
- packet->buf = buf;
- packet->buf_start = buf;
- packet->buf_len = len;
- packet->endpoint = eid;
-}
-
-static inline int get_queue_depth(struct list_head *queue)
-{
- struct list_head *tmp_list;
- int depth = 0;
-
- list_for_each(tmp_list, queue)
- depth++;
-
- return depth;
-}
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
deleted file mode 100755
index ba587f9..0000000
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ /dev/null
@@ -1,2330 +0,0 @@
-
-/*
- * Copyright (c) 2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/moduleparam.h>
-#include <linux/errno.h>
-//#include <linux/of.h>
-#include <linux/mmc/sdio_func.h>
-#include "core.h"
-#include "cfg80211.h"
-#include "target.h"
-#include "debug.h"
-#include "hif-ops.h"
-#include "pm.h"
-#include <linux/vmalloc.h>
-
-unsigned int debug_mask = ATH6KL_DBG_WMI | ATH6KL_DBG_BOOT |
- ATH6KL_DBG_WLAN_CFG | ATH6KL_DBG_SUSPEND |
- ATH6KL_DBG_TRC;
-static unsigned int testmode;
-#ifdef CONFIG_MACH_PX
-/* WoW2 (deepsleep), Suspend (WoW) */
-static unsigned int suspend_mode = WLAN_POWER_STATE_WOW;
-static unsigned int wow_mode = WLAN_POWER_STATE_DEEP_SLEEP;
-#else
-static unsigned int suspend_mode;
-static unsigned int wow_mode;
-#endif
-static unsigned int uart_debug;
-#ifdef CONFIG_MACH_PX
-static unsigned int ar6k_clock = 26000000;
-#else
-static unsigned int ar6k_clock = 19200000;
-#endif
-
-#ifdef CONFIG_ATH6KL_LOCALE_USA
-static unsigned short reg_domain = 0x8348;
-#else
-static unsigned short reg_domain = 0xffff;
-#endif
-
-static unsigned short lrssi = 10;
-
-static unsigned short en_ani = 1;
-
-module_param(debug_mask, uint, 0644);
-module_param(testmode, uint, 0644);
-module_param(suspend_mode, uint, 0644);
-module_param(wow_mode, uint, 0644);
-module_param(uart_debug, uint, 0644);
-module_param(ar6k_clock, uint, 0644);
-module_param(reg_domain, ushort, 0644);
-module_param(lrssi, ushort, 0644);
-module_param(en_ani, ushort, 0644);
-
-
-static const struct ath6kl_hw hw_list[] = {
- {
- .id = AR6003_HW_2_0_VERSION,
- .name = "ar6003 hw 2.0",
- .dataset_patch_addr = 0x57e884,
- .app_load_addr = 0x543180,
- .board_ext_data_addr = 0x57e500,
- .reserved_ram_size = 6912,
- .refclk_hz = 26000000,
- .uarttx_pin = 8,
-
- /* hw2.0 needs override address hardcoded */
- .app_start_override_addr = 0x944C00,
-
- .fw = {
- .dir = AR6003_HW_2_0_FW_DIR,
- .otp = AR6003_HW_2_0_OTP_FILE,
- .fw = AR6003_HW_2_0_FIRMWARE_FILE,
- .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE,
- .patch = AR6003_HW_2_0_PATCH_FILE,
- },
-
- .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE,
- .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE,
- },
- {
- .id = AR6003_HW_2_1_1_VERSION,
- .name = "ar6003 hw 2.1.1",
- .dataset_patch_addr = 0x57ff74,
- .app_load_addr = 0x1234,
- .board_ext_data_addr = 0x542330,
- .reserved_ram_size = 512,
- .refclk_hz = 26000000,
- .uarttx_pin = 8,
- .testscript_addr = 0x57ef74,
-
- .fw = {
- .dir = AR6003_HW_2_1_1_FW_DIR,
- .otp = AR6003_HW_2_1_1_OTP_FILE,
- .fw = AR6003_HW_2_1_1_FIRMWARE_FILE,
- .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE,
- .patch = AR6003_HW_2_1_1_PATCH_FILE,
- .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE,
- .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE,
- },
-
- .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE,
- .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE,
- },
- {
- .id = AR6004_HW_1_0_VERSION,
- .name = "ar6004 hw 1.0",
- .dataset_patch_addr = 0x57e884,
- .app_load_addr = 0x1234,
- .board_ext_data_addr = 0x437000,
- .reserved_ram_size = 19456,
- .board_addr = 0x433900,
- .refclk_hz = 26000000,
- .uarttx_pin = 11,
-
- .fw = {
- .dir = AR6004_HW_1_0_FW_DIR,
- .fw = AR6004_HW_1_0_FIRMWARE_FILE,
- },
-
- .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE,
- .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE,
- },
- {
- .id = AR6004_HW_1_1_VERSION,
- .name = "ar6004 hw 1.1",
- .dataset_patch_addr = 0x57e884,
- .app_load_addr = 0x1234,
- .board_ext_data_addr = 0x437000,
- .reserved_ram_size = 11264,
- .board_addr = 0x43d400,
- .refclk_hz = 40000000,
- .uarttx_pin = 11,
-
- .fw = {
- .dir = AR6004_HW_1_1_FW_DIR,
- .fw = AR6004_HW_1_1_FIRMWARE_FILE,
- },
-
- .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE,
- .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE,
- },
-};
-
-/*
- * Include definitions here that can be used to tune the WLAN module
- * behavior. Different customers can tune the behavior as per their needs,
- * here.
- */
-
-/*
- * This configuration item enable/disable keepalive support.
- * Keepalive support: In the absence of any data traffic to AP, null
- * frames will be sent to the AP at periodic interval, to keep the association
- * active. This configuration item defines the periodic interval.
- * Use value of zero to disable keepalive support
- * Default: 60 seconds
- */
-#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
-
-/*
- * This configuration item sets the value of disconnect timeout
- * Firmware delays sending the disconnec event to the host for this
- * timeout after is gets disconnected from the current AP.
- * If the firmware successly roams within the disconnect timeout
- * it sends a new connect event
- */
-#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
-
-
-#define ATH6KL_DATA_OFFSET 64
-
-typedef char A_CHAR;
-extern int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length);
-
- /*
- * Number of bytes in board data that we are interested
- * in while setting regulatory domain from host
- */
-#define REG_DMN_BOARD_DATA_LEN 16
-
-/* Modifies regulatory domain in board data in target RAM */
-static int ath6kl_set_reg_dmn(struct ath6kl *ar)
-{
- u8 buf[REG_DMN_BOARD_DATA_LEN];
- __le16 old_sum, old_ver, old_rd, old_rd_next;
- __le32 brd_dat_addr = 0, new_sum, new_rd;
- int ret;
-
- ret = ath6kl_bmi_read(ar, AR6003_BOARD_DATA_ADDR,
- (u8 *)&brd_dat_addr, 4);
- if (ret)
- return ret;
-
- memset(buf, 0, sizeof(buf));
- ret = ath6kl_bmi_read(ar, brd_dat_addr, buf, sizeof(buf));
- if (ret)
- return ret;
-
- memcpy((u8 *)&old_sum, buf + AR6003_BOARD_DATA_OFFSET, 2);
- memcpy((u8 *)&old_ver, buf + AR6003_BOARD_DATA_OFFSET + 2, 2);
- memcpy((u8 *)&old_rd, buf + AR6003_RD_OFFSET, 2);
- memcpy((u8 *)&old_rd_next, buf + AR6003_RD_OFFSET + 2, 2);
-
- /*
- * Overwrite the new regulatory domain and preserve the
- * MAC addr which is in the same word.
- */
- new_rd = cpu_to_le32((le32_to_cpu(old_rd_next) << 16) + reg_domain);
- ret = ath6kl_bmi_write(ar,
- cpu_to_le32(le32_to_cpu(brd_dat_addr) + AR6003_RD_OFFSET),
- (u8 *)&new_rd, 4);
- if (ret)
- return ret;
-
- /*
- * Recompute the board data checksum with the new regulatory
- * domain, preserve the version information which is in the
- * same word.
- */
- new_sum = cpu_to_le32((le32_to_cpu(old_ver) << 16) +
- (le32_to_cpu(old_sum) ^ le32_to_cpu(old_rd) ^
- reg_domain));
- ret = ath6kl_bmi_write(ar,
- cpu_to_le32(le32_to_cpu(brd_dat_addr) +
- AR6003_BOARD_DATA_OFFSET),
- (u8 *)&new_sum, 4);
-
- return ret;
-}
-
-struct sk_buff *ath6kl_buf_alloc(int size)
-{
- struct sk_buff *skb;
- u16 reserved;
-
- /* Add chacheline space at front and back of buffer */
- reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
- sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
- skb = dev_alloc_skb(size + reserved);
-
- if (skb)
- skb_reserve(skb, reserved - L1_CACHE_BYTES);
- return skb;
-}
-
-void ath6kl_init_profile_info(struct ath6kl_vif *vif)
-{
- vif->ssid_len = 0;
- memset(vif->ssid, 0, sizeof(vif->ssid));
-
- vif->dot11_auth_mode = OPEN_AUTH;
- vif->auth_mode = NONE_AUTH;
- vif->prwise_crypto = NONE_CRYPT;
- vif->prwise_crypto_len = 0;
- vif->grp_crypto = NONE_CRYPT;
- vif->grp_crypto_len = 0;
- memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
- memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
- memset(vif->bssid, 0, sizeof(vif->bssid));
- vif->bss_ch = 0;
-}
-
-static int ath6kl_set_host_app_area(struct ath6kl *ar)
-{
- u32 address, data;
- struct host_app_area host_app_area;
-
- /* Fetch the address of the host_app_area_s
- * instance in the host interest area */
- address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
- address = TARG_VTOP(ar->target_type, address);
-
- if (ath6kl_diag_read32(ar, address, &data))
- return -EIO;
-
- address = TARG_VTOP(ar->target_type, data);
- host_app_area.wmi_protocol_ver = cpu_to_le32(WMI_PROTOCOL_VERSION);
- if (ath6kl_diag_write(ar, address, (u8 *) &host_app_area,
- sizeof(struct host_app_area)))
- return -EIO;
-
- return 0;
-}
-
-static inline void set_ac2_ep_map(struct ath6kl *ar,
- u8 ac,
- enum htc_endpoint_id ep)
-{
- ar->ac2ep_map[ac] = ep;
- ar->ep2ac_map[ep] = ac;
-}
-
-/* connect to a service */
-static int ath6kl_connectservice(struct ath6kl *ar,
- struct htc_service_connect_req *con_req,
- char *desc)
-{
- int status;
- struct htc_service_connect_resp response;
-
- memset(&response, 0, sizeof(response));
-
- status = ath6kl_htc_conn_service(ar->htc_target, con_req, &response);
- if (status) {
- ath6kl_err("failed to connect to %s service status:%d\n",
- desc, status);
- return status;
- }
-
- switch (con_req->svc_id) {
- case WMI_CONTROL_SVC:
- if (test_bit(WMI_ENABLED, &ar->flag))
- ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
- ar->ctrl_ep = response.endpoint;
- break;
- case WMI_DATA_BE_SVC:
- set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
- break;
- case WMI_DATA_BK_SVC:
- set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
- break;
- case WMI_DATA_VI_SVC:
- set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
- break;
- case WMI_DATA_VO_SVC:
- set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
- break;
- default:
- ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int ath6kl_init_service_ep(struct ath6kl *ar)
-{
- struct htc_service_connect_req connect;
-
- memset(&connect, 0, sizeof(connect));
-
- /* these fields are the same for all service endpoints */
- connect.ep_cb.rx = ath6kl_rx;
- connect.ep_cb.rx_refill = ath6kl_rx_refill;
- connect.ep_cb.tx_full = ath6kl_tx_queue_full;
-
- /*
- * Set the max queue depth so that our ath6kl_tx_queue_full handler
- * gets called.
- */
- connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
- connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
- if (!connect.ep_cb.rx_refill_thresh)
- connect.ep_cb.rx_refill_thresh++;
-
- /* connect to control service */
- connect.svc_id = WMI_CONTROL_SVC;
- if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
- return -EIO;
-
- connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
-
- /*
- * Limit the HTC message size on the send path, although e can
- * receive A-MSDU frames of 4K, we will only send ethernet-sized
- * (802.3) frames on the send path.
- */
- connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
-
- /*
- * To reduce the amount of committed memory for larger A_MSDU
- * frames, use the recv-alloc threshold mechanism for larger
- * packets.
- */
- connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
- connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
-
- /*
- * For the remaining data services set the connection flag to
- * reduce dribbling, if configured to do so.
- */
- connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
- connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
- connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
-
- connect.svc_id = WMI_DATA_BE_SVC;
-
- if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
- return -EIO;
-
- /* connect to back-ground map this to WMI LOW_PRI */
- connect.svc_id = WMI_DATA_BK_SVC;
- if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
- return -EIO;
-
- /* connect to Video service, map this to to HI PRI */
- connect.svc_id = WMI_DATA_VI_SVC;
- if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
- return -EIO;
-
- /*
- * Connect to VO service, this is currently not mapped to a WMI
- * priority stream due to historical reasons. WMI originally
- * defined 3 priorities over 3 mailboxes We can change this when
- * WMI is reworked so that priorities are not dependent on
- * mailboxes.
- */
- connect.svc_id = WMI_DATA_VO_SVC;
- if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
- return -EIO;
-
- return 0;
-}
-
-void ath6kl_init_control_info(struct ath6kl_vif *vif)
-{
- ath6kl_init_profile_info(vif);
- vif->def_txkey_index = 0;
- memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
- vif->ch_hint = 0;
-}
-
-/*
- * Set HTC/Mbox operational parameters, this can only be called when the
- * target is in the BMI phase.
- */
-static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
- u8 htc_ctrl_buf)
-{
- int status;
- u32 blk_size;
-
- blk_size = ar->mbox_info.block_size;
-
- if (htc_ctrl_buf)
- blk_size |= ((u32)htc_ctrl_buf) << 16;
-
- /* set the host interest area for the block size */
- status = ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_mbox_io_block_sz)),
- (u8 *)&blk_size,
- 4);
- if (status) {
- ath6kl_err("bmi_write_memory for IO block size failed\n");
- goto out;
- }
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
- blk_size,
- ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
-
- if (mbox_isr_yield_val) {
- /* set the host interest area for the mbox ISR yield limit */
- status = ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_mbox_isr_yield_limit)),
- (u8 *)&mbox_isr_yield_val,
- 4);
- if (status) {
- ath6kl_err("bmi_write_memory for yield limit failed\n");
- goto out;
- }
- }
-
-out:
- return status;
-}
-
-static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
-{
- int status = 0;
- int ret;
-#ifdef CONFIG_MACH_PX
- struct ath6kl_vif *vif = ath6kl_get_vif_by_index(ar, idx);
-#endif
- /*
- * Configure the device for rx dot11 header rules. "0,0" are the
- * default values. Required if checksum offload is needed. Set
- * RxMetaVersion to 2.
- */
- if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, idx,
- ar->rx_meta_ver, 0, 0)) {
- ath6kl_err("unable to set the rx frame format\n");
- status = -EIO;
- }
-
-
-#ifdef CONFIG_MACH_PX
- if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN) {
- if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx,
- 0, vif->pspoll_num, 0, 0, 1,
- IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
- ath6kl_err("unable to set power save fail event policy during scan\n");
- status = -EIO;
- }
- } else {
- if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0,
- vif->pspoll_num, 0, 0, 1, 0)) != 0) {
- ath6kl_err("unable to set pm params\n");
- status = -EIO;
- }
- }
-#else
- if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
- if ((ath6kl_wmi_pmparams_cmd(ar->wmi, idx, 0, 1, 0, 0, 1,
- IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
- ath6kl_err("unable to set power save fail event policy\n");
- status = -EIO;
- }
-#endif
-
-
- if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
- if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, idx, 0,
- WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
- ath6kl_err("unable to set barker preamble policy\n");
- status = -EIO;
- }
-
- if (ath6kl_wmi_set_keepalive_cmd(ar->wmi, idx,
- WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
- ath6kl_err("unable to set keep alive interval\n");
- status = -EIO;
- }
-
- if (ath6kl_wmi_disctimeout_cmd(ar->wmi, idx,
- WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
- ath6kl_err("unable to set disconnect timeout\n");
- status = -EIO;
- }
-
- if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
- if (ath6kl_wmi_set_wmm_txop(ar->wmi, idx, WMI_TXOP_DISABLED)) {
- ath6kl_err("unable to set txop bursting\n");
- status = -EIO;
- }
-
- if (ar->p2p && (ar->vif_max == 1 || idx)) {
- ret = ath6kl_wmi_info_req_cmd(ar->wmi, idx,
- P2P_FLAG_CAPABILITIES_REQ |
- P2P_FLAG_MACADDR_REQ |
- P2P_FLAG_HMODEL_REQ);
- if (ret) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "failed to request P2P "
- "capabilities (%d) - assuming P2P not "
- "supported\n", ret);
- ar->p2p = 0;
- }
- }
-
- if (ar->p2p && (ar->vif_max == 1 || idx)) {
- /* Enable Probe Request reporting for P2P */
- ret = ath6kl_wmi_probe_report_req_cmd(ar->wmi, idx, true);
- if (ret) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "failed to enable Probe "
- "Request reporting (%d)\n", ret);
- }
- }
-
-#ifdef CONFIG_MACH_PX
- if (vif->nw_type == INFRA_NETWORK) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "AR6K: bg scan interval = %d, active dwell time = %d, passive dwell time = %d\n",
- vif->scparams.bg_period,
- vif->scparams.maxact_chdwell_time,
- vif->scparams.pas_chdwell_time);
-
- ath6kl_wmi_scanparams_cmd(ar->wmi, idx,
- vif->scparams.fg_start_period,
- vif->scparams.fg_end_period, vif->scparams.bg_period,
- vif->scparams.minact_chdwell_time,
- vif->scparams.maxact_chdwell_time,
- vif->scparams.pas_chdwell_time,
- vif->scparams.short_scan_ratio,
- vif->scparams.scan_ctrl_flags,
- vif->scparams.max_dfsch_act_time,
- vif->scparams.maxact_scan_per_ssid);
-
- ath6kl_wmi_set_roam_lrssi_cmd(ar->wmi, lrssi);
- }
-#endif
- return status;
-}
-
-int ath6kl_configure_target(struct ath6kl *ar)
-{
- u32 param, ram_reserved_size;
- u8 fw_iftype, fw_mode = 0, fw_submode = 0;
- int i, status;
-
- param = uart_debug;
- if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_serial_enable)), (u8 *)&param, 4)) {
- ath6kl_err("bmi_write_memory for uart debug failed\n");
- return -EIO;
- }
-
- /*
- * Note: Even though the firmware interface type is
- * chosen as BSS_STA for all three interfaces, can
- * be configured to IBSS/AP as long as the fw submode
- * remains normal mode (0 - AP, STA and IBSS). But
- * due to an target assert in firmware only one interface is
- * configured for now.
- */
- fw_iftype = HI_OPTION_FW_MODE_BSS_STA;
-
- for (i = 0; i < ar->vif_max; i++)
- fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
-
- /*
- * By default, submodes :
- * vif[0] - AP/STA/IBSS
- * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
- * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
- */
-
- for (i = 0; i < ar->max_norm_iface; i++)
- fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
- (i * HI_OPTION_FW_SUBMODE_BITS);
-
- for (i = ar->max_norm_iface; i < ar->vif_max; i++)
- fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
- (i * HI_OPTION_FW_SUBMODE_BITS);
-
- if (ar->p2p && ar->vif_max == 1)
- fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
-
- param = HTC_PROTOCOL_VERSION;
- if (ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_app_host_interest)),
- (u8 *)&param, 4) != 0) {
- ath6kl_err("bmi_write_memory for htc version failed\n");
- return -EIO;
- }
-
- /* set the firmware mode to STA/IBSS/AP */
- param = 0;
-
- if (ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_option_flag)),
- (u8 *)&param, 4) != 0) {
- ath6kl_err("bmi_read_memory for setting fwmode failed\n");
- return -EIO;
- }
-
- param |= (ar->vif_max << HI_OPTION_NUM_DEV_SHIFT);
- param |= fw_mode << HI_OPTION_FW_MODE_SHIFT;
- param |= fw_submode << HI_OPTION_FW_SUBMODE_SHIFT;
-
- param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
- param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
-
- if (ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_option_flag)),
- (u8 *)&param,
- 4) != 0) {
- ath6kl_err("bmi_write_memory for setting fwmode failed\n");
- return -EIO;
- }
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
-
- /*
- * Hardcode the address use for the extended board data
- * Ideally this should be pre-allocate by the OS at boot time
- * But since it is a new feature and board data is loaded
- * at init time, we have to workaround this from host.
- * It is difficult to patch the firmware boot code,
- * but possible in theory.
- */
-
- param = ar->hw.board_ext_data_addr;
- ram_reserved_size = ar->hw.reserved_ram_size;
-
- if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_ext_data)),
- (u8 *)&param, 4) != 0) {
- ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
- return -EIO;
- }
-
- if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_end_ram_reserve_sz)),
- (u8 *)&ram_reserved_size, 4) != 0) {
- ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
- return -EIO;
- }
-
- /* set the block size for the target */
- if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
- /* use default number of control buffers */
- return -EIO;
-
- /* Configure GPIO AR600x UART */
- param = ar->hw.uarttx_pin;
- status = ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_dbg_uart_txpin)),
- (u8 *)&param, 4);
- if (status)
- return status;
-
- /* Configure target refclk_hz */
- param = ar->hw.refclk_hz;
- status = ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_refclk_hz)),
- (u8 *)&param, 4);
- if (status)
- return status;
-
- return 0;
-}
-
-void ath6kl_core_free(struct ath6kl *ar)
-{
- wiphy_free(ar->wiphy);
-}
-
-void ath6kl_core_cleanup(struct ath6kl *ar)
-{
- ath6kl_hif_power_off(ar);
-
- destroy_workqueue(ar->ath6kl_wq);
-
- if (ar->htc_target)
- ath6kl_htc_cleanup(ar->htc_target);
-
- ath6kl_cookie_cleanup(ar);
-
- ath6kl_cleanup_amsdu_rxbufs(ar);
-
- ath6kl_bmi_cleanup(ar);
-
- ath6kl_debug_cleanup(ar);
-
- vfree(ar->fw_board);
- vfree(ar->fw_otp);
- vfree(ar->fw);
- vfree(ar->fw_patch);
- vfree(ar->fw_testscript);
-
- ath6kl_deinit_ieee80211_hw(ar);
-}
-
-/* firmware upload */
-static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
- u8 **fw, size_t *fw_len)
-{
- const struct firmware *fw_entry;
- int ret;
-
- ret = request_firmware(&fw_entry, filename, ar->dev);
- if (ret)
- return ret;
-
- *fw_len = fw_entry->size;
- *fw = vmalloc(fw_entry->size);
-
- if (*fw == NULL)
- ret = -ENOMEM;
-
- memcpy(*fw, fw_entry->data, fw_entry->size);
-
- release_firmware(fw_entry);
-
- return ret;
-}
-
-#if 0
-#ifdef CONFIG_OF
-/*
- * Check the device tree for a board-id and use it to construct
- * the pathname to the firmware file. Used (for now) to find a
- * fallback to the "bdata.bin" file--typically a symlink to the
- * appropriate board-specific file.
- */
-static bool check_device_tree(struct ath6kl *ar)
-{
- static const char *board_id_prop = "atheros,board-id";
- struct device_node *node;
- char board_filename[64];
- const char *board_id;
- int ret;
-
- for_each_compatible_node(node, NULL, "atheros,ath6kl") {
- board_id = of_get_property(node, board_id_prop, NULL);
- if (board_id == NULL) {
- ath6kl_warn("No \"%s\" property on %s node.\n",
- board_id_prop, node->name);
- continue;
- }
- snprintf(board_filename, sizeof(board_filename),
- "%s/bdata.%s.bin", ar->hw.fw.dir, board_id);
-
- ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board,
- &ar->fw_board_len);
- if (ret) {
- ath6kl_err("Failed to get DT board file %s: %d\n",
- board_filename, ret);
- continue;
- }
- return true;
- }
- return false;
-}
-#else
-static bool check_device_tree(struct ath6kl *ar)
-{
- return false;
-}
-#endif /* CONFIG_OF */
-#endif
-static int ath6kl_fetch_board_file(struct ath6kl *ar)
-{
- const char *filename;
- int ret;
-
- if (ar->fw_board != NULL)
- return 0;
-
- if (WARN_ON(ar->hw.fw_board == NULL))
- return -EINVAL;
-
- filename = ar->hw.fw_board;
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
- &ar->fw_board_len);
- if (ret == 0) {
- /* managed to get proper board file */
- return 0;
- }
-#if 0
- if (check_device_tree(ar)) {
- /* got board file from device tree */
- return 0;
- }
-#endif
- /* there was no proper board file, try to use default instead */
- ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
- filename, ret);
-
- filename = ar->hw.fw_default_board;
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
- &ar->fw_board_len);
- if (ret) {
- ath6kl_err("Failed to get default board file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
- ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
-
- return 0;
-}
-
-static int ath6kl_fetch_otp_file(struct ath6kl *ar)
-{
- char filename[100];
- int ret;
-
- if (ar->fw_otp != NULL)
- return 0;
-
- if (ar->hw.fw.otp == NULL) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "no OTP file configured for this hw\n");
- return 0;
- }
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.otp);
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
- &ar->fw_otp_len);
- if (ret) {
- ath6kl_err("Failed to get OTP file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_testmode_file(struct ath6kl *ar)
-{
- char filename[100];
- int ret;
-
- if (testmode == 0)
- return 0;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", testmode);
-
- if (testmode == 2) {
- if (ar->hw.fw.utf == NULL) {
- ath6kl_warn("testmode 2 not supported\n");
- return -EOPNOTSUPP;
- }
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.utf);
- } else {
- if (ar->hw.fw.tcmd == NULL) {
- ath6kl_warn("testmode 1 not supported\n");
- return -EOPNOTSUPP;
- }
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.tcmd);
- }
-
- set_bit(TESTMODE, &ar->flag);
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
- if (ret) {
- ath6kl_err("Failed to get testmode %d firmware file %s: %d\n",
- testmode, filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_file(struct ath6kl *ar)
-{
- char filename[100];
- int ret;
-
- if (ar->fw != NULL)
- return 0;
-
- /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */
- if (WARN_ON(ar->hw.fw.fw == NULL))
- return -EINVAL;
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.fw);
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
- if (ret) {
- ath6kl_err("Failed to get firmware file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_patch_file(struct ath6kl *ar)
-{
- char filename[100];
- int ret;
-
- if (ar->fw_patch != NULL)
- return 0;
-
- if (ar->hw.fw.patch == NULL)
- return 0;
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.patch);
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
- &ar->fw_patch_len);
- if (ret) {
- ath6kl_err("Failed to get patch file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_testscript_file(struct ath6kl *ar)
-{
- char filename[100];
- int ret;
-
- if (testmode != 2)
- return 0;
-
- if (ar->fw_testscript != NULL)
- return 0;
-
- if (ar->hw.fw.testscript == NULL)
- return 0;
-
- snprintf(filename, sizeof(filename), "%s/%s",
- ar->hw.fw.dir, ar->hw.fw.testscript);
-
- ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript,
- &ar->fw_testscript_len);
- if (ret) {
- ath6kl_err("Failed to get testscript file %s: %d\n",
- filename, ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_api1(struct ath6kl *ar)
-{
- int ret;
-
- ret = ath6kl_fetch_otp_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_fw_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_patch_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_testscript_file(ar);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
-{
- size_t magic_len, len, ie_len;
- const struct firmware *fw;
- struct ath6kl_fw_ie *hdr;
- char filename[100];
- const u8 *data;
- int ret, ie_id, i, index, bit;
- __le32 *val;
-
- snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
-
- ret = request_firmware(&fw, filename, ar->dev);
- if (ret)
- return ret;
-
- data = fw->data;
- len = fw->size;
-
- /* magic also includes the null byte, check that as well */
- magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
-
- if (len < magic_len) {
- ret = -EINVAL;
- goto out;
- }
-
- if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
- ret = -EINVAL;
- goto out;
- }
-
- len -= magic_len;
- data += magic_len;
-
- /* loop elements */
- while (len > sizeof(struct ath6kl_fw_ie)) {
- /* hdr is unaligned! */
- hdr = (struct ath6kl_fw_ie *) data;
-
- ie_id = le32_to_cpup(&hdr->id);
- ie_len = le32_to_cpup(&hdr->len);
-
- len -= sizeof(*hdr);
- data += sizeof(*hdr);
-
- if (len < ie_len) {
- ret = -EINVAL;
- goto out;
- }
-
- switch (ie_id) {
- case ATH6KL_FW_IE_OTP_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n",
- ie_len);
-
- ar->fw_otp = vmalloc(ie_len);
-
- if (ar->fw_otp == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(ar->fw_otp, data, ie_len);
- ar->fw_otp_len = ie_len;
- break;
- case ATH6KL_FW_IE_FW_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n",
- ie_len);
-
- /* in testmode we already might have a fw file */
- if (ar->fw != NULL)
- break;
-
- ar->fw = vmalloc(ie_len);
-
- if (ar->fw == NULL) {
- ret = -ENOMEM;
- goto out;
-
- }
- memcpy(ar->fw, data, ie_len);
- ar->fw_len = ie_len;
- break;
- case ATH6KL_FW_IE_PATCH_IMAGE:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "found patch image ie (%zd B)\n",
- ie_len);
-
- ar->fw_patch = vmalloc(ie_len);
-
- if (ar->fw_patch == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(ar->fw_patch, data, ie_len);
- ar->fw_patch_len = ie_len;
- break;
- case ATH6KL_FW_IE_RESERVED_RAM_SIZE:
- val = (__le32 *) data;
- ar->hw.reserved_ram_size = le32_to_cpup(val);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found reserved ram size ie 0x%d\n",
- ar->hw.reserved_ram_size);
- break;
- case ATH6KL_FW_IE_CAPABILITIES:
- if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8))
- break;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found firmware capabilities ie (%zd B)\n",
- ie_len);
-
- for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
- index = i / 8;
- bit = i % 8;
-
- if (data[index] & (1 << bit))
- __set_bit(i, ar->fw_capabilities);
- }
-
- ath6kl_dbg_dump(ATH6KL_DBG_BOOT, "capabilities", "",
- ar->fw_capabilities,
- sizeof(ar->fw_capabilities));
- break;
- case ATH6KL_FW_IE_PATCH_ADDR:
- if (ie_len != sizeof(*val))
- break;
-
- val = (__le32 *) data;
- ar->hw.dataset_patch_addr = le32_to_cpup(val);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found patch address ie 0x%x\n",
- ar->hw.dataset_patch_addr);
- break;
- case ATH6KL_FW_IE_BOARD_ADDR:
- if (ie_len != sizeof(*val))
- break;
-
- val = (__le32 *) data;
- ar->hw.board_addr = le32_to_cpup(val);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found board address ie 0x%x\n",
- ar->hw.board_addr);
- break;
- case ATH6KL_FW_IE_VIF_MAX:
- if (ie_len != sizeof(*val))
- break;
-
- val = (__le32 *) data;
- ar->vif_max = min_t(unsigned int, le32_to_cpup(val),
- ATH6KL_VIF_MAX);
-
- if (ar->vif_max > 1 && !ar->p2p)
- ar->max_norm_iface = 2;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "found vif max ie %d\n", ar->vif_max);
- break;
- default:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "Unknown fw ie: %u\n",
- le32_to_cpup(&hdr->id));
- break;
- }
-
- len -= ie_len;
- data += ie_len;
- };
-
- ret = 0;
-out:
- release_firmware(fw);
-
- return ret;
-}
-
-static int ath6kl_fetch_firmwares(struct ath6kl *ar)
-{
- int ret;
-
-#ifdef CONFIG_MACH_PX
- if (testmode)
- ar->hw.fw_board = AR6003_HW_2_1_1_TCMD_BOARD_DATA_FILE;
-#endif
-
- ret = ath6kl_fetch_board_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_testmode_file(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE);
- if (ret == 0) {
- ar->fw_api = 3;
- goto out;
- }
-
- ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE);
- if (ret == 0) {
- ar->fw_api = 2;
- goto out;
- }
-
- ret = ath6kl_fetch_fw_api1(ar);
- if (ret)
- return ret;
-
- ar->fw_api = 1;
-
-out:
- ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api);
-
- return 0;
-}
-
-static int ath6kl_upload_board_file(struct ath6kl *ar)
-{
- u32 board_address, board_ext_address, param;
- u32 board_data_size, board_ext_data_size;
- int ret;
-
- if (WARN_ON(ar->fw_board == NULL))
- return -ENOENT;
-
- /*
- * Determine where in Target RAM to write Board Data.
- * For AR6004, host determine Target RAM address for
- * writing board data.
- */
- if (ar->hw.board_addr != 0) {
- board_address = ar->hw.board_addr;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_data)),
- (u8 *) &board_address, 4);
- } else {
- ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_data)),
- (u8 *) &board_address, 4);
- }
-
- /* determine where in target ram to write extended board data */
- ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_ext_data)),
- (u8 *) &board_ext_address, 4);
-
- if (ar->target_type == TARGET_TYPE_AR6003 &&
- board_ext_address == 0) {
- ath6kl_err("Failed to get board file target address.\n");
- return -EINVAL;
- }
-
- switch (ar->target_type) {
- case TARGET_TYPE_AR6003:
- board_data_size = AR6003_BOARD_DATA_SZ;
- board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ;
- if (ar->fw_board_len > (board_data_size + board_ext_data_size))
- board_ext_data_size = AR6003_BOARD_EXT_DATA_SZ_V2;
- break;
- case TARGET_TYPE_AR6004:
- board_data_size = AR6004_BOARD_DATA_SZ;
- board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ;
- break;
- default:
- WARN_ON(1);
- return -EINVAL;
- break;
- }
-
- if (board_ext_address &&
- ar->fw_board_len == (board_data_size + board_ext_data_size)) {
-
- /* write extended board data */
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "writing extended board data to 0x%x (%d B)\n",
- board_ext_address, board_ext_data_size);
-
- ret = ath6kl_bmi_write(ar, board_ext_address,
- ar->fw_board + board_data_size,
- board_ext_data_size);
- if (ret) {
- ath6kl_err("Failed to write extended board data: %d\n",
- ret);
- return ret;
- }
-
- /* record that extended board data is initialized */
- param = (board_ext_data_size << 16) | 1;
-
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_ext_data_config)),
- (unsigned char *) &param, 4);
- }
-
- if (ar->fw_board_len < board_data_size) {
- ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
- ret = -EINVAL;
- return ret;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing board file to 0x%x (%d B)\n",
- board_address, board_data_size);
-
- ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
- board_data_size);
-
- if (ret) {
- ath6kl_err("Board file bmi write failed: %d\n", ret);
- return ret;
- }
-
- /* record the fact that Board Data IS initialized */
- param = 1;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_board_data_initialized)),
- (u8 *)&param, 4);
-
- return ret;
-}
-
-static int ath6kl_upload_otp(struct ath6kl *ar)
-{
- u32 address, param;
- bool from_hw = false;
- int ret;
-
- if (ar->fw_otp == NULL)
- return 0;
-
- address = ar->hw.app_load_addr;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing otp to 0x%x (%zd B)\n", address,
- ar->fw_otp_len);
-
- ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
- ar->fw_otp_len);
- if (ret) {
- ath6kl_err("Failed to upload OTP file: %d\n", ret);
- return ret;
- }
-
- /* read firmware start address */
- ret = ath6kl_bmi_read(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_app_start)),
- (u8 *) &address, sizeof(address));
-
- if (ret) {
- ath6kl_err("Failed to read hi_app_start: %d\n", ret);
- return ret;
- }
-
- if (ar->hw.app_start_override_addr == 0) {
- ar->hw.app_start_override_addr = address;
- from_hw = true;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "app_start_override_addr%s 0x%x\n",
- from_hw ? " (from hw)" : "",
- ar->hw.app_start_override_addr);
-
- /* execute the OTP code */
- ath6kl_dbg(ATH6KL_DBG_BOOT, "executing OTP at 0x%x\n",
- ar->hw.app_start_override_addr);
-
-#ifdef CONFIG_MACH_PX
- /* SOFTMAC has higher priority than OTP MAC */
- param = 1;
-#else
- param = 0;
-#endif
-
- ath6kl_bmi_execute(ar, ar->hw.app_start_override_addr, &param);
-
- return ret;
-}
-
-static int ath6kl_upload_firmware(struct ath6kl *ar)
-{
- u32 address;
- int ret;
-
- if (WARN_ON(ar->fw == NULL))
- return 0;
-
- address = ar->hw.app_load_addr;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing firmware to 0x%x (%zd B)\n",
- address, ar->fw_len);
-
- ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
-
- if (ret) {
- ath6kl_err("Failed to write firmware: %d\n", ret);
- return ret;
- }
-
- /*
- * Set starting address for firmware
- * Don't need to setup app_start override addr on AR6004
- */
- if (ar->target_type != TARGET_TYPE_AR6004) {
- address = ar->hw.app_start_override_addr;
- ath6kl_bmi_set_app_start(ar, address);
- }
- return ret;
-}
-
-static int ath6kl_upload_patch(struct ath6kl *ar)
-{
- u32 address, param;
- int ret;
-
- if (ar->fw_patch == NULL)
- return 0;
-
- address = ar->hw.dataset_patch_addr;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing patch to 0x%x (%zd B)\n",
- address, ar->fw_patch_len);
-
- ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
- if (ret) {
- ath6kl_err("Failed to write patch file: %d\n", ret);
- return ret;
- }
-
- param = address;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_dset_list_head)),
- (unsigned char *) &param, 4);
-
- return 0;
-}
-
-static int ath6kl_upload_testscript(struct ath6kl *ar)
-{
- u32 address, param;
- int ret;
-
- if (testmode != 2)
- return 0;
-
- if (ar->fw_testscript == NULL)
- return 0;
-
- address = ar->hw.testscript_addr;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n",
- address, ar->fw_testscript_len);
-
- ret = ath6kl_bmi_write(ar, address, ar->fw_testscript,
- ar->fw_testscript_len);
- if (ret) {
- ath6kl_err("Failed to write testscript file: %d\n", ret);
- return ret;
- }
-
- param = address;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_ota_testscript)),
- (unsigned char *) &param, 4);
-
- param = 4096;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_end_ram_reserve_sz)),
- (unsigned char *) &param, 4);
-
- param = 1;
- ath6kl_bmi_write(ar,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_test_apps_related)),
- (unsigned char *) &param, 4);
-
- return 0;
-}
-
-#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
-#define COUNTRY_MAX 76
-struct channels {
- char country[30];
- char ccode[6];
- unsigned short reg_dmn_code;
-}
-pArray[COUNTRY_MAX] = {
- {"Afghanistan", "AF 0", 0x406a},
- {"Albania", "AL 0", 0x8008},
- {"Algeria", "DZ 0", 0x800c},
- {"Angola", "AD 0", 0x406a},
- {"Austria", "AT 0", 0x8028},
- {"Australia", "AU 0", 0x8024},
- {"Bangladesh", "BD 0", 0x8032},
- {"Belgium", "BE 0", 0x8038},
- {"Bosnia", "BA 0", 0x8046},
- {"Bulgaria", "BG 0", 0x8064},
- {"Croatia", "HR 0", 0x80bf},
- {"Greece", "GR 0", 0x812c},
- {"Czech Republic", "CZ 0", 0x80cb},
- {"Egypt", "EG 0", 0x8332},
- {"Nordic", "FI 0", 0x80f6},
- {"Finland", "FI 0", 0x80f6},
- {"France", "FR 0", 0x80FA},
- {"Gabon", "GA 0", 0x406a},
- {"Germany", "DE 0", 0x8114},
- {"Ghana", "GH 0", 0x406a},
- {"Greece", "GR 0", 0x812c},
- {"Hungary", "HU 0", 0x815c},
- {"Iceland", "IS 0", 0x8160},
- {"India", "IN 0", 0x8164},
- {"Indonesia", "ID 0", 0x8168},
- {"Iraq", "IQ 0", 0x406a},
- {"IE", "IE 0", 0x8174},
- {"Ireland", "IE 0", 0x8174},
- {"Israel", "IL 0", 0x8178},
- {"Italy", "IT 0", 0x817c},
- {"Jamaica", "JM 0", 0x8184},
- {"Jordan", "JO 0", 0x8190},
- {"Central Asia", "KZ 0", 0x818e},
- {"Kazakhstan", "KZ 0", 0x818e},
- {"Kenya", "KE 0", 0x8198},
- {"BALTIC", "LV 0", 0x81ac},
- {"Libya", "LY 0", 0x406a},
- {"Lithuania", "LT 0", 0x81b8},
- {"Luxemburg", "LU 0", 0x81ba},
- {"Macedonia", "MK 0", 0x8327},
- {"Malaysia", "MY 0", 0x81ca},
- {"Mongolia", "MN 0", 0x406a},
- {"Montenegro", "ME 0", 0x837b},
- {"Morocco", "MA 0", 0x81f8},
- {"Nepal", "NP 0", 0x820c},
- {"Netherlands", "NL 0", 0x8210},
- {"The Netherlands", "NL 0", 0x8210},
- {"New Zealand", "NZ 0", 0x822a},
- {"Nigeria", "NG 0", 0x406a},
- {"Norway", "NO 0", 0x8242},
- {"Pakistan", "PK 0", 0x824a},
- {"Philippines", "PH 0", 0x8260},
- {"Poland", "PL 0", 0x8268},
- {"Portugal", "PT 0", 0x826c},
- {"Romania", "RO 0", 0x8282},
- {"Russia", "RU 0", 0x8283},
- {"KSA", "SA 0", 0x82aa},
- {"Senegal", "SN 0", 0x406a},
- {"Serbia", "RS 0", 0x8114},
- {"Singapore", "SG 0", 0x82be},
- {"Slovakia", "SK 0", 0x82bf},
- {"Slovenia", "SI 0", 0x82c1},
- {"South Africa", "ZA 0", 0x82c6},
- {"Spain", "ES 0", 0x82D4},
- {"Sri Lanka", "LK 0", 0x8090},
- {"Sweden", "SE 0", 0x82f0},
- {"Switzerland", "CH 0", 0x82f4},
- {"Thailand", "TH 0", 0x82fc},
- {"Tunisia", "TN 0", 0x8314},
- {"Turkey", "TR 0", 0x8318},
- {"Ukraine", "UA 0", 0x8324},
- {"UK", "GB 0", 0x833A},
- {"UK &IRE", "GB 0", 0x833A},
- {"United Kingdom", "GB 0", 0x833A},
- {"Uzbekistan", "UZ 0", 0x835c},
- {"Vietnam", "VN 0", 0x82c0}
-};
-
-static unsigned short ath6kl_get_reg_dmn_code(u8 *ccode)
-{
- int i = 0;
-
- for (i = 0; i < COUNTRY_MAX; i++) {
- if (strncmp(ccode, pArray[i].ccode, 2) == 0) {
- ath6kl_dbg(ATH6KL_DBG_BOOT, "%s: %s %s 0x%x",
- __func__, pArray[i].country, pArray[i].ccode,
- pArray[i].reg_dmn_code);
- return pArray[i].reg_dmn_code;
- }
- }
-
- ath6kl_err("%s() Failed to find reg_domain code for %s\n",
- __func__, ccode);
-
- return 0xffff;
-}
-
-static void ath6kl_update_ccodeinfo(struct ath6kl *ar)
-{
- char ccode_filename[32];
-
- do {
- int ret = 0;
- size_t length;
- u8 *pdata = NULL;
-
- snprintf(ccode_filename, sizeof(ccode_filename),
- "/data/.ccode.info");
-
- ret = android_readwrite_file(ccode_filename, NULL, NULL, 0);
-
- if (ret < 0)
- break;
- else
- length = ret;
-
- pdata = vmalloc(length + 1);
-
- if (!pdata) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Cannot allocate buffer for ccode_info (%d)\n",
- __func__, length);
- break;
- }
-
- if (android_readwrite_file(ccode_filename,
- (char *)pdata, NULL, length) != length) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: file read error, length %d\n",
- __func__, length);
- vfree(pdata);
- break;
- }
- pdata[length] = '\0';
-
- if (reg_domain == 0xffff)
- reg_domain = ath6kl_get_reg_dmn_code(pdata);
-
-
- vfree(pdata);
- } while (0);
-}
-#endif
-
-static void ath6kl_update_psminfo(struct ath6kl *ar)
-{
- char psm_filename[32];
- ar->psminfo = 1;
-
- do {
- int ret = 0;
- size_t length;
- u8 *pdata = NULL;
-
- snprintf(psm_filename, sizeof(psm_filename), "/data/.psm.info");
-
- ret = android_readwrite_file(psm_filename, NULL, NULL, 0);
-
- if (ret < 0)
- break;
- else
- length = ret;
-
- pdata = vmalloc(length);
-
- if (!pdata) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Cannot allocate buffer for psm_info (%d)\n",
- __func__, length);
- break;
- }
-
- if (android_readwrite_file(psm_filename,
- (char *)pdata, NULL, length) != length) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: file read error, length %d\n",
- __func__, length);
- vfree(pdata);
- break;
- }
-
- ar->psminfo = *pdata - '0';
- ath6kl_dbg(ATH6KL_DBG_BOOT,"%s: psm_info is %d\n", __FUNCTION__, ar->psminfo);
- vfree(pdata);
- } while (0);
-}
-
-static int ath6kl_init_upload(struct ath6kl *ar)
-{
- u32 param, options, sleep, address;
- int status = 0;
-
- if (ar->target_type != TARGET_TYPE_AR6003 &&
- ar->target_type != TARGET_TYPE_AR6004)
- return -EINVAL;
-
- /* temporarily disable system sleep */
- address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
- status = ath6kl_bmi_reg_read(ar, address, &param);
- if (status)
- return status;
-
- options = param;
-
- param |= ATH6KL_OPTION_SLEEP_DISABLE;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
- status = ath6kl_bmi_reg_read(ar, address, &param);
- if (status)
- return status;
-
- sleep = param;
-
- param |= SM(SYSTEM_SLEEP_DISABLE, 1);
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
- options, sleep);
-
- /* program analog PLL register */
- /* no need to control 40/44MHz clock on AR6004 */
- if (ar->target_type != TARGET_TYPE_AR6004) {
- status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
- 0xF9104001);
-
- if (status)
- return status;
-
- /* Run at 80/88MHz by default */
- param = SM(CPU_CLOCK_STANDARD, 1);
-
- address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
- }
-
- param = 0;
- address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
- param = SM(LPO_CAL_ENABLE, 1);
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- /* WAR to avoid SDIO CRC err */
- if (ar->version.target_ver == AR6003_HW_2_0_VERSION ||
- ar->version.target_ver == AR6003_HW_2_1_1_VERSION) {
- ath6kl_err("temporary war to avoid sdio crc error\n");
-
- param = 0x20;
-
- address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
- }
-
- ath6kl_bmi_init(ar);
- ath6kl_bmi_reg_write(ar, 0x540678, ar6k_clock);
-
- /* write EEPROM data to Target RAM */
- status = ath6kl_upload_board_file(ar);
- if (status)
- return status;
-
- /* transfer One time Programmable data */
- status = ath6kl_upload_otp(ar);
- if (status)
- return status;
-
- /* Download Target firmware */
- status = ath6kl_upload_firmware(ar);
- if (status)
- return status;
-
- status = ath6kl_upload_patch(ar);
- if (status)
- return status;
-
- /* Download the test script */
- status = ath6kl_upload_testscript(ar);
- if (status)
- return status;
-
- /* Restore system sleep */
- address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
- status = ath6kl_bmi_reg_write(ar, address, sleep);
- if (status)
- return status;
-
- address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
-
- if (en_ani)
- param = options & ~0x20;
- else
- param = options | 0x20;
-
- status = ath6kl_bmi_reg_write(ar, address, param);
- if (status)
- return status;
-
- return status;
-}
-
-static int ath6kl_init_hw_params(struct ath6kl *ar)
-{
- const struct ath6kl_hw *hw;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
- hw = &hw_list[i];
-
- if (hw->id == ar->version.target_ver)
- break;
- }
-
- if (i == ARRAY_SIZE(hw_list)) {
- ath6kl_err("Unsupported hardware version: 0x%x\n",
- ar->version.target_ver);
- return -EINVAL;
- }
-
- ar->hw = *hw;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "target_ver 0x%x target_type 0x%x dataset_patch 0x%x app_load_addr 0x%x\n",
- ar->version.target_ver, ar->target_type,
- ar->hw.dataset_patch_addr, ar->hw.app_load_addr);
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "app_start_override_addr 0x%x board_ext_data_addr 0x%x reserved_ram_size 0x%x",
- ar->hw.app_start_override_addr, ar->hw.board_ext_data_addr,
- ar->hw.reserved_ram_size);
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "refclk_hz %d uarttx_pin %d",
- ar->hw.refclk_hz, ar->hw.uarttx_pin);
-
- return 0;
-}
-
-static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
-{
- switch (type) {
- case ATH6KL_HIF_TYPE_SDIO:
- return "sdio";
- case ATH6KL_HIF_TYPE_USB:
- return "usb";
- }
-
- return NULL;
-}
-
-int ath6kl_init_hw_start(struct ath6kl *ar)
-{
- long timeleft;
- int ret, i;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
-
- ret = ath6kl_hif_power_on(ar);
- if (ret)
- return ret;
-
- ret = ath6kl_configure_target(ar);
- if (ret)
- goto err_power_off;
-
- ret = ath6kl_init_upload(ar);
- if (ret)
- goto err_power_off;
-
- if (reg_domain != 0xffff) {
- ret = ath6kl_set_reg_dmn(ar);
- if (ret)
- goto err_power_off;
- }
-
- /* Do we need to finish the BMI phase */
- /* FIXME: return error from ath6kl_bmi_done() */
- if (ath6kl_bmi_done(ar)) {
- ret = -EIO;
- goto err_power_off;
- }
-
- /*
- * The reason we have to wait for the target here is that the
- * driver layer has to init BMI in order to set the host block
- * size.
- */
- if (ath6kl_htc_wait_target(ar->htc_target)) {
- ret = -EIO;
- goto err_power_off;
- }
-
- if (ath6kl_init_service_ep(ar)) {
- ret = -EIO;
- goto err_cleanup_scatter;
- }
-
- /* setup credit distribution */
- ath6kl_credit_setup(ar->htc_target, &ar->credit_state_info);
-
- /* start HTC */
- ret = ath6kl_htc_start(ar->htc_target);
- if (ret) {
- /* FIXME: call this */
- ath6kl_cookie_cleanup(ar);
- goto err_cleanup_scatter;
- }
-
- /* Wait for Wmi event to be ready */
- timeleft = wait_event_interruptible_timeout(ar->event_wq,
- test_bit(WMI_READY,
- &ar->flag),
- WMI_TIMEOUT);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "firmware booted\n");
-
-
- if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) {
- ath6kl_info("%s %s fw %s api %d%s\n",
- ar->hw.name,
- ath6kl_init_get_hif_name(ar->hif_type),
- ar->wiphy->fw_version,
- ar->fw_api,
- test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
- }
-
- if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
- ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
- ATH6KL_ABI_VERSION, ar->version.abi_ver);
- ret = -EIO;
- goto err_htc_stop;
- }
-
- if (!timeleft || signal_pending(current)) {
- ath6kl_err("wmi is not ready or wait was interrupted\n");
- ret = -EIO;
- goto err_htc_stop;
- }
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
-
- /* communicate the wmi protocol verision to the target */
- /* FIXME: return error */
- if ((ath6kl_set_host_app_area(ar)) != 0)
- ath6kl_err("unable to set the host app area\n");
-
- for (i = 0; i < ar->vif_max; i++) {
- ret = ath6kl_target_config_wlan_params(ar, i);
- if (ret)
- goto err_htc_stop;
- }
-
- ar->state = ATH6KL_STATE_ON;
-#ifdef CONFIG_MACH_PX
- wake_up(&ar->event_wq);
-#endif
-
- return 0;
-
-err_htc_stop:
- ath6kl_htc_stop(ar->htc_target);
-err_cleanup_scatter:
- ath6kl_hif_cleanup_scatter(ar);
-err_power_off:
- ath6kl_hif_power_off(ar);
-
- return ret;
-}
-
-int ath6kl_init_hw_stop(struct ath6kl *ar)
-{
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "hw stop\n");
-
- ath6kl_htc_stop(ar->htc_target);
-
- ath6kl_hif_stop(ar);
-
- ath6kl_bmi_reset(ar);
-
- ret = ath6kl_hif_power_off(ar);
- if (ret)
- ath6kl_warn("failed to power off hif: %d\n", ret);
-
- ar->state = ATH6KL_STATE_OFF;
-
- return 0;
-}
-
-int ath6kl_core_init(struct ath6kl *ar)
-{
- struct ath6kl_bmi_target_info targ_info;
- struct net_device *ndev;
- int ret = 0, i;
-
- ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
- if (!ar->ath6kl_wq)
- return -ENOMEM;
-
- ret = ath6kl_bmi_init(ar);
- if (ret)
- goto err_wq;
-
- /*
- * Turn on power to get hardware (target) version and leave power
- * on delibrately as we will boot the hardware anyway within few
- * seconds.
- */
- ret = ath6kl_hif_power_on(ar);
- if (ret)
- goto err_bmi_cleanup;
-
- ret = ath6kl_bmi_get_target_info(ar, &targ_info);
- if (ret)
- goto err_power_off;
-
- ar->version.target_ver = le32_to_cpu(targ_info.version);
- ar->target_type = le32_to_cpu(targ_info.type);
- ar->wiphy->hw_version = le32_to_cpu(targ_info.version);
-
- ret = ath6kl_init_hw_params(ar);
- if (ret)
- goto err_power_off;
-
- ar->htc_target = ath6kl_htc_create(ar);
-
- if (!ar->htc_target) {
- ret = -ENOMEM;
- goto err_power_off;
- }
-
- ret = ath6kl_fetch_firmwares(ar);
- if (ret)
- goto err_htc_cleanup;
-
- ath6kl_mangle_mac_address(ar);
- ath6kl_update_psminfo(ar);
-#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
- ath6kl_update_ccodeinfo(ar);
-#endif
-
- /* FIXME: we should free all firmwares in the error cases below */
-
- /* Indicate that WMI is enabled (although not ready yet) */
- set_bit(WMI_ENABLED, &ar->flag);
- ar->wmi = ath6kl_wmi_init(ar);
- if (!ar->wmi) {
- ath6kl_err("failed to initialize wmi\n");
- ret = -EIO;
- goto err_htc_cleanup;
- }
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
-
- ret = ath6kl_register_ieee80211_hw(ar);
- if (ret)
- goto err_node_cleanup;
-
- ret = ath6kl_debug_init(ar);
- if (ret) {
- wiphy_unregister(ar->wiphy);
- goto err_node_cleanup;
- }
-
- for (i = 0; i < ar->vif_max; i++)
- ar->avail_idx_map |= BIT(i);
-
- rtnl_lock();
-
- /* Add an initial station interface */
- ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0,
- INFRA_NETWORK);
-
- rtnl_unlock();
-
- if (!ndev) {
- ath6kl_err("Failed to instantiate a network device\n");
- ret = -ENOMEM;
- wiphy_unregister(ar->wiphy);
- goto err_debug_init;
- }
-
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
- __func__, ndev->name, ndev, ar);
-
- /* setup access class priority mappings */
- ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
- ar->ac_stream_pri_map[WMM_AC_BE] = 1;
- ar->ac_stream_pri_map[WMM_AC_VI] = 2;
- ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
-
- /* allocate some buffers that handle larger AMSDU frames */
- ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
-
- ath6kl_cookie_init(ar);
-
- ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
- ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
-
- if (suspend_mode &&
- suspend_mode >= WLAN_POWER_STATE_CUT_PWR &&
- suspend_mode <= WLAN_POWER_STATE_WOW)
- ar->suspend_mode = suspend_mode;
- else
- ar->suspend_mode = 0;
-
- if (suspend_mode == WLAN_POWER_STATE_WOW &&
- (wow_mode == WLAN_POWER_STATE_CUT_PWR ||
- wow_mode == WLAN_POWER_STATE_DEEP_SLEEP))
- ar->wow_suspend_mode = wow_mode;
- else
- ar->wow_suspend_mode = 0;
-
- ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
- WIPHY_FLAG_HAVE_AP_SME |
- WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
-
-#ifdef CONFIG_MACH_PX
-#else
- if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
- ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
-#endif
-
- ar->wiphy->probe_resp_offload =
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
- NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
-
- set_bit(FIRST_BOOT, &ar->flag);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
- ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
-#endif
-
- ret = ath6kl_init_hw_start(ar);
- if (ret) {
- ath6kl_err("Failed to start hardware: %d\n", ret);
- goto err_rxbuf_cleanup;
- }
-
- /* give our connected endpoints some buffers */
- ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
- ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
-
- /*
- * Set mac address which is received in ready event
- * FIXME: Move to ath6kl_interface_add()
- */
- memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
-
- return ret;
-
-err_rxbuf_cleanup:
- ath6kl_htc_flush_rx_buf(ar->htc_target);
- ath6kl_cleanup_amsdu_rxbufs(ar);
- rtnl_lock();
- ath6kl_deinit_if_data(netdev_priv(ndev));
- rtnl_unlock();
- wiphy_unregister(ar->wiphy);
-err_debug_init:
- ath6kl_debug_cleanup(ar);
-err_node_cleanup:
- ath6kl_cleanup_android_resource(ar);
- ath6kl_wmi_shutdown(ar->wmi);
- clear_bit(WMI_ENABLED, &ar->flag);
- ar->wmi = NULL;
-err_htc_cleanup:
- ath6kl_htc_cleanup(ar->htc_target);
-err_power_off:
- ath6kl_hif_power_off(ar);
-err_bmi_cleanup:
- ath6kl_bmi_cleanup(ar);
-err_wq:
- destroy_workqueue(ar->ath6kl_wq);
-
- return ret;
-}
-
-void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready)
-{
- static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- bool discon_issued;
-
- netif_stop_queue(vif->ndev);
-
- clear_bit(WLAN_ENABLED, &vif->flags);
-
- if (wmi_ready) {
- discon_issued = test_bit(CONNECTED, &vif->flags) ||
- test_bit(CONNECT_PEND, &vif->flags);
- ath6kl_disconnect(vif);
- del_timer(&vif->disconnect_timer);
-
- if (discon_issued)
- ath6kl_disconnect_event(vif, DISCONNECT_CMD,
- (vif->nw_type & AP_NETWORK) ?
- bcast_mac : vif->bssid,
- 0, NULL, 0);
- }
-
- if (vif->scan_req) {
- cfg80211_scan_done(vif->scan_req, true);
- vif->scan_req = NULL;
- }
-}
-
-void ath6kl_stop_txrx(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif, *tmp_vif;
- int i;
-
- set_bit(DESTROY_IN_PROGRESS, &ar->flag);
-
- if (down_interruptible(&ar->sem)) {
- ath6kl_err("down_interruptible failed\n");
- return;
- }
-
- for (i = 0; i < AP_MAX_NUM_STA; i++)
- aggr_reset_state(ar->sta_list[i].aggr_conn);
-
- spin_lock_bh(&ar->list_lock);
- list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) {
- list_del(&vif->list);
- spin_unlock_bh(&ar->list_lock);
- ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
- rtnl_lock();
- ath6kl_deinit_if_data(vif);
- rtnl_unlock();
- spin_lock_bh(&ar->list_lock);
- }
- spin_unlock_bh(&ar->list_lock);
-
- clear_bit(WMI_READY, &ar->flag);
-
- /*
- * After wmi_shudown all WMI events will be dropped. We
- * need to cleanup the buffers allocated in AP mode and
- * give disconnect notification to stack, which usually
- * happens in the disconnect_event. Simulate the disconnect
- * event by calling the function directly. Sometimes
- * disconnect_event will be received when the debug logs
- * are collected.
- */
- ath6kl_wmi_shutdown(ar->wmi);
-
- clear_bit(WMI_ENABLED, &ar->flag);
- if (ar->htc_target) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
- ath6kl_htc_stop(ar->htc_target);
- }
-
- /*
- * Try to reset the device if we can. The driver may have been
- * configure NOT to reset the target during a debug session.
- */
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "attempting to reset target on instance destroy\n");
- ath6kl_reset_device(ar, ar->target_type, true, true);
-
- clear_bit(WLAN_ENABLED, &ar->flag);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
deleted file mode 100755
index 9c674e6..0000000
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ /dev/null
@@ -1,1324 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "hif-ops.h"
-#include "cfg80211.h"
-#include "target.h"
-#include "debug.h"
-#include "wmiconfig.h"
-
-struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr)
-{
- struct ath6kl *ar = vif->ar;
- struct ath6kl_sta *conn = NULL;
- u8 i, max_conn;
-
- max_conn = (vif->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
-
- for (i = 0; i < max_conn; i++) {
- if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
- conn = &ar->sta_list[i];
- break;
- }
- }
-
- return conn;
-}
-
-struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
-{
- struct ath6kl_sta *conn = NULL;
- u8 ctr;
-
- for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
- if (ar->sta_list[ctr].aid == aid) {
- conn = &ar->sta_list[ctr];
- break;
- }
- }
- return conn;
-}
-
-static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,
- u8 *wpaie, size_t ielen, u8 keymgmt,
- u8 ucipher, u8 auth, u8 apsd_info)
-{
- struct ath6kl *ar = vif->ar;
- struct ath6kl_sta *sta;
- u8 free_slot;
-
- free_slot = aid - 1;
-
- sta = &ar->sta_list[free_slot];
- memcpy(sta->mac, mac, ETH_ALEN);
- if (ielen <= ATH6KL_MAX_IE)
- memcpy(sta->wpa_ie, wpaie, ielen);
- sta->aid = aid;
- sta->keymgmt = keymgmt;
- sta->ucipher = ucipher;
- sta->auth = auth;
- sta->apsd_info = apsd_info;
-
- ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
- ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
- aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn);
-}
-
-static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
-{
- struct ath6kl_sta *sta = &ar->sta_list[i];
- struct ath6kl_mgmt_buff *entry, *tmp;
-
- /* empty the queued pkts in the PS queue if any */
- spin_lock_bh(&sta->psq_lock);
- skb_queue_purge(&sta->psq);
- skb_queue_purge(&sta->apsdq);
-
- if (sta->mgmt_psq_len != 0) {
- list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) {
- kfree(entry);
- }
- INIT_LIST_HEAD(&sta->mgmt_psq);
- sta->mgmt_psq_len = 0;
- }
-
- spin_unlock_bh(&sta->psq_lock);
-
- memset(&ar->ap_stats.sta[sta->aid - 1], 0,
- sizeof(struct wmi_per_sta_stat));
- memset(sta->mac, 0, ETH_ALEN);
- memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);
- sta->aid = 0;
- sta->sta_flags = 0;
-
- ar->sta_list_index = ar->sta_list_index & ~(1 << i);
- aggr_reset_state(sta->aggr_conn);
-}
-
-static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
-{
- u8 i, removed = 0;
-
- if (is_zero_ether_addr(mac))
- return removed;
-
- if (is_broadcast_ether_addr(mac)) {
- ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");
-
- for (i = 0; i < AP_MAX_NUM_STA; i++) {
- if (!is_zero_ether_addr(ar->sta_list[i].mac)) {
- ath6kl_sta_cleanup(ar, i);
- removed = 1;
- }
- }
- } else {
- for (i = 0; i < AP_MAX_NUM_STA; i++) {
- if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "deleting station %s aid=%d reason=%d\n",
- sec_conv_mac(mac),
- ar->sta_list[i].aid, reason);
- ath6kl_sta_cleanup(ar, i);
- removed = 1;
- break;
- }
- }
- }
-
- return removed;
-}
-
-enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)
-{
- struct ath6kl *ar = devt;
- return ar->ac2ep_map[ac];
-}
-
-struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)
-{
- struct ath6kl_cookie *cookie;
-
- cookie = ar->cookie_list;
- if (cookie != NULL) {
- ar->cookie_list = cookie->arc_list_next;
- ar->cookie_count--;
- }
-
- return cookie;
-}
-
-void ath6kl_cookie_init(struct ath6kl *ar)
-{
- u32 i;
-
- ar->cookie_list = NULL;
- ar->cookie_count = 0;
-
- memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));
-
- for (i = 0; i < MAX_COOKIE_NUM; i++)
- ath6kl_free_cookie(ar, &ar->cookie_mem[i]);
-}
-
-void ath6kl_cookie_cleanup(struct ath6kl *ar)
-{
- ar->cookie_list = NULL;
- ar->cookie_count = 0;
-}
-
-void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
-{
- /* Insert first */
-
- if (!ar || !cookie)
- return;
-
- cookie->arc_list_next = ar->cookie_list;
- ar->cookie_list = cookie;
- ar->cookie_count++;
-}
-
-/*
- * Read from the hardware through its diagnostic window. No cooperation
- * from the firmware is required for this.
- */
-int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
-{
- int ret;
-
- ret = ath6kl_hif_diag_read32(ar, address, value);
- if (ret) {
- ath6kl_warn("failed to read32 through diagnose window: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Write to the ATH6KL through its diagnostic window. No cooperation from
- * the Target is required for this.
- */
-int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
-{
- int ret;
-
- ret = ath6kl_hif_diag_write32(ar, address, value);
-
- if (ret) {
- ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
- address, value);
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
-{
- u32 count, *buf = data;
- int ret;
-
- if (WARN_ON(length % 4))
- return -EINVAL;
-
- for (count = 0; count < length / 4; count++, address += 4) {
- ret = ath6kl_diag_read32(ar, address, &buf[count]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)
-{
- u32 count;
- __le32 *buf = data;
- int ret;
-
- if (WARN_ON(length % 4))
- return -EINVAL;
-
- for (count = 0; count < length / 4; count++, address += 4) {
- ret = ath6kl_diag_write32(ar, address, buf[count]);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-int ath6kl_read_fwlogs(struct ath6kl *ar)
-{
- struct ath6kl_dbglog_hdr debug_hdr;
- struct ath6kl_dbglog_buf debug_buf;
- u32 address, length, dropped, firstbuf, debug_hdr_addr;
- int ret, loop;
- u8 *buf;
-
- buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- address = TARG_VTOP(ar->target_type,
- ath6kl_get_hi_item_addr(ar,
- HI_ITEM(hi_dbglog_hdr)));
-
- ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);
- if (ret)
- goto out;
-
- /* Get the contents of the ring buffer */
- if (debug_hdr_addr == 0) {
- ath6kl_warn("Invalid address for debug_hdr_addr\n");
- ret = -EINVAL;
- goto out;
- }
-
- address = TARG_VTOP(ar->target_type, debug_hdr_addr);
- ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));
-
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_hdr.dbuf_addr));
- firstbuf = address;
- dropped = le32_to_cpu(debug_hdr.dropped);
- ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
-
- loop = 100;
-
- do {
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_buf.buffer_addr));
- length = le32_to_cpu(debug_buf.length);
-
- if (length != 0 && (le32_to_cpu(debug_buf.length) <=
- le32_to_cpu(debug_buf.bufsize))) {
- length = ALIGN(length, 4);
-
- ret = ath6kl_diag_read(ar, address,
- buf, length);
- if (ret)
- goto out;
-
- ath6kl_debug_fwlog_event(ar, buf, length);
- }
-
- address = TARG_VTOP(ar->target_type,
- le32_to_cpu(debug_buf.next));
- ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));
- if (ret)
- goto out;
-
- loop--;
-
- if (WARN_ON(loop == 0)) {
- ret = -ETIMEDOUT;
- goto out;
- }
- } while (address != firstbuf);
-
-out:
- kfree(buf);
-
- return ret;
-}
-
-#ifdef CONFIG_MACH_PX
-void ath6kl_print_ar6k_registers(struct ath6kl *ar)
-{
-#if 0
- u32 reg_addr;
- u32 epc_addr1, epc_addr2, epc_addr3, epc_addr4;
- u32 epc1, epc2, epc3, epc4;
- u32 intrs, resetc, ssleep;
- int ret;
-
- epc_addr1 = EPC1_ADDR;
- if (epc_addr1 != 0x00)
- {
- epc_addr2 = epc_addr1 + 4;
- epc_addr3 = epc_addr1 + 8;
- epc_addr4 = epc_addr1 + 12;
-
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(epc_addr1));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &epc1);
- if (ret)
- ath6kl_err("diag_read of epc1 is failed\n");
-
-
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(epc_addr2));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &epc2);
- if (ret)
- ath6kl_err("diag_read of epc2 is failed\n");
-
-
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(epc_addr3));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &epc3);
- if (ret)
- ath6kl_err("diag_read of epc3 is failed\n");
-
-
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(epc_addr4));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &epc4);
- if (ret)
- ath6kl_err("diag_read of epc4 is failed\n");
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "ath6kl:reg_dump EPC: %x %x %x %x\n",
- epc1, epc2, epc3, epc4);
- }
-
- /* Interrupt Status */
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(0x4034));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &intrs);
- if (ret)
- ath6kl_err("diag_read of intrs is failed\n");
- else
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "ath6kl:reg_dump interrupt status: %x\n", intrs);
-
- /* Reset Cause */
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(0x40C0));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &resetc);
- if (ret)
- ath6kl_err("diag_read of resetc is failed\n");
- else
- ath6kl_dbg(ATH6KL_DBG_TRC, "ath6kl:reg_dump reset cause: %x\n",
- resetc);
-
-
- /* System Sleep */
- reg_addr = TARG_VTOP(ar->target_type, le32_to_cpu(0x40C4));
-
- ret = ath6kl_diag_read32(ar, reg_addr, &ssleep);
- if (ret)
- ath6kl_err("diag_read of ssleep is failed\n");
- else
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "ath6kl:reg_dump system sleep: %x\n", ssleep);
-#endif
-}
-#endif
-
-/* FIXME: move to a better place, target.h? */
-#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
-#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
-
-void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
- bool wait_fot_compltn, bool cold_reset)
-{
- int status = 0;
- u32 address;
- __le32 data;
-
- if (target_type != TARGET_TYPE_AR6003 &&
- target_type != TARGET_TYPE_AR6004)
- return;
-
- data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
- cpu_to_le32(RESET_CONTROL_MBOX_RST);
-
- switch (target_type) {
- case TARGET_TYPE_AR6003:
- address = AR6003_RESET_CONTROL_ADDRESS;
- break;
- case TARGET_TYPE_AR6004:
- address = AR6004_RESET_CONTROL_ADDRESS;
- break;
- }
-
- status = ath6kl_diag_write32(ar, address, data);
-
- if (status)
- ath6kl_err("failed to reset target\n");
-}
-
-static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
-{
- u8 index;
- u8 keyusage;
-
- for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) {
- if (vif->wep_key_list[index].key_len) {
- keyusage = GROUP_USAGE;
- if (index == vif->def_txkey_index)
- keyusage |= TX_USAGE;
-
- ath6kl_wmi_addkey_cmd(vif->ar->wmi, vif->fw_vif_idx,
- index,
- WEP_CRYPT,
- keyusage,
- vif->wep_key_list[index].key_len,
- NULL, 0,
- vif->wep_key_list[index].key,
- KEY_OP_INIT_VAL, NULL,
- NO_SYNC_WMIFLAG);
- }
- }
-}
-
-void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)
-{
- struct ath6kl *ar = vif->ar;
- struct ath6kl_req_key *ik;
- int res;
- u8 key_rsc[ATH6KL_KEY_SEQ_LEN];
-
- ik = &ar->ap_mode_bkey;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);
-
- switch (vif->auth_mode) {
- case NONE_AUTH:
- if (vif->prwise_crypto == WEP_CRYPT)
- ath6kl_install_static_wep_keys(vif);
- if (!ik->valid || ik->key_type != WAPI_CRYPT)
- break;
- /* for WAPI, we need to set the delayed group key, continue: */
- case WPA_PSK_AUTH:
- case WPA2_PSK_AUTH:
- case (WPA_PSK_AUTH | WPA2_PSK_AUTH):
- if (!ik->valid)
- break;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed addkey for "
- "the initial group key for AP mode\n");
- memset(key_rsc, 0, sizeof(key_rsc));
- res = ath6kl_wmi_addkey_cmd(
- ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,
- GROUP_USAGE, ik->key_len, key_rsc, ATH6KL_KEY_SEQ_LEN,
- ik->key,
- KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);
- if (res) {
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delayed "
- "addkey failed: %d\n", res);
- }
- break;
- }
-
- ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);
- set_bit(CONNECTED, &vif->flags);
- netif_carrier_on(vif->ndev);
-}
-
-void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
- u8 keymgmt, u8 ucipher, u8 auth,
- u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)
-{
- u8 *ies = NULL, *wpa_ie = NULL, *pos;
- size_t ies_len = 0;
- struct station_info sinfo;
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "new station %s aid=%d\n",
- sec_conv_mac(mac_addr), aid);
-
- if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {
- struct ieee80211_mgmt *mgmt =
- (struct ieee80211_mgmt *) assoc_info;
- if (ieee80211_is_assoc_req(mgmt->frame_control) &&
- assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +
- sizeof(mgmt->u.assoc_req)) {
- ies = mgmt->u.assoc_req.variable;
- ies_len = assoc_info + assoc_req_len - ies;
- } else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&
- assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)
- + sizeof(mgmt->u.reassoc_req)) {
- ies = mgmt->u.reassoc_req.variable;
- ies_len = assoc_info + assoc_req_len - ies;
- }
- }
-
- pos = ies;
- while (pos && pos + 1 < ies + ies_len) {
- if (pos + 2 + pos[1] > ies + ies_len)
- break;
- if (pos[0] == WLAN_EID_RSN)
- wpa_ie = pos; /* RSN IE */
- else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
- pos[1] >= 4 &&
- pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {
- if (pos[5] == 0x01)
- wpa_ie = pos; /* WPA IE */
- else if (pos[5] == 0x04) {
- wpa_ie = pos; /* WPS IE */
- break; /* overrides WPA/RSN IE */
- }
- } else if (pos[0] == 0x44 && wpa_ie == NULL) {
- /*
- * Note: WAPI Parameter Set IE re-uses Element ID that
- * was officially allocated for BSS AC Access Delay. As
- * such, we need to be a bit more careful on when
- * parsing the frame. However, BSS AC Access Delay
- * element is not supposed to be included in
- * (Re)Association Request frames, so this should not
- * cause problems.
- */
- wpa_ie = pos; /* WAPI IE */
- break;
- }
- pos += 2 + pos[1];
- }
-
- ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie,
- wpa_ie ? 2 + wpa_ie[1] : 0,
- keymgmt, ucipher, auth, apsd_info);
-
- /* send event to application */
- memset(&sinfo, 0, sizeof(sinfo));
-
- /* TODO: sinfo.generation */
-
- sinfo.assoc_req_ies = ies;
- sinfo.assoc_req_ies_len = ies_len;
- sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
-
- cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL);
-
- netif_wake_queue(vif->ndev);
-}
-
-void disconnect_timer_handler(unsigned long ptr)
-{
- struct net_device *dev = (struct net_device *)ptr;
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- ath6kl_init_profile_info(vif);
- ath6kl_disconnect(vif);
-}
-
-void ath6kl_disconnect(struct ath6kl_vif *vif)
-{
- if (test_bit(CONNECTED, &vif->flags) ||
- test_bit(CONNECT_PEND, &vif->flags)) {
- ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
- /*
- * Disconnect command is issued, clear the connect pending
- * flag. The connected flag will be cleared in
- * disconnect event notification.
- */
- clear_bit(CONNECT_PEND, &vif->flags);
- }
-}
-
-/* WMI Event handlers */
-
-void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
-{
- struct ath6kl *ar = devt;
-
- memcpy(ar->mac_addr, datap, ETH_ALEN);
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %s\n",
- __func__, sec_conv_mac(ar->mac_addr));
-
- ar->version.wlan_ver = sw_ver;
- ar->version.abi_ver = abi_ver;
-
- snprintf(ar->wiphy->fw_version,
- sizeof(ar->wiphy->fw_version),
- "%u.%u.%u.%u",
- (ar->version.wlan_ver & 0xf0000000) >> 28,
- (ar->version.wlan_ver & 0x0f000000) >> 24,
- (ar->version.wlan_ver & 0x00ff0000) >> 16,
- (ar->version.wlan_ver & 0x0000ffff));
-
- /* indicate to the waiting thread that the ready event was received */
- set_bit(WMI_READY, &ar->flag);
- wake_up(&ar->event_wq);
-}
-
-void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)
-{
- struct ath6kl *ar = vif->ar;
- bool aborted = false;
-
- if (status != WMI_SCAN_STATUS_SUCCESS)
- aborted = true;
-
- ath6kl_cfg80211_scan_complete_event(vif, aborted);
-
- if (!ar->usr_bss_filter) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- NONE_BSS_FILTER, 0);
- }
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
-}
-
-void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,
- u16 listen_int, u16 beacon_int,
- enum network_type net_type, u8 beacon_ie_len,
- u8 assoc_req_len, u8 assoc_resp_len,
- u8 *assoc_info)
-{
- struct ath6kl *ar = vif->ar;
-
- ath6kl_cfg80211_connect_event(vif, channel, bssid,
- listen_int, beacon_int,
- net_type, beacon_ie_len,
- assoc_req_len, assoc_resp_len,
- assoc_info);
-
- memcpy(vif->bssid, bssid, sizeof(vif->bssid));
- vif->bss_ch = channel;
-
- if ((vif->nw_type == INFRA_NETWORK))
- ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
- vif->listen_intvl_t, 0);
-
- netif_wake_queue(vif->ndev);
-
- /* Update connect & link status atomically */
- spin_lock_bh(&vif->if_lock);
- set_bit(CONNECTED, &vif->flags);
- clear_bit(CONNECT_PEND, &vif->flags);
- netif_carrier_on(vif->ndev);
- spin_unlock_bh(&vif->if_lock);
-
- aggr_reset_state(vif->aggr_cntxt->aggr_conn);
- vif->reconnect_flag = 0;
-
- if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
- memset(ar->node_map, 0, sizeof(ar->node_map));
- ar->node_num = 0;
- ar->next_ep_id = ENDPOINT_2;
- }
-
- if (!ar->usr_bss_filter) {
- set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- CURRENT_BSS_FILTER, 0);
- }
-}
-
-void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast)
-{
- struct ath6kl_sta *sta;
- struct ath6kl *ar = vif->ar;
- u8 tsc[6];
-
- /*
- * For AP case, keyid will have aid of STA which sent pkt with
- * MIC error. Use this aid to get MAC & send it to hostapd.
- */
- if (vif->nw_type == AP_NETWORK) {
- sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
- if (!sta)
- return;
-
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "ap tkip mic error received from aid=%d\n", keyid);
-
- memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
- cfg80211_michael_mic_failure(vif->ndev, sta->mac,
- NL80211_KEYTYPE_PAIRWISE, keyid,
- tsc, GFP_KERNEL);
- } else
- ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);
-
-}
-
-static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
-{
- struct wmi_target_stats *tgt_stats =
- (struct wmi_target_stats *) ptr;
- struct ath6kl *ar = vif->ar;
- struct target_stats *stats = &vif->target_stats;
- struct tkip_ccmp_stats *ccmp_stats;
- u8 ac;
-
- if (len < sizeof(*tgt_stats))
- return;
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
-
- stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
- stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);
- stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);
- stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);
- stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);
- stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);
- stats->tx_bcast_pkt += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);
- stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);
- stats->tx_rts_success_cnt +=
- le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);
-
- for (ac = 0; ac < WMM_NUM_AC; ac++)
- stats->tx_pkt_per_ac[ac] +=
- le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);
-
- stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);
- stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);
- stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);
- stats->tx_mult_retry_cnt +=
- le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
- stats->tx_rts_fail_cnt +=
- le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
- stats->tx_ucast_rate =
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
-
- stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
- stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
- stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);
- stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);
- stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);
- stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);
- stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);
- stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);
- stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);
- stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);
- stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);
- stats->rx_key_cache_miss +=
- le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
- stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
- stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
- stats->rx_ucast_rate =
- ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
-
- ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
-
- stats->tkip_local_mic_fail +=
- le32_to_cpu(ccmp_stats->tkip_local_mic_fail);
- stats->tkip_cnter_measures_invoked +=
- le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);
- stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);
-
- stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);
- stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);
-
- stats->pwr_save_fail_cnt +=
- le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);
- stats->noise_floor_calib =
- a_sle32_to_cpu(tgt_stats->noise_floor_calib);
-
- stats->cs_bmiss_cnt +=
- le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);
- stats->cs_low_rssi_cnt +=
- le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);
- stats->cs_connect_cnt +=
- le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);
- stats->cs_discon_cnt +=
- le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);
-
- stats->cs_ave_beacon_rssi =
- a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);
-
- stats->cs_last_roam_msec =
- tgt_stats->cserv_stats.cs_last_roam_msec;
- stats->cs_snr = tgt_stats->cserv_stats.cs_snr;
- stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);
-
- stats->lq_val = le32_to_cpu(tgt_stats->lq_val);
-
- stats->wow_pkt_dropped +=
- le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);
- stats->wow_host_pkt_wakeups +=
- tgt_stats->wow_stats.wow_host_pkt_wakeups;
- stats->wow_host_evt_wakeups +=
- tgt_stats->wow_stats.wow_host_evt_wakeups;
- stats->wow_evt_discarded +=
- le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
-
- stats->arp_received = le32_to_cpu(tgt_stats->arp_stats.arp_received);
- stats->arp_replied = le32_to_cpu(tgt_stats->arp_stats.arp_replied);
- stats->arp_matched = le32_to_cpu(tgt_stats->arp_stats.arp_matched);
-
- ath6kl_wmicfg_send_stats(vif, stats);
-
- if (test_bit(STATS_UPDATE_PEND, &vif->flags)) {
- clear_bit(STATS_UPDATE_PEND, &vif->flags);
- wake_up(&ar->event_wq);
- }
-}
-
-static void ath6kl_add_le32(__le32 *var, __le32 val)
-{
- *var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
-}
-
-void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)
-{
- struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
- struct ath6kl *ar = vif->ar;
- struct wmi_ap_mode_stat *ap = &ar->ap_stats;
- struct wmi_per_sta_stat *st_ap, *st_p;
- u8 ac;
-
- if (vif->nw_type == AP_NETWORK) {
- if (len < sizeof(*p))
- return;
-
- for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {
- st_ap = &ap->sta[ac];
- st_p = &p->sta[ac];
-
- ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);
- ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);
- ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);
- ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);
- ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);
- ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);
- ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);
- ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);
- }
-
- } else {
- ath6kl_update_target_stats(vif, ptr, len);
- }
-}
-
-void ath6kl_wakeup_event(void *dev)
-{
- struct ath6kl *ar = (struct ath6kl *) dev;
-
- wake_up(&ar->event_wq);
-}
-
-void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
-{
- struct ath6kl *ar = (struct ath6kl *) devt;
-
- ar->tx_pwr = tx_pwr;
- wake_up(&ar->event_wq);
-}
-
-void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)
-{
- struct ath6kl_sta *conn;
- struct sk_buff *skb;
- bool psq_empty = false;
- struct ath6kl *ar = vif->ar;
- struct ath6kl_mgmt_buff *mgmt_buf;
-
- conn = ath6kl_find_sta_by_aid(ar, aid);
-
- if (!conn)
- return;
- /*
- * Send out a packet queued on ps queue. When the ps queue
- * becomes empty update the PVB for this station.
- */
- spin_lock_bh(&conn->psq_lock);
- psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);
- spin_unlock_bh(&conn->psq_lock);
-
- if (psq_empty)
- /* TODO: Send out a NULL data frame */
- return;
-
- spin_lock_bh(&conn->psq_lock);
- if (conn->mgmt_psq_len > 0) {
- mgmt_buf = list_first_entry(&conn->mgmt_psq,
- struct ath6kl_mgmt_buff, list);
- list_del(&mgmt_buf->list);
- conn->mgmt_psq_len--;
- spin_unlock_bh(&conn->psq_lock);
-
- conn->sta_flags |= STA_PS_POLLED;
- ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx,
- mgmt_buf->id, mgmt_buf->freq,
- mgmt_buf->wait, mgmt_buf->buf,
- mgmt_buf->len, mgmt_buf->no_cck);
- conn->sta_flags &= ~STA_PS_POLLED;
- kfree(mgmt_buf);
- } else {
- skb = skb_dequeue(&conn->psq);
- spin_unlock_bh(&conn->psq_lock);
-
- conn->sta_flags |= STA_PS_POLLED;
- ath6kl_data_tx(skb, vif->ndev);
- conn->sta_flags &= ~STA_PS_POLLED;
- }
-
- spin_lock_bh(&conn->psq_lock);
- psq_empty = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);
- spin_unlock_bh(&conn->psq_lock);
-
- if (psq_empty)
- ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
-}
-
-void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif)
-{
- bool mcastq_empty = false;
- struct sk_buff *skb;
- struct ath6kl *ar = vif->ar;
-
- /*
- * If there are no associated STAs, ignore the DTIM expiry event.
- * There can be potential race conditions where the last associated
- * STA may disconnect & before the host could clear the 'Indicate
- * DTIM' request to the firmware, the firmware would have just
- * indicated a DTIM expiry event. The race is between 'clear DTIM
- * expiry cmd' going from the host to the firmware & the DTIM
- * expiry event happening from the firmware to the host.
- */
- if (!ar->sta_list_index)
- return;
-
- spin_lock_bh(&ar->mcastpsq_lock);
- mcastq_empty = skb_queue_empty(&ar->mcastpsq);
- spin_unlock_bh(&ar->mcastpsq_lock);
-
- if (mcastq_empty)
- return;
-
- /* set the STA flag to dtim_expired for the frame to go out */
- set_bit(DTIM_EXPIRED, &vif->flags);
-
- spin_lock_bh(&ar->mcastpsq_lock);
- while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
- spin_unlock_bh(&ar->mcastpsq_lock);
-
- ath6kl_data_tx(skb, vif->ndev);
-
- spin_lock_bh(&ar->mcastpsq_lock);
- }
- spin_unlock_bh(&ar->mcastpsq_lock);
-
- clear_bit(DTIM_EXPIRED, &vif->flags);
-
- /* clear the LSB of the BitMapCtl field of the TIM IE */
- ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0);
-}
-
-void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,
- u8 assoc_resp_len, u8 *assoc_info,
- u16 prot_reason_status)
-{
- struct ath6kl *ar = vif->ar;
-
- if (vif->nw_type == AP_NETWORK) {
- if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
- return;
-
- /* if no more associated STAs, empty the mcast PS q */
- if (ar->sta_list_index == 0) {
- spin_lock_bh(&ar->mcastpsq_lock);
- skb_queue_purge(&ar->mcastpsq);
- spin_unlock_bh(&ar->mcastpsq_lock);
-
- /* clear the LSB of the TIM IE's BitMapCtl field */
- if (test_bit(WMI_READY, &ar->flag))
- ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
- MCAST_AID, 0);
- }
-
- if (!is_broadcast_ether_addr(bssid)) {
- /* send event to application */
- cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL);
- }
-
- if (memcmp(vif->ndev->dev_addr, bssid, ETH_ALEN) == 0) {
- memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));
- clear_bit(CONNECTED, &vif->flags);
- }
- return;
- }
-
- ath6kl_cfg80211_disconnect_event(vif, reason, bssid,
- assoc_resp_len, assoc_info,
- prot_reason_status);
-
- aggr_reset_state(vif->aggr_cntxt->aggr_conn);
-
- del_timer(&vif->disconnect_timer);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason);
-
- /*
- * If the event is due to disconnect cmd from the host, only they
- * the target would stop trying to connect. Under any other
- * condition, target would keep trying to connect.
- */
- if (reason == DISCONNECT_CMD) {
- if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
- ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- NONE_BSS_FILTER, 0);
- } else {
- set_bit(CONNECT_PEND, &vif->flags);
- if (((reason == ASSOC_FAILED) &&
- (prot_reason_status == 0x11)) ||
- ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
- && (vif->reconnect_flag == 1))) {
- set_bit(CONNECTED, &vif->flags);
- return;
- }
- }
-
- /* update connect & link status atomically */
- spin_lock_bh(&vif->if_lock);
- clear_bit(CONNECTED, &vif->flags);
- netif_carrier_off(vif->ndev);
- spin_unlock_bh(&vif->if_lock);
-
- if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))
- vif->reconnect_flag = 0;
-
- if (reason != CSERV_DISCONNECT)
- ar->user_key_ctrl = 0;
-
- netif_stop_queue(vif->ndev);
- memset(vif->bssid, 0, sizeof(vif->bssid));
- vif->bss_ch = 0;
-
- ath6kl_tx_data_cleanup(ar);
-}
-
-struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar)
-{
- struct ath6kl_vif *vif;
-
- spin_lock_bh(&ar->list_lock);
- if (list_empty(&ar->vif_list)) {
- spin_unlock_bh(&ar->list_lock);
- return NULL;
- }
-
- vif = list_first_entry(&ar->vif_list, struct ath6kl_vif, list);
-
- spin_unlock_bh(&ar->list_lock);
-
- return vif;
-}
-
-static int ath6kl_open(struct net_device *dev)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- set_bit(WLAN_ENABLED, &vif->flags);
-
- if (test_bit(CONNECTED, &vif->flags)) {
- netif_carrier_on(dev);
- netif_wake_queue(dev);
- } else
- netif_carrier_off(dev);
-
- return 0;
-}
-
-static int ath6kl_close(struct net_device *dev)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- netif_stop_queue(dev);
-
- ath6kl_cfg80211_stop(vif);
-
- clear_bit(WLAN_ENABLED, &vif->flags);
-
- return 0;
-}
-
-static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
-
- return &vif->net_stats;
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
-static int ath6kl_set_features(struct net_device *dev, u32 features)
-{
- struct ath6kl_vif *vif = netdev_priv(dev);
- struct ath6kl *ar = vif->ar;
- int err = 0;
-
- if ((features & NETIF_F_RXCSUM) &&
- (ar->rx_meta_ver != WMI_META_VERSION_2)) {
- ar->rx_meta_ver = WMI_META_VERSION_2;
- err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
- vif->fw_vif_idx,
- ar->rx_meta_ver, 0, 0);
- if (err) {
- dev->features = features & ~NETIF_F_RXCSUM;
- return err;
- }
- } else if (!(features & NETIF_F_RXCSUM) &&
- (ar->rx_meta_ver == WMI_META_VERSION_2)) {
- ar->rx_meta_ver = 0;
- err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
- vif->fw_vif_idx,
- ar->rx_meta_ver, 0, 0);
- if (err) {
- dev->features = features | NETIF_F_RXCSUM;
- return err;
- }
-
- }
-
- return err;
-}
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
-
-static void ath6kl_set_multicast_list(struct net_device *ndev)
-{
- struct ath6kl_vif *vif = netdev_priv(ndev);
- bool mc_all_on = false;
- int mc_count = netdev_mc_count(ndev);
- struct netdev_hw_addr *ha;
- bool found;
- struct ath6kl_mc_filter *mc_filter, *tmp;
- struct list_head mc_filter_new;
- int ret;
-
- if (!test_bit(WMI_READY, &vif->ar->flag) ||
- !test_bit(WLAN_ENABLED, &vif->flags))
- return;
-
- /* Enable multicast-all filter. */
- mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
- !!(ndev->flags & IFF_ALLMULTI) ||
- !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST) ||
- (vif->ar->state == ATH6KL_STATE_ON);
-
- if (!(ndev->flags & IFF_MULTICAST))
- mc_all_on = false;
-
- ath6kl_dbg(ATH6KL_DBG_TRC, "multicast state IFF_ALLMULTI = %d , IFF_MULTICAST = %d, "
- "mc_count = %d, mc_all_on = %d",
- ndev->flags & IFF_ALLMULTI, ndev->flags & IFF_MULTICAST, mc_count,
- mc_all_on);
-
- /* Enable/disable "multicast-all" filter*/
- ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n",
- mc_all_on ? "enabling" : "disabling");
-
- ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
- mc_all_on);
-
- if (ret) {
- ath6kl_warn("Failed to %s multicast receive\n",
- mc_all_on ? "enable" : "disable");
- return;
- }
-
- /* Keep the driver and firmware mcast list in sync. */
- list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
- found = false;
- netdev_for_each_mc_addr(ha, ndev) {
- if (memcmp(ha->addr, mc_filter->hw_addr,
- ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- /*
- * Delete the filter which was previously set
- * but not in the new request.
- */
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "Removing %s from multicast filter\n",
- sec_conv_mac(mc_filter->hw_addr));
- ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
- vif->fw_vif_idx, mc_filter->hw_addr,
- false);
- if (ret) {
- ath6kl_warn("Failed to remove multicast filter:%s\n",
- sec_conv_mac(mc_filter->hw_addr));
- return;
- }
-
- list_del(&mc_filter->list);
- kfree(mc_filter);
- }
- }
-
- INIT_LIST_HEAD(&mc_filter_new);
-
- netdev_for_each_mc_addr(ha, ndev) {
- found = false;
- list_for_each_entry(mc_filter, &vif->mc_filter, list) {
- if (memcmp(ha->addr, mc_filter->hw_addr,
- ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter),
- GFP_ATOMIC);
- if (!mc_filter) {
- WARN_ON(1);
- goto out;
- }
-
- if (memcmp(ha->addr, "\x33\x33\x00\x00\x00\x01", ETH_ALEN) == 0) {
- ath6kl_warn("Skipped : %s\n", sec_conv_mac(ha->addr));
- kfree(mc_filter);
- continue;
- } else {
- memcpy(mc_filter->hw_addr, ha->addr,
- ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
- /* Set the multicast filter */
- ath6kl_dbg(ATH6KL_DBG_TRC,
- "Adding %s to multicast filter list\n",
- sec_conv_mac(mc_filter->hw_addr));
- ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,
- vif->fw_vif_idx, mc_filter->hw_addr,
- true);
- if (ret) {
- ath6kl_warn("Failed to add multicast filter :%s\n",
- sec_conv_mac(mc_filter->hw_addr));
- kfree(mc_filter);
- goto out;
- }
- }
-
- list_add_tail(&mc_filter->list, &mc_filter_new);
- }
- }
-
-out:
- list_splice_tail(&mc_filter_new, &vif->mc_filter);
-}
-
-static struct net_device_ops ath6kl_netdev_ops = {
- .ndo_open = ath6kl_open,
- .ndo_stop = ath6kl_close,
- .ndo_start_xmit = ath6kl_data_tx,
- .ndo_get_stats = ath6kl_get_stats,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
- .ndo_set_features = ath6kl_set_features,
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
- .ndo_set_rx_mode = ath6kl_set_multicast_list,
-};
-
-void init_netdev(struct net_device *dev)
-{
- netdev_attach_ops(dev, &ath6kl_netdev_ops);
- dev->destructor = free_netdev;
- dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
-
- dev->needed_headroom = ETH_HLEN;
- dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
- sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
- + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
-
- return;
-}
diff --git a/drivers/net/wireless/ath/ath6kl/msm.c b/drivers/net/wireless/ath/ath6kl/msm.c
deleted file mode 100644
index c9013bf..0000000
--- a/drivers/net/wireless/ath/ath6kl/msm.c
+++ /dev/null
@@ -1,425 +0,0 @@
-#include <linux/device.h>
-#include <linux/regulator/consumer.h>
-#include <linux/gpio.h>
-#include <linux/err.h>
-
-#ifdef CONFIG_ARCH_MSM7X27A
-#include <mach/rpc_pmapp.h>
-#include <linux/qcomwlan7x27a_pwrif.h>
-#else
-#include <linux/platform_device.h>
-/* replace with plaftform specific changes */
-#endif
-
-#include "core.h"
-
-typedef int A_BOOL;
-typedef unsigned char A_UCHAR;
-typedef unsigned long A_ATH_TIMER;
-typedef int8_t A_INT8;
-typedef int16_t A_INT16;
-typedef int32_t A_INT32;
-typedef u_int8_t A_UINT8;
-typedef u_int16_t A_UINT16;
-typedef u_int32_t A_UINT32;
-
-#define WMI_MAX_SSID_LEN 32
-#define ATH_MAC_LEN 6 /* length of mac in bytes */
-
-#define __ATTRIB_PACK
-#define POSTPACK __ATTRIB_PACK
-#define PREPACK
-
-typedef PREPACK struct {
- PREPACK union {
- A_UINT8 ie[17];
- A_INT32 wac_status;
- } POSTPACK info;
-} POSTPACK WMI_GET_WAC_INFO;
-
-struct ar_wep_key {
- A_UINT8 arKeyIndex;
- A_UINT8 arKeyLen;
- A_UINT8 arKey[64];
-} ;
-
-#ifdef CONFIG_ARCH_MSM7X27A
-/* BeginMMC polling stuff */
-#define MMC_MSM_DEV "msm_sdcc.2"
-#define A_MDELAY(msecs) mdelay(msecs)
-/* End MMC polling stuff */
-#else
-/* replace with plaftform specific changes */
-#endif
-
-#define WMI_MAX_RATE_MASK 2
-
-
-
-#define GET_INODE_FROM_FILEP(filp) \
- (filp)->f_path.dentry->d_inode
-typedef char A_CHAR;
-int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length)
-{
- int ret = 0;
- struct file *filp = (struct file *)-ENOENT;
- mm_segment_t oldfs;
- oldfs = get_fs();
- set_fs(KERNEL_DS);
-
- do {
- int mode = (wbuf) ? O_RDWR : O_RDONLY;
- filp = filp_open(filename, mode, S_IRUSR);
-
- if (IS_ERR(filp) || !filp->f_op) {
- ret = -ENOENT;
- break;
- }
-
- if (length == 0) {
- /* Read the length of the file only */
- struct inode *inode;
-
- inode = GET_INODE_FROM_FILEP(filp);
- if (!inode) {
- printk(KERN_ERR "android_readwrite_file: Error 2\n");
- ret = -ENOENT;
- break;
- }
- ret = i_size_read(inode->i_mapping->host);
- break;
- }
-
- if (wbuf) {
- if ((ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_ERR "android_readwrite_file: Error 3\n");
- break;
- }
- } else {
- if ((ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
- printk(KERN_ERR "android_readwrite_file: Error 4\n");
- break;
- }
- }
- } while (0);
-
- if (!IS_ERR(filp)) {
- filp_close(filp, NULL);
- }
-
- set_fs(oldfs);
- printk(KERN_ERR "android_readwrite_file: ret=%d\n", ret);
-
- return ret;
-}
-
-
-#ifdef CONFIG_ARCH_MSM7X27A
-
-#define WLAN_GPIO_EXT_POR_N 134
-#define A0_CLOCK
-static const char *id = "WLAN";
-
-enum {
- WLAN_VREG_L17 = 0,
- WLAN_VREG_L19
-};
-
-struct wlan_vreg_info {
- const char *vreg_id;
- unsigned int level_min;
- unsigned int level_max;
- unsigned int pmapp_id;
- unsigned int is_vreg_pin_controlled;
- struct regulator *reg;
-};
-
-
-static struct wlan_vreg_info vreg_info[] = {
- {"bt", 3300000, 3300000, 21, 1, NULL},
- {"wlan4", 1800000, 1800000, 23, 1, NULL},
-};
-
-static int qrf6285_init_regs(void)
-{
- struct regulator_bulk_data regs[ARRAY_SIZE(vreg_info)];
- int i, rc;
-
- for (i = 0; i < ARRAY_SIZE(regs); i++) {
- regs[i].supply = vreg_info[i].vreg_id;
- regs[i].min_uV = vreg_info[i].level_min;
- regs[i].max_uV = vreg_info[i].level_max;
- }
-
- rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs), regs);
- if (rc) {
- pr_err("%s: could not get regulators: %d\n", __func__, rc);
- goto out;
- }
-
- for (i = 0; i < ARRAY_SIZE(regs); i++)
- vreg_info[i].reg = regs[i].consumer;
-
- return 0;
-
-out:
- return rc;
-}
-
-int msm7x27a_wifi_power(bool on)
-{
-
- int rc = 0, index = 0;
- static bool init_done;
- static int resultFlag = 0, flag = 1;
-
- if (unlikely(!init_done)) {
- rc = qrf6285_init_regs();
- if (rc)
- return rc;
- else
- init_done = true;
- }
-
- for (index = 0; index < ARRAY_SIZE(vreg_info); index++) {
- if (on) {
-
- rc = regulator_set_voltage(vreg_info[index].reg,
- vreg_info[index].level_min,
- vreg_info[index].level_max);
- if (rc) {
- pr_err("%s:%s set voltage failed %d\n",
- __func__, vreg_info[index].vreg_id, rc);
-
- goto vreg_fail;
- }
-
- rc = regulator_enable(vreg_info[index].reg);
- if (rc) {
- pr_err("%s:%s vreg enable failed %d\n",
- __func__, vreg_info[index].vreg_id, rc);
-
- goto vreg_fail;
- }
-
- if (vreg_info[index].is_vreg_pin_controlled) {
- rc = pmapp_vreg_lpm_pincntrl_vote(id,
- vreg_info[index].pmapp_id,
- PMAPP_CLOCK_ID_A0, 1);
- if (rc) {
- pr_err("%s:%s pmapp_vreg_lpm_pincntrl"
- " for enable failed %d\n",
- __func__,
- vreg_info[index].vreg_id, rc);
- goto vreg_clock_vote_fail;
- }
- }
-
- if (index == WLAN_VREG_L17)
- usleep(5);
- else if (index == WLAN_VREG_L19)
- usleep(10);
-
- } else {
-
- if (vreg_info[index].is_vreg_pin_controlled) {
- rc = pmapp_vreg_lpm_pincntrl_vote(id,
- vreg_info[index].pmapp_id,
- PMAPP_CLOCK_ID_A0, 0);
- if (rc) {
- pr_err("%s:%s pmapp_vreg_lpm_pincntrl"
- " for disable failed %d\n",
- __func__,
- vreg_info[index].vreg_id, rc);
- }
- }
- rc = regulator_disable(vreg_info[index].reg);
- if (rc) {
- pr_err("%s:%s vreg disable failed %d\n",
- __func__, vreg_info[index].vreg_id, rc);
- }
- }
-
- }
-
- if (on) {
- rc = gpio_request(WLAN_GPIO_EXT_POR_N, "WLAN_DEEP_SLEEP_N");
- if (rc) {
- pr_err("WLAN reset GPIO %d request failed %d\n",
- WLAN_GPIO_EXT_POR_N, rc);
- goto fail;
- }
-
- if(flag)
- {
- flag=0;
- rc = gpio_direction_output(WLAN_GPIO_EXT_POR_N, 1);
- if (rc < 0) {
- pr_err("WLAN reset GPIO %d set direction failed %d\n",
- WLAN_GPIO_EXT_POR_N, rc);
- goto fail_gpio_dir_out;
- }
- }
- printk("\n vote for WLAN GPIO 134 done. \n");
-#ifdef A0_CLOCK
- rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0, PMAPP_CLOCK_VOTE_ON);
- if (rc) {
- pr_err("%s: Configuring A0 to turn on"
- " failed %d\n", __func__, rc);
- }
- printk("\nVote for A0 clock done\n");
- /*
- * Configure A0 clock to be slave to
- * WLAN_CLK_PWR_REQ
- */
- rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
- PMAPP_CLOCK_VOTE_PIN_CTRL);
- if (rc) {
- pr_err("%s: Configuring A0 to Pin"
- " controllable failed %d\n",
- __func__, rc);
- goto vreg_clock_vote_fail;
- }
-#else
-
- rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0, PMAPP_CLOCK_VOTE_OFF);
- if (rc) {
- pr_err("%s: Configuring A0 to turn off"
- " failed %d\n", __func__, rc);
- }
- printk("\n Vote against A0 clock done\n");
-#endif
-
- } else {
-
- if(!resultFlag){
- gpio_set_value_cansleep(WLAN_GPIO_EXT_POR_N, 0);
- rc = gpio_direction_input(WLAN_GPIO_EXT_POR_N);
- if (rc) {
- pr_err("WLAN reset GPIO %d set direction failed %d\n",
- WLAN_GPIO_EXT_POR_N, rc);
- }
- gpio_free(WLAN_GPIO_EXT_POR_N);
- printk("\n vote against WLAN GPIO 134 done. \n");
- }
- rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_A0,
- PMAPP_CLOCK_VOTE_OFF);
- if (rc) {
- pr_err("%s: Configuring A0 to turn OFF"
- " failed %d\n", __func__, rc);
- }
- }
-
- printk("Interface %s success \n",on?"initialization":"deinitialization");
- resultFlag = 0;
- return 0;
-
-fail_gpio_dir_out:
- gpio_free(WLAN_GPIO_EXT_POR_N);
-vreg_fail:
- index--;
-vreg_clock_vote_fail:
- while (index >= 0) {
- rc = regulator_disable(vreg_info[index].reg);
- if (rc) {
- pr_err("%s:%s vreg disable failed %d\n",
- __func__, vreg_info[index].vreg_id, rc);
- }
- index--;
- }
-fail:
- resultFlag = 1;
- printk("Interface %s failed \n",on?"initialization":"deinitialization");
- return 0;
-}
-
-#else
-/* replace with plaftform specific changes */
-#endif
-
-static int ath6kl_pm_probe(struct platform_device *pdev)
-{
-#ifdef CONFIG_ARCH_MSM7X27A
- msm7x27a_wifi_power(1);
-#else
- /* replace with plaftform specific changes */
-#endif
-
- return 0;
-}
-
-static int ath6kl_pm_remove(struct platform_device *pdev)
-{
-#ifdef CONFIG_ARCH_MSM7X27A
- msm7x27a_wifi_power(0);
-#else
- /* replace with plaftform specific changes */
-#endif
-
- return 0;
-}
-
-static int ath6kl_pm_suspend(struct platform_device *pdev, pm_message_t state)
-{
- return 0;
-}
-
-static inline void *ar6k_priv(struct net_device *dev)
-{
- return (wdev_priv(dev->ieee80211_ptr));
-}
-
-static int ath6kl_pm_resume(struct platform_device *pdev)
-{
- return 0;
-}
-
-
-static struct platform_driver ath6kl_pm_device = {
- .probe = ath6kl_pm_probe,
- .remove = ath6kl_pm_remove,
- .suspend = ath6kl_pm_suspend,
- .resume = ath6kl_pm_resume,
- .driver = {
- .name = "wlan_ar6000_pm_dev",
- },
-};
-
-void __init ath6kl_sdio_init_platform(void)
-{
- char buf[3];
- int length;
-
- platform_driver_register(&ath6kl_pm_device);
-
-#ifdef CONFIG_ARCH_MSM7X27A
- length = snprintf(buf, sizeof(buf), "%d\n", 1 ? 1 : 0);
- android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
- length = snprintf(buf, sizeof(buf), "%d\n", 0 ? 1 : 0);
- android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
-
- A_MDELAY(50);
-#else
- /* replace with plaftform specific changes */
-#endif
-}
-
-void __exit ath6kl_sdio_exit_platform(void)
-{
- char buf[3];
- int length;
- platform_driver_unregister(&ath6kl_pm_device);
-
-#ifdef CONFIG_ARCH_MSM7X27A
- length = snprintf(buf, sizeof(buf), "%d\n", 1 ? 1 : 0);
- /* fall back to polling */
- android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
- length = snprintf(buf, sizeof(buf), "%d\n", 0 ? 1 : 0);
- /* fall back to polling */
- android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
-
- A_MDELAY(1000);
-#else
- /* replace with plaftform specific changes */
-#endif
-}
diff --git a/drivers/net/wireless/ath/ath6kl/pm.c b/drivers/net/wireless/ath/ath6kl/pm.c
deleted file mode 100644
index 5238f30..0000000
--- a/drivers/net/wireless/ath/ath6kl/pm.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "debug.h"
-
-static bool ath6kl_parse_event_pkt_for_wake_lock(struct ath6kl *ar,
- struct sk_buff *skb)
-{
- u16 cmd_id;
- bool need_wake = false;
-
- if (skb->len < sizeof(u16))
- return need_wake;
-
- cmd_id = *(const u16 *) skb->data;
- cmd_id = le16_to_cpu(cmd_id);
-
- if (test_and_clear_bit(WOW_RESUME_PRINT, &ar->flag)) {
- if (cmd_id == WMI_CONNECT_EVENTID)
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "(wow) WMI_CONNECT_EVENTID\n");
- else
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "(wow) wmi event id : 0x%x\n", cmd_id);
- }
-
- switch (cmd_id) {
- case WMI_CONNECT_EVENTID:
- need_wake = true;
- break;
- default:
- /* Don't wake lock the system for other events */
- break;
- }
-
- return need_wake;
-}
-
-static bool ath6kl_parse_ip_pkt_for_wake_lock(struct sk_buff *skb)
-{
- const u8 ipsec_keepalve[] = { 0x11, 0x94, 0x11, 0x94, 0x00,
- 0x09, 0x00, 0x00, 0xff };
- bool need_wake = true;
- u16 size;
- u8 *udp;
- u8 ihl;
-
- if (skb->len >= 24 && (*((u8 *)skb->data + 23) == 0x11)) {
-
- udp = (u8 *)skb->data + 14;
- ihl = (*udp & 0x0f) * sizeof(u32);
- udp += ihl;
- size = 14 + ihl + sizeof(ipsec_keepalve);
-
- if ((skb->len >= size) &&
- !memcmp(udp, ipsec_keepalve, sizeof(ipsec_keepalve) - 3) &&
- udp[8] == 0xff) {
- /*
- * RFC 3948 UDP Encapsulation of IPsec ESP Packets
- * src and dest port must be 4500
- * Receivers MUST NOT depend upon the UDP checksum
- * being zero
- * Sender must use 1 byte payload with 0xff
- * Receiver SHOULD ignore a received NAT-keepalive pkt
- *
- * IPSec over UDP NAT keepalive packet. Just ignore
- */
- need_wake = false;
- }
- }
-
- return need_wake;
-}
-
-static bool ath6kl_parse_data_pkt_for_wake_lock(struct ath6kl *ar,
- struct sk_buff *skb)
-{
- struct net_device *ndev;
- struct ath6kl_vif *vif;
- struct ethhdr *hdr;
- bool need_wake = false;
- u16 dst_port;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return need_wake;
-
- if (skb->len < sizeof(struct ethhdr))
- return need_wake;
-
- hdr = (struct ethhdr *) skb->data;
-
- if (test_and_clear_bit(WOW_RESUME_PRINT, &ar->flag)) {
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "(wow) dest mac:%s, src mac:%s, type/len :%04x\n",
- sec_conv_mac(hdr->h_dest),
- sec_conv_mac(hdr->h_source),
- be16_to_cpu(hdr->h_proto));
- }
-
- if (!is_multicast_ether_addr(hdr->h_dest)) {
- switch (ntohs(hdr->h_proto)) {
- case 0x0800: /* IP */
- need_wake = ath6kl_parse_ip_pkt_for_wake_lock(skb);
- break;
- case 0x888e: /* EAPOL */
- case 0x88c7: /* RSN_PREAUTH */
- case 0x88b4: /* WAPI */
- need_wake = true;
- break;
- default:
- break;
- }
- } else if (!is_broadcast_ether_addr(hdr->h_dest)) {
- if (skb->len >= 14 + 20) { /* mDNS packets */
- u8 *dst_ipaddr = (u8 *)(skb->data + 14 + 20 - 4);
- ndev = vif->ndev;
- if (((dst_ipaddr[3] & 0xf8) == 0xf8) &&
- (vif->nw_type == AP_NETWORK ||
- (ndev->flags & IFF_ALLMULTI ||
- ndev->flags & IFF_MULTICAST)))
- need_wake = true;
- }
- } else if (vif->nw_type == AP_NETWORK) {
- switch (ntohs(hdr->h_proto)) {
- case 0x0800: /* IP */
- if (skb->len >= 14 + 20 + 2) {
- dst_port = *(u16 *)(skb->data + 14 + 20);
- /* dhcp req */
- need_wake = (ntohs(dst_port) == 0x43);
- }
- break;
- case 0x0806:
- need_wake = true;
- default:
- break;
- }
- }
-
- return need_wake;
-}
-
-void ath6kl_config_suspend_wake_lock(struct ath6kl *ar, struct sk_buff *skb,
- bool is_event_pkt)
-{
- struct ath6kl_vif *vif;
-#ifdef CONFIG_HAS_WAKELOCK
- unsigned long wl_timeout = 5;
-#endif
- bool need_wake = false;
-
- vif = ath6kl_vif_first(ar);
- if (!vif)
- return;
-
- if (
-#ifdef CONFIG_HAS_EARLYSUSPEND
- ar->screen_off &&
-#endif
- skb && test_bit(CONNECTED, &vif->flags)) {
- if (is_event_pkt) { /* Ctrl pkt received */
- need_wake =
- ath6kl_parse_event_pkt_for_wake_lock(ar, skb);
- if (need_wake) {
-#ifdef CONFIG_HAS_WAKELOCK
- wl_timeout = 3 * HZ;
-#endif
- }
- } else /* Data pkt received */
- need_wake = ath6kl_parse_data_pkt_for_wake_lock(ar,
- skb);
- }
-
- if (need_wake) {
-#ifdef CONFIG_HAS_WAKELOCK
- /*
- * Keep the host wake up if there is any event
- * and pkt comming in.
- */
- wake_lock_timeout(&ar->wake_lock, wl_timeout);
-#endif
- }
-}
-#ifdef CONFIG_HAS_WAKELOCK
-void ath6kl_p2p_acquire_wakelock(struct ath6kl *ar, int wl_timeout)
-{
- if (!wake_lock_active(&ar->p2p_wake_lock))
- wake_lock_timeout(&ar->p2p_wake_lock, wl_timeout);
- return;
-}
-
-void ath6kl_p2p_release_wakelock(struct ath6kl *ar)
-{
- if (wake_lock_active(&ar->p2p_wake_lock))
- wake_unlock(&ar->p2p_wake_lock);
- return;
-}
-#endif
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void ath6kl_early_suspend(struct early_suspend *handler)
-{
- struct ath6kl *ar = container_of(handler, struct ath6kl, early_suspend);
-
- if (ar)
- ar->screen_off = true;
-}
-
-static void ath6kl_late_resume(struct early_suspend *handler)
-{
- struct ath6kl *ar = container_of(handler, struct ath6kl, early_suspend);
-
- if (ar)
- ar->screen_off = false;
-}
-#endif
-
-void ath6kl_setup_android_resource(struct ath6kl *ar)
-{
-#ifdef CONFIG_HAS_EARLYSUSPEND
- ar->screen_off = false;
- ar->early_suspend.suspend = ath6kl_early_suspend;
- ar->early_suspend.resume = ath6kl_late_resume;
- ar->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
- register_early_suspend(&ar->early_suspend);
-#endif
-#ifdef CONFIG_HAS_WAKELOCK
- wake_lock_init(&ar->wake_lock, WAKE_LOCK_SUSPEND, "ath6kl_suspend_wl");
- wake_lock_init(&ar->p2p_wake_lock,
- WAKE_LOCK_SUSPEND,
- "ath6kl_p2p_suspend_wl");
-#endif
-}
-
-void ath6kl_cleanup_android_resource(struct ath6kl *ar)
-{
-#ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&ar->early_suspend);
-#endif
-#ifdef CONFIG_HAS_WAKELOCK
- wake_lock_destroy(&ar->wake_lock);
- wake_lock_destroy(&ar->p2p_wake_lock);
-#endif
-}
diff --git a/drivers/net/wireless/ath/ath6kl/pm.h b/drivers/net/wireless/ath/ath6kl/pm.h
deleted file mode 100644
index 1ac989b..0000000
--- a/drivers/net/wireless/ath/ath6kl/pm.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-void ath6kl_config_suspend_wake_lock(struct ath6kl *ar, struct sk_buff *skb,
- bool is_event_pkt);
-void ath6kl_setup_android_resource(struct ath6kl *ar);
-void ath6kl_cleanup_android_resource(struct ath6kl *ar);
-#ifdef CONFIG_HAS_WAKELOCK
-void ath6kl_p2p_acquire_wakelock(struct ath6kl *ar, int wl_timeout);
-void ath6kl_p2p_release_wakelock(struct ath6kl *ar);
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
deleted file mode 100755
index d4ea7ad..0000000
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ /dev/null
@@ -1,1534 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <linux/mmc/card.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sdio_func.h>
-#include <linux/mmc/sdio_ids.h>
-#include <linux/mmc/sdio.h>
-#include <linux/mmc/sd.h>
-#include "hif.h"
-#include "hif-ops.h"
-#include "target.h"
-#include "debug.h"
-#include "cfg80211.h"
-
-#define CMD53_ARG_READ 0
-#define CMD53_ARG_WRITE 1
-#define CMD53_ARG_BLOCK_BASIS 1
-#define CMD53_ARG_FIXED_ADDRESS 0
-#define CMD53_ARG_INCR_ADDRESS 1
-
-/*
- * Macro to check if DMA buffer is WORD-aligned and DMA-able.
- * Most host controllers assume the buffer is DMA'able and will
- * bug-check otherwise (i.e. buffers on the stack). virt_addr_valid
- * check fails on stack memory.
- */
-static inline bool buf_needs_bounce(u8 *buf)
-{
- return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf);
-}
-
-static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar)
-{
- struct ath6kl_mbox_info *mbox_info = &ar->mbox_info;
-
- /* EP1 has an extended range */
- mbox_info->htc_addr = HIF_MBOX_BASE_ADDR;
- mbox_info->htc_ext_addr = HIF_MBOX0_EXT_BASE_ADDR;
- mbox_info->htc_ext_sz = HIF_MBOX0_EXT_WIDTH;
- mbox_info->block_size = HIF_MBOX_BLOCK_SIZE;
- mbox_info->gmbox_addr = HIF_GMBOX_BASE_ADDR;
- mbox_info->gmbox_sz = HIF_GMBOX_WIDTH;
-}
-
-static inline void ath6kl_sdio_set_cmd53_arg(u32 *arg, u8 rw, u8 func,
- u8 mode, u8 opcode, u32 addr,
- u16 blksz)
-{
- *arg = (((rw & 1) << 31) |
- ((func & 0x7) << 28) |
- ((mode & 1) << 27) |
- ((opcode & 1) << 26) |
- ((addr & 0x1FFFF) << 9) |
- (blksz & 0x1FF));
-}
-
-static inline void ath6kl_sdio_set_cmd52_arg(u32 *arg, u8 write, u8 raw,
- unsigned int address,
- unsigned char val)
-{
- const u8 func = 0;
-
- *arg = ((write & 1) << 31) |
- ((func & 0x7) << 28) |
- ((raw & 1) << 27) |
- (1 << 26) |
- ((address & 0x1FFFF) << 9) |
- (1 << 8) |
- (val & 0xFF);
-}
-
-static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
- unsigned int address,
- unsigned char byte)
-{
- struct mmc_command io_cmd;
-
- memset(&io_cmd, 0, sizeof(io_cmd));
- ath6kl_sdio_set_cmd52_arg(&io_cmd.arg, 1, 0, address, byte);
- io_cmd.opcode = SD_IO_RW_DIRECT;
- io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
-
- return mmc_wait_for_cmd(card->host, &io_cmd, 0);
-}
-
-static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
- u8 *buf, u32 len)
-{
- int ret = 0;
-
-
- if (request & HIF_WRITE) {
- /* FIXME: looks like ugly workaround for something */
- if (addr >= HIF_MBOX_BASE_ADDR &&
- addr <= HIF_MBOX_END_ADDR)
- addr += (HIF_MBOX_WIDTH - len);
-
- /* FIXME: this also looks like ugly workaround */
- if (addr == HIF_MBOX0_EXT_BASE_ADDR)
- addr += HIF_MBOX0_EXT_WIDTH - len;
-
- if (request & HIF_FIXED_ADDRESS)
- ret = sdio_writesb(func, addr, buf, len);
- else
- ret = sdio_memcpy_toio(func, addr, buf, len);
- } else {
- if (request & HIF_FIXED_ADDRESS)
- ret = sdio_readsb(func, buf, addr, len);
- else
- ret = sdio_memcpy_fromio(func, buf, addr, len);
- }
-
-
- ath6kl_dbg(ATH6KL_DBG_SDIO, "%s addr 0x%x%s buf 0x%p len %d\n",
- request & HIF_WRITE ? "wr" : "rd", addr,
- request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len);
- ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
-
- return ret;
-}
-
-static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
-{
- struct bus_request *bus_req;
-
- spin_lock_bh(&ar_sdio->lock);
-
- if (list_empty(&ar_sdio->bus_req_freeq)) {
- spin_unlock_bh(&ar_sdio->lock);
- return NULL;
- }
-
- bus_req = list_first_entry(&ar_sdio->bus_req_freeq,
- struct bus_request, list);
- list_del(&bus_req->list);
-
- spin_unlock_bh(&ar_sdio->lock);
- ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
- __func__, bus_req);
-
- return bus_req;
-}
-
-static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
- struct bus_request *bus_req)
-{
- ath6kl_dbg(ATH6KL_DBG_SCATTER, "%s: bus request 0x%p\n",
- __func__, bus_req);
-
- spin_lock_bh(&ar_sdio->lock);
- list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
- spin_unlock_bh(&ar_sdio->lock);
-}
-
-static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
- struct mmc_data *data)
-{
- struct scatterlist *sg;
- int i;
-
- data->blksz = HIF_MBOX_BLOCK_SIZE;
- data->blocks = scat_req->len / HIF_MBOX_BLOCK_SIZE;
-
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
- "hif-scatter: (%s) addr: 0x%X, (block len: %d, block count: %d) , (tot:%d,sg:%d)\n",
- (scat_req->req & HIF_WRITE) ? "WR" : "RD", scat_req->addr,
- data->blksz, data->blocks, scat_req->len,
- scat_req->scat_entries);
-
- data->flags = (scat_req->req & HIF_WRITE) ? MMC_DATA_WRITE :
- MMC_DATA_READ;
-
- /* fill SG entries */
- sg = scat_req->sgentries;
- sg_init_table(sg, scat_req->scat_entries);
-
- /* assemble SG list */
- for (i = 0; i < scat_req->scat_entries; i++, sg++) {
- ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
- i, scat_req->scat_list[i].buf,
- scat_req->scat_list[i].len);
-
- sg_set_buf(sg, scat_req->scat_list[i].buf,
- scat_req->scat_list[i].len);
- }
-
- /* set scatter-gather table for request */
- data->sg = scat_req->sgentries;
- data->sg_len = scat_req->scat_entries;
-}
-
-static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
- struct bus_request *req)
-{
- struct mmc_request mmc_req;
- struct mmc_command cmd;
- struct mmc_data data;
- struct hif_scatter_req *scat_req;
- u8 opcode, rw;
- int status, len;
-
- scat_req = req->scat_req;
-
- if (scat_req->virt_scat) {
- len = scat_req->len;
- if (scat_req->req & HIF_BLOCK_BASIS)
- len = round_down(len, HIF_MBOX_BLOCK_SIZE);
-
- status = ath6kl_sdio_io(ar_sdio->func, scat_req->req,
- scat_req->addr, scat_req->virt_dma_buf,
- len);
- goto scat_complete;
- }
-
- memset(&mmc_req, 0, sizeof(struct mmc_request));
- memset(&cmd, 0, sizeof(struct mmc_command));
- memset(&data, 0, sizeof(struct mmc_data));
-
- ath6kl_sdio_setup_scat_data(scat_req, &data);
-
- opcode = (scat_req->req & HIF_FIXED_ADDRESS) ?
- CMD53_ARG_FIXED_ADDRESS : CMD53_ARG_INCR_ADDRESS;
-
- rw = (scat_req->req & HIF_WRITE) ? CMD53_ARG_WRITE : CMD53_ARG_READ;
-
- /* Fixup the address so that the last byte will fall on MBOX EOM */
- if (scat_req->req & HIF_WRITE) {
- if (scat_req->addr == HIF_MBOX_BASE_ADDR)
- scat_req->addr += HIF_MBOX_WIDTH - scat_req->len;
- else
- /* Uses extended address range */
- scat_req->addr += HIF_MBOX0_EXT_WIDTH - scat_req->len;
- }
-
- /* set command argument */
- ath6kl_sdio_set_cmd53_arg(&cmd.arg, rw, ar_sdio->func->num,
- CMD53_ARG_BLOCK_BASIS, opcode, scat_req->addr,
- data.blocks);
-
- cmd.opcode = SD_IO_RW_EXTENDED;
- cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
-
- mmc_req.cmd = &cmd;
- mmc_req.data = &data;
-
- mmc_set_data_timeout(&data, ar_sdio->func->card);
- /* synchronous call to process request */
- mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
-
- status = cmd.error ? cmd.error : data.error;
-
-scat_complete:
- scat_req->status = status;
-
- if (scat_req->status)
- ath6kl_err("Scatter write request failed:%d\n",
- scat_req->status);
-
- if (scat_req->req & HIF_ASYNCHRONOUS)
- scat_req->complete(ar_sdio->ar->htc_target, scat_req);
-
- return status;
-}
-
-static int ath6kl_sdio_alloc_prep_scat_req(struct ath6kl_sdio *ar_sdio,
- int n_scat_entry, int n_scat_req,
- bool virt_scat)
-{
- struct hif_scatter_req *s_req;
- struct bus_request *bus_req;
- int i, scat_req_sz, scat_list_sz, sg_sz = 0, buf_sz;
- u8 *virt_buf;
-
- scat_list_sz = (n_scat_entry - 1) * sizeof(struct hif_scatter_item);
- scat_req_sz = sizeof(*s_req) + scat_list_sz;
-
- if (!virt_scat)
- sg_sz = sizeof(struct scatterlist) * n_scat_entry;
- else
- buf_sz = 2 * L1_CACHE_BYTES +
- ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
-
- for (i = 0; i < n_scat_req; i++) {
- /* allocate the scatter request */
- s_req = kzalloc(scat_req_sz, GFP_KERNEL);
- if (!s_req)
- return -ENOMEM;
-
- if (virt_scat) {
- virt_buf = kzalloc(buf_sz, GFP_KERNEL);
- if (!virt_buf) {
- kfree(s_req);
- return -ENOMEM;
- }
-
- s_req->virt_dma_buf =
- (u8 *)L1_CACHE_ALIGN((unsigned long)virt_buf);
- } else {
- /* allocate sglist */
- s_req->sgentries = kzalloc(sg_sz, GFP_KERNEL);
-
- if (!s_req->sgentries) {
- kfree(s_req);
- return -ENOMEM;
- }
- }
-
- /* allocate a bus request for this scatter request */
- bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
- if (!bus_req) {
- kfree(s_req->sgentries);
- kfree(s_req->virt_dma_buf);
- kfree(s_req);
- return -ENOMEM;
- }
-
- /* assign the scatter request to this bus request */
- bus_req->scat_req = s_req;
- s_req->busrequest = bus_req;
-
- s_req->virt_scat = virt_scat;
-
- /* add it to the scatter pool */
- hif_scatter_req_add(ar_sdio->ar, s_req);
- }
-
- return 0;
-}
-
-static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
- u32 len, u32 request)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- u8 *tbuf = NULL;
- int ret;
- bool bounced = false;
-
- if (request & HIF_BLOCK_BASIS)
- len = round_down(len, HIF_MBOX_BLOCK_SIZE);
-
- if (buf_needs_bounce(buf)) {
- if (!ar_sdio->dma_buffer)
- return -ENOMEM;
- mutex_lock(&ar_sdio->dma_buffer_mutex);
- tbuf = ar_sdio->dma_buffer;
-
- if (request & HIF_WRITE)
- memcpy(tbuf, buf, len);
-
- bounced = true;
- } else
- tbuf = buf;
-
- ret = ath6kl_sdio_io(ar_sdio->func, request, addr, tbuf, len);
- if ((request & HIF_READ) && bounced)
- memcpy(buf, tbuf, len);
-
- if (bounced)
- mutex_unlock(&ar_sdio->dma_buffer_mutex);
-
- return ret;
-}
-
-static int ath6kl_sdio_read_write_sync_pri(struct ath6kl *ar, u32 addr, u8 *buf,
- u32 len, u32 request)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- int ret;
-
- sdio_claim_host(ar_sdio->func);
- ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len, request);
- sdio_release_host(ar_sdio->func);
- return ret;
-}
-
-
-static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
- struct bus_request *req)
-{
- if (req->scat_req)
- ath6kl_sdio_scat_rw(ar_sdio, req);
- else {
- void *context;
- int status;
- u32 addr, len, request;
- u8 *buf;
-
- addr = req->address;
- len = req->length;
- request = req->request;
- buf = req->buffer;
-
- context = req->packet;
- ath6kl_sdio_free_bus_req(ar_sdio, req);
-
- status = ath6kl_sdio_read_write_sync(ar_sdio->ar, addr, buf,
- len, request);
- ath6kl_hif_rw_comp_handler(context, status);
- }
-}
-
-static void ath6kl_sdio_write_async_work(struct work_struct *work)
-{
- struct ath6kl_sdio *ar_sdio;
- struct bus_request *req, *tmp_req;
-
- ar_sdio = container_of(work, struct ath6kl_sdio, wr_async_work);
-
- spin_lock_bh(&ar_sdio->wr_async_lock);
- list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) {
- list_del(&req->list);
- spin_unlock_bh(&ar_sdio->wr_async_lock);
- sdio_claim_host(ar_sdio->func);
- __ath6kl_sdio_write_async(ar_sdio, req);
- sdio_release_host(ar_sdio->func);
- spin_lock_bh(&ar_sdio->wr_async_lock);
- }
- spin_unlock_bh(&ar_sdio->wr_async_lock);
-}
-
-static void ath6kl_sdio_irq_handler(struct sdio_func *func)
-{
- int status;
- struct ath6kl_sdio *ar_sdio;
-
- ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n");
-
- ar_sdio = sdio_get_drvdata(func);
- atomic_set(&ar_sdio->irq_handling, 1);
- /*
- * Release the host during interrups so we can pick it back up when
- * we process commands.
- */
- sdio_release_host(ar_sdio->func);
-
- status = ath6kl_hif_intr_bh_handler(ar_sdio->ar);
- sdio_claim_host(ar_sdio->func);
- atomic_set(&ar_sdio->irq_handling, 0);
- wake_up(&ar_sdio->irq_wq);
-
- WARN_ON_ONCE(status && status != -ECANCELED);
-}
-
-static int ath6kl_sdio_power_on(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- int ret = 0;
-
- if (!ar_sdio->is_disabled)
- return 0;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power on\n");
-
- sdio_claim_host(func);
-
- ret = sdio_enable_func(func);
- if (ret) {
- ath6kl_err("Unable to enable sdio func: %d)\n", ret);
- sdio_release_host(func);
- return ret;
- }
-
- sdio_release_host(func);
-
- /*
- * Wait for hardware to initialise. It should take a lot less than
- * 10 ms but let's be conservative here.
- */
- msleep(10);
-
- ar_sdio->is_disabled = false;
-
- return ret;
-}
-
-static int ath6kl_sdio_power_off(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- int ret;
-
- if (ar_sdio->is_disabled)
- return 0;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power off\n");
-
- /* Disable the card */
- sdio_claim_host(ar_sdio->func);
- ret = sdio_disable_func(ar_sdio->func);
- sdio_release_host(ar_sdio->func);
-
- if (ret)
- return ret;
-
- ar_sdio->is_disabled = true;
-
- return ret;
-}
-
-static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
- u32 length, u32 request,
- struct htc_packet *packet)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct bus_request *bus_req;
-
- bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
-
- if (!bus_req)
- return -ENOMEM;
-
- bus_req->address = address;
- bus_req->buffer = buffer;
- bus_req->length = length;
- bus_req->request = request;
- bus_req->packet = packet;
-
- spin_lock_bh(&ar_sdio->wr_async_lock);
- list_add_tail(&bus_req->list, &ar_sdio->wr_asyncq);
- spin_unlock_bh(&ar_sdio->wr_async_lock);
- queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
-
- return 0;
-}
-
-static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- int ret;
-
- sdio_claim_host(ar_sdio->func);
-
- /* Register the isr */
- ret = sdio_claim_irq(ar_sdio->func, ath6kl_sdio_irq_handler);
- if (ret)
- ath6kl_err("Failed to claim sdio irq: %d\n", ret);
-
- sdio_release_host(ar_sdio->func);
-}
-
-static bool ath6kl_sdio_is_on_irq(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
-
- return !atomic_read(&ar_sdio->irq_handling);
-}
-
-static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- int ret;
-
- sdio_claim_host(ar_sdio->func);
-
- if (atomic_read(&ar_sdio->irq_handling)) {
- sdio_release_host(ar_sdio->func);
-
- ret = wait_event_interruptible(ar_sdio->irq_wq,
- ath6kl_sdio_is_on_irq(ar));
- if (ret)
- return;
-
- sdio_claim_host(ar_sdio->func);
- }
-
- ret = sdio_release_irq(ar_sdio->func);
- if (ret)
- ath6kl_err("Failed to release sdio irq: %d\n", ret);
-
- sdio_release_host(ar_sdio->func);
-}
-
-static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct hif_scatter_req *node = NULL;
-
- spin_lock_bh(&ar_sdio->scat_lock);
-
- if (!list_empty(&ar_sdio->scat_req)) {
- node = list_first_entry(&ar_sdio->scat_req,
- struct hif_scatter_req, list);
- list_del(&node->list);
-
- node->scat_q_depth = get_queue_depth(&ar_sdio->scat_req);
- }
-
- spin_unlock_bh(&ar_sdio->scat_lock);
-
- return node;
-}
-
-static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar,
- struct hif_scatter_req *s_req)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
-
- spin_lock_bh(&ar_sdio->scat_lock);
-
- list_add_tail(&s_req->list, &ar_sdio->scat_req);
-
- spin_unlock_bh(&ar_sdio->scat_lock);
-
-}
-
-/* scatter gather read write request */
-static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
- struct hif_scatter_req *scat_req)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- u32 request = scat_req->req;
- int status = 0;
-
- if (!scat_req->len)
- return -EINVAL;
-
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
- "hif-scatter: total len: %d scatter entries: %d\n",
- scat_req->len, scat_req->scat_entries);
-
- if (request & HIF_SYNCHRONOUS) {
- sdio_claim_host(ar_sdio->func);
- status = ath6kl_sdio_scat_rw(ar_sdio, scat_req->busrequest);
- sdio_release_host(ar_sdio->func);
- }
- else {
- spin_lock_bh(&ar_sdio->wr_async_lock);
- list_add_tail(&scat_req->busrequest->list, &ar_sdio->wr_asyncq);
- spin_unlock_bh(&ar_sdio->wr_async_lock);
- queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
- }
-
- return status;
-}
-
-/* clean up scatter support */
-static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct hif_scatter_req *s_req, *tmp_req;
-
- /* empty the free list */
- spin_lock_bh(&ar_sdio->scat_lock);
- list_for_each_entry_safe(s_req, tmp_req, &ar_sdio->scat_req, list) {
- list_del(&s_req->list);
- spin_unlock_bh(&ar_sdio->scat_lock);
-
- /*
- * FIXME: should we also call completion handler with
- * ath6kl_hif_rw_comp_handler() with status -ECANCELED so
- * that the packet is properly freed?
- */
- if (s_req->busrequest)
- ath6kl_sdio_free_bus_req(ar_sdio, s_req->busrequest);
- kfree(s_req->virt_dma_buf);
- kfree(s_req->sgentries);
- kfree(s_req);
-
- spin_lock_bh(&ar_sdio->scat_lock);
- }
- spin_unlock_bh(&ar_sdio->scat_lock);
-}
-
-/* setup of HIF scatter resources */
-static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct htc_target *target = ar->htc_target;
- int ret;
- bool virt_scat = false;
-
- if (ar_sdio->scatter_enabled)
- return 0;
-
- ar_sdio->scatter_enabled = true;
-
- /* check if host supports scatter and it meets our requirements */
- if (ar_sdio->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
- ath6kl_err("host only supports scatter of :%d entries, need: %d\n",
- ar_sdio->func->card->host->max_segs,
- MAX_SCATTER_ENTRIES_PER_REQ);
- virt_scat = true;
- }
-
- if (!virt_scat) {
- ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
- MAX_SCATTER_ENTRIES_PER_REQ,
- MAX_SCATTER_REQUESTS, virt_scat);
-
- if (!ret) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "hif-scatter enabled requests %d entries %d\n",
- MAX_SCATTER_REQUESTS,
- MAX_SCATTER_ENTRIES_PER_REQ);
-
- target->max_scat_entries = MAX_SCATTER_ENTRIES_PER_REQ;
- target->max_xfer_szper_scatreq =
- MAX_SCATTER_REQ_TRANSFER_SIZE;
- } else {
- ath6kl_sdio_cleanup_scatter(ar);
- ath6kl_warn("hif scatter resource setup failed, trying virtual scatter method\n");
- }
- }
-
- if (virt_scat || ret) {
- ret = ath6kl_sdio_alloc_prep_scat_req(ar_sdio,
- ATH6KL_SCATTER_ENTRIES_PER_REQ,
- ATH6KL_SCATTER_REQS, virt_scat);
-
- if (ret) {
- ath6kl_err("failed to alloc virtual scatter resources !\n");
- ath6kl_sdio_cleanup_scatter(ar);
- return ret;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "virtual scatter enabled requests %d entries %d\n",
- ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
-
- target->max_scat_entries = ATH6KL_SCATTER_ENTRIES_PER_REQ;
- target->max_xfer_szper_scatreq =
- ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
- }
-
- return 0;
-}
-
-static int ath6kl_sdio_config(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- int ret;
-
- sdio_claim_host(func);
-
- /* give us some time to enable, in ms */
- func->enable_timeout = 100;
-
- ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
- if (ret) {
- ath6kl_err("Set sdio block size %d failed: %d)\n",
- HIF_MBOX_BLOCK_SIZE, ret);
- goto out;
- }
-
-out:
- sdio_release_host(func);
-
- return ret;
-}
-
-static int ath6kl_sdio_setup_irq_mode(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- int ret = 0;
-
- sdio_claim_host(func);
-
- if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >=
- MANUFACTURER_ID_AR6003_BASE) {
- /* enable 4-bit ASYNC interrupt on AR6003 or later */
- ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card,
- CCCR_SDIO_IRQ_MODE_REG,
- SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
- if (ret) {
- ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
- ret);
- goto out;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "4-bit async irq mode enabled\n");
- }
-
-out:
- sdio_release_host(func);
-
- return ret;
-}
-
-static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- mmc_pm_flag_t flags;
- int ret;
-
- flags = sdio_get_host_pm_caps(func);
-
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags);
-#ifdef CONFIG_MACH_PX
-#else
- if (!(flags & MMC_PM_WAKE_SDIO_IRQ) ||
- !(flags & MMC_PM_KEEP_POWER))
- return -EINVAL;
-#endif
-
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
- if (ret) {
- ath6kl_err("set sdio keep pwr flag failed: %d\n", ret);
- return ret;
- }
-
- /* sdio irq wakes up host */
- ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ);
- if (ret)
- ath6kl_err("set sdio wake irq flag failed: %d\n", ret);
-
- return ret;
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct sdio_func *func = ar_sdio->func;
- mmc_pm_flag_t flags;
- bool try_deepsleep = false;
- int ret;
- struct ath6kl_vif *vif;
- int connected = 0;
- int force_sleep_policy = 0;
-
- vif = ath6kl_vif_first(ar);
- connected = test_bit(CONNECTED, &vif->flags);
- force_sleep_policy = test_bit(SLEEP_POLICY_ENABLED, &vif->flags);
-
- if (force_sleep_policy) {
- try_deepsleep = true;
- goto deep_sleep;
- }
-
- if (ar->state == ATH6KL_STATE_SCHED_SCAN) {
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n");
-
- ret = ath6kl_set_sdio_pm_caps(ar);
-
- if (ret)
- return ret;
-
- ret = ath6kl_cfg80211_suspend(ar,
- ATH6KL_CFG_SUSPEND_SCHED_SCAN,
- NULL);
- return ret;
-
- }
-
- if (ar->suspend_mode == WLAN_POWER_STATE_WOW ||
- (!ar->suspend_mode && wow)) {
-
- ret = ath6kl_set_sdio_pm_caps(ar);
- if (ret)
- return ret;
-
- if (connected) {
- ret = ath6kl_cfg80211_suspend(ar,
- ATH6KL_CFG_SUSPEND_WOW, wow);
- return ret;
- } else {
- if (!ar->wow_suspend_mode ||
- ar->wow_suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP)
- try_deepsleep = true;
- else if (ar->wow_suspend_mode \
- == WLAN_POWER_STATE_CUT_PWR)
- goto cut_pwr;
- }
- }
-
-deep_sleep:
- if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP ||
- !ar->suspend_mode || try_deepsleep) {
-
-#ifdef CONFIG_MACH_PX
- ret = ath6kl_set_sdio_pm_caps(ar);
- if (ret)
- return ret;
-#else
- flags = sdio_get_host_pm_caps(func);
- if (!(flags & MMC_PM_KEEP_POWER))
- return -1;
-
- ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
- if (ret)
- return ret;
-
- /*
- * Workaround to support Deep Sleep with MSM, set the host pm
- * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable
- * the sdc2_clock and internally allows MSM to enter
- * TCXO shutdown properly.
- */
- if ((flags & MMC_PM_WAKE_SDIO_IRQ)) {
- ret = sdio_set_host_pm_flags(func,
- MMC_PM_WAKE_SDIO_IRQ);
- if (ret)
- return ret;
- }
-#endif
- ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP,
- NULL);
-
- return ret;
- }
-
-cut_pwr:
- return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL);
-}
-
-static int ath6kl_sdio_resume(struct ath6kl *ar)
-{
-
-#if !defined(CONFIG_MACH_P8LTE)
- ath6kl_sdio_setup_irq_mode(ar);
-#endif
-
- switch (ar->state) {
- case ATH6KL_STATE_OFF:
- case ATH6KL_STATE_CUTPOWER:
- ath6kl_dbg(ATH6KL_DBG_SUSPEND,
- "sdio resume configuring sdio\n");
-
- /* need to set sdio settings after power is cut from sdio */
- ath6kl_sdio_config(ar);
- break;
-
- case ATH6KL_STATE_ON:
- break;
-
- case ATH6KL_STATE_DEEPSLEEP:
- break;
-
- case ATH6KL_STATE_WOW:
- break;
-
- case ATH6KL_STATE_SCHED_SCAN:
- break;
-
- case ATH6KL_STATE_SUSPENDING:
- break;
-
- case ATH6KL_STATE_RESUMING:
- break;
- }
-
- ath6kl_cfg80211_resume(ar);
-
- return 0;
-}
-#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)) */
-
-/* set the window address register (using 4-byte register access ). */
-static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
-{
- int status;
- u8 addr_val[4];
- s32 i;
-
- /*
- * Write bytes 1,2,3 of the register to set the upper address bytes,
- * the LSB is written last to initiate the access cycle
- */
-
- for (i = 1; i <= 3; i++) {
- /*
- * Fill the buffer with the address byte value we want to
- * hit 4 times.
- */
- memset(addr_val, ((u8 *)&addr)[i], 4);
-
- /*
- * Hit each byte of the register address with a 4-byte
- * write operation to the same address, this is a harmless
- * operation.
- */
- status = ath6kl_sdio_read_write_sync_pri(ar, reg_addr + i, addr_val,
- 4, HIF_WR_SYNC_BYTE_FIX);
- if (status)
- break;
- }
-
- if (status) {
- ath6kl_err("%s: failed to write initial bytes of 0x%x "
- "to window reg: 0x%X\n", __func__,
- addr, reg_addr);
- return status;
- }
-
- /*
- * Write the address register again, this time write the whole
- * 4-byte value. The effect here is that the LSB write causes the
- * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
- * effect since we are writing the same values again
- */
- status = ath6kl_sdio_read_write_sync_pri(ar, reg_addr, (u8 *)(&addr),
- 4, HIF_WR_SYNC_BYTE_INC);
-
- if (status) {
- ath6kl_err("%s: failed to write 0x%x to window reg: 0x%X\n",
- __func__, addr, reg_addr);
- return status;
- }
-
- return 0;
-}
-
-static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
-{
- int status;
-
- /* set window register to start read cycle */
- status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
- address);
-
- if (status)
- return status;
-
- /* read the data */
- status = ath6kl_sdio_read_write_sync_pri(ar, WINDOW_DATA_ADDRESS,
- (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC);
- if (status) {
- ath6kl_err("%s: failed to read from window data addr\n",
- __func__);
- return status;
- }
-
- return status;
-}
-
-static int ath6kl_sdio_diag_write32(struct ath6kl *ar, u32 address,
- __le32 data)
-{
- int status;
- u32 val = (__force u32) data;
-
- /* set write data */
- status = ath6kl_sdio_read_write_sync_pri(ar, WINDOW_DATA_ADDRESS,
- (u8 *) &val, sizeof(u32), HIF_WR_SYNC_BYTE_INC);
- if (status) {
- ath6kl_err("%s: failed to write 0x%x to window data addr\n",
- __func__, data);
- return status;
- }
-
- /* set window register, which starts the write cycle */
- return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
- address);
-}
-
-static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
-{
- u32 addr;
- unsigned long timeout;
- int ret;
-
- ar->bmi.cmd_credits = 0;
-
- /* Read the counter register to get the command credits */
- addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
-
- timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
- while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
-
- /*
- * Hit the credit counter with a 4-byte access, the first byte
- * read will hit the counter and cause a decrement, while the
- * remaining 3 bytes has no effect. The rationale behind this
- * is to make all HIF accesses 4-byte aligned.
- */
- ret = ath6kl_sdio_read_write_sync_pri(ar, addr,
- (u8 *)&ar->bmi.cmd_credits, 4,
- HIF_RD_SYNC_BYTE_INC);
- if (ret) {
- ath6kl_err("Unable to decrement the command credit "
- "count register: %d\n", ret);
- return ret;
- }
-
- /* The counter is only 8 bits.
- * Ignore anything in the upper 3 bytes
- */
- ar->bmi.cmd_credits &= 0xFF;
- }
-
- if (!ar->bmi.cmd_credits) {
- ath6kl_err("bmi communication timeout\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
-{
- unsigned long timeout;
- u32 rx_word = 0;
- int ret = 0;
-
- timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
- while ((time_before(jiffies, timeout)) && !rx_word) {
- ret = ath6kl_sdio_read_write_sync_pri(ar,
- RX_LOOKAHEAD_VALID_ADDRESS,
- (u8 *)&rx_word, sizeof(rx_word),
- HIF_RD_SYNC_BYTE_INC);
- if (ret) {
- ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
- return ret;
- }
-
- /* all we really want is one bit */
- rx_word &= (1 << ENDPOINT1);
- }
-
- if (!rx_word) {
- ath6kl_err("bmi_recv_buf FIFO empty\n");
- return -EINVAL;
- }
-
- return ret;
-}
-
-static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
-{
- int ret;
- u32 addr;
-
- ret = ath6kl_sdio_bmi_credits(ar);
- if (ret)
- return ret;
-
- addr = ar->mbox_info.htc_addr;
-
- ret = ath6kl_sdio_read_write_sync_pri(ar, addr, buf, len,
- HIF_WR_SYNC_BYTE_INC);
- if (ret)
- ath6kl_err("unable to send the bmi data to the device\n");
-
- return ret;
-}
-
-static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
-{
- int ret;
- u32 addr;
-
- /*
- * During normal bootup, small reads may be required.
- * Rather than issue an HIF Read and then wait as the Target
- * adds successive bytes to the FIFO, we wait here until
- * we know that response data is available.
- *
- * This allows us to cleanly timeout on an unexpected
- * Target failure rather than risk problems at the HIF level.
- * In particular, this avoids SDIO timeouts and possibly garbage
- * data on some host controllers. And on an interconnect
- * such as Compact Flash (as well as some SDIO masters) which
- * does not provide any indication on data timeout, it avoids
- * a potential hang or garbage response.
- *
- * Synchronization is more difficult for reads larger than the
- * size of the MBOX FIFO (128B), because the Target is unable
- * to push the 129th byte of data until AFTER the Host posts an
- * HIF Read and removes some FIFO data. So for large reads the
- * Host proceeds to post an HIF Read BEFORE all the data is
- * actually available to read. Fortunately, large BMI reads do
- * not occur in practice -- they're supported for debug/development.
- *
- * So Host/Target BMI synchronization is divided into these cases:
- * CASE 1: length < 4
- * Should not happen
- *
- * CASE 2: 4 <= length <= 128
- * Wait for first 4 bytes to be in FIFO
- * If CONSERVATIVE_BMI_READ is enabled, also wait for
- * a BMI command credit, which indicates that the ENTIRE
- * response is available in the the FIFO
- *
- * CASE 3: length > 128
- * Wait for the first 4 bytes to be in FIFO
- *
- * For most uses, a small timeout should be sufficient and we will
- * usually see a response quickly; but there may be some unusual
- * (debug) cases of BMI_EXECUTE where we want an larger timeout.
- * For now, we use an unbounded busy loop while waiting for
- * BMI_EXECUTE.
- *
- * If BMI_EXECUTE ever needs to support longer-latency execution,
- * especially in production, this code needs to be enhanced to sleep
- * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
- * a function of Host processor speed.
- */
- if (len >= 4) { /* NB: Currently, always true */
- ret = ath6kl_bmi_get_rx_lkahd(ar);
- if (ret)
- return ret;
- }
-
- addr = ar->mbox_info.htc_addr;
- ret = ath6kl_sdio_read_write_sync_pri(ar, addr, buf, len,
- HIF_RD_SYNC_BYTE_INC);
- if (ret) {
- ath6kl_err("Unable to read the bmi data from the device: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static void ath6kl_sdio_stop(struct ath6kl *ar)
-{
- struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
- struct bus_request *req, *tmp_req;
- void *context;
-
- /* FIXME: make sure that wq is not queued again */
-
- cancel_work_sync(&ar_sdio->wr_async_work);
-
- spin_lock_bh(&ar_sdio->wr_async_lock);
-
- list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) {
- list_del(&req->list);
-
- if (req->scat_req) {
- /* this is a scatter gather request */
- req->scat_req->status = -ECANCELED;
- req->scat_req->complete(ar_sdio->ar->htc_target,
- req->scat_req);
- } else {
- context = req->packet;
- ath6kl_sdio_free_bus_req(ar_sdio, req);
- ath6kl_hif_rw_comp_handler(context, -ECANCELED);
- }
- }
-
- spin_unlock_bh(&ar_sdio->wr_async_lock);
-
- WARN_ON(get_queue_depth(&ar_sdio->scat_req) != 4);
-}
-
-static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
- .read_write_sync = ath6kl_sdio_read_write_sync_pri,
- .write_async = ath6kl_sdio_write_async,
- .irq_enable = ath6kl_sdio_irq_enable,
- .irq_disable = ath6kl_sdio_irq_disable,
- .scatter_req_get = ath6kl_sdio_scatter_req_get,
- .scatter_req_add = ath6kl_sdio_scatter_req_add,
- .enable_scatter = ath6kl_sdio_enable_scatter,
- .scat_req_rw = ath6kl_sdio_async_rw_scatter,
- .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
- .suspend = ath6kl_sdio_suspend,
- .resume = ath6kl_sdio_resume,
-#endif
- .diag_read32 = ath6kl_sdio_diag_read32,
- .diag_write32 = ath6kl_sdio_diag_write32,
- .bmi_read = ath6kl_sdio_bmi_read,
- .bmi_write = ath6kl_sdio_bmi_write,
- .power_on = ath6kl_sdio_power_on,
- .power_off = ath6kl_sdio_power_off,
- .stop = ath6kl_sdio_stop,
-};
-
-#if defined(CONFIG_PM_SLEEP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
-
-/*
- * Empty handlers so that mmc subsystem doesn't remove us entirely during
- * suspend. We instead follow cfg80211 suspend/resume handlers.
- */
-static int ath6kl_sdio_pm_suspend(struct device *device)
-{
-#ifdef CONFIG_MACH_PX
- struct sdio_func *func;
- struct ath6kl_sdio *ar_sdio;
- int ret;
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm suspend\n");
-
- func = dev_to_sdio_func(device);
- ar_sdio = sdio_get_drvdata(func);
-
- sdio_release_host(func);
- ret = ath6kl_sdio_suspend(ar_sdio->ar, NULL);
- sdio_claim_host(func);
-
- return ret;
-#else
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm suspend\n");
-
- return 0;
-#endif
-}
-
-static int ath6kl_sdio_pm_resume(struct device *device)
-{
-#ifdef CONFIG_MACH_PX
- struct sdio_func *func;
- struct ath6kl_sdio *ar_sdio;
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm resume\n");
-
- func = dev_to_sdio_func(device);
- ar_sdio = sdio_get_drvdata(func);
-
- return ath6kl_sdio_resume(ar_sdio->ar);
-#else
- ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio pm resume\n");
-
- return 0;
-#endif
-}
-
-#ifdef CONFIG_MACH_PX
-static struct dev_pm_ops ath6kl_sdio_pm_ops = {
- .suspend = ath6kl_sdio_pm_suspend,
- .resume = ath6kl_sdio_pm_resume,
-};
-#else
-static SIMPLE_DEV_PM_OPS(ath6kl_sdio_pm_ops, ath6kl_sdio_pm_suspend,
- ath6kl_sdio_pm_resume);
-#endif
-
-#define ATH6KL_SDIO_PM_OPS (&ath6kl_sdio_pm_ops)
-
-#else
-
-#define ATH6KL_SDIO_PM_OPS NULL
-
-#endif /* CONFIG_PM_SLEEP */
-
-static int ath6kl_sdio_probe(struct sdio_func *func,
- const struct sdio_device_id *id)
-{
- int ret;
- struct ath6kl_sdio *ar_sdio;
- struct ath6kl *ar;
- int count;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",
- func->num, func->vendor, func->device,
- func->max_blksize, func->cur_blksize);
-
- ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
- if (!ar_sdio)
- return -ENOMEM;
-
- ar_sdio->dma_buffer = kzalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
- if (!ar_sdio->dma_buffer) {
- ret = -ENOMEM;
- goto err_hif;
- }
-
- ar_sdio->func = func;
- sdio_set_drvdata(func, ar_sdio);
-
- ar_sdio->id = id;
- ar_sdio->is_disabled = true;
-
- spin_lock_init(&ar_sdio->lock);
- spin_lock_init(&ar_sdio->scat_lock);
- spin_lock_init(&ar_sdio->wr_async_lock);
- mutex_init(&ar_sdio->dma_buffer_mutex);
-
- INIT_LIST_HEAD(&ar_sdio->scat_req);
- INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
- INIT_LIST_HEAD(&ar_sdio->wr_asyncq);
-
- INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);
- init_waitqueue_head(&ar_sdio->irq_wq);
-
- for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
- ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
-
- ar = ath6kl_core_alloc(&ar_sdio->func->dev);
- if (!ar) {
- ath6kl_err("Failed to alloc ath6kl core\n");
- ret = -ENOMEM;
- goto err_dma;
- }
-
- ar_sdio->ar = ar;
- ar->hif_type = ATH6KL_HIF_TYPE_SDIO;
- ar->hif_priv = ar_sdio;
- ar->hif_ops = &ath6kl_sdio_ops;
- ar->bmi.max_data_size = 256;
-
- ath6kl_sdio_set_mbox_info(ar);
-
- ret = ath6kl_sdio_setup_irq_mode(ar);
- if (ret) {
- ath6kl_err("Failed to setup sdio irq mode: %d\n", ret);
- goto err_core_alloc;
- }
-
- ret = ath6kl_sdio_config(ar);
- if (ret) {
- ath6kl_err("Failed to config sdio: %d\n", ret);
- goto err_core_alloc;
- }
-
- ret = ath6kl_core_init(ar);
- if (ret) {
- ath6kl_err("Failed to init ath6kl core\n");
- goto err_core_alloc;
- }
-
- return ret;
-
-err_core_alloc:
- ath6kl_core_free(ar_sdio->ar);
-err_dma:
- kfree(ar_sdio->dma_buffer);
-err_hif:
- kfree(ar_sdio);
-
- return ret;
-}
-
-static void ath6kl_sdio_remove(struct sdio_func *func)
-{
- struct ath6kl_sdio *ar_sdio;
- struct ath6kl_vif *vif;
- long timeleft;
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "sdio removed func %d vendor 0x%x device 0x%x\n",
- func->num, func->vendor, func->device);
-
- ar_sdio = sdio_get_drvdata(func);
-#ifdef CONFIG_MACH_PX
- vif = ath6kl_vif_first(ar_sdio->ar);
- /* Wait for Wmi event to be ready */
- timeleft = wait_event_interruptible_timeout(ar_sdio->ar->event_wq,
- ar_sdio->ar->state == ATH6KL_STATE_ON,
- WMI_TIMEOUT);
-
- ath6kl_hif_rx_control(ar_sdio->ar->htc_target->dev, false);
- vif->sdio_remove = true;
-#endif
-
- ath6kl_stop_txrx(ar_sdio->ar);
- cancel_work_sync(&ar_sdio->wr_async_work);
-
- ath6kl_core_cleanup(ar_sdio->ar);
-
- kfree(ar_sdio->dma_buffer);
- kfree(ar_sdio);
-}
-
-static const struct sdio_device_id ath6kl_sdio_devices[] = {
- {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))},
- {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))},
- {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))},
- {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))},
- {},
-};
-
-MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
-
-static struct sdio_driver ath6kl_sdio_driver = {
- .name = "ath6kl_sdio",
- .id_table = ath6kl_sdio_devices,
- .probe = ath6kl_sdio_probe,
- .remove = ath6kl_sdio_remove,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
- .drv.pm = ATH6KL_SDIO_PM_OPS,
-#endif
-};
-
-static int __init ath6kl_sdio_init(void)
-{
- int ret;
-#ifdef CONFIG_MACH_PX
- ath6kl_sdio_init_c210();
-#else
- ath6kl_sdio_init_msm();
-#endif
- ret = sdio_register_driver(&ath6kl_sdio_driver);
- if (ret)
- ath6kl_err("sdio driver registration failed: %d\n", ret);
-
- return ret;
-}
-
-static void __exit ath6kl_sdio_exit(void)
-{
- sdio_unregister_driver(&ath6kl_sdio_driver);
-#ifdef CONFIG_MACH_PX
- ath6kl_sdio_exit_c210();
-#else
- ath6kl_sdio_exit_msm();
-#endif
-
-}
-
-module_init(ath6kl_sdio_init);
-module_exit(ath6kl_sdio_exit);
-
-MODULE_AUTHOR("Atheros Communications, Inc.");
-MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
-MODULE_LICENSE("Dual BSD/GPL");
-
-MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/softmac.c b/drivers/net/wireless/ath/ath6kl/softmac.c
deleted file mode 100644
index 3725871..0000000
--- a/drivers/net/wireless/ath/ath6kl/softmac.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (c) 2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "debug.h"
-#include <linux/vmalloc.h>
-#include <linux/random.h>
-#define MAC_FILE "ath6k/AR6003/hw2.1.1/softmac"
-
-typedef char A_CHAR;
-extern int android_readwrite_file(const A_CHAR *filename, A_CHAR *rbuf, const A_CHAR *wbuf, size_t length);
-
-/* Bleh, same offsets. */
-#define AR6003_MAC_ADDRESS_OFFSET 0x16
-#define AR6004_MAC_ADDRESS_OFFSET 0x16
-
-/* Global variables, sane coding be damned. */
-u8 *ath6kl_softmac;
-size_t ath6kl_softmac_len;
-
-static void ath6kl_calculate_crc(u32 target_type, u8 *data, size_t len)
-{
- u16 *crc, *data_idx;
- u16 checksum;
- int i;
-
- if (target_type == TARGET_TYPE_AR6003) {
- crc = (u16 *)(data + 0x04);
- } else if (target_type == TARGET_TYPE_AR6004) {
- len = 1024;
- crc = (u16 *)(data + 0x04);
- } else {
- ath6kl_err("Invalid target type\n");
- return;
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "Old Checksum: %u\n", *crc);
-
- *crc = 0;
- checksum = 0;
- data_idx = (u16 *)data;
-
- for (i = 0; i < len; i += 2) {
- checksum = checksum ^ (*data_idx);
- data_idx++;
- }
-
- *crc = cpu_to_le16(checksum);
-
- ath6kl_dbg(ATH6KL_DBG_BOOT, "New Checksum: %u\n", checksum);
-}
-
-#ifdef CONFIG_MACH_PX
-static int ath6kl_fetch_nvmac_info(struct ath6kl *ar)
-{
- char softmac_temp[64];
- int ret = 0, ath6kl_softmac_len = 0;
- int isnvmac_imei = 0, isnvmac_wifi = 0;
- int isnvmac_file = 0, ismac_file = 0;
-
- char nvfilepath[32] = {0};
- char *nvfilepath_imei = "/efs/imei/.nvmac.info";
- char *nvfilepath_wifi = "/efs/wifi/.nvmac.info";
- char *softmac_filename = "/efs/wifi/.mac.info";
- char *softmac_old_filename = "/data/.mac.info";
-
- do {
- /*
- isnvmac_imei = android_readwrite_file(nvfilepath_imei,
- NULL, NULL, 0);
- isnvmac_wifi = android_readwrite_file(nvfilepath_wifi,
- NULL, NULL, 0); */
- ismac_file = android_readwrite_file(softmac_filename,
- NULL, NULL, 0);
-
- /*
- if (isnvmac_imei >= 16 && isnvmac_wifi >= 16) {
- strcpy(nvfilepath, nvfilepath_wifi);
- isnvmac_file = isnvmac_wifi;
- } else if (isnvmac_wifi >= 16) {
- strcpy(nvfilepath, nvfilepath_wifi);
- isnvmac_file = isnvmac_wifi;
- } else if (isnvmac_imei >= 16) {
- strcpy(nvfilepath, nvfilepath_imei);
- isnvmac_file = isnvmac_imei;
- } */
-
- /* copy .nvmac.info file to .mac.info
- wifi driver will use .mac.info finally */
- /*
- if (isnvmac_file >= 16) {
- ret = android_readwrite_file(nvfilepath,
- (char *)softmac_temp, NULL, isnvmac_file);
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Read Mac Address on nvmac.info - %d\n",
- __func__, ret);
- ret = android_readwrite_file(softmac_filename,
- NULL, (char *)softmac_temp, ret);
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Write Mac Address on mac.info - %d\n",
- __func__, ret);
- ret = android_readwrite_file(softmac_old_filename,
- NULL, (char *)softmac_temp, ret);
- } */
-
- //if (isnvmac_file < 16 && ismac_file < 16) {
- if (ismac_file < 16) {
- snprintf(softmac_temp, sizeof(softmac_temp),
- "00:12:34:%02x:%02x:%02x",
- random32() & 0xff,
- random32() & 0xff,
- random32() & 0xff);
-
- ret = android_readwrite_file(softmac_filename, NULL,
- (char *)softmac_temp, strlen(softmac_temp));
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Write Random Mac on mac.info - %d\n",
- __func__, ret);
- ret = android_readwrite_file(softmac_old_filename, NULL,
- (char *)softmac_temp, strlen(softmac_temp));
- }
-
-
- ret = android_readwrite_file(softmac_filename, NULL, NULL, 0);
- if (ret < 0)
- break;
- else
- ath6kl_softmac_len = ret;
-
- ath6kl_softmac = vmalloc(ath6kl_softmac_len);
- if (!ath6kl_softmac) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: Cannot allocate buffer for %s (%d)\n",
- __func__, softmac_filename, ath6kl_softmac_len);
- ret = -ENOMEM;
- break;
- }
-
- ret = android_readwrite_file(softmac_filename,
- (char *)ath6kl_softmac,
- NULL, ath6kl_softmac_len);
-
- if (ret != ath6kl_softmac_len) {
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "%s: file read error, length %d\n",
- __func__, ath6kl_softmac_len);
- vfree(ath6kl_softmac);
- ret = -1;
- break;
- }
-
- if (!strncmp(ath6kl_softmac, "00:00:00:00:00:00", 17)) {
- ath6kl_dbg(ATH6KL_DBG_BOOT, "%s: mac address is zero\n",
- __func__);
- vfree(ath6kl_softmac);
- ret = -1;
- break;
- }
-
- ret = 0;
- } while (0);
-
- return ret;
-}
-
-#else
-static int ath6kl_fetch_mac_file(struct ath6kl *ar)
-{
- const struct firmware *fw_entry;
- int ret = 0;
-
-
- ret = request_firmware(&fw_entry, MAC_FILE, ar->dev);
- if (ret)
- return ret;
-
- ath6kl_softmac_len = fw_entry->size;
- ath6kl_softmac = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
-
- if (ath6kl_softmac == NULL)
- ret = -ENOMEM;
-
- release_firmware(fw_entry);
-
- return ret;
-}
-#endif
-
-void ath6kl_mangle_mac_address(struct ath6kl *ar)
-{
- u8 *ptr_mac;
- int i, ret;
-#ifdef CONFIG_MACH_PX
- unsigned int softmac[6];
-#endif
-
- switch (ar->target_type) {
- case TARGET_TYPE_AR6003:
- ptr_mac = ar->fw_board + AR6003_MAC_ADDRESS_OFFSET;
- break;
- case TARGET_TYPE_AR6004:
- ptr_mac = ar->fw_board + AR6004_MAC_ADDRESS_OFFSET;
- break;
- default:
- ath6kl_err("Invalid Target Type\n");
- return;
- }
-
-#if 0
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "MAC from EEPROM %02X:%02X:%02X:%02X:%02X:%02X\n",
- ptr_mac[0], ptr_mac[1], ptr_mac[2],
- ptr_mac[3], ptr_mac[4], ptr_mac[5]);
-#endif
-
-#ifdef CONFIG_MACH_PX
- ret = ath6kl_fetch_nvmac_info(ar);
-
- if (ret) {
- ath6kl_err("MAC address file not found\n");
- return;
- }
-
- if (sscanf(ath6kl_softmac, "%02x:%02x:%02x:%02x:%02x:%02x",
- &softmac[0], &softmac[1], &softmac[2],
- &softmac[3], &softmac[4], &softmac[5])==6) {
-
- for (i=0; i<6; ++i) {
- ptr_mac[i] = softmac[i] & 0xff;
- }
- }
-
- ath6kl_dbg(ATH6KL_DBG_BOOT,
- "MAC from SoftMAC %02X_%02X:%02X\n",
- ptr_mac[0], ptr_mac[4], ptr_mac[5]);
- vfree(ath6kl_softmac);
-#else
- ret = ath6kl_fetch_mac_file(ar);
- if (ret) {
- ath6kl_err("MAC address file not found\n");
- return;
- }
-
- for (i = 0; i < ETH_ALEN; ++i) {
- ptr_mac[i] = ath6kl_softmac[i] & 0xff;
- }
-
- kfree(ath6kl_softmac);
-#endif
-
- ath6kl_calculate_crc(ar->target_type, ar->fw_board, ar->fw_board_len);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
deleted file mode 100755
index fa0faa4..0000000
--- a/drivers/net/wireless/ath/ath6kl/target.h
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2004-2010 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef TARGET_H
-#define TARGET_H
-
-#define AR6003_BOARD_DATA_ADDR 0x00540654
-#define AR6003_BOARD_DATA_INIT_ADDR 0x00540658
-#define AR6003_BOARD_DATA_OFFSET 4
-#define AR6003_RD_OFFSET 12
-
-#define AR6003_BOARD_DATA_SZ 1024
-#define AR6003_BOARD_EXT_DATA_SZ 768
-#define AR6003_BOARD_EXT_DATA_SZ_V2 1024
-
-#define AR6004_BOARD_DATA_SZ 6144
-#define AR6004_BOARD_EXT_DATA_SZ 0
-
-#define RESET_CONTROL_ADDRESS 0x00000000
-#define RESET_CONTROL_COLD_RST 0x00000100
-#define RESET_CONTROL_MBOX_RST 0x00000004
-
-#define CPU_CLOCK_STANDARD_S 0
-#define CPU_CLOCK_STANDARD 0x00000003
-#define CPU_CLOCK_ADDRESS 0x00000020
-
-#define CLOCK_CONTROL_ADDRESS 0x00000028
-#define CLOCK_CONTROL_LF_CLK32_S 2
-#define CLOCK_CONTROL_LF_CLK32 0x00000004
-
-#define SYSTEM_SLEEP_ADDRESS 0x000000c4
-#define SYSTEM_SLEEP_DISABLE_S 0
-#define SYSTEM_SLEEP_DISABLE 0x00000001
-
-#define LPO_CAL_ADDRESS 0x000000e0
-#define LPO_CAL_ENABLE_S 20
-#define LPO_CAL_ENABLE 0x00100000
-
-#define GPIO_PIN10_ADDRESS 0x00000050
-#define GPIO_PIN11_ADDRESS 0x00000054
-#define GPIO_PIN12_ADDRESS 0x00000058
-#define GPIO_PIN13_ADDRESS 0x0000005c
-
-#define HOST_INT_STATUS_ADDRESS 0x00000400
-#define HOST_INT_STATUS_ERROR_S 7
-#define HOST_INT_STATUS_ERROR 0x00000080
-
-#define HOST_INT_STATUS_CPU_S 6
-#define HOST_INT_STATUS_CPU 0x00000040
-
-#define HOST_INT_STATUS_COUNTER_S 4
-#define HOST_INT_STATUS_COUNTER 0x00000010
-
-#define CPU_INT_STATUS_ADDRESS 0x00000401
-
-#define ERROR_INT_STATUS_ADDRESS 0x00000402
-#define ERROR_INT_STATUS_WAKEUP_S 2
-#define ERROR_INT_STATUS_WAKEUP 0x00000004
-
-#define ERROR_INT_STATUS_RX_UNDERFLOW_S 1
-#define ERROR_INT_STATUS_RX_UNDERFLOW 0x00000002
-
-#define ERROR_INT_STATUS_TX_OVERFLOW_S 0
-#define ERROR_INT_STATUS_TX_OVERFLOW 0x00000001
-
-#define COUNTER_INT_STATUS_ADDRESS 0x00000403
-#define COUNTER_INT_STATUS_COUNTER_S 0
-#define COUNTER_INT_STATUS_COUNTER 0x000000ff
-
-#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
-
-#define INT_STATUS_ENABLE_ADDRESS 0x00000418
-#define INT_STATUS_ENABLE_ERROR_S 7
-#define INT_STATUS_ENABLE_ERROR 0x00000080
-
-#define INT_STATUS_ENABLE_CPU_S 6
-#define INT_STATUS_ENABLE_CPU 0x00000040
-
-#define INT_STATUS_ENABLE_INT_S 5
-#define INT_STATUS_ENABLE_INT 0x00000020
-#define INT_STATUS_ENABLE_COUNTER_S 4
-#define INT_STATUS_ENABLE_COUNTER 0x00000010
-
-#define INT_STATUS_ENABLE_MBOX_DATA_S 0
-#define INT_STATUS_ENABLE_MBOX_DATA 0x0000000f
-
-#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
-#define CPU_INT_STATUS_ENABLE_BIT_S 0
-#define CPU_INT_STATUS_ENABLE_BIT 0x000000ff
-
-#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_S 1
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW 0x00000002
-
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_S 0
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW 0x00000001
-
-#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
-#define COUNTER_INT_STATUS_ENABLE_BIT_S 0
-#define COUNTER_INT_STATUS_ENABLE_BIT 0x000000ff
-
-#define COUNT_ADDRESS 0x00000420
-
-#define COUNT_DEC_ADDRESS 0x00000440
-
-#define WINDOW_DATA_ADDRESS 0x00000474
-#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
-#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
-#define CPU_DBG_SEL_ADDRESS 0x00000483
-#define CPU_DBG_ADDRESS 0x00000484
-
-#define LOCAL_SCRATCH_ADDRESS 0x000000c0
-#define ATH6KL_OPTION_SLEEP_DISABLE 0x08
-
-#define RTC_BASE_ADDRESS 0x00004000
-#define GPIO_BASE_ADDRESS 0x00014000
-#define MBOX_BASE_ADDRESS 0x00018000
-#define ANALOG_INTF_BASE_ADDRESS 0x0001c000
-
-/* real name of the register is unknown */
-#define ATH6KL_ANALOG_PLL_REGISTER (ANALOG_INTF_BASE_ADDRESS + 0x284)
-
-#define SM(f, v) (((v) << f##_S) & f)
-#define MS(f, v) (((v) & f) >> f##_S)
-
-/*
- * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
- * host_interest structure.
- *
- * Host Interest is shared between Host and Target in order to coordinate
- * between the two, and is intended to remain constant (with additions only
- * at the end).
- */
-#define ATH6KL_AR6003_HI_START_ADDR 0x00540600
-#define ATH6KL_AR6004_HI_START_ADDR 0x00400800
-
-/*
- * These are items that the Host may need to access
- * via BMI or via the Diagnostic Window. The position
- * of items in this structure must remain constant.
- * across firmware revisions!
- *
- * Types for each item must be fixed size across target and host platforms.
- * The structure is used only to calculate offset for each register with
- * HI_ITEM() macro, no values are stored to it.
- *
- * More items may be added at the end.
- */
-struct host_interest {
- /*
- * Pointer to application-defined area, if any.
- * Set by Target application during startup.
- */
- u32 hi_app_host_interest; /* 0x00 */
-
- /* Pointer to register dump area, valid after Target crash. */
- u32 hi_failure_state; /* 0x04 */
-
- /* Pointer to debug logging header */
- u32 hi_dbglog_hdr; /* 0x08 */
-
- u32 hi_unused1; /* 0x0c */
-
- /*
- * General-purpose flag bits, similar to ATH6KL_OPTION_* flags.
- * Can be used by application rather than by OS.
- */
- u32 hi_option_flag; /* 0x10 */
-
- /*
- * Boolean that determines whether or not to
- * display messages on the serial port.
- */
- u32 hi_serial_enable; /* 0x14 */
-
- /* Start address of DataSet index, if any */
- u32 hi_dset_list_head; /* 0x18 */
-
- /* Override Target application start address */
- u32 hi_app_start; /* 0x1c */
-
- /* Clock and voltage tuning */
- u32 hi_skip_clock_init; /* 0x20 */
- u32 hi_core_clock_setting; /* 0x24 */
- u32 hi_cpu_clock_setting; /* 0x28 */
- u32 hi_system_sleep_setting; /* 0x2c */
- u32 hi_xtal_control_setting; /* 0x30 */
- u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
- u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
- u32 hi_ref_voltage_trim_setting; /* 0x3c */
- u32 hi_clock_info; /* 0x40 */
-
- /*
- * Flash configuration overrides, used only
- * when firmware is not executing from flash.
- * (When using flash, modify the global variables
- * with equivalent names.)
- */
- u32 hi_bank0_addr_value; /* 0x44 */
- u32 hi_bank0_read_value; /* 0x48 */
- u32 hi_bank0_write_value; /* 0x4c */
- u32 hi_bank0_config_value; /* 0x50 */
-
- /* Pointer to Board Data */
- u32 hi_board_data; /* 0x54 */
- u32 hi_board_data_initialized; /* 0x58 */
-
- u32 hi_dset_ram_index_tbl; /* 0x5c */
-
- u32 hi_desired_baud_rate; /* 0x60 */
- u32 hi_dbglog_config; /* 0x64 */
- u32 hi_end_ram_reserve_sz; /* 0x68 */
- u32 hi_mbox_io_block_sz; /* 0x6c */
-
- u32 hi_num_bpatch_streams; /* 0x70 -- unused */
- u32 hi_mbox_isr_yield_limit; /* 0x74 */
-
- u32 hi_refclk_hz; /* 0x78 */
- u32 hi_ext_clk_detected; /* 0x7c */
- u32 hi_dbg_uart_txpin; /* 0x80 */
- u32 hi_dbg_uart_rxpin; /* 0x84 */
- u32 hi_hci_uart_baud; /* 0x88 */
- u32 hi_hci_uart_pin_assignments; /* 0x8C */
- /*
- * NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts
- * pin
- */
- u32 hi_hci_uart_baud_scale_val; /* 0x90 */
- u32 hi_hci_uart_baud_step_val; /* 0x94 */
-
- u32 hi_allocram_start; /* 0x98 */
- u32 hi_allocram_sz; /* 0x9c */
- u32 hi_hci_bridge_flags; /* 0xa0 */
- u32 hi_hci_uart_support_pins; /* 0xa4 */
- /*
- * NOTE: byte [0] = RESET pin (bit 7 is polarity),
- * bytes[1]..bytes[3] are for future use
- */
- u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
- /*
- * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
- * [31:16]: wakeup timeout in ms
- */
-
- /* Pointer to extended board data */
- u32 hi_board_ext_data; /* 0xac */
- u32 hi_board_ext_data_config; /* 0xb0 */
-
- /*
- * Bit [0] : valid
- * Bit[31:16: size
- */
- /*
- * hi_reset_flag is used to do some stuff when target reset.
- * such as restore app_start after warm reset or
- * preserve host Interest area, or preserve ROM data, literals etc.
- */
- u32 hi_reset_flag; /* 0xb4 */
- /* indicate hi_reset_flag is valid */
- u32 hi_reset_flag_valid; /* 0xb8 */
- u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */
- /*
- * 0xbc - [31:0]: idle timeout in ms
- */
- /* ACS flags */
- u32 hi_acs_flags; /* 0xc0 */
- u32 hi_console_flags; /* 0xc4 */
- u32 hi_nvram_state; /* 0xc8 */
- u32 hi_option_flag2; /* 0xcc */
-
- /* If non-zero, override values sent to Host in WMI_READY event. */
- u32 hi_sw_version_override; /* 0xd0 */
- u32 hi_abi_version_override; /* 0xd4 */
-
- /*
- * Percentage of high priority RX traffic to total expected RX traffic -
- * applicable only to ar6004
- */
- u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
-
- /* test applications flags */
- u32 hi_test_apps_related ; /* 0xdc */
- /* location of test script */
- u32 hi_ota_testscript; /* 0xe0 */
- /* location of CAL data */
- u32 hi_cal_data; /* 0xe4 */
- /* Number of packet log buffers */
- u32 hi_pktlog_num_buffers; /* 0xe8 */
-
-} __packed;
-
-#define HI_ITEM(item) offsetof(struct host_interest, item)
-
-#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
-
-#define HI_OPTION_FW_MODE_IBSS 0x0
-#define HI_OPTION_FW_MODE_BSS_STA 0x1
-#define HI_OPTION_FW_MODE_AP 0x2
-
-#define HI_OPTION_FW_SUBMODE_NONE 0x0
-#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1
-#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2
-#define HI_OPTION_FW_SUBMODE_P2PGO 0x3
-
-#define HI_OPTION_NUM_DEV_SHIFT 0x9
-
-#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
-
-/* Fw Mode/SubMode Mask
-|------------------------------------------------------------------------------|
-| SUB | SUB | SUB | SUB | | | |
-| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
-| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
-|------------------------------------------------------------------------------|
-*/
-#define HI_OPTION_FW_MODE_BITS 0x2
-#define HI_OPTION_FW_MODE_SHIFT 0xC
-
-#define HI_OPTION_FW_SUBMODE_BITS 0x2
-#define HI_OPTION_FW_SUBMODE_SHIFT 0x14
-
-/* Convert a Target virtual address into a Target physical address */
-#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
-#define AR6004_VTOP(vaddr) (vaddr)
-
-#define TARG_VTOP(target_type, vaddr) \
- (((target_type) == TARGET_TYPE_AR6003) ? AR6003_VTOP(vaddr) : \
- (((target_type) == TARGET_TYPE_AR6004) ? AR6004_VTOP(vaddr) : 0))
-
-#define ATH6KL_FWLOG_PAYLOAD_SIZE 1500
-
-struct ath6kl_dbglog_buf {
- __le32 next;
- __le32 buffer_addr;
- __le32 bufsize;
- __le32 length;
- __le32 count;
- __le32 free;
-} __packed;
-
-struct ath6kl_dbglog_hdr {
- __le32 dbuf_addr;
- __le32 dropped;
-} __packed;
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
deleted file mode 100755
index f4a5cc3..0000000
--- a/drivers/net/wireless/ath/ath6kl/testmode.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "testmode.h"
-#include "debug.h"
-
-#include <net/netlink.h>
-#include "wmiconfig.h"
-
-enum ath6kl_tm_attr {
- __ATH6KL_TM_ATTR_INVALID = 0,
- ATH6KL_TM_ATTR_CMD = 1,
- ATH6KL_TM_ATTR_DATA = 2,
-
- /* keep last */
- __ATH6KL_TM_ATTR_AFTER_LAST,
- ATH6KL_TM_ATTR_MAX = __ATH6KL_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum ath6kl_tm_cmd {
- ATH6KL_TM_CMD_TCMD = 0,
- ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */
- ATH6KL_TM_CMD_WMI_CMD = 0xF000,
-};
-
-#define ATH6KL_TM_DATA_MAX_LEN 5000
-
-static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
- [ATH6KL_TM_ATTR_CMD] = { .type = NLA_U32 },
- [ATH6KL_TM_ATTR_DATA] = { .type = NLA_BINARY,
- .len = ATH6KL_TM_DATA_MAX_LEN },
-};
-
-
-void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len)
-{
- struct sk_buff *skb;
-
- if (!buf || buf_len == 0)
- return;
-
- skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
- if (!skb) {
- ath6kl_warn("failed to allocate testmode rx skb!\n");
- return;
- }
- NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
- cfg80211_testmode_event(skb, GFP_KERNEL);
- return;
-
-nla_put_failure:
- kfree_skb(skb);
- ath6kl_warn("nla_put failed on testmode rx skb!\n");
-}
-
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
-{
- struct ath6kl *ar = wiphy_priv(wiphy);
- struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
- int err, buf_len;
- void *buf;
- u32 wmi_cmd;
- struct sk_buff *skb;
-
- err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
- ath6kl_tm_policy);
- if (err)
- return err;
-
- if (!tb[ATH6KL_TM_ATTR_CMD])
- return -EINVAL;
-
- switch (nla_get_u32(tb[ATH6KL_TM_ATTR_CMD])) {
- case ATH6KL_TM_CMD_WMI_CMD:
- if (!tb[ATH6KL_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
- buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
- /* First four bytes hold the wmi_cmd and the rest is the data */
- skb = ath6kl_wmi_get_buf(buf_len-4);
- if (!skb)
- return -ENOMEM;
-
- memcpy(&wmi_cmd, buf, sizeof(wmi_cmd));
- memcpy(skb->data, (u32 *)buf + 1, buf_len - 4);
- ath6kl_wmi_cmd_send(ar->wmi, 0, skb, wmi_cmd, NO_SYNC_WMIFLAG);
-
- return 0;
-
- break;
- case ATH6KL_TM_CMD_TCMD:
- if (!tb[ATH6KL_TM_ATTR_DATA])
- return -EINVAL;
-
- buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
- buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
-
- ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len);
-
- return 0;
-
- break;
- case ATH6KL_TM_CMD_RX_REPORT:
- default:
- return -EOPNOTSUPP;
- }
-}
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h
deleted file mode 100755
index fe651d6..0000000
--- a/drivers/net/wireless/ath/ath6kl/testmode.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-
-#ifdef CONFIG_NL80211_TESTMODE
-
-void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
-
-#else
-
-static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
- size_t buf_len)
-{
-}
-
-static inline int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
-{
- return 0;
-}
-
-#endif
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
deleted file mode 100644
index b8924dd..0000000
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ /dev/null
@@ -1,1853 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "core.h"
-#include "debug.h"
-
-/*
- * tid - tid_mux0..tid_mux3
- * aid - tid_mux4..tid_mux7
- */
-#define ATH6KL_TID_MASK 0xf
-#define ATH6KL_AID_SHIFT 4
-
-static inline u8 ath6kl_get_tid(u8 tid_mux)
-{
- return tid_mux & ATH6KL_TID_MASK;
-}
-
-static inline u8 ath6kl_get_aid(u8 tid_mux)
-{
- return tid_mux >> ATH6KL_AID_SHIFT;
-}
-
-static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
- u32 *map_no)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ethhdr *eth_hdr;
- u32 i, ep_map = -1;
- u8 *datap;
-
- *map_no = 0;
- datap = skb->data;
- eth_hdr = (struct ethhdr *) (datap + sizeof(struct wmi_data_hdr));
-
- if (is_multicast_ether_addr(eth_hdr->h_dest))
- return ENDPOINT_2;
-
- for (i = 0; i < ar->node_num; i++) {
- if (memcmp(eth_hdr->h_dest, ar->node_map[i].mac_addr,
- ETH_ALEN) == 0) {
- *map_no = i + 1;
- ar->node_map[i].tx_pend++;
- return ar->node_map[i].ep_id;
- }
-
- if ((ep_map == -1) && !ar->node_map[i].tx_pend)
- ep_map = i;
- }
-
- if (ep_map == -1) {
- ep_map = ar->node_num;
- ar->node_num++;
- if (ar->node_num > MAX_NODE_NUM)
- return ENDPOINT_UNUSED;
- }
-
- memcpy(ar->node_map[ep_map].mac_addr, eth_hdr->h_dest, ETH_ALEN);
-
- for (i = ENDPOINT_2; i <= ENDPOINT_5; i++) {
- if (!ar->tx_pending[i]) {
- ar->node_map[ep_map].ep_id = i;
- break;
- }
-
- /*
- * No free endpoint is available, start redistribution on
- * the inuse endpoints.
- */
- if (i == ENDPOINT_5) {
- ar->node_map[ep_map].ep_id = ar->next_ep_id;
- ar->next_ep_id++;
- if (ar->next_ep_id > ENDPOINT_5)
- ar->next_ep_id = ENDPOINT_2;
- }
- }
-
- *map_no = ep_map + 1;
- ar->node_map[ep_map].tx_pend++;
-
- return ar->node_map[ep_map].ep_id;
-}
-
-static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn,
- struct ath6kl_vif *vif,
- struct sk_buff *skb,
- u32 *flags)
-{
- struct ath6kl *ar = vif->ar;
- bool is_apsdq_empty = false;
- struct ethhdr *datap = (struct ethhdr *) skb->data;
- u8 up = 0, traffic_class, *ip_hdr;
- u16 ether_type;
- struct ath6kl_llc_snap_hdr *llc_hdr;
-
- if (conn->sta_flags & STA_PS_APSD_TRIGGER) {
- /*
- * This tx is because of a uAPSD trigger, determine
- * more and EOSP bit. Set EOSP if queue is empty
- * or sufficient frames are delivered for this trigger.
- */
- spin_lock_bh(&conn->psq_lock);
- if (!skb_queue_empty(&conn->apsdq))
- *flags |= WMI_DATA_HDR_FLAGS_MORE;
- else if (conn->sta_flags & STA_PS_APSD_EOSP)
- *flags |= WMI_DATA_HDR_FLAGS_EOSP;
- *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
- spin_unlock_bh(&conn->psq_lock);
- return false;
- } else if (!conn->apsd_info)
- return false;
-
- if (test_bit(WMM_ENABLED, &vif->flags)) {
- ether_type = be16_to_cpu(datap->h_proto);
- if (is_ethertype(ether_type)) {
- /* packet is in DIX format */
- ip_hdr = (u8 *)(datap + 1);
- } else {
- /* packet is in 802.3 format */
- llc_hdr = (struct ath6kl_llc_snap_hdr *)
- (datap + 1);
- ether_type = be16_to_cpu(llc_hdr->eth_type);
- ip_hdr = (u8 *)(llc_hdr + 1);
- }
-
- if (ether_type == IP_ETHERTYPE)
- up = ath6kl_wmi_determine_user_priority(
- ip_hdr, 0);
- } else {
- up = 0;
- }
-
- traffic_class = ath6kl_wmi_get_traffic_class(up);
-
- if ((conn->apsd_info & (1 << traffic_class)) == 0)
- return false;
-
- /* Queue the frames if the STA is sleeping */
- spin_lock_bh(&conn->psq_lock);
- is_apsdq_empty = skb_queue_empty(&conn->apsdq);
- skb_queue_tail(&conn->apsdq, skb);
- spin_unlock_bh(&conn->psq_lock);
-
- /*
- * If this is the first pkt getting queued
- * for this STA, update the PVB for this STA
- */
- if (is_apsdq_empty) {
- ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 1, 0);
- }
- *flags |= WMI_DATA_HDR_FLAGS_UAPSD;
-
- return true;
-}
-
-static bool ath6kl_process_psq(struct ath6kl_sta *conn,
- struct ath6kl_vif *vif,
- struct sk_buff *skb,
- u32 *flags)
-{
- bool is_psq_empty = false;
- struct ath6kl *ar = vif->ar;
-
- if (conn->sta_flags & STA_PS_POLLED) {
- spin_lock_bh(&conn->psq_lock);
- if (!skb_queue_empty(&conn->psq))
- *flags |= WMI_DATA_HDR_FLAGS_MORE;
- spin_unlock_bh(&conn->psq_lock);
- return false;
- }
-
- /* Queue the frames if the STA is sleeping */
- spin_lock_bh(&conn->psq_lock);
- is_psq_empty = skb_queue_empty(&conn->psq);
- skb_queue_tail(&conn->psq, skb);
- spin_unlock_bh(&conn->psq_lock);
-
- /*
- * If this is the first pkt getting queued
- * for this STA, update the PVB for this
- * STA.
- */
- if (is_psq_empty)
- ath6kl_wmi_set_pvb_cmd(ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 1);
- return true;
-}
-
-static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb,
- u32 *flags)
-{
- struct ethhdr *datap = (struct ethhdr *) skb->data;
- struct ath6kl_sta *conn = NULL;
- bool ps_queued = false;
- struct ath6kl *ar = vif->ar;
-
- if (is_multicast_ether_addr(datap->h_dest)) {
- u8 ctr = 0;
- bool q_mcast = false;
-
- for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
- if (ar->sta_list[ctr].sta_flags & STA_PS_SLEEP) {
- q_mcast = true;
- break;
- }
- }
-
- if (q_mcast) {
- /*
- * If this transmit is not because of a Dtim Expiry
- * q it.
- */
- if (!test_bit(DTIM_EXPIRED, &vif->flags)) {
- bool is_mcastq_empty = false;
-
- spin_lock_bh(&ar->mcastpsq_lock);
- is_mcastq_empty =
- skb_queue_empty(&ar->mcastpsq);
- skb_queue_tail(&ar->mcastpsq, skb);
- spin_unlock_bh(&ar->mcastpsq_lock);
-
- /*
- * If this is the first Mcast pkt getting
- * queued indicate to the target to set the
- * BitmapControl LSB of the TIM IE.
- */
- if (is_mcastq_empty)
- ath6kl_wmi_set_pvb_cmd(ar->wmi,
- vif->fw_vif_idx,
- MCAST_AID, 1);
-
- ps_queued = true;
- } else {
- /*
- * This transmit is because of Dtim expiry.
- * Determine if MoreData bit has to be set.
- */
- spin_lock_bh(&ar->mcastpsq_lock);
- if (!skb_queue_empty(&ar->mcastpsq))
- *flags |= WMI_DATA_HDR_FLAGS_MORE;
- spin_unlock_bh(&ar->mcastpsq_lock);
- }
- }
- } else {
- conn = ath6kl_find_sta(vif, datap->h_dest);
- if (!conn) {
- dev_kfree_skb(skb);
-
- /* Inform the caller that the skb is consumed */
- return true;
- }
-
- if (conn->sta_flags & STA_PS_SLEEP) {
- ps_queued = ath6kl_process_uapsdq(conn,
- vif, skb, flags);
- if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD))
- ps_queued = ath6kl_process_psq(conn,
- vif, skb, flags);
- }
- }
- return ps_queued;
-}
-
-/* Tx functions */
-
-int ath6kl_control_tx(void *devt, struct sk_buff *skb,
- enum htc_endpoint_id eid)
-{
- struct ath6kl *ar = devt;
- int status = 0;
- struct ath6kl_cookie *cookie = NULL;
- struct ath6kl_vif *vif;
- vif = ath6kl_vif_first(ar);
-
- if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
- goto fail_ctrl_tx;
-
- if (!test_bit(WMI_READY, &ar->flag))
- goto fail_ctrl_tx;
-
- spin_lock_bh(&ar->lock);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
- "%s: skb=0x%p, len=0x%x eid =%d\n", __func__,
- skb, skb->len, eid);
-
- if (test_bit(WMI_CTRL_EP_FULL, &ar->flag) && (eid == ar->ctrl_ep)) {
- /*
- * Control endpoint is full, don't allocate resources, we
- * are just going to drop this packet.
- */
- cookie = NULL;
- ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
- skb, skb->len);
-#ifdef CONFIG_MACH_PX
- if (vif->nw_type == INFRA_NETWORK)
- vif->force_reload = true;
-#endif
- } else
- cookie = ath6kl_alloc_cookie(ar);
-
- if (cookie == NULL) {
- spin_unlock_bh(&ar->lock);
- status = -ENOMEM;
- goto fail_ctrl_tx;
- }
-
- ar->tx_pending[eid]++;
-
- if (eid != ar->ctrl_ep)
- ar->total_tx_data_pend++;
-
- spin_unlock_bh(&ar->lock);
-
- cookie->skb = skb;
- cookie->map_no = 0;
- set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
- eid, ATH6KL_CONTROL_PKT_TAG);
-
- /*
- * This interface is asynchronous, if there is an error, cleanup
- * will happen in the TX completion callback.
- */
- ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
-
- return 0;
-
-fail_ctrl_tx:
- dev_kfree_skb(skb);
- return status;
-}
-
-int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
-{
- struct ath6kl *ar = ath6kl_priv(dev);
- struct ath6kl_cookie *cookie = NULL;
- enum htc_endpoint_id eid = ENDPOINT_UNUSED;
- struct ath6kl_vif *vif = netdev_priv(dev);
- u32 map_no = 0;
- u16 htc_tag = ATH6KL_DATA_PKT_TAG;
- u8 ac = 99 ; /* initialize to unmapped ac */
- bool chk_adhoc_ps_mapping = false;
- int ret;
- struct wmi_tx_meta_v2 meta_v2;
- void *meta;
- u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed;
- u8 meta_ver = 0;
- u32 flags = 0;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
- "%s: skb=0x%p, data=0x%p, len=0x%x, actual_len=0x%x\n", __func__,
- skb, skb->data, skb->len, skb->tail - skb->data);
-
- /* If target is not associated */
- if (!test_bit(CONNECTED, &vif->flags)) {
- dev_kfree_skb(skb);
- return 0;
- }
-
- if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) {
- dev_kfree_skb(skb);
- return 0;
- }
-
- if (!test_bit(WMI_READY, &ar->flag))
- goto fail_tx;
-
- /* AP mode Power saving processing */
- if (vif->nw_type == AP_NETWORK) {
- if (ath6kl_powersave_ap(vif, skb, &flags))
- return 0;
- }
-
- if (test_bit(WMI_ENABLED, &ar->flag)) {
- if ((dev->features & NETIF_F_IP_CSUM) &&
- (csum == CHECKSUM_PARTIAL)) {
- csum_start = skb->csum_start -
- (skb_network_header(skb) - skb->head) +
- sizeof(struct ath6kl_llc_snap_hdr);
- csum_dest = skb->csum_offset + csum_start;
- }
-
- if (skb_headroom(skb) < dev->needed_headroom)
- {
- struct sk_buff *tmp_skb = skb;
-
- skb = skb_realloc_headroom(skb, dev->needed_headroom);
- kfree_skb(tmp_skb);
- if (skb == NULL) {
- vif->net_stats.tx_dropped++;
- return 0;
- }
- }
-
- if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) {
- ath6kl_err("ath6kl_wmi_dix_2_dot3 failed\n");
- goto fail_tx;
- }
-
- if ((dev->features & NETIF_F_IP_CSUM) &&
- (csum == CHECKSUM_PARTIAL)) {
- meta_v2.csum_start = csum_start;
- meta_v2.csum_dest = csum_dest;
-
- /* instruct target to calculate checksum */
- meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD;
- meta_ver = WMI_META_VERSION_2;
- meta = &meta_v2;
- } else {
- meta_ver = 0;
- meta = NULL;
- }
-
- ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb,
- DATA_MSGTYPE, flags, 0,
- meta_ver,
- meta, vif->fw_vif_idx);
-
- if (ret) {
- ath6kl_warn("failed to add wmi data header:%d\n"
- , ret);
- goto fail_tx;
- }
-
- if ((vif->nw_type == ADHOC_NETWORK) &&
- ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
- chk_adhoc_ps_mapping = true;
- else {
- /* get the stream mapping */
- ret = ath6kl_wmi_implicit_create_pstream(ar->wmi,
- vif->fw_vif_idx, skb,
- 0, test_bit(WMM_ENABLED, &vif->flags), &ac);
- if (ret)
- goto fail_tx;
- }
- } else
- goto fail_tx;
-
- spin_lock_bh(&ar->lock);
-
- if (chk_adhoc_ps_mapping)
- eid = ath6kl_ibss_map_epid(skb, dev, &map_no);
- else
- eid = ar->ac2ep_map[ac];
-
- if (eid == 0 || eid == ENDPOINT_UNUSED) {
- ath6kl_err("eid %d is not mapped!\n", eid);
- spin_unlock_bh(&ar->lock);
- goto fail_tx;
- }
-
- /* allocate resource for this packet */
- cookie = ath6kl_alloc_cookie(ar);
-
- if (!cookie) {
- spin_unlock_bh(&ar->lock);
- goto fail_tx;
- }
-
- /* update counts while the lock is held */
- ar->tx_pending[eid]++;
- ar->total_tx_data_pend++;
-
- spin_unlock_bh(&ar->lock);
-
- if (!IS_ALIGNED((unsigned long) skb->data - HTC_HDR_LENGTH, 4) &&
- skb_cloned(skb)) {
- /*
- * We will touch (move the buffer data to align it. Since the
- * skb buffer is cloned and not only the header is changed, we
- * have to copy it to allow the changes. Since we are copying
- * the data here, we may as well align it by reserving suitable
- * headroom to avoid the memmove in ath6kl_htc_tx_buf_align().
- */
- struct sk_buff *nskb;
-
- nskb = skb_copy_expand(skb, HTC_HDR_LENGTH, 0, GFP_ATOMIC);
- if (nskb == NULL)
- goto fail_tx;
- kfree_skb(skb);
- skb = nskb;
- }
-
- cookie->skb = skb;
- cookie->map_no = map_no;
- set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
- eid, htc_tag);
-
- ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ",
- skb->data, skb->len);
- /*
- * HTC interface is asynchronous, if this fails, cleanup will
- * happen in the ath6kl_tx_complete callback.
- */
- ath6kl_htc_tx(ar->htc_target, &cookie->htc_pkt);
-
- return 0;
-
-fail_tx:
- dev_kfree_skb(skb);
-
- vif->net_stats.tx_dropped++;
- vif->net_stats.tx_aborted_errors++;
-
- return 0;
-}
-
-/* indicate tx activity or inactivity on a WMI stream */
-void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
-{
- struct ath6kl *ar = devt;
- enum htc_endpoint_id eid;
- int i;
-
- eid = ar->ac2ep_map[traffic_class];
-
- if (!test_bit(WMI_ENABLED, &ar->flag))
- goto notify_htc;
-
- spin_lock_bh(&ar->lock);
-
- ar->ac_stream_active[traffic_class] = active;
-
- if (active) {
- /*
- * Keep track of the active stream with the highest
- * priority.
- */
- if (ar->ac_stream_pri_map[traffic_class] >
- ar->hiac_stream_active_pri)
- /* set the new highest active priority */
- ar->hiac_stream_active_pri =
- ar->ac_stream_pri_map[traffic_class];
-
- } else {
- /*
- * We may have to search for the next active stream
- * that is the highest priority.
- */
- if (ar->hiac_stream_active_pri ==
- ar->ac_stream_pri_map[traffic_class]) {
- /*
- * The highest priority stream just went inactive
- * reset and search for the "next" highest "active"
- * priority stream.
- */
- ar->hiac_stream_active_pri = 0;
-
- for (i = 0; i < WMM_NUM_AC; i++) {
- if (ar->ac_stream_active[i] &&
- (ar->ac_stream_pri_map[i] >
- ar->hiac_stream_active_pri))
- /*
- * Set the new highest active
- * priority.
- */
- ar->hiac_stream_active_pri =
- ar->ac_stream_pri_map[i];
- }
- }
- }
-
- spin_unlock_bh(&ar->lock);
-
-notify_htc:
- /* notify HTC, this may cause credit distribution changes */
- ath6kl_htc_indicate_activity_change(ar->htc_target, eid, active);
-}
-
-enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
- struct htc_packet *packet)
-{
- struct ath6kl *ar = target->dev->ar;
- struct ath6kl_vif *vif;
- enum htc_endpoint_id endpoint = packet->endpoint;
- enum htc_send_full_action action = HTC_SEND_FULL_KEEP;
-
- if (endpoint == ar->ctrl_ep) {
- /*
- * Under normal WMI if this is getting full, then something
- * is running rampant the host should not be exhausting the
- * WMI queue with too many commands the only exception to
- * this is during testing using endpointping.
- */
- set_bit(WMI_CTRL_EP_FULL, &ar->flag);
- ath6kl_err("wmi ctrl ep is full\n");
- return action;
- }
-
- if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
- return action;
-
- /*
- * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for
- * the highest active stream.
- */
- if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
- ar->hiac_stream_active_pri &&
- ar->cookie_count <= MAX_HI_COOKIE_NUM)
- /*
- * Give preference to the highest priority stream by
- * dropping the packets which overflowed.
- */
- action = HTC_SEND_FULL_DROP;
-
- /* FIXME: Locking */
- spin_lock_bh(&ar->list_lock);
- list_for_each_entry(vif, &ar->vif_list, list) {
- if (vif->nw_type == ADHOC_NETWORK ||
- action != HTC_SEND_FULL_DROP) {
- spin_unlock_bh(&ar->list_lock);
-
- set_bit(NETQ_STOPPED, &vif->flags);
- netif_stop_queue(vif->ndev);
-
- return action;
- }
- }
- spin_unlock_bh(&ar->list_lock);
-
- return action;
-}
-
-/* TODO this needs to be looked at */
-static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif,
- enum htc_endpoint_id eid, u32 map_no)
-{
- struct ath6kl *ar = vif->ar;
- u32 i;
-
- if (vif->nw_type != ADHOC_NETWORK)
- return;
-
- if (!ar->ibss_ps_enable)
- return;
-
- if (eid == ar->ctrl_ep)
- return;
-
- if (map_no == 0)
- return;
-
- map_no--;
- ar->node_map[map_no].tx_pend--;
-
- if (ar->node_map[map_no].tx_pend)
- return;
-
- if (map_no != (ar->node_num - 1))
- return;
-
- for (i = ar->node_num; i > 0; i--) {
- if (ar->node_map[i - 1].tx_pend)
- break;
-
- memset(&ar->node_map[i - 1], 0,
- sizeof(struct ath6kl_node_mapping));
- ar->node_num--;
- }
-}
-
-void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
-{
- struct ath6kl *ar = context;
- struct sk_buff_head skb_queue;
- struct htc_packet *packet;
- struct sk_buff *skb;
- struct ath6kl_cookie *ath6kl_cookie;
- u32 map_no = 0;
- int status;
- enum htc_endpoint_id eid;
- bool wake_event = false;
- bool flushing[ATH6KL_VIF_MAX] = {false};
- u8 if_idx;
- struct ath6kl_vif *vif;
- bool ctrl_ep = false;
-
- skb_queue_head_init(&skb_queue);
-
- /* lock the driver as we update internal state */
- spin_lock_bh(&ar->lock);
-
- /* reap completed packets */
- while (!list_empty(packet_queue)) {
-
- packet = list_first_entry(packet_queue, struct htc_packet,
- list);
- list_del(&packet->list);
-
- ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
- if (!ath6kl_cookie)
- goto fatal;
-
- status = packet->status;
- skb = ath6kl_cookie->skb;
- eid = packet->endpoint;
- map_no = ath6kl_cookie->map_no;
-
- if (!skb || !skb->data)
- goto fatal;
-
- __skb_queue_tail(&skb_queue, skb);
-
- if (!status && (packet->act_len != skb->len))
- goto fatal;
-
- ar->tx_pending[eid]--;
-
- if (eid != ar->ctrl_ep)
- ar->total_tx_data_pend--;
-
- if (eid == ar->ctrl_ep) {
- if (test_bit(WMI_CTRL_EP_FULL, &ar->flag))
- clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
-
- if (ar->tx_pending[eid] == 0)
- wake_event = true;
- ctrl_ep = true;
-
- } else {
- if_idx = wmi_data_hdr_get_if_idx(
- (struct wmi_data_hdr *) packet->buf);
-
- vif = ath6kl_get_vif_by_index(ar, if_idx);
- if (!vif) {
- ath6kl_free_cookie(ar, ath6kl_cookie);
- continue;
- }
-
- if (status) {
- if (status == -ECANCELED)
- /* a packet was flushed */
- flushing[if_idx] = true;
-
- vif->net_stats.tx_errors++;
-
- if (status != -ENOSPC && status != -ECANCELED)
- ath6kl_warn("tx complete error: %d\n", status);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
- "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
- __func__, skb, packet->buf, packet->act_len,
- eid, "error!");
- } else {
- ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
- "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
- __func__, skb, packet->buf, packet->act_len,
- eid, "OK");
-
- flushing[if_idx] = false;
- vif->net_stats.tx_packets++;
- vif->net_stats.tx_bytes += skb->len;
- }
-
- ath6kl_tx_clear_node_map(vif, eid, map_no);
- if (test_bit(NETQ_STOPPED, &vif->flags))
- clear_bit(NETQ_STOPPED, &vif->flags);
- }
-
-
- ath6kl_free_cookie(ar, ath6kl_cookie);
- }
-
- spin_unlock_bh(&ar->lock);
-
- __skb_queue_purge(&skb_queue);
-
- /* FIXME: Locking */
- if (!ctrl_ep) {
- spin_lock_bh(&ar->list_lock);
- list_for_each_entry(vif, &ar->vif_list, list) {
- if (test_bit(CONNECTED, &vif->flags) &&
- !flushing[vif->fw_vif_idx]) {
- spin_unlock_bh(&ar->list_lock);
- netif_wake_queue(vif->ndev);
- spin_lock_bh(&ar->list_lock);
- }
- }
- spin_unlock_bh(&ar->list_lock);
- }
-
- if (wake_event)
- wake_up(&ar->event_wq);
-
- return;
-
-fatal:
- WARN_ON(1);
- spin_unlock_bh(&ar->lock);
- return;
-}
-
-void ath6kl_tx_data_cleanup(struct ath6kl *ar)
-{
- int i;
-
- /* flush all the data (non-control) streams */
- for (i = 0; i < WMM_NUM_AC; i++)
- ath6kl_htc_flush_txep(ar->htc_target, ar->ac2ep_map[i],
- ATH6KL_DATA_PKT_TAG);
-}
-
-/* Rx functions */
-
-static void ath6kl_deliver_frames_to_nw_stack(struct net_device *dev,
- struct sk_buff *skb)
-{
- if (!skb)
- return;
-
- skb->dev = dev;
-
- if (!(skb->dev->flags & IFF_UP)) {
- dev_kfree_skb(skb);
- return;
- }
-
- skb->protocol = eth_type_trans(skb, skb->dev);
-
-#ifdef CONFIG_MACH_PX
- skb->len = skb->tail - skb->data;
-#endif
-
- netif_rx_ni(skb);
-}
-
-static void ath6kl_alloc_netbufs(struct sk_buff_head *q, u16 num)
-{
- struct sk_buff *skb;
-
- while (num) {
- skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
- if (!skb) {
- ath6kl_err("netbuf allocation failed\n");
- return;
- }
- skb_queue_tail(q, skb);
- num--;
- }
-}
-
-static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
-{
- struct sk_buff *skb = NULL;
-
- if (skb_queue_len(&p_aggr->rx_amsdu_freeq) <
- (AGGR_NUM_OF_FREE_NETBUFS >> 2))
- ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq,
- AGGR_NUM_OF_FREE_NETBUFS);
-
- skb = skb_dequeue(&p_aggr->rx_amsdu_freeq);
-
- return skb;
-}
-
-void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
-{
- struct ath6kl *ar = target->dev->ar;
- struct sk_buff *skb;
- int rx_buf;
- int n_buf_refill;
- struct htc_packet *packet;
- struct list_head queue;
-
- n_buf_refill = ATH6KL_MAX_RX_BUFFERS -
- ath6kl_htc_get_rxbuf_num(ar->htc_target, endpoint);
-
- if (n_buf_refill <= 0)
- return;
-
- INIT_LIST_HEAD(&queue);
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
- "%s: providing htc with %d buffers at eid=%d\n",
- __func__, n_buf_refill, endpoint);
-
- for (rx_buf = 0; rx_buf < n_buf_refill; rx_buf++) {
- skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
- if (!skb)
- break;
-
- packet = (struct htc_packet *) skb->head;
- if (!IS_ALIGNED((unsigned long) skb->data, 4))
- skb->data = PTR_ALIGN(skb->data - 4, 4);
- set_htc_rxpkt_info(packet, skb, skb->data,
- ATH6KL_BUFFER_SIZE, endpoint);
- list_add_tail(&packet->list, &queue);
- }
-
- if (!list_empty(&queue))
- ath6kl_htc_add_rxbuf_multiple(ar->htc_target, &queue);
-}
-
-void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
-{
- struct htc_packet *packet;
- struct sk_buff *skb;
-
- while (count) {
- skb = ath6kl_buf_alloc(ATH6KL_AMSDU_BUFFER_SIZE);
- if (!skb)
- return;
-
- packet = (struct htc_packet *) skb->head;
- if (!IS_ALIGNED((unsigned long) skb->data, 4))
- skb->data = PTR_ALIGN(skb->data - 4, 4);
- set_htc_rxpkt_info(packet, skb, skb->data,
- ATH6KL_AMSDU_BUFFER_SIZE, 0);
- spin_lock_bh(&ar->lock);
- list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue);
- spin_unlock_bh(&ar->lock);
- count--;
- }
-}
-
-/*
- * Callback to allocate a receive buffer for a pending packet. We use a
- * pre-allocated list of buffers of maximum AMSDU size (4K).
- */
-struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
- enum htc_endpoint_id endpoint,
- int len)
-{
- struct ath6kl *ar = target->dev->ar;
- struct htc_packet *packet = NULL;
- struct list_head *pkt_pos;
- int refill_cnt = 0, depth = 0;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: eid=%d, len:%d\n",
- __func__, endpoint, len);
-
- if ((len <= ATH6KL_BUFFER_SIZE) ||
- (len > ATH6KL_AMSDU_BUFFER_SIZE))
- return NULL;
-
- spin_lock_bh(&ar->lock);
-
- if (list_empty(&ar->amsdu_rx_buffer_queue)) {
- spin_unlock_bh(&ar->lock);
- refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS;
- goto refill_buf;
- }
-
- packet = list_first_entry(&ar->amsdu_rx_buffer_queue,
- struct htc_packet, list);
- list_del(&packet->list);
- list_for_each(pkt_pos, &ar->amsdu_rx_buffer_queue)
- depth++;
-
- refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS - depth;
- spin_unlock_bh(&ar->lock);
-
- /* set actual endpoint ID */
- packet->endpoint = endpoint;
-
-refill_buf:
- if (refill_cnt >= ATH6KL_AMSDU_REFILL_THRESHOLD)
- ath6kl_refill_amsdu_rxbufs(ar, refill_cnt);
-
- return packet;
-}
-
-static void aggr_slice_amsdu(struct aggr_info *p_aggr,
- struct rxtid *rxtid, struct sk_buff *skb)
-{
- struct sk_buff *new_skb;
- struct ethhdr *hdr;
- u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
- u8 *framep;
-
- mac_hdr_len = sizeof(struct ethhdr);
- framep = skb->data + mac_hdr_len;
- amsdu_len = skb->len - mac_hdr_len;
-
- while (amsdu_len > mac_hdr_len) {
- hdr = (struct ethhdr *) framep;
- payload_8023_len = ntohs(hdr->h_proto);
-
- if (payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN ||
- payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
- ath6kl_err("802.3 AMSDU frame bound check failed. len %d\n",
- payload_8023_len);
- break;
- }
-
- frame_8023_len = payload_8023_len + mac_hdr_len;
- new_skb = aggr_get_free_skb(p_aggr);
- if (!new_skb) {
- ath6kl_err("no buffer available\n");
- break;
- }
-
- memcpy(new_skb->data, framep, frame_8023_len);
- skb_put(new_skb, frame_8023_len);
- if (ath6kl_wmi_dot3_2_dix(new_skb)) {
- ath6kl_err("dot3_2_dix error\n");
- dev_kfree_skb(new_skb);
- break;
- }
-
- skb_queue_tail(&rxtid->q, new_skb);
-
- /* Is this the last subframe within this aggregate ? */
- if ((amsdu_len - frame_8023_len) == 0)
- break;
-
- /* Add the length of A-MSDU subframe padding bytes -
- * Round to nearest word.
- */
- frame_8023_len = ALIGN(frame_8023_len, 4);
-
- framep += frame_8023_len;
- amsdu_len -= frame_8023_len;
- }
-
- dev_kfree_skb(skb);
-}
-
-static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid,
- u16 seq_no, u8 order)
-{
- struct sk_buff *skb;
- struct rxtid *rxtid;
- struct skb_hold_q *node;
- u16 idx, idx_end, seq_end;
- struct rxtid_stats *stats;
-
- rxtid = &agg_conn->rx_tid[tid];
- stats = &agg_conn->stat[tid];
-
- idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
-
- /*
- * idx_end is typically the last possible frame in the window,
- * but changes to 'the' seq_no, when BAR comes. If seq_no
- * is non-zero, we will go up to that and stop.
- * Note: last seq no in current window will occupy the same
- * index position as index that is just previous to start.
- * An imp point : if win_sz is 7, for seq_no space of 4095,
- * then, there would be holes when sequence wrap around occurs.
- * Target should judiciously choose the win_sz, based on
- * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
- * 2, 4, 8, 16 win_sz works fine).
- * We must deque from "idx" to "idx_end", including both.
- */
- seq_end = seq_no ? seq_no : rxtid->seq_next;
- idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
-
- spin_lock_bh(&rxtid->lock);
-
- do {
- node = &rxtid->hold_q[idx];
- if ((order == 1) && (!node->skb))
- break;
-
- if (node->skb) {
- if (node->is_amsdu)
- aggr_slice_amsdu(agg_conn->aggr_info, rxtid,
- node->skb);
- else
- skb_queue_tail(&rxtid->q, node->skb);
- node->skb = NULL;
- } else
- stats->num_hole++;
-
- rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
- idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
- } while (idx != idx_end);
-
- spin_unlock_bh(&rxtid->lock);
-
- stats->num_delivered += skb_queue_len(&rxtid->q);
-
- while ((skb = skb_dequeue(&rxtid->q)))
- ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb);
-}
-
-static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid,
- u16 seq_no,
- bool is_amsdu, struct sk_buff *frame)
-{
- struct rxtid *rxtid;
- struct rxtid_stats *stats;
- struct sk_buff *skb;
- struct skb_hold_q *node;
- u16 idx, st, cur, end;
- bool is_queued = false;
- u16 extended_end;
-
- rxtid = &agg_conn->rx_tid[tid];
- stats = &agg_conn->stat[tid];
-
- stats->num_into_aggr++;
-
- if (!rxtid->aggr) {
- if (is_amsdu) {
- aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame);
- is_queued = true;
- stats->num_amsdu++;
- while ((skb = skb_dequeue(&rxtid->q)))
- ath6kl_deliver_frames_to_nw_stack(agg_conn->dev,
- skb);
- }
- return is_queued;
- }
-
- /* Check the incoming sequence no, if it's in the window */
- st = rxtid->seq_next;
- cur = seq_no;
- end = (st + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO;
-
- if (((st < end) && (cur < st || cur > end)) ||
- ((st > end) && (cur > end) && (cur < st))) {
- extended_end = (end + rxtid->hold_q_sz - 1) &
- ATH6KL_MAX_SEQ_NO;
-
- if (((end < extended_end) &&
- (cur < end || cur > extended_end)) ||
- ((end > extended_end) && (cur > extended_end) &&
- (cur < end))) {
- aggr_deque_frms(agg_conn, tid, 0, 0);
- if (cur >= rxtid->hold_q_sz - 1)
- rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
- else
- rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
- (rxtid->hold_q_sz - 2 - cur);
- } else {
- /*
- * Dequeue only those frames that are outside the
- * new shifted window.
- */
- if (cur >= rxtid->hold_q_sz - 1)
- st = cur - (rxtid->hold_q_sz - 1);
- else
- st = ATH6KL_MAX_SEQ_NO -
- (rxtid->hold_q_sz - 2 - cur);
-
- aggr_deque_frms(agg_conn, tid, st, 0);
- }
-
- stats->num_oow++;
- }
-
- idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
-
- node = &rxtid->hold_q[idx];
-
- spin_lock_bh(&rxtid->lock);
-
- /*
- * Is the cur frame duplicate or something beyond our window(hold_q
- * -> which is 2x, already)?
- *
- * 1. Duplicate is easy - drop incoming frame.
- * 2. Not falling in current sliding window.
- * 2a. is the frame_seq_no preceding current tid_seq_no?
- * -> drop the frame. perhaps sender did not get our ACK.
- * this is taken care of above.
- * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
- * -> Taken care of it above, by moving window forward.
- */
- dev_kfree_skb(node->skb);
- stats->num_dups++;
-
- node->skb = frame;
- is_queued = true;
- node->is_amsdu = is_amsdu;
- node->seq_no = seq_no;
-
- if (node->is_amsdu)
- stats->num_amsdu++;
- else
- stats->num_mpdu++;
-
- spin_unlock_bh(&rxtid->lock);
-
- aggr_deque_frms(agg_conn, tid, 0, 1);
-
- if (agg_conn->timer_scheduled)
- rxtid->progress = true;
- else
- for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
- if (rxtid->hold_q[idx].skb) {
- /*
- * There is a frame in the queue and no
- * timer so start a timer to ensure that
- * the frame doesn't remain stuck
- * forever.
- */
- agg_conn->timer_scheduled = true;
- mod_timer(&agg_conn->timer,
- (jiffies +
- HZ * (AGGR_RX_TIMEOUT) / 1000));
- rxtid->progress = false;
- rxtid->timer_mon = true;
- break;
- }
- }
-
- return is_queued;
-}
-
-static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
- struct ath6kl_sta *conn)
-{
- struct ath6kl *ar = vif->ar;
- bool is_apsdq_empty, is_apsdq_empty_at_start;
- u32 num_frames_to_deliver, flags;
- struct sk_buff *skb = NULL;
-
- /*
- * If the APSD q for this STA is not empty, dequeue and
- * send a pkt from the head of the q. Also update the
- * More data bit in the WMI_DATA_HDR if there are
- * more pkts for this STA in the APSD q.
- * If there are no more pkts for this STA,
- * update the APSD bitmap for this STA.
- */
-
- num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) &
- ATH6KL_APSD_FRAME_MASK;
- /*
- * Number of frames to send in a service period is
- * indicated by the station
- * in the QOS_INFO of the association request
- * If it is zero, send all frames
- */
- if (!num_frames_to_deliver)
- num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME;
-
- spin_lock_bh(&conn->psq_lock);
- is_apsdq_empty = skb_queue_empty(&conn->apsdq);
- spin_unlock_bh(&conn->psq_lock);
- is_apsdq_empty_at_start = is_apsdq_empty;
-
- while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
-
- spin_lock_bh(&conn->psq_lock);
- skb = skb_dequeue(&conn->apsdq);
- is_apsdq_empty = skb_queue_empty(&conn->apsdq);
- spin_unlock_bh(&conn->psq_lock);
-
- /*
- * Set the STA flag to Trigger delivery,
- * so that the frame will go out
- */
- conn->sta_flags |= STA_PS_APSD_TRIGGER;
- num_frames_to_deliver--;
-
- /* Last frame in the service period, set EOSP or queue empty */
- if ((is_apsdq_empty) || (!num_frames_to_deliver))
- conn->sta_flags |= STA_PS_APSD_EOSP;
-
- ath6kl_data_tx(skb, vif->ndev);
- conn->sta_flags &= ~(STA_PS_APSD_TRIGGER);
- conn->sta_flags &= ~(STA_PS_APSD_EOSP);
- }
-
- if (is_apsdq_empty) {
- if (is_apsdq_empty_at_start)
- flags = WMI_AP_APSD_NO_DELIVERY_FRAMES;
- else
- flags = 0;
-
- ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 0, flags);
- }
-
- return;
-}
-
-void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
-{
- struct ath6kl *ar = target->dev->ar;
- struct sk_buff *skb = packet->pkt_cntxt;
- struct wmi_rx_meta_v2 *meta;
- struct wmi_data_hdr *dhdr;
- int min_hdr_len;
- u8 meta_type, dot11_hdr = 0;
- int status = packet->status;
- enum htc_endpoint_id ept = packet->endpoint;
- bool is_amsdu, prev_ps, ps_state = false;
- bool trig_state = false;
- struct ath6kl_sta *conn = NULL;
- struct sk_buff *skb1 = NULL;
- struct ethhdr *datap = NULL;
- struct ath6kl_vif *vif;
- struct aggr_info_conn *aggr_conn;
- u16 seq_no, offset;
- u8 tid, if_idx;
-
- ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
- "%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
- __func__, ar, ept, skb, packet->buf,
- packet->act_len, status);
-
- if (status || !(skb->data + HTC_HDR_LENGTH)) {
- dev_kfree_skb(skb);
- return;
- }
-
- skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
- skb_pull(skb, HTC_HDR_LENGTH);
-
- if (ept == ar->ctrl_ep) {
- if_idx =
- wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data);
- } else {
- if_idx =
- wmi_data_hdr_get_if_idx((struct wmi_data_hdr *) skb->data);
- }
-
- vif = ath6kl_get_vif_by_index(ar, if_idx);
- if (!vif) {
- dev_kfree_skb(skb);
- return;
- }
-
- /*
- * Take lock to protect buffer counts and adaptive power throughput
- * state.
- */
- spin_lock_bh(&vif->if_lock);
-
- vif->net_stats.rx_packets++;
- vif->net_stats.rx_bytes += packet->act_len;
-
- spin_unlock_bh(&vif->if_lock);
-
-
- //ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
- // skb->data, skb->len);
-
- skb->dev = vif->ndev;
-
- if (!test_bit(WMI_ENABLED, &ar->flag)) {
- if (EPPING_ALIGNMENT_PAD > 0)
- skb_pull(skb, EPPING_ALIGNMENT_PAD);
- ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
- return;
- }
-
- if (ept == ar->ctrl_ep) {
- ath6kl_check_wow_status(ar, skb, true);
- ath6kl_wmi_control_rx(ar->wmi, skb);
- return;
- }
-
- min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
- sizeof(struct ath6kl_llc_snap_hdr);
-
- dhdr = (struct wmi_data_hdr *) skb->data;
-
- ath6kl_check_wow_status(ar, skb, false);
-
- /*
- * In the case of AP mode we may receive NULL data frames
- * that do not have LLC hdr. They are 16 bytes in size.
- * Allow these frames in the AP mode.
- */
- if (vif->nw_type != AP_NETWORK &&
- ((packet->act_len < min_hdr_len) ||
- (packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
- ath6kl_info("frame len is too short or too long\n");
- vif->net_stats.rx_errors++;
- vif->net_stats.rx_length_errors++;
- dev_kfree_skb(skb);
- return;
- }
-
- /* Get the Power save state of the STA */
- if (vif->nw_type == AP_NETWORK) {
- meta_type = wmi_data_hdr_get_meta(dhdr);
-
- ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
- WMI_DATA_HDR_PS_MASK);
-
- offset = sizeof(struct wmi_data_hdr);
- trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
-
- switch (meta_type) {
- case 0:
- break;
- case WMI_META_VERSION_1:
- offset += sizeof(struct wmi_rx_meta_v1);
- break;
- case WMI_META_VERSION_2:
- offset += sizeof(struct wmi_rx_meta_v2);
- break;
- default:
- break;
- }
-
- datap = (struct ethhdr *) (skb->data + offset);
- conn = ath6kl_find_sta(vif, datap->h_source);
-
- if (!conn) {
- dev_kfree_skb(skb);
- return;
- }
-
- /*
- * If there is a change in PS state of the STA,
- * take appropriate steps:
- *
- * 1. If Sleep-->Awake, flush the psq for the STA
- * Clear the PVB for the STA.
- * 2. If Awake-->Sleep, Starting queueing frames
- * the STA.
- */
- prev_ps = !!(conn->sta_flags & STA_PS_SLEEP);
-
- if (ps_state)
- conn->sta_flags |= STA_PS_SLEEP;
- else
- conn->sta_flags &= ~STA_PS_SLEEP;
-
- /* Accept trigger only when the station is in sleep */
- if ((conn->sta_flags & STA_PS_SLEEP) && trig_state)
- ath6kl_uapsd_trigger_frame_rx(vif, conn);
-
- if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
- if (!(conn->sta_flags & STA_PS_SLEEP)) {
- struct sk_buff *skbuff = NULL;
- bool is_apsdq_empty;
- struct ath6kl_mgmt_buff *mgmt;
- u8 idx;
-
- spin_lock_bh(&conn->psq_lock);
- while (conn->mgmt_psq_len > 0) {
- mgmt = list_first_entry(
- &conn->mgmt_psq,
- struct ath6kl_mgmt_buff,
- list);
- list_del(&mgmt->list);
- conn->mgmt_psq_len--;
- spin_unlock_bh(&conn->psq_lock);
- idx = vif->fw_vif_idx;
-
- ath6kl_wmi_send_mgmt_cmd(ar->wmi,
- idx,
- mgmt->id,
- mgmt->freq,
- mgmt->wait,
- mgmt->buf,
- mgmt->len,
- mgmt->no_cck);
-
- kfree(mgmt);
- spin_lock_bh(&conn->psq_lock);
- }
- conn->mgmt_psq_len = 0;
- while ((skbuff = skb_dequeue(&conn->psq))) {
- spin_unlock_bh(&conn->psq_lock);
- ath6kl_data_tx(skbuff, vif->ndev);
- spin_lock_bh(&conn->psq_lock);
- }
-
- is_apsdq_empty = skb_queue_empty(&conn->apsdq);
- while ((skbuff = skb_dequeue(&conn->apsdq))) {
- spin_unlock_bh(&conn->psq_lock);
- ath6kl_data_tx(skbuff, vif->ndev);
- spin_lock_bh(&conn->psq_lock);
- }
- spin_unlock_bh(&conn->psq_lock);
-
- if (!is_apsdq_empty)
- ath6kl_wmi_set_apsd_bfrd_traf(
- ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 0, 0);
-
- /* Clear the PVB for this STA */
- ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
- conn->aid, 0);
- }
- }
-
- /* drop NULL data frames here */
- if ((packet->act_len < min_hdr_len) ||
- (packet->act_len >
- WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) {
- dev_kfree_skb(skb);
- return;
- }
- }
-
- is_amsdu = wmi_data_hdr_is_amsdu(dhdr) ? true : false;
- tid = wmi_data_hdr_get_up(dhdr);
- seq_no = wmi_data_hdr_get_seqno(dhdr);
- meta_type = wmi_data_hdr_get_meta(dhdr);
- dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
- skb_pull(skb, sizeof(struct wmi_data_hdr));
-
- switch (meta_type) {
- case WMI_META_VERSION_1:
- skb_pull(skb, sizeof(struct wmi_rx_meta_v1));
- break;
- case WMI_META_VERSION_2:
- meta = (struct wmi_rx_meta_v2 *) skb->data;
- if (meta->csum_flags & 0x1) {
- skb->ip_summed = CHECKSUM_COMPLETE;
- skb->csum = (__force __wsum) meta->csum;
- }
- skb_pull(skb, sizeof(struct wmi_rx_meta_v2));
- break;
- default:
- break;
- }
-
- if (dot11_hdr)
- status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb);
- else if (!is_amsdu)
- status = ath6kl_wmi_dot3_2_dix(skb);
-
- if (status) {
- /*
- * Drop frames that could not be processed (lack of
- * memory, etc.)
- */
- dev_kfree_skb(skb);
- return;
- }
-
- if (!(vif->ndev->flags & IFF_UP)) {
- dev_kfree_skb(skb);
- return;
- }
-
- if (vif->nw_type == AP_NETWORK) {
- datap = (struct ethhdr *) skb->data;
- if (is_multicast_ether_addr(datap->h_dest))
- /*
- * Bcast/Mcast frames should be sent to the
- * OS stack as well as on the air.
- */
- skb1 = skb_copy(skb, GFP_ATOMIC);
- else {
- /*
- * Search for a connected STA with dstMac
- * as the Mac address. If found send the
- * frame to it on the air else send the
- * frame up the stack.
- */
- conn = ath6kl_find_sta(vif, datap->h_dest);
-
- if (conn && ar->intra_bss) {
- skb1 = skb;
- skb = NULL;
- } else if (conn && !ar->intra_bss) {
- dev_kfree_skb(skb);
- skb = NULL;
- }
- }
- if (skb1)
- ath6kl_data_tx(skb1, vif->ndev);
-
- if (skb == NULL) {
- /* nothing to deliver up the stack */
- return;
- }
- }
-
- datap = (struct ethhdr *) skb->data;
-
- if (is_unicast_ether_addr(datap->h_dest)) {
- if (vif->nw_type == AP_NETWORK) {
- conn = ath6kl_find_sta(vif, datap->h_source);
- if (!conn)
- return;
- aggr_conn = conn->aggr_conn;
- } else
- aggr_conn = vif->aggr_cntxt->aggr_conn;
-
- if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
- is_amsdu, skb)) {
- /* aggregation code will handle the skb */
- return;
- }
- }
-
- ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb);
-}
-
-static void aggr_timeout(unsigned long arg)
-{
- u8 i, j;
- struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg;
- struct rxtid *rxtid;
- struct rxtid_stats *stats;
-
- for (i = 0; i < NUM_OF_TIDS; i++) {
- rxtid = &aggr_conn->rx_tid[i];
- stats = &aggr_conn->stat[i];
-
- if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
- continue;
-
- stats->num_timeouts++;
- ath6kl_dbg(ATH6KL_DBG_AGGR,
- "aggr timeout (st %d end %d)\n",
- rxtid->seq_next,
- ((rxtid->seq_next + rxtid->hold_q_sz-1) &
- ATH6KL_MAX_SEQ_NO));
- aggr_deque_frms(aggr_conn, i, 0, 0);
- }
-
- aggr_conn->timer_scheduled = false;
-
- for (i = 0; i < NUM_OF_TIDS; i++) {
- rxtid = &aggr_conn->rx_tid[i];
-
- if (rxtid->aggr && rxtid->hold_q) {
- for (j = 0; j < rxtid->hold_q_sz; j++) {
- if (rxtid->hold_q[j].skb) {
- aggr_conn->timer_scheduled = true;
- rxtid->timer_mon = true;
- rxtid->progress = false;
- break;
- }
- }
-
- if (j >= rxtid->hold_q_sz)
- rxtid->timer_mon = false;
- }
- }
-
- if (aggr_conn->timer_scheduled)
- mod_timer(&aggr_conn->timer,
- jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
-}
-
-static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
-{
- struct rxtid *rxtid;
- struct rxtid_stats *stats;
-
- if (!aggr_conn || tid >= NUM_OF_TIDS)
- return;
-
- rxtid = &aggr_conn->rx_tid[tid];
- stats = &aggr_conn->stat[tid];
-
- if (rxtid->aggr)
- aggr_deque_frms(aggr_conn, tid, 0, 0);
-
- rxtid->aggr = false;
- rxtid->progress = false;
- rxtid->timer_mon = false;
- rxtid->win_sz = 0;
- rxtid->seq_next = 0;
- rxtid->hold_q_sz = 0;
-
- kfree(rxtid->hold_q);
- rxtid->hold_q = NULL;
-
- memset(stats, 0, sizeof(struct rxtid_stats));
-}
-
-void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no,
- u8 win_sz)
-{
- struct ath6kl_sta *sta;
- struct aggr_info_conn *aggr_conn = NULL;
- struct rxtid *rxtid;
- struct rxtid_stats *stats;
- u16 hold_q_size;
- u8 tid, aid;
-
- if (vif->nw_type == AP_NETWORK) {
- aid = ath6kl_get_aid(tid_mux);
- sta = ath6kl_find_sta_by_aid(vif->ar, aid);
- if (sta)
- aggr_conn = sta->aggr_conn;
- } else
- aggr_conn = vif->aggr_cntxt->aggr_conn;
-
- if (!aggr_conn)
- return;
-
- tid = ath6kl_get_tid(tid_mux);
- if (tid >= NUM_OF_TIDS)
- return;
-
- rxtid = &aggr_conn->rx_tid[tid];
- stats = &aggr_conn->stat[tid];
-
- if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
- ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
- __func__, win_sz, tid);
-
- if (rxtid->aggr)
- aggr_delete_tid_state(aggr_conn, tid);
-
- rxtid->seq_next = seq_no;
- hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
- rxtid->hold_q = kzalloc(hold_q_size, GFP_KERNEL);
- if (!rxtid->hold_q)
- return;
-
- rxtid->win_sz = win_sz;
- rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
- if (!skb_queue_empty(&rxtid->q))
- return;
-
- rxtid->aggr = true;
-}
-
-void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
- struct aggr_info_conn *aggr_conn)
-{
- struct rxtid *rxtid;
- u8 i;
-
- aggr_conn->aggr_sz = AGGR_SZ_DEFAULT;
- aggr_conn->dev = vif->ndev;
- init_timer(&aggr_conn->timer);
- aggr_conn->timer.function = aggr_timeout;
- aggr_conn->timer.data = (unsigned long) aggr_conn;
- aggr_conn->aggr_info = aggr_info;
-
- aggr_conn->timer_scheduled = false;
-
- for (i = 0; i < NUM_OF_TIDS; i++) {
- rxtid = &aggr_conn->rx_tid[i];
- rxtid->aggr = false;
- rxtid->progress = false;
- rxtid->timer_mon = false;
- skb_queue_head_init(&rxtid->q);
- spin_lock_init(&rxtid->lock);
- }
-
-}
-
-struct aggr_info *aggr_init(struct ath6kl_vif *vif)
-{
- struct aggr_info *p_aggr = NULL;
-
- p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
- if (!p_aggr) {
- ath6kl_err("failed to alloc memory for aggr_node\n");
- return NULL;
- }
-
- p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
- if (!p_aggr->aggr_conn) {
- ath6kl_err("failed to alloc memory for connection specific aggr info\n");
- kfree(p_aggr);
- return NULL;
- }
-
- aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn);
-
- skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
- ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);
-
- return p_aggr;
-}
-
-void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux)
-{
- struct ath6kl_sta *sta;
- struct rxtid *rxtid;
- struct aggr_info_conn *aggr_conn = NULL;
- u8 tid, aid;
-
- if (vif->nw_type == AP_NETWORK) {
- aid = ath6kl_get_aid(tid_mux);
- sta = ath6kl_find_sta_by_aid(vif->ar, aid);
- if (sta)
- aggr_conn = sta->aggr_conn;
- } else
- aggr_conn = vif->aggr_cntxt->aggr_conn;
-
- if (!aggr_conn)
- return;
-
- tid = ath6kl_get_tid(tid_mux);
- if (tid >= NUM_OF_TIDS)
- return;
-
- rxtid = &aggr_conn->rx_tid[tid];
-
- if (rxtid->aggr)
- aggr_delete_tid_state(aggr_conn, tid);
-}
-
-void aggr_reset_state(struct aggr_info_conn *aggr_conn)
-{
- u8 tid;
-
- if (!aggr_conn)
- return;
-
- if (aggr_conn->timer_scheduled) {
- del_timer(&aggr_conn->timer);
- aggr_conn->timer_scheduled = false;
- }
-
- for (tid = 0; tid < NUM_OF_TIDS; tid++)
- aggr_delete_tid_state(aggr_conn, tid);
-}
-
-/* clean up our amsdu buffer list */
-void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
-{
- struct htc_packet *packet, *tmp_pkt;
-
- spin_lock_bh(&ar->lock);
- if (list_empty(&ar->amsdu_rx_buffer_queue)) {
- spin_unlock_bh(&ar->lock);
- return;
- }
-
- list_for_each_entry_safe(packet, tmp_pkt, &ar->amsdu_rx_buffer_queue,
- list) {
- list_del(&packet->list);
- spin_unlock_bh(&ar->lock);
- dev_kfree_skb(packet->pkt_cntxt);
- spin_lock_bh(&ar->lock);
- }
-
- spin_unlock_bh(&ar->lock);
-}
-
-void aggr_module_destroy(struct aggr_info *aggr_info)
-{
- if (!aggr_info)
- return;
-
- aggr_reset_state(aggr_info->aggr_conn);
- skb_queue_purge(&aggr_info->rx_amsdu_freeq);
- kfree(aggr_info->aggr_conn);
- kfree(aggr_info);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c
deleted file mode 100755
index daf5122..0000000
--- a/drivers/net/wireless/ath/ath6kl/usb.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2007-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#include "debug.h"
-#include "core.h"
-
-/* usb device object */
-struct ath6kl_usb {
- struct usb_device *udev;
- struct usb_interface *interface;
- u8 *diag_cmd_buffer;
- u8 *diag_resp_buffer;
- struct ath6kl *ar;
-};
-
-/* diagnostic command defnitions */
-#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1
-#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2
-#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3
-#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4
-
-#define ATH6KL_USB_CTRL_DIAG_CC_READ 0
-#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1
-
-struct ath6kl_usb_ctrl_diag_cmd_write {
- __le32 cmd;
- __le32 address;
- __le32 value;
- __le32 _pad[1];
-} __packed;
-
-struct ath6kl_usb_ctrl_diag_cmd_read {
- __le32 cmd;
- __le32 address;
-} __packed;
-
-struct ath6kl_usb_ctrl_diag_resp_read {
- __le32 value;
-} __packed;
-
-#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write))
-#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read))
-
-static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb)
-{
- usb_set_intfdata(ar_usb->interface, NULL);
-
- kfree(ar_usb->diag_cmd_buffer);
- kfree(ar_usb->diag_resp_buffer);
-
- kfree(ar_usb);
-}
-
-static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface)
-{
- struct ath6kl_usb *ar_usb = NULL;
- struct usb_device *dev = interface_to_usbdev(interface);
- int status = 0;
-
- ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
- if (ar_usb == NULL)
- goto fail_ath6kl_usb_create;
-
- memset(ar_usb, 0, sizeof(struct ath6kl_usb));
- usb_set_intfdata(interface, ar_usb);
- ar_usb->udev = dev;
- ar_usb->interface = interface;
-
- ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL);
- if (ar_usb->diag_cmd_buffer == NULL) {
- status = -ENOMEM;
- goto fail_ath6kl_usb_create;
- }
-
- ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP,
- GFP_KERNEL);
- if (ar_usb->diag_resp_buffer == NULL) {
- status = -ENOMEM;
- goto fail_ath6kl_usb_create;
- }
-
-fail_ath6kl_usb_create:
- if (status != 0) {
- ath6kl_usb_destroy(ar_usb);
- ar_usb = NULL;
- }
- return ar_usb;
-}
-
-static void ath6kl_usb_device_detached(struct usb_interface *interface)
-{
- struct ath6kl_usb *ar_usb;
-
- ar_usb = usb_get_intfdata(interface);
- if (ar_usb == NULL)
- return;
-
- ath6kl_stop_txrx(ar_usb->ar);
-
- ath6kl_core_cleanup(ar_usb->ar);
-
- ath6kl_usb_destroy(ar_usb);
-}
-
-static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
- u8 req, u16 value, u16 index, void *data,
- u32 size)
-{
- u8 *buf = NULL;
- int ret;
-
- if (size > 0) {
- buf = kmalloc(size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- memcpy(buf, data, size);
- }
-
- /* note: if successful returns number of bytes transfered */
- ret = usb_control_msg(ar_usb->udev,
- usb_sndctrlpipe(ar_usb->udev, 0),
- req,
- USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, value, index, buf,
- size, 1000);
-
- if (ret < 0) {
- ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
- __func__, ret);
- }
-
- kfree(buf);
-
- return 0;
-}
-
-static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
- u8 req, u16 value, u16 index, void *data,
- u32 size)
-{
- u8 *buf = NULL;
- int ret;
-
- if (size > 0) {
- buf = kmalloc(size, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- }
-
- /* note: if successful returns number of bytes transfered */
- ret = usb_control_msg(ar_usb->udev,
- usb_rcvctrlpipe(ar_usb->udev, 0),
- req,
- USB_DIR_IN | USB_TYPE_VENDOR |
- USB_RECIP_DEVICE, value, index, buf,
- size, 2 * HZ);
-
- if (ret < 0) {
- ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
- __func__, ret);
- }
-
- memcpy((u8 *) data, buf, size);
-
- kfree(buf);
-
- return 0;
-}
-
-static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb,
- u8 req_val, u8 *req_buf, u32 req_len,
- u8 resp_val, u8 *resp_buf, u32 *resp_len)
-{
- int ret;
-
- /* send command */
- ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0,
- req_buf, req_len);
-
- if (ret != 0)
- return ret;
-
- if (resp_buf == NULL) {
- /* no expected response */
- return ret;
- }
-
- /* get response */
- ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0,
- resp_buf, *resp_len);
-
- return ret;
-}
-
-static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
-{
- struct ath6kl_usb *ar_usb = ar->hif_priv;
- struct ath6kl_usb_ctrl_diag_resp_read *resp;
- struct ath6kl_usb_ctrl_diag_cmd_read *cmd;
- u32 resp_len;
- int ret;
-
- cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer;
-
- memset(cmd, 0, sizeof(*cmd));
- cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ;
- cmd->address = cpu_to_le32(address);
- resp_len = sizeof(*resp);
-
- ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
- ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
- (u8 *) cmd,
- sizeof(struct ath6kl_usb_ctrl_diag_cmd_write),
- ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
- ar_usb->diag_resp_buffer, &resp_len);
-
- if (ret)
- return ret;
-
- resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
- ar_usb->diag_resp_buffer;
-
- *data = le32_to_cpu(resp->value);
-
- return ret;
-}
-
-static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
-{
- struct ath6kl_usb *ar_usb = ar->hif_priv;
- struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
-
- cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
-
- memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write));
- cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE);
- cmd->address = cpu_to_le32(address);
- cmd->value = data;
-
- return ath6kl_usb_ctrl_msg_exchange(ar_usb,
- ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
- (u8 *) cmd,
- sizeof(*cmd),
- 0, NULL, NULL);
-
-}
-
-static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
-{
- struct ath6kl_usb *ar_usb = ar->hif_priv;
- int ret;
-
- /* get response */
- ret = ath6kl_usb_submit_ctrl_in(ar_usb,
- ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
- 0, 0, buf, len);
- if (ret != 0) {
- ath6kl_err("Unable to read the bmi data from the device: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
-{
- struct ath6kl_usb *ar_usb = ar->hif_priv;
- int ret;
-
- /* send command */
- ret = ath6kl_usb_submit_ctrl_out(ar_usb,
- ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
- 0, 0, buf, len);
- if (ret != 0) {
- ath6kl_err("unable to send the bmi data to the device: %d\n",
- ret);
- return ret;
- }
-
- return 0;
-}
-
-static int ath6kl_usb_power_on(struct ath6kl *ar)
-{
- return 0;
-}
-
-static int ath6kl_usb_power_off(struct ath6kl *ar)
-{
- return 0;
-}
-
-static const struct ath6kl_hif_ops ath6kl_usb_ops = {
- .diag_read32 = ath6kl_usb_diag_read32,
- .diag_write32 = ath6kl_usb_diag_write32,
- .bmi_read = ath6kl_usb_bmi_read,
- .bmi_write = ath6kl_usb_bmi_write,
- .power_on = ath6kl_usb_power_on,
- .power_off = ath6kl_usb_power_off,
-};
-
-/* ath6kl usb driver registered functions */
-static int ath6kl_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(interface);
- struct ath6kl *ar;
- struct ath6kl_usb *ar_usb = NULL;
- int vendor_id, product_id;
- int ret = 0;
-
- usb_get_dev(dev);
-
- vendor_id = le16_to_cpu(dev->descriptor.idVendor);
- product_id = le16_to_cpu(dev->descriptor.idProduct);
-
- ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id);
- ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id);
-
- if (interface->cur_altsetting)
- ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n",
- interface->cur_altsetting->desc.bInterfaceNumber);
-
-
- if (dev->speed == USB_SPEED_HIGH)
- ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n");
- else
- ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n");
-
- ar_usb = ath6kl_usb_create(interface);
-
- if (ar_usb == NULL) {
- ret = -ENOMEM;
- goto err_usb_put;
- }
-
- ar = ath6kl_core_alloc(&ar_usb->udev->dev);
- if (ar == NULL) {
- ath6kl_err("Failed to alloc ath6kl core\n");
- ret = -ENOMEM;
- goto err_usb_destroy;
- }
-
- ar->hif_priv = ar_usb;
- ar->hif_type = ATH6KL_HIF_TYPE_USB;
- ar->hif_ops = &ath6kl_usb_ops;
- ar->mbox_info.block_size = 16;
- ar->bmi.max_data_size = 252;
-
- ar_usb->ar = ar;
-
- ret = ath6kl_core_init(ar);
- if (ret) {
- ath6kl_err("Failed to init ath6kl core: %d\n", ret);
- goto err_core_free;
- }
-
- return ret;
-
-err_core_free:
- ath6kl_core_free(ar);
-err_usb_destroy:
- ath6kl_usb_destroy(ar_usb);
-err_usb_put:
- usb_put_dev(dev);
-
- return ret;
-}
-
-static void ath6kl_usb_remove(struct usb_interface *interface)
-{
- usb_put_dev(interface_to_usbdev(interface));
- ath6kl_usb_device_detached(interface);
-}
-
-/* table of devices that work with this driver */
-static struct usb_device_id ath6kl_usb_ids[] = {
- {USB_DEVICE(0x0cf3, 0x9374)},
- { /* Terminating entry */ },
-};
-
-MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids);
-
-static struct usb_driver ath6kl_usb_driver = {
- .name = "ath6kl_usb",
- .probe = ath6kl_usb_probe,
- .disconnect = ath6kl_usb_remove,
- .id_table = ath6kl_usb_ids,
-};
-
-static int ath6kl_usb_init(void)
-{
- usb_register(&ath6kl_usb_driver);
- return 0;
-}
-
-static void ath6kl_usb_exit(void)
-{
- usb_deregister(&ath6kl_usb_driver);
-}
-
-module_init(ath6kl_usb_init);
-module_exit(ath6kl_usb_exit);
-
-MODULE_AUTHOR("Atheros Communications, Inc.");
-MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices");
-MODULE_LICENSE("Dual BSD/GPL");
-
-MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE);
-MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
deleted file mode 100755
index f7afb1d..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ /dev/null
@@ -1,3947 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/ip.h>
-#include "core.h"
-#include "debug.h"
-#include "testmode.h"
-#include "../regd.h"
-#include "../regd_common.h"
-#include "btc.h"
-#include "debugfs_pri.h"
-
-static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx);
-
-static const s32 wmi_rate_tbl[][2] = {
- /* {W/O SGI, with SGI} */
- {1000, 1000},
- {2000, 2000},
- {5500, 5500},
- {11000, 11000},
- {6000, 6000},
- {9000, 9000},
- {12000, 12000},
- {18000, 18000},
- {24000, 24000},
- {36000, 36000},
- {48000, 48000},
- {54000, 54000},
- {6500, 7200},
- {13000, 14400},
- {19500, 21700},
- {26000, 28900},
- {39000, 43300},
- {52000, 57800},
- {58500, 65000},
- {65000, 72200},
- {13500, 15000},
- {27000, 30000},
- {40500, 45000},
- {54000, 60000},
- {81000, 90000},
- {108000, 120000},
- {121500, 135000},
- {135000, 150000},
- {0, 0}
-};
-
-/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
-static const u8 up_to_ac[] = {
- WMM_AC_BE,
- WMM_AC_BK,
- WMM_AC_BK,
- WMM_AC_BE,
- WMM_AC_VI,
- WMM_AC_VI,
- WMM_AC_VO,
- WMM_AC_VO,
-};
-
-void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id)
-{
- if (WARN_ON(ep_id == ENDPOINT_UNUSED || ep_id >= ENDPOINT_MAX))
- return;
-
- wmi->ep_id = ep_id;
-}
-
-enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
-{
- return wmi->ep_id;
-}
-
-struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx)
-{
- struct ath6kl_vif *vif, *found = NULL;
-
- if (WARN_ON(if_idx > (ar->vif_max - 1)))
- return NULL;
-
- /* FIXME: Locking */
- spin_lock_bh(&ar->list_lock);
- list_for_each_entry(vif, &ar->vif_list, list) {
- if (vif->fw_vif_idx == if_idx) {
- found = vif;
- break;
- }
- }
- spin_unlock_bh(&ar->list_lock);
-
- return found;
-}
-
-/* Performs DIX to 802.3 encapsulation for transmit packets.
- * Assumes the entire DIX header is contigous and that there is
- * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
- */
-int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
-{
- struct ath6kl_llc_snap_hdr *llc_hdr;
- struct ethhdr *eth_hdr;
- size_t new_len;
- __be16 type;
- u8 *datap;
- u16 size;
-
- if (WARN_ON(skb == NULL))
- return -EINVAL;
-
- size = sizeof(struct ath6kl_llc_snap_hdr) + sizeof(struct wmi_data_hdr);
- if (skb_headroom(skb) < size)
- return -ENOMEM;
-
- eth_hdr = (struct ethhdr *) skb->data;
- type = eth_hdr->h_proto;
-
- if (!is_ethertype(be16_to_cpu(type))) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "%s: pkt is already in 802.3 format\n", __func__);
- return 0;
- }
-
- new_len = skb->len - sizeof(*eth_hdr) + sizeof(*llc_hdr);
-
- skb_push(skb, sizeof(struct ath6kl_llc_snap_hdr));
- datap = skb->data;
-
- eth_hdr->h_proto = cpu_to_be16(new_len);
-
- memcpy(datap, eth_hdr, sizeof(*eth_hdr));
-
- llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap + sizeof(*eth_hdr));
- llc_hdr->dsap = 0xAA;
- llc_hdr->ssap = 0xAA;
- llc_hdr->cntl = 0x03;
- llc_hdr->org_code[0] = 0x0;
- llc_hdr->org_code[1] = 0x0;
- llc_hdr->org_code[2] = 0x0;
- llc_hdr->eth_type = type;
-
- return 0;
-}
-
-static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
- u8 *version, void *tx_meta_info)
-{
- struct wmi_tx_meta_v1 *v1;
- struct wmi_tx_meta_v2 *v2;
-
- if (WARN_ON(skb == NULL || version == NULL))
- return -EINVAL;
-
- switch (*version) {
- case WMI_META_VERSION_1:
- skb_push(skb, WMI_MAX_TX_META_SZ);
- v1 = (struct wmi_tx_meta_v1 *) skb->data;
- v1->pkt_id = 0;
- v1->rate_plcy_id = 0;
- *version = WMI_META_VERSION_1;
- break;
- case WMI_META_VERSION_2:
- skb_push(skb, WMI_MAX_TX_META_SZ);
- v2 = (struct wmi_tx_meta_v2 *) skb->data;
- memcpy(v2, (struct wmi_tx_meta_v2 *) tx_meta_info,
- sizeof(struct wmi_tx_meta_v2));
- break;
- }
-
- return 0;
-}
-
-int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
- u8 msg_type, u32 flags,
- enum wmi_data_hdr_data_type data_type,
- u8 meta_ver, void *tx_meta_info, u8 if_idx)
-{
- struct wmi_data_hdr *data_hdr;
- int ret;
-
- if (WARN_ON(skb == NULL || (if_idx > wmi->parent_dev->vif_max - 1)))
- return -EINVAL;
-
- if (tx_meta_info) {
- ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
- if (ret)
- return ret;
- }
-
- skb_push(skb, sizeof(struct wmi_data_hdr));
-
- data_hdr = (struct wmi_data_hdr *)skb->data;
- memset(data_hdr, 0, sizeof(struct wmi_data_hdr));
-
- data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
- data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
-
- if (flags & WMI_DATA_HDR_FLAGS_MORE)
- data_hdr->info |= WMI_DATA_HDR_MORE;
-
- if (flags & WMI_DATA_HDR_FLAGS_EOSP)
- data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP);
-
- data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
- data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
-
- return 0;
-}
-
-u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
-{
- struct iphdr *ip_hdr = (struct iphdr *) pkt;
- u8 ip_pri;
-
- /*
- * Determine IPTOS priority
- *
- * IP-TOS - 8bits
- * : DSCP(6-bits) ECN(2-bits)
- * : DSCP - P2 P1 P0 X X X
- * where (P2 P1 P0) form 802.1D
- */
- ip_pri = ip_hdr->tos >> 5;
- ip_pri &= 0x7;
-
- if ((layer2_pri & 0x7) > ip_pri)
- return (u8) layer2_pri & 0x7;
- else
- return ip_pri;
-}
-
-u8 ath6kl_wmi_get_traffic_class(u8 user_priority)
-{
- return up_to_ac[user_priority & 0x7];
-}
-
-int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
- struct sk_buff *skb,
- u32 layer2_priority, bool wmm_enabled,
- u8 *ac)
-{
- struct wmi_data_hdr *data_hdr;
- struct ath6kl_llc_snap_hdr *llc_hdr;
- struct wmi_create_pstream_cmd cmd;
- u32 meta_size, hdr_size;
- u16 ip_type = IP_ETHERTYPE;
- u8 stream_exist, usr_pri;
- u8 traffic_class = WMM_AC_BE;
- u8 *datap;
-
- if (WARN_ON(skb == NULL))
- return -EINVAL;
-
- datap = skb->data;
- data_hdr = (struct wmi_data_hdr *) datap;
-
- meta_size = ((le16_to_cpu(data_hdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
- WMI_DATA_HDR_META_MASK) ? WMI_MAX_TX_META_SZ : 0;
-
- if (!wmm_enabled) {
- /* If WMM is disabled all traffic goes as BE traffic */
- usr_pri = 0;
- } else {
- hdr_size = sizeof(struct ethhdr);
-
- llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap +
- sizeof(struct
- wmi_data_hdr) +
- meta_size + hdr_size);
-
- if (llc_hdr->eth_type == htons(ip_type)) {
- /*
- * Extract the endpoint info from the TOS field
- * in the IP header.
- */
- usr_pri =
- ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
- sizeof(struct ath6kl_llc_snap_hdr),
- layer2_priority);
- } else
- usr_pri = layer2_priority & 0x7;
-
- /*
- * Queue the EAPOL frames in the same WMM_AC_VO queue
- * as that of management frames.
- */
- if (skb->protocol == cpu_to_be16(ETH_P_PAE))
- usr_pri = WMI_VOICE_USER_PRIORITY;
- }
-
- /*
- * workaround for WMM S5
- *
- * FIXME: wmi->traffic_class is always 100 so this test doesn't
- * make sense
- */
- if ((wmi->traffic_class == WMM_AC_VI) &&
- ((usr_pri == 5) || (usr_pri == 4)))
- usr_pri = 1;
-
- /* Convert user priority to traffic class */
- traffic_class = up_to_ac[usr_pri & 0x7];
-
- wmi_data_hdr_set_up(data_hdr, usr_pri);
-
- spin_lock_bh(&wmi->lock);
- stream_exist = wmi->fat_pipe_exist;
- spin_unlock_bh(&wmi->lock);
-
- if (!(stream_exist & (1 << traffic_class))) {
- memset(&cmd, 0, sizeof(cmd));
- cmd.traffic_class = traffic_class;
- cmd.user_pri = usr_pri;
- cmd.inactivity_int =
- cpu_to_le32(WMI_IMPLICIT_PSTREAM_INACTIVITY_INT);
- /* Implicit streams are created with TSID 0xFF */
- cmd.tsid = WMI_IMPLICIT_PSTREAM;
- ath6kl_wmi_create_pstream_cmd(wmi, if_idx, &cmd);
- }
-
- *ac = traffic_class;
-
- return 0;
-}
-
-int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
-{
- struct ieee80211_hdr_3addr *pwh, wh;
- struct ath6kl_llc_snap_hdr *llc_hdr;
- struct ethhdr eth_hdr;
- u32 hdr_size;
- u8 *datap;
- __le16 sub_type;
-
- if (WARN_ON(skb == NULL))
- return -EINVAL;
-
- datap = skb->data;
- pwh = (struct ieee80211_hdr_3addr *) datap;
-
- sub_type = pwh->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
-
- memcpy((u8 *) &wh, datap, sizeof(struct ieee80211_hdr_3addr));
-
- /* Strip off the 802.11 header */
- if (sub_type == cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
- hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
- sizeof(u32));
- skb_pull(skb, hdr_size);
- } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
- skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
-
- datap = skb->data;
- llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
-
- memset(&eth_hdr, 0, sizeof(eth_hdr));
- eth_hdr.h_proto = llc_hdr->eth_type;
-
- switch ((le16_to_cpu(wh.frame_control)) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case 0:
- memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
- memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_TODS:
- memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN);
- memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
- memcpy(eth_hdr.h_source, wh.addr3, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- break;
- }
-
- skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
- skb_push(skb, sizeof(eth_hdr));
-
- datap = skb->data;
-
- memcpy(datap, &eth_hdr, sizeof(eth_hdr));
-
- return 0;
-}
-
-/*
- * Performs 802.3 to DIX encapsulation for received packets.
- * Assumes the entire 802.3 header is contigous.
- */
-int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
-{
- struct ath6kl_llc_snap_hdr *llc_hdr;
- struct ethhdr eth_hdr;
- u8 *datap;
-
- if (WARN_ON(skb == NULL))
- return -EINVAL;
-
- datap = skb->data;
-
- memcpy(&eth_hdr, datap, sizeof(eth_hdr));
-
- llc_hdr = (struct ath6kl_llc_snap_hdr *) (datap + sizeof(eth_hdr));
- eth_hdr.h_proto = llc_hdr->eth_type;
-
- skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
- datap = skb->data;
-
- memcpy(datap, &eth_hdr, sizeof(eth_hdr));
-
- return 0;
-}
-
-static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
-{
- struct tx_complete_msg_v1 *msg_v1;
- struct wmi_tx_complete_event *evt;
- int index;
- u16 size;
-
- evt = (struct wmi_tx_complete_event *) datap;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
- evt->num_msg, evt->msg_len, evt->msg_type);
-
- if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
- return 0;
-
- for (index = 0; index < evt->num_msg; index++) {
- size = sizeof(struct wmi_tx_complete_event) +
- (index * sizeof(struct tx_complete_msg_v1));
- msg_v1 = (struct tx_complete_msg_v1 *)(datap + size);
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "msg: %d %d %d %d\n",
- msg_v1->status, msg_v1->pkt_id,
- msg_v1->rate_idx, msg_v1->ack_failures);
- }
-
- return 0;
-}
-
-static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap,
- int len, struct ath6kl_vif *vif)
-{
- struct wmi_remain_on_chnl_event *ev;
- u32 freq;
- u32 dur;
- struct ieee80211_channel *chan;
- struct ath6kl *ar = wmi->parent_dev;
- u32 id;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_remain_on_chnl_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dur = le32_to_cpu(ev->duration);
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: freq=%u dur=%u\n",
- freq, dur);
- chan = ieee80211_get_channel(ar->wiphy, freq);
- if (!chan) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl: Unknown channel "
- "(freq=%u)\n", freq);
- return -EINVAL;
- }
- id = vif->last_roc_id;
- cfg80211_ready_on_channel(vif->ndev, id, chan, NL80211_CHAN_NO_HT,
- dur, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi,
- u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_cancel_remain_on_chnl_event *ev;
- u32 freq;
- u32 dur;
- struct ieee80211_channel *chan;
- struct ath6kl *ar = wmi->parent_dev;
- u32 id;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_cancel_remain_on_chnl_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dur = le32_to_cpu(ev->duration);
- ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: freq=%u dur=%u "
- "status=%u\n", freq, dur, ev->status);
- chan = ieee80211_get_channel(ar->wiphy, freq);
- if (!chan) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl: Unknown "
- "channel (freq=%u)\n", freq);
- return -EINVAL;
- }
- if (vif->last_cancel_roc_id &&
- vif->last_cancel_roc_id + 1 == vif->last_roc_id)
- id = vif->last_cancel_roc_id; /* event for cancel command */
- else
- id = vif->last_roc_id; /* timeout on uncanceled r-o-c */
- vif->last_cancel_roc_id = 0;
- cfg80211_remain_on_channel_expired(vif->ndev, id, chan,
- NL80211_CHAN_NO_HT, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_tx_status_event *ev;
- u32 id;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_tx_status_event *) datap;
- id = le32_to_cpu(ev->id);
- ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n",
- id, ev->ack_status);
-
- mutex_lock(&wmi->lock_mgmt);
- if (wmi->last_mgmt_tx_frame) {
- cfg80211_mgmt_tx_status(vif->ndev, id,
- wmi->last_mgmt_tx_frame,
- wmi->last_mgmt_tx_frame_len,
- !!ev->ack_status, GFP_ATOMIC);
- kfree(wmi->last_mgmt_tx_frame);
- wmi->last_mgmt_tx_frame = NULL;
- wmi->last_mgmt_tx_frame_len = 0;
- }
- mutex_unlock(&wmi->lock_mgmt);
-
- return 0;
-}
-
-static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_p2p_rx_probe_req_event *ev;
- u32 freq;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_p2p_rx_probe_req_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dlen = le16_to_cpu(ev->len);
- if (datap + len < ev->data + dlen) {
- ath6kl_err("invalid wmi_p2p_rx_probe_req_event: "
- "len=%d dlen=%u\n", len, dlen);
- return -EINVAL;
- }
- ath6kl_dbg(ATH6KL_DBG_WMI, "rx_probe_req: len=%u freq=%u "
- "probe_req_report=%d\n",
- dlen, freq, vif->probe_req_report);
-
- if (vif->probe_req_report || vif->nw_type == AP_NETWORK)
- cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_p2p_capabilities_event_rx(u8 *datap, int len)
-{
- struct wmi_p2p_capabilities_event *ev;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_p2p_capabilities_event *) datap;
- dlen = le16_to_cpu(ev->len);
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_capab: len=%u\n", dlen);
-
- return 0;
-}
-
-static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_rx_action_event *ev;
- u32 freq;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_rx_action_event *) datap;
- freq = le32_to_cpu(ev->freq);
- dlen = le16_to_cpu(ev->len);
- if (datap + len < ev->data + dlen) {
- ath6kl_err("invalid wmi_rx_action_event: "
- "len=%d dlen=%u\n", len, dlen);
- return -EINVAL;
- }
- ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq);
- cfg80211_rx_mgmt(vif->ndev, freq, ev->data, dlen, GFP_ATOMIC);
-
- return 0;
-}
-
-static int ath6kl_wmi_p2p_info_event_rx(u8 *datap, int len)
-{
- struct wmi_p2p_info_event *ev;
- u32 flags;
- u16 dlen;
-
- if (len < sizeof(*ev))
- return -EINVAL;
-
- ev = (struct wmi_p2p_info_event *) datap;
- flags = le32_to_cpu(ev->info_req_flags);
- dlen = le16_to_cpu(ev->len);
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: flags=%x len=%d\n", flags, dlen);
-
- if (flags & P2P_FLAG_CAPABILITIES_REQ) {
- struct wmi_p2p_capabilities *cap;
- if (dlen < sizeof(*cap))
- return -EINVAL;
- cap = (struct wmi_p2p_capabilities *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: GO Power Save = %d\n",
- cap->go_power_save);
- }
-
- if (flags & P2P_FLAG_MACADDR_REQ) {
- struct wmi_p2p_macaddr *mac;
- if (dlen < sizeof(*mac))
- return -EINVAL;
- mac = (struct wmi_p2p_macaddr *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: MAC Address = %s\n",
- sec_conv_mac(mac->mac_addr));
- }
-
- if (flags & P2P_FLAG_HMODEL_REQ) {
- struct wmi_p2p_hmodel *mod;
- if (dlen < sizeof(*mod))
- return -EINVAL;
- mod = (struct wmi_p2p_hmodel *) ev->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "p2p_info: P2P Model = %d (%s)\n",
- mod->p2p_model,
- mod->p2p_model ? "host" : "firmware");
- }
- return 0;
-}
-
-static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
-{
- struct sk_buff *skb;
-
- skb = ath6kl_buf_alloc(size);
- if (!skb)
- return NULL;
-
- skb_put(skb, size);
- if (size)
- memset(skb->data, 0, size);
-
- return skb;
-}
-
-/* Send a "simple" wmi command -- one with no arguments */
-static int ath6kl_wmi_simple_cmd(struct wmi *wmi, u8 if_idx,
- enum wmi_cmd_id cmd_id)
-{
- struct sk_buff *skb;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(0);
- if (!skb)
- return -ENOMEM;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, cmd_id, NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
- struct wmi_ready_event_2 *ev = (struct wmi_ready_event_2 *) datap;
-
- if (len < sizeof(struct wmi_ready_event_2))
- return -EINVAL;
-
- ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
- le32_to_cpu(ev->sw_version),
- le32_to_cpu(ev->abi_version));
-
- return 0;
-}
-
-/*
- * Mechanism to modify the roaming behavior in the firmware. The lower rssi
- * at which the station has to roam can be passed with
- * WMI_SET_LRSSI_SCAN_PARAMS. Subtract 96 from RSSI to get the signal level
- * in dBm.
- */
-int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi)
-{
- struct sk_buff *skb;
- struct roam_ctrl_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct roam_ctrl_cmd *) skb->data;
-
-#ifdef CONFIG_MACH_PX
- if (wmi->parent_dev->psminfo == 0)
- cmd->info.params.lrssi_scan_period = 0xFFFF;
- else
- cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
-#else
- cmd->info.params.lrssi_scan_period = cpu_to_le16(DEF_LRSSI_SCAN_PERIOD);
-#endif
-
- cmd->info.params.lrssi_scan_threshold = a_cpu_to_sle16(lrssi +
- DEF_SCAN_FOR_ROAM_INTVL);
- cmd->info.params.lrssi_roam_threshold = a_cpu_to_sle16(lrssi);
- cmd->info.params.roam_rssi_floor = DEF_LRSSI_ROAM_FLOOR;
- cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
- "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
- cmd->info.params.lrssi_scan_period, cmd->info.params.lrssi_scan_threshold,
- cmd->info.params.lrssi_roam_threshold, cmd->info.params.roam_rssi_floor);
-
- ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
- NO_SYNC_WMIFLAG);
-
- return 0;
-}
-
-int ath6kl_wmi_set_roam_lrssi_config_cmd(struct wmi *wmi,
- struct low_rssi_scan_params *params)
-{
- struct sk_buff *skb;
- struct roam_ctrl_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct roam_ctrl_cmd *) skb->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "lrssi_scan_period %d, lrssi_scan_threshold = %d, "
- "lrssi_roam_threshold = %d, roam_rssi_floor = %d\n",
- params->lrssi_scan_period, params->lrssi_scan_threshold,
- params->lrssi_roam_threshold, params->roam_rssi_floor);
-
- if (params->lrssi_scan_period == 0)
- cmd->info.params.lrssi_scan_period = 0xFFFF;
- else
- cmd->info.params.lrssi_scan_period = params->lrssi_scan_period;
- cmd->info.params.lrssi_scan_threshold = params->lrssi_scan_threshold;
- cmd->info.params.lrssi_roam_threshold = params->lrssi_roam_threshold;
- cmd->info.params.roam_rssi_floor = params->roam_rssi_floor;
- cmd->roam_ctrl = WMI_SET_LRSSI_SCAN_PARAMS;
-
- ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
- NO_SYNC_WMIFLAG);
-
- return 0;
-}
-
-int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid)
-{
- struct sk_buff *skb;
- struct roam_ctrl_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct roam_ctrl_cmd *) skb->data;
- memset(cmd, 0, sizeof(*cmd));
-
- memcpy(cmd->info.bssid, bssid, ETH_ALEN);
- cmd->roam_ctrl = WMI_FORCE_ROAM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "force roam to %s\n", sec_conv_mac(bssid));
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode)
-{
- struct sk_buff *skb;
- struct roam_ctrl_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct roam_ctrl_cmd *) skb->data;
- memset(cmd, 0, sizeof(*cmd));
-
- cmd->info.roam_mode = mode;
- cmd->roam_ctrl = WMI_SET_ROAM_MODE;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "set roam mode %d\n", mode);
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_ROAM_CTRL_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_connect_event *ev;
- u8 *pie, *peie;
-
- if (len < sizeof(struct wmi_connect_event))
- return -EINVAL;
-
- ev = (struct wmi_connect_event *) datap;
-
- if (vif->nw_type == AP_NETWORK) {
- /* AP mode start/STA connected event */
- struct net_device *dev = vif->ndev;
- if (memcmp(dev->dev_addr, ev->u.ap_bss.bssid, ETH_ALEN) == 0) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %s "
- "(AP started)\n",
- __func__, le16_to_cpu(ev->u.ap_bss.ch),
- sec_conv_mac(ev->u.ap_bss.bssid));
- ath6kl_connect_ap_mode_bss(
- vif, le16_to_cpu(ev->u.ap_bss.ch));
- } else {
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s: aid %u mac_addr %s "
- "auth=%u keymgmt=%u cipher=%u apsd_info=%u "
- "(STA connected)\n",
- __func__, ev->u.ap_sta.aid,
- sec_conv_mac(ev->u.ap_sta.mac_addr),
- ev->u.ap_sta.auth,
- ev->u.ap_sta.keymgmt,
- le16_to_cpu(ev->u.ap_sta.cipher),
- ev->u.ap_sta.apsd_info);
-
- ath6kl_connect_ap_mode_sta(
- vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
- ev->u.ap_sta.keymgmt,
- le16_to_cpu(ev->u.ap_sta.cipher),
- ev->u.ap_sta.auth, ev->assoc_req_len,
- ev->assoc_info + ev->beacon_ie_len,
- ev->u.ap_sta.apsd_info);
- }
- return 0;
- }
-
- /* STA/IBSS mode connection event */
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi event connect freq %d bssid %s listen_intvl %d beacon_intvl %d type %d\n",
- le16_to_cpu(ev->u.sta.ch), sec_conv_mac(ev->u.sta.bssid),
- le16_to_cpu(ev->u.sta.listen_intvl),
- le16_to_cpu(ev->u.sta.beacon_intvl),
- le32_to_cpu(ev->u.sta.nw_type));
-
- /* Start of assoc rsp IEs */
- pie = ev->assoc_info + ev->beacon_ie_len +
- ev->assoc_req_len + (sizeof(u16) * 3); /* capinfo, status, aid */
-
- /* End of assoc rsp IEs */
- peie = ev->assoc_info + ev->beacon_ie_len + ev->assoc_req_len +
- ev->assoc_resp_len;
-
- while (pie < peie) {
- switch (*pie) {
- case WLAN_EID_VENDOR_SPECIFIC:
- if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
- pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
- /* WMM OUT (00:50:F2) */
- if (pie[1] > 5
- && pie[6] == WMM_PARAM_OUI_SUBTYPE)
- wmi->is_wmm_enabled = true;
- }
- break;
- }
-
- if (wmi->is_wmm_enabled)
- break;
-
- pie += pie[1] + 2;
- }
-
- ath6kl_connect_event(vif, le16_to_cpu(ev->u.sta.ch),
- ev->u.sta.bssid,
- le16_to_cpu(ev->u.sta.listen_intvl),
- le16_to_cpu(ev->u.sta.beacon_intvl),
- le32_to_cpu(ev->u.sta.nw_type),
- ev->beacon_ie_len, ev->assoc_req_len,
- ev->assoc_resp_len, ev->assoc_info);
-
- return 0;
-}
-
-static struct country_code_to_enum_rd *
-ath6kl_regd_find_country(u16 countryCode)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].countryCode == countryCode)
- return &allCountries[i];
- }
-
- return NULL;
-}
-
-static struct reg_dmn_pair_mapping *
-ath6kl_get_regpair(u16 regdmn)
-{
- int i;
-
- if (regdmn == NO_ENUMRD)
- return NULL;
-
- for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
- if (regDomainPairs[i].regDmnEnum == regdmn)
- return &regDomainPairs[i];
- }
-
- return NULL;
-}
-
-static struct country_code_to_enum_rd *
-ath6kl_regd_find_country_by_rd(u16 regdmn)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
- if (allCountries[i].regDmnEnum == regdmn)
- return &allCountries[i];
- }
-
- return NULL;
-}
-
-static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len)
-{
-
- struct ath6kl_wmi_regdomain *ev;
- struct country_code_to_enum_rd *country = NULL;
- struct reg_dmn_pair_mapping *regpair = NULL;
- char alpha2[2];
- u32 reg_code;
-
- ev = (struct ath6kl_wmi_regdomain *) datap;
- reg_code = le32_to_cpu(ev->reg_code);
-
- if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG)
- country = ath6kl_regd_find_country((u16) reg_code);
- else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) {
-
- regpair = ath6kl_get_regpair((u16) reg_code);
- country = ath6kl_regd_find_country_by_rd((u16) reg_code);
- ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n",
- regpair->regDmnEnum);
- }
-
- if (country) {
- alpha2[0] = country->isoName[0];
- alpha2[1] = country->isoName[1];
-
- regulatory_hint(wmi->parent_dev->wiphy, alpha2);
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "Country alpha2 being used: %c%c\n",
- alpha2[0], alpha2[1]);
- }
-}
-
-static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_disconnect_event *ev;
- wmi->traffic_class = 100;
-
- if (len < sizeof(struct wmi_disconnect_event))
- return -EINVAL;
-
- ev = (struct wmi_disconnect_event *) datap;
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi event disconnect proto_reason %d bssid %s wmi_reason %d assoc_resp_len %d\n",
- le16_to_cpu(ev->proto_reason_status),
- sec_conv_mac(ev->bssid),
- ev->disconn_reason, ev->assoc_resp_len);
-
- wmi->is_wmm_enabled = false;
-
- ath6kl_disconnect_event(vif, ev->disconn_reason,
- ev->bssid, ev->assoc_resp_len, ev->assoc_info,
- le16_to_cpu(ev->proto_reason_status));
-
- return 0;
-}
-
-static int ath6kl_wmi_peer_node_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
- struct wmi_peer_node_event *ev;
-
- if (len < sizeof(struct wmi_peer_node_event))
- return -EINVAL;
-
- ev = (struct wmi_peer_node_event *) datap;
-
- if (ev->event_code == PEER_NODE_JOIN_EVENT)
- ath6kl_dbg(ATH6KL_DBG_WMI, "joined node with mac addr: %s\n",
- sec_conv_mac(ev->peer_mac_addr));
- else if (ev->event_code == PEER_NODE_LEAVE_EVENT)
- ath6kl_dbg(ATH6KL_DBG_WMI, "left node with mac addr: %s\n",
- sec_conv_mac(ev->peer_mac_addr));
-
- return 0;
-}
-
-static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_tkip_micerr_event *ev;
-
- if (len < sizeof(struct wmi_tkip_micerr_event))
- return -EINVAL;
-
- ev = (struct wmi_tkip_micerr_event *) datap;
-
- ath6kl_tkip_micerr_event(vif, ev->key_id, ev->is_mcast);
-
- return 0;
-}
-
-void ath6kl_wmi_sscan_timer(unsigned long ptr)
-{
- struct ath6kl_vif *vif = (struct ath6kl_vif *) ptr;
-
- cfg80211_sched_scan_results(vif->ar->wiphy);
-}
-
-static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_bss_info_hdr2 *bih;
- u8 *buf;
- struct ieee80211_channel *channel;
- struct ath6kl *ar = wmi->parent_dev;
- struct ieee80211_mgmt *mgmt;
- struct cfg80211_bss *bss;
-
- if (len <= sizeof(struct wmi_bss_info_hdr2))
- return -EINVAL;
-
- bih = (struct wmi_bss_info_hdr2 *) datap;
- buf = datap + sizeof(struct wmi_bss_info_hdr2);
- len -= sizeof(struct wmi_bss_info_hdr2);
-
-#if 0
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
- "frame_type=%d\n",
- bih->ch, bih->snr, bih->snr - 95, bih->bssid,
- bih->frame_type);
-#endif
-
- if (bih->frame_type != BEACON_FTYPE &&
- bih->frame_type != PROBERESP_FTYPE)
- return 0; /* Only update BSS table for now */
-
- if (bih->frame_type == BEACON_FTYPE &&
- test_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags)) {
- clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
- ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
- NONE_BSS_FILTER, 0);
- }
-
- channel = ieee80211_get_channel(ar->wiphy, le16_to_cpu(bih->ch));
- if (channel == NULL)
- return -EINVAL;
-
- if (len < 8 + 2 + 2)
- return -EINVAL;
-
- if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &vif->flags)
- && memcmp(bih->bssid, vif->bssid, ETH_ALEN) == 0) {
- const u8 *tim;
- tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
- len - 8 - 2 - 2);
- if (tim && tim[1] >= 2) {
- vif->assoc_bss_dtim_period = tim[3];
- set_bit(DTIM_PERIOD_AVAIL, &vif->flags);
- }
- }
-
- /*
- * In theory, use of cfg80211_inform_bss() would be more natural here
- * since we do not have the full frame. However, at least for now,
- * cfg80211 can only distinguish Beacon and Probe Response frames from
- * each other when using cfg80211_inform_bss_frame(), so let's build a
- * fake IEEE 802.11 header to be able to take benefit of this.
- */
- mgmt = kmalloc(24 + len, GFP_ATOMIC);
- if (mgmt == NULL)
- return -EINVAL;
-
- if (bih->frame_type == BEACON_FTYPE) {
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_BEACON);
- memset(mgmt->da, 0xff, ETH_ALEN);
- } else {
- struct net_device *dev = vif->ndev;
-
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_PROBE_RESP);
- memcpy(mgmt->da, dev->dev_addr, ETH_ALEN);
- }
- mgmt->duration = cpu_to_le16(0);
- memcpy(mgmt->sa, bih->bssid, ETH_ALEN);
- memcpy(mgmt->bssid, bih->bssid, ETH_ALEN);
- mgmt->seq_ctrl = cpu_to_le16(0);
-
- memcpy(&mgmt->u.beacon, buf, len);
-
- bss = cfg80211_inform_bss_frame(ar->wiphy, channel, mgmt,
- 24 + len, (bih->snr - 95) * 100,
- GFP_ATOMIC);
- kfree(mgmt);
- if (bss == NULL)
- return -ENOMEM;
- cfg80211_put_bss(bss);
-
- /*
- * Firmware doesn't return any event when scheduled scan has
- * finished, so we need to use a timer to find out when there are
- * no more results.
- *
- * The timer is started from the first bss info received, otherwise
- * the timer would not ever fire if the scan interval is short
- * enough.
- */
- if (ar->state == ATH6KL_STATE_SCHED_SCAN &&
- !timer_pending(&vif->sched_scan_timer)) {
- mod_timer(&vif->sched_scan_timer, jiffies +
- msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY));
- }
-
- return 0;
-}
-
-/* Inactivity timeout of a fatpipe(pstream) at the target */
-static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
- int len)
-{
- struct wmi_pstream_timeout_event *ev;
-
- if (len < sizeof(struct wmi_pstream_timeout_event))
- return -EINVAL;
-
- ev = (struct wmi_pstream_timeout_event *) datap;
-
- /*
- * When the pstream (fat pipe == AC) timesout, it means there were
- * no thinStreams within this pstream & it got implicitly created
- * due to data flow on this AC. We start the inactivity timer only
- * for implicitly created pstream. Just reset the host state.
- */
- spin_lock_bh(&wmi->lock);
- wmi->stream_exist_for_ac[ev->traffic_class] = 0;
- wmi->fat_pipe_exist &= ~(1 << ev->traffic_class);
- spin_unlock_bh(&wmi->lock);
-
- /* Indicate inactivity to driver layer for this fatpipe (pstream) */
- ath6kl_indicate_tx_activity(wmi->parent_dev, ev->traffic_class, false);
-
- return 0;
-}
-
-static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
-{
- struct wmi_bit_rate_reply *reply;
- s32 rate;
- u32 sgi, index;
-
- if (len < sizeof(struct wmi_bit_rate_reply))
- return -EINVAL;
-
- reply = (struct wmi_bit_rate_reply *) datap;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index);
-
- if (reply->rate_index == (s8) RATE_AUTO) {
- rate = RATE_AUTO;
- } else {
- index = reply->rate_index & 0x7f;
- sgi = (reply->rate_index & 0x80) ? 1 : 0;
- rate = wmi_rate_tbl[index][sgi];
- }
-
- ath6kl_wakeup_event(wmi->parent_dev);
-
- return 0;
-}
-
-static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len)
-{
- ath6kl_tm_rx_event(wmi->parent_dev, datap, len);
-
- return 0;
-}
-
-static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
-{
- if (len < sizeof(struct wmi_fix_rates_reply))
- return -EINVAL;
-
- ath6kl_wakeup_event(wmi->parent_dev);
-
- return 0;
-}
-
-static int ath6kl_wmi_ch_list_reply_rx(struct wmi *wmi, u8 *datap, int len)
-{
- if (len < sizeof(struct wmi_channel_list_reply))
- return -EINVAL;
-
- ath6kl_wakeup_event(wmi->parent_dev);
-
- return 0;
-}
-
-static int ath6kl_wmi_tx_pwr_reply_rx(struct wmi *wmi, u8 *datap, int len)
-{
- struct wmi_tx_pwr_reply *reply;
-
- if (len < sizeof(struct wmi_tx_pwr_reply))
- return -EINVAL;
-
- reply = (struct wmi_tx_pwr_reply *) datap;
- ath6kl_txpwr_rx_evt(wmi->parent_dev, reply->dbM);
-
- return 0;
-}
-
-static int ath6kl_wmi_keepalive_reply_rx(struct wmi *wmi, u8 *datap, int len)
-{
- if (len < sizeof(struct wmi_get_keepalive_cmd))
- return -EINVAL;
-
- ath6kl_wakeup_event(wmi->parent_dev);
-
- return 0;
-}
-
-static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_scan_complete_event *ev;
-
- ev = (struct wmi_scan_complete_event *) datap;
-
- ath6kl_scan_complete_evt(vif, a_sle32_to_cpu(ev->status));
- wmi->is_probe_ssid = false;
-
- return 0;
-}
-
-static int ath6kl_wmi_neighbor_report_event_rx(struct wmi *wmi, u8 *datap,
- int len, struct ath6kl_vif *vif)
-{
- struct wmi_neighbor_report_event *ev;
- u8 i;
-
- if (len < sizeof(*ev))
- return -EINVAL;
- ev = (struct wmi_neighbor_report_event *) datap;
- if (sizeof(*ev) + ev->num_neighbors * sizeof(struct wmi_neighbor_info)
- > len) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "truncated neighbor event "
- "(num=%d len=%d)\n", ev->num_neighbors, len);
- return -EINVAL;
- }
- for (i = 0; i < ev->num_neighbors; i++) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "neighbor %d/%d - %s 0x%x\n",
- i + 1, ev->num_neighbors,
- sec_conv_mac(ev->neighbor[i].bssid),
- ev->neighbor[i].bss_flags);
- cfg80211_pmksa_candidate_notify(vif->ndev, i,
- ev->neighbor[i].bssid,
- !!(ev->neighbor[i].bss_flags &
- WMI_PREAUTH_CAPABLE_BSS),
- GFP_ATOMIC);
- }
-
- return 0;
-}
-
-/*
- * Target is reporting a programming error. This is for
- * developer aid only. Target only checks a few common violations
- * and it is responsibility of host to do all error checking.
- * Behavior of target after wmi error event is undefined.
- * A reset is recommended.
- */
-static int ath6kl_wmi_error_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
- const char *type = "unknown error";
- struct wmi_cmd_error_event *ev;
- ev = (struct wmi_cmd_error_event *) datap;
-
- switch (ev->err_code) {
- case INVALID_PARAM:
- type = "invalid parameter";
- break;
- case ILLEGAL_STATE:
- type = "invalid state";
- break;
- case INTERNAL_ERROR:
- type = "internal error";
- break;
- }
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "programming error, cmd=%d %s\n",
- ev->cmd_id, type);
-
- return 0;
-}
-
-static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- ath6kl_tgt_stats_event(vif, datap, len);
-
- return 0;
-}
-
-static u8 ath6kl_wmi_get_upper_threshold(s16 rssi,
- struct sq_threshold_params *sq_thresh,
- u32 size)
-{
- u32 index;
- u8 threshold = (u8) sq_thresh->upper_threshold[size - 1];
-
- /* The list is already in sorted order. Get the next lower value */
- for (index = 0; index < size; index++) {
- if (rssi < sq_thresh->upper_threshold[index]) {
- threshold = (u8) sq_thresh->upper_threshold[index];
- break;
- }
- }
-
- return threshold;
-}
-
-static u8 ath6kl_wmi_get_lower_threshold(s16 rssi,
- struct sq_threshold_params *sq_thresh,
- u32 size)
-{
- u32 index;
- u8 threshold = (u8) sq_thresh->lower_threshold[size - 1];
-
- /* The list is already in sorted order. Get the next lower value */
- for (index = 0; index < size; index++) {
- if (rssi > sq_thresh->lower_threshold[index]) {
- threshold = (u8) sq_thresh->lower_threshold[index];
- break;
- }
- }
-
- return threshold;
-}
-
-static int ath6kl_wmi_send_rssi_threshold_params(struct wmi *wmi,
- struct wmi_rssi_threshold_params_cmd *rssi_cmd)
-{
- struct sk_buff *skb;
- struct wmi_rssi_threshold_params_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_rssi_threshold_params_cmd *) skb->data;
- memcpy(cmd, rssi_cmd, sizeof(struct wmi_rssi_threshold_params_cmd));
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
- int len)
-{
- struct wmi_rssi_threshold_event *reply;
- struct wmi_rssi_threshold_params_cmd cmd;
- struct sq_threshold_params *sq_thresh;
- enum wmi_rssi_threshold_val new_threshold;
- u8 upper_rssi_threshold, lower_rssi_threshold;
- s16 rssi;
- int ret;
-
- if (len < sizeof(struct wmi_rssi_threshold_event))
- return -EINVAL;
-
- reply = (struct wmi_rssi_threshold_event *) datap;
- new_threshold = (enum wmi_rssi_threshold_val) reply->range;
- rssi = a_sle16_to_cpu(reply->rssi);
-
- sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_RSSI];
-
- /*
- * Identify the threshold breached and communicate that to the app.
- * After that install a new set of thresholds based on the signal
- * quality reported by the target
- */
- if (new_threshold) {
- /* Upper threshold breached */
- if (rssi < sq_thresh->upper_threshold[0]) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "spurious upper rssi threshold event: %d\n",
- rssi);
- } else if ((rssi < sq_thresh->upper_threshold[1]) &&
- (rssi >= sq_thresh->upper_threshold[0])) {
- new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
- } else if ((rssi < sq_thresh->upper_threshold[2]) &&
- (rssi >= sq_thresh->upper_threshold[1])) {
- new_threshold = WMI_RSSI_THRESHOLD2_ABOVE;
- } else if ((rssi < sq_thresh->upper_threshold[3]) &&
- (rssi >= sq_thresh->upper_threshold[2])) {
- new_threshold = WMI_RSSI_THRESHOLD3_ABOVE;
- } else if ((rssi < sq_thresh->upper_threshold[4]) &&
- (rssi >= sq_thresh->upper_threshold[3])) {
- new_threshold = WMI_RSSI_THRESHOLD4_ABOVE;
- } else if ((rssi < sq_thresh->upper_threshold[5]) &&
- (rssi >= sq_thresh->upper_threshold[4])) {
- new_threshold = WMI_RSSI_THRESHOLD5_ABOVE;
- } else if (rssi >= sq_thresh->upper_threshold[5]) {
- new_threshold = WMI_RSSI_THRESHOLD6_ABOVE;
- }
- } else {
- /* Lower threshold breached */
- if (rssi > sq_thresh->lower_threshold[0]) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "spurious lower rssi threshold event: %d %d\n",
- rssi, sq_thresh->lower_threshold[0]);
- } else if ((rssi > sq_thresh->lower_threshold[1]) &&
- (rssi <= sq_thresh->lower_threshold[0])) {
- new_threshold = WMI_RSSI_THRESHOLD6_BELOW;
- } else if ((rssi > sq_thresh->lower_threshold[2]) &&
- (rssi <= sq_thresh->lower_threshold[1])) {
- new_threshold = WMI_RSSI_THRESHOLD5_BELOW;
- } else if ((rssi > sq_thresh->lower_threshold[3]) &&
- (rssi <= sq_thresh->lower_threshold[2])) {
- new_threshold = WMI_RSSI_THRESHOLD4_BELOW;
- } else if ((rssi > sq_thresh->lower_threshold[4]) &&
- (rssi <= sq_thresh->lower_threshold[3])) {
- new_threshold = WMI_RSSI_THRESHOLD3_BELOW;
- } else if ((rssi > sq_thresh->lower_threshold[5]) &&
- (rssi <= sq_thresh->lower_threshold[4])) {
- new_threshold = WMI_RSSI_THRESHOLD2_BELOW;
- } else if (rssi <= sq_thresh->lower_threshold[5]) {
- new_threshold = WMI_RSSI_THRESHOLD1_BELOW;
- }
- }
-
- /* Calculate and install the next set of thresholds */
- lower_rssi_threshold = ath6kl_wmi_get_lower_threshold(rssi, sq_thresh,
- sq_thresh->lower_threshold_valid_count);
- upper_rssi_threshold = ath6kl_wmi_get_upper_threshold(rssi, sq_thresh,
- sq_thresh->upper_threshold_valid_count);
-
- /* Issue a wmi command to install the thresholds */
- cmd.thresh_above1_val = a_cpu_to_sle16(upper_rssi_threshold);
- cmd.thresh_below1_val = a_cpu_to_sle16(lower_rssi_threshold);
- cmd.weight = sq_thresh->weight;
- cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
-
- ret = ath6kl_wmi_send_rssi_threshold_params(wmi, &cmd);
- if (ret) {
- ath6kl_err("unable to configure rssi thresholds\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_cac_event *reply;
- struct ieee80211_tspec_ie *ts;
- u16 active_tsids, tsinfo;
- u8 tsid, index;
- u8 ts_id;
-
- if (len < sizeof(struct wmi_cac_event))
- return -EINVAL;
-
- reply = (struct wmi_cac_event *) datap;
-
- if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
- (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
-
- ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
- tsinfo = le16_to_cpu(ts->tsinfo);
- tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
- IEEE80211_WMM_IE_TSPEC_TID_MASK;
-
- ath6kl_wmi_delete_pstream_cmd(wmi, vif->fw_vif_idx,
- reply->ac, tsid);
- } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
- /*
- * Following assumes that there is only one outstanding
- * ADDTS request when this event is received
- */
- spin_lock_bh(&wmi->lock);
- active_tsids = wmi->stream_exist_for_ac[reply->ac];
- spin_unlock_bh(&wmi->lock);
-
- for (index = 0; index < sizeof(active_tsids) * 8; index++) {
- if ((active_tsids >> index) & 1)
- break;
- }
- if (index < (sizeof(active_tsids) * 8))
- ath6kl_wmi_delete_pstream_cmd(wmi, vif->fw_vif_idx,
- reply->ac, index);
- }
-
- /*
- * Clear active tsids and Add missing handling
- * for delete qos stream from AP
- */
- else if (reply->cac_indication == CAC_INDICATION_DELETE) {
-
- ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
- tsinfo = le16_to_cpu(ts->tsinfo);
- ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
- IEEE80211_WMM_IE_TSPEC_TID_MASK);
-
- spin_lock_bh(&wmi->lock);
- wmi->stream_exist_for_ac[reply->ac] &= ~(1 << ts_id);
- active_tsids = wmi->stream_exist_for_ac[reply->ac];
- spin_unlock_bh(&wmi->lock);
-
- /* Indicate stream inactivity to driver layer only if all tsids
- * within this AC are deleted.
- */
- if (!active_tsids) {
- ath6kl_indicate_tx_activity(wmi->parent_dev, reply->ac,
- false);
- wmi->fat_pipe_exist &= ~(1 << reply->ac);
- }
- }
-
- return 0;
-}
-
-static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
- struct wmi_snr_threshold_params_cmd *snr_cmd)
-{
- struct sk_buff *skb;
- struct wmi_snr_threshold_params_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_snr_threshold_params_cmd *) skb->data;
- memcpy(cmd, snr_cmd, sizeof(struct wmi_snr_threshold_params_cmd));
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
- int len)
-{
- struct wmi_snr_threshold_event *reply;
- struct sq_threshold_params *sq_thresh;
- struct wmi_snr_threshold_params_cmd cmd;
- enum wmi_snr_threshold_val new_threshold;
- u8 upper_snr_threshold, lower_snr_threshold;
- s16 snr;
- int ret;
-
- if (len < sizeof(struct wmi_snr_threshold_event))
- return -EINVAL;
-
- reply = (struct wmi_snr_threshold_event *) datap;
-
- new_threshold = (enum wmi_snr_threshold_val) reply->range;
- snr = reply->snr;
-
- sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_SNR];
-
- /*
- * Identify the threshold breached and communicate that to the app.
- * After that install a new set of thresholds based on the signal
- * quality reported by the target.
- */
- if (new_threshold) {
- /* Upper threshold breached */
- if (snr < sq_thresh->upper_threshold[0]) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "spurious upper snr threshold event: %d\n",
- snr);
- } else if ((snr < sq_thresh->upper_threshold[1]) &&
- (snr >= sq_thresh->upper_threshold[0])) {
- new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
- } else if ((snr < sq_thresh->upper_threshold[2]) &&
- (snr >= sq_thresh->upper_threshold[1])) {
- new_threshold = WMI_SNR_THRESHOLD2_ABOVE;
- } else if ((snr < sq_thresh->upper_threshold[3]) &&
- (snr >= sq_thresh->upper_threshold[2])) {
- new_threshold = WMI_SNR_THRESHOLD3_ABOVE;
- } else if (snr >= sq_thresh->upper_threshold[3]) {
- new_threshold = WMI_SNR_THRESHOLD4_ABOVE;
- }
- } else {
- /* Lower threshold breached */
- if (snr > sq_thresh->lower_threshold[0]) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "spurious lower snr threshold event: %d\n",
- sq_thresh->lower_threshold[0]);
- } else if ((snr > sq_thresh->lower_threshold[1]) &&
- (snr <= sq_thresh->lower_threshold[0])) {
- new_threshold = WMI_SNR_THRESHOLD4_BELOW;
- } else if ((snr > sq_thresh->lower_threshold[2]) &&
- (snr <= sq_thresh->lower_threshold[1])) {
- new_threshold = WMI_SNR_THRESHOLD3_BELOW;
- } else if ((snr > sq_thresh->lower_threshold[3]) &&
- (snr <= sq_thresh->lower_threshold[2])) {
- new_threshold = WMI_SNR_THRESHOLD2_BELOW;
- } else if (snr <= sq_thresh->lower_threshold[3]) {
- new_threshold = WMI_SNR_THRESHOLD1_BELOW;
- }
- }
-
- /* Calculate and install the next set of thresholds */
- lower_snr_threshold = ath6kl_wmi_get_lower_threshold(snr, sq_thresh,
- sq_thresh->lower_threshold_valid_count);
- upper_snr_threshold = ath6kl_wmi_get_upper_threshold(snr, sq_thresh,
- sq_thresh->upper_threshold_valid_count);
-
- /* Issue a wmi command to install the thresholds */
- cmd.thresh_above1_val = upper_snr_threshold;
- cmd.thresh_below1_val = lower_snr_threshold;
- cmd.weight = sq_thresh->weight;
- cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "snr: %d, threshold: %d, lower: %d, upper: %d\n",
- snr, new_threshold,
- lower_snr_threshold, upper_snr_threshold);
-
- ret = ath6kl_wmi_send_snr_threshold_params(wmi, &cmd);
- if (ret) {
- ath6kl_err("unable to configure snr threshold\n");
- return -EIO;
- }
-
- return 0;
-}
-
-static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
- u16 ap_info_entry_size;
- struct wmi_aplist_event *ev = (struct wmi_aplist_event *) datap;
- struct wmi_ap_info_v1 *ap_info_v1;
- u8 index;
-
- if (len < sizeof(struct wmi_aplist_event) ||
- ev->ap_list_ver != APLIST_VER1)
- return -EINVAL;
-
- ap_info_entry_size = sizeof(struct wmi_ap_info_v1);
- ap_info_v1 = (struct wmi_ap_info_v1 *) ev->ap_list;
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "number of APs in aplist event: %d\n", ev->num_ap);
-
- if (len < (int) (sizeof(struct wmi_aplist_event) +
- (ev->num_ap - 1) * ap_info_entry_size))
- return -EINVAL;
-
- /* AP list version 1 contents */
- for (index = 0; index < ev->num_ap; index++) {
- ath6kl_dbg(ATH6KL_DBG_WMI, "AP#%d BSSID %s Channel %d\n",
- index, sec_conv_mac(ap_info_v1->bssid),
- ap_info_v1->channel);
- ap_info_v1++;
- }
-
- return 0;
-}
-
-int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
- enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag)
-{
- struct wmi_cmd_hdr *cmd_hdr;
- enum htc_endpoint_id ep_id = wmi->ep_id;
- int ret;
- u16 info1;
-
- if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1))))
- return -EINVAL;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n",
- cmd_id, skb->len, sync_flag);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi tx ",
- skb->data, skb->len);
-
- if (sync_flag >= END_WMIFLAG) {
- dev_kfree_skb(skb);
- return -EINVAL;
- }
-
- if ((sync_flag == SYNC_BEFORE_WMIFLAG) ||
- (sync_flag == SYNC_BOTH_WMIFLAG)) {
- /*
- * Make sure all data currently queued is transmitted before
- * the cmd execution. Establish a new sync point.
- */
- ath6kl_wmi_sync_point(wmi, if_idx);
- }
-
- skb_push(skb, sizeof(struct wmi_cmd_hdr));
-
- cmd_hdr = (struct wmi_cmd_hdr *) skb->data;
- cmd_hdr->cmd_id = cpu_to_le16(cmd_id);
- info1 = if_idx & WMI_CMD_HDR_IF_ID_MASK;
- cmd_hdr->info1 = cpu_to_le16(info1);
-
- /* Only for OPT_TX_CMD, use BE endpoint. */
- if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
- ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE,
- false, false, 0, NULL, if_idx);
- if (ret) {
- dev_kfree_skb(skb);
- return ret;
- }
- ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, WMM_AC_BE);
- }
-
- ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
-
- if ((sync_flag == SYNC_AFTER_WMIFLAG) ||
- (sync_flag == SYNC_BOTH_WMIFLAG)) {
- /*
- * Make sure all new data queued waits for the command to
- * execute. Establish a new sync point.
- */
- ath6kl_wmi_sync_point(wmi, if_idx);
- }
-
- return 0;
-}
-
-int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
- enum network_type nw_type,
- enum dot11_auth_mode dot11_auth_mode,
- enum auth_mode auth_mode,
- enum crypto_type pairwise_crypto,
- u8 pairwise_crypto_len,
- enum crypto_type group_crypto,
- u8 group_crypto_len, int ssid_len, u8 *ssid,
- u8 *bssid, u16 channel, u32 ctrl_flags,
- u8 nw_subtype)
-{
- struct sk_buff *skb;
- struct wmi_connect_cmd *cc;
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "wmi connect bssid %s freq %d flags 0x%x ssid_len %d "
- "type %d dot11_auth %d auth %d pairwise %d group %d\n",
- sec_conv_mac(bssid), channel, ctrl_flags, ssid_len, nw_type,
- dot11_auth_mode, auth_mode, pairwise_crypto, group_crypto);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI, NULL, "ssid ", ssid, ssid_len);
-
- wmi->traffic_class = 100;
-
- if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
- return -EINVAL;
-
- if ((pairwise_crypto != NONE_CRYPT) && (group_crypto == NONE_CRYPT))
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_connect_cmd));
- if (!skb)
- return -ENOMEM;
-
- cc = (struct wmi_connect_cmd *) skb->data;
-
- if (ssid_len)
- memcpy(cc->ssid, ssid, ssid_len);
-
- cc->ssid_len = ssid_len;
- cc->nw_type = nw_type;
- cc->dot11_auth_mode = dot11_auth_mode;
- cc->auth_mode = auth_mode;
- cc->prwise_crypto_type = pairwise_crypto;
- cc->prwise_crypto_len = pairwise_crypto_len;
- cc->grp_crypto_type = group_crypto;
- cc->grp_crypto_len = group_crypto_len;
- cc->ch = cpu_to_le16(channel);
- cc->ctrl_flags = cpu_to_le32(ctrl_flags);
- cc->nw_subtype = nw_subtype;
-
- if (bssid != NULL)
- memcpy(cc->bssid, bssid, ETH_ALEN);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CONNECT_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
- u16 channel)
-{
- struct sk_buff *skb;
- struct wmi_reconnect_cmd *cc;
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi reconnect bssid %s freq %d\n",
- sec_conv_mac(bssid), channel);
-
- wmi->traffic_class = 100;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
- if (!skb)
- return -ENOMEM;
-
- cc = (struct wmi_reconnect_cmd *) skb->data;
- cc->channel = cpu_to_le16(channel);
-
- if (bssid != NULL)
- memcpy(cc->bssid, bssid, ETH_ALEN);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RECONNECT_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx)
-{
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi disconnect\n");
-
- wmi->traffic_class = 100;
-
- /* Disconnect command does not need to do a SYNC before. */
- ret = ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_DISCONNECT_CMDID);
-
- return ret;
-}
-
-int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
- enum wmi_scan_type scan_type,
- u32 force_fgscan, u32 is_legacy,
- u32 home_dwell_time, u32 force_scan_interval,
- s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates)
-{
- struct sk_buff *skb;
- struct wmi_begin_scan_cmd *sc;
-#ifdef CONFIG_MACH_PX
- unsigned int size;
-#else
- s8 size;
-#endif
- int i, band, ret;
- struct ath6kl *ar = wmi->parent_dev;
- int num_rates;
-
- size = sizeof(struct wmi_begin_scan_cmd);
-
- if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
- return -EINVAL;
-
-#ifdef CONFIG_MACH_PX
-#else
- if (num_chan > WMI_MAX_CHANNELS)
- return -EINVAL;
-#endif
-
- if (num_chan)
- size += sizeof(u16) * (num_chan - 1);
-
- skb = ath6kl_wmi_get_new_buf(size);
- if (!skb)
- return -ENOMEM;
-
- sc = (struct wmi_begin_scan_cmd *) skb->data;
- sc->scan_type = scan_type;
- sc->force_fg_scan = cpu_to_le32(force_fgscan);
- sc->is_legacy = cpu_to_le32(is_legacy);
- sc->home_dwell_time = cpu_to_le32(home_dwell_time);
- sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
- sc->no_cck = cpu_to_le32(no_cck);
- sc->num_ch = num_chan;
-
- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
- struct ieee80211_supported_band *sband =
- ar->wiphy->bands[band];
- u32 ratemask = rates[band];
- u8 *supp_rates = sc->supp_rates[band].rates;
- num_rates = 0;
-
- for (i = 0; i < sband->n_bitrates; i++) {
- if ((BIT(i) & ratemask) == 0)
- continue; /* skip rate */
- supp_rates[num_rates++] =
- (u8) (sband->bitrates[i].bitrate / 5);
- }
- sc->supp_rates[band].nrates = num_rates;
- }
-
- for (i = 0; i < num_chan; i++)
- sc->ch_list[i] = cpu_to_le16(ch_list[i]);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_BEGIN_SCAN_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use
- * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P
- * mgmt operations using station interface.
- */
-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
- enum wmi_scan_type scan_type,
- u32 force_fgscan, u32 is_legacy,
- u32 home_dwell_time, u32 force_scan_interval,
- s8 num_chan, u16 *ch_list)
-{
- struct sk_buff *skb;
- struct wmi_start_scan_cmd *sc;
- s8 size;
- int i, ret;
-
- size = sizeof(struct wmi_start_scan_cmd);
-
- if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
- return -EINVAL;
-
- if (num_chan > WMI_MAX_CHANNELS)
- return -EINVAL;
-
- if (num_chan)
- size += sizeof(u16) * (num_chan - 1);
-
- skb = ath6kl_wmi_get_new_buf(size);
- if (!skb)
- return -ENOMEM;
-
- sc = (struct wmi_start_scan_cmd *) skb->data;
- sc->scan_type = scan_type;
- sc->force_fg_scan = cpu_to_le32(force_fgscan);
- sc->is_legacy = cpu_to_le32(is_legacy);
- sc->home_dwell_time = cpu_to_le32(home_dwell_time);
- sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
- sc->num_ch = num_chan;
-
- for (i = 0; i < num_chan; i++)
- sc->ch_list[i] = cpu_to_le16(ch_list[i]);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx,
- u16 fg_start_sec,
- u16 fg_end_sec, u16 bg_sec,
- u16 minact_chdw_msec, u16 maxact_chdw_msec,
- u16 pas_chdw_msec, u8 short_scan_ratio,
- u8 scan_ctrl_flag, u32 max_dfsch_act_time,
- u16 maxact_scan_per_ssid)
-{
- struct sk_buff *skb;
- struct wmi_scan_params_cmd *sc;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
- if (!skb)
- return -ENOMEM;
-
- sc = (struct wmi_scan_params_cmd *) skb->data;
- sc->fg_start_period = cpu_to_le16(fg_start_sec);
- sc->fg_end_period = cpu_to_le16(fg_end_sec);
- sc->bg_period = cpu_to_le16(bg_sec);
- sc->minact_chdwell_time = cpu_to_le16(minact_chdw_msec);
- sc->maxact_chdwell_time = cpu_to_le16(maxact_chdw_msec);
- sc->pas_chdwell_time = cpu_to_le16(pas_chdw_msec);
- sc->short_scan_ratio = short_scan_ratio;
- sc->scan_ctrl_flags = scan_ctrl_flag;
- sc->max_dfsch_act_time = cpu_to_le32(max_dfsch_act_time);
- sc->maxact_scan_per_ssid = cpu_to_le16(maxact_scan_per_ssid);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_SCAN_PARAMS_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter, u32 ie_mask)
-{
- struct sk_buff *skb;
- struct wmi_bss_filter_cmd *cmd;
- int ret;
-
- if (filter >= LAST_BSS_FILTER)
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_bss_filter_cmd *) skb->data;
- cmd->bss_filter = filter;
- cmd->ie_mask = cpu_to_le32(ie_mask);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BSS_FILTER_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
- u8 ssid_len, u8 *ssid)
-{
- struct sk_buff *skb;
- struct wmi_probed_ssid_cmd *cmd;
- int ret;
-
- if (index > MAX_PROBED_SSIDS)
- return -EINVAL;
-
- if (ssid_len > sizeof(cmd->ssid))
- return -EINVAL;
-
- if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssid_len > 0))
- return -EINVAL;
-
- if ((flag & SPECIFIC_SSID_FLAG) && !ssid_len)
- return -EINVAL;
-
- if (flag & SPECIFIC_SSID_FLAG)
- wmi->is_probe_ssid = true;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_probed_ssid_cmd *) skb->data;
- cmd->entry_index = index;
- cmd->flag = flag;
- cmd->ssid_len = ssid_len;
- memcpy(cmd->ssid, ssid, ssid_len);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PROBED_SSID_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
- u16 listen_interval,
- u16 listen_beacons)
-{
- struct sk_buff *skb;
- struct wmi_listen_int_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_listen_int_cmd *) skb->data;
- cmd->listen_intvl = cpu_to_le16(listen_interval);
- cmd->num_beacons = cpu_to_le16(listen_beacons);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LISTEN_INT_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_mcastrate_cmd(struct wmi *wmi, u8 if_idx,
- u16 bitrate)
-{
- struct sk_buff *skb;
- struct wmi_set_mcastrate_cmd *cmd;
- int ret;
-
- printk(KERN_INFO "\tmcastrate = %d\n", bitrate);
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_mcastrate_cmd *) skb->data;
- cmd->bitrate = bitrate;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_MCASTRATE_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx,
- u16 bmiss_time,
- u16 num_beacons)
-{
- struct sk_buff *skb;
- struct wmi_bmiss_time_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_bmiss_time_cmd *) skb->data;
- cmd->bmiss_time = cpu_to_le16(bmiss_time);
- cmd->num_beacons = cpu_to_le16(num_beacons);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_BMISS_TIME_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode)
-{
- struct sk_buff *skb;
- struct wmi_power_mode_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_power_mode_cmd *) skb->data;
-
- if(wmi->parent_dev->psminfo == 0)
- {
- pwr_mode = MAX_PERF_POWER;
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s() pwr_mode = %d\n",
- __func__, pwr_mode);
- }
-
- cmd->pwr_mode = pwr_mode;
- wmi->pwr_mode = pwr_mode;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_POWER_MODE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period,
- u16 ps_poll_num, u16 dtim_policy,
- u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
- u16 ps_fail_event_policy)
-{
- struct sk_buff *skb;
- struct wmi_power_params_cmd *pm;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*pm));
- if (!skb)
- return -ENOMEM;
-
- pm = (struct wmi_power_params_cmd *)skb->data;
- pm->idle_period = cpu_to_le16(idle_period);
- pm->pspoll_number = cpu_to_le16(ps_poll_num);
- pm->dtim_policy = cpu_to_le16(dtim_policy);
- pm->tx_wakeup_policy = cpu_to_le16(tx_wakeup_policy);
- pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
- pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_POWER_PARAMS_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout)
-{
- struct sk_buff *skb;
- struct wmi_disc_timeout_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_disc_timeout_cmd *) skb->data;
- cmd->discon_timeout = timeout;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_DISC_TIMEOUT_CMDID,
- NO_SYNC_WMIFLAG);
-
- if (ret == 0)
- ath6kl_debug_set_disconnect_timeout(wmi->parent_dev, timeout);
-
- return ret;
-}
-
-int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
- enum crypto_type key_type,
- u8 key_usage, u8 key_len,
- u8 *key_rsc, unsigned int key_rsc_len,
- u8 *key_material,
- u8 key_op_ctrl, u8 *mac_addr,
- enum wmi_sync_flag sync_flag)
-{
- struct sk_buff *skb;
- struct wmi_add_cipher_key_cmd *cmd;
- int ret;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "addkey cmd: key_index=%u key_type=%d "
- "key_usage=%d key_len=%d key_op_ctrl=%d\n",
- key_index, key_type, key_usage, key_len, key_op_ctrl);
-
- if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
- (key_material == NULL) || key_rsc_len > 8)
- return -EINVAL;
-
- if ((WEP_CRYPT != key_type) && (NULL == key_rsc))
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_add_cipher_key_cmd *) skb->data;
- cmd->key_index = key_index;
- cmd->key_type = key_type;
- cmd->key_usage = key_usage;
- cmd->key_len = key_len;
- memcpy(cmd->key, key_material, key_len);
-
- if (key_rsc != NULL)
- memcpy(cmd->key_rsc, key_rsc, key_rsc_len);
-
- cmd->key_op_ctrl = key_op_ctrl;
-
- if (mac_addr)
- memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_CIPHER_KEY_CMDID,
- sync_flag);
-
- return ret;
-}
-
-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk)
-{
- struct sk_buff *skb;
- struct wmi_add_krk_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_add_krk_cmd *) skb->data;
- memcpy(cmd->krk, krk, WMI_KRK_LEN);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_KRK_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index)
-{
- struct sk_buff *skb;
- struct wmi_delete_cipher_key_cmd *cmd;
- int ret;
-
- if (key_index > WMI_MAX_KEY_INDEX)
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_delete_cipher_key_cmd *) skb->data;
- cmd->key_index = key_index;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_CIPHER_KEY_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
- const u8 *pmkid, bool set)
-{
- struct sk_buff *skb;
- struct wmi_setpmkid_cmd *cmd;
- int ret;
-
- if (bssid == NULL)
- return -EINVAL;
-
- if (set && pmkid == NULL)
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_setpmkid_cmd *) skb->data;
- memcpy(cmd->bssid, bssid, ETH_ALEN);
- if (set) {
- memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
- cmd->enable = PMKID_ENABLE;
- } else {
- memset(cmd->pmkid, 0, sizeof(cmd->pmkid));
- cmd->enable = PMKID_DISABLE;
- }
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_PMKID_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
- enum htc_endpoint_id ep_id, u8 if_idx)
-{
- struct wmi_data_hdr *data_hdr;
- int ret;
-
- if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
- return -EINVAL;
-
- skb_push(skb, sizeof(struct wmi_data_hdr));
-
- data_hdr = (struct wmi_data_hdr *) skb->data;
- data_hdr->info = SYNC_MSGTYPE << WMI_DATA_HDR_MSG_TYPE_SHIFT;
- data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
-
- ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
-
- return ret;
-}
-
-static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx)
-{
- struct sk_buff *skb;
- struct wmi_sync_cmd *cmd;
- struct wmi_data_sync_bufs data_sync_bufs[WMM_NUM_AC];
- enum htc_endpoint_id ep_id;
- u8 index, num_pri_streams = 0;
- int ret = 0;
- u8 fat_pipe_exist;
-
- memset(data_sync_bufs, 0, sizeof(data_sync_bufs));
-
- spin_lock_bh(&wmi->lock);
-
- fat_pipe_exist = wmi->fat_pipe_exist;
-
- for (index = 0; index < WMM_NUM_AC; index++) {
- if (fat_pipe_exist & (1 << index)) {
- num_pri_streams++;
- data_sync_bufs[num_pri_streams - 1].traffic_class =
- index;
- }
- }
-
- spin_unlock_bh(&wmi->lock);
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb) {
- ret = -ENOMEM;
- goto free_skb;
- }
-
- cmd = (struct wmi_sync_cmd *) skb->data;
-
- /*
- * In the SYNC cmd sent on the control Ep, send a bitmap
- * of the data eps on which the Data Sync will be sent
- */
- cmd->data_sync_map = fat_pipe_exist;
-
- for (index = 0; index < num_pri_streams; index++) {
- data_sync_bufs[index].skb = ath6kl_buf_alloc(0);
- if (data_sync_bufs[index].skb == NULL) {
- ret = -ENOMEM;
- break;
- }
- }
-
- /*
- * If buffer allocation for any of the dataSync fails,
- * then do not send the Synchronize cmd on the control ep
- */
- if (ret)
- goto free_skb;
-
- /*
- * Send sync cmd followed by sync data messages on all
- * endpoints being used
- */
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SYNCHRONIZE_CMDID,
- NO_SYNC_WMIFLAG);
-
- if (ret)
- goto free_skb;
-
- /* cmd buffer sent, we no longer own it */
- skb = NULL;
-
- for (index = 0; index < num_pri_streams; index++) {
-
- if (WARN_ON(!data_sync_bufs[index].skb))
- break;
-
- ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
- data_sync_bufs[index].
- traffic_class);
- ret =
- ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
- ep_id, if_idx);
-
- if (ret)
- break;
-
- data_sync_bufs[index].skb = NULL;
- }
-
-free_skb:
- /* free up any resources left over (possibly due to an error) */
- if (skb)
- dev_kfree_skb(skb);
-
- for (index = 0; index < num_pri_streams; index++) {
- if (data_sync_bufs[index].skb != NULL) {
- dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
- skb);
- }
- }
-
- return ret;
-}
-
-int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
- struct wmi_create_pstream_cmd *params)
-{
- struct sk_buff *skb;
- struct wmi_create_pstream_cmd *cmd;
- u8 fatpipe_exist_for_ac = 0;
- s32 min_phy = 0;
- s32 nominal_phy = 0;
- int ret;
-
- if (!((params->user_pri < 8) &&
- (params->user_pri <= 0x7) &&
- (up_to_ac[params->user_pri & 0x7] == params->traffic_class) &&
- (params->traffic_direc == UPLINK_TRAFFIC ||
- params->traffic_direc == DNLINK_TRAFFIC ||
- params->traffic_direc == BIDIR_TRAFFIC) &&
- (params->traffic_type == TRAFFIC_TYPE_APERIODIC ||
- params->traffic_type == TRAFFIC_TYPE_PERIODIC) &&
- (params->voice_psc_cap == DISABLE_FOR_THIS_AC ||
- params->voice_psc_cap == ENABLE_FOR_THIS_AC ||
- params->voice_psc_cap == ENABLE_FOR_ALL_AC) &&
- (params->tsid == WMI_IMPLICIT_PSTREAM ||
- params->tsid <= WMI_MAX_THINSTREAM))) {
- return -EINVAL;
- }
-
- /*
- * Check nominal PHY rate is >= minimalPHY,
- * so that DUT can allow TSRS IE
- */
-
- /* Get the physical rate (units of bps) */
- min_phy = ((le32_to_cpu(params->min_phy_rate) / 1000) / 1000);
-
- /* Check minimal phy < nominal phy rate */
- if (params->nominal_phy >= min_phy) {
- /* unit of 500 kbps */
- nominal_phy = (params->nominal_phy * 1000) / 500;
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "TSRS IE enabled::MinPhy %x->NominalPhy ===> %x\n",
- min_phy, nominal_phy);
-
- params->nominal_phy = nominal_phy;
- } else {
- params->nominal_phy = 0;
- }
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "sending create_pstream_cmd: ac=%d tsid:%d\n",
- params->traffic_class, params->tsid);
-
- cmd = (struct wmi_create_pstream_cmd *) skb->data;
- memcpy(cmd, params, sizeof(*cmd));
-
- /* This is an implicitly created Fat pipe */
- if ((u32) params->tsid == (u32) WMI_IMPLICIT_PSTREAM) {
- spin_lock_bh(&wmi->lock);
- fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
- (1 << params->traffic_class));
- wmi->fat_pipe_exist |= (1 << params->traffic_class);
- spin_unlock_bh(&wmi->lock);
- } else {
- /* explicitly created thin stream within a fat pipe */
- spin_lock_bh(&wmi->lock);
- fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
- (1 << params->traffic_class));
- wmi->stream_exist_for_ac[params->traffic_class] |=
- (1 << params->tsid);
- /*
- * If a thinstream becomes active, the fat pipe automatically
- * becomes active
- */
- wmi->fat_pipe_exist |= (1 << params->traffic_class);
- spin_unlock_bh(&wmi->lock);
- }
-
- /*
- * Indicate activty change to driver layer only if this is the
- * first TSID to get created in this AC explicitly or an implicit
- * fat pipe is getting created.
- */
- if (!fatpipe_exist_for_ac)
- ath6kl_indicate_tx_activity(wmi->parent_dev,
- params->traffic_class, true);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_CREATE_PSTREAM_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
- u8 tsid)
-{
- struct sk_buff *skb;
- struct wmi_delete_pstream_cmd *cmd;
- u16 active_tsids = 0;
- int ret;
-
- if (traffic_class > 3) {
- ath6kl_err("invalid traffic class: %d\n", traffic_class);
- return -EINVAL;
- }
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_delete_pstream_cmd *) skb->data;
- cmd->traffic_class = traffic_class;
- cmd->tsid = tsid;
-
- spin_lock_bh(&wmi->lock);
- active_tsids = wmi->stream_exist_for_ac[traffic_class];
- spin_unlock_bh(&wmi->lock);
-
- if (!(active_tsids & (1 << tsid))) {
- dev_kfree_skb(skb);
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "TSID %d doesn't exist for traffic class: %d\n",
- tsid, traffic_class);
- return -ENODATA;
- }
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
- traffic_class, tsid);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELETE_PSTREAM_CMDID,
- SYNC_BEFORE_WMIFLAG);
-
- spin_lock_bh(&wmi->lock);
- wmi->stream_exist_for_ac[traffic_class] &= ~(1 << tsid);
- active_tsids = wmi->stream_exist_for_ac[traffic_class];
- spin_unlock_bh(&wmi->lock);
-
- /*
- * Indicate stream inactivity to driver layer only if all tsids
- * within this AC are deleted.
- */
- if (!active_tsids) {
- ath6kl_indicate_tx_activity(wmi->parent_dev,
- traffic_class, false);
- wmi->fat_pipe_exist &= ~(1 << traffic_class);
- }
-
- return ret;
-}
-
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
- __be32 ips0, __be32 ips1)
-{
- struct sk_buff *skb;
- struct wmi_set_ip_cmd *cmd;
- int ret;
-
- /* Multicast address are not valid */
- if (ipv4_is_multicast(ips0) ||
- ipv4_is_multicast(ips1))
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_ip_cmd *) skb->data;
- cmd->ips[0] = ips0;
- cmd->ips[1] = ips1;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi)
-{
- u16 active_tsids;
- u8 stream_exist;
- int i;
-
- /*
- * Relinquish credits from all implicitly created pstreams
- * since when we go to sleep. If user created explicit
- * thinstreams exists with in a fatpipe leave them intact
- * for the user to delete.
- */
- spin_lock_bh(&wmi->lock);
- stream_exist = wmi->fat_pipe_exist;
- spin_unlock_bh(&wmi->lock);
-
- for (i = 0; i < WMM_NUM_AC; i++) {
- if (stream_exist & (1 << i)) {
-
- /*
- * FIXME: Is this lock & unlock inside
- * for loop correct? may need rework.
- */
- spin_lock_bh(&wmi->lock);
- active_tsids = wmi->stream_exist_for_ac[i];
- spin_unlock_bh(&wmi->lock);
-
- /*
- * If there are no user created thin streams
- * delete the fatpipe
- */
- if (!active_tsids) {
- stream_exist &= ~(1 << i);
- /*
- * Indicate inactivity to driver layer for
- * this fatpipe (pstream)
- */
- ath6kl_indicate_tx_activity(wmi->parent_dev,
- i, false);
- }
- }
- }
-
- /* FIXME: Can we do this assignment without locking ? */
- spin_lock_bh(&wmi->lock);
- wmi->fat_pipe_exist = stream_exist;
- spin_unlock_bh(&wmi->lock);
-}
-
-int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
- enum ath6kl_host_mode host_mode)
-{
- struct sk_buff *skb;
- struct wmi_set_host_sleep_mode_cmd *cmd;
- int ret;
-
- if ((host_mode != ATH6KL_HOST_MODE_ASLEEP) &&
- (host_mode != ATH6KL_HOST_MODE_AWAKE)) {
- ath6kl_err("invalid host sleep mode: %d\n", host_mode);
- return -EINVAL;
- }
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_host_sleep_mode_cmd *) skb->data;
-
- if (host_mode == ATH6KL_HOST_MODE_ASLEEP) {
- ath6kl_wmi_relinquish_implicit_pstream_credits(wmi);
- cmd->asleep = cpu_to_le32(1);
- } else
- cmd->awake = cpu_to_le32(1);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
- WMI_SET_HOST_SLEEP_MODE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-/* This command has zero length payload */
-static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi,
- struct ath6kl_vif *vif)
-{
- struct ath6kl *ar = wmi->parent_dev;
-
- set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
- wake_up(&ar->event_wq);
-
- return 0;
-}
-
-int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
- enum ath6kl_wow_mode wow_mode,
- u32 filter, u16 host_req_delay)
-{
- struct sk_buff *skb;
- struct wmi_set_wow_mode_cmd *cmd;
- int ret;
-
- if ((wow_mode != ATH6KL_WOW_MODE_ENABLE) &&
- wow_mode != ATH6KL_WOW_MODE_DISABLE) {
- ath6kl_err("invalid wow mode: %d\n", wow_mode);
- return -EINVAL;
- }
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_wow_mode_cmd *) skb->data;
- cmd->enable_wow = cpu_to_le32(wow_mode);
- cmd->filter = cpu_to_le32(filter);
- cmd->host_req_delay = cpu_to_le16(host_req_delay);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WOW_MODE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
- u8 list_id, u8 filter_size,
- u8 filter_offset, const u8 *filter,
- const u8 *mask)
-{
- struct sk_buff *skb;
- struct wmi_add_wow_pattern_cmd *cmd;
- u16 size;
- u8 *filter_mask;
- int ret;
-
- /*
- * Allocate additional memory in the buffer to hold
- * filter and mask value, which is twice of filter_size.
- */
- size = sizeof(*cmd) + (2 * filter_size);
-
- skb = ath6kl_wmi_get_new_buf(size);
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_add_wow_pattern_cmd *) skb->data;
- cmd->filter_list_id = list_id;
- cmd->filter_size = filter_size;
- cmd->filter_offset = filter_offset;
-
- memcpy(cmd->filter, filter, filter_size);
-
- filter_mask = (u8 *) (cmd->filter + filter_size);
- memcpy(filter_mask, mask, filter_size);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADD_WOW_PATTERN_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
- u16 list_id, u16 filter_id)
-{
- struct sk_buff *skb;
- struct wmi_del_wow_pattern_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_del_wow_pattern_cmd *) skb->data;
- cmd->filter_list_id = cpu_to_le16(list_id);
- cmd->filter_id = cpu_to_le16(filter_id);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DEL_WOW_PATTERN_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb,
- enum wmix_command_id cmd_id,
- enum wmi_sync_flag sync_flag)
-{
- struct wmix_cmd_hdr *cmd_hdr;
- int ret;
-
- skb_push(skb, sizeof(struct wmix_cmd_hdr));
-
- cmd_hdr = (struct wmix_cmd_hdr *) skb->data;
- cmd_hdr->cmd_id = cpu_to_le32(cmd_id);
-
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_EXTENSION_CMDID, sync_flag);
-
- return ret;
-}
-
-int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
-{
- struct sk_buff *skb;
- struct wmix_hb_challenge_resp_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmix_hb_challenge_resp_cmd *) skb->data;
- cmd->cookie = cpu_to_le32(cookie);
- cmd->source = cpu_to_le32(source);
-
- ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_HB_CHALLENGE_RESP_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config)
-{
- struct ath6kl_wmix_dbglog_cfg_module_cmd *cmd;
- struct sk_buff *skb;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct ath6kl_wmix_dbglog_cfg_module_cmd *) skb->data;
- cmd->valid = cpu_to_le32(valid);
- cmd->config = cpu_to_le32(config);
-
- ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_DBGLOG_CFG_MODULE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_get_stats_cmd(struct wmi *wmi, u8 if_idx)
-{
- return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_STATISTICS_CMDID);
-}
-
-int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM)
-{
- struct sk_buff *skb;
- struct wmi_set_tx_pwr_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_tx_pwr_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
- cmd->dbM = dbM;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_TX_PWR_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx)
-{
- return ath6kl_wmi_simple_cmd(wmi, if_idx, WMI_GET_TX_PWR_CMDID);
-}
-
-int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi)
-{
- return ath6kl_wmi_simple_cmd(wmi, 0, WMI_GET_ROAM_TBL_CMDID);
-}
-
-int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 if_idx, u8 status,
- u8 preamble_policy)
-{
- struct sk_buff *skb;
- struct wmi_set_lpreamble_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_lpreamble_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_lpreamble_cmd *) skb->data;
- cmd->status = status;
- cmd->preamble_policy = preamble_policy;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_LPREAMBLE_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
-{
- struct sk_buff *skb;
- struct wmi_set_rts_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_rts_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_rts_cmd *) skb->data;
- cmd->threshold = cpu_to_le16(threshold);
-
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_RTS_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg)
-{
- struct sk_buff *skb;
- struct wmi_set_wmm_txop_cmd *cmd;
- int ret;
-
- if (!((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)))
- return -EINVAL;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_wmm_txop_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
- cmd->txop_enable = cfg;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_WMM_TXOP_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
- u8 keep_alive_intvl)
-{
- struct sk_buff *skb;
- struct wmi_set_keepalive_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_keepalive_cmd *) skb->data;
- cmd->keep_alive_intvl = keep_alive_intvl;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_KEEPALIVE_CMDID,
- NO_SYNC_WMIFLAG);
-
- if (ret == 0)
- ath6kl_debug_set_keepalive(wmi->parent_dev, keep_alive_intvl);
-
- return ret;
-}
-
-int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len)
-{
- struct sk_buff *skb;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(len);
- if (!skb)
- return -ENOMEM;
-
- memcpy(skb->data, buf, len);
-
- ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_TEST_CMDID, NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on)
-{
- struct sk_buff *skb;
- struct wmi_mcast_filter_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_mcast_filter_cmd *) skb->data;
- cmd->mcast_all_enable = mc_all_on;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
- u8 *filter, bool add_filter)
-{
- struct sk_buff *skb;
- struct wmi_mcast_filter_add_del_cmd *cmd;
- int ret;
-
- if ((filter[0] != 0x33 || filter[1] != 0x33) &&
- (filter[0] != 0x01 || filter[1] != 0x00 ||
- filter[2] != 0x5e || filter[3] > 0x7f)) {
- ath6kl_warn("invalid multicast filter address\n");
- return -EINVAL;
- }
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data;
- memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb,
- add_filter ? WMI_SET_MCAST_FILTER_CMDID :
- WMI_DEL_MCAST_FILTER_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_set_ht_cap_cmd(struct wmi *wmi, u8 if_idx,
- struct wmi_set_ht_cap_cmd *params)
-{
- struct sk_buff *skb;
- struct wmi_set_ht_cap_cmd *cmd;
- struct ath6kl *ar = wmi->parent_dev;
- struct ieee80211_supported_band *sband;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_ht_cap_cmd *) skb->data;
- ath6kl_dbg(ATH6KL_DBG_WMI, "bands %d, ht_supported = %d, "
- "chan_width_40m_supported %d, short_gi_20mhz = %d, "
- "short_gi_40mhz = %d, intolerance_40mhz = %d\n",
- params->band, params->enable,
- params->chan_width_40m_supported, params->short_gi_20mhz,
- params->short_gi_40mhz, params->intolerance_40mhz);
- memcpy(cmd, params, sizeof(*cmd));
-
- sband = ar->wiphy->bands[params->band];
- sband->ht_cap.ht_supported = params->enable;
- if (params->chan_width_40m_supported)
- sband->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
- else
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-
- if (params->short_gi_20mhz)
- sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
- else
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
-
- if (params->short_gi_40mhz)
- sband->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
- else
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
-
- if (params->intolerance_40mhz)
- sband->ht_cap.cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
- else
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
-
- if (params->max_ampdu_len_exp)
- sband->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
- else
- sband->ht_cap.cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HT_CAP_CMDID,
- NO_SYNC_WMIFLAG);
- return ret;
-}
-
-
-s32 ath6kl_wmi_get_rate(s8 rate_index)
-{
- u32 sgi;
-
- if (rate_index == RATE_AUTO)
- return 0;
-
- /* SGI is stored as the MSG of the rate_index */
- if (rate_index & 0x80) {
- rate_index &= 0x7f;
- sgi = 1;
- } else {
- sgi = 0;
- }
-
- if (rate_index > RATE_MCS_7_40)
- rate_index = RATE_MCS_7_40;
-
- return wmi_rate_tbl[(u32) rate_index][sgi];
-}
-
-static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
- u32 len)
-{
- struct wmi_pmkid_list_reply *reply;
- u32 expected_len;
-
- if (len < sizeof(struct wmi_pmkid_list_reply))
- return -EINVAL;
-
- reply = (struct wmi_pmkid_list_reply *)datap;
- expected_len = sizeof(reply->num_pmkid) +
- le32_to_cpu(reply->num_pmkid) * WMI_PMKID_LEN;
-
- if (len < expected_len)
- return -EINVAL;
-
- return 0;
-}
-
-static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;
-
- aggr_recv_addba_req_evt(vif, cmd->tid,
- le16_to_cpu(cmd->st_seq_no), cmd->win_sz);
-
- return 0;
-}
-
-static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;
-
- aggr_recv_delba_req_evt(vif, cmd->tid);
-
- return 0;
-}
-
-/* AP mode functions */
-
-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
- struct wmi_connect_cmd *p)
-{
- struct sk_buff *skb;
- struct wmi_connect_cmd *cm;
- int res;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
- if (!skb)
- return -ENOMEM;
-
- cm = (struct wmi_connect_cmd *) skb->data;
- memcpy(cm, p, sizeof(*cm));
-
- res = ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_CONFIG_COMMIT_CMDID,
- NO_SYNC_WMIFLAG);
- ath6kl_dbg(ATH6KL_DBG_WMI, "%s: nw_type=%u auth_mode=%u ch=%u "
- "ctrl_flags=0x%x-> res=%d\n",
- __func__, p->nw_type, p->auth_mode, le16_to_cpu(p->ch),
- le32_to_cpu(p->ctrl_flags), res);
- return res;
-}
-
-int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
- u16 reason)
-{
- struct sk_buff *skb;
- struct wmi_ap_set_mlme_cmd *cm;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cm));
- if (!skb)
- return -ENOMEM;
-
- cm = (struct wmi_ap_set_mlme_cmd *) skb->data;
- memcpy(cm->mac, mac, ETH_ALEN);
- cm->reason = cpu_to_le16(reason);
- cm->cmd = cmd;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "ap_set_mlme: cmd=%d reason=%d\n", cm->cmd,
- cm->reason);
-
- return ath6kl_wmi_cmd_send(wmip, if_idx, skb, WMI_AP_SET_MLME_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable)
-{
- struct sk_buff *skb;
- struct wmi_ap_hidden_ssid_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_ap_hidden_ssid_cmd *) skb->data;
- cmd->hidden_ssid = enable ? 1 : 0;
-
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_HIDDEN_SSID_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-/* This command will be used to enable/disable AP uAPSD feature */
-int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
-{
- struct wmi_ap_set_apsd_cmd *cmd;
- struct sk_buff *skb;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_ap_set_apsd_cmd *)skb->data;
- cmd->enable = enable;
-
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx,
- u16 aid, u16 bitmap, u32 flags)
-{
- struct wmi_ap_apsd_buffered_traffic_cmd *cmd;
- struct sk_buff *skb;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data;
- cmd->aid = cpu_to_le16(aid);
- cmd->bitmap = cpu_to_le16(bitmap);
- cmd->flags = cpu_to_le32(flags);
-
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
- WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- struct wmi_pspoll_event *ev;
-
- if (len < sizeof(struct wmi_pspoll_event))
- return -EINVAL;
-
- ev = (struct wmi_pspoll_event *) datap;
-
- ath6kl_pspoll_event(vif, le16_to_cpu(ev->aid));
-
- return 0;
-}
-
-static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len,
- struct ath6kl_vif *vif)
-{
- ath6kl_dtimexpiry_event(vif);
-
- return 0;
-}
-
-int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid,
- bool flag)
-{
- struct sk_buff *skb;
- struct wmi_ap_set_pvb_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_ap_set_pvb_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
- cmd->aid = cpu_to_le16(aid);
- cmd->rsvd = cpu_to_le16(0);
- cmd->flag = cpu_to_le32(flag);
-
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_PVB_CMDID,
- NO_SYNC_WMIFLAG);
-
- return 0;
-}
-
-int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
- u8 rx_meta_ver,
- bool rx_dot11_hdr, bool defrag_on_host)
-{
- struct sk_buff *skb;
- struct wmi_rx_frame_format_cmd *cmd;
- int ret;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_rx_frame_format_cmd *) skb->data;
- cmd->dot11_hdr = rx_dot11_hdr ? 1 : 0;
- cmd->defrag_on_host = defrag_on_host ? 1 : 0;
- cmd->meta_ver = rx_meta_ver;
-
- /* Delete the local aggr state, on host */
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_RX_FRAME_FORMAT_CMDID,
- NO_SYNC_WMIFLAG);
-
- return ret;
-}
-
-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
- const u8 *ie, u8 ie_len)
-{
- struct sk_buff *skb;
- struct wmi_set_appie_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + ie_len);
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "set_appie_cmd: mgmt_frm_type=%u "
- "ie_len=%u\n", mgmt_frm_type, ie_len);
- p = (struct wmi_set_appie_cmd *) skb->data;
- p->mgmt_frm_type = mgmt_frm_type;
- p->ie_len = ie_len;
-
- if (ie != NULL && ie_len > 0)
- memcpy(p->ie_info, ie, ie_len);
-
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_APPIE_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field,
- const u8 *ie_info, u8 ie_len)
-{
- struct sk_buff *skb;
- struct wmi_set_ie_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + ie_len);
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "set_ie_cmd: ie_id=%u ie_ie_field=%u "
- "ie_len=%u\n", ie_id, ie_field, ie_len);
- p = (struct wmi_set_ie_cmd *) skb->data;
- p->ie_id = ie_id;
- p->ie_field = ie_field;
- p->ie_len = ie_len;
- if (ie_info != NULL && ie_len > 0)
- memcpy(p->ie_info, ie_info, ie_len);
-
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IE_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable)
-{
- struct sk_buff *skb;
- struct wmi_disable_11b_rates_cmd *cmd;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "disable_11b_rates_cmd: disable=%u\n",
- disable);
- cmd = (struct wmi_disable_11b_rates_cmd *) skb->data;
- cmd->disable = disable ? 1 : 0;
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_DISABLE_11B_RATES_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq, u32 dur)
-{
- struct sk_buff *skb;
- struct wmi_remain_on_chnl_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "remain_on_chnl_cmd: freq=%u dur=%u\n",
- freq, dur);
- p = (struct wmi_remain_on_chnl_cmd *) skb->data;
- p->freq = cpu_to_le32(freq);
- p->duration = cpu_to_le32(dur);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_REMAIN_ON_CHNL_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-/* ath6kl_wmi_send_action_cmd is to be deprecated. Use
- * ath6kl_wmi_send_mgmt_cmd instead. The new function supports P2P
- * mgmt operations using station interface.
- */
-static int ath6kl_wmi_send_action_cmd(struct wmi *wmi, u8 if_idx, u32 id,
- u32 freq, u32 wait, const u8 *data,
- u16 data_len)
-{
- struct sk_buff *skb;
- struct wmi_send_action_cmd *p;
- u8 *buf;
- int ret;
-
- if (wait)
- return -EINVAL; /* Offload for wait not supported */
-
- buf = kmalloc(data_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
- if (!skb) {
- kfree(buf);
- return -ENOMEM;
- }
-
- mutex_lock(&wmi->lock_mgmt);
- if (wmi->last_mgmt_tx_frame)
- kfree(wmi->last_mgmt_tx_frame);
-
- memcpy(buf, data, data_len);
- wmi->last_mgmt_tx_frame = buf;
- wmi->last_mgmt_tx_frame_len = data_len;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
- "len=%u\n", id, freq, wait, data_len);
- p = (struct wmi_send_action_cmd *) skb->data;
- p->id = cpu_to_le32(id);
- p->freq = cpu_to_le32(freq);
- p->wait = cpu_to_le32(wait);
- p->len = cpu_to_le16(data_len);
- memcpy(p->data, data, data_len);
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_ACTION_CMDID,
- NO_SYNC_WMIFLAG);
- mutex_unlock(&wmi->lock_mgmt);
- return ret;
-}
-
-static int __ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id,
- u32 freq, u32 wait, const u8 *data,
- u16 data_len, u32 no_cck)
-{
- struct sk_buff *skb;
- struct wmi_send_mgmt_cmd *p;
- u8 *buf;
- int ret;
-
- if (wait)
- return -EINVAL; /* Offload for wait not supported */
-
- buf = kmalloc(data_len, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p) + data_len);
- if (!skb) {
- kfree(buf);
- return -ENOMEM;
- }
-
- mutex_lock(&wmi->lock_mgmt);
- if (wmi->last_mgmt_tx_frame)
- kfree(wmi->last_mgmt_tx_frame);
-
- memcpy(buf, data, data_len);
- wmi->last_mgmt_tx_frame = buf;
- wmi->last_mgmt_tx_frame_len = data_len;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "send_action_cmd: id=%u freq=%u wait=%u "
- "len=%u\n", id, freq, wait, data_len);
- p = (struct wmi_send_mgmt_cmd *) skb->data;
- p->id = cpu_to_le32(id);
- p->freq = cpu_to_le32(freq);
- p->wait = cpu_to_le32(wait);
- p->no_cck = cpu_to_le32(no_cck);
- p->len = cpu_to_le16(data_len);
- memcpy(p->data, data, data_len);
- ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SEND_MGMT_CMDID,
- NO_SYNC_WMIFLAG);
- mutex_unlock(&wmi->lock_mgmt);
-
- return ret;
-}
-
-int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
- u32 wait, const u8 *data, u16 data_len,
- u32 no_cck)
-{
- int status;
- struct ath6kl *ar = wmi->parent_dev;
-
- if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
- ar->fw_capabilities)) {
- /*
- * If capable of doing P2P mgmt operations using
- * station interface, send additional information like
- * supported rates to advertise and xmit rates for
- * probe requests
- */
- status = __ath6kl_wmi_send_mgmt_cmd(ar->wmi, if_idx, id, freq,
- wait, data, data_len,
- no_cck);
- } else {
- status = ath6kl_wmi_send_action_cmd(ar->wmi, if_idx, id, freq,
- wait, data, data_len);
- }
-
- return status;
-}
-
-int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
- const u8 *dst, const u8 *data,
- u16 data_len)
-{
- struct sk_buff *skb;
- struct wmi_p2p_probe_response_cmd *p;
- size_t cmd_len = sizeof(*p) + data_len;
-
- if (data_len == 0)
- cmd_len++; /* work around target minimum length requirement */
-
- skb = ath6kl_wmi_get_new_buf(cmd_len);
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "send_probe_response_cmd: freq=%u dst=%s "
- "len=%u\n", freq, sec_conv_mac(dst), data_len);
- p = (struct wmi_p2p_probe_response_cmd *) skb->data;
- p->freq = cpu_to_le32(freq);
- memcpy(p->destination_addr, dst, ETH_ALEN);
- p->len = cpu_to_le16(data_len);
- memcpy(p->data, data, data_len);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
- WMI_SEND_PROBE_RESPONSE_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable)
-{
- struct sk_buff *skb;
- struct wmi_probe_req_report_cmd *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "probe_report_req_cmd: enable=%u\n",
- enable);
- p = (struct wmi_probe_req_report_cmd *) skb->data;
- p->enable = enable ? 1 : 0;
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_PROBE_REQ_REPORT_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags)
-{
- struct sk_buff *skb;
- struct wmi_get_p2p_info *p;
-
- skb = ath6kl_wmi_get_new_buf(sizeof(*p));
- if (!skb)
- return -ENOMEM;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "info_req_cmd: flags=%x\n",
- info_req_flags);
- p = (struct wmi_get_p2p_info *) skb->data;
- p->info_req_flags = cpu_to_le32(info_req_flags);
- return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_GET_P2P_INFO_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx)
-{
- ath6kl_dbg(ATH6KL_DBG_WMI, "cancel_remain_on_chnl_cmd\n");
- return ath6kl_wmi_simple_cmd(wmi, if_idx,
- WMI_CANCEL_REMAIN_ON_CHNL_CMDID);
-}
-
-static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
-{
- struct wmix_cmd_hdr *cmd;
- u32 len;
- u16 id;
- u8 *datap;
- int ret = 0;
-
- if (skb->len < sizeof(struct wmix_cmd_hdr)) {
- ath6kl_err("bad packet 1\n");
- return -EINVAL;
- }
-
- cmd = (struct wmix_cmd_hdr *) skb->data;
- id = le32_to_cpu(cmd->cmd_id);
-
- skb_pull(skb, sizeof(struct wmix_cmd_hdr));
-
- datap = skb->data;
- len = skb->len;
-
- switch (id) {
- case WMIX_HB_CHALLENGE_RESP_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n");
- break;
- case WMIX_DBGLOG_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len);
- ath6kl_debug_fwlog_event(wmi->parent_dev, datap, len);
- break;
- default:
- ath6kl_warn("unknown cmd id 0x%x\n", id);
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int ath6kl_wmi_roam_tbl_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
- return ath6kl_debug_roam_tbl_event(wmi->parent_dev, datap, len);
-}
-
-/* Control Path */
-int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
-{
- struct wmi_cmd_hdr *cmd;
- struct ath6kl_vif *vif;
- __le32 regcode;
- u32 len;
- u16 id;
- u8 if_idx;
- u8 *datap;
- int ret = 0;
-
- if (WARN_ON(skb == NULL))
- return -EINVAL;
-
- if (skb->len < sizeof(struct wmi_cmd_hdr)) {
- ath6kl_err("bad packet 1\n");
- dev_kfree_skb(skb);
- return -EINVAL;
- }
-
- cmd = (struct wmi_cmd_hdr *) skb->data;
- id = le16_to_cpu(cmd->cmd_id);
- if_idx = le16_to_cpu(cmd->info1) & WMI_CMD_HDR_IF_ID_MASK;
-
- skb_pull(skb, sizeof(struct wmi_cmd_hdr));
-
- datap = skb->data;
- len = skb->len;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi rx id %d len %d\n", id, len);
- ath6kl_dbg_dump(ATH6KL_DBG_WMI_DUMP, NULL, "wmi rx ",
- datap, len);
-
- vif = ath6kl_get_vif_by_index(wmi->parent_dev, if_idx);
- if (!vif) {
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "Wmi event for unavailable vif, vif_index:%d\n",
- if_idx);
- dev_kfree_skb(skb);
- return -EINVAL;
- }
-
- switch (id) {
- case WMI_GET_BITRATE_CMDID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
- ret = ath6kl_wmi_bitrate_reply_rx(wmi, datap, len);
- break;
- case WMI_GET_CHANNEL_LIST_CMDID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_CHANNEL_LIST_CMDID\n");
- ret = ath6kl_wmi_ch_list_reply_rx(wmi, datap, len);
- break;
- case WMI_GET_TX_PWR_CMDID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_TX_PWR_CMDID\n");
- ret = ath6kl_wmi_tx_pwr_reply_rx(wmi, datap, len);
- break;
- case WMI_READY_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
- ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_CONNECT_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
- ret = ath6kl_wmi_connect_event_rx(wmi, datap, len, vif);
- cfg80211_send_genevent_to_app(skb->dev, id, datap, len);
- break;
- case WMI_DISCONNECT_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
- ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len, vif);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_PEER_NODE_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
- ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_TKIP_MICERR_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
- ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len, vif);
- break;
- case WMI_BSSINFO_EVENTID:
- /* ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n"); */
- ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len, vif);
- break;
- case WMI_REGDOMAIN_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
- memcpy(&regcode, datap, 4);
- ath6kl_info("%s: 0x%x WWR:%d\n",
- le32_to_cpu(regcode) & BIT(31) ?
- "Country Code" : "Reg Domain",
- le32_to_cpu(regcode) & 0xfff,
- !!(le32_to_cpu(regcode) & BIT(30)));
- ath6kl_wmi_regdomain_event(wmi, datap, len);
- break;
- case WMI_PSTREAM_TIMEOUT_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
- ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_NEIGHBOR_REPORT_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
- ret = ath6kl_wmi_neighbor_report_event_rx(wmi, datap, len,
- vif);
- break;
- case WMI_SCAN_COMPLETE_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
- ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len, vif);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_CMDERROR_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
- ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
- break;
- case WMI_REPORT_STATISTICS_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
- ret = ath6kl_wmi_stats_event_rx(wmi, datap, len, vif);
- break;
- case WMI_RSSI_THRESHOLD_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
- ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
- break;
- case WMI_ERROR_REPORT_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ERROR_REPORT_EVENTID\n");
- ath6kl_wmi_error_report_event(wmi, datap, len);
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_OPT_RX_FRAME_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
- /* this event has been deprecated */
- break;
- case WMI_REPORT_ROAM_TBL_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
- ret = ath6kl_wmi_roam_tbl_event_rx(wmi, datap, len);
- break;
- case WMI_EXTENSION_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
- ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
- break;
- case WMI_CAC_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
- ret = ath6kl_wmi_cac_event_rx(wmi, datap, len, vif);
- break;
- case WMI_CHANNEL_CHANGE_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
- break;
- case WMI_REPORT_ROAM_DATA_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
- break;
- case WMI_TEST_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
- ret = ath6kl_wmi_test_rx(wmi, datap, len);
- break;
- case WMI_GET_FIXRATES_CMDID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
- ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
- break;
- case WMI_TX_RETRY_ERR_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_RETRY_ERR_EVENTID\n");
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_SNR_THRESHOLD_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SNR_THRESHOLD_EVENTID\n");
- ret = ath6kl_wmi_snr_threshold_event_rx(wmi, datap, len);
- break;
- case WMI_LQ_THRESHOLD_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_LQ_THRESHOLD_EVENTID\n");
- cfg80211_send_event_to_app(skb->dev, id, datap, len);
- break;
- case WMI_APLIST_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_APLIST_EVENTID\n");
- ret = ath6kl_wmi_aplist_event_rx(wmi, datap, len);
- break;
- case WMI_GET_KEEPALIVE_CMDID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_KEEPALIVE_CMDID\n");
- ret = ath6kl_wmi_keepalive_reply_rx(wmi, datap, len);
- break;
- case WMI_GET_WOW_LIST_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_WOW_LIST_EVENTID\n");
- break;
- case WMI_GET_PMKID_LIST_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
- ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
- break;
- case WMI_PSPOLL_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
- ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len, vif);
- break;
- case WMI_DTIMEXPIRY_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
- ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len, vif);
- break;
- case WMI_SET_PARAMS_REPLY_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
- break;
- case WMI_ADDBA_REQ_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
- ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len, vif);
- break;
- case WMI_ADDBA_RESP_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
- break;
- case WMI_DELBA_REQ_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
- ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len, vif);
- break;
- case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
- break;
- case WMI_REPORT_BTCOEX_STATS_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "WMI_REPORT_BTCOEX_STATS_EVENTID\n");
- break;
- case WMI_TX_COMPLETE_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
- ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
- break;
- case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID");
- ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif);
- break;
- case WMI_REMAIN_ON_CHNL_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n");
- ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif);
- break;
- case WMI_CANCEL_REMAIN_ON_CHNL_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "WMI_CANCEL_REMAIN_ON_CHNL_EVENTID\n");
- ret = ath6kl_wmi_cancel_remain_on_chnl_event_rx(wmi, datap,
- len, vif);
- break;
- case WMI_TX_STATUS_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_STATUS_EVENTID\n");
- ret = ath6kl_wmi_tx_status_event_rx(wmi, datap, len, vif);
- break;
- case WMI_RX_PROBE_REQ_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_PROBE_REQ_EVENTID\n");
- ret = ath6kl_wmi_rx_probe_req_event_rx(wmi, datap, len, vif);
- break;
- case WMI_P2P_CAPABILITIES_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_CAPABILITIES_EVENTID\n");
- ret = ath6kl_wmi_p2p_capabilities_event_rx(datap, len);
- break;
- case WMI_RX_ACTION_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n");
- ret = ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif);
- break;
- case WMI_P2P_INFO_EVENTID:
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_P2P_INFO_EVENTID\n");
- ret = ath6kl_wmi_p2p_info_event_rx(datap, len);
- break;
- default:
- ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
- ret = -EINVAL;
- break;
- }
-
- dev_kfree_skb(skb);
-
- return ret;
-}
-
-void ath6kl_wmi_reset(struct wmi *wmi)
-{
- spin_lock_bh(&wmi->lock);
-
- wmi->fat_pipe_exist = 0;
- memset(wmi->stream_exist_for_ac, 0, sizeof(wmi->stream_exist_for_ac));
-
- spin_unlock_bh(&wmi->lock);
-}
-
-void *ath6kl_wmi_init(struct ath6kl *dev)
-{
- struct wmi *wmi;
-
- wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
- if (!wmi)
- return NULL;
-
- spin_lock_init(&wmi->lock);
- mutex_init(&wmi->lock_mgmt);
-
- wmi->parent_dev = dev;
-
- wmi->pwr_mode = REC_POWER;
-
- ath6kl_wmi_reset(wmi);
-
- return wmi;
-}
-
-void ath6kl_wmi_shutdown(struct wmi *wmi)
-{
- if (!wmi)
- return;
-
- kfree(wmi->last_mgmt_tx_frame);
- kfree(wmi);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
deleted file mode 100755
index 1e6c48d..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ /dev/null
@@ -1,2602 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file contains the definitions of the WMI protocol specified in the
- * Wireless Module Interface (WMI). It includes definitions of all the
- * commands and events. Commands are messages from the host to the WM.
- * Events and Replies are messages from the WM to the host.
- */
-
-#ifndef WMI_H
-#define WMI_H
-
-#include <linux/ieee80211.h>
-
-#include "htc.h"
-
-#define HTC_PROTOCOL_VERSION 0x0002
-#define WMI_PROTOCOL_VERSION 0x0002
-#define WMI_CONTROL_MSG_MAX_LEN 256
-#define is_ethertype(type_or_len) ((type_or_len) >= 0x0600)
-
-#define IP_ETHERTYPE 0x0800
-
-#define WMI_IMPLICIT_PSTREAM 0xFF
-#define WMI_MAX_THINSTREAM 15
-
-#define SSID_IE_LEN_INDEX 13
-
-/* Host side link management data structures */
-#define SIG_QUALITY_THRESH_LVLS 6
-#define SIG_QUALITY_UPPER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
-#define SIG_QUALITY_LOWER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
-
-#define A_BAND_24GHZ 0
-#define A_BAND_5GHZ 1
-#define A_NUM_BANDS 2
-
-/* in ms */
-#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
-
-/*
- * There are no signed versions of __le16 and __le32, so for a temporary
- * solution come up with our own version. The idea is from fs/ntfs/types.h.
- *
- * Use a_ prefix so that it doesn't conflict if we get proper support to
- * linux/types.h.
- */
-typedef __s16 __bitwise a_sle16;
-typedef __s32 __bitwise a_sle32;
-
-static inline a_sle32 a_cpu_to_sle32(s32 val)
-{
- return (__force a_sle32) cpu_to_le32(val);
-}
-
-static inline s32 a_sle32_to_cpu(a_sle32 val)
-{
- return le32_to_cpu((__force __le32) val);
-}
-
-static inline a_sle16 a_cpu_to_sle16(s16 val)
-{
- return (__force a_sle16) cpu_to_le16(val);
-}
-
-static inline s16 a_sle16_to_cpu(a_sle16 val)
-{
- return le16_to_cpu((__force __le16) val);
-}
-
-struct sq_threshold_params {
- s16 upper_threshold[SIG_QUALITY_UPPER_THRESH_LVLS];
- s16 lower_threshold[SIG_QUALITY_LOWER_THRESH_LVLS];
- u32 upper_threshold_valid_count;
- u32 lower_threshold_valid_count;
- u32 polling_interval;
- u8 weight;
- u8 last_rssi;
- u8 last_rssi_poll_event;
-};
-
-struct wmi_data_sync_bufs {
- u8 traffic_class;
- struct sk_buff *skb;
-};
-
-/* WMM stream classes */
-#define WMM_NUM_AC 4
-#define WMM_AC_BE 0 /* best effort */
-#define WMM_AC_BK 1 /* background */
-#define WMM_AC_VI 2 /* video */
-#define WMM_AC_VO 3 /* voice */
-
-#define WMI_VOICE_USER_PRIORITY 0x7
-
-struct wmi {
- u16 stream_exist_for_ac[WMM_NUM_AC];
- u8 fat_pipe_exist;
- struct ath6kl *parent_dev;
- u8 pwr_mode;
- spinlock_t lock;
- struct mutex lock_mgmt;
- enum htc_endpoint_id ep_id;
- struct sq_threshold_params
- sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX];
- bool is_wmm_enabled;
- u8 traffic_class;
- bool is_probe_ssid;
-
- u8 *last_mgmt_tx_frame;
- size_t last_mgmt_tx_frame_len;
- u8 saved_pwr_mode;
-};
-
-struct host_app_area {
- __le32 wmi_protocol_ver;
-} __packed;
-
-enum wmi_msg_type {
- DATA_MSGTYPE = 0x0,
- CNTL_MSGTYPE,
- SYNC_MSGTYPE,
- OPT_MSGTYPE,
-};
-
-/*
- * Macros for operating on WMI_DATA_HDR (info) field
- */
-
-#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
-#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
-#define WMI_DATA_HDR_UP_MASK 0x07
-#define WMI_DATA_HDR_UP_SHIFT 2
-
-/* In AP mode, the same bit (b5) is used to indicate Power save state in
- * the Rx dir and More data bit state in the tx direction.
- */
-#define WMI_DATA_HDR_PS_MASK 0x1
-#define WMI_DATA_HDR_PS_SHIFT 5
-
-#define WMI_DATA_HDR_MORE 0x20
-
-enum wmi_data_hdr_data_type {
- WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
- WMI_DATA_HDR_DATA_TYPE_802_11,
-
- /* used to be used for the PAL */
- WMI_DATA_HDR_DATA_TYPE_ACL,
-};
-
-/* Bitmap of data header flags */
-enum wmi_data_hdr_flags {
- WMI_DATA_HDR_FLAGS_MORE = 0x1,
- WMI_DATA_HDR_FLAGS_EOSP = 0x2,
- WMI_DATA_HDR_FLAGS_UAPSD = 0x4,
-};
-
-#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
-#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
-
-/* Macros for operating on WMI_DATA_HDR (info2) field */
-#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
-#define WMI_DATA_HDR_SEQNO_SHIFT 0
-
-#define WMI_DATA_HDR_AMSDU_MASK 0x1
-#define WMI_DATA_HDR_AMSDU_SHIFT 12
-
-#define WMI_DATA_HDR_META_MASK 0x7
-#define WMI_DATA_HDR_META_SHIFT 13
-
-/* Macros for operating on WMI_DATA_HDR (info3) field */
-#define WMI_DATA_HDR_IF_IDX_MASK 0xF
-
-#define WMI_DATA_HDR_TRIG 0x10
-#define WMI_DATA_HDR_EOSP 0x10
-
-struct wmi_data_hdr {
- s8 rssi;
-
- /*
- * usage of 'info' field(8-bit):
- *
- * b1:b0 - WMI_MSG_TYPE
- * b4:b3:b2 - UP(tid)
- * b5 - Used in AP mode.
- * More-data in tx dir, PS in rx.
- * b7:b6 - Dot3 header(0),
- * Dot11 Header(1),
- * ACL data(2)
- */
- u8 info;
-
- /*
- * usage of 'info2' field(16-bit):
- *
- * b11:b0 - seq_no
- * b12 - A-MSDU?
- * b15:b13 - META_DATA_VERSION 0 - 7
- */
- __le16 info2;
-
- /*
- * usage of info3, 16-bit:
- * b3:b0 - Interface index
- * b4 - uAPSD trigger in rx & EOSP in tx
- * b15:b5 - Reserved
- */
- __le16 info3;
-} __packed;
-
-static inline u8 wmi_data_hdr_get_up(struct wmi_data_hdr *dhdr)
-{
- return (dhdr->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK;
-}
-
-static inline void wmi_data_hdr_set_up(struct wmi_data_hdr *dhdr,
- u8 usr_pri)
-{
- dhdr->info &= ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT);
- dhdr->info |= usr_pri << WMI_DATA_HDR_UP_SHIFT;
-}
-
-static inline u8 wmi_data_hdr_get_dot11(struct wmi_data_hdr *dhdr)
-{
- u8 data_type;
-
- data_type = (dhdr->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) &
- WMI_DATA_HDR_DATA_TYPE_MASK;
- return (data_type == WMI_DATA_HDR_DATA_TYPE_802_11);
-}
-
-static inline u16 wmi_data_hdr_get_seqno(struct wmi_data_hdr *dhdr)
-{
- return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_SEQNO_SHIFT) &
- WMI_DATA_HDR_SEQNO_MASK;
-}
-
-static inline u8 wmi_data_hdr_is_amsdu(struct wmi_data_hdr *dhdr)
-{
- return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_AMSDU_SHIFT) &
- WMI_DATA_HDR_AMSDU_MASK;
-}
-
-static inline u8 wmi_data_hdr_get_meta(struct wmi_data_hdr *dhdr)
-{
- return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
- WMI_DATA_HDR_META_MASK;
-}
-
-static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr)
-{
- return le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_IF_IDX_MASK;
-}
-
-/* Tx meta version definitions */
-#define WMI_MAX_TX_META_SZ 12
-#define WMI_META_VERSION_1 0x01
-#define WMI_META_VERSION_2 0x02
-
-/* Flag to signal to FW to calculate TCP checksum */
-#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01
-
-struct wmi_tx_meta_v1 {
- /* packet ID to identify the tx request */
- u8 pkt_id;
-
- /* rate policy to be used for the tx of this frame */
- u8 rate_plcy_id;
-} __packed;
-
-struct wmi_tx_meta_v2 {
- /*
- * Offset from start of the WMI header for csum calculation to
- * begin.
- */
- u8 csum_start;
-
- /* offset from start of WMI header where final csum goes */
- u8 csum_dest;
-
- /* no of bytes over which csum is calculated */
- u8 csum_flags;
-} __packed;
-
-struct wmi_rx_meta_v1 {
- u8 status;
-
- /* rate index mapped to rate at which this packet was received. */
- u8 rix;
-
- /* rssi of packet */
- u8 rssi;
-
- /* rf channel during packet reception */
- u8 channel;
-
- __le16 flags;
-} __packed;
-
-struct wmi_rx_meta_v2 {
- __le16 csum;
-
- /* bit 0 set -partial csum valid bit 1 set -test mode */
- u8 csum_flags;
-} __packed;
-
-#define WMI_CMD_HDR_IF_ID_MASK 0xF
-
-/* Control Path */
-struct wmi_cmd_hdr {
- __le16 cmd_id;
-
- /* info1 - 16 bits
- * b03:b00 - id
- * b15:b04 - unused */
- __le16 info1;
-
- /* for alignment */
- __le16 reserved;
-} __packed;
-
-static inline u8 wmi_cmd_hdr_get_if_idx(struct wmi_cmd_hdr *chdr)
-{
- return le16_to_cpu(chdr->info1) & WMI_CMD_HDR_IF_ID_MASK;
-}
-
-/* List of WMI commands */
-enum wmi_cmd_id {
- WMI_CONNECT_CMDID = 0x0001,
- WMI_RECONNECT_CMDID,
- WMI_DISCONNECT_CMDID,
- WMI_SYNCHRONIZE_CMDID,
- WMI_CREATE_PSTREAM_CMDID,
- WMI_DELETE_PSTREAM_CMDID,
- /* WMI_START_SCAN_CMDID is to be deprecated. Use
- * WMI_BEGIN_SCAN_CMDID instead. The new cmd supports P2P mgmt
- * operations using station interface.
- */
- WMI_START_SCAN_CMDID,
- WMI_SET_SCAN_PARAMS_CMDID,
- WMI_SET_BSS_FILTER_CMDID,
- WMI_SET_PROBED_SSID_CMDID, /* 10 */
- WMI_SET_LISTEN_INT_CMDID,
- WMI_SET_BMISS_TIME_CMDID,
- WMI_SET_DISC_TIMEOUT_CMDID,
- WMI_GET_CHANNEL_LIST_CMDID,
- WMI_SET_BEACON_INT_CMDID,
- WMI_GET_STATISTICS_CMDID,
- WMI_SET_CHANNEL_PARAMS_CMDID,
- WMI_SET_POWER_MODE_CMDID,
- WMI_SET_IBSS_PM_CAPS_CMDID,
- WMI_SET_POWER_PARAMS_CMDID, /* 20 */
- WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
- WMI_ADD_CIPHER_KEY_CMDID,
- WMI_DELETE_CIPHER_KEY_CMDID,
- WMI_ADD_KRK_CMDID,
- WMI_DELETE_KRK_CMDID,
- WMI_SET_PMKID_CMDID,
- WMI_SET_TX_PWR_CMDID,
- WMI_GET_TX_PWR_CMDID,
- WMI_SET_ASSOC_INFO_CMDID,
- WMI_ADD_BAD_AP_CMDID, /* 30 */
- WMI_DELETE_BAD_AP_CMDID,
- WMI_SET_TKIP_COUNTERMEASURES_CMDID,
- WMI_RSSI_THRESHOLD_PARAMS_CMDID,
- WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
- WMI_SET_ACCESS_PARAMS_CMDID,
- WMI_SET_RETRY_LIMITS_CMDID,
- WMI_SET_OPT_MODE_CMDID,
- WMI_OPT_TX_FRAME_CMDID,
- WMI_SET_VOICE_PKT_SIZE_CMDID,
- WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
- WMI_SET_ROAM_CTRL_CMDID,
- WMI_GET_ROAM_TBL_CMDID,
- WMI_GET_ROAM_DATA_CMDID,
- WMI_ENABLE_RM_CMDID,
- WMI_SET_MAX_OFFHOME_DURATION_CMDID,
- WMI_EXTENSION_CMDID, /* Non-wireless extensions */
- WMI_SNR_THRESHOLD_PARAMS_CMDID,
- WMI_LQ_THRESHOLD_PARAMS_CMDID,
- WMI_SET_LPREAMBLE_CMDID,
- WMI_SET_RTS_CMDID, /* 50 */
- WMI_CLR_RSSI_SNR_CMDID,
- WMI_SET_FIXRATES_CMDID,
- WMI_GET_FIXRATES_CMDID,
- WMI_SET_AUTH_MODE_CMDID,
- WMI_SET_REASSOC_MODE_CMDID,
- WMI_SET_WMM_CMDID,
- WMI_SET_WMM_TXOP_CMDID,
- WMI_TEST_CMDID,
-
- /* COEX AR6002 only */
- WMI_SET_BT_STATUS_CMDID,
- WMI_SET_BT_PARAMS_CMDID, /* 60 */
-
- WMI_SET_KEEPALIVE_CMDID,
- WMI_GET_KEEPALIVE_CMDID,
- WMI_SET_APPIE_CMDID,
- WMI_GET_APPIE_CMDID,
- WMI_SET_WSC_STATUS_CMDID,
-
- /* Wake on Wireless */
- WMI_SET_HOST_SLEEP_MODE_CMDID,
- WMI_SET_WOW_MODE_CMDID,
- WMI_GET_WOW_LIST_CMDID,
- WMI_ADD_WOW_PATTERN_CMDID,
- WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
-
- WMI_SET_FRAMERATES_CMDID,
- WMI_SET_AP_PS_CMDID,
- WMI_SET_QOS_SUPP_CMDID,
- WMI_SET_IE_CMDID,
-
- /* WMI_THIN_RESERVED_... mark the start and end
- * values for WMI_THIN_RESERVED command IDs. These
- * command IDs can be found in wmi_thin.h */
- WMI_THIN_RESERVED_START = 0x8000,
- WMI_THIN_RESERVED_END = 0x8fff,
-
- /* Developer commands starts at 0xF000 */
- WMI_SET_BITRATE_CMDID = 0xF000,
- WMI_GET_BITRATE_CMDID,
- WMI_SET_WHALPARAM_CMDID,
- WMI_SET_MAC_ADDRESS_CMDID,
- WMI_SET_AKMP_PARAMS_CMDID,
- WMI_SET_PMKID_LIST_CMDID,
- WMI_GET_PMKID_LIST_CMDID,
- WMI_ABORT_SCAN_CMDID,
- WMI_SET_TARGET_EVENT_REPORT_CMDID,
-
- /* Unused */
- WMI_UNUSED1,
- WMI_UNUSED2,
-
- /* AP mode commands */
- WMI_AP_HIDDEN_SSID_CMDID,
- WMI_AP_SET_NUM_STA_CMDID,
- WMI_AP_ACL_POLICY_CMDID,
- WMI_AP_ACL_MAC_LIST_CMDID,
- WMI_AP_CONFIG_COMMIT_CMDID,
- WMI_AP_SET_MLME_CMDID,
- WMI_AP_SET_PVB_CMDID,
- WMI_AP_CONN_INACT_CMDID,
- WMI_AP_PROT_SCAN_TIME_CMDID,
- WMI_AP_SET_COUNTRY_CMDID,
- WMI_AP_SET_DTIM_CMDID,
- WMI_AP_MODE_STAT_CMDID,
-
- WMI_SET_IP_CMDID,
- WMI_SET_PARAMS_CMDID,
- WMI_SET_MCAST_FILTER_CMDID,
- WMI_DEL_MCAST_FILTER_CMDID,
-
- WMI_ALLOW_AGGR_CMDID,
- WMI_ADDBA_REQ_CMDID,
- WMI_DELBA_REQ_CMDID,
- WMI_SET_HT_CAP_CMDID,
- WMI_SET_HT_OP_CMDID,
- WMI_SET_TX_SELECT_RATES_CMDID,
- WMI_SET_TX_SGI_PARAM_CMDID,
- WMI_SET_RATE_POLICY_CMDID,
-
- WMI_HCI_CMD_CMDID,
- WMI_RX_FRAME_FORMAT_CMDID,
- WMI_SET_THIN_MODE_CMDID,
- WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
-
- WMI_AP_SET_11BG_RATESET_CMDID,
- WMI_SET_PMK_CMDID,
- WMI_MCAST_FILTER_CMDID,
-
- /* COEX CMDID AR6003 */
- WMI_SET_BTCOEX_FE_ANT_CMDID,
- WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
- WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
- WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
- WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
- WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
- WMI_SET_BTCOEX_DEBUG_CMDID,
- WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
- WMI_GET_BTCOEX_STATS_CMDID,
- WMI_GET_BTCOEX_CONFIG_CMDID,
-
- WMI_SET_DFS_ENABLE_CMDID, /* F034 */
- WMI_SET_DFS_MINRSSITHRESH_CMDID,
- WMI_SET_DFS_MAXPULSEDUR_CMDID,
- WMI_DFS_RADAR_DETECTED_CMDID,
-
- /* P2P commands */
- WMI_P2P_SET_CONFIG_CMDID, /* F038 */
- WMI_WPS_SET_CONFIG_CMDID,
- WMI_SET_REQ_DEV_ATTR_CMDID,
- WMI_P2P_FIND_CMDID,
- WMI_P2P_STOP_FIND_CMDID,
- WMI_P2P_GO_NEG_START_CMDID,
- WMI_P2P_LISTEN_CMDID,
-
- WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
- WMI_SET_PROMISCUOUS_MODE_CMDID,
- WMI_RX_FRAME_FILTER_CMDID,
- WMI_SET_CHANNEL_CMDID,
-
- /* WAC commands */
- WMI_ENABLE_WAC_CMDID,
- WMI_WAC_SCAN_REPLY_CMDID,
- WMI_WAC_CTRL_REQ_CMDID,
- WMI_SET_DIV_PARAMS_CMDID,
-
- WMI_GET_PMK_CMDID,
- WMI_SET_PASSPHRASE_CMDID,
- WMI_SEND_ASSOC_RES_CMDID,
- WMI_SET_ASSOC_REQ_RELAY_CMDID,
-
- /* ACS command, consists of sub-commands */
- WMI_ACS_CTRL_CMDID,
- WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
- WMI_SET_TBD_TIME_CMDID, /*added for wmiconfig command for TBD */
-
- /* Pktlog cmds */
- WMI_PKTLOG_ENABLE_CMDID,
- WMI_PKTLOG_DISABLE_CMDID,
-
- /* More P2P Cmds */
- WMI_P2P_GO_NEG_REQ_RSP_CMDID,
- WMI_P2P_GRP_INIT_CMDID,
- WMI_P2P_GRP_FORMATION_DONE_CMDID,
- WMI_P2P_INVITE_CMDID,
- WMI_P2P_INVITE_REQ_RSP_CMDID,
- WMI_P2P_PROV_DISC_REQ_CMDID,
- WMI_P2P_SET_CMDID,
-
- WMI_GET_RFKILL_MODE_CMDID,
- WMI_SET_RFKILL_MODE_CMDID,
- WMI_AP_SET_APSD_CMDID,
- WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
-
- WMI_P2P_SDPD_TX_CMDID, /* F05C */
- WMI_P2P_STOP_SDPD_CMDID,
- WMI_P2P_CANCEL_CMDID,
- /* Ultra low power store / recall commands */
- WMI_STORERECALL_CONFIGURE_CMDID,
- WMI_STORERECALL_RECALL_CMDID,
- WMI_STORERECALL_HOST_READY_CMDID,
- WMI_FORCE_TARGET_ASSERT_CMDID,
-
- WMI_SET_PROBED_SSID_EX_CMDID,
- WMI_SET_NETWORK_LIST_OFFLOAD_CMDID,
- WMI_SET_ARP_NS_OFFLOAD_CMDID,
- WMI_ADD_WOW_EXT_PATTERN_CMDID,
- WMI_GTK_OFFLOAD_OP_CMDID,
- WMI_REMAIN_ON_CHNL_CMDID,
- WMI_CANCEL_REMAIN_ON_CHNL_CMDID,
- /* WMI_SEND_ACTION_CMDID is to be deprecated. Use
- * WMI_SEND_MGMT_CMDID instead. The new cmd supports P2P mgmt
- * operations using station interface.
- */
- WMI_SEND_ACTION_CMDID,
- WMI_PROBE_REQ_REPORT_CMDID,
- WMI_DISABLE_11B_RATES_CMDID,
- WMI_SEND_PROBE_RESPONSE_CMDID,
- WMI_GET_P2P_INFO_CMDID,
- WMI_AP_JOIN_BSS_CMDID,
-
- WMI_SMPS_ENABLE_CMDID,
- WMI_SMPS_CONFIG_CMDID,
- WMI_SET_RATECTRL_PARM_CMDID,
- /* LPL specific commands*/
- WMI_LPL_FORCE_ENABLE_CMDID,
- WMI_LPL_SET_POLICY_CMDID,
- WMI_LPL_GET_POLICY_CMDID,
- WMI_LPL_GET_HWSTATE_CMDID,
- WMI_LPL_SET_PARAMS_CMDID,
- WMI_LPL_GET_PARAMS_CMDID,
-
- WMI_SET_BUNDLE_PARAM_CMDID,
-
- /*GreenTx specific commands*/
-
- WMI_GREENTX_PARAMS_CMDID,
-
- WMI_RTT_MEASREQ_CMDID,
- WMI_RTT_CAPREQ_CMDID,
- WMI_RTT_STATUSREQ_CMDID,
-
- /* WPS Commands */
- WMI_WPS_START_CMDID,
- WMI_GET_WPS_STATUS_CMDID,
-
- /* More P2P commands */
- WMI_SET_NOA_CMDID,
- WMI_GET_NOA_CMDID,
- WMI_SET_OPPPS_CMDID,
- WMI_GET_OPPPS_CMDID,
- WMI_ADD_PORT_CMDID,
- WMI_DEL_PORT_CMDID,
-
- /* 802.11w cmd */
- WMI_SET_RSN_CAP_CMDID,
- WMI_GET_RSN_CAP_CMDID,
- WMI_SET_IGTK_CMDID,
-
- WMI_RX_FILTER_COALESCE_FILTER_OP_CMDID,
- WMI_RX_FILTER_SET_FRAME_TEST_LIST_CMDID,
-
- WMI_SEND_MGMT_CMDID,
- WMI_BEGIN_SCAN_CMDID,
-
- WMI_SET_MCASTRATE_CMDID,
-};
-
-enum wmi_mgmt_frame_type {
- WMI_FRAME_BEACON = 0,
- WMI_FRAME_PROBE_REQ,
- WMI_FRAME_PROBE_RESP,
- WMI_FRAME_ASSOC_REQ,
- WMI_FRAME_ASSOC_RESP,
- WMI_NUM_MGMT_FRAME
-};
-
-enum wmi_ie_field_type {
- WMI_RSN_IE_CAPB = 0x1,
- WMI_IE_FULL = 0xFF /* indicats full IE */
-};
-
-/* WMI_CONNECT_CMDID */
-enum network_type {
- INFRA_NETWORK = 0x01,
- ADHOC_NETWORK = 0x02,
- ADHOC_CREATOR = 0x04,
- AP_NETWORK = 0x10,
-};
-
-enum network_subtype {
- SUBTYPE_NONE,
- SUBTYPE_BT,
- SUBTYPE_P2PDEV,
- SUBTYPE_P2PCLIENT,
- SUBTYPE_P2PGO,
-};
-
-enum dot11_auth_mode {
- OPEN_AUTH = 0x01,
- SHARED_AUTH = 0x02,
-
- /* different from IEEE_AUTH_MODE definitions */
- LEAP_AUTH = 0x04,
-};
-
-enum auth_mode {
- NONE_AUTH = 0x01,
- WPA_AUTH = 0x02,
- WPA2_AUTH = 0x04,
- WPA_PSK_AUTH = 0x08,
- WPA2_PSK_AUTH = 0x10,
- WPA_AUTH_CCKM = 0x20,
- WPA2_AUTH_CCKM = 0x40,
-};
-
-#define WMI_MAX_KEY_INDEX 3
-
-#define WMI_MAX_KEY_LEN 32
-
-/*
- * NB: these values are ordered carefully; there are lots of
- * of implications in any reordering. In particular beware
- * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
- */
-#define ATH6KL_CIPHER_WEP 0
-#define ATH6KL_CIPHER_TKIP 1
-#define ATH6KL_CIPHER_AES_OCB 2
-#define ATH6KL_CIPHER_AES_CCM 3
-#define ATH6KL_CIPHER_CKIP 5
-#define ATH6KL_CIPHER_CCKM_KRK 6
-#define ATH6KL_CIPHER_NONE 7 /* pseudo value */
-
-/*
- * 802.11 rate set.
- */
-#define ATH6KL_RATE_MAXSIZE 15 /* max rates we'll handle */
-
-#define ATH_OUI_TYPE 0x01
-#define WPA_OUI_TYPE 0x01
-#define WMM_PARAM_OUI_SUBTYPE 0x01
-#define WMM_OUI_TYPE 0x02
-#define WSC_OUT_TYPE 0x04
-
-enum wmi_connect_ctrl_flags_bits {
- CONNECT_ASSOC_POLICY_USER = 0x0001,
- CONNECT_SEND_REASSOC = 0x0002,
- CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
- CONNECT_PROFILE_MATCH_DONE = 0x0008,
- CONNECT_IGNORE_AAC_BEACON = 0x0010,
- CONNECT_CSA_FOLLOW_BSS = 0x0020,
- CONNECT_DO_WPA_OFFLOAD = 0x0040,
- CONNECT_DO_NOT_DEAUTH = 0x0080,
- CONNECT_WPS_FLAG = 0x0100,
-};
-
-struct wmi_connect_cmd {
- u8 nw_type;
- u8 dot11_auth_mode;
- u8 auth_mode;
- u8 prwise_crypto_type;
- u8 prwise_crypto_len;
- u8 grp_crypto_type;
- u8 grp_crypto_len;
- u8 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
- __le16 ch;
- u8 bssid[ETH_ALEN];
- __le32 ctrl_flags;
- u8 nw_subtype;
-} __packed;
-
-/* WMI_RECONNECT_CMDID */
-struct wmi_reconnect_cmd {
- /* channel hint */
- __le16 channel;
-
- /* mandatory if set */
- u8 bssid[ETH_ALEN];
-} __packed;
-
-/* WMI_ADD_CIPHER_KEY_CMDID */
-enum key_usage {
- PAIRWISE_USAGE = 0x00,
- GROUP_USAGE = 0x01,
-
- /* default Tx Key - static WEP only */
- TX_USAGE = 0x02,
-};
-
-/*
- * Bit Flag
- * Bit 0 - Initialise TSC - default is Initialize
- */
-#define KEY_OP_INIT_TSC 0x01
-#define KEY_OP_INIT_RSC 0x02
-
-/* default initialise the TSC & RSC */
-#define KEY_OP_INIT_VAL 0x03
-#define KEY_OP_VALID_MASK 0x03
-
-struct wmi_add_cipher_key_cmd {
- u8 key_index;
- u8 key_type;
-
- /* enum key_usage */
- u8 key_usage;
-
- u8 key_len;
-
- /* key replay sequence counter */
- u8 key_rsc[8];
-
- u8 key[WLAN_MAX_KEY_LEN];
-
- /* additional key control info */
- u8 key_op_ctrl;
-
- u8 key_mac_addr[ETH_ALEN];
-} __packed;
-
-/* WMI_DELETE_CIPHER_KEY_CMDID */
-struct wmi_delete_cipher_key_cmd {
- u8 key_index;
-} __packed;
-
-#define WMI_KRK_LEN 16
-
-/* WMI_ADD_KRK_CMDID */
-struct wmi_add_krk_cmd {
- u8 krk[WMI_KRK_LEN];
-} __packed;
-
-/* WMI_SETPMKID_CMDID */
-
-#define WMI_PMKID_LEN 16
-
-enum pmkid_enable_flg {
- PMKID_DISABLE = 0,
- PMKID_ENABLE = 1,
-};
-
-struct wmi_setpmkid_cmd {
- u8 bssid[ETH_ALEN];
-
- /* enum pmkid_enable_flg */
- u8 enable;
-
- u8 pmkid[WMI_PMKID_LEN];
-} __packed;
-
-/* WMI_START_SCAN_CMD */
-enum wmi_scan_type {
- WMI_LONG_SCAN = 0,
- WMI_SHORT_SCAN = 1,
-};
-
-struct wmi_supp_rates {
- u8 nrates;
- u8 rates[ATH6KL_RATE_MAXSIZE];
-};
-
-struct wmi_begin_scan_cmd {
- __le32 force_fg_scan;
-
- /* for legacy cisco AP compatibility */
- __le32 is_legacy;
-
- /* max duration in the home channel(msec) */
- __le32 home_dwell_time;
-
- /* time interval between scans (msec) */
- __le32 force_scan_intvl;
-
- /* no CCK rates */
- __le32 no_cck;
-
- /* enum wmi_scan_type */
- u8 scan_type;
-
- /* Supported rates to advertise in the probe request frames */
- struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS];
-
- /* how many channels follow */
- u8 num_ch;
-
- /* channels in Mhz */
- __le16 ch_list[1];
-} __packed;
-
-/* wmi_start_scan_cmd is to be deprecated. Use
- * wmi_begin_scan_cmd instead. The new structure supports P2P mgmt
- * operations using station interface.
- */
-struct wmi_start_scan_cmd {
- __le32 force_fg_scan;
-
- /* for legacy cisco AP compatibility */
- __le32 is_legacy;
-
- /* max duration in the home channel(msec) */
- __le32 home_dwell_time;
-
- /* time interval between scans (msec) */
- __le32 force_scan_intvl;
-
- /* enum wmi_scan_type */
- u8 scan_type;
-
- /* how many channels follow */
- u8 num_ch;
-
- /* channels in Mhz */
- __le16 ch_list[1];
-} __packed;
-
-/*
- * Warning: scan control flag value of 0xFF is used to disable
- * all flags in WMI_SCAN_PARAMS_CMD. Do not add any more
- * flags here
- */
-enum wmi_scan_ctrl_flags_bits {
-
- /* set if can scan in the connect cmd */
- CONNECT_SCAN_CTRL_FLAGS = 0x01,
-
- /* set if scan for the SSID it is already connected to */
- SCAN_CONNECTED_CTRL_FLAGS = 0x02,
-
- /* set if enable active scan */
- ACTIVE_SCAN_CTRL_FLAGS = 0x04,
-
- /* set if enable roam scan when bmiss and lowrssi */
- ROAM_SCAN_CTRL_FLAGS = 0x08,
-
- /* set if follows customer BSSINFO reporting rule */
- REPORT_BSSINFO_CTRL_FLAGS = 0x10,
-
- /* if disabled, target doesn't scan after a disconnect event */
- ENABLE_AUTO_CTRL_FLAGS = 0x20,
-
- /*
- * Scan complete event with canceled status will be generated when
- * a scan is prempted before it gets completed.
- */
- ENABLE_SCAN_ABORT_EVENT = 0x40
-};
-
-struct wmi_scan_params_cmd {
- /* sec */
- __le16 fg_start_period;
-
- /* sec */
- __le16 fg_end_period;
-
- /* sec */
- __le16 bg_period;
-
- /* msec */
- __le16 maxact_chdwell_time;
-
- /* msec */
- __le16 pas_chdwell_time;
-
- /* how many shorts scan for one long */
- u8 short_scan_ratio;
-
- u8 scan_ctrl_flags;
-
- /* msec */
- __le16 minact_chdwell_time;
-
- /* max active scans per ssid */
- __le16 maxact_scan_per_ssid;
-
- /* msecs */
- __le32 max_dfsch_act_time;
-} __packed;
-
-/* WMI_SET_BSS_FILTER_CMDID */
-enum wmi_bss_filter {
- /* no beacons forwarded */
- NONE_BSS_FILTER = 0x0,
-
- /* all beacons forwarded */
- ALL_BSS_FILTER,
-
- /* only beacons matching profile */
- PROFILE_FILTER,
-
- /* all but beacons matching profile */
- ALL_BUT_PROFILE_FILTER,
-
- /* only beacons matching current BSS */
- CURRENT_BSS_FILTER,
-
- /* all but beacons matching BSS */
- ALL_BUT_BSS_FILTER,
-
- /* beacons matching probed ssid */
- PROBED_SSID_FILTER,
-
- /* marker only */
- LAST_BSS_FILTER,
-};
-
-struct wmi_bss_filter_cmd {
- /* see, enum wmi_bss_filter */
- u8 bss_filter;
-
- /* for alignment */
- u8 reserved1;
-
- /* for alignment */
- __le16 reserved2;
-
- __le32 ie_mask;
-} __packed;
-
-/* WMI_SET_PROBED_SSID_CMDID */
-#define MAX_PROBED_SSIDS 16
-
-enum wmi_ssid_flag {
- /* disables entry */
- DISABLE_SSID_FLAG = 0,
-
- /* probes specified ssid */
- SPECIFIC_SSID_FLAG = 0x01,
-
- /* probes for any ssid */
- ANY_SSID_FLAG = 0x02,
-};
-
-struct wmi_probed_ssid_cmd {
- /* 0 to MAX_PROBED_SSIDS - 1 */
- u8 entry_index;
-
- /* see, enum wmi_ssid_flg */
- u8 flag;
-
- u8 ssid_len;
- u8 ssid[IEEE80211_MAX_SSID_LEN];
-} __packed;
-
-/*
- * WMI_SET_LISTEN_INT_CMDID
- * The Listen interval is between 15 and 3000 TUs
- */
-struct wmi_listen_int_cmd {
- __le16 listen_intvl;
- __le16 num_beacons;
-} __packed;
-
-/* WMI_SET_BMISS_TIME_CMDID */
-struct wmi_bmiss_time_cmd {
- __le16 bmiss_time;
- __le16 num_beacons;
-};
-
-/* WMI_SET_POWER_MODE_CMDID */
-enum wmi_power_mode {
- REC_POWER = 0x01,
- MAX_PERF_POWER,
-};
-
-struct wmi_power_mode_cmd {
- /* see, enum wmi_power_mode */
- u8 pwr_mode;
-} __packed;
-
-/*
- * Policy to determnine whether power save failure event should be sent to
- * host during scanning
- */
-enum power_save_fail_event_policy {
- SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
- IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
-};
-
-struct wmi_power_params_cmd {
- /* msec */
- __le16 idle_period;
-
- __le16 pspoll_number;
- __le16 dtim_policy;
- __le16 tx_wakeup_policy;
- __le16 num_tx_to_wakeup;
- __le16 ps_fail_event_policy;
-} __packed;
-
-/* WMI_SET_DISC_TIMEOUT_CMDID */
-struct wmi_disc_timeout_cmd {
- /* seconds */
- u8 discon_timeout;
-} __packed;
-
-enum dir_type {
- UPLINK_TRAFFIC = 0,
- DNLINK_TRAFFIC = 1,
- BIDIR_TRAFFIC = 2,
-};
-
-enum voiceps_cap_type {
- DISABLE_FOR_THIS_AC = 0,
- ENABLE_FOR_THIS_AC = 1,
- ENABLE_FOR_ALL_AC = 2,
-};
-
-enum traffic_type {
- TRAFFIC_TYPE_APERIODIC = 0,
- TRAFFIC_TYPE_PERIODIC = 1,
-};
-
-/* WMI_SYNCHRONIZE_CMDID */
-struct wmi_sync_cmd {
- u8 data_sync_map;
-} __packed;
-
-/* WMI_CREATE_PSTREAM_CMDID */
-struct wmi_create_pstream_cmd {
- /* msec */
- __le32 min_service_int;
-
- /* msec */
- __le32 max_service_int;
-
- /* msec */
- __le32 inactivity_int;
-
- /* msec */
- __le32 suspension_int;
-
- __le32 service_start_time;
-
- /* in bps */
- __le32 min_data_rate;
-
- /* in bps */
- __le32 mean_data_rate;
-
- /* in bps */
- __le32 peak_data_rate;
-
- __le32 max_burst_size;
- __le32 delay_bound;
-
- /* in bps */
- __le32 min_phy_rate;
-
- __le32 sba;
- __le32 medium_time;
-
- /* in octects */
- __le16 nominal_msdu;
-
- /* in octects */
- __le16 max_msdu;
-
- u8 traffic_class;
-
- /* see, enum dir_type */
- u8 traffic_direc;
-
- u8 rx_queue_num;
-
- /* see, enum traffic_type */
- u8 traffic_type;
-
- /* see, enum voiceps_cap_type */
- u8 voice_psc_cap;
- u8 tsid;
-
- /* 802.1D user priority */
- u8 user_pri;
-
- /* nominal phy rate */
- u8 nominal_phy;
-} __packed;
-
-/* WMI_DELETE_PSTREAM_CMDID */
-struct wmi_delete_pstream_cmd {
- u8 tx_queue_num;
- u8 rx_queue_num;
- u8 traffic_direc;
- u8 traffic_class;
- u8 tsid;
-} __packed;
-
-/* WMI_SET_CHANNEL_PARAMS_CMDID */
-enum wmi_phy_mode {
- WMI_11A_MODE = 0x1,
- WMI_11G_MODE = 0x2,
- WMI_11AG_MODE = 0x3,
- WMI_11B_MODE = 0x4,
- WMI_11GONLY_MODE = 0x5,
-};
-
-#define WMI_MAX_CHANNELS 32
-
-/*
- * WMI_RSSI_THRESHOLD_PARAMS_CMDID
- * Setting the polltime to 0 would disable polling. Threshold values are
- * in the ascending order, and should agree to:
- * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
- * < highThreshold_upperVal)
- */
-
-struct wmi_rssi_threshold_params_cmd {
- /* polling time as a factor of LI */
- __le32 poll_time;
-
- /* lowest of upper */
- a_sle16 thresh_above1_val;
-
- a_sle16 thresh_above2_val;
- a_sle16 thresh_above3_val;
- a_sle16 thresh_above4_val;
- a_sle16 thresh_above5_val;
-
- /* highest of upper */
- a_sle16 thresh_above6_val;
-
- /* lowest of bellow */
- a_sle16 thresh_below1_val;
-
- a_sle16 thresh_below2_val;
- a_sle16 thresh_below3_val;
- a_sle16 thresh_below4_val;
- a_sle16 thresh_below5_val;
-
- /* highest of bellow */
- a_sle16 thresh_below6_val;
-
- /* "alpha" */
- u8 weight;
-
- u8 reserved[3];
-} __packed;
-
-/*
- * WMI_SNR_THRESHOLD_PARAMS_CMDID
- * Setting the polltime to 0 would disable polling.
- */
-
-struct wmi_snr_threshold_params_cmd {
- /* polling time as a factor of LI */
- __le32 poll_time;
-
- /* "alpha" */
- u8 weight;
-
- /* lowest of uppper */
- u8 thresh_above1_val;
-
- u8 thresh_above2_val;
- u8 thresh_above3_val;
-
- /* highest of upper */
- u8 thresh_above4_val;
-
- /* lowest of bellow */
- u8 thresh_below1_val;
-
- u8 thresh_below2_val;
- u8 thresh_below3_val;
-
- /* highest of bellow */
- u8 thresh_below4_val;
-
- u8 reserved[3];
-} __packed;
-
-enum wmi_preamble_policy {
- WMI_IGNORE_BARKER_IN_ERP = 0,
- WMI_DONOT_IGNORE_BARKER_IN_ERP
-};
-
-struct wmi_set_lpreamble_cmd {
- u8 status;
- u8 preamble_policy;
-} __packed;
-
-struct wmi_set_rts_cmd {
- __le16 threshold;
-} __packed;
-
-/* WMI_SET_TX_PWR_CMDID */
-struct wmi_set_tx_pwr_cmd {
- /* in dbM units */
- u8 dbM;
-} __packed;
-
-struct wmi_tx_pwr_reply {
- /* in dbM units */
- u8 dbM;
-} __packed;
-
-struct wmi_report_sleep_state_event {
- __le32 sleep_state;
-};
-
-enum wmi_report_sleep_status {
- WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP = 0,
- WMI_REPORT_SLEEP_STATUS_IS_AWAKE
-};
-enum target_event_report_config {
- /* default */
- DISCONN_EVT_IN_RECONN = 0,
-
- NO_DISCONN_EVT_IN_RECONN
-};
-
-struct wmi_mcast_filter_cmd {
- u8 mcast_all_enable;
-} __packed;
-
-#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6
-struct wmi_mcast_filter_add_del_cmd {
- u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE];
-} __packed;
-
-/* Command Replies */
-
-/* WMI_GET_CHANNEL_LIST_CMDID reply */
-struct wmi_channel_list_reply {
- u8 reserved;
-
- /* number of channels in reply */
- u8 num_ch;
-
- /* channel in Mhz */
- __le16 ch_list[1];
-} __packed;
-
-/* List of Events (target to host) */
-enum wmi_event_id {
- WMI_READY_EVENTID = 0x1001,
- WMI_CONNECT_EVENTID,
- WMI_DISCONNECT_EVENTID,
- WMI_BSSINFO_EVENTID,
- WMI_CMDERROR_EVENTID,
- WMI_REGDOMAIN_EVENTID,
- WMI_PSTREAM_TIMEOUT_EVENTID,
- WMI_NEIGHBOR_REPORT_EVENTID,
- WMI_TKIP_MICERR_EVENTID,
- WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
- WMI_REPORT_STATISTICS_EVENTID,
- WMI_RSSI_THRESHOLD_EVENTID,
- WMI_ERROR_REPORT_EVENTID,
- WMI_OPT_RX_FRAME_EVENTID,
- WMI_REPORT_ROAM_TBL_EVENTID,
- WMI_EXTENSION_EVENTID,
- WMI_CAC_EVENTID,
- WMI_SNR_THRESHOLD_EVENTID,
- WMI_LQ_THRESHOLD_EVENTID,
- WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
- WMI_REPORT_ROAM_DATA_EVENTID,
- WMI_TEST_EVENTID,
- WMI_APLIST_EVENTID,
- WMI_GET_WOW_LIST_EVENTID,
- WMI_GET_PMKID_LIST_EVENTID,
- WMI_CHANNEL_CHANGE_EVENTID,
- WMI_PEER_NODE_EVENTID,
- WMI_PSPOLL_EVENTID,
- WMI_DTIMEXPIRY_EVENTID,
- WMI_WLAN_VERSION_EVENTID,
- WMI_SET_PARAMS_REPLY_EVENTID,
- WMI_ADDBA_REQ_EVENTID, /*0x1020 */
- WMI_ADDBA_RESP_EVENTID,
- WMI_DELBA_REQ_EVENTID,
- WMI_TX_COMPLETE_EVENTID,
- WMI_HCI_EVENT_EVENTID,
- WMI_ACL_DATA_EVENTID,
- WMI_REPORT_SLEEP_STATE_EVENTID,
- WMI_REPORT_BTCOEX_STATS_EVENTID,
- WMI_REPORT_BTCOEX_CONFIG_EVENTID,
- WMI_GET_PMK_EVENTID,
-
- /* DFS Events */
- WMI_DFS_HOST_ATTACH_EVENTID,
- WMI_DFS_HOST_INIT_EVENTID,
- WMI_DFS_RESET_DELAYLINES_EVENTID,
- WMI_DFS_RESET_RADARQ_EVENTID,
- WMI_DFS_RESET_AR_EVENTID,
- WMI_DFS_RESET_ARQ_EVENTID,
- WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
- WMI_DFS_SET_BANGRADAR_EVENTID,
- WMI_DFS_SET_DEBUGLEVEL_EVENTID,
- WMI_DFS_PHYERR_EVENTID,
-
- /* CCX Evants */
- WMI_CCX_RM_STATUS_EVENTID,
-
- /* P2P Events */
- WMI_P2P_GO_NEG_RESULT_EVENTID,
-
- WMI_WAC_SCAN_DONE_EVENTID,
- WMI_WAC_REPORT_BSS_EVENTID,
- WMI_WAC_START_WPS_EVENTID,
- WMI_WAC_CTRL_REQ_REPLY_EVENTID,
-
- WMI_REPORT_WMM_PARAMS_EVENTID,
- WMI_WAC_REJECT_WPS_EVENTID,
-
- /* More P2P Events */
- WMI_P2P_GO_NEG_REQ_EVENTID,
- WMI_P2P_INVITE_REQ_EVENTID,
- WMI_P2P_INVITE_RCVD_RESULT_EVENTID,
- WMI_P2P_INVITE_SENT_RESULT_EVENTID,
- WMI_P2P_PROV_DISC_RESP_EVENTID,
- WMI_P2P_PROV_DISC_REQ_EVENTID,
-
- /* RFKILL Events */
- WMI_RFKILL_STATE_CHANGE_EVENTID,
- WMI_RFKILL_GET_MODE_CMD_EVENTID,
-
- WMI_P2P_START_SDPD_EVENTID,
- WMI_P2P_SDPD_RX_EVENTID,
-
- WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047,
-
- WMI_THIN_RESERVED_START_EVENTID = 0x8000,
- /* Events in this range are reserved for thinmode */
- WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
-
- WMI_SET_CHANNEL_EVENTID,
- WMI_ASSOC_REQ_EVENTID,
-
- /* Generic ACS event */
- WMI_ACS_EVENTID,
- WMI_STORERECALL_STORE_EVENTID,
- WMI_WOW_EXT_WAKE_EVENTID,
- WMI_GTK_OFFLOAD_STATUS_EVENTID,
- WMI_NETWORK_LIST_OFFLOAD_EVENTID,
- WMI_REMAIN_ON_CHNL_EVENTID,
- WMI_CANCEL_REMAIN_ON_CHNL_EVENTID,
- WMI_TX_STATUS_EVENTID,
- WMI_RX_PROBE_REQ_EVENTID,
- WMI_P2P_CAPABILITIES_EVENTID,
- WMI_RX_ACTION_EVENTID,
- WMI_P2P_INFO_EVENTID,
-};
-
-struct wmi_ready_event_2 {
- __le32 sw_version;
- __le32 abi_version;
- u8 mac_addr[ETH_ALEN];
- u8 phy_cap;
-} __packed;
-
-/* Connect Event */
-struct wmi_connect_event {
- union {
- struct {
- __le16 ch;
- u8 bssid[ETH_ALEN];
- __le16 listen_intvl;
- __le16 beacon_intvl;
- __le32 nw_type;
- } sta;
- struct {
- u8 phymode;
- u8 aid;
- u8 mac_addr[ETH_ALEN];
- u8 auth;
- u8 keymgmt;
- __le16 cipher;
- u8 apsd_info;
- u8 unused[3];
- } ap_sta;
- struct {
- __le16 ch;
- u8 bssid[ETH_ALEN];
- u8 unused[8];
- } ap_bss;
- } u;
- u8 beacon_ie_len;
- u8 assoc_req_len;
- u8 assoc_resp_len;
- u8 assoc_info[1];
-} __packed;
-
-/* Disconnect Event */
-enum wmi_disconnect_reason {
- NO_NETWORK_AVAIL = 0x01,
-
- /* bmiss */
- LOST_LINK = 0x02,
-
- DISCONNECT_CMD = 0x03,
- BSS_DISCONNECTED = 0x04,
- AUTH_FAILED = 0x05,
- ASSOC_FAILED = 0x06,
- NO_RESOURCES_AVAIL = 0x07,
- CSERV_DISCONNECT = 0x08,
- INVALID_PROFILE = 0x0a,
- DOT11H_CHANNEL_SWITCH = 0x0b,
- PROFILE_MISMATCH = 0x0c,
- CONNECTION_EVICTED = 0x0d,
- IBSS_MERGE = 0xe,
-};
-
-#define ATH6KL_COUNTRY_RD_SHIFT 16
-
-struct ath6kl_wmi_regdomain {
- __le32 reg_code;
-};
-
-struct wmi_disconnect_event {
- /* reason code, see 802.11 spec. */
- __le16 proto_reason_status;
-
- /* set if known */
- u8 bssid[ETH_ALEN];
-
- /* see WMI_DISCONNECT_REASON */
- u8 disconn_reason;
-
- u8 assoc_resp_len;
- u8 assoc_info[1];
-} __packed;
-
-/*
- * BSS Info Event.
- * Mechanism used to inform host of the presence and characteristic of
- * wireless networks present. Consists of bss info header followed by
- * the beacon or probe-response frame body. The 802.11 header is no included.
- */
-enum wmi_bi_ftype {
- BEACON_FTYPE = 0x1,
- PROBERESP_FTYPE,
- ACTION_MGMT_FTYPE,
- PROBEREQ_FTYPE,
-};
-
-#ifdef CONFIG_MACH_PX
-#define DEF_LRSSI_SCAN_PERIOD ( 5 * 1000 )
-#else
-#define DEF_LRSSI_SCAN_PERIOD 5
-#endif
-#define DEF_LRSSI_ROAM_THRESHOLD 20
-#define DEF_LRSSI_ROAM_FLOOR 60
-#ifdef CONFIG_MACH_PX
-#define DEF_SCAN_FOR_ROAM_INTVL 5
-#else
-#define DEF_SCAN_FOR_ROAM_INTVL 2
-#endif
-
-enum wmi_roam_ctrl {
- WMI_FORCE_ROAM = 1,
- WMI_SET_ROAM_MODE,
- WMI_SET_HOST_BIAS,
- WMI_SET_LRSSI_SCAN_PARAMS,
-};
-
-enum wmi_roam_mode {
- WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based roam */
- WMI_HOST_BIAS_ROAM_MODE = 2, /* Host bias based roam */
- WMI_LOCK_BSS_MODE = 3, /* Lock to the current BSS */
-};
-
-struct bss_bias {
- u8 bssid[ETH_ALEN];
- s8 bias;
-} __packed;
-
-struct bss_bias_info {
- u8 num_bss;
- struct bss_bias bss_bias[0];
-} __packed;
-
-struct low_rssi_scan_params {
- __le16 lrssi_scan_period;
- a_sle16 lrssi_scan_threshold;
- a_sle16 lrssi_roam_threshold;
- u8 roam_rssi_floor;
- u8 reserved[1];
-} __packed;
-
-struct roam_ctrl_cmd {
- union {
- u8 bssid[ETH_ALEN]; /* WMI_FORCE_ROAM */
- u8 roam_mode; /* WMI_SET_ROAM_MODE */
- struct bss_bias_info bss; /* WMI_SET_HOST_BIAS */
- struct low_rssi_scan_params params; /* WMI_SET_LRSSI_SCAN_PARAMS
- */
- } __packed info;
- u8 roam_ctrl;
-} __packed;
-
-/* BSS INFO HDR version 2.0 */
-struct wmi_bss_info_hdr2 {
- __le16 ch; /* frequency in MHz */
-
- /* see, enum wmi_bi_ftype */
- u8 frame_type;
-
- u8 snr; /* note: rssi = snr - 95 dBm */
- u8 bssid[ETH_ALEN];
- __le16 ie_mask;
-} __packed;
-
-/* Command Error Event */
-enum wmi_error_code {
- INVALID_PARAM = 0x01,
- ILLEGAL_STATE = 0x02,
- INTERNAL_ERROR = 0x03,
-};
-
-struct wmi_cmd_error_event {
- __le16 cmd_id;
- u8 err_code;
-} __packed;
-
-struct wmi_pstream_timeout_event {
- u8 tx_queue_num;
- u8 rx_queue_num;
- u8 traffic_direc;
- u8 traffic_class;
-} __packed;
-
-/*
- * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
- * the host of BSS's it has found that matches the current profile.
- * It can be used by the host to cache PMKs and/to initiate pre-authentication
- * if the BSS supports it. The first bssid is always the current associated
- * BSS.
- * The bssid and bssFlags information repeats according to the number
- * or APs reported.
- */
-enum wmi_bss_flags {
- WMI_DEFAULT_BSS_FLAGS = 0x00,
- WMI_PREAUTH_CAPABLE_BSS = 0x01,
- WMI_PMKID_VALID_BSS = 0x02,
-};
-
-struct wmi_neighbor_info {
- u8 bssid[ETH_ALEN];
- u8 bss_flags; /* enum wmi_bss_flags */
-} __packed;
-
-struct wmi_neighbor_report_event {
- u8 num_neighbors;
- struct wmi_neighbor_info neighbor[0];
-} __packed;
-
-/* TKIP MIC Error Event */
-struct wmi_tkip_micerr_event {
- u8 key_id;
- u8 is_mcast;
-} __packed;
-
-enum wmi_scan_status {
- WMI_SCAN_STATUS_SUCCESS = 0,
-};
-
-/* WMI_SCAN_COMPLETE_EVENTID */
-struct wmi_scan_complete_event {
- a_sle32 status;
-} __packed;
-
-#define MAX_OPT_DATA_LEN 1400
-
-/*
- * Special frame receive Event.
- * Mechanism used to inform host of the receiption of the special frames.
- * Consists of special frame info header followed by special frame body.
- * The 802.11 header is not included.
- */
-struct wmi_opt_rx_info_hdr {
- __le16 ch;
- u8 frame_type;
- s8 snr;
- u8 src_addr[ETH_ALEN];
- u8 bssid[ETH_ALEN];
-} __packed;
-
-/* Reporting statistic */
-struct tx_stats {
- __le32 pkt;
- __le32 byte;
- __le32 ucast_pkt;
- __le32 ucast_byte;
- __le32 mcast_pkt;
- __le32 mcast_byte;
- __le32 bcast_pkt;
- __le32 bcast_byte;
- __le32 rts_success_cnt;
- __le32 pkt_per_ac[4];
- __le32 err_per_ac[4];
-
- __le32 err;
- __le32 fail_cnt;
- __le32 retry_cnt;
- __le32 mult_retry_cnt;
- __le32 rts_fail_cnt;
- a_sle32 ucast_rate;
-} __packed;
-
-struct rx_stats {
- __le32 pkt;
- __le32 byte;
- __le32 ucast_pkt;
- __le32 ucast_byte;
- __le32 mcast_pkt;
- __le32 mcast_byte;
- __le32 bcast_pkt;
- __le32 bcast_byte;
- __le32 frgment_pkt;
-
- __le32 err;
- __le32 crc_err;
- __le32 key_cache_miss;
- __le32 decrypt_err;
- __le32 dupl_frame;
- a_sle32 ucast_rate;
-} __packed;
-
-struct tkip_ccmp_stats {
- __le32 tkip_local_mic_fail;
- __le32 tkip_cnter_measures_invoked;
- __le32 tkip_replays;
- __le32 tkip_fmt_err;
- __le32 ccmp_fmt_err;
- __le32 ccmp_replays;
-} __packed;
-
-struct pm_stats {
- __le32 pwr_save_failure_cnt;
- __le16 stop_tx_failure_cnt;
- __le16 atim_tx_failure_cnt;
- __le16 atim_rx_failure_cnt;
- __le16 bcn_rx_failure_cnt;
-} __packed;
-
-struct cserv_stats {
- __le32 cs_bmiss_cnt;
- __le32 cs_low_rssi_cnt;
- __le16 cs_connect_cnt;
- __le16 cs_discon_cnt;
- a_sle16 cs_ave_beacon_rssi;
- __le16 cs_roam_count;
- a_sle16 cs_rssi;
- u8 cs_snr;
- u8 cs_ave_beacon_snr;
- u8 cs_last_roam_msec;
-} __packed;
-
-struct wlan_net_stats {
- struct tx_stats tx;
- struct rx_stats rx;
- struct tkip_ccmp_stats tkip_ccmp_stats;
-} __packed;
-
-struct arp_stats {
- __le32 arp_received;
- __le32 arp_matched;
- __le32 arp_replied;
-} __packed;
-
-struct wlan_wow_stats {
- __le32 wow_pkt_dropped;
- __le16 wow_evt_discarded;
- u8 wow_host_pkt_wakeups;
- u8 wow_host_evt_wakeups;
-} __packed;
-
-struct wmi_target_stats {
- __le32 lq_val;
- a_sle32 noise_floor_calib;
- struct pm_stats pm_stats;
- struct wlan_net_stats stats;
- struct wlan_wow_stats wow_stats;
- struct arp_stats arp_stats;
- struct cserv_stats cserv_stats;
-} __packed;
-
-/*
- * WMI_RSSI_THRESHOLD_EVENTID.
- * Indicate the RSSI events to host. Events are indicated when we breach a
- * thresold value.
- */
-enum wmi_rssi_threshold_val {
- WMI_RSSI_THRESHOLD1_ABOVE = 0,
- WMI_RSSI_THRESHOLD2_ABOVE,
- WMI_RSSI_THRESHOLD3_ABOVE,
- WMI_RSSI_THRESHOLD4_ABOVE,
- WMI_RSSI_THRESHOLD5_ABOVE,
- WMI_RSSI_THRESHOLD6_ABOVE,
- WMI_RSSI_THRESHOLD1_BELOW,
- WMI_RSSI_THRESHOLD2_BELOW,
- WMI_RSSI_THRESHOLD3_BELOW,
- WMI_RSSI_THRESHOLD4_BELOW,
- WMI_RSSI_THRESHOLD5_BELOW,
- WMI_RSSI_THRESHOLD6_BELOW
-};
-
-struct wmi_rssi_threshold_event {
- a_sle16 rssi;
- u8 range;
-} __packed;
-
-enum wmi_snr_threshold_val {
- WMI_SNR_THRESHOLD1_ABOVE = 1,
- WMI_SNR_THRESHOLD1_BELOW,
- WMI_SNR_THRESHOLD2_ABOVE,
- WMI_SNR_THRESHOLD2_BELOW,
- WMI_SNR_THRESHOLD3_ABOVE,
- WMI_SNR_THRESHOLD3_BELOW,
- WMI_SNR_THRESHOLD4_ABOVE,
- WMI_SNR_THRESHOLD4_BELOW
-};
-
-struct wmi_snr_threshold_event {
- /* see, enum wmi_snr_threshold_val */
- u8 range;
-
- u8 snr;
-} __packed;
-
-/* WMI_REPORT_ROAM_TBL_EVENTID */
-#define MAX_ROAM_TBL_CAND 5
-
-struct wmi_bss_roam_info {
- a_sle32 roam_util;
- u8 bssid[ETH_ALEN];
- s8 rssi;
- s8 rssidt;
- s8 last_rssi;
- s8 util;
- s8 bias;
-
- /* for alignment */
- u8 reserved;
-} __packed;
-
-struct wmi_target_roam_tbl {
- __le16 roam_mode;
- __le16 num_entries;
- struct wmi_bss_roam_info info[];
-} __packed;
-
-/* WMI_CAC_EVENTID */
-enum cac_indication {
- CAC_INDICATION_ADMISSION = 0x00,
- CAC_INDICATION_ADMISSION_RESP = 0x01,
- CAC_INDICATION_DELETE = 0x02,
- CAC_INDICATION_NO_RESP = 0x03,
-};
-
-#define WMM_TSPEC_IE_LEN 63
-
-struct wmi_cac_event {
- u8 ac;
- u8 cac_indication;
- u8 status_code;
- u8 tspec_suggestion[WMM_TSPEC_IE_LEN];
-} __packed;
-
-/* WMI_APLIST_EVENTID */
-
-enum aplist_ver {
- APLIST_VER1 = 1,
-};
-
-struct wmi_ap_info_v1 {
- u8 bssid[ETH_ALEN];
- __le16 channel;
-} __packed;
-
-union wmi_ap_info {
- struct wmi_ap_info_v1 ap_info_v1;
-} __packed;
-
-struct wmi_aplist_event {
- u8 ap_list_ver;
- u8 num_ap;
- union wmi_ap_info ap_list[1];
-} __packed;
-
-/* Developer Commands */
-
-/*
- * WMI_SET_BITRATE_CMDID
- *
- * Get bit rate cmd uses same definition as set bit rate cmd
- */
-enum wmi_bit_rate {
- RATE_AUTO = -1,
- RATE_1Mb = 0,
- RATE_2Mb = 1,
- RATE_5_5Mb = 2,
- RATE_11Mb = 3,
- RATE_6Mb = 4,
- RATE_9Mb = 5,
- RATE_12Mb = 6,
- RATE_18Mb = 7,
- RATE_24Mb = 8,
- RATE_36Mb = 9,
- RATE_48Mb = 10,
- RATE_54Mb = 11,
- RATE_MCS_0_20 = 12,
- RATE_MCS_1_20 = 13,
- RATE_MCS_2_20 = 14,
- RATE_MCS_3_20 = 15,
- RATE_MCS_4_20 = 16,
- RATE_MCS_5_20 = 17,
- RATE_MCS_6_20 = 18,
- RATE_MCS_7_20 = 19,
- RATE_MCS_0_40 = 20,
- RATE_MCS_1_40 = 21,
- RATE_MCS_2_40 = 22,
- RATE_MCS_3_40 = 23,
- RATE_MCS_4_40 = 24,
- RATE_MCS_5_40 = 25,
- RATE_MCS_6_40 = 26,
- RATE_MCS_7_40 = 27,
-};
-
-struct wmi_bit_rate_reply {
- /* see, enum wmi_bit_rate */
- s8 rate_index;
-} __packed;
-
-/*
- * WMI_SET_FIXRATES_CMDID
- *
- * Get fix rates cmd uses same definition as set fix rates cmd
- */
-struct wmi_fix_rates_reply {
- /* see wmi_bit_rate */
- __le32 fix_rate_mask;
-} __packed;
-
-enum roam_data_type {
- /* get the roam time data */
- ROAM_DATA_TIME = 1,
-};
-
-struct wmi_target_roam_time {
- __le32 disassoc_time;
- __le32 no_txrx_time;
- __le32 assoc_time;
- __le32 allow_txrx_time;
- u8 disassoc_bssid[ETH_ALEN];
- s8 disassoc_bss_rssi;
- u8 assoc_bssid[ETH_ALEN];
- s8 assoc_bss_rssi;
-} __packed;
-
-enum wmi_txop_cfg {
- WMI_TXOP_DISABLED = 0,
- WMI_TXOP_ENABLED
-};
-
-struct wmi_set_wmm_txop_cmd {
- u8 txop_enable;
-} __packed;
-
-struct wmi_set_keepalive_cmd {
- u8 keep_alive_intvl;
-} __packed;
-
-struct wmi_get_keepalive_cmd {
- __le32 configured;
- u8 keep_alive_intvl;
-} __packed;
-
-struct wmi_set_mcastrate_cmd {
- u16 bitrate;
-} __packed;
-
-struct wmi_set_appie_cmd {
- u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
- u8 ie_len;
- u8 ie_info[0];
-} __packed;
-
-struct wmi_set_ie_cmd {
- u8 ie_id;
- u8 ie_field; /* enum wmi_ie_field_type */
- u8 ie_len;
- u8 reserved;
- u8 ie_info[0];
-} __packed;
-
-/* Notify the WSC registration status to the target */
-#define WSC_REG_ACTIVE 1
-#define WSC_REG_INACTIVE 0
-
-#define WOW_MAX_FILTERS_PER_LIST 4
-#define WOW_PATTERN_SIZE 64
-#define WOW_MASK_SIZE 64
-
-#define MAC_MAX_FILTERS_PER_LIST 4
-
-struct wow_filter {
- u8 wow_valid_filter;
- u8 wow_filter_id;
- u8 wow_filter_size;
- u8 wow_filter_offset;
- u8 wow_filter_mask[WOW_MASK_SIZE];
- u8 wow_filter_pattern[WOW_PATTERN_SIZE];
-} __packed;
-
-#define MAX_IP_ADDRS 2
-
-struct wmi_set_ip_cmd {
- /* IP in network byte order */
- __be32 ips[MAX_IP_ADDRS];
-} __packed;
-
-enum ath6kl_wow_filters {
- WOW_FILTER_SSID = BIT(1),
- WOW_FILTER_OPTION_MAGIC_PACKET = BIT(2),
- WOW_FILTER_OPTION_EAP_REQ = BIT(3),
- WOW_FILTER_OPTION_PATTERNS = BIT(4),
- WOW_FILTER_OPTION_OFFLOAD_ARP = BIT(5),
- WOW_FILTER_OPTION_OFFLOAD_NS = BIT(6),
- WOW_FILTER_OPTION_OFFLOAD_GTK = BIT(7),
- WOW_FILTER_OPTION_8021X_4WAYHS = BIT(8),
- WOW_FILTER_OPTION_NLO_DISCVRY = BIT(9),
- WOW_FILTER_OPTION_NWK_DISASSOC = BIT(10),
- WOW_FILTER_OPTION_GTK_ERROR = BIT(11),
- WOW_FILTER_OPTION_TEST_MODE = BIT(15),
-};
-
-enum ath6kl_host_mode {
- ATH6KL_HOST_MODE_AWAKE,
- ATH6KL_HOST_MODE_ASLEEP,
-};
-
-struct wmi_set_host_sleep_mode_cmd {
- __le32 awake;
- __le32 asleep;
-} __packed;
-
-enum ath6kl_wow_mode {
- ATH6KL_WOW_MODE_DISABLE,
- ATH6KL_WOW_MODE_ENABLE,
-};
-
-struct wmi_set_wow_mode_cmd {
- __le32 enable_wow;
- __le32 filter;
- __le16 host_req_delay;
-} __packed;
-
-struct wmi_add_wow_pattern_cmd {
- u8 filter_list_id;
- u8 filter_size;
- u8 filter_offset;
- u8 filter[0];
-} __packed;
-
-struct wmi_del_wow_pattern_cmd {
- __le16 filter_list_id;
- __le16 filter_id;
-} __packed;
-
-/* WMI_SET_AKMP_PARAMS_CMD */
-
-struct wmi_pmkid {
- u8 pmkid[WMI_PMKID_LEN];
-} __packed;
-
-/* WMI_GET_PMKID_LIST_CMD Reply */
-struct wmi_pmkid_list_reply {
- __le32 num_pmkid;
- u8 bssid_list[ETH_ALEN][1];
- struct wmi_pmkid pmkid_list[1];
-} __packed;
-
-/* WMI_ADDBA_REQ_EVENTID */
-struct wmi_addba_req_event {
- u8 tid;
- u8 win_sz;
- __le16 st_seq_no;
-
- /* f/w response for ADDBA Req; OK (0) or failure (!=0) */
- u8 status;
-} __packed;
-
-/* WMI_ADDBA_RESP_EVENTID */
-struct wmi_addba_resp_event {
- u8 tid;
-
- /* OK (0), failure (!=0) */
- u8 status;
-
- /* three values: not supported(0), 3839, 8k */
- __le16 amsdu_sz;
-} __packed;
-
-/* WMI_DELBA_EVENTID
- * f/w received a DELBA for peer and processed it.
- * Host is notified of this
- */
-struct wmi_delba_event {
- u8 tid;
- u8 is_peer_initiator;
- __le16 reason_code;
-} __packed;
-
-#define PEER_NODE_JOIN_EVENT 0x00
-#define PEER_NODE_LEAVE_EVENT 0x01
-#define PEER_FIRST_NODE_JOIN_EVENT 0x10
-#define PEER_LAST_NODE_LEAVE_EVENT 0x11
-
-struct wmi_peer_node_event {
- u8 event_code;
- u8 peer_mac_addr[ETH_ALEN];
-} __packed;
-
-/* Transmit complete event data structure(s) */
-
-/* version 1 of tx complete msg */
-struct tx_complete_msg_v1 {
-#define TX_COMPLETE_STATUS_SUCCESS 0
-#define TX_COMPLETE_STATUS_RETRIES 1
-#define TX_COMPLETE_STATUS_NOLINK 2
-#define TX_COMPLETE_STATUS_TIMEOUT 3
-#define TX_COMPLETE_STATUS_OTHER 4
-
- u8 status;
-
- /* packet ID to identify parent packet */
- u8 pkt_id;
-
- /* rate index on successful transmission */
- u8 rate_idx;
-
- /* number of ACK failures in tx attempt */
- u8 ack_failures;
-} __packed;
-
-struct wmi_tx_complete_event {
- /* no of tx comp msgs following this struct */
- u8 num_msg;
-
- /* length in bytes for each individual msg following this struct */
- u8 msg_len;
-
- /* version of tx complete msg data following this struct */
- u8 msg_type;
-
- /* individual messages follow this header */
- u8 reserved;
-} __packed;
-
-/*
- * ------- AP Mode definitions --------------
- */
-
-/*
- * !!! Warning !!!
- * -Changing the following values needs compilation of both driver and firmware
- */
-#define AP_MAX_NUM_STA 10
-
-/* Spl. AID used to set DTIM flag in the beacons */
-#define MCAST_AID 0xFF
-
-#define DEF_AP_COUNTRY_CODE "US "
-
-/* Used with WMI_AP_SET_NUM_STA_CMDID */
-
-/*
- * Used with WMI_AP_SET_MLME_CMDID
- */
-
-/* MLME Commands */
-#define WMI_AP_MLME_ASSOC 1 /* associate station */
-#define WMI_AP_DISASSOC 2 /* disassociate station */
-#define WMI_AP_DEAUTH 3 /* deauthenticate station */
-#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */
-#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */
-
-struct wmi_ap_set_mlme_cmd {
- u8 mac[ETH_ALEN];
- __le16 reason; /* 802.11 reason code */
- u8 cmd; /* operation to perform (WMI_AP_*) */
-} __packed;
-
-struct wmi_ap_set_pvb_cmd {
- __le32 flag;
- __le16 rsvd;
- __le16 aid;
-} __packed;
-
-struct wmi_rx_frame_format_cmd {
- /* version of meta data for rx packets <0 = default> (0-7 = valid) */
- u8 meta_ver;
-
- /*
- * 1 == leave .11 header intact,
- * 0 == replace .11 header with .3 <default>
- */
- u8 dot11_hdr;
-
- /*
- * 1 == defragmentation is performed by host,
- * 0 == performed by target <default>
- */
- u8 defrag_on_host;
-
- /* for alignment */
- u8 reserved[1];
-} __packed;
-
-struct wmi_ap_hidden_ssid_cmd {
- u8 hidden_ssid;
-} __packed;
-
-/* AP mode events */
-struct wmi_ap_set_apsd_cmd {
- u8 enable;
-} __packed;
-
-enum wmi_ap_apsd_buffered_traffic_flags {
- WMI_AP_APSD_NO_DELIVERY_FRAMES = 0x1,
-};
-
-struct wmi_ap_apsd_buffered_traffic_cmd {
- __le16 aid;
- __le16 bitmap;
- __le32 flags;
-} __packed;
-
-/* WMI_PS_POLL_EVENT */
-struct wmi_pspoll_event {
- __le16 aid;
-} __packed;
-
-struct wmi_per_sta_stat {
- __le32 tx_bytes;
- __le32 tx_pkts;
- __le32 tx_error;
- __le32 tx_discard;
- __le32 rx_bytes;
- __le32 rx_pkts;
- __le32 rx_error;
- __le32 rx_discard;
- __le32 aid;
-} __packed;
-
-struct wmi_ap_mode_stat {
- __le32 action;
- struct wmi_per_sta_stat sta[AP_MAX_NUM_STA + 1];
-} __packed;
-
-/* End of AP mode definitions */
-
-struct wmi_remain_on_chnl_cmd {
- __le32 freq;
- __le32 duration;
-} __packed;
-
-/* wmi_send_action_cmd is to be deprecated. Use
- * wmi_send_mgmt_cmd instead. The new structure supports P2P mgmt
- * operations using station interface.
- */
-struct wmi_send_action_cmd {
- __le32 id;
- __le32 freq;
- __le32 wait;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_send_mgmt_cmd {
- __le32 id;
- __le32 freq;
- __le32 wait;
- __le32 no_cck;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_tx_status_event {
- __le32 id;
- u8 ack_status;
-} __packed;
-
-struct wmi_probe_req_report_cmd {
- u8 enable;
-} __packed;
-
-struct wmi_disable_11b_rates_cmd {
- u8 disable;
-} __packed;
-
-struct wmi_set_appie_extended_cmd {
- u8 role_id;
- u8 mgmt_frm_type;
- u8 ie_len;
- u8 ie_info[0];
-} __packed;
-
-struct wmi_remain_on_chnl_event {
- __le32 freq;
- __le32 duration;
-} __packed;
-
-struct wmi_cancel_remain_on_chnl_event {
- __le32 freq;
- __le32 duration;
- u8 status;
-} __packed;
-
-struct wmi_rx_action_event {
- __le32 freq;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_capabilities_event {
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_rx_probe_req_event {
- __le32 freq;
- __le16 len;
- u8 data[0];
-} __packed;
-
-#define P2P_FLAG_CAPABILITIES_REQ (0x00000001)
-#define P2P_FLAG_MACADDR_REQ (0x00000002)
-#define P2P_FLAG_HMODEL_REQ (0x00000002)
-
-struct wmi_get_p2p_info {
- __le32 info_req_flags;
-} __packed;
-
-struct wmi_p2p_info_event {
- __le32 info_req_flags;
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_p2p_capabilities {
- u8 go_power_save;
-} __packed;
-
-struct wmi_p2p_macaddr {
- u8 mac_addr[ETH_ALEN];
-} __packed;
-
-struct wmi_p2p_hmodel {
- u8 p2p_model;
-} __packed;
-
-struct wmi_p2p_probe_response_cmd {
- __le32 freq;
- u8 destination_addr[ETH_ALEN];
- __le16 len;
- u8 data[0];
-} __packed;
-
-struct wmi_set_ht_cap_cmd {
- u8 band;
- u8 enable;
- u8 chan_width_40m_supported;
- u8 short_gi_20mhz;
- u8 short_gi_40mhz;
- u8 intolerance_40mhz;
- u8 max_ampdu_len_exp;
-} __packed;
-
-
-/* Extended WMI (WMIX)
- *
- * Extended WMIX commands are encapsulated in a WMI message with
- * cmd=WMI_EXTENSION_CMD.
- *
- * Extended WMI commands are those that are needed during wireless
- * operation, but which are not really wireless commands. This allows,
- * for instance, platform-specific commands. Extended WMI commands are
- * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
- * Extended WMI events are similarly embedded in a WMI event message with
- * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
- */
-struct wmix_cmd_hdr {
- __le32 cmd_id;
-} __packed;
-
-enum wmix_command_id {
- WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
- WMIX_DSETDATA_REPLY_CMDID,
- WMIX_GPIO_OUTPUT_SET_CMDID,
- WMIX_GPIO_INPUT_GET_CMDID,
- WMIX_GPIO_REGISTER_SET_CMDID,
- WMIX_GPIO_REGISTER_GET_CMDID,
- WMIX_GPIO_INTR_ACK_CMDID,
- WMIX_HB_CHALLENGE_RESP_CMDID,
- WMIX_DBGLOG_CFG_MODULE_CMDID,
- WMIX_PROF_CFG_CMDID, /* 0x200a */
- WMIX_PROF_ADDR_SET_CMDID,
- WMIX_PROF_START_CMDID,
- WMIX_PROF_STOP_CMDID,
- WMIX_PROF_COUNT_GET_CMDID,
-};
-
-enum wmix_event_id {
- WMIX_DSETOPENREQ_EVENTID = 0x3001,
- WMIX_DSETCLOSE_EVENTID,
- WMIX_DSETDATAREQ_EVENTID,
- WMIX_GPIO_INTR_EVENTID,
- WMIX_GPIO_DATA_EVENTID,
- WMIX_GPIO_ACK_EVENTID,
- WMIX_HB_CHALLENGE_RESP_EVENTID,
- WMIX_DBGLOG_EVENTID,
- WMIX_PROF_COUNT_EVENTID,
-};
-
-/*
- * ------Error Detection support-------
- */
-
-/*
- * WMIX_HB_CHALLENGE_RESP_CMDID
- * Heartbeat Challenge Response command
- */
-struct wmix_hb_challenge_resp_cmd {
- __le32 cookie;
- __le32 source;
-} __packed;
-
-struct ath6kl_wmix_dbglog_cfg_module_cmd {
- __le32 valid;
- __le32 config;
-} __packed;
-
-/* End of Extended WMI (WMIX) */
-
-enum wmi_sync_flag {
- NO_SYNC_WMIFLAG = 0,
-
- /* transmit all queued data before cmd */
- SYNC_BEFORE_WMIFLAG,
-
- /* any new data waits until cmd execs */
- SYNC_AFTER_WMIFLAG,
-
- SYNC_BOTH_WMIFLAG,
-
- /* end marker */
- END_WMIFLAG
-};
-
-enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
-void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
-int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
-int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
- u8 msg_type, u32 flags,
- enum wmi_data_hdr_data_type data_type,
- u8 meta_ver, void *tx_meta_info, u8 if_idx);
-
-int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
-int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
-int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
- struct sk_buff *skb, u32 layer2_priority,
- bool wmm_enabled, u8 *ac);
-
-int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
-
-int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb,
- enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
-
-int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx,
- enum network_type nw_type,
- enum dot11_auth_mode dot11_auth_mode,
- enum auth_mode auth_mode,
- enum crypto_type pairwise_crypto,
- u8 pairwise_crypto_len,
- enum crypto_type group_crypto,
- u8 group_crypto_len, int ssid_len, u8 *ssid,
- u8 *bssid, u16 channel, u32 ctrl_flags,
- u8 nw_subtype);
-
-int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid,
- u16 channel);
-int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx);
-int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx,
- enum wmi_scan_type scan_type,
- u32 force_fgscan, u32 is_legacy,
- u32 home_dwell_time, u32 force_scan_interval,
- s8 num_chan, u16 *ch_list);
-
-int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
- enum wmi_scan_type scan_type,
- u32 force_fgscan, u32 is_legacy,
- u32 home_dwell_time, u32 force_scan_interval,
- s8 num_chan, u16 *ch_list, u32 no_cck,
- u32 *rates);
-
-int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec,
- u16 fg_end_sec, u16 bg_sec,
- u16 minact_chdw_msec, u16 maxact_chdw_msec,
- u16 pas_chdw_msec, u8 short_scan_ratio,
- u8 scan_ctrl_flag, u32 max_dfsch_act_time,
- u16 maxact_scan_per_ssid);
-int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 if_idx, u8 filter,
- u32 ie_mask);
-int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag,
- u8 ssid_len, u8 *ssid);
-int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u8 if_idx,
- u16 listen_interval,
- u16 listen_beacons);
-int ath6kl_wmi_mcastrate_cmd(struct wmi *wmi, u8 if_idx,
- u16 bitrate);
-int ath6kl_wmi_bmisstime_cmd(struct wmi *wmi, u8 if_idx,
- u16 bmiss_time,
- u16 bmiss_beacons);
-int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 if_idx, u8 pwr_mode);
-int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u8 if_idx, u16 idle_period,
- u16 ps_poll_num, u16 dtim_policy,
- u16 tx_wakup_policy, u16 num_tx_to_wakeup,
- u16 ps_fail_event_policy);
-int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi, u8 if_idx,
- struct wmi_create_pstream_cmd *pstream);
-int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class,
- u8 tsid);
-int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 if_idx, u8 timeout);
-
-int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
-int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 if_idx, u8 status,
- u8 preamble_policy);
-
-int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
-int ath6kl_wmi_config_debug_module_cmd(struct wmi *wmi, u32 valid, u32 config);
-
-int ath6kl_wmi_get_stats_cmd(struct wmi *wmi, u8 if_idx);
-int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index,
- enum crypto_type key_type,
- u8 key_usage, u8 key_len,
- u8 *key_rsc, unsigned int key_rsc_len,
- u8 *key_material,
- u8 key_op_ctrl, u8 *mac_addr,
- enum wmi_sync_flag sync_flag);
-int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk);
-int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 if_idx, u8 key_index);
-int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, u8 if_idx, const u8 *bssid,
- const u8 *pmkid, bool set);
-int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 if_idx, u8 dbM);
-int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi, u8 if_idx);
-int ath6kl_wmi_get_roam_tbl_cmd(struct wmi *wmi);
-
-int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, u8 if_idx, enum wmi_txop_cfg cfg);
-int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 if_idx,
- u8 keep_alive_intvl);
-int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
-
-s32 ath6kl_wmi_get_rate(s8 rate_index);
-
-int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
- __be32 ips0, __be32 ips1);
-int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx,
- enum ath6kl_host_mode host_mode);
-int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx,
- enum ath6kl_wow_mode wow_mode,
- u32 filter, u16 host_req_delay);
-int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
- u8 list_id, u8 filter_size,
- u8 filter_offset, const u8 *filter,
- const u8 *mask);
-int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx,
- u16 list_id, u16 filter_id);
-int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
-int ath6kl_wmi_set_roam_lrssi_config_cmd(struct wmi *wmi,
- struct low_rssi_scan_params *params);
-int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid);
-int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode);
-int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
-int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
- u8 *filter, bool add_filter);
-int ath6kl_wmi_set_ht_cap_cmd(struct wmi *wmi, u8 if_idx,
- struct wmi_set_ht_cap_cmd *params);
-
-/* AP mode uAPSD */
-int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable);
-
-int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi,
- u8 if_idx, u16 aid,
- u16 bitmap, u32 flags);
-
-int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on);
-int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx,
- u8 *filter, bool add_filter);
-
-u8 ath6kl_wmi_get_traffic_class(u8 user_priority);
-
-u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri);
-/* AP mode */
-int ath6kl_wmi_ap_hidden_ssid(struct wmi *wmi, u8 if_idx, bool enable);
-int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx,
- struct wmi_connect_cmd *p);
-
-int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd,
- const u8 *mac, u16 reason);
-
-int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u8 if_idx, u16 aid, bool flag);
-
-int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 if_idx,
- u8 rx_meta_version,
- bool rx_dot11_hdr, bool defrag_on_host);
-
-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
- const u8 *ie, u8 ie_len);
-
-int ath6kl_wmi_set_ie_cmd(struct wmi *wmi, u8 if_idx, u8 ie_id, u8 ie_field,
- const u8 *ie_info, u8 ie_len);
-
-/* P2P */
-int ath6kl_wmi_disable_11b_rates_cmd(struct wmi *wmi, bool disable);
-
-int ath6kl_wmi_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
- u32 dur);
-
-int ath6kl_wmi_send_mgmt_cmd(struct wmi *wmi, u8 if_idx, u32 id, u32 freq,
- u32 wait, const u8 *data, u16 data_len,
- u32 no_cck);
-
-int ath6kl_wmi_send_probe_response_cmd(struct wmi *wmi, u8 if_idx, u32 freq,
- const u8 *dst, const u8 *data,
- u16 data_len);
-
-int ath6kl_wmi_probe_report_req_cmd(struct wmi *wmi, u8 if_idx, bool enable);
-
-int ath6kl_wmi_info_req_cmd(struct wmi *wmi, u8 if_idx, u32 info_req_flags);
-
-int ath6kl_wmi_cancel_remain_on_chnl_cmd(struct wmi *wmi, u8 if_idx);
-
-int ath6kl_wmi_set_appie_cmd(struct wmi *wmi, u8 if_idx, u8 mgmt_frm_type,
- const u8 *ie, u8 ie_len);
-
-void ath6kl_wmi_sscan_timer(unsigned long ptr);
-
-struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
-void *ath6kl_wmi_init(struct ath6kl *devt);
-void ath6kl_wmi_shutdown(struct wmi *wmi);
-void ath6kl_wmi_reset(struct wmi *wmi);
-
-#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/ath6kl/wmi_btcoex.c b/drivers/net/wireless/ath/ath6kl/wmi_btcoex.c
deleted file mode 100644
index 280522b..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmi_btcoex.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/ip.h>
-#include "core.h"
-#include "wmi_btcoex.h"
-#include "debug.h"
-
-#define BT_COEX_OP_ACTIVE 0x01
-#define BT_COEX_OP_INACTIVE 0x02
-
-#define BT_COEX_DEFAULT_LINK 0x00
-
-static inline struct sk_buff *ath6kl_wmi_btcoex_get_new_buf(u32 size)
-{
- struct sk_buff *skb;
-
- skb = ath6kl_buf_alloc(size);
- if (!skb)
- return NULL;
-
- skb_put(skb, size);
- if (size)
- memset(skb->data, 0, size);
-
- return skb;
-}
-int ath6kl_wmi_set_btcoex_bt_op_status(struct wmi *wmi, u8 op_id, bool flag)
-{
- struct sk_buff *skb;
- struct wmi_btcoex_bt_op_status_cmd *cmd;
- int op_status;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(sizeof
- (struct wmi_btcoex_bt_op_status_cmd));
- if (!skb)
- return -ENOMEM;
-
- if (flag)
- op_status = BT_COEX_OP_ACTIVE;
- else
- op_status = BT_COEX_OP_INACTIVE;
-
- cmd = (struct wmi_btcoex_bt_op_status_cmd *) skb->data;
- cmd->op_type = cpu_to_le32(op_id);
- cmd->op_status = cpu_to_le32(op_status);
- cmd->link_id = cpu_to_le32(BT_COEX_DEFAULT_LINK);
-
- ath6kl_dbg(ATH6KL_DBG_WMI,
- "WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tBT Op status->op_type: %x\n",
- cmd->op_type);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tBT Op status->op_status: %x\n",
- cmd->op_status);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tBT Op status->link_id: %x\n",
- cmd->link_id);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
- NO_SYNC_WMIFLAG);
-}
-static inline int btcoex_get_max_slot(int tx_pkt_len)
-{
- int slot = 2;
-
- if (tx_pkt_len <= 90)
- slot = 1; /* EV3 or 2-EV3 or 3-EV3 */
- else
- slot = 3; /* EV4 or EV5 or 2-EV5 3-EV5 */
-
- slot *= 2;
-
- return slot;
-}
-
-#define SCO_SLOT_DEFAULT 2
-#define SCO_IDLE_SLOT_DEFAULT 4
-#define SCO_FLAGS_DEFAULT 0
-#define SCO_LINK_ID_DEFAULT 0
-#define SCO_CYCLES_FORCE_TRIGGER_DEFAULT 10
-#define SCO_DATA_RES_TIMEOUT_DEFAULT 20
-#define SCO_STOMP_DUTY_CYCLE_DEFAULT 2
-#define SCO_STOMP_DUTY_CYCLE_MAX_DEFAULT 6
-#define SCO_PS_POLL_LATENCY_FRACTION_DEFAULT 2
-#define SCO_STOMP_COUNT_IN_100MS_DEFAULT 3
-#define SCO_CONT_STOMP_MAX_DEFAULT 3
-#define SCO_MIN_RATE_MBPS_DEFAULT 36
-#define SCO_LOW_RATE_CNT_DEFAULT 5
-#define SCO_HI_PKT_RATIO_DEFAULT 5
-#define SCO_MAX_AGGR_SIZE_DEFAULT 1
-#define SCO_SCAN_INTERVAL_DEFAULT 100
-#define SCO_MAX_SCAN_STOMP_CNT_INTERVAL 2
-
-static inline void set_default_sco(struct wmi_set_btcoex_sco_config_cmd *cmd)
-{
- struct btcoex_sco_config *sco_config = &cmd->sco_config;
- struct btcoex_pspoll_mode_sco_config *ppoll_config =
- &cmd->sco_pspoll_config;
- struct btcoex_optmode_sco_config *optmode_config =
- &cmd->sco_optmode_config;
- struct btcoex_wlan_sco_config *wlan_config = &cmd->sco_wlan_config;
-
-
- sco_config->sco_slots = cpu_to_le32(SCO_SLOT_DEFAULT);
- sco_config->sco_idle_slots = cpu_to_le32(SCO_IDLE_SLOT_DEFAULT);
- sco_config->sco_flags = cpu_to_le32(SCO_FLAGS_DEFAULT);
- sco_config->link_id = cpu_to_le32(SCO_LINK_ID_DEFAULT);
-
- ppoll_config->sco_cycle_force_trigger =
- cpu_to_le32(SCO_CYCLES_FORCE_TRIGGER_DEFAULT);
- ppoll_config->sco_data_res_to =
- cpu_to_le32(SCO_DATA_RES_TIMEOUT_DEFAULT);
- ppoll_config->sco_stomp_duty_cycle_val =
- cpu_to_le32(SCO_STOMP_DUTY_CYCLE_DEFAULT);
- ppoll_config->sco_stomp_duty_cycle_max_val =
- cpu_to_le32(SCO_STOMP_DUTY_CYCLE_MAX_DEFAULT);
- ppoll_config->sco_pspoll_latency_fraction =
- cpu_to_le32(SCO_PS_POLL_LATENCY_FRACTION_DEFAULT);
-
- optmode_config->sco_stomp_cnt_in_100ms =
- cpu_to_le32(SCO_STOMP_COUNT_IN_100MS_DEFAULT);
- optmode_config->sco_cont_stomp_cnt_max =
- cpu_to_le32(SCO_CONT_STOMP_MAX_DEFAULT);
- optmode_config->sco_min_low_rate_mbps =
- cpu_to_le32(SCO_MIN_RATE_MBPS_DEFAULT);
- optmode_config->sco_low_rate_cnt =
- cpu_to_le32(SCO_LOW_RATE_CNT_DEFAULT);
- optmode_config->sco_hi_pkt_ratio =
- cpu_to_le32(SCO_HI_PKT_RATIO_DEFAULT);
- optmode_config->sco_max_aggr_size =
- cpu_to_le32(SCO_MAX_AGGR_SIZE_DEFAULT);
-
- wlan_config->scan_interval =
- cpu_to_le32(SCO_SCAN_INTERVAL_DEFAULT);
- wlan_config->max_scan_stomp_cnt =
- cpu_to_le32(SCO_MAX_SCAN_STOMP_CNT_INTERVAL);
-
-}
-#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1)
-
-#define IDLE_SLOT_THREASHOLD 10
-#define MAX_AGGR_SIZE_ABOVE_THREASHOLD 8
-#define POLL_LATENCY_BELOW_THRESHOLD 1
-#define POLL_LATENCY_ABOVE_THRESHOLD 2
-#define POLL_LATENCY_BELOW_THRESHOLD_EDR 2
-#define POLL_LATENCY_ABOVE_THRESHOLD_EDR 3
-#define STOMP_CYCLE_ABOVE_THREASHOLD 2
-#define STOMP_CYCLE_BELOW_THREASHOLD 5
-#define STOMP_CYCLE_ABOVE_THREASHOLD_EDR 2
-#define STOMP_CYCLE_BELOW_THREASHOLD_EDR 5
-#define MAX_STOMP_CNT_BELOW_THRESHOLD 4
-#define MAX_STOMP_CNT_ABOVE_THRESHOLD 2
-#define MAX_STOMP_CNT_BELOW_THRESHOLD_EDR 4
-#define MAX_STOMP_CNT_ABOVE_THRESHOLD_EDR 2
-int ath6kl_wmi_set_btcoex_sco_op(struct wmi *wmi, bool esco, u32 tx_interval,
- u32 tx_pkt_len)
-{
-
- struct sk_buff *skb;
- int max_slot;
-
- struct wmi_set_btcoex_sco_config_cmd *cmd;
- struct btcoex_sco_config *sco_config;
- struct btcoex_pspoll_mode_sco_config *ppoll_config;
- struct btcoex_optmode_sco_config *optmode_config;
- struct btcoex_wlan_sco_config *wlan_config;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(sizeof
- (struct wmi_set_btcoex_sco_config_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_btcoex_sco_config_cmd *)skb->data;
- set_default_sco(cmd);
-
- set_default_sco(cmd);
- sco_config = &cmd->sco_config;
- ppoll_config = &cmd->sco_pspoll_config;
- optmode_config = &cmd->sco_optmode_config;
- wlan_config = &cmd->sco_wlan_config;
-
- if (esco)
- max_slot = btcoex_get_max_slot(tx_pkt_len);
- else
- max_slot = SCO_SLOT_DEFAULT;
-
- sco_config->sco_slots = cpu_to_le32(max_slot);
-
- if (tx_interval >= max_slot)
- sco_config->sco_idle_slots =
- cpu_to_le32(tx_interval - max_slot);
-
-
- if (sco_config->sco_idle_slots >= IDLE_SLOT_THREASHOLD)
- optmode_config->sco_max_aggr_size =
- cpu_to_le32(MAX_AGGR_SIZE_ABOVE_THREASHOLD);
-
- if (esco) {
- sco_config->sco_flags |= WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE;
-
- if (sco_config->sco_idle_slots >= IDLE_SLOT_THREASHOLD) {
- ppoll_config->sco_pspoll_latency_fraction =
- cpu_to_le32(POLL_LATENCY_ABOVE_THRESHOLD_EDR);
- ppoll_config->sco_stomp_duty_cycle_val =
- cpu_to_le32(STOMP_CYCLE_ABOVE_THREASHOLD_EDR);
- wlan_config->max_scan_stomp_cnt =
- cpu_to_le32(MAX_STOMP_CNT_ABOVE_THRESHOLD_EDR);
- } else {
- ppoll_config->sco_pspoll_latency_fraction =
- cpu_to_le32(POLL_LATENCY_BELOW_THRESHOLD_EDR);
- ppoll_config->sco_stomp_duty_cycle_val =
- cpu_to_le32(STOMP_CYCLE_BELOW_THREASHOLD_EDR);
- wlan_config->max_scan_stomp_cnt =
- cpu_to_le32(MAX_STOMP_CNT_BELOW_THRESHOLD_EDR);
- }
- } else {
- if (sco_config->sco_idle_slots >= IDLE_SLOT_THREASHOLD) {
- ppoll_config->sco_pspoll_latency_fraction =
- cpu_to_le32(POLL_LATENCY_ABOVE_THRESHOLD);
- ppoll_config->sco_stomp_duty_cycle_val =
- cpu_to_le32(STOMP_CYCLE_ABOVE_THREASHOLD);
- wlan_config->max_scan_stomp_cnt =
- cpu_to_le32(MAX_STOMP_CNT_ABOVE_THRESHOLD);
- } else {
- ppoll_config->sco_pspoll_latency_fraction =
- cpu_to_le32(POLL_LATENCY_BELOW_THRESHOLD);
- ppoll_config->sco_stomp_duty_cycle_val =
- cpu_to_le32(STOMP_CYCLE_BELOW_THREASHOLD);
- wlan_config->max_scan_stomp_cnt =
- cpu_to_le32(MAX_STOMP_CNT_BELOW_THRESHOLD);
- }
- }
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_BTCOEX_SCO_CONFIG_CMDID\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "wmi_set_btcoex_sco_config_cmd :\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tsco_config->sco_slots:%x\n",
- sco_config->sco_slots);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tsco_config->sco_idle_slots:%x\n",
- sco_config->sco_idle_slots);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tsco_config->sco_flags:%x\n",
- sco_config->sco_flags);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tsco_config->link_id:%x\n",
- sco_config->link_id);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tpspoll_sco_config->sco_cycle_force_trigger %x\n",
- ppoll_config->sco_cycle_force_trigger);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tpspoll_sco_config->sco_data_res_to %x\n",
- ppoll_config->sco_data_res_to);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tpspoll_config->sco_stomp_duty_cycle_val %x\n",
- ppoll_config->sco_stomp_duty_cycle_val);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tpspoll_config->sco_stomp_duty_cycle_max_val %x\n",
- ppoll_config->sco_stomp_duty_cycle_max_val);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tpspoll_config->sco_pspoll_latency_fraction %x\n",
- ppoll_config->sco_pspoll_latency_fraction);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_stomp_cnt_in_100ms %x\n",
- optmode_config->sco_stomp_cnt_in_100ms);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_cont_stomp_cnt_max %x\n",
- optmode_config->sco_cont_stomp_cnt_max);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_min_low_rate_mbps %x\n",
- optmode_config->sco_min_low_rate_mbps);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_low_rate_cnt %x\n",
- optmode_config->sco_low_rate_cnt);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_hi_pkt_ratio %x\n",
- optmode_config->sco_hi_pkt_ratio);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\toptmode_config->sco_max_aggr_size %x\n",
- optmode_config->sco_max_aggr_size);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\twlan_config->scan_interval %x\n",
- wlan_config->scan_interval);
- ath6kl_dbg(ATH6KL_DBG_WMI, "\twlan_config->max_scan_stomp_cnt %x\n",
- wlan_config->max_scan_stomp_cnt);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
- NO_SYNC_WMIFLAG);
-}
-#define BTCOEX_A2DP_FLAG_DEFAULT 0
-#define BTCOEX_A2DP_LINK_ID_DEFAULT 0
-#define BTCOEX_A2DP_WLAN_MAX_DUR_DEFAULT 30
-#define BTCOEX_A2DP_MIN_BURST_CNT_DEFAULT 3
-#define BTCOEX_A2DP_DATA_RESP_TO_DEFAULT 20
-#define BTCOEX_A2DP_LOW_RATE_MBPS_DEFAULT 36
-#define BTCOEX_A2DP_LOW_RATE_CNT_DEFAULT 5
-#define BTCOEX_A2DP_HI_PKT_RATIO_DEFAULT 5
-#define BTCOEX_A2DP_MAX_AGGR_SIZE 1
-#define BTCOEX_A2DP_PKT_STOMP_CNT_DEFAULT 6
-
-static inline void dump_a2dp_cmd(struct wmi_set_btcoex_a2dp_config_cmd *cmd)
-{
- struct btcoex_a2dp_config *a2dp_config = &cmd->a2dp_config;
- struct btcoex_pspoll_a2dp_config *pspoll_config = &cmd->pspoll_config;
- struct btcoex_a2dp_optmode_config *optmode_config =
- &cmd->optmode_config;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "a2dp_config->a2dp_flags:%x\n",
- a2dp_config->a2dp_flags);
- ath6kl_dbg(ATH6KL_DBG_WMI, "a2dp_config->link_id:%x\n",
- a2dp_config->link_id);
- ath6kl_dbg(ATH6KL_DBG_WMI, "pspoll_config->a2dp_wlan_max_dur:%x\n",
- pspoll_config->a2dp_wlan_max_dur);
- ath6kl_dbg(ATH6KL_DBG_WMI, "pspoll_config->a2dp_min_bus_cnt:%x\n",
- pspoll_config->a2dp_min_bus_cnt);
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "optmode_config->a2dp_min_low_rate_mbps:%x\n",
- optmode_config->a2dp_min_low_rate_mbps);
- ath6kl_dbg(ATH6KL_DBG_WMI, "optmode_config->a2dp_low_rate_cnt:%x\n",
- optmode_config->a2dp_low_rate_cnt);
- ath6kl_dbg(ATH6KL_DBG_WMI, "optmode_config->a2dp_hi_pkt_ratio:%x\n",
- optmode_config->a2dp_hi_pkt_ratio);
- ath6kl_dbg(ATH6KL_DBG_WMI, "optmode_config->a2dp_max_aggr_size:%x\n",
- optmode_config->a2dp_max_aggr_size);
- ath6kl_dbg(ATH6KL_DBG_WMI, "optmode_config->a2dp_pkt_stomp_cnt:%x\n",
- optmode_config->a2dp_pkt_stomp_cnt);
-}
-
-static inline void set_default_a2dp(struct wmi_set_btcoex_a2dp_config_cmd *cmd)
-{
- struct btcoex_a2dp_config *a2dp_config = &cmd->a2dp_config;
- struct btcoex_pspoll_a2dp_config *pspoll_config = &cmd->pspoll_config;
- struct btcoex_a2dp_optmode_config *optmode_config =
- &cmd->optmode_config;
-
- a2dp_config->a2dp_flags = cpu_to_le32(BTCOEX_A2DP_FLAG_DEFAULT);
- a2dp_config->link_id = cpu_to_le32(BTCOEX_A2DP_LINK_ID_DEFAULT);
-
- pspoll_config->a2dp_wlan_max_dur =
- cpu_to_le32(BTCOEX_A2DP_WLAN_MAX_DUR_DEFAULT);
- pspoll_config->a2dp_min_bus_cnt =
- cpu_to_le32(BTCOEX_A2DP_MIN_BURST_CNT_DEFAULT);
- pspoll_config->a2dp_data_res_to =
- cpu_to_le32(BTCOEX_A2DP_DATA_RESP_TO_DEFAULT);
-
- optmode_config->a2dp_min_low_rate_mbps =
- cpu_to_le32(BTCOEX_A2DP_LOW_RATE_MBPS_DEFAULT);
- optmode_config->a2dp_low_rate_cnt =
- cpu_to_le32(BTCOEX_A2DP_LOW_RATE_CNT_DEFAULT);
- optmode_config->a2dp_hi_pkt_ratio =
- cpu_to_le32(BTCOEX_A2DP_HI_PKT_RATIO_DEFAULT);
- optmode_config->a2dp_max_aggr_size =
- cpu_to_le32(BTCOEX_A2DP_MAX_AGGR_SIZE);
- optmode_config->a2dp_pkt_stomp_cnt =
- cpu_to_le32(BTCOEX_A2DP_PKT_STOMP_CNT_DEFAULT);
-}
-
-#define BTCOEX_A2DP_WLAN_MAX_DUR_QCOM_BT 25
-#define BTCOEX_A2DP_MIN_BURST_CNT_QCOM_BT 3
-#define BTCOEX_A2DP_PKT_STOMP_CNT_QCOM_BT 2
-#define A2DP_CONFIG_ALLOW_OPTIMIZATION (1 << 0)
-static inline void set_qcom_a2dp(struct wmi_set_btcoex_a2dp_config_cmd *cmd)
-{
- struct btcoex_a2dp_config *a2dp_config = &cmd->a2dp_config;
- struct btcoex_pspoll_a2dp_config *pspoll_config = &cmd->pspoll_config;
- struct btcoex_a2dp_optmode_config *optmode_config =
- &cmd->optmode_config;
-
- a2dp_config->a2dp_flags |= cpu_to_le32(A2DP_CONFIG_ALLOW_OPTIMIZATION);
-
- pspoll_config->a2dp_wlan_max_dur =
- cpu_to_le32(BTCOEX_A2DP_WLAN_MAX_DUR_QCOM_BT);
- pspoll_config->a2dp_min_bus_cnt =
- cpu_to_le32(BTCOEX_A2DP_MIN_BURST_CNT_QCOM_BT);
-
- optmode_config->a2dp_pkt_stomp_cnt =
- cpu_to_le32(BTCOEX_A2DP_PKT_STOMP_CNT_QCOM_BT);
-}
-
-#define BT_VER_1_0 0
-#define BT_VER_1_1 1
-#define BT_VER_1_2 2
-#define BT_VER_2_0 3
-#define BT_VER_2_1 4
-#define BT_VER_3_0 5
-#define BT_VER_4_0 6
-
-#define BTCOEX_A2DP_WLAN_MAX_DUR_BDR 30
-#define BTCOEX_A2DP_DATA_RESP_TO_BDR 10
-#define BTCOEX_A2DP_MIN_BURST_CNT_BDR 4
-
-#define BTCOEX_A2DP_LOW_RATE_MBPS_BDR 52
-#define BTCOEX_A2DP_MAX_AGGR_SIZE_BDR 1
-
-#define BTCOEX_A2DP_DATA_RESP_TO_EDR 20
-#define BTCOEX_A2DP_WLAN_MAX_DUR_EDR 50
-#define BTCOEX_A2DP_LOW_RATE_MBPS_EDR 36
-#define BTCOEX_A2DP_MAX_AGGR_SIZE_EDR 16
-#define BTCOEX_A2DP_MIN_BURST_CNT_EDR 2
-static inline void update_lmp_ver(struct wmi_set_btcoex_a2dp_config_cmd *cmd,
- u32 lmp_ver)
-{
- struct btcoex_pspoll_a2dp_config *pspoll_config = &cmd->pspoll_config;
- struct btcoex_a2dp_optmode_config *optmode_config =
- &cmd->optmode_config;
-
- switch (lmp_ver) {
- case BT_VER_1_0:
- case BT_VER_1_1:
- case BT_VER_1_2: /* BDR */
- pspoll_config->a2dp_wlan_max_dur =
- cpu_to_le32(BTCOEX_A2DP_WLAN_MAX_DUR_BDR);
- pspoll_config->a2dp_min_bus_cnt =
- cpu_to_le32(BTCOEX_A2DP_MIN_BURST_CNT_BDR);
- pspoll_config->a2dp_data_res_to =
- cpu_to_le32(BTCOEX_A2DP_DATA_RESP_TO_BDR);
-
- optmode_config->a2dp_min_low_rate_mbps =
- cpu_to_le32(BTCOEX_A2DP_LOW_RATE_MBPS_BDR);
- optmode_config->a2dp_max_aggr_size =
- cpu_to_le32(BTCOEX_A2DP_MAX_AGGR_SIZE_BDR);
- break;
- default: /* EDR */
- pspoll_config->a2dp_data_res_to =
- cpu_to_le32(BTCOEX_A2DP_DATA_RESP_TO_EDR);
- pspoll_config->a2dp_wlan_max_dur =
- cpu_to_le32(BTCOEX_A2DP_WLAN_MAX_DUR_EDR);
- pspoll_config->a2dp_min_bus_cnt =
- cpu_to_le32(BTCOEX_A2DP_MIN_BURST_CNT_EDR);
-
- optmode_config->a2dp_min_low_rate_mbps =
- cpu_to_le32(BTCOEX_A2DP_LOW_RATE_MBPS_EDR);
- optmode_config->a2dp_max_aggr_size =
- cpu_to_le32(BTCOEX_A2DP_MAX_AGGR_SIZE_EDR);
- }
-}
-
-#define BTCOEX_ACL_ROLE_UNKNOWN 0
-#define BTCOEX_ACL_ROLE_MASTER 1
-#define BTCOEX_ACL_ROLE_SLAVE 2
-
-#define A2DP_CONFIG_IS_MASTER (1 << 2)
-#define BTCOEX_A2DP_WLAN_MAX_DUR_SLAVE 30
-static inline void update_acl_role(struct wmi_set_btcoex_a2dp_config_cmd *cmd,
- u32 role)
-{
- struct btcoex_a2dp_config *a2dp_config = &cmd->a2dp_config;
- struct btcoex_pspoll_a2dp_config *pspoll_config = &cmd->pspoll_config;
-
- if (role == BTCOEX_ACL_ROLE_UNKNOWN)
- return;
-
- if (role == BTCOEX_ACL_ROLE_MASTER) {
- a2dp_config->a2dp_flags |= cpu_to_le32(A2DP_CONFIG_IS_MASTER);
- } else {
- a2dp_config->a2dp_flags &= ~cpu_to_le32(A2DP_CONFIG_IS_MASTER);
- pspoll_config->a2dp_wlan_max_dur =
- cpu_to_le32(BTCOEX_A2DP_WLAN_MAX_DUR_SLAVE);
- }
-}
-
-#define BT_VENDOR_DEFAULT 0
-#define BT_VENDOR_QCOM 1
-
-int ath6kl_wmi_set_btcoex_a2dp_op(struct wmi *wmi, u32 role, u32 ver,
- u32 vendor)
-{
- struct wmi_set_btcoex_a2dp_config_cmd *cmd;
- struct sk_buff *skb;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(sizeof
- (struct wmi_set_btcoex_a2dp_config_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_btcoex_a2dp_config_cmd *)skb->data;
- set_default_a2dp(cmd);
-
- update_acl_role(cmd, role);
- update_lmp_ver(cmd, ver);
-
- if (vendor == BT_VENDOR_QCOM)
- set_qcom_a2dp(cmd);
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_BTCOEX_A2DP_CONFIG_CMDID\n");
- dump_a2dp_cmd(cmd);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-int ath6kl_wmi_set_btcoex_set_colocated_bt(struct wmi *wmi, u8 dev_type)
-{
- struct wmi_set_btcoex_colocated_bt_dev_cmd *cmd;
- struct sk_buff *skb;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(sizeof
- (struct wmi_set_btcoex_colocated_bt_dev_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_btcoex_colocated_bt_dev_cmd *)skb->data;
- cmd->colocated_bt_dev = dev_type;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID:\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tCo-Located BT: %x\n",
- cmd->colocated_bt_dev);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
- NO_SYNC_WMIFLAG);
-}
-int ath6kl_wmi_set_btcoex_set_fe_antenna(struct wmi *wmi, u8 antenna_type)
-{
- struct wmi_set_btcoex_fe_antenna_cmd *cmd;
- struct sk_buff *skb;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(sizeof
- (struct wmi_set_btcoex_fe_antenna_cmd));
- if (!skb)
- return -ENOMEM;
-
- cmd = (struct wmi_set_btcoex_fe_antenna_cmd *)skb->data;
- cmd->fe_antenna_type = antenna_type;
-
- ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_BTCOEX_FE_ANT_CMDID:\n");
- ath6kl_dbg(ATH6KL_DBG_WMI, "\tFe antenna Type: %x\n",
- cmd->fe_antenna_type);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- WMI_SET_BTCOEX_FE_ANT_CMDID,
- NO_SYNC_WMIFLAG);
-}
-
-static int ath6kl_get_wmi_cmd(int nl_cmd)
-{
- int wmi_cmd = 0;
- switch (nl_cmd) {
- case NL80211_WMI_SET_BT_STATUS:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT status\n");
- wmi_cmd = WMI_SET_BT_STATUS_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_PARAMS:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT params\n");
- wmi_cmd = WMI_SET_BT_PARAMS_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_FT_ANT:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT FT antenna\n");
- wmi_cmd = WMI_SET_BTCOEX_FE_ANT_CMDID;
- break;
-
- case NL80211_WMI_SET_COLOCATED_BT_DEV:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT collocated dev\n");
- wmi_cmd = WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_INQUIRY_PAGE_CONFIG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT inquiry page\n");
- wmi_cmd = WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_SCO_CONFIG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT sco config\n");
- wmi_cmd = WMI_SET_BTCOEX_SCO_CONFIG_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_A2DP_CONFIG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT a2dp config\n");
- wmi_cmd = WMI_SET_BTCOEX_A2DP_CONFIG_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_ACLCOEX_CONFIG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT acl config\n");
- wmi_cmd = WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_DEBUG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT bt debug\n");
- wmi_cmd = WMI_SET_BTCOEX_DEBUG_CMDID;
- break;
-
- case NL80211_WMI_SET_BT_OPSTATUS:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Set BT op status\n");
- wmi_cmd = WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID;
- break;
-
- case NL80211_WMI_GET_BT_CONFIG:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Get BT config\n");
- wmi_cmd = WMI_GET_BTCOEX_CONFIG_CMDID;
- break;
-
- case NL80211_WMI_GET_BT_STATS:
- ath6kl_dbg(ATH6KL_DBG_WMI, "Get BT status\n");
- wmi_cmd = WMI_GET_BTCOEX_STATS_CMDID;
- break;
- }
- return wmi_cmd;
-}
-
-int ath6kl_wmi_send_btcoex_cmd(struct wmi *wmi,
- u8 *buf, int len)
-{
- struct sk_buff *skb;
- u32 nl_cmd;
- int wmi_cmd;
-
- nl_cmd = *(u32 *)buf;
- buf += sizeof(u32);
- len -= sizeof(u32);
- wmi_cmd = ath6kl_get_wmi_cmd(nl_cmd);
- if (wmi_cmd == 0)
- return -ENOMEM;
-
- skb = ath6kl_wmi_btcoex_get_new_buf(len);
- if (!skb)
- return -ENOMEM;
-
- memcpy(skb->data, buf, len);
-
- return ath6kl_wmi_cmd_send(wmi, 0, skb,
- (enum wmi_cmd_id)wmi_cmd,
- NO_SYNC_WMIFLAG);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi_btcoex.h b/drivers/net/wireless/ath/ath6kl/wmi_btcoex.h
deleted file mode 100644
index 0f7acce..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmi_btcoex.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * This file contains the definitions of the WMI protocol specified in the
- * Wireless Module Interface (WMI). It includes definitions of all the
- * commands and events. Commands are messages from the host to the WM.
- * Events and Replies are messages from the WM to the host.
- */
-
-#ifndef WMI_BTCOEX_H
-#define WMI_BTCOEX_H
-
-#include <linux/ieee80211.h>
-
-/*
- * WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID
- * Setting the Bluetooth operation status.
- */
-struct wmi_btcoex_bt_op_status_cmd {
- __le32 op_type;
- __le32 op_status;
- __le32 link_id;
-} __packed;
-
-/*
- * WMI_SET_BTCOEX_SCO_CONFIG_CMDID
- * Setting the Bluetooth operation status.
- */
-struct btcoex_sco_config {
- __le32 sco_slots;
- __le32 sco_idle_slots;
- __le32 sco_flags;
- __le32 link_id;
-} __packed;
-
-struct btcoex_pspoll_mode_sco_config {
- __le32 sco_cycle_force_trigger;
- __le32 sco_data_res_to;
- __le32 sco_stomp_duty_cycle_val;
- __le32 sco_stomp_duty_cycle_max_val;
- __le32 sco_pspoll_latency_fraction;
-} __packed;
-
-struct btcoex_optmode_sco_config {
- __le32 sco_stomp_cnt_in_100ms;
- __le32 sco_cont_stomp_cnt_max;
- __le32 sco_min_low_rate_mbps;
- __le32 sco_low_rate_cnt;
- __le32 sco_hi_pkt_ratio;
- __le32 sco_max_aggr_size;
-} __packed;
-
-struct btcoex_wlan_sco_config {
- __le32 scan_interval;
- __le32 max_scan_stomp_cnt;
-} __packed;
-
-struct wmi_set_btcoex_sco_config_cmd {
- struct btcoex_sco_config sco_config;
- struct btcoex_pspoll_mode_sco_config sco_pspoll_config;
- struct btcoex_optmode_sco_config sco_optmode_config;
- struct btcoex_wlan_sco_config sco_wlan_config;
-} __packed;
-/*
- * WMI_SET_BTCOEX_A2DP_CONFIG_CMDID
- * Setting the Bluetooth A2DP configuration operation.
- */
-struct btcoex_a2dp_config {
- __le32 a2dp_flags;
- __le32 link_id;
-} __packed;
-
-struct btcoex_pspoll_a2dp_config {
- __le32 a2dp_wlan_max_dur;
- __le32 a2dp_min_bus_cnt;
- __le32 a2dp_data_res_to;
-
-} __packed;
-
-struct btcoex_a2dp_optmode_config {
- __le32 a2dp_min_low_rate_mbps;
- __le32 a2dp_low_rate_cnt;
- __le32 a2dp_hi_pkt_ratio;
- __le32 a2dp_max_aggr_size;
- __le32 a2dp_pkt_stomp_cnt;
-} __packed;
-
-struct wmi_set_btcoex_a2dp_config_cmd {
- struct btcoex_a2dp_config a2dp_config;
- struct btcoex_pspoll_a2dp_config pspoll_config;
- struct btcoex_a2dp_optmode_config optmode_config;
-} __packed;
-
-struct wmi_set_btcoex_colocated_bt_dev_cmd {
- u8 colocated_bt_dev;
-} __packed;
-
-struct wmi_set_btcoex_fe_antenna_cmd {
- u8 fe_antenna_type;
-} __packed;
-
-/* BT Coex */
-int ath6kl_wmi_set_btcoex_bt_op_status(struct wmi *wmi, u8 op_id, bool flag);
-int ath6kl_wmi_set_btcoex_sco_op(struct wmi *wmi, bool esco, u32 tx_interval,
- u32 tx_pkt_len);
-int ath6kl_wmi_set_btcoex_a2dp_op(struct wmi *wmi, u32 role, u32 ver, u32 ven);
-int ath6kl_wmi_set_btcoex_set_colocated_bt(struct wmi *wmi, u8 dev_type);
-int ath6kl_wmi_set_btcoex_set_fe_antenna(struct wmi *wmi, u8 antenna_type);
-int ath6kl_wmi_send_btcoex_cmd(struct wmi *wmi,
- u8 *buf, int len);
-#endif /* WMI_BTCOEX_H */
diff --git a/drivers/net/wireless/ath/ath6kl/wmiconfig.c b/drivers/net/wireless/ath/ath6kl/wmiconfig.c
deleted file mode 100644
index bb60ed2..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmiconfig.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2010-2011 Atheros Communications Inc.
- * Copyright (c) 2011 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "testmode.h"
-#include "debug.h"
-#include "wmi.h"
-
-#include <net/netlink.h>
-
-enum ath6kl_tm_attr {
- __ATH6KL_TM_ATTR_INVALID = 0,
- ATH6KL_TM_ATTR_CMD = 1,
- ATH6KL_TM_ATTR_DATA = 2,
-
- /* keep last */
- __ATH6KL_TM_ATTR_AFTER_LAST,
- ATH6KL_TM_ATTR_MAX = __ATH6KL_TM_ATTR_AFTER_LAST - 1,
-};
-
-enum ath6kl_tm_cmd {
- ATH6KL_TM_CMD_TCMD = 0,
- ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */
- ATH6KL_TM_CMD_WMI_CMD = 0xF000,
-};
-
-struct sk_buff *ath6kl_wmi_get_buf(u32 size)
-{
- struct sk_buff *skb;
-
- skb = ath6kl_buf_alloc(size);
- if (!skb)
- return NULL;
-
- skb_put(skb, size);
- if (size)
- memset(skb->data, 0, size);
-
- return skb;
-}
-void ath6kl_tm_rx_wmi_event(struct ath6kl *ar, void *buf, size_t buf_len)
-{
- struct sk_buff *skb;
-
-
- if (!buf || buf_len == 0)
- return;
-
- skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
- if (!skb) {
- ath6kl_warn("failed to allocate testmode rx skb!\n");
- return;
- }
- NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_WMI_CMD);
- NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
- cfg80211_testmode_event(skb, GFP_KERNEL);
- return;
-
-nla_put_failure:
- kfree_skb(skb);
- ath6kl_warn("nla_put failed on testmode rx skb!\n");
-}
-
-
-void ath6kl_wmicfg_send_stats(struct ath6kl_vif *vif,
- struct target_stats *stats)
-{
- u32 *buff = kzalloc(sizeof(*stats) + 4, GFP_KERNEL);
-
- buff[0] = WMI_REPORT_STATISTICS_EVENTID;
- memcpy(buff+1, stats, sizeof(struct target_stats));
- ath6kl_tm_rx_wmi_event(vif->ar->wmi->parent_dev, buff,
- sizeof(struct target_stats)+4);
- kfree(buff);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/wmiconfig.h b/drivers/net/wireless/ath/ath6kl/wmiconfig.h
deleted file mode 100644
index bcc29ae..0000000
--- a/drivers/net/wireless/ath/ath6kl/wmiconfig.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2011 Atheros Communications Inc.
- * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef WMICONFIG_H
-#define WMICONFIG_H
-
-struct sk_buff *ath6kl_wmi_get_buf(u32 size);
-void ath6kl_tm_rx_wmi_event(struct ath6kl *ar, void *buf, size_t buf_len);
-void ath6kl_wmicfg_send_stats(struct ath6kl_vif *vif,
- struct target_stats *stats);
-#endif