2 * EEPROM parser code for mac80211 Prism54 drivers
4 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
5 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
6 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
9 * - the islsm (softmac prism54) driver, which is:
10 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
19 #include <linux/init.h>
20 #include <linux/firmware.h>
21 #include <linux/etherdevice.h>
22 #include <linux/sort.h>
23 #include <linux/slab.h>
25 #include <net/mac80211.h>
26 #include <linux/crc-ccitt.h>
27 #include <linux/export.h>
33 static struct ieee80211_rate p54_bgrates[] = {
34 { .bitrate = 10, .hw_value = 0, },
35 { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
36 { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
37 { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
38 { .bitrate = 60, .hw_value = 4, },
39 { .bitrate = 90, .hw_value = 5, },
40 { .bitrate = 120, .hw_value = 6, },
41 { .bitrate = 180, .hw_value = 7, },
42 { .bitrate = 240, .hw_value = 8, },
43 { .bitrate = 360, .hw_value = 9, },
44 { .bitrate = 480, .hw_value = 10, },
45 { .bitrate = 540, .hw_value = 11, },
48 static struct ieee80211_rate p54_arates[] = {
49 { .bitrate = 60, .hw_value = 4, },
50 { .bitrate = 90, .hw_value = 5, },
51 { .bitrate = 120, .hw_value = 6, },
52 { .bitrate = 180, .hw_value = 7, },
53 { .bitrate = 240, .hw_value = 8, },
54 { .bitrate = 360, .hw_value = 9, },
55 { .bitrate = 480, .hw_value = 10, },
56 { .bitrate = 540, .hw_value = 11, },
59 static struct p54_rssi_db_entry p54_rssi_default = {
61 * The defaults are taken from usb-logs of the
62 * vendor driver. So, they should be safe to
63 * use in case we can't get a match from the
64 * rssi <-> dBm conversion database.
70 #define CHAN_HAS_CAL BIT(0)
71 #define CHAN_HAS_LIMIT BIT(1)
72 #define CHAN_HAS_CURVE BIT(2)
73 #define CHAN_HAS_ALL (CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)
75 struct p54_channel_entry {
80 enum ieee80211_band band;
83 struct p54_channel_list {
84 struct p54_channel_entry *channels;
87 size_t band_channel_num[IEEE80211_NUM_BANDS];
90 static int p54_get_band_from_freq(u16 freq)
92 /* FIXME: sync these values with the 802.11 spec */
94 if ((freq >= 2412) && (freq <= 2484))
95 return IEEE80211_BAND_2GHZ;
97 if ((freq >= 4920) && (freq <= 5825))
98 return IEEE80211_BAND_5GHZ;
103 static int same_band(u16 freq, u16 freq2)
105 return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
108 static int p54_compare_channels(const void *_a,
111 const struct p54_channel_entry *a = _a;
112 const struct p54_channel_entry *b = _b;
114 return a->freq - b->freq;
117 static int p54_compare_rssichan(const void *_a,
120 const struct p54_rssi_db_entry *a = _a;
121 const struct p54_rssi_db_entry *b = _b;
123 return a->freq - b->freq;
126 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
127 struct ieee80211_supported_band *band_entry,
128 enum ieee80211_band band)
130 /* TODO: generate rate array dynamically */
133 case IEEE80211_BAND_2GHZ:
134 band_entry->bitrates = p54_bgrates;
135 band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
137 case IEEE80211_BAND_5GHZ:
138 band_entry->bitrates = p54_arates;
139 band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
148 static int p54_generate_band(struct ieee80211_hw *dev,
149 struct p54_channel_list *list,
150 unsigned int *chan_num,
151 enum ieee80211_band band)
153 struct p54_common *priv = dev->priv;
154 struct ieee80211_supported_band *tmp, *old;
158 if ((!list->entries) || (!list->band_channel_num[band]))
161 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
165 tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
166 list->band_channel_num[band], GFP_KERNEL);
170 ret = p54_fill_band_bitrates(dev, tmp, band);
174 for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
175 (i < list->entries); i++) {
176 struct p54_channel_entry *chan = &list->channels[i];
177 struct ieee80211_channel *dest = &tmp->channels[j];
179 if (chan->band != band)
182 if (chan->data != CHAN_HAS_ALL) {
183 wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
184 "channel:%d [%d MHz].\n",
185 (chan->data & CHAN_HAS_CAL ? "" :
186 " [iqauto calibration data]"),
187 (chan->data & CHAN_HAS_LIMIT ? "" :
188 " [output power limits]"),
189 (chan->data & CHAN_HAS_CURVE ? "" :
191 chan->index, chan->freq);
195 dest->band = chan->band;
196 dest->center_freq = chan->freq;
197 dest->max_power = chan->max_power;
198 priv->survey[*chan_num].channel = &tmp->channels[j];
199 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
200 SURVEY_INFO_CHANNEL_TIME |
201 SURVEY_INFO_CHANNEL_TIME_BUSY |
202 SURVEY_INFO_CHANNEL_TIME_TX;
203 dest->hw_value = (*chan_num);
209 wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
210 (band == IEEE80211_BAND_2GHZ) ? 2 : 5);
217 old = priv->band_table[band];
218 priv->band_table[band] = tmp;
220 kfree(old->channels);
228 kfree(tmp->channels);
235 static struct p54_channel_entry *p54_update_channel_param(struct p54_channel_list *list,
239 struct p54_channel_entry *entry = NULL;
242 * usually all lists in the eeprom are mostly sorted.
243 * so it's very likely that the entry we are looking for
244 * is right at the end of the list
246 for (i = list->entries; i >= 0; i--) {
247 if (freq == list->channels[i].freq) {
248 entry = &list->channels[i];
253 if ((i < 0) && (list->entries < list->max_entries)) {
254 /* entry does not exist yet. Initialize a new one. */
255 int band = p54_get_band_from_freq(freq);
258 * filter out frequencies which don't belong into
259 * any supported band.
263 list->band_channel_num[band]++;
265 entry = &list->channels[i];
268 entry->index = ieee80211_frequency_to_channel(freq);
269 entry->max_power = 0;
280 static int p54_get_maxpower(struct p54_common *priv, void *data)
282 switch (priv->rxhw & PDR_SYNTH_FRONTEND_MASK) {
283 case PDR_SYNTH_FRONTEND_LONGBOW: {
284 struct pda_channel_output_limit_longbow *pda = data;
288 for (j = 0; j < ARRAY_SIZE(pda->point); j++) {
289 struct pda_channel_output_limit_point_longbow *point =
291 rawpower = max(rawpower, le16_to_cpu(point->val_qpsk));
292 rawpower = max(rawpower, le16_to_cpu(point->val_bpsk));
293 rawpower = max(rawpower, le16_to_cpu(point->val_16qam));
294 rawpower = max(rawpower, le16_to_cpu(point->val_64qam));
296 /* longbow seems to use 1/16 dBm units */
297 return rawpower / 16;
300 case PDR_SYNTH_FRONTEND_DUETTE3:
301 case PDR_SYNTH_FRONTEND_DUETTE2:
302 case PDR_SYNTH_FRONTEND_FRISBEE:
303 case PDR_SYNTH_FRONTEND_XBOW: {
304 struct pda_channel_output_limit *pda = data;
306 rawpower = max(rawpower, pda->val_qpsk);
307 rawpower = max(rawpower, pda->val_bpsk);
308 rawpower = max(rawpower, pda->val_16qam);
309 rawpower = max(rawpower, pda->val_64qam);
310 /* raw values are in 1/4 dBm units */
319 static int p54_generate_channel_lists(struct ieee80211_hw *dev)
321 struct p54_common *priv = dev->priv;
322 struct p54_channel_list *list;
323 unsigned int i, j, k, max_channel_num;
327 if ((priv->iq_autocal_len != priv->curve_data->entries) ||
328 (priv->iq_autocal_len != priv->output_limit->entries))
329 wiphy_err(dev->wiphy,
330 "Unsupported or damaged EEPROM detected. "
331 "You may not be able to use all channels.\n");
333 max_channel_num = max_t(unsigned int, priv->output_limit->entries,
334 priv->iq_autocal_len);
335 max_channel_num = max_t(unsigned int, max_channel_num,
336 priv->curve_data->entries);
338 list = kzalloc(sizeof(*list), GFP_KERNEL);
343 priv->chan_num = max_channel_num;
344 priv->survey = kzalloc(sizeof(struct survey_info) * max_channel_num,
351 list->max_entries = max_channel_num;
352 list->channels = kzalloc(sizeof(struct p54_channel_entry) *
353 max_channel_num, GFP_KERNEL);
354 if (!list->channels) {
359 for (i = 0; i < max_channel_num; i++) {
360 if (i < priv->iq_autocal_len) {
361 freq = le16_to_cpu(priv->iq_autocal[i].freq);
362 p54_update_channel_param(list, freq, CHAN_HAS_CAL);
365 if (i < priv->output_limit->entries) {
366 struct p54_channel_entry *tmp;
368 void *data = (void *) ((unsigned long) i *
369 priv->output_limit->entry_size +
370 priv->output_limit->offset +
371 priv->output_limit->data);
373 freq = le16_to_cpup((__le16 *) data);
374 tmp = p54_update_channel_param(list, freq,
377 tmp->max_power = p54_get_maxpower(priv, data);
381 if (i < priv->curve_data->entries) {
382 freq = le16_to_cpup((__le16 *) (i *
383 priv->curve_data->entry_size +
384 priv->curve_data->offset +
385 priv->curve_data->data));
387 p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
391 /* sort the channel list by frequency */
392 sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
393 p54_compare_channels, NULL);
396 for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
397 if (p54_generate_band(dev, list, &k, i) == 0)
401 /* no useable band available. */
407 kfree(list->channels);
418 static int p54_convert_rev0(struct ieee80211_hw *dev,
419 struct pda_pa_curve_data *curve_data)
421 struct p54_common *priv = dev->priv;
422 struct p54_pa_curve_data_sample *dst;
423 struct pda_pa_curve_data_sample_rev0 *src;
424 size_t cd_len = sizeof(*curve_data) +
425 (curve_data->points_per_channel*sizeof(*dst) + 2) *
426 curve_data->channels;
428 void *source, *target;
430 priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
432 if (!priv->curve_data)
435 priv->curve_data->entries = curve_data->channels;
436 priv->curve_data->entry_size = sizeof(__le16) +
437 sizeof(*dst) * curve_data->points_per_channel;
438 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
439 priv->curve_data->len = cd_len;
440 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
441 source = curve_data->data;
442 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
443 for (i = 0; i < curve_data->channels; i++) {
444 __le16 *freq = source;
445 source += sizeof(__le16);
446 *((__le16 *)target) = *freq;
447 target += sizeof(__le16);
448 for (j = 0; j < curve_data->points_per_channel; j++) {
452 dst->rf_power = src->rf_power;
453 dst->pa_detector = src->pa_detector;
454 dst->data_64qam = src->pcv;
455 /* "invent" the points for the other modulations */
456 #define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
457 dst->data_16qam = SUB(src->pcv, 12);
458 dst->data_qpsk = SUB(dst->data_16qam, 12);
459 dst->data_bpsk = SUB(dst->data_qpsk, 12);
460 dst->data_barker = SUB(dst->data_bpsk, 14);
462 target += sizeof(*dst);
463 source += sizeof(*src);
470 static int p54_convert_rev1(struct ieee80211_hw *dev,
471 struct pda_pa_curve_data *curve_data)
473 struct p54_common *priv = dev->priv;
474 struct p54_pa_curve_data_sample *dst;
475 struct pda_pa_curve_data_sample_rev1 *src;
476 size_t cd_len = sizeof(*curve_data) +
477 (curve_data->points_per_channel*sizeof(*dst) + 2) *
478 curve_data->channels;
480 void *source, *target;
482 priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
484 if (!priv->curve_data)
487 priv->curve_data->entries = curve_data->channels;
488 priv->curve_data->entry_size = sizeof(__le16) +
489 sizeof(*dst) * curve_data->points_per_channel;
490 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
491 priv->curve_data->len = cd_len;
492 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
493 source = curve_data->data;
494 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
495 for (i = 0; i < curve_data->channels; i++) {
496 __le16 *freq = source;
497 source += sizeof(__le16);
498 *((__le16 *)target) = *freq;
499 target += sizeof(__le16);
500 for (j = 0; j < curve_data->points_per_channel; j++) {
501 memcpy(target, source, sizeof(*src));
503 target += sizeof(*dst);
504 source += sizeof(*src);
512 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
513 "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
515 static int p54_parse_rssical(struct ieee80211_hw *dev,
516 u8 *data, int len, u16 type)
518 struct p54_common *priv = dev->priv;
519 struct p54_rssi_db_entry *entry;
520 size_t db_len, entries;
523 if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
524 entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
525 if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
526 wiphy_err(dev->wiphy, "rssical size mismatch.\n");
531 * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
532 * have an empty two byte header.
534 if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
537 entries = (len - offset) /
538 sizeof(struct pda_rssi_cal_ext_entry);
540 if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
542 wiphy_err(dev->wiphy, "invalid rssi database.\n");
547 db_len = sizeof(*entry) * entries;
548 priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
552 priv->rssi_db->offset = 0;
553 priv->rssi_db->entries = entries;
554 priv->rssi_db->entry_size = sizeof(*entry);
555 priv->rssi_db->len = db_len;
557 entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
558 if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
559 struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
561 for (i = 0; i < entries; i++) {
562 entry[i].freq = le16_to_cpu(cal[i].freq);
563 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
564 entry[i].add = (s16) le16_to_cpu(cal[i].add);
567 struct pda_rssi_cal_entry *cal = (void *) &data[offset];
569 for (i = 0; i < entries; i++) {
572 case IEEE80211_BAND_2GHZ:
575 case IEEE80211_BAND_5GHZ:
580 entry[i].freq = freq;
581 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
582 entry[i].add = (s16) le16_to_cpu(cal[i].add);
586 /* sort the list by channel frequency */
587 sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
591 wiphy_err(dev->wiphy,
592 "rssi calibration data packing type:(%x) len:%d.\n",
595 print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
597 wiphy_err(dev->wiphy, "please report this issue.\n");
601 struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
603 struct p54_rssi_db_entry *entry;
607 return &p54_rssi_default;
609 entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
610 for (i = 0; i < priv->rssi_db->entries; i++) {
611 if (!same_band(freq, entry[i].freq))
620 if (abs(freq - entry[i].freq) <
621 abs(freq - entry[found].freq)) {
629 return found < 0 ? &p54_rssi_default : &entry[found];
632 static void p54_parse_default_country(struct ieee80211_hw *dev,
635 struct pda_country *country;
637 if (len != sizeof(*country)) {
638 wiphy_err(dev->wiphy,
639 "found possible invalid default country eeprom entry. (entry size: %d)\n",
642 print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
645 wiphy_err(dev->wiphy, "please report this issue.\n");
649 country = (struct pda_country *) data;
650 if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
651 regulatory_hint(dev->wiphy, country->alpha2);
654 * write a shared/common function that converts
655 * "Regulatory domain codes" (802.11-2007 14.8.2.2)
656 * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
661 static int p54_convert_output_limits(struct ieee80211_hw *dev,
662 u8 *data, size_t len)
664 struct p54_common *priv = dev->priv;
670 wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
675 if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
678 priv->output_limit = kmalloc(data[1] *
679 sizeof(struct pda_channel_output_limit) +
680 sizeof(*priv->output_limit), GFP_KERNEL);
682 if (!priv->output_limit)
685 priv->output_limit->offset = 0;
686 priv->output_limit->entries = data[1];
687 priv->output_limit->entry_size =
688 sizeof(struct pda_channel_output_limit);
689 priv->output_limit->len = priv->output_limit->entry_size *
690 priv->output_limit->entries +
691 priv->output_limit->offset;
693 memcpy(priv->output_limit->data, &data[2],
694 data[1] * sizeof(struct pda_channel_output_limit));
699 static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
702 struct p54_cal_database *dst;
703 size_t payload_len, entries, entry_size, offset;
705 payload_len = le16_to_cpu(src->len);
706 entries = le16_to_cpu(src->entries);
707 entry_size = le16_to_cpu(src->entry_size);
708 offset = le16_to_cpu(src->offset);
709 if (((entries * entry_size + offset) != payload_len) ||
710 (payload_len + sizeof(*src) != total_len))
713 dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
717 dst->entries = entries;
718 dst->entry_size = entry_size;
719 dst->offset = offset;
720 dst->len = payload_len;
722 memcpy(dst->data, src->data, payload_len);
726 int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
728 struct p54_common *priv = dev->priv;
729 struct eeprom_pda_wrap *wrap;
730 struct pda_entry *entry;
731 unsigned int data_len, entry_len;
734 u8 *end = (u8 *)eeprom + len;
738 wrap = (struct eeprom_pda_wrap *) eeprom;
739 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
741 /* verify that at least the entry length/code fits */
742 while ((u8 *)entry <= end - sizeof(*entry)) {
743 entry_len = le16_to_cpu(entry->len);
744 data_len = ((entry_len - 1) << 1);
746 /* abort if entry exceeds whole structure */
747 if ((u8 *)entry + sizeof(*entry) + data_len > end)
750 switch (le16_to_cpu(entry->code)) {
751 case PDR_MAC_ADDRESS:
752 if (data_len != ETH_ALEN)
754 SET_IEEE80211_PERM_ADDR(dev, entry->data);
756 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
757 if (priv->output_limit)
759 err = p54_convert_output_limits(dev, entry->data,
764 case PDR_PRISM_PA_CAL_CURVE_DATA: {
765 struct pda_pa_curve_data *curve_data =
766 (struct pda_pa_curve_data *)entry->data;
767 if (data_len < sizeof(*curve_data)) {
772 switch (curve_data->cal_method_rev) {
774 err = p54_convert_rev0(dev, curve_data);
777 err = p54_convert_rev1(dev, curve_data);
780 wiphy_err(dev->wiphy,
781 "unknown curve data revision %d\n",
782 curve_data->cal_method_rev);
790 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
791 priv->iq_autocal = kmemdup(entry->data, data_len,
793 if (!priv->iq_autocal) {
798 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
800 case PDR_DEFAULT_COUNTRY:
801 p54_parse_default_country(dev, entry->data, data_len);
803 case PDR_INTERFACE_LIST:
805 while ((u8 *)tmp < entry->data + data_len) {
806 struct exp_if *exp_if = tmp;
807 if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
808 synth = le16_to_cpu(exp_if->variant);
809 tmp += sizeof(*exp_if);
812 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
815 priv->version = *(u8 *)(entry->data + 1);
817 case PDR_RSSI_LINEAR_APPROXIMATION:
818 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
819 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
820 err = p54_parse_rssical(dev, entry->data, data_len,
821 le16_to_cpu(entry->code));
825 case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
826 struct pda_custom_wrapper *pda = (void *) entry->data;
831 if (priv->rssi_db || data_len < sizeof(*pda))
834 priv->rssi_db = p54_convert_db(pda, data_len);
838 src = (void *) priv->rssi_db->data;
839 dst = (void *) priv->rssi_db->data;
841 for (i = 0; i < priv->rssi_db->entries; i++)
842 *(dst++) = (s16) le16_to_cpu(*(src++));
846 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
847 struct pda_custom_wrapper *pda = (void *) entry->data;
848 if (priv->output_limit || data_len < sizeof(*pda))
850 priv->output_limit = p54_convert_db(pda, data_len);
853 case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
854 struct pda_custom_wrapper *pda = (void *) entry->data;
855 if (priv->curve_data || data_len < sizeof(*pda))
857 priv->curve_data = p54_convert_db(pda, data_len);
861 crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
862 if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
863 wiphy_err(dev->wiphy, "eeprom failed checksum "
875 crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
876 entry = (void *)entry + (entry_len + 1) * 2;
879 wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
884 if (!synth || !priv->iq_autocal || !priv->output_limit ||
886 wiphy_err(dev->wiphy,
887 "not all required entries found in eeprom!\n");
892 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
894 err = p54_generate_channel_lists(dev);
898 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
899 p54_init_xbow_synth(priv);
900 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
901 dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
902 priv->band_table[IEEE80211_BAND_2GHZ];
903 if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
904 dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
905 priv->band_table[IEEE80211_BAND_5GHZ];
906 if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
907 priv->rx_diversity_mask = 3;
908 if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
909 priv->tx_diversity_mask = 3;
911 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
912 u8 perm_addr[ETH_ALEN];
914 wiphy_warn(dev->wiphy,
915 "Invalid hwaddr! Using randomly generated MAC addr\n");
916 eth_random_addr(perm_addr);
917 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
920 priv->cur_rssi = &p54_rssi_default;
922 wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
923 dev->wiphy->perm_addr, priv->version,
924 p54_rf_chips[priv->rxhw]);
929 kfree(priv->iq_autocal);
930 kfree(priv->output_limit);
931 kfree(priv->curve_data);
932 kfree(priv->rssi_db);
934 priv->iq_autocal = NULL;
935 priv->output_limit = NULL;
936 priv->curve_data = NULL;
937 priv->rssi_db = NULL;
940 wiphy_err(dev->wiphy, "eeprom parse failed!\n");
943 EXPORT_SYMBOL_GPL(p54_parse_eeprom);
945 int p54_read_eeprom(struct ieee80211_hw *dev)
947 struct p54_common *priv = dev->priv;
948 size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
952 maxblocksize = EEPROM_READBACK_LEN;
953 if (priv->fw_var >= 0x509)
958 eeprom = kzalloc(eeprom_size, GFP_KERNEL);
959 if (unlikely(!eeprom))
962 while (eeprom_size) {
963 blocksize = min(eeprom_size, maxblocksize);
964 ret = p54_download_eeprom(priv, eeprom + offset,
970 eeprom_size -= blocksize;
973 ret = p54_parse_eeprom(dev, eeprom, offset);
978 EXPORT_SYMBOL_GPL(p54_read_eeprom);