/*
* Intel Wireless Multicomm 3200 WiFi driver
*
* Copyright (C) 2009 Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Intel Corporation <ilw@linux.intel.com>
* Samuel Ortiz <samuel.ortiz@intel.com>
* Zhu Yi <yi.zhu@intel.com>
*
*/
#include <linux/kernel.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <linux/ieee80211.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include "iwm.h"
#include "bus.h"
#include "hal.h"
#include "umac.h"
#include "commands.h"
#include "debug.h"
static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
u8 lmac_cmd_id,
const void *lmac_payload,
u16 lmac_payload_size,
u8 resp)
{
struct iwm_udma_wifi_cmd udma_cmd = UDMA_LMAC_INIT;
struct iwm_umac_cmd umac_cmd;
struct iwm_lmac_cmd lmac_cmd;
lmac_cmd.id = lmac_cmd_id;
umac_cmd.id = UMAC_CMD_OPCODE_WIFI_PASS_THROUGH;
umac_cmd.resp = resp;
return iwm_hal_send_host_cmd(iwm, &udma_cmd, &umac_cmd, &lmac_cmd,
lmac_payload, lmac_payload_size);
}
int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
bool resp)
{
struct iwm_umac_wifi_if *hdr = (struct iwm_umac_wifi_if *)payload;
struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
struct iwm_umac_cmd umac_cmd;
int ret;
u8 oid = hdr->oid;
if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
IWM_ERR(iwm, "Interface is not ready yet");
return -EAGAIN;
}
umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
umac_cmd.resp = resp;
ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
payload, payload_size);
if (resp) {
ret = wait_event_interruptible_timeout(iwm->wifi_ntfy_queue,
test_and_clear_bit(oid, &iwm->wifi_ntfy[0]),
3 * HZ);
return ret ? 0 : -EBUSY;
}
return ret;
}
static int modparam_wiwi = COEX_MODE_CM;
module_param_named(wiwi, modparam_wiwi, int, 0644);
MODULE_PARM_DESC(wiwi, "Wifi-WiMAX coexistence: 1=SA, 2=XOR, 3=CM (default)");
static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
{
{4, 3, 0, COEX_UNASSOC_IDLE_FLAGS},
{4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
{4, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
{4, 3, 0, COEX_CALIBRATION_FLAGS},
{4, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
{4, 3, 0, COEX_CONNECTION_ESTAB_FLAGS},
{4, 3, 0, COEX_ASSOCIATED_IDLE_FLAGS},
{4, 3, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
{4, 3, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
{4, 3, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
{6, 3, 0, COEX_XOR_RF_ON_FLAGS},
{4, 3, 0, COEX_RF_OFF_FLAGS},
{6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
{4, 3, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
{4, 3, 0, COEX_RSRVD1_FLAGS},
{4, 3, 0, COEX_RSRVD2_FLAGS}
};
static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
{
{1, 1, 0, COEX_UNASSOC_IDLE_FLAGS},
{4, 4, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
{3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
{6, 6, 0, COEX_CALIBRATION_FLAGS},
{3, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
{6, 5, 0, COEX_CONNECTION_ESTAB_FLAGS},
{4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
{4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
{4, 4, 0, COEX_ASSOC_AUTO_SCAN_FLAGS