/*
 * Intel Wireless Multicomm 3200 WiFi driver
 *
 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
 * Samuel Ortiz <samuel.ortiz@intel.com>
 * Zhu Yi <yi.zhu@intel.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 */

#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/etherdevice.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
#include <linux/slab.h>
#include <net/cfg80211.h>

#include "iwm.h"
#include "commands.h"
#include "cfg80211.h"
#include "debug.h"

#define RATETAB_ENT(_rate, _rateid, _flags) \
	{								\
		.bitrate	= (_rate),				\
		.hw_value	= (_rateid),				\
		.flags		= (_flags),				\
	}

#define CHAN2G(_channel, _freq, _flags) {			\
	.band			= IEEE80211_BAND_2GHZ,		\
	.center_freq		= (_freq),			\
	.hw_value		= (_channel),			\
	.flags			= (_flags),			\
	.max_antenna_gain	= 0,				\
	.max_power		= 30,				\
}

#define CHAN5G(_channel, _flags) {				\
	.band			= IEEE80211_BAND_5GHZ,		\
	.center_freq		= 5000 + (5 * (_channel)),	\
	.hw_value		= (_channel),			\
	.flags			= (_flags),			\
	.max_antenna_gain	= 0,				\
	.max_power		= 30,				\
}

static struct ieee80211_rate iwm_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 iwm_a_rates		(iwm_rates + 4)
#define iwm_a_rates_size	8
#define iwm_g_rates		(iwm_rates + 0)
#define iwm_g_rates_size	12

static struct ieee80211_channel iwm_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 iwm_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 iwm_band_2ghz = {
	.channels = iwm_2ghz_channels,
	.n_channels = ARRAY_SIZE(iwm_2ghz_channels),
	.bitrates = iwm_g_rates,
	.n_bitrates = iwm_g_rates_size,
};

static struct ieee80211_supported_band iwm_band_5ghz = {
	.channels = iwm_5ghz_a_channels,
	.n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
	.bitrates = iwm_a_rates,
	.n_bitrates = iwm_a_rates_size,
};

static int iwm_key_init(struct iwm_key *key, u8 key_index,
			const u8 *mac_addr, struct key_params *params)
{
	key->hdr.key_idx = key_index;
	if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
		key->hdr.multicast = 1;
		memset(key->hdr.mac, 0xff, ETH_ALEN);
	} else {
		key->hdr.multicast = 0;
		memcpy(key->hdr.mac, mac_addr, ETH_ALEN);
	}

	if (params) {
		if (params->key_len > WLAN_MAX_KEY_LEN ||
		    params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
			return -EINVAL;

		key->cipher = params->cipher;
		key->key_len = params->key_len;
		key->seq_len = params->seq_len;
		memcpy(key->key, params->key, key->key_len);
		memcpy(key->seq, params->seq, key->seq_len);
	}

	return 0;
}

static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
				u8 key_index, bool pairwise, const u8 *mac_addr,
				struct key_params *params)
{
	struct iwm_priv *iwm = ndev_to_iwm(ndev);
	struct iwm_key *key;
	int ret;

	IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr);

	if (key_index >= IWM_NUM_KEYS)
		return -ENOENT;

	key = &iwm->keys[key_index];
	memset(key, 0, sizeof(struct iwm_key));
	ret = iwm_key_init(key, key_index, mac_addr, params);
	if (ret < 0) {
		IWM_ERR(iwm, "Invalid key_params\n");
		return ret;
	}

	return iwm_set_key(iwm, 0, key);
}

static int iwm_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 iwm_priv *iwm = ndev_to_iwm(ndev);
	struct iwm_key *key;
	struct key_params params;

	IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);

	if (key_index >= IWM_NUM_KEYS)
		return -ENOENT;

	memset(&params, 0, sizeof(params));

	key = &iwm->keys[key_index];
	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 iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
				u8 key_index, bool pairwise, const u8 *mac_addr)
{
	struct iwm_priv *iwm = ndev_to_iwm(ndev);
	struct iwm_key *key;

	if (key_index >= IWM_NUM_KEYS)
		return -ENOENT;

	key = &iwm->keys[key_index];
	if (!iwm->keys[key_index].key_len) {
		IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index);
		return 0;
	}

	if (key_index == iwm->default_key)
		iwm->default_key = -1;

	return iwm_set_key(iwm, 1, key);
}

