Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
eeprom.c
Go to the documentation of this file.
1 /*
2  * EEPROM parser code for mac80211 Prism54 drivers
3  *
4  * Copyright (c) 2006, Michael Wu <[email protected]>
5  * Copyright (c) 2007-2009, Christian Lamparter <[email protected]>
6  * Copyright 2008, Johannes Berg <[email protected]>
7  *
8  * Based on:
9  * - the islsm (softmac prism54) driver, which is:
10  * Copyright 2004-2006 Jean-Baptiste Note <[email protected]>, 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 #include <linux/export.h>
28 
29 #include "p54.h"
30 #include "eeprom.h"
31 #include "lmac.h"
32 
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, },
46 };
47 
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, },
57 };
58 
59 static struct p54_rssi_db_entry p54_rssi_default = {
60  /*
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.
65  */
66  .mul = 130,
67  .add = -398,
68 };
69 
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)
74 
78  int index;
79  int max_power;
81 };
82 
85  size_t entries;
86  size_t max_entries;
88 };
89 
90 static int p54_get_band_from_freq(u16 freq)
91 {
92  /* FIXME: sync these values with the 802.11 spec */
93 
94  if ((freq >= 2412) && (freq <= 2484))
95  return IEEE80211_BAND_2GHZ;
96 
97  if ((freq >= 4920) && (freq <= 5825))
98  return IEEE80211_BAND_5GHZ;
99 
100  return -1;
101 }
102 
103 static int same_band(u16 freq, u16 freq2)
104 {
105  return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
106 }
107 
108 static int p54_compare_channels(const void *_a,
109  const void *_b)
110 {
111  const struct p54_channel_entry *a = _a;
112  const struct p54_channel_entry *b = _b;
113 
114  return a->freq - b->freq;
115 }
116 
117 static int p54_compare_rssichan(const void *_a,
118  const void *_b)
119 {
120  const struct p54_rssi_db_entry *a = _a;
121  const struct p54_rssi_db_entry *b = _b;
122 
123  return a->freq - b->freq;
124 }
125 
126 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
127  struct ieee80211_supported_band *band_entry,
128  enum ieee80211_band band)
129 {
130  /* TODO: generate rate array dynamically */
131 
132  switch (band) {
133  case IEEE80211_BAND_2GHZ:
134  band_entry->bitrates = p54_bgrates;
135  band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
136  break;
137  case IEEE80211_BAND_5GHZ:
138  band_entry->bitrates = p54_arates;
139  band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
140  break;
141  default:
142  return -EINVAL;
143  }
144 
145  return 0;
146 }
147 
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)
152 {
153  struct p54_common *priv = dev->priv;
154  struct ieee80211_supported_band *tmp, *old;
155  unsigned int i, j;
156  int ret = -ENOMEM;
157 
158  if ((!list->entries) || (!list->band_channel_num[band]))
159  return -EINVAL;
160 
161  tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
162  if (!tmp)
163  goto err_out;
164 
165  tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
166  list->band_channel_num[band], GFP_KERNEL);
167  if (!tmp->channels)
168  goto err_out;
169 
170  ret = p54_fill_band_bitrates(dev, tmp, band);
171  if (ret)
172  goto err_out;
173 
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];
178 
179  if (chan->band != band)
180  continue;
181 
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 ? "" :
190  " [curve data]"),
191  chan->index, chan->freq);
192  continue;
193  }
194 
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 |
203  dest->hw_value = (*chan_num);
204  j++;
205  (*chan_num)++;
206  }
207 
208  if (j == 0) {
209  wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
210  (band == IEEE80211_BAND_2GHZ) ? 2 : 5);
211 
212  ret = -ENODATA;
213  goto err_out;
214  }
215 
216  tmp->n_channels = j;
217  old = priv->band_table[band];
218  priv->band_table[band] = tmp;
219  if (old) {
220  kfree(old->channels);
221  kfree(old);
222  }
223 
224  return 0;
225 
226 err_out:
227  if (tmp) {
228  kfree(tmp->channels);
229  kfree(tmp);
230  }
231 
232  return ret;
233 }
234 
235 static struct p54_channel_entry *p54_update_channel_param(struct p54_channel_list *list,
236  u16 freq, u16 data)
237 {
238  int i;
239  struct p54_channel_entry *entry = NULL;
240 
241  /*
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
245  */
246  for (i = list->entries; i >= 0; i--) {
247  if (freq == list->channels[i].freq) {
248  entry = &list->channels[i];
249  break;
250  }
251  }
252 
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);
256 
257  /*
258  * filter out frequencies which don't belong into
259  * any supported band.
260  */
261  if (band >= 0) {
262  i = list->entries++;
263  list->band_channel_num[band]++;
264 
265  entry = &list->channels[i];
266  entry->freq = freq;
267  entry->band = band;
268  entry->index = ieee80211_frequency_to_channel(freq);
269  entry->max_power = 0;
270  entry->data = 0;
271  }
272  }
273 
274  if (entry)
275  entry->data |= data;
276 
277  return entry;
278 }
279 
280 static int p54_get_maxpower(struct p54_common *priv, void *data)
281 {
282  switch (priv->rxhw & PDR_SYNTH_FRONTEND_MASK) {
285  int j;
286  u16 rawpower = 0;
287  pda = data;
288  for (j = 0; j < ARRAY_SIZE(pda->point); j++) {
290  &pda->point[j];
291  rawpower = max_t(u16,
292  rawpower, le16_to_cpu(point->val_qpsk));
293  rawpower = max_t(u16,
294  rawpower, le16_to_cpu(point->val_bpsk));
295  rawpower = max_t(u16,
296  rawpower, le16_to_cpu(point->val_16qam));
297  rawpower = max_t(u16,
298  rawpower, le16_to_cpu(point->val_64qam));
299  }
300  /* longbow seems to use 1/16 dBm units */
301  return rawpower / 16;
302  }
303 
308  struct pda_channel_output_limit *pda = data;
309  u8 rawpower = 0;
310  rawpower = max(rawpower, pda->val_qpsk);
311  rawpower = max(rawpower, pda->val_bpsk);
312  rawpower = max(rawpower, pda->val_16qam);
313  rawpower = max(rawpower, pda->val_64qam);
314  /* raw values are in 1/4 dBm units */
315  return rawpower / 4;
316  }
317 
318  default:
319  return 20;
320  }
321 }
322 
323 static int p54_generate_channel_lists(struct ieee80211_hw *dev)
324 {
325  struct p54_common *priv = dev->priv;
326  struct p54_channel_list *list;
327  unsigned int i, j, k, max_channel_num;
328  int ret = 0;
329  u16 freq;
330 
331  if ((priv->iq_autocal_len != priv->curve_data->entries) ||
332  (priv->iq_autocal_len != priv->output_limit->entries))
333  wiphy_err(dev->wiphy,
334  "Unsupported or damaged EEPROM detected. "
335  "You may not be able to use all channels.\n");
336 
337  max_channel_num = max_t(unsigned int, priv->output_limit->entries,
338  priv->iq_autocal_len);
339  max_channel_num = max_t(unsigned int, max_channel_num,
340  priv->curve_data->entries);
341 
342  list = kzalloc(sizeof(*list), GFP_KERNEL);
343  if (!list) {
344  ret = -ENOMEM;
345  goto free;
346  }
347  priv->chan_num = max_channel_num;
348  priv->survey = kzalloc(sizeof(struct survey_info) * max_channel_num,
349  GFP_KERNEL);
350  if (!priv->survey) {
351  ret = -ENOMEM;
352  goto free;
353  }
354 
355  list->max_entries = max_channel_num;
356  list->channels = kzalloc(sizeof(struct p54_channel_entry) *
357  max_channel_num, GFP_KERNEL);
358  if (!list->channels) {
359  ret = -ENOMEM;
360  goto free;
361  }
362 
363  for (i = 0; i < max_channel_num; i++) {
364  if (i < priv->iq_autocal_len) {
365  freq = le16_to_cpu(priv->iq_autocal[i].freq);
366  p54_update_channel_param(list, freq, CHAN_HAS_CAL);
367  }
368 
369  if (i < priv->output_limit->entries) {
370  struct p54_channel_entry *tmp;
371 
372  void *data = (void *) ((unsigned long) i *
373  priv->output_limit->entry_size +
374  priv->output_limit->offset +
375  priv->output_limit->data);
376 
377  freq = le16_to_cpup((__le16 *) data);
378  tmp = p54_update_channel_param(list, freq,
380  if (tmp) {
381  tmp->max_power = p54_get_maxpower(priv, data);
382  }
383  }
384 
385  if (i < priv->curve_data->entries) {
386  freq = le16_to_cpup((__le16 *) (i *
387  priv->curve_data->entry_size +
388  priv->curve_data->offset +
389  priv->curve_data->data));
390 
391  p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
392  }
393  }
394 
395  /* sort the channel list by frequency */
396  sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
397  p54_compare_channels, NULL);
398 
399  k = 0;
400  for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
401  if (p54_generate_band(dev, list, &k, i) == 0)
402  j++;
403  }
404  if (j == 0) {
405  /* no useable band available. */
406  ret = -EINVAL;
407  }
408 
409 free:
410  if (list) {
411  kfree(list->channels);
412  kfree(list);
413  }
414  if (ret) {
415  kfree(priv->survey);
416  priv->survey = NULL;
417  }
418 
419  return ret;
420 }
421 
422 static int p54_convert_rev0(struct ieee80211_hw *dev,
423  struct pda_pa_curve_data *curve_data)
424 {
425  struct p54_common *priv = dev->priv;
428  size_t cd_len = sizeof(*curve_data) +
429  (curve_data->points_per_channel*sizeof(*dst) + 2) *
430  curve_data->channels;
431  unsigned int i, j;
432  void *source, *target;
433 
434  priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
435  GFP_KERNEL);
436  if (!priv->curve_data)
437  return -ENOMEM;
438 
439  priv->curve_data->entries = curve_data->channels;
440  priv->curve_data->entry_size = sizeof(__le16) +
441  sizeof(*dst) * curve_data->points_per_channel;
442  priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
443  priv->curve_data->len = cd_len;
444  memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
445  source = curve_data->data;
446  target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
447  for (i = 0; i < curve_data->channels; i++) {
448  __le16 *freq = source;
449  source += sizeof(__le16);
450  *((__le16 *)target) = *freq;
451  target += sizeof(__le16);
452  for (j = 0; j < curve_data->points_per_channel; j++) {
453  dst = target;
454  src = source;
455 
456  dst->rf_power = src->rf_power;
457  dst->pa_detector = src->pa_detector;
458  dst->data_64qam = src->pcv;
459  /* "invent" the points for the other modulations */
460 #define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
461  dst->data_16qam = SUB(src->pcv, 12);
462  dst->data_qpsk = SUB(dst->data_16qam, 12);
463  dst->data_bpsk = SUB(dst->data_qpsk, 12);
464  dst->data_barker = SUB(dst->data_bpsk, 14);
465 #undef SUB
466  target += sizeof(*dst);
467  source += sizeof(*src);
468  }
469  }
470 
471  return 0;
472 }
473 
474 static int p54_convert_rev1(struct ieee80211_hw *dev,
475  struct pda_pa_curve_data *curve_data)
476 {
477  struct p54_common *priv = dev->priv;
480  size_t cd_len = sizeof(*curve_data) +
481  (curve_data->points_per_channel*sizeof(*dst) + 2) *
482  curve_data->channels;
483  unsigned int i, j;
484  void *source, *target;
485 
486  priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
487  GFP_KERNEL);
488  if (!priv->curve_data)
489  return -ENOMEM;
490 
491  priv->curve_data->entries = curve_data->channels;
492  priv->curve_data->entry_size = sizeof(__le16) +
493  sizeof(*dst) * curve_data->points_per_channel;
494  priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
495  priv->curve_data->len = cd_len;
496  memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
497  source = curve_data->data;
498  target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
499  for (i = 0; i < curve_data->channels; i++) {
500  __le16 *freq = source;
501  source += sizeof(__le16);
502  *((__le16 *)target) = *freq;
503  target += sizeof(__le16);
504  for (j = 0; j < curve_data->points_per_channel; j++) {
505  memcpy(target, source, sizeof(*src));
506 
507  target += sizeof(*dst);
508  source += sizeof(*src);
509  }
510  source++;
511  }
512 
513  return 0;
514 }
515 
516 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
517  "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
518 
519 static int p54_parse_rssical(struct ieee80211_hw *dev,
520  u8 *data, int len, u16 type)
521 {
522  struct p54_common *priv = dev->priv;
523  struct p54_rssi_db_entry *entry;
524  size_t db_len, entries;
525  int offset = 0, i;
526 
528  entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
529  if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
530  wiphy_err(dev->wiphy, "rssical size mismatch.\n");
531  goto err_data;
532  }
533  } else {
534  /*
535  * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
536  * have an empty two byte header.
537  */
538  if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
539  offset += 2;
540 
541  entries = (len - offset) /
542  sizeof(struct pda_rssi_cal_ext_entry);
543 
544  if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
545  entries <= 0) {
546  wiphy_err(dev->wiphy, "invalid rssi database.\n");
547  goto err_data;
548  }
549  }
550 
551  db_len = sizeof(*entry) * entries;
552  priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
553  if (!priv->rssi_db)
554  return -ENOMEM;
555 
556  priv->rssi_db->offset = 0;
557  priv->rssi_db->entries = entries;
558  priv->rssi_db->entry_size = sizeof(*entry);
559  priv->rssi_db->len = db_len;
560 
561  entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
563  struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
564 
565  for (i = 0; i < entries; i++) {
566  entry[i].freq = le16_to_cpu(cal[i].freq);
567  entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
568  entry[i].add = (s16) le16_to_cpu(cal[i].add);
569  }
570  } else {
571  struct pda_rssi_cal_entry *cal = (void *) &data[offset];
572 
573  for (i = 0; i < entries; i++) {
574  u16 freq = 0;
575  switch (i) {
576  case IEEE80211_BAND_2GHZ:
577  freq = 2437;
578  break;
579  case IEEE80211_BAND_5GHZ:
580  freq = 5240;
581  break;
582  }
583 
584  entry[i].freq = freq;
585  entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
586  entry[i].add = (s16) le16_to_cpu(cal[i].add);
587  }
588  }
589 
590  /* sort the list by channel frequency */
591  sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
592  return 0;
593 
594 err_data:
595  wiphy_err(dev->wiphy,
596  "rssi calibration data packing type:(%x) len:%d.\n",
597  type, len);
598 
599  print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
600 
601  wiphy_err(dev->wiphy, "please report this issue.\n");
602  return -EINVAL;
603 }
604 
605 struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
606 {
607  struct p54_rssi_db_entry *entry;
608  int i, found = -1;
609 
610  if (!priv->rssi_db)
611  return &p54_rssi_default;
612 
613  entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
614  for (i = 0; i < priv->rssi_db->entries; i++) {
615  if (!same_band(freq, entry[i].freq))
616  continue;
617 
618  if (found == -1) {
619  found = i;
620  continue;
621  }
622 
623  /* nearest match */
624  if (abs(freq - entry[i].freq) <
625  abs(freq - entry[found].freq)) {
626  found = i;
627  continue;
628  } else {
629  break;
630  }
631  }
632 
633  return found < 0 ? &p54_rssi_default : &entry[found];
634 }
635 
636 static void p54_parse_default_country(struct ieee80211_hw *dev,
637  void *data, int len)
638 {
639  struct pda_country *country;
640 
641  if (len != sizeof(*country)) {
642  wiphy_err(dev->wiphy,
643  "found possible invalid default country eeprom entry. (entry size: %d)\n",
644  len);
645 
646  print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
647  data, len);
648 
649  wiphy_err(dev->wiphy, "please report this issue.\n");
650  return;
651  }
652 
653  country = (struct pda_country *) data;
654  if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
655  regulatory_hint(dev->wiphy, country->alpha2);
656  else {
657  /* TODO:
658  * write a shared/common function that converts
659  * "Regulatory domain codes" (802.11-2007 14.8.2.2)
660  * into ISO/IEC 3166-1 alpha2 for regulatory_hint.
661  */
662  }
663 }
664 
665 static int p54_convert_output_limits(struct ieee80211_hw *dev,
666  u8 *data, size_t len)
667 {
668  struct p54_common *priv = dev->priv;
669 
670  if (len < 2)
671  return -EINVAL;
672 
673  if (data[0] != 0) {
674  wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
675  data[0]);
676  return -EINVAL;
677  }
678 
679  if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
680  return -EINVAL;
681 
682  priv->output_limit = kmalloc(data[1] *
683  sizeof(struct pda_channel_output_limit) +
684  sizeof(*priv->output_limit), GFP_KERNEL);
685 
686  if (!priv->output_limit)
687  return -ENOMEM;
688 
689  priv->output_limit->offset = 0;
690  priv->output_limit->entries = data[1];
691  priv->output_limit->entry_size =
692  sizeof(struct pda_channel_output_limit);
693  priv->output_limit->len = priv->output_limit->entry_size *
694  priv->output_limit->entries +
695  priv->output_limit->offset;
696 
697  memcpy(priv->output_limit->data, &data[2],
698  data[1] * sizeof(struct pda_channel_output_limit));
699 
700  return 0;
701 }
702 
703 static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
704  size_t total_len)
705 {
706  struct p54_cal_database *dst;
708 
709  payload_len = le16_to_cpu(src->len);
710  entries = le16_to_cpu(src->entries);
711  entry_size = le16_to_cpu(src->entry_size);
712  offset = le16_to_cpu(src->offset);
713  if (((entries * entry_size + offset) != payload_len) ||
714  (payload_len + sizeof(*src) != total_len))
715  return NULL;
716 
717  dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
718  if (!dst)
719  return NULL;
720 
721  dst->entries = entries;
722  dst->entry_size = entry_size;
723  dst->offset = offset;
724  dst->len = payload_len;
725 
726  memcpy(dst->data, src->data, payload_len);
727  return dst;
728 }
729 
730 int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
731 {
732  struct p54_common *priv = dev->priv;
733  struct eeprom_pda_wrap *wrap;
734  struct pda_entry *entry;
735  unsigned int data_len, entry_len;
736  void *tmp;
737  int err;
738  u8 *end = (u8 *)eeprom + len;
739  u16 synth = 0;
740  u16 crc16 = ~0;
741 
742  wrap = (struct eeprom_pda_wrap *) eeprom;
743  entry = (void *)wrap->data + le16_to_cpu(wrap->len);
744 
745  /* verify that at least the entry length/code fits */
746  while ((u8 *)entry <= end - sizeof(*entry)) {
747  entry_len = le16_to_cpu(entry->len);
748  data_len = ((entry_len - 1) << 1);
749 
750  /* abort if entry exceeds whole structure */
751  if ((u8 *)entry + sizeof(*entry) + data_len > end)
752  break;
753 
754  switch (le16_to_cpu(entry->code)) {
755  case PDR_MAC_ADDRESS:
756  if (data_len != ETH_ALEN)
757  break;
758  SET_IEEE80211_PERM_ADDR(dev, entry->data);
759  break;
761  if (priv->output_limit)
762  break;
763  err = p54_convert_output_limits(dev, entry->data,
764  data_len);
765  if (err)
766  goto err;
767  break;
769  struct pda_pa_curve_data *curve_data =
770  (struct pda_pa_curve_data *)entry->data;
771  if (data_len < sizeof(*curve_data)) {
772  err = -EINVAL;
773  goto err;
774  }
775 
776  switch (curve_data->cal_method_rev) {
777  case 0:
778  err = p54_convert_rev0(dev, curve_data);
779  break;
780  case 1:
781  err = p54_convert_rev1(dev, curve_data);
782  break;
783  default:
784  wiphy_err(dev->wiphy,
785  "unknown curve data revision %d\n",
786  curve_data->cal_method_rev);
787  err = -ENODEV;
788  break;
789  }
790  if (err)
791  goto err;
792  }
793  break;
795  priv->iq_autocal = kmemdup(entry->data, data_len,
796  GFP_KERNEL);
797  if (!priv->iq_autocal) {
798  err = -ENOMEM;
799  goto err;
800  }
801 
802  priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
803  break;
804  case PDR_DEFAULT_COUNTRY:
805  p54_parse_default_country(dev, entry->data, data_len);
806  break;
807  case PDR_INTERFACE_LIST:
808  tmp = entry->data;
809  while ((u8 *)tmp < entry->data + data_len) {
810  struct exp_if *exp_if = tmp;
811  if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
812  synth = le16_to_cpu(exp_if->variant);
813  tmp += sizeof(*exp_if);
814  }
815  break;
817  if (data_len < 2)
818  break;
819  priv->version = *(u8 *)(entry->data + 1);
820  break;
824  err = p54_parse_rssical(dev, entry->data, data_len,
825  le16_to_cpu(entry->code));
826  if (err)
827  goto err;
828  break;
830  struct pda_custom_wrapper *pda = (void *) entry->data;
831  __le16 *src;
832  u16 *dst;
833  int i;
834 
835  if (priv->rssi_db || data_len < sizeof(*pda))
836  break;
837 
838  priv->rssi_db = p54_convert_db(pda, data_len);
839  if (!priv->rssi_db)
840  break;
841 
842  src = (void *) priv->rssi_db->data;
843  dst = (void *) priv->rssi_db->data;
844 
845  for (i = 0; i < priv->rssi_db->entries; i++)
846  *(dst++) = (s16) le16_to_cpu(*(src++));
847 
848  }
849  break;
851  struct pda_custom_wrapper *pda = (void *) entry->data;
852  if (priv->output_limit || data_len < sizeof(*pda))
853  break;
854  priv->output_limit = p54_convert_db(pda, data_len);
855  }
856  break;
858  struct pda_custom_wrapper *pda = (void *) entry->data;
859  if (priv->curve_data || data_len < sizeof(*pda))
860  break;
861  priv->curve_data = p54_convert_db(pda, data_len);
862  }
863  break;
864  case PDR_END:
865  crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
866  if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
867  wiphy_err(dev->wiphy, "eeprom failed checksum "
868  "test!\n");
869  err = -ENOMSG;
870  goto err;
871  } else {
872  goto good_eeprom;
873  }
874  break;
875  default:
876  break;
877  }
878 
879  crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
880  entry = (void *)entry + (entry_len + 1) * 2;
881  }
882 
883  wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
884  err = -ENODATA;
885  goto err;
886 
887 good_eeprom:
888  if (!synth || !priv->iq_autocal || !priv->output_limit ||
889  !priv->curve_data) {
890  wiphy_err(dev->wiphy,
891  "not all required entries found in eeprom!\n");
892  err = -EINVAL;
893  goto err;
894  }
895 
896  priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
897 
898  err = p54_generate_channel_lists(dev);
899  if (err)
900  goto err;
901 
902  if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
903  p54_init_xbow_synth(priv);
904  if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
905  dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
907  if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
908  dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
911  priv->rx_diversity_mask = 3;
913  priv->tx_diversity_mask = 3;
914 
915  if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
916  u8 perm_addr[ETH_ALEN];
917 
918  wiphy_warn(dev->wiphy,
919  "Invalid hwaddr! Using randomly generated MAC addr\n");
920  eth_random_addr(perm_addr);
921  SET_IEEE80211_PERM_ADDR(dev, perm_addr);
922  }
923 
924  priv->cur_rssi = &p54_rssi_default;
925 
926  wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
927  dev->wiphy->perm_addr, priv->version,
928  p54_rf_chips[priv->rxhw]);
929 
930  return 0;
931 
932 err:
933  kfree(priv->iq_autocal);
934  kfree(priv->output_limit);
935  kfree(priv->curve_data);
936  kfree(priv->rssi_db);
937  kfree(priv->survey);
938  priv->iq_autocal = NULL;
939  priv->output_limit = NULL;
940  priv->curve_data = NULL;
941  priv->rssi_db = NULL;
942  priv->survey = NULL;
943 
944  wiphy_err(dev->wiphy, "eeprom parse failed!\n");
945  return err;
946 }
948 
950 {
951  struct p54_common *priv = dev->priv;
952  size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
953  int ret = -ENOMEM;
954  void *eeprom;
955 
956  maxblocksize = EEPROM_READBACK_LEN;
957  if (priv->fw_var >= 0x509)
958  maxblocksize -= 0xc;
959  else
960  maxblocksize -= 0x4;
961 
962  eeprom = kzalloc(eeprom_size, GFP_KERNEL);
963  if (unlikely(!eeprom))
964  goto free;
965 
966  while (eeprom_size) {
967  blocksize = min(eeprom_size, maxblocksize);
968  ret = p54_download_eeprom(priv, eeprom + offset,
969  offset, blocksize);
970  if (unlikely(ret))
971  goto free;
972 
973  offset += blocksize;
974  eeprom_size -= blocksize;
975  }
976 
977  ret = p54_parse_eeprom(dev, eeprom, offset);
978 free:
979  kfree(eeprom);
980  return ret;
981 }