aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-08-04 10:38:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-22 16:29:58 -0400
commit8c5e7a5f59f9d11597bd47de28334da318ea0e80 (patch)
tree46dc69607e8a196fd68b3b040b312bc1e7fc0559
parent906c110fcc24bdd5bf0fa22d89ac75d99c747e53 (diff)
rt2x00: Gather channel information in structure
Channel information which is read from EEPROM should be read into an array containing per-channel information. This removes the requirement of multiple arrays and makes the channel handling a bit cleaner and easier to expand. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c40
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h22
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c39
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c42
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h17
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c43
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h17
13 files changed, 176 insertions, 162 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 4c0538d6099b..0107cec18b26 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1404,7 +1404,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
1404 * RF value list for RF2420 & RF2421 1404 * RF value list for RF2420 & RF2421
1405 * Supports: 2.4 GHz 1405 * Supports: 2.4 GHz
1406 */ 1406 */
1407static const struct rf_channel rf_vals_bg[] = { 1407static const struct rf_channel rf_vals_b[] = {
1408 { 1, 0x00022058, 0x000c1fda, 0x00000101, 0 }, 1408 { 1, 0x00022058, 0x000c1fda, 0x00000101, 0 },
1409 { 2, 0x00022058, 0x000c1fee, 0x00000101, 0 }, 1409 { 2, 0x00022058, 0x000c1fee, 0x00000101, 0 },
1410 { 3, 0x00022058, 0x000c2002, 0x00000101, 0 }, 1410 { 3, 0x00022058, 0x000c2002, 0x00000101, 0 },
@@ -1421,10 +1421,11 @@ static const struct rf_channel rf_vals_bg[] = {
1421 { 14, 0x00022058, 0x000c20fa, 0x00000101, 0 }, 1421 { 14, 0x00022058, 0x000c20fa, 0x00000101, 0 },
1422}; 1422};
1423 1423
1424static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 1424static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1425{ 1425{
1426 struct hw_mode_spec *spec = &rt2x00dev->spec; 1426 struct hw_mode_spec *spec = &rt2x00dev->spec;
1427 u8 *txpower; 1427 struct channel_info *info;
1428 char *tx_power;
1428 unsigned int i; 1429 unsigned int i;
1429 1430
1430 /* 1431 /*
@@ -1440,23 +1441,28 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1440 EEPROM_MAC_ADDR_0)); 1441 EEPROM_MAC_ADDR_0));
1441 1442
1442 /* 1443 /*
1443 * Convert tx_power array in eeprom.
1444 */
1445 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1446 for (i = 0; i < 14; i++)
1447 txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
1448
1449 /*
1450 * Initialize hw_mode information. 1444 * Initialize hw_mode information.
1451 */ 1445 */
1452 spec->supported_bands = SUPPORT_BAND_2GHZ; 1446 spec->supported_bands = SUPPORT_BAND_2GHZ;
1453 spec->supported_rates = SUPPORT_RATE_CCK; 1447 spec->supported_rates = SUPPORT_RATE_CCK;
1454 spec->tx_power_a = NULL;
1455 spec->tx_power_bg = txpower;
1456 spec->tx_power_default = DEFAULT_TXPOWER;
1457 1448
1458 spec->num_channels = ARRAY_SIZE(rf_vals_bg); 1449 spec->num_channels = ARRAY_SIZE(rf_vals_b);
1459 spec->channels = rf_vals_bg; 1450 spec->channels = rf_vals_b;
1451
1452 /*
1453 * Create channel information array
1454 */
1455 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
1456 if (!info)
1457 return -ENOMEM;
1458
1459 spec->channels_info = info;
1460
1461 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1462 for (i = 0; i < 14; i++)
1463 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
1464
1465 return 0;
1460} 1466}
1461 1467
1462static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) 1468static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1477,7 +1483,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
1477 /* 1483 /*
1478 * Initialize hw specifications. 1484 * Initialize hw specifications.
1479 */ 1485 */
1480 rt2400pci_probe_hw_mode(rt2x00dev); 1486 retval = rt2400pci_probe_hw_mode(rt2x00dev);
1487 if (retval)
1488 return retval;
1481 1489
1482 /* 1490 /*
1483 * This device requires the atim queue and DMA-mapped skbs. 1491 * This device requires the atim queue and DMA-mapped skbs.
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index bc5564258228..bbff381ce396 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -938,19 +938,13 @@
938#define MAX_TXPOWER 62 938#define MAX_TXPOWER 62
939#define DEFAULT_TXPOWER 39 939#define DEFAULT_TXPOWER 39
940 940
941#define TXPOWER_FROM_DEV(__txpower) \ 941#define __CLAMP_TX(__txpower) \
942({ \ 942 clamp_t(char, (__txpower), MIN_TXPOWER, MAX_TXPOWER)
943 ((__txpower) > MAX_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER : \ 943
944 ((__txpower) < MIN_TXPOWER) ? DEFAULT_TXPOWER - MIN_TXPOWER : \ 944#define TXPOWER_FROM_DEV(__txpower) \
945 (((__txpower) - MAX_TXPOWER) + MIN_TXPOWER); \ 945 ((__CLAMP_TX(__txpower) - MAX_TXPOWER) + MIN_TXPOWER)
946}) 946
947 947#define TXPOWER_TO_DEV(__txpower) \
948#define TXPOWER_TO_DEV(__txpower) \ 948 MAX_TXPOWER - (__CLAMP_TX(__txpower) - MIN_TXPOWER)
949({ \
950 (__txpower) += MIN_TXPOWER; \
951 ((__txpower) <= MIN_TXPOWER) ? MAX_TXPOWER : \
952 (((__txpower) >= MAX_TXPOWER) ? MIN_TXPOWER : \
953 (MAX_TXPOWER - ((__txpower) - MIN_TXPOWER))); \
954})
955 949
956#endif /* RT2400PCI_H */ 950#endif /* RT2400PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 181a146b4768..e0ff76ff490d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1721,10 +1721,11 @@ static const struct rf_channel rf_vals_5222[] = {
1721 { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 }, 1721 { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
1722}; 1722};
1723 1723
1724static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 1724static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1725{ 1725{
1726 struct hw_mode_spec *spec = &rt2x00dev->spec; 1726 struct hw_mode_spec *spec = &rt2x00dev->spec;
1727 u8 *txpower; 1727 struct channel_info *info;
1728 char *tx_power;
1728 unsigned int i; 1729 unsigned int i;
1729 1730
1730 /* 1731 /*
@@ -1741,20 +1742,10 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1741 EEPROM_MAC_ADDR_0)); 1742 EEPROM_MAC_ADDR_0));
1742 1743
1743 /* 1744 /*
1744 * Convert tx_power array in eeprom.
1745 */
1746 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1747 for (i = 0; i < 14; i++)
1748 txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
1749
1750 /*
1751 * Initialize hw_mode information. 1745 * Initialize hw_mode information.
1752 */ 1746 */
1753 spec->supported_bands = SUPPORT_BAND_2GHZ; 1747 spec->supported_bands = SUPPORT_BAND_2GHZ;
1754 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 1748 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
1755 spec->tx_power_a = NULL;
1756 spec->tx_power_bg = txpower;
1757 spec->tx_power_default = DEFAULT_TXPOWER;
1758 1749
1759 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { 1750 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
1760 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); 1751 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
@@ -1776,6 +1767,26 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1776 spec->num_channels = ARRAY_SIZE(rf_vals_5222); 1767 spec->num_channels = ARRAY_SIZE(rf_vals_5222);
1777 spec->channels = rf_vals_5222; 1768 spec->channels = rf_vals_5222;
1778 } 1769 }
1770
1771 /*
1772 * Create channel information array
1773 */
1774 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
1775 if (!info)
1776 return -ENOMEM;
1777
1778 spec->channels_info = info;
1779
1780 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1781 for (i = 0; i < 14; i++)
1782 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
1783
1784 if (spec->num_channels > 14) {
1785 for (i = 14; i < spec->num_channels; i++)
1786 info[i].tx_power1 = DEFAULT_TXPOWER;
1787 }
1788
1789 return 0;
1779} 1790}
1780 1791
1781static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) 1792static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1796,7 +1807,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
1796 /* 1807 /*
1797 * Initialize hw specifications. 1808 * Initialize hw specifications.
1798 */ 1809 */
1799 rt2500pci_probe_hw_mode(rt2x00dev); 1810 retval = rt2500pci_probe_hw_mode(rt2x00dev);
1811 if (retval)
1812 return retval;
1800 1813
1801 /* 1814 /*
1802 * This device requires the atim queue and DMA-mapped skbs. 1815 * This device requires the atim queue and DMA-mapped skbs.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 42f376929ea9..8c26bef6cf49 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1223,17 +1223,10 @@
1223#define MAX_TXPOWER 31 1223#define MAX_TXPOWER 31
1224#define DEFAULT_TXPOWER 24 1224#define DEFAULT_TXPOWER 24
1225 1225
1226#define TXPOWER_FROM_DEV(__txpower) \ 1226#define TXPOWER_FROM_DEV(__txpower) \
1227({ \ 1227 (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
1228 ((__txpower) > MAX_TXPOWER) ? \ 1228
1229 DEFAULT_TXPOWER : (__txpower); \ 1229#define TXPOWER_TO_DEV(__txpower) \
1230}) 1230 clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
1231
1232#define TXPOWER_TO_DEV(__txpower) \
1233({ \
1234 ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \
1235 (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \
1236 (__txpower)); \
1237})
1238 1231
1239#endif /* RT2500PCI_H */ 1232#endif /* RT2500PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index cd5af656932d..3b90ed622148 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1665,10 +1665,11 @@ static const struct rf_channel rf_vals_5222[] = {
1665 { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 }, 1665 { 161, 0x00022020, 0x000090be, 0x00000101, 0x00000a07 },
1666}; 1666};
1667 1667
1668static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 1668static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1669{ 1669{
1670 struct hw_mode_spec *spec = &rt2x00dev->spec; 1670 struct hw_mode_spec *spec = &rt2x00dev->spec;
1671 u8 *txpower; 1671 struct channel_info *info;
1672 char *tx_power;
1672 unsigned int i; 1673 unsigned int i;
1673 1674
1674 /* 1675 /*
@@ -1687,20 +1688,10 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1687 EEPROM_MAC_ADDR_0)); 1688 EEPROM_MAC_ADDR_0));
1688 1689
1689 /* 1690 /*
1690 * Convert tx_power array in eeprom.
1691 */
1692 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1693 for (i = 0; i < 14; i++)
1694 txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
1695
1696 /*
1697 * Initialize hw_mode information. 1691 * Initialize hw_mode information.
1698 */ 1692 */
1699 spec->supported_bands = SUPPORT_BAND_2GHZ; 1693 spec->supported_bands = SUPPORT_BAND_2GHZ;
1700 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 1694 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
1701 spec->tx_power_a = NULL;
1702 spec->tx_power_bg = txpower;
1703 spec->tx_power_default = DEFAULT_TXPOWER;
1704 1695
1705 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) { 1696 if (rt2x00_rf(&rt2x00dev->chip, RF2522)) {
1706 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522); 1697 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2522);
@@ -1722,6 +1713,26 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
1722 spec->num_channels = ARRAY_SIZE(rf_vals_5222); 1713 spec->num_channels = ARRAY_SIZE(rf_vals_5222);
1723 spec->channels = rf_vals_5222; 1714 spec->channels = rf_vals_5222;
1724 } 1715 }
1716
1717 /*
1718 * Create channel information array
1719 */
1720 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
1721 if (!info)
1722 return -ENOMEM;
1723
1724 spec->channels_info = info;
1725
1726 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START);
1727 for (i = 0; i < 14; i++)
1728 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
1729
1730 if (spec->num_channels > 14) {
1731 for (i = 14; i < spec->num_channels; i++)
1732 info[i].tx_power1 = DEFAULT_TXPOWER;
1733 }
1734
1735 return 0;
1725} 1736}
1726 1737
1727static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) 1738static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -1742,7 +1753,9 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
1742 /* 1753 /*
1743 * Initialize hw specifications. 1754 * Initialize hw specifications.
1744 */ 1755 */
1745 rt2500usb_probe_hw_mode(rt2x00dev); 1756 retval = rt2500usb_probe_hw_mode(rt2x00dev);
1757 if (retval)
1758 return retval;
1746 1759
1747 /* 1760 /*
1748 * This device requires the atim queue 1761 * This device requires the atim queue
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 4769ffeb4cc6..89e5ed24e4f7 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -825,17 +825,10 @@
825#define MAX_TXPOWER 31 825#define MAX_TXPOWER 31
826#define DEFAULT_TXPOWER 24 826#define DEFAULT_TXPOWER 24
827 827
828#define TXPOWER_FROM_DEV(__txpower) \ 828#define TXPOWER_FROM_DEV(__txpower) \
829({ \ 829 (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
830 ((__txpower) > MAX_TXPOWER) ? \ 830
831 DEFAULT_TXPOWER : (__txpower); \ 831#define TXPOWER_TO_DEV(__txpower) \
832}) 832 clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
833
834#define TXPOWER_TO_DEV(__txpower) \
835({ \
836 ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \
837 (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \
838 (__txpower)); \
839})
840 833
841#endif /* RT2500USB_H */ 834#endif /* RT2500USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 0ffd972bb856..323bd54eb801 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -144,6 +144,17 @@ struct rf_channel {
144}; 144};
145 145
146/* 146/*
147 * Channel information structure
148 */
149struct channel_info {
150 unsigned int flags;
151#define GEOGRAPHY_ALLOWED 0x00000001
152
153 short tx_power1;
154 short tx_power2;
155};
156
157/*
147 * Antenna setup values. 158 * Antenna setup values.
148 */ 159 */
149struct antenna_setup { 160struct antenna_setup {
@@ -394,10 +405,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
394 * @num_channels: Number of supported channels. This is used as array size 405 * @num_channels: Number of supported channels. This is used as array size
395 * for @tx_power_a, @tx_power_bg and @channels. 406 * for @tx_power_a, @tx_power_bg and @channels.
396 * @channels: Device/chipset specific channel values (See &struct rf_channel). 407 * @channels: Device/chipset specific channel values (See &struct rf_channel).
397 * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL). 408 * @channels_info: Additional information for channels (See &struct channel_info).
398 * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL).
399 * @tx_power_default: Default TX power value to use when either
400 * @tx_power_a or @tx_power_bg is missing.
401 */ 409 */
402struct hw_mode_spec { 410struct hw_mode_spec {
403 unsigned int supported_bands; 411 unsigned int supported_bands;
@@ -410,10 +418,7 @@ struct hw_mode_spec {
410 418
411 unsigned int num_channels; 419 unsigned int num_channels;
412 const struct rf_channel *channels; 420 const struct rf_channel *channels;
413 421 const struct channel_info *channels_info;
414 const u8 *tx_power_a;
415 const u8 *tx_power_bg;
416 u8 tx_power_default;
417}; 422};
418 423
419/* 424/*
@@ -425,7 +430,9 @@ struct hw_mode_spec {
425 */ 430 */
426struct rt2x00lib_conf { 431struct rt2x00lib_conf {
427 struct ieee80211_conf *conf; 432 struct ieee80211_conf *conf;
433
428 struct rf_channel rf; 434 struct rf_channel rf;
435 struct channel_info channel;
429 436
430 struct antenna_setup ant; 437 struct antenna_setup ant;
431 438
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index d134c3be539a..ea37c7962043 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -245,6 +245,10 @@ config:
245 memcpy(&libconf.rf, 245 memcpy(&libconf.rf,
246 &rt2x00dev->spec.channels[conf->channel->hw_value], 246 &rt2x00dev->spec.channels[conf->channel->hw_value],
247 sizeof(libconf.rf)); 247 sizeof(libconf.rf));
248
249 memcpy(&libconf.channel,
250 &rt2x00dev->spec.channels_info[conf->channel->hw_value],
251 sizeof(libconf.channel));
248 } 252 }
249 253
250 if (flags & CONFIG_UPDATE_ANTENNA) { 254 if (flags & CONFIG_UPDATE_ANTENNA) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 182952249a19..328ff8bc4c16 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -818,7 +818,6 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
818 struct ieee80211_rate *rates; 818 struct ieee80211_rate *rates;
819 unsigned int num_rates; 819 unsigned int num_rates;
820 unsigned int i; 820 unsigned int i;
821 unsigned char tx_power;
822 821
823 num_rates = 0; 822 num_rates = 0;
824 if (spec->supported_rates & SUPPORT_RATE_CCK) 823 if (spec->supported_rates & SUPPORT_RATE_CCK)
@@ -844,20 +843,9 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
844 * Initialize Channel list. 843 * Initialize Channel list.
845 */ 844 */
846 for (i = 0; i < spec->num_channels; i++) { 845 for (i = 0; i < spec->num_channels; i++) {
847 if (spec->channels[i].channel <= 14) {
848 if (spec->tx_power_bg)
849 tx_power = spec->tx_power_bg[i];
850 else
851 tx_power = spec->tx_power_default;
852 } else {
853 if (spec->tx_power_a)
854 tx_power = spec->tx_power_a[i];
855 else
856 tx_power = spec->tx_power_default;
857 }
858
859 rt2x00lib_channel(&channels[i], 846 rt2x00lib_channel(&channels[i],
860 spec->channels[i].channel, tx_power, i); 847 spec->channels[i].channel,
848 spec->channels_info[i].tx_power1, i);
861 } 849 }
862 850
863 /* 851 /*
@@ -909,6 +897,8 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
909 rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; 897 rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
910 rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; 898 rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
911 } 899 }
900
901 kfree(rt2x00dev->spec.channels_info);
912} 902}
913 903
914static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) 904static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 86e7a50374b9..87012f88461f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2514,10 +2514,11 @@ static const struct rf_channel rf_vals_seq[] = {
2514 { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 }, 2514 { 46, 0x00002ccc, 0x000049a6, 0x0009be55, 0x000c0a23 },
2515}; 2515};
2516 2516
2517static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 2517static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2518{ 2518{
2519 struct hw_mode_spec *spec = &rt2x00dev->spec; 2519 struct hw_mode_spec *spec = &rt2x00dev->spec;
2520 u8 *txpower; 2520 struct channel_info *info;
2521 char *tx_power;
2521 unsigned int i; 2522 unsigned int i;
2522 2523
2523 /* 2524 /*
@@ -2534,20 +2535,10 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2534 EEPROM_MAC_ADDR_0)); 2535 EEPROM_MAC_ADDR_0));
2535 2536
2536 /* 2537 /*
2537 * Convert tx_power array in eeprom.
2538 */
2539 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
2540 for (i = 0; i < 14; i++)
2541 txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
2542
2543 /*
2544 * Initialize hw_mode information. 2538 * Initialize hw_mode information.
2545 */ 2539 */
2546 spec->supported_bands = SUPPORT_BAND_2GHZ; 2540 spec->supported_bands = SUPPORT_BAND_2GHZ;
2547 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 2541 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
2548 spec->tx_power_a = NULL;
2549 spec->tx_power_bg = txpower;
2550 spec->tx_power_default = DEFAULT_TXPOWER;
2551 2542
2552 if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) { 2543 if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) {
2553 spec->num_channels = 14; 2544 spec->num_channels = 14;
@@ -2561,13 +2552,28 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2561 rt2x00_rf(&rt2x00dev->chip, RF5325)) { 2552 rt2x00_rf(&rt2x00dev->chip, RF5325)) {
2562 spec->supported_bands |= SUPPORT_BAND_5GHZ; 2553 spec->supported_bands |= SUPPORT_BAND_5GHZ;
2563 spec->num_channels = ARRAY_SIZE(rf_vals_seq); 2554 spec->num_channels = ARRAY_SIZE(rf_vals_seq);
2555 }
2556
2557 /*
2558 * Create channel information array
2559 */
2560 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
2561 if (!info)
2562 return -ENOMEM;
2563
2564 spec->channels_info = info;
2564 2565
2565 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2566 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
2566 for (i = 0; i < 14; i++) 2567 for (i = 0; i < 14; i++)
2567 txpower[i] = TXPOWER_FROM_DEV(txpower[i]); 2568 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
2568 2569
2569 spec->tx_power_a = txpower; 2570 if (spec->num_channels > 14) {
2571 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2572 for (i = 14; i < spec->num_channels; i++)
2573 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
2570 } 2574 }
2575
2576 return 0;
2571} 2577}
2572 2578
2573static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) 2579static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -2588,7 +2594,9 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
2588 /* 2594 /*
2589 * Initialize hw specifications. 2595 * Initialize hw specifications.
2590 */ 2596 */
2591 rt61pci_probe_hw_mode(rt2x00dev); 2597 retval = rt61pci_probe_hw_mode(rt2x00dev);
2598 if (retval)
2599 return retval;
2592 2600
2593 /* 2601 /*
2594 * This device requires firmware and DMA mapped skbs. 2602 * This device requires firmware and DMA mapped skbs.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6d591cef3e5d..8ec1451308cc 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1482,17 +1482,10 @@ struct hw_pairwise_ta_entry {
1482#define MAX_TXPOWER 31 1482#define MAX_TXPOWER 31
1483#define DEFAULT_TXPOWER 24 1483#define DEFAULT_TXPOWER 24
1484 1484
1485#define TXPOWER_FROM_DEV(__txpower) \ 1485#define TXPOWER_FROM_DEV(__txpower) \
1486({ \ 1486 (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
1487 ((__txpower) > MAX_TXPOWER) ? \ 1487
1488 DEFAULT_TXPOWER : (__txpower); \ 1488#define TXPOWER_TO_DEV(__txpower) \
1489}) 1489 clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
1490
1491#define TXPOWER_TO_DEV(__txpower) \
1492({ \
1493 ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \
1494 (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \
1495 (__txpower)); \
1496})
1497 1490
1498#endif /* RT61PCI_H */ 1491#endif /* RT61PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ddba747fed98..1bd6b3ffca09 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2107,10 +2107,11 @@ static const struct rf_channel rf_vals_5225_2527[] = {
2107}; 2107};
2108 2108
2109 2109
2110static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) 2110static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2111{ 2111{
2112 struct hw_mode_spec *spec = &rt2x00dev->spec; 2112 struct hw_mode_spec *spec = &rt2x00dev->spec;
2113 u8 *txpower; 2113 struct channel_info *info;
2114 char *tx_power;
2114 unsigned int i; 2115 unsigned int i;
2115 2116
2116 /* 2117 /*
@@ -2127,20 +2128,10 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2127 EEPROM_MAC_ADDR_0)); 2128 EEPROM_MAC_ADDR_0));
2128 2129
2129 /* 2130 /*
2130 * Convert tx_power array in eeprom.
2131 */
2132 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
2133 for (i = 0; i < 14; i++)
2134 txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
2135
2136 /*
2137 * Initialize hw_mode information. 2131 * Initialize hw_mode information.
2138 */ 2132 */
2139 spec->supported_bands = SUPPORT_BAND_2GHZ; 2133 spec->supported_bands = SUPPORT_BAND_2GHZ;
2140 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; 2134 spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
2141 spec->tx_power_a = NULL;
2142 spec->tx_power_bg = txpower;
2143 spec->tx_power_default = DEFAULT_TXPOWER;
2144 2135
2145 if (rt2x00_rf(&rt2x00dev->chip, RF2528)) { 2136 if (rt2x00_rf(&rt2x00dev->chip, RF2528)) {
2146 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); 2137 spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
@@ -2158,14 +2149,26 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2158 spec->channels = rf_vals_5225_2527; 2149 spec->channels = rf_vals_5225_2527;
2159 } 2150 }
2160 2151
2161 if (rt2x00_rf(&rt2x00dev->chip, RF5225) || 2152 /*
2162 rt2x00_rf(&rt2x00dev->chip, RF5226)) { 2153 * Create channel information array
2163 txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2154 */
2164 for (i = 0; i < 14; i++) 2155 info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
2165 txpower[i] = TXPOWER_FROM_DEV(txpower[i]); 2156 if (!info)
2157 return -ENOMEM;
2166 2158
2167 spec->tx_power_a = txpower; 2159 spec->channels_info = info;
2160
2161 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START);
2162 for (i = 0; i < 14; i++)
2163 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
2164
2165 if (spec->num_channels > 14) {
2166 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2167 for (i = 14; i < spec->num_channels; i++)
2168 info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]);
2168 } 2169 }
2170
2171 return 0;
2169} 2172}
2170 2173
2171static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) 2174static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
@@ -2186,7 +2189,9 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
2186 /* 2189 /*
2187 * Initialize hw specifications. 2190 * Initialize hw specifications.
2188 */ 2191 */
2189 rt73usb_probe_hw_mode(rt2x00dev); 2192 retval = rt73usb_probe_hw_mode(rt2x00dev);
2193 if (retval)
2194 return retval;
2190 2195
2191 /* 2196 /*
2192 * This device requires firmware. 2197 * This device requires firmware.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 91e04d319d76..868386c457f6 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -1050,17 +1050,10 @@ struct hw_pairwise_ta_entry {
1050#define MAX_TXPOWER 31 1050#define MAX_TXPOWER 31
1051#define DEFAULT_TXPOWER 24 1051#define DEFAULT_TXPOWER 24
1052 1052
1053#define TXPOWER_FROM_DEV(__txpower) \ 1053#define TXPOWER_FROM_DEV(__txpower) \
1054({ \ 1054 (((u8)(__txpower)) > MAX_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
1055 ((__txpower) > MAX_TXPOWER) ? \ 1055
1056 DEFAULT_TXPOWER : (__txpower); \ 1056#define TXPOWER_TO_DEV(__txpower) \
1057}) 1057 clamp_t(char, __txpower, MIN_TXPOWER, MAX_TXPOWER)
1058
1059#define TXPOWER_TO_DEV(__txpower) \
1060({ \
1061 ((__txpower) <= MIN_TXPOWER) ? MIN_TXPOWER : \
1062 (((__txpower) >= MAX_TXPOWER) ? MAX_TXPOWER : \
1063 (__txpower)); \
1064})
1065 1058
1066#endif /* RT73USB_H */ 1059#endif /* RT73USB_H */