/*
 * EEPROM parser code for mac80211 Prism54 drivers
 *
 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 *
 * Based on:
 * - the islsm (softmac prism54) driver, which is:
 *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
 * - stlc45xx driver
 *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
 *
 * 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.
 */

#include <linux/init.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/sort.h>
#include <linux/slab.h>

#include <net/mac80211.h>
#include <linux/crc-ccitt.h>

#include "p54.h"
#include "eeprom.h"
#include "lmac.h"

static struct ieee80211_rate p54_bgrates[] = {
	{ .bitrate = 10, .hw_value = 0, },
	{ .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60, .hw_value = 4, },
	{ .bitrate = 90, .hw_value = 5, },
	{ .bitrate = 120, .hw_value = 6, },
	{ .bitrate = 180, .hw_value = 7, },
	{ .bitrate = 240, .hw_value = 8, },
	{ .bitrate = 360, .hw_value = 9, },
	{ .bitrate = 480, .hw_value = 10, },
	{ .bitrate = 540, .hw_value = 11, },
};

static struct ieee80211_rate p54_arates[] = {
	{ .bitrate = 60, .hw_value = 4, },
	{ .bitrate = 90, .hw_value = 5, },
	{ .bitrate = 120, .hw_value = 6, },
	{ .bitrate = 180, .hw_value = 7, },
	{ .bitrate = 240, .hw_value = 8, },
	{ .bitrate = 360, .hw_value = 9, },
	{ .bitrate = 480, .hw_value = 10, },
	{ .bitrate = 540, .hw_value = 11, },
};

static struct p54_rssi_db_entry p54_rssi_default = {
	/*
	 * The defaults are taken from usb-logs of the
	 * vendor driver. So, they should be safe to
	 * use in case we can't get a match from the
	 * rssi <-> dBm conversion database.
	 */
	.mul = 130,
	.add = -398,
};

#define CHAN_HAS_CAL		BIT(0)
#define CHAN_HAS_LIMIT		BIT(1)
#define CHAN_HAS_CURVE		BIT(2)
#define CHAN_HAS_ALL		(CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)

struct p54_channel_entry {
	u16 freq;
	u16 data;
	int index;
	enum ieee80211_band band;
};

struct p54_channel_list {
	struct p54_channel_entry *channels;
	size_t entries;
	size_t max_entries;
	size_t band_channel_num[IEEE80211_NUM_BANDS];
};

static int p54_get_band_from_freq(u16 freq)
{
	/* FIXME: sync these values with the 802.11 spec */

	if ((freq >= 2412) && (freq <= 2484))
		return IEEE80211_BAND_2GHZ;

	if ((freq >= 4920) && (freq <= 5825))
		return IEEE80211_BAND_5GHZ;

	return -1;
}

static int same_band(u16 freq, u16 freq2)
{
	return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
}

static int p54_compare_channels(const void *_a,
				const void *_b)
{
	const struct p54_channel_entry *a = _a;
	const struct p54_channel_entry *b = _b;

	return a->freq - b->freq;
}

static int p54_compare_rssichan(const void *_a,
				const void *_b)
{
	const struct p54_rssi_db_entry *a = _a;
	const struct p54_rssi_db_entry *b = _b;

	return a->freq - b->freq;
}

static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
				  struct ieee80211_supported_band *band_entry,
				  enum ieee80211_band band)
{
	/* TODO: generate rate array dynamically */

