/* cfg80211 Interface for prism2_usb module */
#include "hfa384x.h"
#include "prism2mgmt.h"

/* Prism2 channel/frequency/bitrate declarations */
static const struct ieee80211_channel prism2_channels[] = {
	{ .center_freq = 2412 },
	{ .center_freq = 2417 },
	{ .center_freq = 2422 },
	{ .center_freq = 2427 },
	{ .center_freq = 2432 },
	{ .center_freq = 2437 },
	{ .center_freq = 2442 },
	{ .center_freq = 2447 },
	{ .center_freq = 2452 },
	{ .center_freq = 2457 },
	{ .center_freq = 2462 },
	{ .center_freq = 2467 },
	{ .center_freq = 2472 },
	{ .center_freq = 2484 },
};

static const struct ieee80211_rate prism2_rates[] = {
	{ .bitrate = 10 },
	{ .bitrate = 20 },
	{ .bitrate = 55 },
	{ .bitrate = 110 }
};

#define PRISM2_NUM_CIPHER_SUITES 2
static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = {
	WLAN_CIPHER_SUITE_WEP40,
	WLAN_CIPHER_SUITE_WEP104
};

/* prism2 device private data */
struct prism2_wiphy_private {
	struct wlandevice *wlandev;

	struct ieee80211_supported_band band;
	struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)];
	struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)];

	struct cfg80211_scan_request *scan_request;
};

static const void * const prism2_wiphy_privid = &prism2_wiphy_privid;

/* Helper Functions */
static int prism2_result2err(int prism2_result)
{
	int err = 0;

	switch (prism2_result) {
	case P80211ENUM_resultcode_invalid_parameters:
		err = -EINVAL;
		break;
	case P80211ENUM_resultcode_implementation_failure:
		err = -EIO;
		break;
	case P80211ENUM_resultcode_not_supported:
		err = -EOPNOTSUPP;
		break;
	default:
		err = 0;
		break;
	}

	return err;
}

static int prism2_domibset_uint32(struct wlandevice *wlandev, u32 did, u32 data)
{
	struct p80211msg_dot11req_mibset msg;
	struct p80211item_uint32 *mibitem =
			(struct p80211item_uint32 *)&msg.mibattribute.data;

	msg.msgcode = DIDmsg_dot11req_mibset;
	mibitem->did = did;
	mibitem->data = data;

	return p80211req_dorequest(wlandev, (u8 *)&msg);
}

static int prism2_domibset_pstr32(struct wlandevice *wlandev,
				  u32 did, u8 len, const u8 *data)
{
	struct p80211msg_dot11req_mibset msg;
	struct p80211item_pstr32 *mibitem =
			(struct p80211item_pstr32 *)&msg.mibattribute.data;

	msg.msgcode = DIDmsg_dot11req_mibset;
	mibitem->did = did;
	mibitem->data.len = len;
	memcpy(mibitem->data.data, data, len);

	return p80211req_dorequest(wlandev, (u8 *)&msg);
}

/* The interface functions, called by the cfg80211 layer */
static int prism2_change_virtual_intf(struct wiphy *wiphy,
				      struct net_device *dev,
				      enum nl80211_iftype type, u32 *flags,
				      struct vif_params *params)
{
	struct wlandevice *wlandev = dev->ml_priv;
	u32 data;
	int result;
	int err = 0;

	switch (type) {
	case NL80211_IFTYPE_ADHOC:
		if (wlandev->macmode == WLAN_MACMODE_IBSS_STA)
			goto exit;
		wlandev->macmode = WLAN_MACMODE_IBSS_STA;
		data = 0;
		break;
	case NL80211_IFTYPE_STATION:
		if (wlandev->macmode == WLAN_MACMODE_ESS_STA)
			goto exit;
		wlandev->macmode = WLAN_MACMODE_ESS_STA;
		data = 1;
		break;
	default:
		netdev_warn(dev, "Operation mode: %d not support\n", type);
		return -EOPNOTSUPP;
	}