static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
					struct net_device *ndev,
					u8 key_index, bool unicast,
					bool multicast)
{
	struct iwm_priv *iwm = ndev_to_iwm(ndev);

	IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);

	if (key_index >= IWM_NUM_KEYS)
		return -ENOENT;

	if (!iwm->keys[key_index].key_len) {
		IWM_ERR(iwm, "Key %d not used\n", key_index);
		return -EINVAL;
	}

	iwm->default_key = key_index;

	return iwm_set_tx_key(iwm, key_index);
}

static int iwm_cfg80211_get_station(struct wiphy *wiphy,
				    struct net_device *ndev,
				    u8 *mac, struct station_info *sinfo)
{
	struct iwm_priv *iwm = ndev_to_iwm(ndev);

	if (memcmp(mac, iwm->bssid, ETH_ALEN))
		return -ENOENT;

	sinfo->filled |= STATION_INFO_TX_BITRATE;
	sinfo->txrate.legacy = iwm->rate * 10;

	if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
		sinfo->filled |= STATION_INFO_SIGNAL;
		sinfo->signal = iwm->wstats.qual.level;
	}

	return 0;
}


int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
{
	struct wiphy *wiphy = iwm_to_wiphy(iwm);
	struct iwm_bss_info *bss;
	struct iwm_umac_notif_bss_info *umac_bss;
	struct ieee80211_mgmt *mgmt;
	struct ieee80211_channel *channel;
	struct ieee80211_supported_band *band;
	s32 signal;
	int freq;

	list_for_each_entry(bss, &iwm->bss_list, node) {
		umac_bss = bss->bss;
		mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);

		if (umac_bss->band == UMAC_BAND_2GHZ)
			band = wiphy->bands[IEEE80211_BAND_2GHZ];
		else if (umac_bss->band == UMAC_BAND_5GHZ)
			band = wiphy->bands[IEEE80211_BAND_5GHZ];
		else {
			IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
			return -EINVAL;
		}

		freq = ieee80211_channel_to_frequency(umac_bss->channel,
						      band->band);
		channel = ieee80211_get_channel(wiphy, freq);
		signal = umac_bss->rssi * 100;

		if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
					       le16_to_cpu(umac_bss->frame_len),
					       signal, GFP_KERNEL))
			return -EINVAL;
	}

	return 0;
}

static int iwm_cfg80211_change_iface(struct wiphy *wiphy,
				     struct net_device *ndev,
				     enum nl80211_iftype type, u32 *flags,
				     struct vif_params *params)
{
	struct wireless_dev *wdev;
	struct iwm_priv *iwm;
	u32 old_mode;

	wdev = ndev->ieee80211_ptr;
	iwm = ndev_to_iwm(ndev);
	old_mode = iwm->conf.mode;

	switch (type) {
	case NL80211_IFTYPE_STATION:
		iwm->conf.mode = UMAC_MODE_BSS;
		break;
	case NL80211_IFTYPE_ADHOC:
		iwm->conf.mode = UMAC_MODE_IBSS;
		break;
	default:
		return -EOPNOTSUPP;
	}

	wdev->iftype = type;

	if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
		return 0;

	iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);

	if (iwm->umac_profile_active)
		iwm_invalidate_mlme_profile(iwm);

	return 0;
}

static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
			     struct cfg80211_scan_request *request)
{
	struct iwm_priv *iwm = ndev_to_iwm(ndev);
	int ret;

