Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / wireless / p54 / eeprom.c
1 /*
2  * EEPROM parser code for mac80211 Prism54 drivers
3  *
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>
7  *
8  * Based on:
9  * - the islsm (softmac prism54) driver, which is:
10  *   Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
11  * - stlc45xx driver
12  *   Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
13  *
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.
17  */
18
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>
24
25 #include <net/mac80211.h>
26 #include <linux/crc-ccitt.h>
27
28 #include "p54.h"
29 #include "eeprom.h"
30 #include "lmac.h"
31
32 static struct ieee80211_rate p54_bgrates[] = {
33         { .bitrate = 10, .hw_value = 0, },
34         { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
35         { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
36         { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
37         { .bitrate = 60, .hw_value = 4, },
38         { .bitrate = 90, .hw_value = 5, },
39         { .bitrate = 120, .hw_value = 6, },
40         { .bitrate = 180, .hw_value = 7, },
41         { .bitrate = 240, .hw_value = 8, },
42         { .bitrate = 360, .hw_value = 9, },
43         { .bitrate = 480, .hw_value = 10, },
44         { .bitrate = 540, .hw_value = 11, },
45 };
46
47 static struct ieee80211_rate p54_arates[] = {
48         { .bitrate = 60, .hw_value = 4, },
49         { .bitrate = 90, .hw_value = 5, },
50         { .bitrate = 120, .hw_value = 6, },
51         { .bitrate = 180, .hw_value = 7, },
52         { .bitrate = 240, .hw_value = 8, },
53         { .bitrate = 360, .hw_value = 9, },
54         { .bitrate = 480, .hw_value = 10, },
55         { .bitrate = 540, .hw_value = 11, },
56 };
57
58 static struct p54_rssi_db_entry p54_rssi_default = {
59         /*
60          * The defaults are taken from usb-logs of the
61          * vendor driver. So, they should be safe to
62          * use in case we can't get a match from the
63          * rssi <-> dBm conversion database.
64          */
65         .mul = 130,
66         .add = -398,
67 };
68
69 #define CHAN_HAS_CAL            BIT(0)
70 #define CHAN_HAS_LIMIT          BIT(1)
71 #define CHAN_HAS_CURVE          BIT(2)
72 #define CHAN_HAS_ALL            (CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)
73
74 struct p54_channel_entry {
75         u16 freq;
76         u16 data;
77         int index;
78         enum ieee80211_band band;
79 };
80
81 struct p54_channel_list {
82         struct p54_channel_entry *channels;
83         size_t entries;
84         size_t max_entries;
85         size_t band_channel_num[IEEE80211_NUM_BANDS];
86 };
87
88 static int p54_get_band_from_freq(u16 freq)
89 {
90         /* FIXME: sync these values with the 802.11 spec */
91
92         if ((freq >= 2412) && (freq <= 2484))
93                 return IEEE80211_BAND_2GHZ;
94
95         if ((freq >= 4920) && (freq <= 5825))
96                 return IEEE80211_BAND_5GHZ;
97
98         return -1;
99 }
100
101 static int same_band(u16 freq, u16 freq2)
102 {
103         return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
104 }
105
106 static int p54_compare_channels(const void *_a,
107                                 const void *_b)
108 {
109         const struct p54_channel_entry *a = _a;
110         const struct p54_channel_entry *b = _b;
111
112         return a->freq - b->freq;
113 }
114
115 static int p54_compare_rssichan(const void *_a,
116                                 const void *_b)
117 {
118         const struct p54_rssi_db_entry *a = _a;
119         const struct p54_rssi_db_entry *b = _b;
120
121         return a->freq - b->freq;
122 }
123
124 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
125                                   struct ieee80211_supported_band *band_entry,
126                                   enum ieee80211_band band)
127 {
128         /* TODO: generate rate array dynamically */
129
130         switch (band) {
131         case IEEE80211_BAND_2GHZ:
132                 band_entry->bitrates = p54_bgrates;
133                 band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
134                 break;
135         case IEEE80211_BAND_5GHZ:
136                 band_entry->bitrates = p54_arates;
137                 band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
138                 break;
139         default:
140                 return -EINVAL;
141         }
142
143         return 0;
144 }
145
146 static int p54_generate_band(struct ieee80211_hw *dev,
147                              struct p54_channel_list *list,
148                              enum ieee80211_band band)
149 {
150         struct p54_common *priv = dev->priv;
151         struct ieee80211_supported_band *tmp, *old;
152         unsigned int i, j;
153         int ret = -ENOMEM;
154
155         if ((!list->entries) || (!list->band_channel_num[band]))
156                 return -EINVAL;
157
158         tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
159         if (!tmp)
160                 goto err_out;
161
162         tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
163                                 list->band_channel_num[band], GFP_KERNEL);
164         if (!tmp->channels)
165                 goto err_out;
166
167         ret = p54_fill_band_bitrates(dev, tmp, band);
168         if (ret)
169                 goto err_out;
170
171         for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
172                            (i < list->entries); i++) {
173                 struct p54_channel_entry *chan = &list->channels[i];
174
175                 if (chan->band != band)
176                         continue;
177
178                 if (chan->data != CHAN_HAS_ALL) {
179                         wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
180                                   "channel:%d [%d MHz].\n",
181                                   (chan->data & CHAN_HAS_CAL ? "" :
182                                    " [iqauto calibration data]"),
183                                   (chan->data & CHAN_HAS_LIMIT ? "" :
184                                    " [output power limits]"),
185                                   (chan->data & CHAN_HAS_CURVE ? "" :
186                                    " [curve data]"),
187                                   chan->index, chan->freq);
188                         continue;
189                 }
190
191                 tmp->channels[j].band = chan->band;
192                 tmp->channels[j].center_freq = chan->freq;
193                 j++;
194         }
195
196         if (j == 0) {
197                 wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
198                           (band == IEEE80211_BAND_2GHZ) ? 2 : 5);
199
200                 ret = -ENODATA;
201                 goto err_out;
202         }
203
204         tmp->n_channels = j;
205         old = priv->band_table[band];
206         priv->band_table[band] = tmp;
207         if (old) {
208                 kfree(old->channels);
209                 kfree(old);
210         }
211
212         return 0;
213
214 err_out:
215         if (tmp) {
216                 kfree(tmp->channels);
217                 kfree(tmp);
218         }
219
220         return ret;
221 }
222
223 static void p54_update_channel_param(struct p54_channel_list *list,
224                                      u16 freq, u16 data)
225 {
226         int band, i;
227
228         /*
229          * usually all lists in the eeprom are mostly sorted.
230          * so it's very likely that the entry we are looking for
231          * is right at the end of the list
232          */
233         for (i = list->entries; i >= 0; i--) {
234                 if (freq == list->channels[i].freq) {
235                         list->channels[i].data |= data;
236                         break;
237                 }
238         }
239
240         if ((i < 0) && (list->entries < list->max_entries)) {
241                 /* entry does not exist yet. Initialize a new one. */
242                 band = p54_get_band_from_freq(freq);
243
244                 /*
245                  * filter out frequencies which don't belong into
246                  * any supported band.
247                  */
248                 if (band < 0)
249                         return ;
250
251                 i = list->entries++;
252                 list->band_channel_num[band]++;
253
254                 list->channels[i].freq = freq;
255                 list->channels[i].data = data;
256                 list->channels[i].band = band;
257                 list->channels[i].index = ieee80211_frequency_to_channel(freq);
258                 /* TODO: parse output_limit and fill max_power */
259         }
260 }
261
262 static int p54_generate_channel_lists(struct ieee80211_hw *dev)
263 {
264         struct p54_common *priv = dev->priv;
265         struct p54_channel_list *list;
266         unsigned int i, j, max_channel_num;
267         int ret = 0;
268         u16 freq;
269
270         if ((priv->iq_autocal_len != priv->curve_data->entries) ||
271             (priv->iq_autocal_len != priv->output_limit->entries))
272                 wiphy_err(dev->wiphy,
273                           "Unsupported or damaged EEPROM detected. "
274                           "You may not be able to use all channels.\n");
275
276         max_channel_num = max_t(unsigned int, priv->output_limit->entries,
277                                 priv->iq_autocal_len);
278         max_channel_num = max_t(unsigned int, max_channel_num,
279                                 priv->curve_data->entries);
280
281         list = kzalloc(sizeof(*list), GFP_KERNEL);
282         if (!list) {
283                 ret = -ENOMEM;
284                 goto free;
285         }
286
287         list->max_entries = max_channel_num;
288         list->channels = kzalloc(sizeof(struct p54_channel_entry) *
289                                  max_channel_num, GFP_KERNEL);
290         if (!list->channels) {
291                 ret = -ENOMEM;
292                 goto free;
293         }
294
295         for (i = 0; i < max_channel_num; i++) {
296                 if (i < priv->iq_autocal_len) {
297                         freq = le16_to_cpu(priv->iq_autocal[i].freq);
298                         p54_update_channel_param(list, freq, CHAN_HAS_CAL);
299                 }
300
301                 if (i < priv->output_limit->entries) {
302                         freq = le16_to_cpup((__le16 *) (i *
303                                             priv->output_limit->entry_size +
304                                             priv->output_limit->offset +
305                                             priv->output_limit->data));
306
307                         p54_update_channel_param(list, freq, CHAN_HAS_LIMIT);
308                 }
309
310                 if (i < priv->curve_data->entries) {
311                         freq = le16_to_cpup((__le16 *) (i *
312                                             priv->curve_data->entry_size +
313                                             priv->curve_data->offset +
314                                             priv->curve_data->data));
315
316                         p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
317                 }
318         }
319
320         /* sort the channel list by frequency */
321         sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
322              p54_compare_channels, NULL);
323
324         for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
325                 if (p54_generate_band(dev, list, i) == 0)
326                         j++;
327         }
328         if (j == 0) {
329                 /* no useable band available. */
330                 ret = -EINVAL;
331         }
332
333 free:
334         if (list) {
335                 kfree(list->channels);
336                 kfree(list);
337         }
338
339         return ret;
340 }
341
342 static int p54_convert_rev0(struct ieee80211_hw *dev,
343                             struct pda_pa_curve_data *curve_data)
344 {
345         struct p54_common *priv = dev->priv;
346         struct p54_pa_curve_data_sample *dst;
347         struct pda_pa_curve_data_sample_rev0 *src;
348         size_t cd_len = sizeof(*curve_data) +
349                 (curve_data->points_per_channel*sizeof(*dst) + 2) *
350                  curve_data->channels;
351         unsigned int i, j;
352         void *source, *target;
353
354         priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
355                                    GFP_KERNEL);
356         if (!priv->curve_data)
357                 return -ENOMEM;
358
359         priv->curve_data->entries = curve_data->channels;
360         priv->curve_data->entry_size = sizeof(__le16) +
361                 sizeof(*dst) * curve_data->points_per_channel;
362         priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
363         priv->curve_data->len = cd_len;
364         memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
365         source = curve_data->data;
366         target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
367         for (i = 0; i < curve_data->channels; i++) {
368                 __le16 *freq = source;
369                 source += sizeof(__le16);
370                 *((__le16 *)target) = *freq;
371                 target += sizeof(__le16);
372                 for (j = 0; j < curve_data->points_per_channel; j++) {
373                         dst = target;
374                         src = source;
375
376                         dst->rf_power = src->rf_power;
377                         dst->pa_detector = src->pa_detector;
378                         dst->data_64qam = src->pcv;
379                         /* "invent" the points for the other modulations */
380 #define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
381                         dst->data_16qam = SUB(src->pcv, 12);
382                         dst->data_qpsk = SUB(dst->data_16qam, 12);
383                         dst->data_bpsk = SUB(dst->data_qpsk, 12);
384                         dst->data_barker = SUB(dst->data_bpsk, 14);
385 #undef SUB
386                         target += sizeof(*dst);
387                         source += sizeof(*src);
388                 }
389         }
390
391         return 0;
392 }
393
394 static int p54_convert_rev1(struct ieee80211_hw *dev,
395                             struct pda_pa_curve_data *curve_data)
396 {
397         struct p54_common *priv = dev->priv;
398         struct p54_pa_curve_data_sample *dst;
399         struct pda_pa_curve_data_sample_rev1 *src;
400         size_t cd_len = sizeof(*curve_data) +
401                 (curve_data->points_per_channel*sizeof(*dst) + 2) *
402                  curve_data->channels;
403         unsigned int i, j;
404         void *source, *target;
405
406         priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
407                                    GFP_KERNEL);
408         if (!priv->curve_data)
409                 return -ENOMEM;
410
411         priv->curve_data->entries = curve_data->channels;
412         priv->curve_data->entry_size = sizeof(__le16) +
413                 sizeof(*dst) * curve_data->points_per_channel;
414         priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
415         priv->curve_data->len = cd_len;
416         memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
417         source = curve_data->data;
418         target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
419         for (i = 0; i < curve_data->channels; i++) {
420                 __le16 *freq = source;
421                 source += sizeof(__le16);
422                 *((__le16 *)target) = *freq;
423                 target += sizeof(__le16);
424                 for (j = 0; j < curve_data->points_per_channel; j++) {
425                         memcpy(target, source, sizeof(*src));
426
427                         target += sizeof(*dst);
428                         source += sizeof(*src);
429                 }
430                 source++;
431         }
432
433         return 0;
434 }
435
436 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
437         "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
438
439 static int p54_parse_rssical(struct ieee80211_hw *dev,
440                              u8 *data, int len, u16 type)
441 {
442         struct p54_common *priv = dev->priv;
443         struct p54_rssi_db_entry *entry;
444         size_t db_len, entries;
445         int offset = 0, i;
446
447         if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
448                 entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
449                 if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
450                         wiphy_err(dev->wiphy, "rssical size mismatch.\n");
451                         goto err_data;
452                 }
453         } else {
454                 /*
455                  * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
456                  * have an empty two byte header.
457                  */
458                 if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
459                         offset += 2;
460
461                 entries = (len - offset) /
462                         sizeof(struct pda_rssi_cal_ext_entry);
463
464                 if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
465                     entries <= 0) {
466                         wiphy_err(dev->wiphy, "invalid rssi database.\n");
467                         goto err_data;
468                 }
469         }
470
471         db_len = sizeof(*entry) * entries;
472         priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
473         if (!priv->rssi_db)
474                 return -ENOMEM;
475
476         priv->rssi_db->offset = 0;
477         priv->rssi_db->entries = entries;
478         priv->rssi_db->entry_size = sizeof(*entry);
479         priv->rssi_db->len = db_len;
480
481         entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
482         if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
483                 struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
484
485                 for (i = 0; i < entries; i++) {
486                         entry[i].freq = le16_to_cpu(cal[i].freq);
487                         entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
488                         entry[i].add = (s16) le16_to_cpu(cal[i].add);
489                 }
490         } else {
491                 struct pda_rssi_cal_entry *cal = (void *) &data[offset];
492
493                 for (i = 0; i < entries; i++) {
494                         u16 freq;
495                         switch (i) {
496                         case IEEE80211_BAND_2GHZ:
497                                 freq = 2437;
498                                 break;
499                         case IEEE80211_BAND_5GHZ:
500                                 freq = 5240;
501                                 break;
502                         }
503
504                         entry[i].freq = freq;
505                         entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
506                         entry[i].add = (s16) le16_to_cpu(cal[i].add);
507                 }
508         }
509
510         /* sort the list by channel frequency */
511         sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
512         return 0;
513
514 err_data:
515         wiphy_err(dev->wiphy,
516                   "rssi calibration data packing type:(%x) len:%d.\n",
517                   type, len);
518
519         print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
520
521         wiphy_err(dev->wiphy, "please report this issue.\n");
522         return -EINVAL;
523 }
524
525 struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
526 {
527         struct p54_rssi_db_entry *entry;
528         int i, found = -1;
529
530         if (!priv->rssi_db)
531                 return &p54_rssi_default;
532
533         entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
534         for (i = 0; i < priv->rssi_db->entries; i++) {
535                 if (!same_band(freq, entry[i].freq))
536                         continue;
537
538                 if (found == -1) {
539                         found = i;
540                         continue;
541                 }
542
543                 /* nearest match */
544                 if (abs(freq - entry[i].freq) <
545                     abs(freq - entry[found].freq)) {
546                         found = i;
547                         continue;
548                 } else {
549                         break;
550                 }
551         }
552
553         return found < 0 ? &p54_rssi_default : &entry[found];
554 }
555
556 static void p54_parse_default_country(struct ieee80211_hw *dev,
557                                       void *data, int len)
558 {
559         struct pda_country *country;
560
561         if (len != sizeof(*country)) {
562                 wiphy_err(dev->wiphy,
563                           "found possible invalid default country eeprom entry. (entry size: %d)\n",
564                           len);
565
566                 print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
567                                      data, len);
568
569                 wiphy_err(dev->wiphy, "please report this issue.\n");
570                 return;
571         }
572
573         country = (struct pda_country *) data;
574         if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
575                 regulatory_hint(dev->wiphy, country->alpha2);
576         else {
577                 /* TODO:
578                  * write a shared/common function that converts
579                  * "Regulatory domain codes" (802.11-2007 14.8.2.2)
580                  * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
581                  */
582         }
583 }
584
585 static int p54_convert_output_limits(struct ieee80211_hw *dev,
586                                      u8 *data, size_t len)
587 {
588         struct p54_common *priv = dev->priv;
589
590         if (len < 2)
591                 return -EINVAL;
592
593         if (data[0] != 0) {
594                 wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
595                           data[0]);
596                 return -EINVAL;
597         }
598
599         if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
600                 return -EINVAL;
601
602         priv->output_limit = kmalloc(data[1] *
603                 sizeof(struct pda_channel_output_limit) +
604                 sizeof(*priv->output_limit), GFP_KERNEL);
605
606         if (!priv->output_limit)
607                 return -ENOMEM;
608
609         priv->output_limit->offset = 0;
610         priv->output_limit->entries = data[1];
611         priv->output_limit->entry_size =
612                 sizeof(struct pda_channel_output_limit);
613         priv->output_limit->len = priv->output_limit->entry_size *
614                                   priv->output_limit->entries +
615                                   priv->output_limit->offset;
616
617         memcpy(priv->output_limit->data, &data[2],
618                data[1] * sizeof(struct pda_channel_output_limit));
619
620         return 0;
621 }
622
623 static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
624                                                size_t total_len)
625 {
626         struct p54_cal_database *dst;
627         size_t payload_len, entries, entry_size, offset;
628
629         payload_len = le16_to_cpu(src->len);
630         entries = le16_to_cpu(src->entries);
631         entry_size = le16_to_cpu(src->entry_size);
632         offset = le16_to_cpu(src->offset);
633         if (((entries * entry_size + offset) != payload_len) ||
634              (payload_len + sizeof(*src) != total_len))
635                 return NULL;
636
637         dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
638         if (!dst)
639                 return NULL;
640
641         dst->entries = entries;
642         dst->entry_size = entry_size;
643         dst->offset = offset;
644         dst->len = payload_len;
645
646         memcpy(dst->data, src->data, payload_len);
647         return dst;
648 }
649
650 int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
651 {
652         struct p54_common *priv = dev->priv;
653         struct eeprom_pda_wrap *wrap;
654         struct pda_entry *entry;
655         unsigned int data_len, entry_len;
656         void *tmp;
657         int err;
658         u8 *end = (u8 *)eeprom + len;
659         u16 synth = 0;
660         u16 crc16 = ~0;
661
662         wrap = (struct eeprom_pda_wrap *) eeprom;
663         entry = (void *)wrap->data + le16_to_cpu(wrap->len);
664
665         /* verify that at least the entry length/code fits */
666         while ((u8 *)entry <= end - sizeof(*entry)) {
667                 entry_len = le16_to_cpu(entry->len);
668                 data_len = ((entry_len - 1) << 1);
669
670                 /* abort if entry exceeds whole structure */
671                 if ((u8 *)entry + sizeof(*entry) + data_len > end)
672                         break;
673
674                 switch (le16_to_cpu(entry->code)) {
675                 case PDR_MAC_ADDRESS:
676                         if (data_len != ETH_ALEN)
677                                 break;
678                         SET_IEEE80211_PERM_ADDR(dev, entry->data);
679                         break;
680                 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
681                         if (priv->output_limit)
682                                 break;
683                         err = p54_convert_output_limits(dev, entry->data,
684                                                         data_len);
685                         if (err)
686                                 goto err;
687                         break;
688                 case PDR_PRISM_PA_CAL_CURVE_DATA: {
689                         struct pda_pa_curve_data *curve_data =
690                                 (struct pda_pa_curve_data *)entry->data;
691                         if (data_len < sizeof(*curve_data)) {
692                                 err = -EINVAL;
693                                 goto err;
694                         }
695
696                         switch (curve_data->cal_method_rev) {
697                         case 0:
698                                 err = p54_convert_rev0(dev, curve_data);
699                                 break;
700                         case 1:
701                                 err = p54_convert_rev1(dev, curve_data);
702                                 break;
703                         default:
704                                 wiphy_err(dev->wiphy,
705                                           "unknown curve data revision %d\n",
706                                           curve_data->cal_method_rev);
707                                 err = -ENODEV;
708                                 break;
709                         }
710                         if (err)
711                                 goto err;
712                         }
713                         break;
714                 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
715                         priv->iq_autocal = kmemdup(entry->data, data_len,
716                                                    GFP_KERNEL);
717                         if (!priv->iq_autocal) {
718                                 err = -ENOMEM;
719                                 goto err;
720                         }
721
722                         priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
723                         break;
724                 case PDR_DEFAULT_COUNTRY:
725                         p54_parse_default_country(dev, entry->data, data_len);
726                         break;
727                 case PDR_INTERFACE_LIST:
728                         tmp = entry->data;
729                         while ((u8 *)tmp < entry->data + data_len) {
730                                 struct exp_if *exp_if = tmp;
731                                 if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
732                                         synth = le16_to_cpu(exp_if->variant);
733                                 tmp += sizeof(*exp_if);
734                         }
735                         break;
736                 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
737                         if (data_len < 2)
738                                 break;
739                         priv->version = *(u8 *)(entry->data + 1);
740                         break;
741                 case PDR_RSSI_LINEAR_APPROXIMATION:
742                 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
743                 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
744                         err = p54_parse_rssical(dev, entry->data, data_len,
745                                                 le16_to_cpu(entry->code));
746                         if (err)
747                                 goto err;
748                         break;
749                 case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
750                         struct pda_custom_wrapper *pda = (void *) entry->data;
751                         __le16 *src;
752                         u16 *dst;
753                         int i;
754
755                         if (priv->rssi_db || data_len < sizeof(*pda))
756                                 break;
757
758                         priv->rssi_db = p54_convert_db(pda, data_len);
759                         if (!priv->rssi_db)
760                                 break;
761
762                         src = (void *) priv->rssi_db->data;
763                         dst = (void *) priv->rssi_db->data;
764
765                         for (i = 0; i < priv->rssi_db->entries; i++)
766                                 *(dst++) = (s16) le16_to_cpu(*(src++));
767
768                         }
769                         break;
770                 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
771                         struct pda_custom_wrapper *pda = (void *) entry->data;
772                         if (priv->output_limit || data_len < sizeof(*pda))
773                                 break;
774                         priv->output_limit = p54_convert_db(pda, data_len);
775                         }
776                         break;
777                 case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
778                         struct pda_custom_wrapper *pda = (void *) entry->data;
779                         if (priv->curve_data || data_len < sizeof(*pda))
780                                 break;
781                         priv->curve_data = p54_convert_db(pda, data_len);
782                         }
783                         break;
784                 case PDR_END:
785                         crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
786                         if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
787                                 wiphy_err(dev->wiphy, "eeprom failed checksum "
788                                          "test!\n");
789                                 err = -ENOMSG;
790                                 goto err;
791                         } else {
792                                 goto good_eeprom;
793                         }
794                         break;
795                 default:
796                         break;
797                 }
798
799                 crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
800                 entry = (void *)entry + (entry_len + 1) * 2;
801         }
802
803         wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
804         err = -ENODATA;
805         goto err;
806
807 good_eeprom:
808         if (!synth || !priv->iq_autocal || !priv->output_limit ||
809             !priv->curve_data) {
810                 wiphy_err(dev->wiphy,
811                           "not all required entries found in eeprom!\n");
812                 err = -EINVAL;
813                 goto err;
814         }
815
816         err = p54_generate_channel_lists(dev);
817         if (err)
818                 goto err;
819
820         priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
821         if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
822                 p54_init_xbow_synth(priv);
823         if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
824                 dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
825                         priv->band_table[IEEE80211_BAND_2GHZ];
826         if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
827                 dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
828                         priv->band_table[IEEE80211_BAND_5GHZ];
829         if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
830                 priv->rx_diversity_mask = 3;
831         if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
832                 priv->tx_diversity_mask = 3;
833
834         if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
835                 u8 perm_addr[ETH_ALEN];
836
837                 wiphy_warn(dev->wiphy,
838                            "Invalid hwaddr! Using randomly generated MAC addr\n");
839                 random_ether_addr(perm_addr);
840                 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
841         }
842
843         priv->cur_rssi = &p54_rssi_default;
844
845         wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
846                    dev->wiphy->perm_addr, priv->version,
847                    p54_rf_chips[priv->rxhw]);
848
849         return 0;
850
851 err:
852         kfree(priv->iq_autocal);
853         kfree(priv->output_limit);
854         kfree(priv->curve_data);
855         kfree(priv->rssi_db);
856         priv->iq_autocal = NULL;
857         priv->output_limit = NULL;
858         priv->curve_data = NULL;
859         priv->rssi_db = NULL;
860
861         wiphy_err(dev->wiphy, "eeprom parse failed!\n");
862         return err;
863 }
864 EXPORT_SYMBOL_GPL(p54_parse_eeprom);
865
866 int p54_read_eeprom(struct ieee80211_hw *dev)
867 {
868         struct p54_common *priv = dev->priv;
869         size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
870         int ret = -ENOMEM;
871         void *eeprom;
872
873         maxblocksize = EEPROM_READBACK_LEN;
874         if (priv->fw_var >= 0x509)
875                 maxblocksize -= 0xc;
876         else
877                 maxblocksize -= 0x4;
878
879         eeprom = kzalloc(eeprom_size, GFP_KERNEL);
880         if (unlikely(!eeprom))
881                 goto free;
882
883         while (eeprom_size) {
884                 blocksize = min(eeprom_size, maxblocksize);
885                 ret = p54_download_eeprom(priv, (void *) (eeprom + offset),
886                                           offset, blocksize);
887                 if (unlikely(ret))
888                         goto free;
889
890                 offset += blocksize;
891                 eeprom_size -= blocksize;
892         }
893
894         ret = p54_parse_eeprom(dev, eeprom, offset);
895 free:
896         kfree(eeprom);
897         return ret;
898 }
899 EXPORT_SYMBOL_GPL(p54_read_eeprom);