	/* Set Operation mode to the PORT TYPE RID */
	result = prism2_domibset_uint32(wlandev,
					DIDmib_p2_p2Static_p2CnfPortType,
					data);

	if (result)
		err = -EFAULT;

	dev->ieee80211_ptr->iftype = type;

exit:
	return err;
}

static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev,
			  u8 key_index, bool pairwise, const u8 *mac_addr,
			  struct key_params *params)
{
	struct wlandevice *wlandev = dev->ml_priv;
	u32 did;

	int err = 0;
	int result = 0;

	if (key_index >= NUM_WEPKEYS)
		return -EINVAL;

	switch (params->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
						key_index);
		if (result)
			goto exit;

		/* send key to driver */
		did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);

		result = prism2_domibset_pstr32(wlandev, did,
						params->key_len, params->key);
		if (result)
			goto exit;
		break;

	default:
		pr_debug("Unsupported cipher suite\n");
		result = 1;
	}

exit:
	if (result)
		err = -EFAULT;

	return err;
}

static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev,
			  u8 key_index, bool pairwise,
			  const u8 *mac_addr, void *cookie,
			  void (*callback)(void *cookie, struct key_params*))
{
	struct wlandevice *wlandev = dev->ml_priv;
	struct key_params params;
	int len;

	if (key_index >= NUM_WEPKEYS)
		return -EINVAL;

	len = wlandev->wep_keylens[key_index];
	memset(&params, 0, sizeof(params));

	if (len == 13)
		params.cipher = WLAN_CIPHER_SUITE_WEP104;
	else if (len == 5)
		params.cipher = WLAN_CIPHER_SUITE_WEP104;
	else
		return -ENOENT;
	params.key_len = len;
	params.key = wlandev->wep_keys[key_index];
	params.seq_len = 0;

	callback(cookie, &params);

	return 0;
}

static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev,
			  u8 key_index, bool pairwise, const u8 *mac_addr)
{
	struct wlandevice *wlandev = dev->ml_priv;
	u32 did;
	int err = 0;
	int result = 0;

	/* There is no direct way in the hardware (AFAIK) of removing
	 * a key, so we will cheat by setting the key to a bogus value
	 */

	if (key_index >= NUM_WEPKEYS)
		return -EINVAL;

	/* send key to driver */
	did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(key_index + 1);
	result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000");

	if (result)
		err = -EFAULT;

	return err;
}

static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev,
				  u8 key_index, bool unicast, bool multicast)
{
	struct wlandevice *wlandev = dev->ml_priv;

	int err = 0;
	int result = 0;

	result = prism2_domibset_uint32(wlandev,
		DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
		key_index);

	if (result)
		err = -EFAULT;

	return err;
}

static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev,
			      const u8 *mac, struct station_info *sinfo)
{
	struct wlandevice *wlandev = dev->ml_priv;
	struct p80211msg_lnxreq_commsquality quality;
	int result;

	memset(sinfo, 0, sizeof(*sinfo));

	if (!wlandev || (wlandev->msdstate != WLAN_MSD_RUNNING))
		return -EOPNOTSUPP;

	/* build request message */
	quality.msgcode = DIDmsg_lnxreq_commsquality;
	quality.dbm.data = P80211ENUM_truth_true;
	quality.dbm.status = P80211ENUM_msgitem_status_data_ok;

	/* send message to nsd */
	if (!wlandev->mlmerequest)
		return -EOPNOTSUPP;

	result = wlandev->mlmerequest(wlandev, (struct p80211msg *)&quality);

	if (result == 0) {
		sinfo->txrate.legacy = quality.txrate.data;
		sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
		sinfo->signal = quality.level.data;
		sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
	}

	return result;
}

