diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/eeprom.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 255 |
1 files changed, 113 insertions, 142 deletions
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index ae316fec4a6a..392771f93759 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -28,45 +28,16 @@ | |||
28 | #include "debug.h" | 28 | #include "debug.h" |
29 | #include "base.h" | 29 | #include "base.h" |
30 | 30 | ||
31 | /* | ||
32 | * Read from eeprom | ||
33 | */ | ||
34 | static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | ||
35 | { | ||
36 | u32 status, timeout; | ||
37 | |||
38 | /* | ||
39 | * Initialize EEPROM access | ||
40 | */ | ||
41 | if (ah->ah_version == AR5K_AR5210) { | ||
42 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); | ||
43 | (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); | ||
44 | } else { | ||
45 | ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); | ||
46 | AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, | ||
47 | AR5K_EEPROM_CMD_READ); | ||
48 | } | ||
49 | |||
50 | for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { | ||
51 | status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); | ||
52 | if (status & AR5K_EEPROM_STAT_RDDONE) { | ||
53 | if (status & AR5K_EEPROM_STAT_RDERR) | ||
54 | return -EIO; | ||
55 | *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & | ||
56 | 0xffff); | ||
57 | return 0; | ||
58 | } | ||
59 | udelay(15); | ||
60 | } | ||
61 | 31 | ||
62 | return -ETIMEDOUT; | 32 | /******************\ |
63 | } | 33 | * Helper functions * |
34 | \******************/ | ||
64 | 35 | ||
65 | /* | 36 | /* |
66 | * Translate binary channel representation in EEPROM to frequency | 37 | * Translate binary channel representation in EEPROM to frequency |
67 | */ | 38 | */ |
68 | static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, | 39 | static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, |
69 | unsigned int mode) | 40 | unsigned int mode) |
70 | { | 41 | { |
71 | u16 val; | 42 | u16 val; |
72 | 43 | ||
@@ -89,6 +60,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, | |||
89 | return val; | 60 | return val; |
90 | } | 61 | } |
91 | 62 | ||
63 | |||
64 | /*********\ | ||
65 | * Parsers * | ||
66 | \*********/ | ||
67 | |||
92 | /* | 68 | /* |
93 | * Initialize eeprom & capabilities structs | 69 | * Initialize eeprom & capabilities structs |
94 | */ | 70 | */ |
@@ -96,7 +72,6 @@ static int | |||
96 | ath5k_eeprom_init_header(struct ath5k_hw *ah) | 72 | ath5k_eeprom_init_header(struct ath5k_hw *ah) |
97 | { | 73 | { |
98 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 74 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
99 | int ret; | ||
100 | u16 val; | 75 | u16 val; |
101 | u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; | 76 | u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; |
102 | 77 | ||
@@ -198,7 +173,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah) | |||
198 | * | 173 | * |
199 | * XXX: Serdes values seem to be fixed so | 174 | * XXX: Serdes values seem to be fixed so |
200 | * no need to read them here, we write them | 175 | * no need to read them here, we write them |
201 | * during ath5k_hw_attach */ | 176 | * during ath5k_hw_init */ |
202 | AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); | 177 | AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val); |
203 | ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? | 178 | ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ? |
204 | true : false; | 179 | true : false; |
@@ -216,7 +191,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | |||
216 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 191 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
217 | u32 o = *offset; | 192 | u32 o = *offset; |
218 | u16 val; | 193 | u16 val; |
219 | int ret, i = 0; | 194 | int i = 0; |
220 | 195 | ||
221 | AR5K_EEPROM_READ(o++, val); | 196 | AR5K_EEPROM_READ(o++, val); |
222 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; | 197 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; |
@@ -276,7 +251,6 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
276 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 251 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
277 | u32 o = *offset; | 252 | u32 o = *offset; |
278 | u16 val; | 253 | u16 val; |
279 | int ret; | ||
280 | 254 | ||
281 | ee->ee_n_piers[mode] = 0; | 255 | ee->ee_n_piers[mode] = 0; |
282 | AR5K_EEPROM_READ(o++, val); | 256 | AR5K_EEPROM_READ(o++, val); |
@@ -539,7 +513,6 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, | |||
539 | int o = *offset; | 513 | int o = *offset; |
540 | int i = 0; | 514 | int i = 0; |
541 | u8 freq1, freq2; | 515 | u8 freq1, freq2; |
542 | int ret; | ||
543 | u16 val; | 516 | u16 val; |
544 | 517 | ||
545 | ee->ee_n_piers[mode] = 0; | 518 | ee->ee_n_piers[mode] = 0; |
@@ -575,7 +548,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset) | |||
575 | { | 548 | { |
576 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 549 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
577 | struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; | 550 | struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; |
578 | int i, ret; | 551 | int i; |
579 | u16 val; | 552 | u16 val; |
580 | u8 mask; | 553 | u8 mask; |
581 | 554 | ||
@@ -647,6 +620,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | |||
647 | return 0; | 620 | return 0; |
648 | } | 621 | } |
649 | 622 | ||
623 | |||
650 | /* | 624 | /* |
651 | * Read power calibration for RF5111 chips | 625 | * Read power calibration for RF5111 chips |
652 | * | 626 | * |
@@ -661,7 +635,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) | |||
661 | * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC | 635 | * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC |
662 | * steps that match with the power values we read from eeprom. On | 636 | * steps that match with the power values we read from eeprom. On |
663 | * older eeprom versions (< 3.2) these steps are equaly spaced at | 637 | * older eeprom versions (< 3.2) these steps are equaly spaced at |
664 | * 10% of the pcdac curve -until the curve reaches it's maximum- | 638 | * 10% of the pcdac curve -until the curve reaches its maximum- |
665 | * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) | 639 | * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) |
666 | * these 11 steps are spaced in a different way. This function returns | 640 | * these 11 steps are spaced in a different way. This function returns |
667 | * the pcdac steps based on eeprom version and curve min/max so that we | 641 | * the pcdac steps based on eeprom version and curve min/max so that we |
@@ -686,6 +660,51 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp) | |||
686 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; | 660 | vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100; |
687 | } | 661 | } |
688 | 662 | ||
663 | static int | ||
664 | ath5k_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 < AR5K_EEPROM_N_PD_CURVES; pdg++) { | ||
695 | struct ath5k_pdgain_info *pd = | ||
696 | &chinfo[pier].pd_curves[pdg]; | ||
697 | |||
698 | kfree(pd->pd_step); | ||
699 | kfree(pd->pd_pwr); | ||
700 | } | ||
701 | |||
702 | kfree(chinfo[pier].pd_curves); | ||
703 | } | ||
704 | |||
705 | return 0; | ||
706 | } | ||
707 | |||
689 | /* Convert RF5111 specific data to generic raw data | 708 | /* Convert RF5111 specific data to generic raw data |
690 | * used by interpolation code */ | 709 | * used by interpolation code */ |
691 | static int | 710 | static int |
@@ -710,7 +729,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
710 | GFP_KERNEL); | 729 | GFP_KERNEL); |
711 | 730 | ||
712 | if (!chinfo[pier].pd_curves) | 731 | if (!chinfo[pier].pd_curves) |
713 | return -ENOMEM; | 732 | goto err_out; |
714 | 733 | ||
715 | /* Only one curve for RF5111 | 734 | /* Only one curve for RF5111 |
716 | * find out which one and place | 735 | * find out which one and place |
@@ -734,12 +753,12 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
734 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 753 | pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
735 | sizeof(u8), GFP_KERNEL); | 754 | sizeof(u8), GFP_KERNEL); |
736 | if (!pd->pd_step) | 755 | if (!pd->pd_step) |
737 | return -ENOMEM; | 756 | goto err_out; |
738 | 757 | ||
739 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, | 758 | pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, |
740 | sizeof(s16), GFP_KERNEL); | 759 | sizeof(s16), GFP_KERNEL); |
741 | if (!pd->pd_pwr) | 760 | if (!pd->pd_pwr) |
742 | return -ENOMEM; | 761 | goto err_out; |
743 | 762 | ||
744 | /* Fill raw dataset | 763 | /* Fill raw dataset |
745 | * (convert power to 0.25dB units | 764 | * (convert power to 0.25dB units |
@@ -760,6 +779,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, | |||
760 | } | 779 | } |
761 | 780 | ||
762 | return 0; | 781 | return 0; |
782 | |||
783 | err_out: | ||
784 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
785 | return -ENOMEM; | ||
763 | } | 786 | } |
764 | 787 | ||
765 | /* Parse EEPROM data */ | 788 | /* Parse EEPROM data */ |
@@ -893,7 +916,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
893 | GFP_KERNEL); | 916 | GFP_KERNEL); |
894 | 917 | ||
895 | if (!chinfo[pier].pd_curves) | 918 | if (!chinfo[pier].pd_curves) |
896 | return -ENOMEM; | 919 | goto err_out; |
897 | 920 | ||
898 | /* Fill pd_curves */ | 921 | /* Fill pd_curves */ |
899 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 922 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -912,14 +935,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
912 | sizeof(u8), GFP_KERNEL); | 935 | sizeof(u8), GFP_KERNEL); |
913 | 936 | ||
914 | if (!pd->pd_step) | 937 | if (!pd->pd_step) |
915 | return -ENOMEM; | 938 | goto err_out; |
916 | 939 | ||
917 | pd->pd_pwr = kcalloc(pd->pd_points, | 940 | pd->pd_pwr = kcalloc(pd->pd_points, |
918 | sizeof(s16), GFP_KERNEL); | 941 | sizeof(s16), GFP_KERNEL); |
919 | 942 | ||
920 | if (!pd->pd_pwr) | 943 | if (!pd->pd_pwr) |
921 | return -ENOMEM; | 944 | goto err_out; |
922 | |||
923 | 945 | ||
924 | /* Fill raw dataset | 946 | /* Fill raw dataset |
925 | * (all power levels are in 0.25dB units) */ | 947 | * (all power levels are in 0.25dB units) */ |
@@ -951,13 +973,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
951 | sizeof(u8), GFP_KERNEL); | 973 | sizeof(u8), GFP_KERNEL); |
952 | 974 | ||
953 | if (!pd->pd_step) | 975 | if (!pd->pd_step) |
954 | return -ENOMEM; | 976 | goto err_out; |
955 | 977 | ||
956 | pd->pd_pwr = kcalloc(pd->pd_points, | 978 | pd->pd_pwr = kcalloc(pd->pd_points, |
957 | sizeof(s16), GFP_KERNEL); | 979 | sizeof(s16), GFP_KERNEL); |
958 | 980 | ||
959 | if (!pd->pd_pwr) | 981 | if (!pd->pd_pwr) |
960 | return -ENOMEM; | 982 | goto err_out; |
961 | 983 | ||
962 | /* Fill raw dataset | 984 | /* Fill raw dataset |
963 | * (all power levels are in 0.25dB units) */ | 985 | * (all power levels are in 0.25dB units) */ |
@@ -980,6 +1002,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, | |||
980 | } | 1002 | } |
981 | 1003 | ||
982 | return 0; | 1004 | return 0; |
1005 | |||
1006 | err_out: | ||
1007 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1008 | return -ENOMEM; | ||
983 | } | 1009 | } |
984 | 1010 | ||
985 | /* Parse EEPROM data */ | 1011 | /* Parse EEPROM data */ |
@@ -993,7 +1019,6 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | |||
993 | u32 offset; | 1019 | u32 offset; |
994 | u8 i, c; | 1020 | u8 i, c; |
995 | u16 val; | 1021 | u16 val; |
996 | int ret; | ||
997 | u8 pd_gains = 0; | 1022 | u8 pd_gains = 0; |
998 | 1023 | ||
999 | /* Count how many curves we have and | 1024 | /* Count how many curves we have and |
@@ -1107,13 +1132,13 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) | |||
1107 | * | 1132 | * |
1108 | * To recreate the curves we read here the points and interpolate | 1133 | * To recreate the curves we read here the points and interpolate |
1109 | * later. Note that in most cases only 2 (higher and lower) curves are | 1134 | * later. Note that in most cases only 2 (higher and lower) curves are |
1110 | * used (like RF5112) but vendors have the oportunity to include all | 1135 | * used (like RF5112) but vendors have the opportunity to include all |
1111 | * 4 curves on eeprom. The final curve (higher power) has an extra | 1136 | * 4 curves on eeprom. The final curve (higher power) has an extra |
1112 | * point for better accuracy like RF5112. | 1137 | * point for better accuracy like RF5112. |
1113 | */ | 1138 | */ |
1114 | 1139 | ||
1115 | /* For RF2413 power calibration data doesn't start on a fixed location and | 1140 | /* For RF2413 power calibration data doesn't start on a fixed location and |
1116 | * if a mode is not supported, it's section is missing -not zeroed-. | 1141 | * if a mode is not supported, its section is missing -not zeroed-. |
1117 | * So we need to calculate the starting offset for each section by using | 1142 | * So we need to calculate the starting offset for each section by using |
1118 | * these two functions */ | 1143 | * these two functions */ |
1119 | 1144 | ||
@@ -1183,7 +1208,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1183 | GFP_KERNEL); | 1208 | GFP_KERNEL); |
1184 | 1209 | ||
1185 | if (!chinfo[pier].pd_curves) | 1210 | if (!chinfo[pier].pd_curves) |
1186 | return -ENOMEM; | 1211 | goto err_out; |
1187 | 1212 | ||
1188 | /* Fill pd_curves */ | 1213 | /* Fill pd_curves */ |
1189 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 1214 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { |
@@ -1204,13 +1229,13 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1204 | sizeof(u8), GFP_KERNEL); | 1229 | sizeof(u8), GFP_KERNEL); |
1205 | 1230 | ||
1206 | if (!pd->pd_step) | 1231 | if (!pd->pd_step) |
1207 | return -ENOMEM; | 1232 | goto err_out; |
1208 | 1233 | ||
1209 | pd->pd_pwr = kcalloc(pd->pd_points, | 1234 | pd->pd_pwr = kcalloc(pd->pd_points, |
1210 | sizeof(s16), GFP_KERNEL); | 1235 | sizeof(s16), GFP_KERNEL); |
1211 | 1236 | ||
1212 | if (!pd->pd_pwr) | 1237 | if (!pd->pd_pwr) |
1213 | return -ENOMEM; | 1238 | goto err_out; |
1214 | 1239 | ||
1215 | /* Fill raw dataset | 1240 | /* Fill raw dataset |
1216 | * convert all pwr levels to | 1241 | * convert all pwr levels to |
@@ -1240,6 +1265,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, | |||
1240 | } | 1265 | } |
1241 | 1266 | ||
1242 | return 0; | 1267 | return 0; |
1268 | |||
1269 | err_out: | ||
1270 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1271 | return -ENOMEM; | ||
1243 | } | 1272 | } |
1244 | 1273 | ||
1245 | /* Parse EEPROM data */ | 1274 | /* Parse EEPROM data */ |
@@ -1251,7 +1280,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) | |||
1251 | struct ath5k_chan_pcal_info *chinfo; | 1280 | struct ath5k_chan_pcal_info *chinfo; |
1252 | u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; | 1281 | u8 *pdgain_idx = ee->ee_pdc_to_idx[mode]; |
1253 | u32 offset; | 1282 | u32 offset; |
1254 | int idx, i, ret; | 1283 | int idx, i; |
1255 | u16 val; | 1284 | u16 val; |
1256 | u8 pd_gains = 0; | 1285 | u8 pd_gains = 0; |
1257 | 1286 | ||
@@ -1329,7 +1358,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode) | |||
1329 | /* | 1358 | /* |
1330 | * Pd gain 0 is not the last pd gain | 1359 | * Pd gain 0 is not the last pd gain |
1331 | * so it only has 2 pd points. | 1360 | * so it only has 2 pd points. |
1332 | * Continue wih pd gain 1. | 1361 | * Continue with pd gain 1. |
1333 | */ | 1362 | */ |
1334 | pcinfo->pwr_i[1] = (val >> 10) & 0x1f; | 1363 | pcinfo->pwr_i[1] = (val >> 10) & 0x1f; |
1335 | 1364 | ||
@@ -1442,7 +1471,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | |||
1442 | u8 *rate_target_pwr_num; | 1471 | u8 *rate_target_pwr_num; |
1443 | u32 offset; | 1472 | u32 offset; |
1444 | u16 val; | 1473 | u16 val; |
1445 | int ret, i; | 1474 | int i; |
1446 | 1475 | ||
1447 | offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); | 1476 | offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1); |
1448 | rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; | 1477 | rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; |
@@ -1514,6 +1543,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) | |||
1514 | return 0; | 1543 | return 0; |
1515 | } | 1544 | } |
1516 | 1545 | ||
1546 | |||
1517 | /* | 1547 | /* |
1518 | * Read per channel calibration info from EEPROM | 1548 | * Read per channel calibration info from EEPROM |
1519 | * | 1549 | * |
@@ -1560,62 +1590,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah) | |||
1560 | return 0; | 1590 | return 0; |
1561 | } | 1591 | } |
1562 | 1592 | ||
1563 | static int | ||
1564 | ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | ||
1565 | { | ||
1566 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1567 | struct ath5k_chan_pcal_info *chinfo; | ||
1568 | u8 pier, pdg; | ||
1569 | |||
1570 | switch (mode) { | ||
1571 | case AR5K_EEPROM_MODE_11A: | ||
1572 | if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) | ||
1573 | return 0; | ||
1574 | chinfo = ee->ee_pwr_cal_a; | ||
1575 | break; | ||
1576 | case AR5K_EEPROM_MODE_11B: | ||
1577 | if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) | ||
1578 | return 0; | ||
1579 | chinfo = ee->ee_pwr_cal_b; | ||
1580 | break; | ||
1581 | case AR5K_EEPROM_MODE_11G: | ||
1582 | if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) | ||
1583 | return 0; | ||
1584 | chinfo = ee->ee_pwr_cal_g; | ||
1585 | break; | ||
1586 | default: | ||
1587 | return -EINVAL; | ||
1588 | } | ||
1589 | |||
1590 | for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { | ||
1591 | if (!chinfo[pier].pd_curves) | ||
1592 | continue; | ||
1593 | |||
1594 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | ||
1595 | struct ath5k_pdgain_info *pd = | ||
1596 | &chinfo[pier].pd_curves[pdg]; | ||
1597 | |||
1598 | if (pd != NULL) { | ||
1599 | kfree(pd->pd_step); | ||
1600 | kfree(pd->pd_pwr); | ||
1601 | } | ||
1602 | } | ||
1603 | |||
1604 | kfree(chinfo[pier].pd_curves); | ||
1605 | } | ||
1606 | |||
1607 | return 0; | ||
1608 | } | ||
1609 | |||
1610 | void | ||
1611 | ath5k_eeprom_detach(struct ath5k_hw *ah) | ||
1612 | { | ||
1613 | u8 mode; | ||
1614 | |||
1615 | for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) | ||
1616 | ath5k_eeprom_free_pcal_info(ah, mode); | ||
1617 | } | ||
1618 | |||
1619 | /* Read conformance test limits used for regulatory control */ | 1593 | /* Read conformance test limits used for regulatory control */ |
1620 | static int | 1594 | static int |
1621 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | 1595 | ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) |
@@ -1624,7 +1598,7 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) | |||
1624 | struct ath5k_edge_power *rep; | 1598 | struct ath5k_edge_power *rep; |
1625 | unsigned int fmask, pmask; | 1599 | unsigned int fmask, pmask; |
1626 | unsigned int ctl_mode; | 1600 | unsigned int ctl_mode; |
1627 | int ret, i, j; | 1601 | int i, j; |
1628 | u32 offset; | 1602 | u32 offset; |
1629 | u16 val; | 1603 | u16 val; |
1630 | 1604 | ||
@@ -1756,6 +1730,11 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) | |||
1756 | return ret; | 1730 | return ret; |
1757 | } | 1731 | } |
1758 | 1732 | ||
1733 | |||
1734 | /***********************\ | ||
1735 | * Init/Detach functions * | ||
1736 | \***********************/ | ||
1737 | |||
1759 | /* | 1738 | /* |
1760 | * Initialize eeprom data structure | 1739 | * Initialize eeprom data structure |
1761 | */ | 1740 | */ |
@@ -1787,35 +1766,27 @@ ath5k_eeprom_init(struct ath5k_hw *ah) | |||
1787 | return 0; | 1766 | return 0; |
1788 | } | 1767 | } |
1789 | 1768 | ||
1790 | /* | 1769 | void |
1791 | * Read the MAC address from eeprom | 1770 | ath5k_eeprom_detach(struct ath5k_hw *ah) |
1792 | */ | ||
1793 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
1794 | { | 1771 | { |
1795 | u8 mac_d[ETH_ALEN] = {}; | 1772 | u8 mode; |
1796 | u32 total, offset; | ||
1797 | u16 data; | ||
1798 | int octet, ret; | ||
1799 | |||
1800 | ret = ath5k_hw_eeprom_read(ah, 0x20, &data); | ||
1801 | if (ret) | ||
1802 | return ret; | ||
1803 | 1773 | ||
1804 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | 1774 | for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) |
1805 | ret = ath5k_hw_eeprom_read(ah, offset, &data); | 1775 | ath5k_eeprom_free_pcal_info(ah, mode); |
1806 | if (ret) | 1776 | } |
1807 | return ret; | ||
1808 | 1777 | ||
1809 | total += data; | 1778 | int |
1810 | mac_d[octet + 1] = data & 0xff; | 1779 | ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) |
1811 | mac_d[octet] = data >> 8; | 1780 | { |
1812 | octet += 2; | 1781 | switch (channel->hw_value & CHANNEL_MODES) { |
1782 | case CHANNEL_A: | ||
1783 | case CHANNEL_XR: | ||
1784 | return AR5K_EEPROM_MODE_11A; | ||
1785 | case CHANNEL_G: | ||
1786 | return AR5K_EEPROM_MODE_11G; | ||
1787 | case CHANNEL_B: | ||
1788 | return AR5K_EEPROM_MODE_11B; | ||
1789 | default: | ||
1790 | return -1; | ||
1813 | } | 1791 | } |
1814 | |||
1815 | if (!total || total == 3 * 0xffff) | ||
1816 | return -EINVAL; | ||
1817 | |||
1818 | memcpy(mac, mac_d, ETH_ALEN); | ||
1819 | |||
1820 | return 0; | ||
1821 | } | 1792 | } |