	switch (band) {
	case IEEE80211_BAND_2GHZ:
		band_entry->bitrates = p54_bgrates;
		band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
		break;
	case IEEE80211_BAND_5GHZ:
		band_entry->bitrates = p54_arates;
		band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int p54_generate_band(struct ieee80211_hw *dev,
			     struct p54_channel_list *list,
			     unsigned int *chan_num,
			     enum ieee80211_band band)
{
	struct p54_common *priv = dev->priv;
	struct ieee80211_supported_band *tmp, *old;
	unsigned int i, j;
	int ret = -ENOMEM;

	if ((!list->entries) || (!list->band_channel_num[band]))
		return -EINVAL;

	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
	if (!tmp)
		goto err_out;

	tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
				list->band_channel_num[band], GFP_KERNEL);
	if (!tmp->channels)
		goto err_out;

	ret = p54_fill_band_bitrates(dev, tmp, band);
	if (ret)
		goto err_out;

	for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
			   (i < list->entries); i++) {
		struct p54_channel_entry *chan = &list->channels[i];

		if (chan->band != band)
			continue;

		if (chan->data != CHAN_HAS_ALL) {
			wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
				  "channel:%d [%d MHz].\n",
				  (chan->data & CHAN_HAS_CAL ? "" :
				   " [iqauto calibration data]"),
				  (chan->data & CHAN_HAS_LIMIT ? "" :
				   " [output power limits]"),
				  (chan->data & CHAN_HAS_CURVE ? "" :
				   " [curve data]"),
				  chan->index, chan->freq);
			continue;
		}

		tmp->channels[j].band = chan->band;
		tmp->channels[j].center_freq = chan->freq;
		priv->survey[*chan_num].channel = &tmp->channels[j];
		priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
			SURVEY_INFO_CHANNEL_TIME |
			SURVEY_INFO_CHANNEL_TIME_BUSY |
			SURVEY_INFO_CHANNEL_TIME_TX;
		tmp->channels[j].hw_value = (*chan_num);
		j++;
		(*chan_num)++;
	}

	if (j == 0) {
		wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
			  (band == IEEE80211_BAND_2GHZ) ? 2 : 5);

		ret = -ENODATA;
		goto err_out;
	}

	tmp->n_channels = j;
	old = priv->band_table[band];
	priv->band_table[band] = tmp;
	if (old) {
		kfree(old->channels);
		kfree(old);
	}

	return 0;

err_out:
	if (tmp) {
		kfree(tmp->channels);
		kfree(tmp);
	}

	return ret;
}

static void p54_update_channel_param(struct p54_channel_list *list,
				     u16 freq, u16 data)
{
	int band, i;

	/*
	 * usually all lists in the eeprom are mostly sorted.
	 * so it's very likely that the entry we are looking for
	 * is right at the end of the list
	 */
	for (i = list->entries; i >= 0; i--) {
		if (freq == list->channels[i].freq) {
			list->channels[i].data |= data;
			break;
		}
	}

	if ((i < 0) && (list->entries < list->max_entries)) {
		/* entry does not exist yet. Initialize a new one. */
		band = p54_get_band_from_freq(freq);

		/*
		 * filter out frequencies which don't belong into
		 * any supported band.
		 */
		if (band < 0)
			return ;

		i = list->entries++;
		list->band_channel_num[band]++;

		list->channels[i].freq = freq;
		list->channels[i].data = data;
		list->channels[i].band = band;
		list->channels[i].index = ieee80211_frequency_to_channel(freq);
		/* TODO: parse output_limit and fill max_power */
	}
}

static int p54_generate_channel_lists(struct ieee80211_hw *dev)
{
	struct p54_common *priv = dev->priv;
	struct p54_channel_list *list;
	unsigned int i, j, k, max_channel_num;
	int ret = 0;
	u16 freq;

	if ((priv->iq_autocal_len != priv->curve_data->entries) ||
	    (priv->iq_autocal_len != priv->output_limit->entries))
		wiphy_err(dev->wiphy,
			  "Unsupported or damaged EEPROM detected. "
			  "You may not be able to use all channels.\n");

	max_channel_num = max_t(unsigned int, priv->output_limit->entries,
				priv->iq_autocal_len);
	max_channel_num = max_t(unsigned int, max_channel_num,
				priv->curve_data->entries);

	list = kzalloc(sizeof(*list), GFP_KERNEL);
	if (!list) {
		ret = -ENOMEM;
		goto free;
	}
	priv->chan_num = max_channel_num;
	priv->survey = kzalloc(sizeof(struct survey_info) * max_channel_num,
			       GFP_KERNEL);
	if (!priv->survey) {
		ret = -ENOMEM;
		goto free;
	}

	list->max_entries = max_channel_num;
	list->channels = kzalloc(sizeof(struct p54_channel_entry) *
				 max_channel_num, GFP_KERNEL);
	if (!list->channels) {
		ret = -ENOMEM;
		goto free;
	}

	for (i = 0; i < max_channel_num; i++) {
		if (i < priv->iq_autocal_len) {
			freq = le16_to_cpu(priv->iq_autocal[i].freq);
			p54_update_channel_param(list, freq, CHAN_HAS_CAL);
		}

		if (i < priv->output_limit->entries) {
			freq = le16_to_cpup((__le16 *) (i *
					    priv->output_limit->entry_size +
					    priv->output_limit->offset +
					    priv->output_limit->data));

			p54_update_channel_param(list, freq, CHAN_HAS_LIMIT);
		}

		if (i < priv->curve_data->entries) {
			freq = le16_to_cpup((__le16 *) (i *
					    priv->curve_data->entry_size +
					    priv->curve_data->offset +
					    priv->curve_data->data));

			p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
		}
	}

	/* sort the channel list by frequency */
	sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
	     p54_compare_channels, NULL);

	k = 0;
	for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
		if (p54_generate_band(dev, list, &k, i) == 0)
			j++;
	}
	if (j == 0) {
		/* no useable band available. */
		ret = -EINVAL;
	}

