Lines Matching +full:country +full:- +full:code
1 // SPDX-License-Identifier: GPL-2.0-only
3 * EEPROM parser code for mac80211 Prism54 drivers
6 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
10 * - the islsm (softmac prism54) driver, which is:
11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
12 * - stlc45xx driver
13 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
22 #include <linux/crc-ccitt.h>
57 * The defaults are taken from usb-logs of the
60 * rssi <-> dBm conversion database.
63 .add = -398,
96 return -1; in p54_get_band_from_freq()
110 return a->freq - b->freq; in p54_compare_channels()
119 return a->freq - b->freq; in p54_compare_rssichan()
130 band_entry->bitrates = p54_bgrates; in p54_fill_band_bitrates()
131 band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates); in p54_fill_band_bitrates()
134 band_entry->bitrates = p54_arates; in p54_fill_band_bitrates()
135 band_entry->n_bitrates = ARRAY_SIZE(p54_arates); in p54_fill_band_bitrates()
138 return -EINVAL; in p54_fill_band_bitrates()
149 struct p54_common *priv = dev->priv; in p54_generate_band()
152 int ret = -ENOMEM; in p54_generate_band()
154 if ((!list->entries) || (!list->band_channel_num[band])) in p54_generate_band()
155 return -EINVAL; in p54_generate_band()
161 tmp->channels = kcalloc(list->band_channel_num[band], in p54_generate_band()
164 if (!tmp->channels) in p54_generate_band()
171 for (i = 0, j = 0; (j < list->band_channel_num[band]) && in p54_generate_band()
172 (i < list->entries); i++) { in p54_generate_band()
173 struct p54_channel_entry *chan = &list->channels[i]; in p54_generate_band()
174 struct ieee80211_channel *dest = &tmp->channels[j]; in p54_generate_band()
176 if (chan->band != band) in p54_generate_band()
179 if (chan->data != CHAN_HAS_ALL) { in p54_generate_band()
180 wiphy_err(dev->wiphy, "%s%s%s is/are missing for " in p54_generate_band()
182 (chan->data & CHAN_HAS_CAL ? "" : in p54_generate_band()
184 (chan->data & CHAN_HAS_LIMIT ? "" : in p54_generate_band()
186 (chan->data & CHAN_HAS_CURVE ? "" : in p54_generate_band()
188 chan->index, chan->freq); in p54_generate_band()
192 dest->band = chan->band; in p54_generate_band()
193 dest->center_freq = chan->freq; in p54_generate_band()
194 dest->max_power = chan->max_power; in p54_generate_band()
195 priv->survey[*chan_num].channel = &tmp->channels[j]; in p54_generate_band()
196 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM | in p54_generate_band()
200 dest->hw_value = (*chan_num); in p54_generate_band()
206 wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n", in p54_generate_band()
209 ret = -ENODATA; in p54_generate_band()
213 tmp->n_channels = j; in p54_generate_band()
214 old = priv->band_table[band]; in p54_generate_band()
215 priv->band_table[band] = tmp; in p54_generate_band()
217 kfree(old->channels); in p54_generate_band()
225 kfree(tmp->channels); in p54_generate_band()
243 for (i = list->entries; i >= 0; i--) { in p54_update_channel_param()
244 if (freq == list->channels[i].freq) { in p54_update_channel_param()
245 entry = &list->channels[i]; in p54_update_channel_param()
250 if ((i < 0) && (list->entries < list->max_entries)) { in p54_update_channel_param()
259 i = list->entries++; in p54_update_channel_param()
260 list->band_channel_num[band]++; in p54_update_channel_param()
262 entry = &list->channels[i]; in p54_update_channel_param()
263 entry->freq = freq; in p54_update_channel_param()
264 entry->band = band; in p54_update_channel_param()
265 entry->index = ieee80211_frequency_to_channel(freq); in p54_update_channel_param()
266 entry->max_power = 0; in p54_update_channel_param()
267 entry->data = 0; in p54_update_channel_param()
272 entry->data |= data; in p54_update_channel_param()
279 switch (priv->rxhw & PDR_SYNTH_FRONTEND_MASK) { in p54_get_maxpower()
285 for (j = 0; j < ARRAY_SIZE(pda->point); j++) { in p54_get_maxpower()
287 &pda->point[j]; in p54_get_maxpower()
289 rawpower, le16_to_cpu(point->val_qpsk)); in p54_get_maxpower()
291 rawpower, le16_to_cpu(point->val_bpsk)); in p54_get_maxpower()
293 rawpower, le16_to_cpu(point->val_16qam)); in p54_get_maxpower()
295 rawpower, le16_to_cpu(point->val_64qam)); in p54_get_maxpower()
307 rawpower = max(rawpower, pda->val_qpsk); in p54_get_maxpower()
308 rawpower = max(rawpower, pda->val_bpsk); in p54_get_maxpower()
309 rawpower = max(rawpower, pda->val_16qam); in p54_get_maxpower()
310 rawpower = max(rawpower, pda->val_64qam); in p54_get_maxpower()
322 struct p54_common *priv = dev->priv; in p54_generate_channel_lists()
328 if ((priv->iq_autocal_len != priv->curve_data->entries) || in p54_generate_channel_lists()
329 (priv->iq_autocal_len != priv->output_limit->entries)) in p54_generate_channel_lists()
330 wiphy_err(dev->wiphy, in p54_generate_channel_lists()
334 max_channel_num = max_t(unsigned int, priv->output_limit->entries, in p54_generate_channel_lists()
335 priv->iq_autocal_len); in p54_generate_channel_lists()
337 priv->curve_data->entries); in p54_generate_channel_lists()
341 ret = -ENOMEM; in p54_generate_channel_lists()
344 priv->chan_num = max_channel_num; in p54_generate_channel_lists()
345 priv->survey = kcalloc(max_channel_num, sizeof(struct survey_info), in p54_generate_channel_lists()
347 if (!priv->survey) { in p54_generate_channel_lists()
348 ret = -ENOMEM; in p54_generate_channel_lists()
352 list->max_entries = max_channel_num; in p54_generate_channel_lists()
353 list->channels = kcalloc(max_channel_num, in p54_generate_channel_lists()
356 if (!list->channels) { in p54_generate_channel_lists()
357 ret = -ENOMEM; in p54_generate_channel_lists()
362 if (i < priv->iq_autocal_len) { in p54_generate_channel_lists()
363 freq = le16_to_cpu(priv->iq_autocal[i].freq); in p54_generate_channel_lists()
367 if (i < priv->output_limit->entries) { in p54_generate_channel_lists()
371 priv->output_limit->entry_size + in p54_generate_channel_lists()
372 priv->output_limit->offset + in p54_generate_channel_lists()
373 priv->output_limit->data); in p54_generate_channel_lists()
379 tmp->max_power = p54_get_maxpower(priv, data); in p54_generate_channel_lists()
383 if (i < priv->curve_data->entries) { in p54_generate_channel_lists()
385 priv->curve_data->entry_size + in p54_generate_channel_lists()
386 priv->curve_data->offset + in p54_generate_channel_lists()
387 priv->curve_data->data)); in p54_generate_channel_lists()
394 sort(list->channels, list->entries, sizeof(struct p54_channel_entry), in p54_generate_channel_lists()
404 ret = -EINVAL; in p54_generate_channel_lists()
409 kfree(list->channels); in p54_generate_channel_lists()
413 kfree(priv->survey); in p54_generate_channel_lists()
414 priv->survey = NULL; in p54_generate_channel_lists()
423 struct p54_common *priv = dev->priv; in p54_convert_rev0()
427 (curve_data->points_per_channel*sizeof(*dst) + 2) * in p54_convert_rev0()
428 curve_data->channels; in p54_convert_rev0()
432 priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len, in p54_convert_rev0()
434 if (!priv->curve_data) in p54_convert_rev0()
435 return -ENOMEM; in p54_convert_rev0()
437 priv->curve_data->entries = curve_data->channels; in p54_convert_rev0()
438 priv->curve_data->entry_size = sizeof(__le16) + in p54_convert_rev0()
439 sizeof(*dst) * curve_data->points_per_channel; in p54_convert_rev0()
440 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data); in p54_convert_rev0()
441 priv->curve_data->len = cd_len; in p54_convert_rev0()
442 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data)); in p54_convert_rev0()
443 source = curve_data->data; in p54_convert_rev0()
444 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data; in p54_convert_rev0()
445 for (i = 0; i < curve_data->channels; i++) { in p54_convert_rev0()
450 for (j = 0; j < curve_data->points_per_channel; j++) { in p54_convert_rev0()
454 dst->rf_power = src->rf_power; in p54_convert_rev0()
455 dst->pa_detector = src->pa_detector; in p54_convert_rev0()
456 dst->data_64qam = src->pcv; in p54_convert_rev0()
458 #define SUB(x, y) (u8)(((x) - (y)) > (x) ? 0 : (x) - (y)) in p54_convert_rev0()
459 dst->data_16qam = SUB(src->pcv, 12); in p54_convert_rev0()
460 dst->data_qpsk = SUB(dst->data_16qam, 12); in p54_convert_rev0()
461 dst->data_bpsk = SUB(dst->data_qpsk, 12); in p54_convert_rev0()
462 dst->data_barker = SUB(dst->data_bpsk, 14); in p54_convert_rev0()
475 struct p54_common *priv = dev->priv; in p54_convert_rev1()
479 (curve_data->points_per_channel*sizeof(*dst) + 2) * in p54_convert_rev1()
480 curve_data->channels; in p54_convert_rev1()
484 priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data), in p54_convert_rev1()
486 if (!priv->curve_data) in p54_convert_rev1()
487 return -ENOMEM; in p54_convert_rev1()
489 priv->curve_data->entries = curve_data->channels; in p54_convert_rev1()
490 priv->curve_data->entry_size = sizeof(__le16) + in p54_convert_rev1()
491 sizeof(*dst) * curve_data->points_per_channel; in p54_convert_rev1()
492 priv->curve_data->offset = offsetof(struct pda_pa_curve_data, data); in p54_convert_rev1()
493 priv->curve_data->len = cd_len; in p54_convert_rev1()
494 memcpy(priv->curve_data->data, curve_data, sizeof(*curve_data)); in p54_convert_rev1()
495 source = curve_data->data; in p54_convert_rev1()
496 target = ((struct pda_pa_curve_data *) priv->curve_data->data)->data; in p54_convert_rev1()
497 for (i = 0; i < curve_data->channels; i++) { in p54_convert_rev1()
502 for (j = 0; j < curve_data->points_per_channel; j++) { in p54_convert_rev1()
514 static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
515 "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
520 struct p54_common *priv = dev->priv; in p54_parse_rssical()
528 wiphy_err(dev->wiphy, "rssical size mismatch.\n"); in p54_parse_rssical()
539 entries = (len - offset) / in p54_parse_rssical()
543 (len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || in p54_parse_rssical()
545 wiphy_err(dev->wiphy, "invalid rssi database.\n"); in p54_parse_rssical()
551 priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL); in p54_parse_rssical()
552 if (!priv->rssi_db) in p54_parse_rssical()
553 return -ENOMEM; in p54_parse_rssical()
555 priv->rssi_db->offset = 0; in p54_parse_rssical()
556 priv->rssi_db->entries = entries; in p54_parse_rssical()
557 priv->rssi_db->entry_size = sizeof(*entry); in p54_parse_rssical()
558 priv->rssi_db->len = db_len; in p54_parse_rssical()
560 entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset); in p54_parse_rssical()
594 wiphy_err(dev->wiphy, in p54_parse_rssical()
600 wiphy_err(dev->wiphy, "please report this issue.\n"); in p54_parse_rssical()
601 return -EINVAL; in p54_parse_rssical()
607 int i, found = -1; in p54_rssi_find()
609 if (!priv->rssi_db) in p54_rssi_find()
612 entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset); in p54_rssi_find()
613 for (i = 0; i < priv->rssi_db->entries; i++) { in p54_rssi_find()
617 if (found == -1) { in p54_rssi_find()
623 if (abs(freq - entry[i].freq) < in p54_rssi_find()
624 abs(freq - entry[found].freq)) { in p54_rssi_find()
638 struct pda_country *country; in p54_parse_default_country() local
640 if (len != sizeof(*country)) { in p54_parse_default_country()
641 wiphy_err(dev->wiphy, in p54_parse_default_country()
642 "found possible invalid default country eeprom entry. (entry size: %d)\n", in p54_parse_default_country()
645 print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, in p54_parse_default_country()
648 wiphy_err(dev->wiphy, "please report this issue.\n"); in p54_parse_default_country()
652 country = (struct pda_country *) data; in p54_parse_default_country()
653 if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO) in p54_parse_default_country()
654 regulatory_hint(dev->wiphy, country->alpha2); in p54_parse_default_country()
658 * "Regulatory domain codes" (802.11-2007 14.8.2.2) in p54_parse_default_country()
659 * into ISO/IEC 3166-1 alpha2 for regulatory_hint. in p54_parse_default_country()
667 struct p54_common *priv = dev->priv; in p54_convert_output_limits()
670 return -EINVAL; in p54_convert_output_limits()
673 wiphy_err(dev->wiphy, "unknown output power db revision:%x\n", in p54_convert_output_limits()
675 return -EINVAL; in p54_convert_output_limits()
679 return -EINVAL; in p54_convert_output_limits()
681 priv->output_limit = kmalloc(data[1] * in p54_convert_output_limits()
683 sizeof(*priv->output_limit), GFP_KERNEL); in p54_convert_output_limits()
685 if (!priv->output_limit) in p54_convert_output_limits()
686 return -ENOMEM; in p54_convert_output_limits()
688 priv->output_limit->offset = 0; in p54_convert_output_limits()
689 priv->output_limit->entries = data[1]; in p54_convert_output_limits()
690 priv->output_limit->entry_size = in p54_convert_output_limits()
692 priv->output_limit->len = priv->output_limit->entry_size * in p54_convert_output_limits()
693 priv->output_limit->entries + in p54_convert_output_limits()
694 priv->output_limit->offset; in p54_convert_output_limits()
696 memcpy(priv->output_limit->data, &data[2], in p54_convert_output_limits()
708 payload_len = le16_to_cpu(src->len); in p54_convert_db()
709 entries = le16_to_cpu(src->entries); in p54_convert_db()
710 entry_size = le16_to_cpu(src->entry_size); in p54_convert_db()
711 offset = le16_to_cpu(src->offset); in p54_convert_db()
720 dst->entries = entries; in p54_convert_db()
721 dst->entry_size = entry_size; in p54_convert_db()
722 dst->offset = offset; in p54_convert_db()
723 dst->len = payload_len; in p54_convert_db()
725 memcpy(dst->data, src->data, payload_len); in p54_convert_db()
731 struct p54_common *priv = dev->priv; in p54_parse_eeprom()
742 entry = (void *)wrap->data + le16_to_cpu(wrap->len); in p54_parse_eeprom()
744 /* verify that at least the entry length/code fits */ in p54_parse_eeprom()
745 while ((u8 *)entry <= end - sizeof(*entry)) { in p54_parse_eeprom()
746 entry_len = le16_to_cpu(entry->len); in p54_parse_eeprom()
747 data_len = ((entry_len - 1) << 1); in p54_parse_eeprom()
753 switch (le16_to_cpu(entry->code)) { in p54_parse_eeprom()
757 SET_IEEE80211_PERM_ADDR(dev, entry->data); in p54_parse_eeprom()
760 if (priv->output_limit) in p54_parse_eeprom()
762 err = p54_convert_output_limits(dev, entry->data, in p54_parse_eeprom()
769 (struct pda_pa_curve_data *)entry->data; in p54_parse_eeprom()
771 err = -EINVAL; in p54_parse_eeprom()
775 switch (curve_data->cal_method_rev) { in p54_parse_eeprom()
783 wiphy_err(dev->wiphy, in p54_parse_eeprom()
785 curve_data->cal_method_rev); in p54_parse_eeprom()
786 err = -ENODEV; in p54_parse_eeprom()
794 priv->iq_autocal = kmemdup(entry->data, data_len, in p54_parse_eeprom()
796 if (!priv->iq_autocal) { in p54_parse_eeprom()
797 err = -ENOMEM; in p54_parse_eeprom()
801 priv->iq_autocal_len = data_len / sizeof(struct pda_iq_autocal_entry); in p54_parse_eeprom()
804 p54_parse_default_country(dev, entry->data, data_len); in p54_parse_eeprom()
807 tmp = entry->data; in p54_parse_eeprom()
808 while ((u8 *)tmp < entry->data + data_len) { in p54_parse_eeprom()
810 if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000)) in p54_parse_eeprom()
811 synth = le16_to_cpu(exp_if->variant); in p54_parse_eeprom()
818 priv->version = *(u8 *)(entry->data + 1); in p54_parse_eeprom()
823 err = p54_parse_rssical(dev, entry->data, data_len, in p54_parse_eeprom()
824 le16_to_cpu(entry->code)); in p54_parse_eeprom()
829 struct pda_custom_wrapper *pda = (void *) entry->data; in p54_parse_eeprom()
834 if (priv->rssi_db || data_len < sizeof(*pda)) in p54_parse_eeprom()
837 priv->rssi_db = p54_convert_db(pda, data_len); in p54_parse_eeprom()
838 if (!priv->rssi_db) in p54_parse_eeprom()
841 src = (void *) priv->rssi_db->data; in p54_parse_eeprom()
842 dst = (void *) priv->rssi_db->data; in p54_parse_eeprom()
844 for (i = 0; i < priv->rssi_db->entries; i++) in p54_parse_eeprom()
850 struct pda_custom_wrapper *pda = (void *) entry->data; in p54_parse_eeprom()
851 if (priv->output_limit || data_len < sizeof(*pda)) in p54_parse_eeprom()
853 priv->output_limit = p54_convert_db(pda, data_len); in p54_parse_eeprom()
857 struct pda_custom_wrapper *pda = (void *) entry->data; in p54_parse_eeprom()
858 if (priv->curve_data || data_len < sizeof(*pda)) in p54_parse_eeprom()
860 priv->curve_data = p54_convert_db(pda, data_len); in p54_parse_eeprom()
865 if (crc16 != le16_to_cpup((__le16 *)entry->data)) { in p54_parse_eeprom()
866 wiphy_err(dev->wiphy, "eeprom failed checksum " in p54_parse_eeprom()
868 err = -ENOMSG; in p54_parse_eeprom()
882 wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n"); in p54_parse_eeprom()
883 err = -ENODATA; in p54_parse_eeprom()
887 if (!synth || !priv->iq_autocal || !priv->output_limit || in p54_parse_eeprom()
888 !priv->curve_data) { in p54_parse_eeprom()
889 wiphy_err(dev->wiphy, in p54_parse_eeprom()
891 err = -EINVAL; in p54_parse_eeprom()
895 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; in p54_parse_eeprom()
901 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) in p54_parse_eeprom()
904 dev->wiphy->bands[NL80211_BAND_2GHZ] = in p54_parse_eeprom()
905 priv->band_table[NL80211_BAND_2GHZ]; in p54_parse_eeprom()
907 dev->wiphy->bands[NL80211_BAND_5GHZ] = in p54_parse_eeprom()
908 priv->band_table[NL80211_BAND_5GHZ]; in p54_parse_eeprom()
910 priv->rx_diversity_mask = 3; in p54_parse_eeprom()
912 priv->tx_diversity_mask = 3; in p54_parse_eeprom()
914 if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { in p54_parse_eeprom()
917 wiphy_warn(dev->wiphy, in p54_parse_eeprom()
923 priv->cur_rssi = &p54_rssi_default; in p54_parse_eeprom()
925 wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", in p54_parse_eeprom()
926 dev->wiphy->perm_addr, priv->version, in p54_parse_eeprom()
927 p54_rf_chips[priv->rxhw]); in p54_parse_eeprom()
932 kfree(priv->iq_autocal); in p54_parse_eeprom()
933 kfree(priv->output_limit); in p54_parse_eeprom()
934 kfree(priv->curve_data); in p54_parse_eeprom()
935 kfree(priv->rssi_db); in p54_parse_eeprom()
936 kfree(priv->survey); in p54_parse_eeprom()
937 priv->iq_autocal = NULL; in p54_parse_eeprom()
938 priv->output_limit = NULL; in p54_parse_eeprom()
939 priv->curve_data = NULL; in p54_parse_eeprom()
940 priv->rssi_db = NULL; in p54_parse_eeprom()
941 priv->survey = NULL; in p54_parse_eeprom()
943 wiphy_err(dev->wiphy, "eeprom parse failed!\n"); in p54_parse_eeprom()
950 struct p54_common *priv = dev->priv; in p54_read_eeprom()
952 int ret = -ENOMEM; in p54_read_eeprom()
956 if (priv->fw_var >= 0x509) in p54_read_eeprom()
957 maxblocksize -= 0xc; in p54_read_eeprom()
959 maxblocksize -= 0x4; in p54_read_eeprom()
973 eeprom_size -= blocksize; in p54_read_eeprom()