0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/firmware.h>
0017 #include <linux/etherdevice.h>
0018 #include <linux/sort.h>
0019 #include <linux/slab.h>
0020
0021 #include <net/mac80211.h>
0022 #include <linux/crc-ccitt.h>
0023 #include <linux/export.h>
0024
0025 #include "p54.h"
0026 #include "eeprom.h"
0027 #include "lmac.h"
0028
0029 static struct ieee80211_rate p54_bgrates[] = {
0030 { .bitrate = 10, .hw_value = 0, },
0031 { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
0032 { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
0033 { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
0034 { .bitrate = 60, .hw_value = 4, },
0035 { .bitrate = 90, .hw_value = 5, },
0036 { .bitrate = 120, .hw_value = 6, },
0037 { .bitrate = 180, .hw_value = 7, },
0038 { .bitrate = 240, .hw_value = 8, },
0039 { .bitrate = 360, .hw_value = 9, },
0040 { .bitrate = 480, .hw_value = 10, },
0041 { .bitrate = 540, .hw_value = 11, },
0042 };
0043
0044 static struct ieee80211_rate p54_arates[] = {
0045 { .bitrate = 60, .hw_value = 4, },
0046 { .bitrate = 90, .hw_value = 5, },
0047 { .bitrate = 120, .hw_value = 6, },
0048 { .bitrate = 180, .hw_value = 7, },
0049 { .bitrate = 240, .hw_value = 8, },
0050 { .bitrate = 360, .hw_value = 9, },
0051 { .bitrate = 480, .hw_value = 10, },
0052 { .bitrate = 540, .hw_value = 11, },
0053 };
0054
0055 static struct p54_rssi_db_entry p54_rssi_default = {
0056
0057
0058
0059
0060
0061
0062 .mul = 130,
0063 .add = -398,
0064 };
0065
0066 #define CHAN_HAS_CAL BIT(0)
0067 #define CHAN_HAS_LIMIT BIT(1)
0068 #define CHAN_HAS_CURVE BIT(2)
0069 #define CHAN_HAS_ALL (CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)
0070
0071 struct p54_channel_entry {
0072 u16 freq;
0073 u16 data;
0074 int index;
0075 int max_power;
0076 enum nl80211_band band;
0077 };
0078
0079 struct p54_channel_list {
0080 struct p54_channel_entry *channels;
0081 size_t entries;
0082 size_t max_entries;
0083 size_t band_channel_num[NUM_NL80211_BANDS];
0084 };
0085
0086 static int p54_get_band_from_freq(u16 freq)
0087 {
0088
0089
0090 if ((freq >= 2412) && (freq <= 2484))
0091 return NL80211_BAND_2GHZ;
0092
0093 if ((freq >= 4920) && (freq <= 5825))
0094 return NL80211_BAND_5GHZ;
0095
0096 return -1;
0097 }
0098
0099 static int same_band(u16 freq, u16 freq2)
0100 {
0101 return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
0102 }
0103
0104 static int p54_compare_channels(const void *_a,
0105 const void *_b)
0106 {
0107 const struct p54_channel_entry *a = _a;
0108 const struct p54_channel_entry *b = _b;
0109
0110 return a->freq - b->freq;
0111 }
0112
0113 static int p54_compare_rssichan(const void *_a,
0114 const void *_b)
0115 {
0116 const struct p54_rssi_db_entry *a = _a;
0117 const struct p54_rssi_db_entry *b = _b;
0118
0119 return a->freq - b->freq;
0120 }
0121
0122 static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
0123 struct ieee80211_supported_band *band_entry,
0124 enum nl80211_band band)
0125 {
0126
0127
0128 switch (band) {
0129 case NL80211_BAND_2GHZ:
0130 band_entry->bitrates = p54_bgrates;
0131 band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
0132 break;
0133 case NL80211_BAND_5GHZ:
0134 band_entry->bitrates = p54_arates;
0135 band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
0136 break;
0137 default:
0138 return -EINVAL;
0139 }
0140
0141 return 0;
0142 }
0143
0144 static int p54_generate_band(struct ieee80211_hw *dev,
0145 struct p54_channel_list *list,
0146 unsigned int *chan_num,
0147 enum nl80211_band band)
0148 {
0149 struct p54_common *priv = dev->priv;
0150 struct ieee80211_supported_band *tmp, *old;
0151 unsigned int i, j;
0152 int ret = -ENOMEM;
0153
0154 if ((!list->entries) || (!list->band_channel_num[band]))
0155 return -EINVAL;
0156
0157 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
0158 if (!tmp)
0159 goto err_out;
0160
0161 tmp->channels = kcalloc(list->band_channel_num[band],
0162 sizeof(struct ieee80211_channel),
0163 GFP_KERNEL);
0164 if (!tmp->channels)
0165 goto err_out;
0166
0167 ret = p54_fill_band_bitrates(dev, tmp, band);
0168 if (ret)
0169 goto err_out;
0170
0171 for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
0172 (i < list->entries); i++) {
0173 struct p54_channel_entry *chan = &list->channels[i];
0174 struct ieee80211_channel *dest = &tmp->channels[j];
0175
0176 if (chan->band != band)
0177 continue;
0178
0179 if (chan->data != CHAN_HAS_ALL) {
0180 wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
0181 "channel:%d [%d MHz].\n",
0182 (chan->data & CHAN_HAS_CAL ? "" :
0183 " [iqauto calibration data]"),
0184 (chan->data & CHAN_HAS_LIMIT ? "" :
0185 " [output power limits]"),
0186 (chan->data & CHAN_HAS_CURVE ? "" :
0187 " [curve data]"),
0188 chan->index, chan->freq);
0189 continue;
0190 }
0191
0192 dest->band = chan->band;
0193 dest->center_freq = chan->freq;
0194 dest->max_power = chan->max_power;
0195 priv->survey[*chan_num].channel = &tmp->channels[j];
0196 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
0197 SURVEY_INFO_TIME |
0198 SURVEY_INFO_TIME_BUSY |
0199 SURVEY_INFO_TIME_TX;
0200 dest->hw_value = (*chan_num);
0201 j++;
0202 (*chan_num)++;
0203 }
0204
0205 if (j == 0) {
0206 wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n",
0207 (band == NL80211_BAND_2GHZ) ? 2 : 5);
0208
0209 ret = -ENODATA;
0210 goto err_out;
0211 }
0212
0213 tmp->n_channels = j;
0214 old = priv->band_table[band];
0215 priv->band_table[band] = tmp;
0216 if (old) {
0217 kfree(old->channels);
0218 kfree(old);
0219 }
0220
0221 return 0;
0222
0223 err_out:
0224 if (tmp) {
0225 kfree(tmp->channels);
0226 kfree(tmp);
0227 }
0228
0229 return ret;
0230 }
0231
0232 static struct p54_channel_entry *p54_update_channel_param(struct p54_channel_list *list,
0233 u16 freq, u16 data)
0234 {
0235 int i;
0236 struct p54_channel_entry *entry = NULL;
0237
0238
0239
0240
0241
0242
0243 for (i = list->entries; i >= 0; i--) {
0244 if (freq == list->channels[i].freq) {
0245 entry = &list->channels[i];
0246 break;
0247 }
0248 }
0249
0250 if ((i < 0) && (list->entries < list->max_entries)) {
0251
0252 int band = p54_get_band_from_freq(freq);
0253
0254
0255
0256
0257
0258 if (band >= 0) {
0259 i = list->entries++;
0260 list->band_channel_num[band]++;
0261
0262 entry = &list->channels[i];
0263 entry->freq = freq;
0264 entry->band = band;
0265 entry->index = ieee80211_frequency_to_channel(freq);
0266 entry->max_power = 0;
0267 entry->data = 0;
0268 }
0269 }
0270
0271 if (entry)
0272 entry->data |= data;
0273
0274 return entry;
0275 }
0276
0277 static int p54_get_maxpower(struct p54_common *priv, void *data)
0278 {
0279 switch (priv->rxhw & PDR_SYNTH_FRONTEND_MASK) {
0280 case PDR_SYNTH_FRONTEND_LONGBOW: {
0281 struct pda_channel_output_limit_longbow *pda = data;
0282 int j;
0283 u16 rawpower = 0;
0284 pda = data;
0285 for (j = 0; j < ARRAY_SIZE(pda->point); j++) {
0286 struct pda_channel_output_limit_point_longbow *point =
0287 &pda->point[j];
0288 rawpower = max_t(u16,
0289 rawpower, le16_to_cpu(point->val_qpsk));
0290 rawpower = max_t(u16,
0291 rawpower, le16_to_cpu(point->val_bpsk));
0292 rawpower = max_t(u16,
0293 rawpower, le16_to_cpu(point->val_16qam));
0294 rawpower = max_t(u16,
0295 rawpower, le16_to_cpu(point->val_64qam));
0296 }
0297
0298 return rawpower / 16;
0299 }
0300
0301 case PDR_SYNTH_FRONTEND_DUETTE3:
0302 case PDR_SYNTH_FRONTEND_DUETTE2:
0303 case PDR_SYNTH_FRONTEND_FRISBEE:
0304 case PDR_SYNTH_FRONTEND_XBOW: {
0305 struct pda_channel_output_limit *pda = data;
0306 u8 rawpower = 0;
0307 rawpower = max(rawpower, pda->val_qpsk);
0308 rawpower = max(rawpower, pda->val_bpsk);
0309 rawpower = max(rawpower, pda->val_16qam);
0310 rawpower = max(rawpower, pda->val_64qam);
0311
0312 return rawpower / 4;
0313 }
0314
0315 default:
0316 return 20;
0317 }
0318 }
0319
0320 static int p54_generate_channel_lists(struct ieee80211_hw *dev)
0321 {
0322 struct p54_common *priv = dev->priv;
0323 struct p54_channel_list *list;
0324 unsigned int i, j, k, max_channel_num;
0325 int ret = 0;
0326 u16 freq;
0327
0328 if ((priv->iq_autocal_len != priv->curve_data->entries) ||
0329 (priv->iq_autocal_len != priv->output_limit->entries))
0330 wiphy_err(dev->wiphy,
0331 "Unsupported or damaged EEPROM detected. "
0332 "You may not be able to use all channels.\n");
0333
0334 max_channel_num = max_t(unsigned int, priv->output_limit->entries,
0335 priv->iq_autocal_len);
0336 max_channel_num = max_t(unsigned int, max_channel_num,
0337 priv->curve_data->entries);
0338
0339 list = kzalloc(sizeof(*list), GFP_KERNEL);
0340 if (!list) {
0341 ret = -ENOMEM;
0342 goto free;
0343 }
0344 priv->chan_num = max_channel_num;
0345 priv->survey = kcalloc(max_channel_num, sizeof(struct survey_info),
0346 GFP_KERNEL);
0347 if (!priv->survey) {
0348 ret = -ENOMEM;
0349 goto free;
0350 }
0351
0352 list->max_entries = max_channel_num;
0353 list->channels = kcalloc(max_channel_num,
0354 sizeof(struct p54_channel_entry),
0355 GFP_KERNEL);
0356 if (!list->channels) {
0357 ret = -ENOMEM;
0358 goto free;
0359 }
0360
0361 for (i = 0; i < max_channel_num; i++) {
0362 if (i < priv->iq_autocal_len) {
0363 freq = le16_to_cpu(priv->iq_autocal[i].freq);
0364 p54_update_channel_param(list, freq, CHAN_HAS_CAL);
0365 }
0366
0367 if (i < priv->output_limit->entries) {
0368 struct p54_channel_entry *tmp;
0369
0370 void *data = (void *) ((unsigned long) i *
0371 priv->output_limit->entry_size +
0372 priv->output_limit->offset +
0373 priv->output_limit->data);
0374
0375 freq = le16_to_cpup((__le16 *) data);
0376 tmp = p54_update_channel_param(list, freq,
0377 CHAN_HAS_LIMIT);
0378 if (tmp) {
0379 tmp->max_power = p54_get_maxpower(priv, data);
0380 }
0381 }
0382
0383 if (i < priv->curve_data->entries) {
0384 freq = le16_to_cpup((__le16 *) (i *
0385 priv->curve_data->entry_size +
0386 priv->curve_data->offset +
0387 priv->curve_data->data));
0388
0389 p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
0390 }
0391 }
0392
0393
0394 sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
0395 p54_compare_channels, NULL);
0396
0397 k = 0;
0398 for (i = 0, j = 0; i < NUM_NL80211_BANDS; i++) {
0399 if (p54_generate_band(dev, list, &k, i) == 0)
0400 j++;
0401 }
0402 if (j == 0) {
0403
0404 ret = -EINVAL;
0405 }
0406
0407 free:
0408 if (list) {
0409 kfree(list->channels);
0410 kfree(list);
0411 }
0412 if (ret) {
0413 kfree(priv->survey);
0414 priv->survey = NULL;
0415 }
0416
0417 return ret;
0418 }
0419
0420 static int p54_convert_rev0(struct ieee80211_hw *dev,
0421 struct pda_pa_curve_data *curve_data)
0422 {
0423 struct p54_common *priv = dev->priv;
0424 struct p54_pa_curve_data_sample *dst;
0425 struct pda_pa_curve_data_sample_rev0 *src;
0426 size_t cd_len = sizeof(*curve_data) +
0427 (curve_data->points_per_channel*sizeof(*dst) + 2) *
0428 curve_data->channels;
0429 unsigned int i, j;
0430 void *source, *target;
0431
0432 priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
0433 GFP_KERNEL);
0434 if (!priv->curve_data)
0435 return -ENOMEM;
0436
0437 priv->curve_data->entries = curve_data->channels;
0438 priv->curve_data->entry_size = sizeof(__le16) +
0439 sizeof(*dst) * curve_data->points_per_channel;
0440 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
0441 priv->curve_data->len = cd_len;
0442 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
0443 source = curve_data->data;
0444 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
0445 for (i = 0; i < curve_data->channels; i++) {
0446 __le16 *freq = source;
0447 source += sizeof(__le16);
0448 *((__le16 *)target) = *freq;
0449 target += sizeof(__le16);
0450 for (j = 0; j < curve_data->points_per_channel; j++) {
0451 dst = target;
0452 src = source;
0453
0454 dst->rf_power = src->rf_power;
0455 dst->pa_detector = src->pa_detector;
0456 dst->data_64qam = src->pcv;
0457
0458 #define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y))
0459 dst->data_16qam = SUB(src->pcv, 12);
0460 dst->data_qpsk = SUB(dst->data_16qam, 12);
0461 dst->data_bpsk = SUB(dst->data_qpsk, 12);
0462 dst->data_barker = SUB(dst->data_bpsk, 14);
0463 #undef SUB
0464 target += sizeof(*dst);
0465 source += sizeof(*src);
0466 }
0467 }
0468
0469 return 0;
0470 }
0471
0472 static int p54_convert_rev1(struct ieee80211_hw *dev,
0473 struct pda_pa_curve_data *curve_data)
0474 {
0475 struct p54_common *priv = dev->priv;
0476 struct p54_pa_curve_data_sample *dst;
0477 struct pda_pa_curve_data_sample_rev1 *src;
0478 size_t cd_len = sizeof(*curve_data) +
0479 (curve_data->points_per_channel*sizeof(*dst) + 2) *
0480 curve_data->channels;
0481 unsigned int i, j;
0482 void *source, *target;
0483
0484 priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
0485 GFP_KERNEL);
0486 if (!priv->curve_data)
0487 return -ENOMEM;
0488
0489 priv->curve_data->entries = curve_data->channels;
0490 priv->curve_data->entry_size = sizeof(__le16) +
0491 sizeof(*dst) * curve_data->points_per_channel;
0492 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data);
0493 priv->curve_data->len = cd_len;
0494 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data));
0495 source = curve_data->data;
0496 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data;
0497 for (i = 0; i < curve_data->channels; i++) {
0498 __le16 *freq = source;
0499 source += sizeof(__le16);
0500 *((__le16 *)target) = *freq;
0501 target += sizeof(__le16);
0502 for (j = 0; j < curve_data->points_per_channel; j++) {
0503 memcpy(target, source, sizeof(*src));
0504
0505 target += sizeof(*dst);
0506 source += sizeof(*src);
0507 }
0508 source++;
0509 }
0510
0511 return 0;
0512 }
0513
0514 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
0515 "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
0516
0517 static int p54_parse_rssical(struct ieee80211_hw *dev,
0518 u8 *data, int len, u16 type)
0519 {
0520 struct p54_common *priv = dev->priv;
0521 struct p54_rssi_db_entry *entry;
0522 size_t db_len, entries;
0523 int offset = 0, i;
0524
0525 if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
0526 entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
0527 if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
0528 wiphy_err(dev->wiphy, "rssical size mismatch.\n");
0529 goto err_data;
0530 }
0531 } else {
0532
0533
0534
0535
0536 if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
0537 offset += 2;
0538
0539 entries = (len - offset) /
0540 sizeof(struct pda_rssi_cal_ext_entry);
0541
0542 if (len < offset ||
0543 (len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
0544 entries == 0) {
0545 wiphy_err(dev->wiphy, "invalid rssi database.\n");
0546 goto err_data;
0547 }
0548 }
0549
0550 db_len = sizeof(*entry) * entries;
0551 priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
0552 if (!priv->rssi_db)
0553 return -ENOMEM;
0554
0555 priv->rssi_db->offset = 0;
0556 priv->rssi_db->entries = entries;
0557 priv->rssi_db->entry_size = sizeof(*entry);
0558 priv->rssi_db->len = db_len;
0559
0560 entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
0561 if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
0562 struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
0563
0564 for (i = 0; i < entries; i++) {
0565 entry[i].freq = le16_to_cpu(cal[i].freq);
0566 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
0567 entry[i].add = (s16) le16_to_cpu(cal[i].add);
0568 }
0569 } else {
0570 struct pda_rssi_cal_entry *cal = (void *) &data[offset];
0571
0572 for (i = 0; i < entries; i++) {
0573 u16 freq = 0;
0574 switch (i) {
0575 case NL80211_BAND_2GHZ:
0576 freq = 2437;
0577 break;
0578 case NL80211_BAND_5GHZ:
0579 freq = 5240;
0580 break;
0581 }
0582
0583 entry[i].freq = freq;
0584 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
0585 entry[i].add = (s16) le16_to_cpu(cal[i].add);
0586 }
0587 }
0588
0589
0590 sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
0591 return 0;
0592
0593 err_data:
0594 wiphy_err(dev->wiphy,
0595 "rssi calibration data packing type:(%x) len:%d.\n",
0596 type, len);
0597
0598 print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
0599
0600 wiphy_err(dev->wiphy, "please report this issue.\n");
0601 return -EINVAL;
0602 }
0603
0604 struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
0605 {
0606 struct p54_rssi_db_entry *entry;
0607 int i, found = -1;
0608
0609 if (!priv->rssi_db)
0610 return &p54_rssi_default;
0611
0612 entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
0613 for (i = 0; i < priv->rssi_db->entries; i++) {
0614 if (!same_band(freq, entry[i].freq))
0615 continue;
0616
0617 if (found == -1) {
0618 found = i;
0619 continue;
0620 }
0621
0622
0623 if (abs(freq - entry[i].freq) <
0624 abs(freq - entry[found].freq)) {
0625 found = i;
0626 continue;
0627 } else {
0628 break;
0629 }
0630 }
0631
0632 return found < 0 ? &p54_rssi_default : &entry[found];
0633 }
0634
0635 static void p54_parse_default_country(struct ieee80211_hw *dev,
0636 void *data, int len)
0637 {
0638 struct pda_country *country;
0639
0640 if (len != sizeof(*country)) {
0641 wiphy_err(dev->wiphy,
0642 "found possible invalid default country eeprom entry. (entry size: %d)\n",
0643 len);
0644
0645 print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
0646 data, len);
0647
0648 wiphy_err(dev->wiphy, "please report this issue.\n");
0649 return;
0650 }
0651
0652 country = (struct pda_country *) data;
0653 if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO)
0654 regulatory_hint(dev->wiphy, country->alpha2);
0655 else {
0656
0657
0658
0659
0660
0661 }
0662 }
0663
0664 static int p54_convert_output_limits(struct ieee80211_hw *dev,
0665 u8 *data, size_t len)
0666 {
0667 struct p54_common *priv = dev->priv;
0668
0669 if (len < 2)
0670 return -EINVAL;
0671
0672 if (data[0] != 0) {
0673 wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
0674 data[0]);
0675 return -EINVAL;
0676 }
0677
0678 if (2 + data[1] * sizeof(struct pda_channel_output_limit) > len)
0679 return -EINVAL;
0680
0681 priv->output_limit = kmalloc(data[1] *
0682 sizeof(struct pda_channel_output_limit) +
0683 sizeof(*priv->output_limit), GFP_KERNEL);
0684
0685 if (!priv->output_limit)
0686 return -ENOMEM;
0687
0688 priv->output_limit->offset = 0;
0689 priv->output_limit->entries = data[1];
0690 priv->output_limit->entry_size =
0691 sizeof(struct pda_channel_output_limit);
0692 priv->output_limit->len = priv->output_limit->entry_size *
0693 priv->output_limit->entries +
0694 priv->output_limit->offset;
0695
0696 memcpy(priv->output_limit->data, &data[2],
0697 data[1] * sizeof(struct pda_channel_output_limit));
0698
0699 return 0;
0700 }
0701
0702 static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
0703 size_t total_len)
0704 {
0705 struct p54_cal_database *dst;
0706 size_t payload_len, entries, entry_size, offset;
0707
0708 payload_len = le16_to_cpu(src->len);
0709 entries = le16_to_cpu(src->entries);
0710 entry_size = le16_to_cpu(src->entry_size);
0711 offset = le16_to_cpu(src->offset);
0712 if (((entries * entry_size + offset) != payload_len) ||
0713 (payload_len + sizeof(*src) != total_len))
0714 return NULL;
0715
0716 dst = kmalloc(sizeof(*dst) + payload_len, GFP_KERNEL);
0717 if (!dst)
0718 return NULL;
0719
0720 dst->entries = entries;
0721 dst->entry_size = entry_size;
0722 dst->offset = offset;
0723 dst->len = payload_len;
0724
0725 memcpy(dst->data, src->data, payload_len);
0726 return dst;
0727 }
0728
0729 int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
0730 {
0731 struct p54_common *priv = dev->priv;
0732 struct eeprom_pda_wrap *wrap;
0733 struct pda_entry *entry;
0734 unsigned int data_len, entry_len;
0735 void *tmp;
0736 int err;
0737 u8 *end = (u8 *)eeprom + len;
0738 u16 synth = 0;
0739 u16 crc16 = ~0;
0740
0741 wrap = (struct eeprom_pda_wrap *) eeprom;
0742 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
0743
0744
0745 while ((u8 *)entry <= end - sizeof(*entry)) {
0746 entry_len = le16_to_cpu(entry->len);
0747 data_len = ((entry_len - 1) << 1);
0748
0749
0750 if ((u8 *)entry + sizeof(*entry) + data_len > end)
0751 break;
0752
0753 switch (le16_to_cpu(entry->code)) {
0754 case PDR_MAC_ADDRESS:
0755 if (data_len != ETH_ALEN)
0756 break;
0757 SET_IEEE80211_PERM_ADDR(dev, entry->data);
0758 break;
0759 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS:
0760 if (priv->output_limit)
0761 break;
0762 err = p54_convert_output_limits(dev, entry->data,
0763 data_len);
0764 if (err)
0765 goto err;
0766 break;
0767 case PDR_PRISM_PA_CAL_CURVE_DATA: {
0768 struct pda_pa_curve_data *curve_data =
0769 (struct pda_pa_curve_data *)entry->data;
0770 if (data_len < sizeof(*curve_data)) {
0771 err = -EINVAL;
0772 goto err;
0773 }
0774
0775 switch (curve_data->cal_method_rev) {
0776 case 0:
0777 err = p54_convert_rev0(dev, curve_data);
0778 break;
0779 case 1:
0780 err = p54_convert_rev1(dev, curve_data);
0781 break;
0782 default:
0783 wiphy_err(dev->wiphy,
0784 "unknown curve data revision %d\n",
0785 curve_data->cal_method_rev);
0786 err = -ENODEV;
0787 break;
0788 }
0789 if (err)
0790 goto err;
0791 }
0792 break;
0793 case PDR_PRISM_ZIF_TX_IQ_CALIBRATION:
0794 priv->iq_autocal = kmemdup(entry->data, data_len,
0795 GFP_KERNEL);
0796 if (!priv->iq_autocal) {
0797 err = -ENOMEM;
0798 goto err;
0799 }
0800
0801 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry);
0802 break;
0803 case PDR_DEFAULT_COUNTRY:
0804 p54_parse_default_country(dev, entry->data, data_len);
0805 break;
0806 case PDR_INTERFACE_LIST:
0807 tmp = entry->data;
0808 while ((u8 *)tmp < entry->data + data_len) {
0809 struct exp_if *exp_if = tmp;
0810 if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
0811 synth = le16_to_cpu(exp_if->variant);
0812 tmp += sizeof(*exp_if);
0813 }
0814 break;
0815 case PDR_HARDWARE_PLATFORM_COMPONENT_ID:
0816 if (data_len < 2)
0817 break;
0818 priv->version = *(u8 *)(entry->data + 1);
0819 break;
0820 case PDR_RSSI_LINEAR_APPROXIMATION:
0821 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
0822 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
0823 err = p54_parse_rssical(dev, entry->data, data_len,
0824 le16_to_cpu(entry->code));
0825 if (err)
0826 goto err;
0827 break;
0828 case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
0829 struct pda_custom_wrapper *pda = (void *) entry->data;
0830 __le16 *src;
0831 u16 *dst;
0832 int i;
0833
0834 if (priv->rssi_db || data_len < sizeof(*pda))
0835 break;
0836
0837 priv->rssi_db = p54_convert_db(pda, data_len);
0838 if (!priv->rssi_db)
0839 break;
0840
0841 src = (void *) priv->rssi_db->data;
0842 dst = (void *) priv->rssi_db->data;
0843
0844 for (i = 0; i < priv->rssi_db->entries; i++)
0845 *(dst++) = (s16) le16_to_cpu(*(src++));
0846
0847 }
0848 break;
0849 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
0850 struct pda_custom_wrapper *pda = (void *) entry->data;
0851 if (priv->output_limit || data_len < sizeof(*pda))
0852 break;
0853 priv->output_limit = p54_convert_db(pda, data_len);
0854 }
0855 break;
0856 case PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM: {
0857 struct pda_custom_wrapper *pda = (void *) entry->data;
0858 if (priv->curve_data || data_len < sizeof(*pda))
0859 break;
0860 priv->curve_data = p54_convert_db(pda, data_len);
0861 }
0862 break;
0863 case PDR_END:
0864 crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
0865 if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
0866 wiphy_err(dev->wiphy, "eeprom failed checksum "
0867 "test!\n");
0868 err = -ENOMSG;
0869 goto err;
0870 } else {
0871 goto good_eeprom;
0872 }
0873 break;
0874 default:
0875 break;
0876 }
0877
0878 crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
0879 entry = (void *)entry + (entry_len + 1) * 2;
0880 }
0881
0882 wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
0883 err = -ENODATA;
0884 goto err;
0885
0886 good_eeprom:
0887 if (!synth || !priv->iq_autocal || !priv->output_limit ||
0888 !priv->curve_data) {
0889 wiphy_err(dev->wiphy,
0890 "not all required entries found in eeprom!\n");
0891 err = -EINVAL;
0892 goto err;
0893 }
0894
0895 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
0896
0897 err = p54_generate_channel_lists(dev);
0898 if (err)
0899 goto err;
0900
0901 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
0902 p54_init_xbow_synth(priv);
0903 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
0904 dev->wiphy->bands[NL80211_BAND_2GHZ] =
0905 priv->band_table[NL80211_BAND_2GHZ];
0906 if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
0907 dev->wiphy->bands[NL80211_BAND_5GHZ] =
0908 priv->band_table[NL80211_BAND_5GHZ];
0909 if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
0910 priv->rx_diversity_mask = 3;
0911 if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
0912 priv->tx_diversity_mask = 3;
0913
0914 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
0915 u8 perm_addr[ETH_ALEN];
0916
0917 wiphy_warn(dev->wiphy,
0918 "Invalid hwaddr! Using randomly generated MAC addr\n");
0919 eth_random_addr(perm_addr);
0920 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
0921 }
0922
0923 priv->cur_rssi = &p54_rssi_default;
0924
0925 wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
0926 dev->wiphy->perm_addr, priv->version,
0927 p54_rf_chips[priv->rxhw]);
0928
0929 return 0;
0930
0931 err:
0932 kfree(priv->iq_autocal);
0933 kfree(priv->output_limit);
0934 kfree(priv->curve_data);
0935 kfree(priv->rssi_db);
0936 kfree(priv->survey);
0937 priv->iq_autocal = NULL;
0938 priv->output_limit = NULL;
0939 priv->curve_data = NULL;
0940 priv->rssi_db = NULL;
0941 priv->survey = NULL;
0942
0943 wiphy_err(dev->wiphy, "eeprom parse failed!\n");
0944 return err;
0945 }
0946 EXPORT_SYMBOL_GPL(p54_parse_eeprom);
0947
0948 int p54_read_eeprom(struct ieee80211_hw *dev)
0949 {
0950 struct p54_common *priv = dev->priv;
0951 size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
0952 int ret = -ENOMEM;
0953 void *eeprom;
0954
0955 maxblocksize = EEPROM_READBACK_LEN;
0956 if (priv->fw_var >= 0x509)
0957 maxblocksize -= 0xc;
0958 else
0959 maxblocksize -= 0x4;
0960
0961 eeprom = kzalloc(eeprom_size, GFP_KERNEL);
0962 if (unlikely(!eeprom))
0963 goto free;
0964
0965 while (eeprom_size) {
0966 blocksize = min(eeprom_size, maxblocksize);
0967 ret = p54_download_eeprom(priv, eeprom + offset,
0968 offset, blocksize);
0969 if (unlikely(ret))
0970 goto free;
0971
0972 offset += blocksize;
0973 eeprom_size -= blocksize;
0974 }
0975
0976 ret = p54_parse_eeprom(dev, eeprom, offset);
0977 free:
0978 kfree(eeprom);
0979 return ret;
0980 }
0981 EXPORT_SYMBOL_GPL(p54_read_eeprom);