free:
	if (list) {
		kfree(list->channels);
		kfree(list);
	}
	if (ret) {
		kfree(priv->survey);
		priv->survey = NULL;
	}

	return ret;
}

static int p54_convert_rev0(struct ieee80211_hw *dev,
			    struct pda_pa_curve_data *curve_data)
{
	struct p54_common *priv = dev->priv;
	struct p54_pa_curve_data_sample *dst;
	struct pda_pa_curve_data_sample_rev0 *src;
	size_t cd_len = sizeof(*curve_data) +
		(curve_data->points_per_channel*sizeof(*dst) + 2) *
		 curve_data->channels;
	unsigned int i, j;
	void *source, *target;

	priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
				   GFP_KERNEL);
	if (!priv->curve_data)
		return -ENOMEM;

	priv->curve_data->entries = curve_data->channels;
	priv->curve_data->entry_size = sizeof(__le16) +
		sizeof(*dst) * curve_data->points_per_channel;
	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
	priv->curve_data->len = cd_len;
	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
	source = curve_data->data;
	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
	for (i = 0; i < curve_data->channels; i++) {
		__le16 *freq = source;
		source += sizeof(__le16);
		*((__le16 *)target) = *freq;
		target += sizeof(__le16);
		for (j = 0; j < curve_data->points_per_channel; j++) {
			dst = target;
			src = source;

			dst->rf_power = src->rf_power;
			dst->pa_detector = src->pa_detector;
			dst->data_64qam = src->pcv;
			/* "invent" the points for the other modulations */
#define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
			dst->data_16qam = SUB(src->pcv, 12);
			dst->data_qpsk = SUB(dst->data_16qam, 12);
			dst->data_bpsk = SUB(dst->data_qpsk, 12);
			dst->data_barker = SUB(dst->data_bpsk, 14);
#undef SUB
			target += sizeof(*dst);
			source += sizeof(*src);
		}
	}

	return 0;
}

static int p54_convert_rev1(struct ieee80211_hw *dev,
			    struct pda_pa_curve_data *curve_data)
{
	struct p54_common *priv = dev->priv;
	struct p54_pa_curve_data_sample *dst;
	struct pda_pa_curve_data_sample_rev1 *src;
	size_t cd_len = sizeof(*curve_data) +
		(curve_data->points_per_channel*sizeof(*dst) + 2) *
		 curve_data->channels;
	unsigned int i, j;
	void *source, *target;

	priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
				   GFP_KERNEL);
	if (!priv->curve_data)
		return -ENOMEM;

	priv->curve_data->entries = curve_data->channels;
	priv->curve_data->entry_size = sizeof(__le16) +
		sizeof(*dst) * curve_data->points_per_channel;
	priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
	priv->curve_data->len = cd_len;
	memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
	source = curve_data->data;
	target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
	for (i = 0; i < curve_data->channels; i++) {
		__le16 *freq = source;
		source += sizeof(__le16);
		*((__le16 *)target) = *freq;
		target += sizeof(__le16);
		for (j = 0; j < curve_data->points_per_channel; j++) {
			memcpy(target, source, sizeof(*src));

			target += sizeof(*dst);
			source += sizeof(*src);
		}
		source++;
	}

	return 0;
}