static int prism2_scan(struct wiphy *wiphy,
		       struct cfg80211_scan_request *request)
{
	struct net_device *dev;
	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
	struct wlandevice *wlandev;
	struct p80211msg_dot11req_scan msg1;
	struct p80211msg_dot11req_scan_results msg2;
	struct cfg80211_bss *bss;
	struct cfg80211_scan_info info = {};

	int result;
	int err = 0;
	int numbss = 0;
	int i = 0;
	u8 ie_buf[46];
	int ie_len;

	if (!request)
		return -EINVAL;

	dev = request->wdev->netdev;
	wlandev = dev->ml_priv;

	if (priv->scan_request && priv->scan_request != request)
		return -EBUSY;

	if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
		netdev_err(dev, "Can't scan in AP mode\n");
		return -EOPNOTSUPP;
	}

	priv->scan_request = request;

	memset(&msg1, 0x00, sizeof(struct p80211msg_dot11req_scan));
	msg1.msgcode = DIDmsg_dot11req_scan;
	msg1.bsstype.data = P80211ENUM_bsstype_any;

	memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data));
	msg1.bssid.data.len = 6;

	if (request->n_ssids > 0) {
		msg1.scantype.data = P80211ENUM_scantype_active;
		msg1.ssid.data.len = request->ssids->ssid_len;
		memcpy(msg1.ssid.data.data,
		       request->ssids->ssid, request->ssids->ssid_len);
	} else {
		msg1.scantype.data = 0;
	}
	msg1.probedelay.data = 0;

	for (i = 0;
		(i < request->n_channels) && i < ARRAY_SIZE(prism2_channels);
		i++)
		msg1.channellist.data.data[i] =
			ieee80211_frequency_to_channel(
				request->channels[i]->center_freq);
	msg1.channellist.data.len = request->n_channels;

	msg1.maxchanneltime.data = 250;
	msg1.minchanneltime.data = 200;

	result = p80211req_dorequest(wlandev, (u8 *)&msg1);
	if (result) {
		err = prism2_result2err(msg1.resultcode.data);
		goto exit;
	}
	/* Now retrieve scan results */
	numbss = msg1.numbss.data;

	for (i = 0; i < numbss; i++) {
		int freq;

		memset(&msg2, 0, sizeof(msg2));
		msg2.msgcode = DIDmsg_dot11req_scan_results;
		msg2.bssindex.data = i;

		result = p80211req_dorequest(wlandev, (u8 *)&msg2);
		if ((result != 0) ||
		    (msg2.resultcode.data != P80211ENUM_resultcode_success)) {
			break;
		}

		ie_buf[0] = WLAN_EID_SSID;
		ie_buf[1] = msg2.ssid.data.len;
		ie_len = ie_buf[1] + 2;
		memcpy(&ie_buf[2], &(msg2.ssid.data.data), msg2.ssid.data.len);
		freq = ieee80211_channel_to_frequency(msg2.dschannel.data,
						      NL80211_BAND_2GHZ);
		bss = cfg80211_inform_bss(wiphy,
			ieee80211_get_channel(wiphy, freq),
			CFG80211_BSS_FTYPE_UNKNOWN,
			(const u8 *)&(msg2.bssid.data.data),
			msg2.timestamp.data, msg2.capinfo.data,
			msg2.beaconperiod.data,
			ie_buf,
			ie_len,
			(msg2.signal.data - 65536) * 100, /* Conversion to signed type */
			GFP_KERNEL
		);

		if (!bss) {
			err = -ENOMEM;
			goto exit;
		}

		cfg80211_put_bss(wiphy, bss);
	}

	if (result)
		err = prism2_result2err(msg2.resultcode.data);

exit:
	info.aborted = !!(err);
	cfg80211_scan_done(request, &info);
	priv->scan_request = NULL;
	return err;
}