	if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
		IWM_ERR(iwm, "Scan while device is not ready\n");
		return -EIO;
	}

	if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
		IWM_ERR(iwm, "Scanning already\n");
		return -EAGAIN;
	}

	if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
		IWM_ERR(iwm, "Scanning being aborted\n");
		return -EAGAIN;
	}

	set_bit(IWM_STATUS_SCANNING, &iwm->status);

	ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
	if (ret) {
		clear_bit(IWM_STATUS_SCANNING, &iwm->status);
		return ret;
	}

	iwm->scan_request = request;
	return 0;
}

static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
	    (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
		int ret;

		iwm->conf.rts_threshold = wiphy->rts_threshold;

		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
					     CFG_RTS_THRESHOLD,
					     iwm->conf.rts_threshold);
		if (ret < 0)
			return ret;
	}

	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
	    (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
		int ret;

		iwm->conf.frag_threshold = wiphy->frag_threshold;

		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
					     CFG_FRAG_THRESHOLD,
					     iwm->conf.frag_threshold);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
				  struct cfg80211_ibss_params *params)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
	struct ieee80211_channel *chan = params->channel;

	if (!test_bit(IWM_STATUS_READY, &iwm->status))
		return -EIO;

	/* UMAC doesn't support creating or joining an IBSS network
	 * with specified bssid. */
	if (params->bssid)
		return -EOPNOTSUPP;

	iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
	iwm->umac_profile->ibss.band = chan->band;
	iwm->umac_profile->ibss.channel = iwm->channel;
	iwm->umac_profile->ssid.ssid_len = params->ssid_len;
	memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);

	return iwm_send_mlme_profile(iwm);
}

static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	if (iwm->umac_profile_active)
		return iwm_invalidate_mlme_profile(iwm);

	return 0;
}

static int iwm_set_auth_type(struct iwm_priv *iwm,
			     enum nl80211_auth_type sme_auth_type)
{
	u8 *auth_type = &iwm->umac_profile->sec.auth_type;

	switch (sme_auth_type) {
	case NL80211_AUTHTYPE_AUTOMATIC:
	case NL80211_AUTHTYPE_OPEN_SYSTEM:
		IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
		*auth_type = UMAC_AUTH_TYPE_OPEN;
		break;
	case NL80211_AUTHTYPE_SHARED_KEY:
		if (iwm->umac_profile->sec.flags &
		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
			IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
		} else {
			IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
		}

		break;
	default:
		IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
		return -ENOTSUPP;
	}

	return 0;
}

static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
{
	IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);

	if (!wpa_version) {
		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
		return 0;
	}

	if (wpa_version & NL80211_WPA_VERSION_1)
		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;

	if (wpa_version & NL80211_WPA_VERSION_2)
		iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;

	return 0;
}

static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
{
	u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
		&iwm->umac_profile->sec.mcast_cipher;

	if (!cipher) {
		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
		return 0;
	}

	IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
		     cipher);

	switch (cipher) {
	case IW_AUTH_CIPHER_NONE:
		*profile_cipher = UMAC_CIPHER_TYPE_NONE;
		break;
	case WLAN_CIPHER_SUITE_WEP40:
		*profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
		break;
	case WLAN_CIPHER_SUITE_WEP104:
		*profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
		break;
	case WLAN_CIPHER_SUITE_TKIP:
		*profile_cipher = UMAC_CIPHER_TYPE_TKIP;
		break;
	case WLAN_CIPHER_SUITE_CCMP:
		*profile_cipher = UMAC_CIPHER_TYPE_CCMP;
		break;
	default:
		IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
		return -ENOTSUPP;
	}

	return 0;
}