static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
	"Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };

static int p54_parse_rssical(struct ieee80211_hw *dev,
			     u8 *data, int len, u16 type)
{
	struct p54_common *priv = dev->priv;
	struct p54_rssi_db_entry *entry;
	size_t db_len, entries;
	int offset = 0, i;

	if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
		entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
		if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
			wiphy_err(dev->wiphy, "rssical size mismatch.\n");
			goto err_data;
		}
	} else {
		/*
		 * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
		 * have an empty two byte header.
		 */
		if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
			offset += 2;

		entries = (len - offset) /
			sizeof(struct pda_rssi_cal_ext_entry);

		if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
		    entries <= 0) {
			wiphy_err(dev->wiphy, "invalid rssi database.\n");
			goto err_data;
		}
	}

	db_len = sizeof(*entry) * entries;
	priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
	if (!priv->rssi_db)
		return -ENOMEM;

	priv->rssi_db->offset = 0;
	priv->rssi_db->entries = entries;
	priv->rssi_db->entry_size = sizeof(*entry);
	priv->rssi_db->len = db_len;

	entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
	if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
		struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];

		for (i = 0; i < entries; i++) {
			entry[i].freq = le16_to_cpu(cal[i].freq);
			entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
			entry[i].add = (s16) le16_to_cpu(cal[i].add);
		}
	} else {
		struct pda_rssi_cal_entry *cal = (void *) &data[offset];

		for (i = 0; i < entries; i++) {
			u16 freq = 0;
			switch (i) {
			case IEEE80211_BAND_2GHZ:
				freq = 2437;
				break;
			case IEEE80211_BAND_5GHZ:
				freq = 5240;
				break;
			}

			entry[i].freq = freq;
			entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
			entry[i].add = (s16) le16_to_cpu(cal[i].add);
		}
	}

	/* sort the list by channel frequency */
	sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
	return 0;

err_data:
	wiphy_err(dev->wiphy,
		  "rssi calibration data packing type:(%x) len:%d.\n",
		  type, len);

	print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);

	wiphy_err(dev->wiphy, "please report this issue.\n");
	return -EINVAL;
}

struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
{
	struct p54_rssi_db_entry *entry;
	int i, found = -1;

	if (!priv->rssi_db)
		return &p54_rssi_default;

	entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
	for (i = 0; i < priv->rssi_db->entries; i++) {
		if (!same_band(freq, entry[i].freq))
			continue;

		if (found == -1) {
			found = i;
			continue;
		}

		/* nearest match */
		if (abs(freq - entry[i].freq) <
		    abs(freq - entry[found].freq)) {
			found = i;
			continue;
		} else {
			break;
		}
	}

	return found < 0 ? &p54_rssi_default : &entry[found];
}

static void p54_parse_default_country(struct ieee80211_hw *dev,
				      void *data, int len)
{
	struct pda_country *country;

	if (len != sizeof(*country)) {
		wiphy_err(dev->wiphy,
			  "found possible invalid default country eeprom entry. (entry size: %d)\n",
			  len);

		print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
				     data, len);

		wiphy_err(dev->wiphy, "please report this issue.\n");
		return;
	}

	country = (struct pda_country *) data;
	if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
		regulatory_hint(dev->wiphy, country->alpha2);
	else {
		/* TODO:
		 * write a shared/common function that converts
		 * "Regulatory domain codes" (802.11-2007 14.8.2.2)
		 * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
		 */
	}
}