static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
	struct wlandevice *wlandev = priv->wlandev;
	u32 data;
	int result;
	int err = 0;

	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
		if (wiphy->rts_threshold == -1)
			data = 2347;
		else
			data = wiphy->rts_threshold;

		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
						data);
		if (result) {
			err = -EFAULT;
			goto exit;
		}
	}

	if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
		if (wiphy->frag_threshold == -1)
			data = 2346;
		else
			data = wiphy->frag_threshold;

		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
						data);
		if (result) {
			err = -EFAULT;
			goto exit;
		}
	}

exit:
	return err;
}

static int prism2_connect(struct wiphy *wiphy, struct net_device *dev,
			  struct cfg80211_connect_params *sme)
{
	struct wlandevice *wlandev = dev->ml_priv;
	struct ieee80211_channel *channel = sme->channel;
	struct p80211msg_lnxreq_autojoin msg_join;
	u32 did;
	int length = sme->ssid_len;
	int chan = -1;
	int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) ||
	    (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104);
	int result;
	int err = 0;

	/* Set the channel */
	if (channel) {
		chan = ieee80211_frequency_to_channel(channel->center_freq);
		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
						chan);
		if (result)
			goto exit;
	}

	/* Set the authorization */
	if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) ||
	    ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep))
		msg_join.authtype.data = P80211ENUM_authalg_opensystem;
	else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) ||
		 ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep))
		msg_join.authtype.data = P80211ENUM_authalg_sharedkey;
	else
		netdev_warn(dev,
			"Unhandled authorisation type for connect (%d)\n",
			sme->auth_type);

	/* Set the encryption - we only support wep */
	if (is_wep) {
		if (sme->key) {
			if (sme->key_idx >= NUM_WEPKEYS)
				return -EINVAL;

			result = prism2_domibset_uint32(wlandev,
				DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
				sme->key_idx);
			if (result)
				goto exit;

			/* send key to driver */
			did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_key(
					sme->key_idx + 1);
			result = prism2_domibset_pstr32(wlandev,
							did, sme->key_len,
							(u8 *)sme->key);
			if (result)
				goto exit;
		}

		/* Assume we should set privacy invoked and exclude unencrypted
		 * We could possible use sme->privacy here, but the assumption
		 * seems reasonable anyways
		 */
		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
						P80211ENUM_truth_true);
		if (result)
			goto exit;

		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
						P80211ENUM_truth_true);
		if (result)
			goto exit;

	} else {
		/* Assume we should unset privacy invoked
		 * and exclude unencrypted
		 */
		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
						P80211ENUM_truth_false);
		if (result)
			goto exit;

		result = prism2_domibset_uint32(wlandev,
						DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
						P80211ENUM_truth_false);
		if (result)
			goto exit;
	}

	/* Now do the actual join. Note there is no way that I can
	 * see to request a specific bssid
	 */
	msg_join.msgcode = DIDmsg_lnxreq_autojoin;

	memcpy(msg_join.ssid.data.data, sme->ssid, length);
	msg_join.ssid.data.len = length;

	result = p80211req_dorequest(wlandev, (u8 *)&msg_join);

exit:
	if (result)
		err = -EFAULT;

	return err;
}

static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev,
			     u16 reason_code)
{
	struct wlandevice *wlandev = dev->ml_priv;
	struct p80211msg_lnxreq_autojoin msg_join;
	int result;
	int err = 0;

	/* Do a join, with a bogus ssid. Thats the only way I can think of */
	msg_join.msgcode = DIDmsg_lnxreq_autojoin;

	memcpy(msg_join.ssid.data.data, "---", 3);
	msg_join.ssid.data.len = 3;

	result = p80211req_dorequest(wlandev, (u8 *)&msg_join);

	if (result)
		err = -EFAULT;

	return err;
}

static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev,
			    struct cfg80211_ibss_params *params)
{
	return -EOPNOTSUPP;
}

static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
{
	return -EOPNOTSUPP;
}

static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
			       enum nl80211_tx_power_setting type, int mbm)
{
	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
	struct wlandevice *wlandev = priv->wlandev;
	u32 data;
	int result;
	int err = 0;

