/*
* Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
*
* 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.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
#include "wcn36xx.h"
unsigned int wcn36xx_dbg_mask;
module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
MODULE_PARM_DESC(debug_mask, "Debugging mask");
#define CHAN2G(_freq, _idx) { \
.band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 25, \
}
#define CHAN5G(_freq, _idx) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 25, \
}
/* The wcn firmware expects channel values to matching
* their mnemonic values. So use these for .hw_value. */
static struct ieee80211_channel wcn_2ghz_channels[] = {
CHAN2G(2412, 1), /* Channel 1 */
CHAN2G(2417, 2), /* Channel 2 */
CHAN2G(2422, 3), /* Channel 3 */
CHAN2G(2427, 4), /* Channel 4 */
CHAN2G(2432, 5), /* Channel 5 */
CHAN2G(2437, 6), /* Channel 6 */
CHAN2G(2442, 7), /* Channel 7 */
CHAN2G(2447, 8), /* Channel 8 */
CHAN2G(2452, 9), /* Channel 9 */
CHAN2G(2457, 10), /* Channel 10 */
CHAN2G(2462, 11), /* Channel 11 */
CHAN2G(2467, 12), /* Channel 12 */
CHAN2G(2472, 13), /* Channel 13 */
CHAN2G(2484, 14) /* Channel 14 */
};
static struct ieee80211_channel wcn_5ghz_channels[] = {
CHAN5G(5180, 36),
CHAN5G(5200, 40),
CHAN5G(5220, 44),
CHAN5G(5240, 48),
CHAN5G(5260, 52),
CHAN5G(5280, 56),
CHAN5G(5300, 60),
CHAN5G(5320, 64),
CHAN5G(5500, 100),
CHAN5G(5520, 104),
CHAN5G(5540, 108),
CHAN5G(5560, 112),
CHAN5G(5580, 116),
CHAN5G(5600, 120),
CHAN5G(5620, 124),
CHAN5G(5640, 128),
CHAN5G(5660, 132),
CHAN5G(5700, 140),
CHAN5G(5745, 149),
CHAN5G(5765, 153),
CHAN5G(5785, 157),
CHAN5G(5805, 161),
CHAN5G(5825, 165)
};
#define RATE(_bitrate, _hw_rate, _flags) { \
.bitrate = (_bitrate), \
.flags = (_flags), \
.hw_value = (_hw_rate), \
.hw_value_short = (_hw_rate) \
}
static struct ieee80211_rate wcn_2ghz_rates[] = {
RATE(10, HW_RATE_INDEX_1MBPS, 0),
RATE(20, HW_RATE_INDEX_2MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(55, HW_RATE_INDEX_5_5MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(110, HW_RATE_INDEX_11MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(60, HW_RATE_INDEX_6MBPS, 0),
RATE(90, HW_RATE_INDEX_9MBPS, 0),
RATE(120, HW_RATE_INDEX_12MBPS, 0),
RATE(180, HW_RATE_INDEX_18MBPS, 0),
RATE(240, HW_RATE_INDEX_24MBPS, 0),
RATE(360, HW_RATE_INDEX_36MBPS, 0),
RATE(480, HW_RATE_INDEX_48MBPS, 0),
RATE(540, HW_RATE_INDEX_54MBPS, 0)
};
static struct ieee80211_rate wcn_5ghz_rates[] = {
RATE(60, HW_RATE_INDEX_6MBPS, 0),
RATE(90, HW_RATE_INDEX_9MBPS, 0),
RATE(120, HW_RATE_INDEX_12MBPS, 0),
RATE(180, HW_RATE_INDEX_18MBPS, 0),
RATE(240,