static int p54_convert_output_limits(struct ieee80211_hw *dev,
				     u8 *data, size_t len)
{
	struct p54_common *priv = dev->priv;

	if (len < 2)
		return -EINVAL;

	if (data[0] != 0) {
		wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
			  data[0]);
		return -EINVAL;
	}

	if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
		return -EINVAL;

	priv->output_limit = kmalloc(data[1] *
		sizeof(struct pda_channel_output_limit) +
		sizeof(*priv->output_limit), GFP_KERNEL);

	if (!priv->output_limit)
		return -ENOMEM;

	priv->output_limit->offset = 0;
	priv->output_limit->entries = data[1];
	priv->output_limit->entry_size =
		sizeof(struct pda_channel_output_limit);
	priv->output_limit->len = priv->output_limit->entry_size *
				  priv->output_limit->entries +
				  priv->output_limit->offset;

	memcpy(priv->output_limit->data, &data[2],
	       data[1] * sizeof(struct pda_channel_output_limit));

	return 0;
}

static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
					       size_t total_len)
{
	struct p54_cal_database *dst;
	size_t payload_len, entries, entry_size, offset;

	payload_len = le16_to_cpu(src->len);
	entries = le16_to_cpu(src->entries);
	entry_size = le16_to_cpu(src->entry_size);
	offset = le16_to_cpu(src->offset);
	if (((entries * entry_size + offset) != payload_len) ||
	     (payload_len + sizeof(*src) != total_len))
		return NULL;

	dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
	if (!dst)
		return NULL;

	dst->entries = entries;
	dst->entry_size = entry_size;
	dst->offset = offset;
	dst->len = payload_len;

	memcpy(dst->data, src->data, payload_len);
	return dst;
}

int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
{
	struct p54_common *priv = dev->priv;
	struct eeprom_pda_wrap *wrap;
	struct pda_entry *entry;
	unsigned int data_len, entry_len;
	void *tmp;
	int err;
	u8 *end = (u8 *)eeprom + len;
	u16 synth = 0;
	u16 crc16 = ~0;

	wrap = (struct eeprom_pda_wrap *) eeprom;
	entry = (void *)wrap->data + le16_to_cpu(wrap->len);

	/* verify that at least the entry length/code fits */
	while ((u8 *)entry <= end - sizeof(*entry)) {
		entry_len = le16_to_cpu(entry->len);
		data_len = ((entry_len - 1) << 1);

		/* abort if entry exceeds whole structure */
		if ((u8 *)entry + sizeof(*entry) + data_len > end)
			break;

		switch (le16_to_cpu(entry->code)) {
		case PDR_MAC_ADDRESS:
			if (data_len != ETH_ALEN)
				break;
			SET_IEEE80211_PERM_ADDR(dev, entry->data);
			break;
		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
			if (priv->output_limit)
				break;
			err = p54_convert_output_limits(dev, entry->data,
							data_len);
			if (err)
				goto err;
			break;
		case PDR_PRISM_PA_CAL_CURVE_DATA: {
			struct pda_pa_curve_data *curve_data =
				(struct pda_pa_curve_data *)entry->data;
			if (data_len < sizeof(*curve_data)) {
				err = -EINVAL;
				goto err;
			}

			switch (curve_data->cal_method_rev) {
			case 0:
				err = p54_convert_rev0(dev, curve_data);
				break;
			case 1:
				err = p54_convert_rev1(dev, curve_data);
				break;
			default:
				wiphy_err(dev->wiphy,
					  "unknown curve data revision %d\n",
					  curve_data->cal_method_rev);
				err = -ENODEV;
				break;
			}
			if (err)
				goto err;
			}
			break;
		case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
			priv->iq_autocal = kmemdup(entry->data, data_len,
						   GFP_KERNEL);
			if (!priv->iq_autocal) {
				err = -ENOMEM;
				goto err;
			}

			priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
			break;
		case PDR_DEFAULT_COUNTRY:
			p54_parse_default_country(dev, entry->data, data_len);
			break;
		case PDR_INTERFACE_LIST:
			tmp = entry->data;
			while ((u8 *)tmp < entry->data + data_len) {
				struct exp_if *exp_if = tmp;
				if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
					synth = le16_to_cpu(exp_if->variant);
				tmp += sizeof(*exp_if);
			}
			break;
		case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
			if (data_len < 2)
				break;
			priv->version = *(u8 *)(entry->data + 1);
			break;
		case PDR_RSSI_LINEAR_APPROXIMATION:
		case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
		case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
			err = p54_parse_rssical(dev, entry->data, data_len,
						le16_to_cpu(entry->code));
			if (err)
				goto err;
			break;
		case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
			struct pda_custom_wrapper *pda = (void *) entry->data;
			__le16 *src;
			u16 *dst;
			int i;

			if (priv->rssi_db || data_len < sizeof(*pda))
				break;

			priv->rssi_db = p54_convert_db(pda, data_len);
			if (!priv->rssi_db)
				break;

			src = (void *) priv->rssi_db->data;
			dst = (void *) priv->rssi_db->data;

			for (i = 0; i < priv->rssi_db->entries; i++)
				*(dst++) = (s16) le16_to_cpu(*(src++));

			}
			break;
		case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
			struct pda_custom_wrapper *pda = (void *) entry->data;
			if (priv->output_limit || data_len < sizeof(*pda))
				break;
			priv->output_limit = p54_convert_db(pda, data_len);
			}
			break;
		case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
			struct pda_custom_wrapper *pda = (void *) entry->data;
			if (priv->curve_data || data_len < sizeof(*pda))
				break;
			priv->curve_data = p54_convert_db(pda, data_len);
			}
			break;
		case PDR_END:
			crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
			if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
				wiphy_err(dev->wiphy, "eeprom failed checksum "
					 "test!\n");
				err = -ENOMSG;
				goto err;
			} else {
				goto good_eeprom;
			}
			break;
		default:
			break;
		}

		crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
		entry = (void *)entry + (entry_len + 1) * 2;
	}

	wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
	err = -ENODATA;
	goto err;