static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
{
	u8 *auth_type = &iwm->umac_profile->sec.auth_type;

	IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);

	if (key_mgt == WLAN_AKM_SUITE_8021X)
		*auth_type = UMAC_AUTH_TYPE_8021X;
	else if (key_mgt == WLAN_AKM_SUITE_PSK) {
		if (iwm->umac_profile->sec.flags &
		    (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
			*auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
		else
			*auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
	} else {
		IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
		return -EINVAL;
	}

	return 0;
}


static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
				 struct cfg80211_connect_params *sme)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
	struct ieee80211_channel *chan = sme->channel;
	struct key_params key_param;
	int ret;

	if (!test_bit(IWM_STATUS_READY, &iwm->status))
		return -EIO;

	if (!sme->ssid)
		return -EINVAL;

	if (iwm->umac_profile_active) {
		ret = iwm_invalidate_mlme_profile(iwm);
		if (ret) {
			IWM_ERR(iwm, "Couldn't invalidate profile\n");
			return ret;
		}
	}

	if (chan)
		iwm->channel =
			ieee80211_frequency_to_channel(chan->center_freq);

	iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
	memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);

	if (sme->bssid) {
		IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
		memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
		iwm->umac_profile->bss_num = 1;
	} else {
		memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
		iwm->umac_profile->bss_num = 0;
	}

	ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
	if (ret < 0)
		return ret;

	ret = iwm_set_auth_type(iwm, sme->auth_type);
	if (ret < 0)
		return ret;

	if (sme->crypto.n_ciphers_pairwise) {
		ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
				     true);
		if (ret < 0)
			return ret;
	}

	ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
	if (ret < 0)
		return ret;

	if (sme->crypto.n_akm_suites) {
		ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
		if (ret < 0)
			return ret;
	}

	/*
	 * We save the WEP key in case we want to do shared authentication.
	 * We have to do it so because UMAC will assert whenever it gets a
	 * key before a profile.
	 */
	if (sme->key) {
		key_param.key = kmemdup(sme->key, sme->key_len, GFP_KERNEL);
		if (key_param.key == NULL)
			return -ENOMEM;
		key_param.key_len = sme->key_len;
		key_param.seq_len = 0;
		key_param.cipher = sme->crypto.ciphers_pairwise[0];

		ret = iwm_key_init(&iwm->keys[sme->key_idx], sme->key_idx,
				   NULL, &key_param);
		kfree(key_param.key);
		if (ret < 0) {
			IWM_ERR(iwm, "Invalid key_params\n");
			return ret;
		}

		iwm->default_key = sme->key_idx;
	}

	/* WPA and open AUTH type from wpa_s means WPS (a.k.a. WSC) */
	if ((iwm->umac_profile->sec.flags &
	     (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) &&
	    iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN) {
			iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WSC_ON_MSK;
	}

	ret = iwm_send_mlme_profile(iwm);

	if (iwm->umac_profile->sec.auth_type != UMAC_AUTH_TYPE_LEGACY_PSK ||
	    sme->key == NULL)
		return ret;

	/*
	 * We want to do shared auth.
	 * We need to actually set the key we previously cached,
	 * and then tell the UMAC it's the default one.
	 * That will trigger the auth+assoc UMAC machinery, and again,
	 * this must be done after setting the profile.
	 */
	ret = iwm_set_key(iwm, 0, &iwm->keys[sme->key_idx]);
	if (ret < 0)
		return ret;

	return iwm_set_tx_key(iwm, iwm->default_key);
}

static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
				   u16 reason_code)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);

	if (iwm->umac_profile_active)
		iwm_invalidate_mlme_profile(iwm);

	return 0;
}

static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
				    enum nl80211_tx_power_setting type, int mbm)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
	int ret;

	switch (type) {
	case NL80211_TX_POWER_AUTOMATIC:
		return 0;
	case NL80211_TX_POWER_FIXED:
		if (mbm < 0 || (mbm % 100))
			return -EOPNOTSUPP;

		if (!test_bit(IWM_STATUS_READY, &iwm->status))
			return 0;

		ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
					      CFG_TX_PWR_LIMIT_USR,
					      MBM_TO_DBM(mbm) * 2);
		if (ret < 0)
			return ret;

		return iwm_tx_power_trigger(iwm);
	default:
		IWM_ERR(iwm, "Unsupported power type: %d\n", type);
		return -EOPNOTSUPP;
	}

	return 0;
}

static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	*dbm = iwm->txpower >> 1;

	return 0;
}