	if (type == NL80211_TX_POWER_AUTOMATIC)
		data = 30;
	else
		data = MBM_TO_DBM(mbm);

	result = prism2_domibset_uint32(wlandev,
		DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
		data);

	if (result) {
		err = -EFAULT;
		goto exit;
	}

exit:
	return err;
}

static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
			       int *dbm)
{
	struct prism2_wiphy_private *priv = wiphy_priv(wiphy);
	struct wlandevice *wlandev = priv->wlandev;
	struct p80211msg_dot11req_mibget msg;
	struct p80211item_uint32 *mibitem;
	int result;
	int err = 0;

	mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data;
	msg.msgcode = DIDmsg_dot11req_mibget;
	mibitem->did =
	    DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;

	result = p80211req_dorequest(wlandev, (u8 *)&msg);

	if (result) {
		err = -EFAULT;
		goto exit;
	}

	*dbm = mibitem->data;

exit:
	return err;
}

/* Interface callback functions, passing data back up to the cfg80211 layer */
void prism2_connect_result(struct wlandevice *wlandev, u8 failed)
{
	u16 status = failed ?
		     WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS;

	cfg80211_connect_result(wlandev->netdev, wlandev->bssid,
				NULL, 0, NULL, 0, status, GFP_KERNEL);
}

void prism2_disconnected(struct wlandevice *wlandev)
{
	cfg80211_disconnected(wlandev->netdev, 0, NULL,
			      0, false, GFP_KERNEL);
}

void prism2_roamed(struct wlandevice *wlandev)
{
	cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
		NULL, 0, NULL, 0, GFP_KERNEL);
}

/* Structures for declaring wiphy interface */
static const struct cfg80211_ops prism2_usb_cfg_ops = {
	.change_virtual_intf = prism2_change_virtual_intf,
	.add_key = prism2_add_key,
	.get_key = prism2_get_key,
	.del_key = prism2_del_key,
	.set_default_key = prism2_set_default_key,
	.get_station = prism2_get_station,
	.scan = prism2_scan,
	.set_wiphy_params = prism2_set_wiphy_params,
	.connect = prism2_connect,
	.disconnect = prism2_disconnect,
	.join_ibss = prism2_join_ibss,
	.leave_ibss = prism2_leave_ibss,
	.set_tx_power = prism2_set_tx_power,
	.get_tx_power = prism2_get_tx_power,
};

/* Functions to create/free wiphy interface */
static struct wiphy *wlan_create_wiphy(struct device *dev, struct wlandevice *wlandev)
{
	struct wiphy *wiphy;
	struct prism2_wiphy_private *priv;

	wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv));
	if (!wiphy)
		return NULL;

	priv = wiphy_priv(wiphy);
	priv->wlandev = wlandev;
	memcpy(priv->channels, prism2_channels, sizeof(prism2_channels));
	memcpy(priv->rates, prism2_rates, sizeof(prism2_rates));
	priv->band.channels = priv->channels;
	priv->band.n_channels = ARRAY_SIZE(prism2_channels);
	priv->band.bitrates = priv->rates;
	priv->band.n_bitrates = ARRAY_SIZE(prism2_rates);
	priv->band.band = NL80211_BAND_2GHZ;
	priv->band.ht_cap.ht_supported = false;
	wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;

	set_wiphy_dev(wiphy, dev);
	wiphy->privid = prism2_wiphy_privid;
	wiphy->max_scan_ssids = 1;
	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
				 | BIT(NL80211_IFTYPE_ADHOC);
	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
	wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES;
	wiphy->cipher_suites = prism2_cipher_suites;

	if (wiphy_register(wiphy) < 0) {
		wiphy_free(wiphy);
		return NULL;
	}

	return wiphy;
}

static void wlan_free_wiphy(struct wiphy *wiphy)
{
	wiphy_unregister(wiphy);
	wiphy_free(wiphy);
}