good_eeprom:
	if (!synth || !priv->iq_autocal || !priv->output_limit ||
	    !priv->curve_data) {
		wiphy_err(dev->wiphy,
			  "not all required entries found in eeprom!\n");
		err = -EINVAL;
		goto err;
	}

	err = p54_generate_channel_lists(dev);
	if (err)
		goto err;

	priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
	if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
		p54_init_xbow_synth(priv);
	if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
		dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
			priv->band_table[IEEE80211_BAND_2GHZ];
	if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
		dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
			priv->band_table[IEEE80211_BAND_5GHZ];
	if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
		priv->rx_diversity_mask = 3;
	if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
		priv->tx_diversity_mask = 3;

	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
		u8 perm_addr[ETH_ALEN];

		wiphy_warn(dev->wiphy,
			   "Invalid hwaddr! Using randomly generated MAC addr\n");
		random_ether_addr(perm_addr);
		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
	}

	priv->cur_rssi = &p54_rssi_default;

	wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
		   dev->wiphy->perm_addr, priv->version,
		   p54_rf_chips[priv->rxhw]);

	return 0;

err:
	kfree(priv->iq_autocal);
	kfree(priv->output_limit);
	kfree(priv->curve_data);
	kfree(priv->rssi_db);
	kfree(priv->survey);
	priv->iq_autocal = NULL;
	priv->output_limit = NULL;
	priv->curve_data = NULL;
	priv->rssi_db = NULL;
	priv->survey = NULL;

	wiphy_err(dev->wiphy, "eeprom parse failed!\n");
	return err;
}
EXPORT_SYMBOL_GPL(p54_parse_eeprom);

int p54_read_eeprom(struct ieee80211_hw *dev)
{
	struct p54_common *priv = dev->priv;
	size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
	int ret = -ENOMEM;
	void *eeprom;

	maxblocksize = EEPROM_READBACK_LEN;
	if (priv->fw_var >= 0x509)
		maxblocksize -= 0xc;
	else
		maxblocksize -= 0x4;

	eeprom = kzalloc(eeprom_size, GFP_KERNEL);
	if (unlikely(!eeprom))
		goto free;

	while (eeprom_size) {
		blocksize = min(eeprom_size, maxblocksize);
		ret = p54_download_eeprom(priv, (void *) (eeprom + offset),
					  offset, blocksize);
		if (unlikely(ret))
			goto free;

		offset += blocksize;
		eeprom_size -= blocksize;
	}

	ret = p54_parse_eeprom(dev, eeprom, offset);
free:
	kfree(eeprom);
	return ret;
}
EXPORT_SYMBOL_GPL(p54_read_eeprom);