static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy,
				       struct net_device *dev,
				       bool enabled, int timeout)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
	u32 power_index;

	if (enabled)
		power_index = IWM_POWER_INDEX_DEFAULT;
	else
		power_index = IWM_POWER_INDEX_MIN;

	if (power_index == iwm->conf.power_index)
		return 0;

	iwm->conf.power_index = power_index;

	return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
				       CFG_POWER_INDEX, iwm->conf.power_index);
}

static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy,
				  struct net_device *netdev,
				  struct cfg80211_pmksa *pmksa)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD);
}

static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy,
				  struct net_device *netdev,
				  struct cfg80211_pmksa *pmksa)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);

	return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL);
}

static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy,
				    struct net_device *netdev)
{
	struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
	struct cfg80211_pmksa pmksa;

	memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));

	return iwm_send_pmkid_update(iwm, &pmksa, IWM_CMD_PMKID_FLUSH);
}


static struct cfg80211_ops iwm_cfg80211_ops = {
	.change_virtual_intf = iwm_cfg80211_change_iface,
	.add_key = iwm_cfg80211_add_key,
	.get_key = iwm_cfg80211_get_key,
	.del_key = iwm_cfg80211_del_key,
	.set_default_key = iwm_cfg80211_set_default_key,
	.get_station = iwm_cfg80211_get_station,
	.scan = iwm_cfg80211_scan,
	.set_wiphy_params = iwm_cfg80211_set_wiphy_params,
	.connect = iwm_cfg80211_connect,
	.disconnect = iwm_cfg80211_disconnect,
	.join_ibss = iwm_cfg80211_join_ibss,
	.leave_ibss = iwm_cfg80211_leave_ibss,
	.set_tx_power = iwm_cfg80211_set_txpower,
	.get_tx_power = iwm_cfg80211_get_txpower,
	.set_power_mgmt = iwm_cfg80211_set_power_mgmt,
	.set_pmksa = iwm_cfg80211_set_pmksa,
	.del_pmksa = iwm_cfg80211_del_pmksa,
	.flush_pmksa = iwm_cfg80211_flush_pmksa,
};

static const u32 cipher_suites[] = {
	WLAN_CIPHER_SUITE_WEP40,
	WLAN_CIPHER_SUITE_WEP104,
	WLAN_CIPHER_SUITE_TKIP,
	WLAN_CIPHER_SUITE_CCMP,
};

struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
{
	int ret = 0;
	struct wireless_dev *wdev;

	/*
	 * We're trying to have the following memory
	 * layout:
	 *
	 * +-------------------------+
	 * | struct wiphy	     |
	 * +-------------------------+
	 * | struct iwm_priv         |
	 * +-------------------------+
	 * | bus private data        |
	 * | (e.g. iwm_priv_sdio)    |
	 * +-------------------------+
	 *
	 */

	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
	if (!wdev) {
		dev_err(dev, "Couldn't allocate wireless device\n");
		return ERR_PTR(-ENOMEM);
	}

	wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
				sizeof(struct iwm_priv) + sizeof_bus);
	if (!wdev->wiphy) {
		dev_err(dev, "Couldn't allocate wiphy device\n");
		ret = -ENOMEM;
		goto out_err_new;
	}

	set_wiphy_dev(wdev->wiphy, dev);
	wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
	wdev->wiphy->max_num_pmkids = UMAC_MAX_NUM_PMKIDS;
	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
				       BIT(NL80211_IFTYPE_ADHOC);
	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
	wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;

	wdev->wiphy->cipher_suites = cipher_suites;
	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);

	ret = wiphy_register(wdev->wiphy);
	if (ret < 0) {
		dev_err(dev, "Couldn't register wiphy device\n");
		goto out_err_register;
	}

	return wdev;

 out_err_register:
	wiphy_free(wdev->wiphy);

 out_err_new:
	kfree(wdev);

	return ERR_PTR(ret);
}

void iwm_wdev_free(struct iwm_priv *iwm)
{
	struct wireless_dev *wdev = iwm_to_wdev(iwm);

	if (!wdev)
		return;

	wiphy_unregister(wdev->wiphy);
	wiphy_free(wdev->wiphy);
	kfree(wdev);
}
