aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath5k/eeprom.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/eeprom.c')
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c158
1 files changed, 70 insertions, 88 deletions
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index efb672cb31e4..1fef84f87c78 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -660,6 +660,53 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
660 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; 660 vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
661} 661}
662 662
663static int
664ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
665{
666 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
667 struct ath5k_chan_pcal_info *chinfo;
668 u8 pier, pdg;
669
670 switch (mode) {
671 case AR5K_EEPROM_MODE_11A:
672 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
673 return 0;
674 chinfo = ee->ee_pwr_cal_a;
675 break;
676 case AR5K_EEPROM_MODE_11B:
677 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
678 return 0;
679 chinfo = ee->ee_pwr_cal_b;
680 break;
681 case AR5K_EEPROM_MODE_11G:
682 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
683 return 0;
684 chinfo = ee->ee_pwr_cal_g;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
691 if (!chinfo[pier].pd_curves)
692 continue;
693
694 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
695 struct ath5k_pdgain_info *pd =
696 &chinfo[pier].pd_curves[pdg];
697
698 if (pd != NULL) {
699 kfree(pd->pd_step);
700 kfree(pd->pd_pwr);
701 }
702 }
703
704 kfree(chinfo[pier].pd_curves);
705 }
706
707 return 0;
708}
709
663/* Convert RF5111 specific data to generic raw data 710/* Convert RF5111 specific data to generic raw data
664 * used by interpolation code */ 711 * used by interpolation code */
665static int 712static int
@@ -684,7 +731,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
684 GFP_KERNEL); 731 GFP_KERNEL);
685 732
686 if (!chinfo[pier].pd_curves) 733 if (!chinfo[pier].pd_curves)
687 return -ENOMEM; 734 goto err_out;
688 735
689 /* Only one curve for RF5111 736 /* Only one curve for RF5111
690 * find out which one and place 737 * find out which one and place
@@ -708,12 +755,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
708 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 755 pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
709 sizeof(u8), GFP_KERNEL); 756 sizeof(u8), GFP_KERNEL);
710 if (!pd->pd_step) 757 if (!pd->pd_step)
711 return -ENOMEM; 758 goto err_out;
712 759
713 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, 760 pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
714 sizeof(s16), GFP_KERNEL); 761 sizeof(s16), GFP_KERNEL);
715 if (!pd->pd_pwr) 762 if (!pd->pd_pwr)
716 return -ENOMEM; 763 goto err_out;
717 764
718 /* Fill raw dataset 765 /* Fill raw dataset
719 * (convert power to 0.25dB units 766 * (convert power to 0.25dB units
@@ -734,6 +781,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
734 } 781 }
735 782
736 return 0; 783 return 0;
784
785err_out:
786 ath5k_eeprom_free_pcal_info(ah, mode);
787 return -ENOMEM;
737} 788}
738 789
739/* Parse EEPROM data */ 790/* Parse EEPROM data */
@@ -867,7 +918,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
867 GFP_KERNEL); 918 GFP_KERNEL);
868 919
869 if (!chinfo[pier].pd_curves) 920 if (!chinfo[pier].pd_curves)
870 return -ENOMEM; 921 goto err_out;
871 922
872 /* Fill pd_curves */ 923 /* Fill pd_curves */
873 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 924 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -886,14 +937,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
886 sizeof(u8), GFP_KERNEL); 937 sizeof(u8), GFP_KERNEL);
887 938
888 if (!pd->pd_step) 939 if (!pd->pd_step)
889 return -ENOMEM; 940 goto err_out;
890 941
891 pd->pd_pwr = kcalloc(pd->pd_points, 942 pd->pd_pwr = kcalloc(pd->pd_points,
892 sizeof(s16), GFP_KERNEL); 943 sizeof(s16), GFP_KERNEL);
893 944
894 if (!pd->pd_pwr) 945 if (!pd->pd_pwr)
895 return -ENOMEM; 946 goto err_out;
896
897 947
898 /* Fill raw dataset 948 /* Fill raw dataset
899 * (all power levels are in 0.25dB units) */ 949 * (all power levels are in 0.25dB units) */
@@ -925,13 +975,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
925 sizeof(u8), GFP_KERNEL); 975 sizeof(u8), GFP_KERNEL);
926 976
927 if (!pd->pd_step) 977 if (!pd->pd_step)
928 return -ENOMEM; 978 goto err_out;
929 979
930 pd->pd_pwr = kcalloc(pd->pd_points, 980 pd->pd_pwr = kcalloc(pd->pd_points,
931 sizeof(s16), GFP_KERNEL); 981 sizeof(s16), GFP_KERNEL);
932 982
933 if (!pd->pd_pwr) 983 if (!pd->pd_pwr)
934 return -ENOMEM; 984 goto err_out;
935 985
936 /* Fill raw dataset 986 /* Fill raw dataset
937 * (all power levels are in 0.25dB units) */ 987 * (all power levels are in 0.25dB units) */
@@ -954,6 +1004,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
954 } 1004 }
955 1005
956 return 0; 1006 return 0;
1007
1008err_out:
1009 ath5k_eeprom_free_pcal_info(ah, mode);
1010 return -ENOMEM;
957} 1011}
958 1012
959/* Parse EEPROM data */ 1013/* Parse EEPROM data */
@@ -1156,7 +1210,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1156 GFP_KERNEL); 1210 GFP_KERNEL);
1157 1211
1158 if (!chinfo[pier].pd_curves) 1212 if (!chinfo[pier].pd_curves)
1159 return -ENOMEM; 1213 goto err_out;
1160 1214
1161 /* Fill pd_curves */ 1215 /* Fill pd_curves */
1162 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { 1216 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -1177,13 +1231,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1177 sizeof(u8), GFP_KERNEL); 1231 sizeof(u8), GFP_KERNEL);
1178 1232
1179 if (!pd->pd_step) 1233 if (!pd->pd_step)
1180 return -ENOMEM; 1234 goto err_out;
1181 1235
1182 pd->pd_pwr = kcalloc(pd->pd_points, 1236 pd->pd_pwr = kcalloc(pd->pd_points,
1183 sizeof(s16), GFP_KERNEL); 1237 sizeof(s16), GFP_KERNEL);
1184 1238
1185 if (!pd->pd_pwr) 1239 if (!pd->pd_pwr)
1186 return -ENOMEM; 1240 goto err_out;
1187 1241
1188 /* Fill raw dataset 1242 /* Fill raw dataset
1189 * convert all pwr levels to 1243 * convert all pwr levels to
@@ -1213,6 +1267,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
1213 } 1267 }
1214 1268
1215 return 0; 1269 return 0;
1270
1271err_out:
1272 ath5k_eeprom_free_pcal_info(ah, mode);
1273 return -ENOMEM;
1216} 1274}
1217 1275
1218/* Parse EEPROM data */ 1276/* Parse EEPROM data */
@@ -1534,53 +1592,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
1534 return 0; 1592 return 0;
1535} 1593}
1536 1594
1537static int
1538ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
1539{
1540 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1541 struct ath5k_chan_pcal_info *chinfo;
1542 u8 pier, pdg;
1543
1544 switch (mode) {
1545 case AR5K_EEPROM_MODE_11A:
1546 if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
1547 return 0;
1548 chinfo = ee->ee_pwr_cal_a;
1549 break;
1550 case AR5K_EEPROM_MODE_11B:
1551 if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
1552 return 0;
1553 chinfo = ee->ee_pwr_cal_b;
1554 break;
1555 case AR5K_EEPROM_MODE_11G:
1556 if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
1557 return 0;
1558 chinfo = ee->ee_pwr_cal_g;
1559 break;
1560 default:
1561 return -EINVAL;
1562 }
1563
1564 for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
1565 if (!chinfo[pier].pd_curves)
1566 continue;
1567
1568 for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
1569 struct ath5k_pdgain_info *pd =
1570 &chinfo[pier].pd_curves[pdg];
1571
1572 if (pd != NULL) {
1573 kfree(pd->pd_step);
1574 kfree(pd->pd_pwr);
1575 }
1576 }
1577
1578 kfree(chinfo[pier].pd_curves);
1579 }
1580
1581 return 0;
1582}
1583
1584/* Read conformance test limits used for regulatory control */ 1595/* Read conformance test limits used for regulatory control */
1585static int 1596static int
1586ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) 1597ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1721,35 +1732,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
1721 return ret; 1732 return ret;
1722} 1733}
1723 1734
1724/*
1725 * Read the MAC address from eeprom
1726 */
1727int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
1728{
1729 u8 mac_d[ETH_ALEN] = {};
1730 u32 total, offset;
1731 u16 data;
1732 int octet;
1733
1734 AR5K_EEPROM_READ(0x20, data);
1735
1736 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
1737 AR5K_EEPROM_READ(offset, data);
1738
1739 total += data;
1740 mac_d[octet + 1] = data & 0xff;
1741 mac_d[octet] = data >> 8;
1742 octet += 2;
1743 }
1744
1745 if (!total || total == 3 * 0xffff)
1746 return -EINVAL;
1747
1748 memcpy(mac, mac_d, ETH_ALEN);
1749
1750 return 0;
1751}
1752
1753 1735
1754/***********************\ 1736/***********************\
1755* Init/Detach functions * 1737* Init/Detach functions *