Commit 31562e80 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Cleanup mode registration

Don't wildly pass any number for num_rates to rt2x00lib,
instead pass which type of rates are supported (CCK, OFDM).
Same for num_modes but then for the 2GHZ and 5GHZ band.

This makes the interface look much nicer and makes
extending it later easier.
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent de99ff82
...@@ -1352,8 +1352,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1352,8 +1352,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/* /*
* Initialize hw_mode information. * Initialize hw_mode information.
*/ */
spec->num_modes = 1; spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->num_rates = 4; spec->supported_rates = SUPPORT_RATE_CCK;
spec->tx_power_a = NULL; spec->tx_power_a = NULL;
spec->tx_power_bg = txpower; spec->tx_power_bg = txpower;
spec->tx_power_default = DEFAULT_TXPOWER; spec->tx_power_default = DEFAULT_TXPOWER;
......
...@@ -1666,8 +1666,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1666,8 +1666,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/* /*
* Initialize hw_mode information. * Initialize hw_mode information.
*/ */
spec->num_modes = 2; spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->num_rates = 12; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
spec->tx_power_a = NULL; spec->tx_power_a = NULL;
spec->tx_power_bg = txpower; spec->tx_power_bg = txpower;
spec->tx_power_default = DEFAULT_TXPOWER; spec->tx_power_default = DEFAULT_TXPOWER;
...@@ -1688,9 +1688,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1688,9 +1688,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
spec->channels = rf_vals_bg_2525e; spec->channels = rf_vals_bg_2525e;
} else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5222); spec->num_channels = ARRAY_SIZE(rf_vals_5222);
spec->channels = rf_vals_5222; spec->channels = rf_vals_5222;
spec->num_modes = 3;
} }
} }
......
...@@ -1586,8 +1586,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1586,8 +1586,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/* /*
* Initialize hw_mode information. * Initialize hw_mode information.
*/ */
spec->num_modes = 2; spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->num_rates = 12; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
spec->tx_power_a = NULL; spec->tx_power_a = NULL;
spec->tx_power_bg = txpower; spec->tx_power_bg = txpower;
spec->tx_power_default = DEFAULT_TXPOWER; spec->tx_power_default = DEFAULT_TXPOWER;
...@@ -1608,9 +1608,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1608,9 +1608,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e);
spec->channels = rf_vals_bg_2525e; spec->channels = rf_vals_bg_2525e;
} else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5222); spec->num_channels = ARRAY_SIZE(rf_vals_5222);
spec->channels = rf_vals_5222; spec->channels = rf_vals_5222;
spec->num_modes = 3;
} }
} }
......
...@@ -392,30 +392,38 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) ...@@ -392,30 +392,38 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
return (struct rt2x00_intf *)vif->drv_priv; return (struct rt2x00_intf *)vif->drv_priv;
} }
/* /**
* struct hw_mode_spec: Hardware specifications structure
*
* Details about the supported modes, rates and channels * Details about the supported modes, rates and channels
* of a particular chipset. This is used by rt2x00lib * of a particular chipset. This is used by rt2x00lib
* to build the ieee80211_hw_mode array for mac80211. * to build the ieee80211_hw_mode array for mac80211.
*
* @supported_bands: Bitmask contained the supported bands (2.4GHz, 5.2GHz).
* @supported_rates: Rate types which are supported (CCK, OFDM).
* @num_channels: Number of supported channels. This is used as array size
* for @tx_power_a, @tx_power_bg and @channels.
* channels: Device/chipset specific channel values (See &struct rf_channel).
* @tx_power_a: TX power values for all 5.2GHz channels (may be NULL).
* @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL).
* @tx_power_default: Default TX power value to use when either
* @tx_power_a or @tx_power_bg is missing.
*/ */
struct hw_mode_spec { struct hw_mode_spec {
/* unsigned int supported_bands;
* Number of modes, rates and channels. #define SUPPORT_BAND_2GHZ 0x00000001
*/ #define SUPPORT_BAND_5GHZ 0x00000002
int num_modes;
int num_rates; unsigned int supported_rates;
int num_channels; #define SUPPORT_RATE_CCK 0x00000001
#define SUPPORT_RATE_OFDM 0x00000002
unsigned int num_channels;
const struct rf_channel *channels;
/*
* txpower values.
*/
const u8 *tx_power_a; const u8 *tx_power_a;
const u8 *tx_power_bg; const u8 *tx_power_bg;
u8 tx_power_default; u8 tx_power_default;
/*
* Device/chipset specific value.
*/
const struct rf_channel *channels;
}; };
/* /*
......
...@@ -767,25 +767,25 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); ...@@ -767,25 +767,25 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
*/ */
const struct rt2x00_rate rt2x00_supported_rates[12] = { const struct rt2x00_rate rt2x00_supported_rates[12] = {
{ {
.flags = 0, .flags = DEV_RATE_CCK,
.bitrate = 10, .bitrate = 10,
.ratemask = DEV_RATEMASK_1MB, .ratemask = DEV_RATEMASK_1MB,
.plcp = 0x00, .plcp = 0x00,
}, },
{ {
.flags = DEV_RATE_SHORT_PREAMBLE, .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 20, .bitrate = 20,
.ratemask = DEV_RATEMASK_2MB, .ratemask = DEV_RATEMASK_2MB,
.plcp = 0x01, .plcp = 0x01,
}, },
{ {
.flags = DEV_RATE_SHORT_PREAMBLE, .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 55, .bitrate = 55,
.ratemask = DEV_RATEMASK_5_5MB, .ratemask = DEV_RATEMASK_5_5MB,
.plcp = 0x02, .plcp = 0x02,
}, },
{ {
.flags = DEV_RATE_SHORT_PREAMBLE, .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
.bitrate = 110, .bitrate = 110,
.ratemask = DEV_RATEMASK_11MB, .ratemask = DEV_RATEMASK_11MB,
.plcp = 0x03, .plcp = 0x03,
...@@ -868,67 +868,64 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, ...@@ -868,67 +868,64 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
struct hw_mode_spec *spec) struct hw_mode_spec *spec)
{ {
struct ieee80211_hw *hw = rt2x00dev->hw; struct ieee80211_hw *hw = rt2x00dev->hw;
struct ieee80211_supported_band *sbands;
struct ieee80211_channel *channels; struct ieee80211_channel *channels;
struct ieee80211_rate *rates; struct ieee80211_rate *rates;
unsigned int num_rates;
unsigned int i; unsigned int i;
unsigned char tx_power; unsigned char tx_power;
sbands = &rt2x00dev->bands[0]; num_rates = 0;
if (spec->supported_rates & SUPPORT_RATE_CCK)
num_rates += 4;
if (spec->supported_rates & SUPPORT_RATE_OFDM)
num_rates += 8;
channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL);
if (!channels) if (!channels)
return -ENOMEM; return -ENOMEM;
rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL);
if (!rates) if (!rates)
goto exit_free_channels; goto exit_free_channels;
/* /*
* Initialize Rate list. * Initialize Rate list.
*/ */
for (i = 0; i < spec->num_rates; i++) for (i = 0; i < num_rates; i++)
rt2x00lib_rate(&rates[i], i, rt2x00_get_rate(i)); rt2x00lib_rate(&rates[i], i, rt2x00_get_rate(i));
/* /*
* Initialize Channel list. * Initialize Channel list.
*/ */
for (i = 0; i < spec->num_channels; i++) { for (i = 0; i < spec->num_channels; i++) {
if (spec->channels[i].channel <= 14) if (spec->channels[i].channel <= 14) {
tx_power = spec->tx_power_bg[i]; if (spec->tx_power_bg)
else if (spec->tx_power_a) tx_power = spec->tx_power_bg[i];
tx_power = spec->tx_power_a[i]; else
else tx_power = spec->tx_power_default;
tx_power = spec->tx_power_default; } else {
if (spec->tx_power_a)
tx_power = spec->tx_power_a[i];
else
tx_power = spec->tx_power_default;
}
rt2x00lib_channel(&channels[i], rt2x00lib_channel(&channels[i],
spec->channels[i].channel, tx_power, i); spec->channels[i].channel, tx_power, i);
} }
/* /*
* Intitialize 802.11b * Intitialize 802.11b, 802.11g
* Rates: CCK.
* Channels: 2.4 GHz
*/
if (spec->num_modes > 0) {
sbands[IEEE80211_BAND_2GHZ].n_channels = 14;
sbands[IEEE80211_BAND_2GHZ].n_bitrates = 4;
sbands[IEEE80211_BAND_2GHZ].channels = channels;
sbands[IEEE80211_BAND_2GHZ].bitrates = rates;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
}
/*
* Intitialize 802.11g
* Rates: CCK, OFDM. * Rates: CCK, OFDM.
* Channels: 2.4 GHz * Channels: 2.4 GHz
*/ */
if (spec->num_modes > 1) { if (spec->supported_bands > SUPPORT_BAND_2GHZ) {
sbands[IEEE80211_BAND_2GHZ].n_channels = 14; rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_channels = 14;
sbands[IEEE80211_BAND_2GHZ].n_bitrates = spec->num_rates; rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_bitrates = num_rates;
sbands[IEEE80211_BAND_2GHZ].channels = channels; rt2x00dev->bands[IEEE80211_BAND_2GHZ].channels = channels;
sbands[IEEE80211_BAND_2GHZ].bitrates = rates; rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_2GHZ];
} }
/* /*
...@@ -936,12 +933,15 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, ...@@ -936,12 +933,15 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
* Rates: OFDM. * Rates: OFDM.
* Channels: OFDM, UNII, HiperLAN2. * Channels: OFDM, UNII, HiperLAN2.
*/ */
if (spec->num_modes > 2) { if (spec->supported_bands > SUPPORT_BAND_5GHZ) {
sbands[IEEE80211_BAND_5GHZ].n_channels = spec->num_channels - 14; rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_channels =
sbands[IEEE80211_BAND_5GHZ].n_bitrates = spec->num_rates - 4; spec->num_channels - 14;
sbands[IEEE80211_BAND_5GHZ].channels = &channels[14]; rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_bitrates =
sbands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; num_rates - 4;
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; rt2x00dev->bands[IEEE80211_BAND_5GHZ].channels = &channels[14];
rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&rt2x00dev->bands[IEEE80211_BAND_5GHZ];
} }
return 0; return 0;
......
...@@ -38,8 +38,9 @@ ...@@ -38,8 +38,9 @@
*/ */
struct rt2x00_rate { struct rt2x00_rate {
unsigned short flags; unsigned short flags;
#define DEV_RATE_OFDM 0x0001 #define DEV_RATE_CCK 0x0001
#define DEV_RATE_SHORT_PREAMBLE 0x0002 #define DEV_RATE_OFDM 0x0002
#define DEV_RATE_SHORT_PREAMBLE 0x0004
unsigned short bitrate; /* In 100kbit/s */ unsigned short bitrate; /* In 100kbit/s */
......
...@@ -2209,8 +2209,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -2209,8 +2209,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/* /*
* Initialize hw_mode information. * Initialize hw_mode information.
*/ */
spec->num_modes = 2; spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->num_rates = 12; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
spec->tx_power_a = NULL; spec->tx_power_a = NULL;
spec->tx_power_bg = txpower; spec->tx_power_bg = txpower;
spec->tx_power_default = DEFAULT_TXPOWER; spec->tx_power_default = DEFAULT_TXPOWER;
...@@ -2225,7 +2225,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -2225,7 +2225,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
if (rt2x00_rf(&rt2x00dev->chip, RF5225) || if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF5325)) { rt2x00_rf(&rt2x00dev->chip, RF5325)) {
spec->num_modes = 3; spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_seq); spec->num_channels = ARRAY_SIZE(rf_vals_seq);
txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
......
...@@ -1791,8 +1791,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1791,8 +1791,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/* /*
* Initialize hw_mode information. * Initialize hw_mode information.
*/ */
spec->num_modes = 2; spec->supported_bands = SUPPORT_BAND_2GHZ;
spec->num_rates = 12; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
spec->tx_power_a = NULL; spec->tx_power_a = NULL;
spec->tx_power_bg = txpower; spec->tx_power_bg = txpower;
spec->tx_power_default = DEFAULT_TXPOWER; spec->tx_power_default = DEFAULT_TXPOWER;
...@@ -1801,20 +1801,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) ...@@ -1801,20 +1801,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528);
spec->channels = rf_vals_bg_2528; spec->channels = rf_vals_bg_2528;
} else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5226); spec->num_channels = ARRAY_SIZE(rf_vals_5226);
spec->channels = rf_vals_5226; spec->channels = rf_vals_5226;
} else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) {
spec->num_channels = 14; spec->num_channels = 14;
spec->channels = rf_vals_5225_2527; spec->channels = rf_vals_5225_2527;
} else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) {
spec->supported_bands |= SUPPORT_BAND_5GHZ;
spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527);
spec->channels = rf_vals_5225_2527; spec->channels = rf_vals_5225_2527;
} }
if (rt2x00_rf(&rt2x00dev->chip, RF5225) || if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
rt2x00_rf(&rt2x00dev->chip, RF5226)) { rt2x00_rf(&rt2x00dev->chip, RF5226)) {
spec->num_modes = 3;
txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
for (i = 0; i < 14; i++) for (i = 0; i < 14; i++)
txpower[i] = TXPOWER_FROM_DEV(txpower[i]); txpower[i] = TXPOWER_FROM_DEV(txpower[i]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment