提交 8318d78a 编写于 作者: J Johannes Berg 提交者: John W. Linville

cfg80211 API for channels/bitrates, mac80211 and driver conversion

This patch creates new cfg80211 wiphy API for channel and bitrate
registration and converts mac80211 and drivers to the new API. The
old mac80211 API is completely ripped out. All drivers (except ath5k)
are updated to the new API, in many cases I expect that optimisations
can be done.

Along with the regulatory code I've also ripped out the
IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag, I believe it to be
unnecessary if the hardware simply gives us whatever channels it wants
to support and we then enable/disable them as required, which is pretty
much required for travelling.

Additionally, the patch adds proper "basic" rate handling for STA
mode interface, AP mode interface will have to have new API added
to allow userspace to set the basic rate set, currently it'll be
empty... However, the basic rate handling will need to be moved to
the BSS conf stuff.

I do expect there to be bugs in this, especially wrt. transmit
power handling where I'm basically clueless about how it should work.
Signed-off-by: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 10b6b801
...@@ -735,6 +735,7 @@ config P54_PCI ...@@ -735,6 +735,7 @@ config P54_PCI
config ATH5K config ATH5K
tristate "Atheros 5xxx wireless cards support" tristate "Atheros 5xxx wireless cards support"
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
depends on BROKEN
---help--- ---help---
This module adds support for wireless adapters based on This module adds support for wireless adapters based on
Atheros 5xxx chipset. Atheros 5xxx chipset.
......
...@@ -48,6 +48,32 @@ static struct pci_device_id adm8211_pci_id_table[] __devinitdata = { ...@@ -48,6 +48,32 @@ static struct pci_device_id adm8211_pci_id_table[] __devinitdata = {
{ 0 } { 0 }
}; };
static struct ieee80211_rate adm8211_rates[] = {
{ .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 220, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, /* XX ?? */
};
static const struct ieee80211_channel adm8211_channels[] = {
{ .center_freq = 2412},
{ .center_freq = 2417},
{ .center_freq = 2422},
{ .center_freq = 2427},
{ .center_freq = 2432},
{ .center_freq = 2437},
{ .center_freq = 2442},
{ .center_freq = 2447},
{ .center_freq = 2452},
{ .center_freq = 2457},
{ .center_freq = 2462},
{ .center_freq = 2467},
{ .center_freq = 2472},
{ .center_freq = 2484},
};
static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom) static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom)
{ {
struct adm8211_priv *priv = eeprom->data; struct adm8211_priv *priv = eeprom->data;
...@@ -155,17 +181,17 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev) ...@@ -155,17 +181,17 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n",
pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max);
priv->modes[0].num_channels = chan_range.max - chan_range.min + 1; BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels));
priv->modes[0].channels = priv->channels;
memcpy(priv->channels, adm8211_channels, sizeof(adm8211_channels)); memcpy(priv->channels, adm8211_channels, sizeof(priv->channels));
priv->band.channels = priv->channels;
priv->band.n_channels = ARRAY_SIZE(adm8211_channels);
priv->band.bitrates = adm8211_rates;
priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates);
for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++)
if (i >= chan_range.min && i <= chan_range.max) if (i < chan_range.min || i > chan_range.max)
priv->channels[i - 1].flag = priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED;
IEEE80211_CHAN_W_SCAN |
IEEE80211_CHAN_W_ACTIVE_SCAN |
IEEE80211_CHAN_W_IBSS;
switch (priv->eeprom->specific_bbptype) { switch (priv->eeprom->specific_bbptype) {
case ADM8211_BBP_RFMD3000: case ADM8211_BBP_RFMD3000:
...@@ -347,7 +373,6 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) ...@@ -347,7 +373,6 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
unsigned int pktlen; unsigned int pktlen;
struct sk_buff *skb, *newskb; struct sk_buff *skb, *newskb;
unsigned int limit = priv->rx_ring_size; unsigned int limit = priv->rx_ring_size;
static const u8 rate_tbl[] = {10, 20, 55, 110, 220};
u8 rssi, rate; u8 rssi, rate;
while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) { while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) {
...@@ -425,12 +450,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) ...@@ -425,12 +450,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
else else
rx_status.ssi = 100 - rssi; rx_status.ssi = 100 - rssi;
if (rate <= 4) rx_status.rate_idx = rate;
rx_status.rate = rate_tbl[rate];
rx_status.channel = priv->channel; rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
rx_status.freq = adm8211_channels[priv->channel - 1].freq; rx_status.band = IEEE80211_BAND_2GHZ;
rx_status.phymode = MODE_IEEE80211B;
ieee80211_rx_irqsafe(dev, skb, &rx_status); ieee80211_rx_irqsafe(dev, skb, &rx_status);
} }
...@@ -1054,7 +1077,7 @@ static int adm8211_set_rate(struct ieee80211_hw *dev) ...@@ -1054,7 +1077,7 @@ static int adm8211_set_rate(struct ieee80211_hw *dev)
if (priv->pdev->revision != ADM8211_REV_BA) { if (priv->pdev->revision != ADM8211_REV_BA) {
rate_buf[0] = ARRAY_SIZE(adm8211_rates); rate_buf[0] = ARRAY_SIZE(adm8211_rates);
for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++) for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++)
rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80; rate_buf[i + 1] = (adm8211_rates[i].bitrate / 5) | 0x80;
} else { } else {
/* workaround for rev BA specific bug */ /* workaround for rev BA specific bug */
rate_buf[0] = 0x04; rate_buf[0] = 0x04;
...@@ -1303,9 +1326,10 @@ static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len) ...@@ -1303,9 +1326,10 @@ static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len)
static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
{ {
struct adm8211_priv *priv = dev->priv; struct adm8211_priv *priv = dev->priv;
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
if (conf->channel != priv->channel) { if (channel != priv->channel) {
priv->channel = conf->channel; priv->channel = channel;
adm8211_rf_set_channel(dev, priv->channel); adm8211_rf_set_channel(dev, priv->channel);
} }
...@@ -1680,10 +1704,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -1680,10 +1704,10 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
if (control->tx_rate < 0) { if (control->tx_rate < 0) {
short_preamble = 1; short_preamble = 1;
plcp_signal = -control->tx_rate; plcp_signal = -control->tx_rate->bitrate;
} else { } else {
short_preamble = 0; short_preamble = 0;
plcp_signal = control->tx_rate; plcp_signal = control->tx_rate->bitrate;
} }
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
...@@ -1880,18 +1904,11 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, ...@@ -1880,18 +1904,11 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
SET_IEEE80211_PERM_ADDR(dev, perm_addr); SET_IEEE80211_PERM_ADDR(dev, perm_addr);
dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
dev->flags = IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
/* IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */
dev->channel_change_time = 1000; dev->channel_change_time = 1000;
dev->max_rssi = 100; /* FIXME: find better value */ dev->max_rssi = 100; /* FIXME: find better value */
priv->modes[0].mode = MODE_IEEE80211B;
/* channel info filled in by adm8211_read_eeprom */
memcpy(priv->rates, adm8211_rates, sizeof(adm8211_rates));
priv->modes[0].num_rates = ARRAY_SIZE(adm8211_rates);
priv->modes[0].rates = priv->rates;
dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
priv->retry_limit = 3; priv->retry_limit = 3;
...@@ -1917,14 +1934,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, ...@@ -1917,14 +1934,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
goto err_free_desc; goto err_free_desc;
} }
priv->channel = priv->modes[0].channels[0].chan; priv->channel = 1;
err = ieee80211_register_hwmode(dev, &priv->modes[0]);
if (err) {
printk(KERN_ERR "%s (adm8211): Can't register hwmode\n",
pci_name(pdev));
goto err_free_desc;
}
err = ieee80211_register_hw(dev); err = ieee80211_register_hw(dev);
if (err) { if (err) {
......
...@@ -534,61 +534,6 @@ struct adm8211_eeprom { ...@@ -534,61 +534,6 @@ struct adm8211_eeprom {
u8 cis_data[0]; /* 0x80, 384 bytes */ u8 cis_data[0]; /* 0x80, 384 bytes */
} __attribute__ ((packed)); } __attribute__ ((packed));
static const struct ieee80211_rate adm8211_rates[] = {
{ .rate = 10,
.val = 10,
.val2 = -10,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 20,
.val = 20,
.val2 = -20,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 55,
.val = 55,
.val2 = -55,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 110,
.val = 110,
.val2 = -110,
.flags = IEEE80211_RATE_CCK_2 }
};
struct ieee80211_chan_range {
u8 min;
u8 max;
};
static const struct ieee80211_channel adm8211_channels[] = {
{ .chan = 1,
.freq = 2412},
{ .chan = 2,
.freq = 2417},
{ .chan = 3,
.freq = 2422},
{ .chan = 4,
.freq = 2427},
{ .chan = 5,
.freq = 2432},
{ .chan = 6,
.freq = 2437},
{ .chan = 7,
.freq = 2442},
{ .chan = 8,
.freq = 2447},
{ .chan = 9,
.freq = 2452},
{ .chan = 10,
.freq = 2457},
{ .chan = 11,
.freq = 2462},
{ .chan = 12,
.freq = 2467},
{ .chan = 13,
.freq = 2472},
{ .chan = 14,
.freq = 2484},
};
struct adm8211_priv { struct adm8211_priv {
struct pci_dev *pdev; struct pci_dev *pdev;
spinlock_t lock; spinlock_t lock;
...@@ -603,9 +548,8 @@ struct adm8211_priv { ...@@ -603,9 +548,8 @@ struct adm8211_priv {
unsigned int cur_tx, dirty_tx, cur_rx; unsigned int cur_tx, dirty_tx, cur_rx;
struct ieee80211_low_level_stats stats; struct ieee80211_low_level_stats stats;
struct ieee80211_hw_mode modes[1]; struct ieee80211_supported_band band;
struct ieee80211_channel channels[ARRAY_SIZE(adm8211_channels)]; struct ieee80211_channel channels[14];
struct ieee80211_rate rates[ARRAY_SIZE(adm8211_rates)];
int mode; int mode;
int channel; int channel;
...@@ -643,6 +587,11 @@ struct adm8211_priv { ...@@ -643,6 +587,11 @@ struct adm8211_priv {
} transceiver_type; } transceiver_type;
}; };
struct ieee80211_chan_range {
u8 min;
u8 max;
};
static const struct ieee80211_chan_range cranges[] = { static const struct ieee80211_chan_range cranges[] = {
{1, 11}, /* FCC */ {1, 11}, /* FCC */
{1, 11}, /* IC */ {1, 11}, /* IC */
......
...@@ -468,10 +468,6 @@ struct b43_phy { ...@@ -468,10 +468,6 @@ struct b43_phy {
u8 possible_phymodes; u8 possible_phymodes;
/* GMODE bit enabled? */ /* GMODE bit enabled? */
bool gmode; bool gmode;
/* Possible ieee80211 subsystem hwmodes for this PHY.
* Which mode is selected, depends on thr GMODE enabled bit */
#define B43_MAX_PHYHWMODES 2
struct ieee80211_hw_mode hwmodes[B43_MAX_PHYHWMODES];
/* Analog Type */ /* Analog Type */
u8 analog; u8 analog;
...@@ -727,7 +723,6 @@ struct b43_wldev { ...@@ -727,7 +723,6 @@ struct b43_wldev {
bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
bool short_preamble; /* TRUE, if short preamble is enabled. */
bool short_slot; /* TRUE, if short slot timing is enabled. */ bool short_slot; /* TRUE, if short slot timing is enabled. */
bool radio_hw_enable; /* saved state of radio hardware enabled state */ bool radio_hw_enable; /* saved state of radio hardware enabled state */
bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
......
...@@ -96,25 +96,29 @@ MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); ...@@ -96,25 +96,29 @@ MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl);
* data in there. This data is the same for all devices, so we don't * data in there. This data is the same for all devices, so we don't
* get concurrency issues */ * get concurrency issues */
#define RATETAB_ENT(_rateid, _flags) \ #define RATETAB_ENT(_rateid, _flags) \
{ \ { \
.rate = B43_RATE_TO_BASE100KBPS(_rateid), \ .bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \
.val = (_rateid), \ .hw_value = (_rateid), \
.val2 = (_rateid), \ .flags = (_flags), \
.flags = (_flags), \
} }
/*
* NOTE: When changing this, sync with xmit.c's
* b43_plcp_get_bitrate_idx_* functions!
*/
static struct ieee80211_rate __b43_ratetable[] = { static struct ieee80211_rate __b43_ratetable[] = {
RATETAB_ENT(B43_CCK_RATE_1MB, IEEE80211_RATE_CCK), RATETAB_ENT(B43_CCK_RATE_1MB, 0),
RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_6MB, 0),
RATETAB_ENT(B43_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_9MB, 0),
RATETAB_ENT(B43_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_12MB, 0),
RATETAB_ENT(B43_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_18MB, 0),
RATETAB_ENT(B43_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_24MB, 0),
RATETAB_ENT(B43_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_36MB, 0),
RATETAB_ENT(B43_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_48MB, 0),
RATETAB_ENT(B43_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43_OFDM_RATE_54MB, 0),
}; };
#define b43_a_ratetable (__b43_ratetable + 4) #define b43_a_ratetable (__b43_ratetable + 4)
...@@ -126,14 +130,8 @@ static struct ieee80211_rate __b43_ratetable[] = { ...@@ -126,14 +130,8 @@ static struct ieee80211_rate __b43_ratetable[] = {
#define CHANTAB_ENT(_chanid, _freq) \ #define CHANTAB_ENT(_chanid, _freq) \
{ \ { \
.chan = (_chanid), \ .center_freq = (_freq), \
.freq = (_freq), \ .hw_value = (_chanid), \
.val = (_chanid), \
.flag = IEEE80211_CHAN_W_SCAN | \
IEEE80211_CHAN_W_ACTIVE_SCAN | \
IEEE80211_CHAN_W_IBSS, \
.power_level = 0xFF, \
.antenna_max = 0xFF, \
} }
static struct ieee80211_channel b43_2ghz_chantable[] = { static struct ieee80211_channel b43_2ghz_chantable[] = {
CHANTAB_ENT(1, 2412), CHANTAB_ENT(1, 2412),
...@@ -151,9 +149,8 @@ static struct ieee80211_channel b43_2ghz_chantable[] = { ...@@ -151,9 +149,8 @@ static struct ieee80211_channel b43_2ghz_chantable[] = {
CHANTAB_ENT(13, 2472), CHANTAB_ENT(13, 2472),
CHANTAB_ENT(14, 2484), CHANTAB_ENT(14, 2484),
}; };
#define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable)
#if 0 #ifdef NOTYET
static struct ieee80211_channel b43_5ghz_chantable[] = { static struct ieee80211_channel b43_5ghz_chantable[] = {
CHANTAB_ENT(36, 5180), CHANTAB_ENT(36, 5180),
CHANTAB_ENT(40, 5200), CHANTAB_ENT(40, 5200),
...@@ -169,9 +166,22 @@ static struct ieee80211_channel b43_5ghz_chantable[] = { ...@@ -169,9 +166,22 @@ static struct ieee80211_channel b43_5ghz_chantable[] = {
CHANTAB_ENT(161, 5805), CHANTAB_ENT(161, 5805),
CHANTAB_ENT(165, 5825), CHANTAB_ENT(165, 5825),
}; };
#define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable)
static struct ieee80211_supported_band b43_band_5GHz = {
.channels = b43_5ghz_chantable,
.n_channels = ARRAY_SIZE(b43_5ghz_chantable),
.bitrates = b43_a_ratetable,
.n_bitrates = b43_a_ratetable_size,
};
#endif #endif
static struct ieee80211_supported_band b43_band_2GHz = {
.channels = b43_2ghz_chantable,
.n_channels = ARRAY_SIZE(b43_2ghz_chantable),
.bitrates = b43_g_ratetable,
.n_bitrates = b43_g_ratetable_size,
};
static void b43_wireless_core_exit(struct b43_wldev *dev); static void b43_wireless_core_exit(struct b43_wldev *dev);
static int b43_wireless_core_init(struct b43_wldev *dev); static int b43_wireless_core_init(struct b43_wldev *dev);
static void b43_wireless_core_stop(struct b43_wldev *dev); static void b43_wireless_core_stop(struct b43_wldev *dev);
...@@ -1222,17 +1232,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev, ...@@ -1222,17 +1232,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
} }
static void b43_write_probe_resp_plcp(struct b43_wldev *dev, static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
u16 shm_offset, u16 size, u8 rate) u16 shm_offset, u16 size,
struct ieee80211_rate *rate)
{ {
struct b43_plcp_hdr4 plcp; struct b43_plcp_hdr4 plcp;
u32 tmp; u32 tmp;
__le16 dur; __le16 dur;
plcp.data = 0; plcp.data = 0;
b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
dur = ieee80211_generic_frame_duration(dev->wl->hw, dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, size, dev->wl->vif, size,
B43_RATE_TO_BASE100KBPS(rate)); rate);
/* Write PLCP in two parts and timing for packet transfer */ /* Write PLCP in two parts and timing for packet transfer */
tmp = le32_to_cpu(plcp.data); tmp = le32_to_cpu(plcp.data);
b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF);
...@@ -1247,7 +1258,8 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev, ...@@ -1247,7 +1258,8 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev,
* 3) Stripping TIM * 3) Stripping TIM
*/ */
static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
u16 *dest_size, u8 rate) u16 *dest_size,
struct ieee80211_rate *rate)
{ {
const u8 *src_data; const u8 *src_data;
u8 *dest_data; u8 *dest_data;
...@@ -1292,7 +1304,7 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, ...@@ -1292,7 +1304,7 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
IEEE80211_STYPE_PROBE_RESP); IEEE80211_STYPE_PROBE_RESP);
dur = ieee80211_generic_frame_duration(dev->wl->hw, dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, *dest_size, dev->wl->vif, *dest_size,
B43_RATE_TO_BASE100KBPS(rate)); rate);
hdr->duration_id = dur; hdr->duration_id = dur;
return dest_data; return dest_data;
...@@ -1300,7 +1312,8 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, ...@@ -1300,7 +1312,8 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev,
static void b43_write_probe_resp_template(struct b43_wldev *dev, static void b43_write_probe_resp_template(struct b43_wldev *dev,
u16 ram_offset, u16 ram_offset,
u16 shm_size_offset, u8 rate) u16 shm_size_offset,
struct ieee80211_rate *rate)
{ {
const u8 *probe_resp_data; const u8 *probe_resp_data;
u16 size; u16 size;
...@@ -1313,14 +1326,15 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, ...@@ -1313,14 +1326,15 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev,
/* Looks like PLCP headers plus packet timings are stored for /* Looks like PLCP headers plus packet timings are stored for
* all possible basic rates * all possible basic rates
*/ */
b43_write_probe_resp_plcp(dev, 0x31A, size, B43_CCK_RATE_1MB); b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
b43_write_probe_resp_plcp(dev, 0x32C, size, B43_CCK_RATE_2MB); b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
b43_write_probe_resp_plcp(dev, 0x33E, size, B43_CCK_RATE_5MB); b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
b43_write_probe_resp_plcp(dev, 0x350, size, B43_CCK_RATE_11MB); b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
b43_write_template_common(dev, probe_resp_data, b43_write_template_common(dev, probe_resp_data,
size, ram_offset, shm_size_offset, rate); size, ram_offset, shm_size_offset,
rate->hw_value);
kfree(probe_resp_data); kfree(probe_resp_data);
} }
...@@ -1388,7 +1402,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) ...@@ -1388,7 +1402,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
b43_write_beacon_template(dev, 0x68, 0x18, b43_write_beacon_template(dev, 0x68, 0x18,
B43_CCK_RATE_1MB); B43_CCK_RATE_1MB);
b43_write_probe_resp_template(dev, 0x268, 0x4A, b43_write_probe_resp_template(dev, 0x268, 0x4A,
B43_CCK_RATE_11MB); &__b43_ratetable[3]);
wl->beacon0_uploaded = 1; wl->beacon0_uploaded = 1;
} }
cmd |= B43_MACCMD_BEACON0_VALID; cmd |= B43_MACCMD_BEACON0_VALID;
...@@ -2830,14 +2844,11 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) ...@@ -2830,14 +2844,11 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
/* Switch the PHY mode (if necessary). */ /* Switch the PHY mode (if necessary). */
switch (conf->phymode) { switch (conf->channel->band) {
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
new_phymode = B43_PHYMODE_A; new_phymode = B43_PHYMODE_A;
break; break;
case MODE_IEEE80211B: case IEEE80211_BAND_2GHZ:
new_phymode = B43_PHYMODE_B;
break;
case MODE_IEEE80211G:
new_phymode = B43_PHYMODE_G; new_phymode = B43_PHYMODE_G;
break; break;
default: default:
...@@ -2863,8 +2874,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) ...@@ -2863,8 +2874,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
/* Switch to the requested channel. /* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */ * The firmware takes care of races with the TX handler. */
if (conf->channel_val != phy->channel) if (conf->channel->hw_value != phy->channel)
b43_radio_selectchannel(dev, conf->channel_val, 0); b43_radio_selectchannel(dev, conf->channel->hw_value, 0);
/* Enable/Disable ShortSlot timing. */ /* Enable/Disable ShortSlot timing. */
if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) !=
...@@ -3810,9 +3821,7 @@ static int b43_setup_modes(struct b43_wldev *dev, ...@@ -3810,9 +3821,7 @@ static int b43_setup_modes(struct b43_wldev *dev,
bool have_2ghz_phy, bool have_5ghz_phy) bool have_2ghz_phy, bool have_5ghz_phy)
{ {
struct ieee80211_hw *hw = dev->wl->hw; struct ieee80211_hw *hw = dev->wl->hw;
struct ieee80211_hw_mode *mode;
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
int err;
/* XXX: This function will go away soon, when mac80211 /* XXX: This function will go away soon, when mac80211
* band stuff is rewritten. So this is just a hack. * band stuff is rewritten. So this is just a hack.
...@@ -3821,15 +3830,7 @@ static int b43_setup_modes(struct b43_wldev *dev, ...@@ -3821,15 +3830,7 @@ static int b43_setup_modes(struct b43_wldev *dev,
* This assumption is OK, as any B, N or A PHY will already * This assumption is OK, as any B, N or A PHY will already
* have died a horrible sanity check death earlier. */ * have died a horrible sanity check death earlier. */
mode = &phy->hwmodes[0]; hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
mode->mode = MODE_IEEE80211G;
mode->num_channels = b43_2ghz_chantable_size;
mode->channels = b43_2ghz_chantable;
mode->num_rates = b43_g_ratetable_size;
mode->rates = b43_g_ratetable;
err = ieee80211_register_hwmode(hw, mode);
if (err)
return err;
phy->possible_phymodes |= B43_PHYMODE_G; phy->possible_phymodes |= B43_PHYMODE_G;
return 0; return 0;
......
...@@ -47,29 +47,6 @@ static int get_integer(const char *buf, size_t count) ...@@ -47,29 +47,6 @@ static int get_integer(const char *buf, size_t count)
return ret; return ret;
} }
static int get_boolean(const char *buf, size_t count)
{
if (count != 0) {
if (buf[0] == '1')
return 1;
if (buf[0] == '0')
return 0;
if (count >= 4 && memcmp(buf, "true", 4) == 0)
return 1;
if (count >= 5 && memcmp(buf, "false", 5) == 0)
return 0;
if (count >= 3 && memcmp(buf, "yes", 3) == 0)
return 1;
if (count >= 2 && memcmp(buf, "no", 2) == 0)
return 0;
if (count >= 2 && memcmp(buf, "on", 2) == 0)
return 1;
if (count >= 3 && memcmp(buf, "off", 3) == 0)
return 0;
}
return -EINVAL;
}
static ssize_t b43_attr_interfmode_show(struct device *dev, static ssize_t b43_attr_interfmode_show(struct device *dev,
struct device_attribute *attr, struct device_attribute *attr,
char *buf) char *buf)
...@@ -155,82 +132,18 @@ static ssize_t b43_attr_interfmode_store(struct device *dev, ...@@ -155,82 +132,18 @@ static ssize_t b43_attr_interfmode_store(struct device *dev,
static DEVICE_ATTR(interference, 0644, static DEVICE_ATTR(interference, 0644,
b43_attr_interfmode_show, b43_attr_interfmode_store); b43_attr_interfmode_show, b43_attr_interfmode_store);
static ssize_t b43_attr_preamble_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct b43_wldev *wldev = dev_to_b43_wldev(dev);
ssize_t count;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
mutex_lock(&wldev->wl->mutex);
if (wldev->short_preamble)
count =
snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n");
else
count =
snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n");
mutex_unlock(&wldev->wl->mutex);
return count;
}
static ssize_t b43_attr_preamble_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct b43_wldev *wldev = dev_to_b43_wldev(dev);
unsigned long flags;
int value;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
value = get_boolean(buf, count);
if (value < 0)
return value;
mutex_lock(&wldev->wl->mutex);
spin_lock_irqsave(&wldev->wl->irq_lock, flags);
wldev->short_preamble = !!value;
spin_unlock_irqrestore(&wldev->wl->irq_lock, flags);
mutex_unlock(&wldev->wl->mutex);
return count;
}
static DEVICE_ATTR(shortpreamble, 0644,
b43_attr_preamble_show, b43_attr_preamble_store);
int b43_sysfs_register(struct b43_wldev *wldev) int b43_sysfs_register(struct b43_wldev *wldev)
{ {
struct device *dev = wldev->dev->dev; struct device *dev = wldev->dev->dev;
int err;
B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
err = device_create_file(dev, &dev_attr_interference); return device_create_file(dev, &dev_attr_interference);
if (err)
goto out;
err = device_create_file(dev, &dev_attr_shortpreamble);
if (err)
goto err_remove_interfmode;
out:
return err;
err_remove_interfmode:
device_remove_file(dev, &dev_attr_interference);
goto out;
} }
void b43_sysfs_unregister(struct b43_wldev *wldev) void b43_sysfs_unregister(struct b43_wldev *wldev)
{ {
struct device *dev = wldev->dev->dev; struct device *dev = wldev->dev->dev;
device_remove_file(dev, &dev_attr_shortpreamble);
device_remove_file(dev, &dev_attr_interference); device_remove_file(dev, &dev_attr_interference);
} }
...@@ -32,46 +32,48 @@ ...@@ -32,46 +32,48 @@
#include "dma.h" #include "dma.h"
/* Extract the bitrate out of a CCK PLCP header. */ /* Extract the bitrate index out of a CCK PLCP header. */
static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp)
{ {
switch (plcp->raw[0]) { switch (plcp->raw[0]) {
case 0x0A: case 0x0A:
return B43_CCK_RATE_1MB; return 0;
case 0x14: case 0x14:
return B43_CCK_RATE_2MB; return 1;
case 0x37: case 0x37:
return B43_CCK_RATE_5MB; return 2;
case 0x6E: case 0x6E:
return B43_CCK_RATE_11MB; return 3;
} }
B43_WARN_ON(1); B43_WARN_ON(1);
return 0; return -1;
} }
/* Extract the bitrate out of an OFDM PLCP header. */ /* Extract the bitrate index out of an OFDM PLCP header. */
static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy)
{ {
int base = aphy ? 0 : 4;
switch (plcp->raw[0] & 0xF) { switch (plcp->raw[0] & 0xF) {
case 0xB: case 0xB:
return B43_OFDM_RATE_6MB; return base + 0;
case 0xF: case 0xF:
return B43_OFDM_RATE_9MB; return base + 1;
case 0xA: case 0xA:
return B43_OFDM_RATE_12MB; return base + 2;
case 0xE: case 0xE:
return B43_OFDM_RATE_18MB; return base + 3;
case 0x9: case 0x9:
return B43_OFDM_RATE_24MB; return base + 4;
case 0xD: case 0xD:
return B43_OFDM_RATE_36MB; return base + 5;
case 0x8: case 0x8:
return B43_OFDM_RATE_48MB; return base + 6;
case 0xC: case 0xC:
return B43_OFDM_RATE_54MB; return base + 7;
} }
B43_WARN_ON(1); B43_WARN_ON(1);
return 0; return -1;
} }
u8 b43_plcp_get_ratecode_cck(const u8 bitrate) u8 b43_plcp_get_ratecode_cck(const u8 bitrate)
...@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
(const struct ieee80211_hdr *)fragment_data; (const struct ieee80211_hdr *)fragment_data;
int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
u16 fctl = le16_to_cpu(wlhdr->frame_control); u16 fctl = le16_to_cpu(wlhdr->frame_control);
struct ieee80211_rate *fbrate;
u8 rate, rate_fb; u8 rate, rate_fb;
int rate_ofdm, rate_fb_ofdm; int rate_ofdm, rate_fb_ofdm;
unsigned int plcp_fragment_len; unsigned int plcp_fragment_len;
...@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev,
memset(txhdr, 0, sizeof(*txhdr)); memset(txhdr, 0, sizeof(*txhdr));
rate = txctl->tx_rate; WARN_ON(!txctl->tx_rate);
rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB;
rate_ofdm = b43_is_ofdm_rate(rate); rate_ofdm = b43_is_ofdm_rate(rate);
rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; fbrate = txctl->alt_retry_rate ? : txctl->tx_rate;
rate_fb = fbrate->hw_value;
rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
if (rate_ofdm) if (rate_ofdm)
...@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev,
* use the original dur_id field. */ * use the original dur_id field. */
txhdr->dur_fb = wlhdr->duration_id; txhdr->dur_fb = wlhdr->duration_id;
} else { } else {
int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb);
txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
txctl->vif, txctl->vif,
fragment_len, fragment_len,
fbrate_base100kbps); fbrate);
} }
plcp_fragment_len = fragment_len + FCS_LEN; plcp_fragment_len = fragment_len + FCS_LEN;
...@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
phy_ctl |= B43_TXH_PHY_ENC_OFDM; phy_ctl |= B43_TXH_PHY_ENC_OFDM;
else else
phy_ctl |= B43_TXH_PHY_ENC_CCK; phy_ctl |= B43_TXH_PHY_ENC_CCK;
if (dev->short_preamble) if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
phy_ctl |= B43_TXH_PHY_SHORTPRMBL; phy_ctl |= B43_TXH_PHY_SHORTPRMBL;
switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) {
...@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, ...@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev,
int rts_rate_ofdm, rts_rate_fb_ofdm; int rts_rate_ofdm, rts_rate_fb_ofdm;
struct b43_plcp_hdr6 *plcp; struct b43_plcp_hdr6 *plcp;
rts_rate = txctl->rts_cts_rate; WARN_ON(!txctl->rts_cts_rate);
rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB;
rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); rts_rate_ofdm = b43_is_ofdm_rate(rts_rate);
rts_rate_fb = b43_calc_fallback_rate(rts_rate); rts_rate_fb = b43_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb);
...@@ -506,6 +511,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -506,6 +511,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
u16 phystat0, phystat3, chanstat, mactime; u16 phystat0, phystat3, chanstat, mactime;
u32 macstat; u32 macstat;
u16 chanid; u16 chanid;
u16 phytype;
u8 jssi; u8 jssi;
int padding; int padding;
...@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
macstat = le32_to_cpu(rxhdr->mac_status); macstat = le32_to_cpu(rxhdr->mac_status);
mactime = le16_to_cpu(rxhdr->mac_time); mactime = le16_to_cpu(rxhdr->mac_time);
chanstat = le16_to_cpu(rxhdr->channel); chanstat = le16_to_cpu(rxhdr->channel);
phytype = chanstat & B43_RX_CHAN_PHYTYPE;
if (macstat & B43_RX_MAC_FCSERR) if (macstat & B43_RX_MAC_FCSERR)
dev->wl->ieee_stats.dot11FCSErrorCount++; dev->wl->ieee_stats.dot11FCSErrorCount++;
...@@ -575,9 +582,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -575,9 +582,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
/* the next line looks wrong, but is what mac80211 wants */ /* the next line looks wrong, but is what mac80211 wants */
status.signal = (jssi * 100) / B43_RX_MAX_SSI; status.signal = (jssi * 100) / B43_RX_MAX_SSI;
if (phystat0 & B43_RX_PHYST0_OFDM) if (phystat0 & B43_RX_PHYST0_OFDM)
status.rate = b43_plcp_get_bitrate_ofdm(plcp); status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp,
phytype == B43_PHYTYPE_A);
else else
status.rate = b43_plcp_get_bitrate_cck(plcp); status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp);
status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT);
/* /*
...@@ -601,29 +609,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) ...@@ -601,29 +609,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT;
switch (chanstat & B43_RX_CHAN_PHYTYPE) { switch (chanstat & B43_RX_CHAN_PHYTYPE) {
case B43_PHYTYPE_A: case B43_PHYTYPE_A:
status.phymode = MODE_IEEE80211A; status.band = IEEE80211_BAND_5GHZ;
B43_WARN_ON(1); B43_WARN_ON(1);
/* FIXME: We don't really know which value the "chanid" contains. /* FIXME: We don't really know which value the "chanid" contains.
* So the following assignment might be wrong. */ * So the following assignment might be wrong. */
status.channel = chanid; status.freq = b43_channel_to_freq_5ghz(chanid);
status.freq = b43_channel_to_freq_5ghz(status.channel);
break; break;
case B43_PHYTYPE_G: case B43_PHYTYPE_G:
status.phymode = MODE_IEEE80211G; status.band = IEEE80211_BAND_2GHZ;
/* chanid is the radio channel cookie value as used /* chanid is the radio channel cookie value as used
* to tune the radio. */ * to tune the radio. */
status.freq = chanid + 2400; status.freq = chanid + 2400;
status.channel = b43_freq_to_channel_2ghz(status.freq);
break; break;
case B43_PHYTYPE_N: case B43_PHYTYPE_N:
status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/;
/* chanid is the SHM channel cookie. Which is the plain /* chanid is the SHM channel cookie. Which is the plain
* channel number in b43. */ * channel number in b43. */
status.channel = chanid; if (chanstat & B43_RX_CHAN_5GHZ) {
if (chanstat & B43_RX_CHAN_5GHZ) status.band = IEEE80211_BAND_5GHZ;
status.freq = b43_freq_to_channel_5ghz(status.freq); status.freq = b43_freq_to_channel_5ghz(chanid);
else } else {
status.freq = b43_freq_to_channel_2ghz(status.freq); status.band = IEEE80211_BAND_2GHZ;
status.freq = b43_freq_to_channel_2ghz(chanid);
}
break; break;
default: default:
B43_WARN_ON(1); B43_WARN_ON(1);
......
...@@ -392,10 +392,6 @@ struct b43legacy_phy { ...@@ -392,10 +392,6 @@ struct b43legacy_phy {
u8 possible_phymodes; u8 possible_phymodes;
/* GMODE bit enabled in MACCTL? */ /* GMODE bit enabled in MACCTL? */
bool gmode; bool gmode;
/* Possible ieee80211 subsystem hwmodes for this PHY.
* Which mode is selected, depends on thr GMODE enabled bit */
#define B43legacy_MAX_PHYHWMODES 2
struct ieee80211_hw_mode hwmodes[B43legacy_MAX_PHYHWMODES];
/* Analog Type */ /* Analog Type */
u8 analog; u8 analog;
......
...@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl); ...@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl);
* data in there. This data is the same for all devices, so we don't * data in there. This data is the same for all devices, so we don't
* get concurrency issues */ * get concurrency issues */
#define RATETAB_ENT(_rateid, _flags) \ #define RATETAB_ENT(_rateid, _flags) \
{ \ { \
.rate = B43legacy_RATE_TO_100KBPS(_rateid), \ .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \
.val = (_rateid), \ .hw_value = (_rateid), \
.val2 = (_rateid), \ .flags = (_flags), \
.flags = (_flags), \
} }
/*
* NOTE: When changing this, sync with xmit.c's
* b43legacy_plcp_get_bitrate_idx_* functions!
*/
static struct ieee80211_rate __b43legacy_ratetable[] = { static struct ieee80211_rate __b43legacy_ratetable[] = {
RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK), RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0),
RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0),
}; };
#define b43legacy_a_ratetable (__b43legacy_ratetable + 4)
#define b43legacy_a_ratetable_size 8
#define b43legacy_b_ratetable (__b43legacy_ratetable + 0) #define b43legacy_b_ratetable (__b43legacy_ratetable + 0)
#define b43legacy_b_ratetable_size 4 #define b43legacy_b_ratetable_size 4
#define b43legacy_g_ratetable (__b43legacy_ratetable + 0) #define b43legacy_g_ratetable (__b43legacy_ratetable + 0)
...@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = { ...@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = {
#define CHANTAB_ENT(_chanid, _freq) \ #define CHANTAB_ENT(_chanid, _freq) \
{ \ { \
.chan = (_chanid), \ .center_freq = (_freq), \
.freq = (_freq), \ .hw_value = (_chanid), \
.val = (_chanid), \
.flag = IEEE80211_CHAN_W_SCAN | \
IEEE80211_CHAN_W_ACTIVE_SCAN | \
IEEE80211_CHAN_W_IBSS, \
.power_level = 0x0A, \
.antenna_max = 0xFF, \
} }
static struct ieee80211_channel b43legacy_bg_chantable[] = { static struct ieee80211_channel b43legacy_bg_chantable[] = {
CHANTAB_ENT(1, 2412), CHANTAB_ENT(1, 2412),
...@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = { ...@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = {
CHANTAB_ENT(13, 2472), CHANTAB_ENT(13, 2472),
CHANTAB_ENT(14, 2484), CHANTAB_ENT(14, 2484),
}; };
#define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable)
static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = {
.channels = b43legacy_bg_chantable,
.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
.bitrates = b43legacy_b_ratetable,
.n_bitrates = b43legacy_b_ratetable_size,
};
static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = {
.channels = b43legacy_bg_chantable,
.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
.bitrates = b43legacy_g_ratetable,
.n_bitrates = b43legacy_g_ratetable_size,
};
static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev);
static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev);
...@@ -969,18 +977,18 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, ...@@ -969,18 +977,18 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
u16 shm_offset, u16 size, u16 shm_offset, u16 size,
u8 rate) struct ieee80211_rate *rate)
{ {
struct b43legacy_plcp_hdr4 plcp; struct b43legacy_plcp_hdr4 plcp;
u32 tmp; u32 tmp;
__le16 dur; __le16 dur;
plcp.data = 0; plcp.data = 0;
b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate);
dur = ieee80211_generic_frame_duration(dev->wl->hw, dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, dev->wl->vif,
size, size,
B43legacy_RATE_TO_100KBPS(rate)); rate);
/* Write PLCP in two parts and timing for packet transfer */ /* Write PLCP in two parts and timing for packet transfer */
tmp = le32_to_cpu(plcp.data); tmp = le32_to_cpu(plcp.data);
b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset,
...@@ -998,7 +1006,8 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, ...@@ -998,7 +1006,8 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
* 3) Stripping TIM * 3) Stripping TIM
*/ */
static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
u16 *dest_size, u8 rate) u16 *dest_size,
struct ieee80211_rate *rate)
{ {
const u8 *src_data; const u8 *src_data;
u8 *dest_data; u8 *dest_data;
...@@ -1046,7 +1055,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, ...@@ -1046,7 +1055,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
dur = ieee80211_generic_frame_duration(dev->wl->hw, dur = ieee80211_generic_frame_duration(dev->wl->hw,
dev->wl->vif, dev->wl->vif,
*dest_size, *dest_size,
B43legacy_RATE_TO_100KBPS(rate)); rate);
hdr->duration_id = dur; hdr->duration_id = dur;
return dest_data; return dest_data;
...@@ -1054,7 +1063,8 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, ...@@ -1054,7 +1063,8 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev,
static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
u16 ram_offset, u16 ram_offset,
u16 shm_size_offset, u8 rate) u16 shm_size_offset,
struct ieee80211_rate *rate)
{ {
u8 *probe_resp_data; u8 *probe_resp_data;
u16 size; u16 size;
...@@ -1069,19 +1079,19 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, ...@@ -1069,19 +1079,19 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
* all possible basic rates * all possible basic rates
*/ */
b43legacy_write_probe_resp_plcp(dev, 0x31A, size, b43legacy_write_probe_resp_plcp(dev, 0x31A, size,
B43legacy_CCK_RATE_1MB); &b43legacy_b_ratetable[0]);
b43legacy_write_probe_resp_plcp(dev, 0x32C, size, b43legacy_write_probe_resp_plcp(dev, 0x32C, size,
B43legacy_CCK_RATE_2MB); &b43legacy_b_ratetable[1]);
b43legacy_write_probe_resp_plcp(dev, 0x33E, size, b43legacy_write_probe_resp_plcp(dev, 0x33E, size,
B43legacy_CCK_RATE_5MB); &b43legacy_b_ratetable[2]);
b43legacy_write_probe_resp_plcp(dev, 0x350, size, b43legacy_write_probe_resp_plcp(dev, 0x350, size,
B43legacy_CCK_RATE_11MB); &b43legacy_b_ratetable[3]);
size = min((size_t)size, size = min((size_t)size,
0x200 - sizeof(struct b43legacy_plcp_hdr6)); 0x200 - sizeof(struct b43legacy_plcp_hdr6));
b43legacy_write_template_common(dev, probe_resp_data, b43legacy_write_template_common(dev, probe_resp_data,
size, ram_offset, size, ram_offset,
shm_size_offset, rate); shm_size_offset, rate->bitrate);
kfree(probe_resp_data); kfree(probe_resp_data);
} }
...@@ -1106,7 +1116,7 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev) ...@@ -1106,7 +1116,7 @@ static void b43legacy_update_templates(struct b43legacy_wldev *dev)
b43legacy_write_beacon_template(dev, 0x468, 0x1A, b43legacy_write_beacon_template(dev, 0x468, 0x1A,
B43legacy_CCK_RATE_1MB); B43legacy_CCK_RATE_1MB);
b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
B43legacy_CCK_RATE_11MB); &b43legacy_b_ratetable[0]);
status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
status |= 0x03; status |= 0x03;
...@@ -2550,14 +2560,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2550,14 +2560,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx);
mutex_lock(&wl->mutex); mutex_lock(&wl->mutex);
dev = wl->current_dev;
phy = &dev->phy;
/* Switch the PHY mode (if necessary). */ /* Switch the PHY mode (if necessary). */
switch (conf->phymode) { switch (conf->channel->band) {
case MODE_IEEE80211B: case IEEE80211_BAND_2GHZ:
new_phymode = B43legacy_PHYMODE_B; if (phy->type == B43legacy_PHYTYPE_B)
break; new_phymode = B43legacy_PHYMODE_B;
case MODE_IEEE80211G: else
new_phymode = B43legacy_PHYMODE_G; new_phymode = B43legacy_PHYMODE_G;
break; break;
default: default:
B43legacy_WARN_ON(1); B43legacy_WARN_ON(1);
...@@ -2565,8 +2577,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2565,8 +2577,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
err = b43legacy_switch_phymode(wl, new_phymode); err = b43legacy_switch_phymode(wl, new_phymode);
if (err) if (err)
goto out_unlock_mutex; goto out_unlock_mutex;
dev = wl->current_dev;
phy = &dev->phy;
/* Disable IRQs while reconfiguring the device. /* Disable IRQs while reconfiguring the device.
* This makes it possible to drop the spinlock throughout * This makes it possible to drop the spinlock throughout
...@@ -2582,8 +2592,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, ...@@ -2582,8 +2592,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
/* Switch to the requested channel. /* Switch to the requested channel.
* The firmware takes care of races with the TX handler. */ * The firmware takes care of races with the TX handler. */
if (conf->channel_val != phy->channel) if (conf->channel->hw_value != phy->channel)
b43legacy_radio_selectchannel(dev, conf->channel_val, 0); b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0);
/* Enable/Disable ShortSlot timing. */ /* Enable/Disable ShortSlot timing. */
if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME))
...@@ -3398,48 +3408,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev, ...@@ -3398,48 +3408,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev,
int have_gphy) int have_gphy)
{ {
struct ieee80211_hw *hw = dev->wl->hw; struct ieee80211_hw *hw = dev->wl->hw;
struct ieee80211_hw_mode *mode;
struct b43legacy_phy *phy = &dev->phy; struct b43legacy_phy *phy = &dev->phy;
int cnt = 0;
int err;
phy->possible_phymodes = 0; phy->possible_phymodes = 0;
for (; 1; cnt++) { if (have_bphy) {
if (have_bphy) { hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); &b43legacy_band_2GHz_BPHY;
mode = &phy->hwmodes[cnt]; phy->possible_phymodes |= B43legacy_PHYMODE_B;
}
mode->mode = MODE_IEEE80211B;
mode->num_channels = b43legacy_bg_chantable_size; if (have_gphy) {
mode->channels = b43legacy_bg_chantable; hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
mode->num_rates = b43legacy_b_ratetable_size; &b43legacy_band_2GHz_GPHY;
mode->rates = b43legacy_b_ratetable; phy->possible_phymodes |= B43legacy_PHYMODE_G;
err = ieee80211_register_hwmode(hw, mode);
if (err)
return err;
phy->possible_phymodes |= B43legacy_PHYMODE_B;
have_bphy = 0;
continue;
}
if (have_gphy) {
B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES);
mode = &phy->hwmodes[cnt];
mode->mode = MODE_IEEE80211G;
mode->num_channels = b43legacy_bg_chantable_size;
mode->channels = b43legacy_bg_chantable;
mode->num_rates = b43legacy_g_ratetable_size;
mode->rates = b43legacy_g_ratetable;
err = ieee80211_register_hwmode(hw, mode);
if (err)
return err;
phy->possible_phymodes |= B43legacy_PHYMODE_G;
have_gphy = 0;
continue;
}
break;
} }
return 0; return 0;
......
...@@ -37,45 +37,48 @@ ...@@ -37,45 +37,48 @@
/* Extract the bitrate out of a CCK PLCP header. */ /* Extract the bitrate out of a CCK PLCP header. */
static u8 b43legacy_plcp_get_bitrate_cck(struct b43legacy_plcp_hdr6 *plcp) static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp)
{ {
switch (plcp->raw[0]) { switch (plcp->raw[0]) {
case 0x0A: case 0x0A:
return B43legacy_CCK_RATE_1MB; return 0;
case 0x14: case 0x14:
return B43legacy_CCK_RATE_2MB; return 1;
case 0x37: case 0x37:
return B43legacy_CCK_RATE_5MB; return 2;
case 0x6E: case 0x6E:
return B43legacy_CCK_RATE_11MB; return 3;
} }
B43legacy_BUG_ON(1); B43legacy_BUG_ON(1);
return 0; return -1;
} }
/* Extract the bitrate out of an OFDM PLCP header. */ /* Extract the bitrate out of an OFDM PLCP header. */
static u8 b43legacy_plcp_get_bitrate_ofdm(struct b43legacy_plcp_hdr6 *plcp) static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp,
bool aphy)
{ {
int base = aphy ? 0 : 4;
switch (plcp->raw[0] & 0xF) { switch (plcp->raw[0] & 0xF) {
case 0xB: case 0xB:
return B43legacy_OFDM_RATE_6MB; return base + 0;
case 0xF: case 0xF:
return B43legacy_OFDM_RATE_9MB; return base + 1;
case 0xA: case 0xA:
return B43legacy_OFDM_RATE_12MB; return base + 2;
case 0xE: case 0xE:
return B43legacy_OFDM_RATE_18MB; return base + 3;
case 0x9: case 0x9:
return B43legacy_OFDM_RATE_24MB; return base + 4;
case 0xD: case 0xD:
return B43legacy_OFDM_RATE_36MB; return base + 5;
case 0x8: case 0x8:
return B43legacy_OFDM_RATE_48MB; return base + 6;
case 0xC: case 0xC:
return B43legacy_OFDM_RATE_54MB; return base + 7;
} }
B43legacy_BUG_ON(1); B43legacy_BUG_ON(1);
return 0; return -1;
} }
u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate) u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
...@@ -192,7 +195,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, ...@@ -192,7 +195,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT));
u16 fctl; u16 fctl;
u8 rate; u8 rate;
u8 rate_fb; struct ieee80211_rate *rate_fb;
int rate_ofdm; int rate_ofdm;
int rate_fb_ofdm; int rate_fb_ofdm;
unsigned int plcp_fragment_len; unsigned int plcp_fragment_len;
...@@ -204,16 +207,16 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, ...@@ -204,16 +207,16 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
memset(txhdr, 0, sizeof(*txhdr)); memset(txhdr, 0, sizeof(*txhdr));
rate = txctl->tx_rate; rate = txctl->tx_rate->hw_value;
rate_ofdm = b43legacy_is_ofdm_rate(rate); rate_ofdm = b43legacy_is_ofdm_rate(rate);
rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate;
rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb); rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
txhdr->mac_frame_ctl = wlhdr->frame_control; txhdr->mac_frame_ctl = wlhdr->frame_control;
memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); memcpy(txhdr->tx_receiver, wlhdr->addr1, 6);
/* Calculate duration for fallback rate */ /* Calculate duration for fallback rate */
if ((rate_fb == rate) || if ((rate_fb->hw_value == rate) ||
(wlhdr->duration_id & cpu_to_le16(0x8000)) || (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
(wlhdr->duration_id == cpu_to_le16(0))) { (wlhdr->duration_id == cpu_to_le16(0))) {
/* If the fallback rate equals the normal rate or the /* If the fallback rate equals the normal rate or the
...@@ -221,11 +224,10 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, ...@@ -221,11 +224,10 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
* use the original dur_id field. */ * use the original dur_id field. */
txhdr->dur_fb = wlhdr->duration_id; txhdr->dur_fb = wlhdr->duration_id;
} else { } else {
int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb);
txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
txctl->vif, txctl->vif,
fragment_len, fragment_len,
fbrate_base100kbps); rate_fb);
} }
plcp_fragment_len = fragment_len + FCS_LEN; plcp_fragment_len = fragment_len + FCS_LEN;
...@@ -266,7 +268,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, ...@@ -266,7 +268,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
rate); rate);
b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
(&txhdr->plcp_fb), plcp_fragment_len, (&txhdr->plcp_fb), plcp_fragment_len,
rate_fb); rate_fb->hw_value);
/* PHY TX Control word */ /* PHY TX Control word */
if (rate_ofdm) if (rate_ofdm)
...@@ -310,7 +312,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, ...@@ -310,7 +312,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
int rts_rate_ofdm; int rts_rate_ofdm;
int rts_rate_fb_ofdm; int rts_rate_fb_ofdm;
rts_rate = txctl->rts_cts_rate; rts_rate = txctl->rts_cts_rate->hw_value;
rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate);
rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
...@@ -536,10 +538,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -536,10 +538,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
(phystat3 & B43legacy_RX_PHYST3_TRSTATE)); (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
status.noise = dev->stats.link_noise; status.noise = dev->stats.link_noise;
status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI;
/* change to support A PHY */
if (phystat0 & B43legacy_RX_PHYST0_OFDM) if (phystat0 & B43legacy_RX_PHYST0_OFDM)
status.rate = b43legacy_plcp_get_bitrate_ofdm(plcp); status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
else else
status.rate = b43legacy_plcp_get_bitrate_cck(plcp); status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp);
status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
/* /*
...@@ -564,14 +567,9 @@ void b43legacy_rx(struct b43legacy_wldev *dev, ...@@ -564,14 +567,9 @@ void b43legacy_rx(struct b43legacy_wldev *dev,
B43legacy_RX_CHAN_ID_SHIFT; B43legacy_RX_CHAN_ID_SHIFT;
switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) { switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) {
case B43legacy_PHYTYPE_B: case B43legacy_PHYTYPE_B:
status.phymode = MODE_IEEE80211B;
status.freq = chanid + 2400;
status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
break;
case B43legacy_PHYTYPE_G: case B43legacy_PHYTYPE_G:
status.phymode = MODE_IEEE80211G; status.band = IEEE80211_BAND_2GHZ;
status.freq = chanid + 2400; status.freq = chanid + 2400;
status.channel = b43legacy_freq_to_channel_bg(chanid + 2400);
break; break;
default: default:
b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
......
...@@ -100,14 +100,6 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { ...@@ -100,14 +100,6 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = {
{-89, IWL_RATE_6M_INDEX} {-89, IWL_RATE_6M_INDEX}
}; };
static struct iwl3945_tpt_entry iwl3945_tpt_table_b[] = {
{-86, IWL_RATE_11M_INDEX},
{-88, IWL_RATE_5M_INDEX},
{-90, IWL_RATE_2M_INDEX},
{-92, IWL_RATE_1M_INDEX}
};
static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
{-60, IWL_RATE_54M_INDEX}, {-60, IWL_RATE_54M_INDEX},
{-64, IWL_RATE_48M_INDEX}, {-64, IWL_RATE_48M_INDEX},
...@@ -129,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { ...@@ -129,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
#define IWL_RATE_MIN_SUCCESS_TH 8 #define IWL_RATE_MIN_SUCCESS_TH 8
#define IWL_RATE_DECREASE_TH 1920 #define IWL_RATE_DECREASE_TH 1920
static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band)
{ {
u32 index = 0; u32 index = 0;
u32 table_size = 0; u32 table_size = 0;
...@@ -138,21 +130,19 @@ static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) ...@@ -138,21 +130,19 @@ static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode)
if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL))
rssi = IWL_MIN_RSSI_VAL; rssi = IWL_MIN_RSSI_VAL;
switch (mode) { switch (band) {
case MODE_IEEE80211G: case IEEE80211_BAND_2GHZ:
tpt_table = iwl3945_tpt_table_g; tpt_table = iwl3945_tpt_table_g;
table_size = ARRAY_SIZE(iwl3945_tpt_table_g); table_size = ARRAY_SIZE(iwl3945_tpt_table_g);
break; break;
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
tpt_table = iwl3945_tpt_table_a; tpt_table = iwl3945_tpt_table_a;
table_size = ARRAY_SIZE(iwl3945_tpt_table_a); table_size = ARRAY_SIZE(iwl3945_tpt_table_a);
break; break;
default: default:
case MODE_IEEE80211B: BUG();
tpt_table = iwl3945_tpt_table_b;
table_size = ARRAY_SIZE(iwl3945_tpt_table_b);
break; break;
} }
...@@ -340,17 +330,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -340,17 +330,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
* after assoc.. */ * after assoc.. */
for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
if (sta->supp_rates & (1 << i)) { if (sta->supp_rates[local->hw.conf.channel->band] & (1 << i)) {
sta->txrate = i; sta->txrate_idx = i;
break; break;
} }
} }
sta->last_txrate = sta->txrate; sta->last_txrate_idx = sta->txrate_idx;
/* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */ /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
if (local->hw.conf.phymode == MODE_IEEE80211A) if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
sta->last_txrate += IWL_FIRST_OFDM_RATE; sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
IWL_DEBUG_RATE("leave\n"); IWL_DEBUG_RATE("leave\n");
} }
...@@ -429,17 +419,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) ...@@ -429,17 +419,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
{ {
int next_rate = iwl3945_get_prev_ieee_rate(rate); int next_rate = iwl3945_get_prev_ieee_rate(rate);
switch (priv->phymode) { switch (priv->band) {
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
if (rate == IWL_RATE_12M_INDEX) if (rate == IWL_RATE_12M_INDEX)
next_rate = IWL_RATE_9M_INDEX; next_rate = IWL_RATE_9M_INDEX;
else if (rate == IWL_RATE_6M_INDEX) else if (rate == IWL_RATE_6M_INDEX)
next_rate = IWL_RATE_6M_INDEX; next_rate = IWL_RATE_6M_INDEX;
break; break;
/* XXX cannot be invoked in current mac80211 so not a regression
case MODE_IEEE80211B: case MODE_IEEE80211B:
if (rate == IWL_RATE_11M_INDEX_TABLE) if (rate == IWL_RATE_11M_INDEX_TABLE)
next_rate = IWL_RATE_5M_INDEX_TABLE; next_rate = IWL_RATE_5M_INDEX_TABLE;
break; break;
*/
default: default:
break; break;
} }
...@@ -465,15 +457,17 @@ static void rs_tx_status(void *priv_rate, ...@@ -465,15 +457,17 @@ static void rs_tx_status(void *priv_rate,
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct iwl3945_rs_sta *rs_sta; struct iwl3945_rs_sta *rs_sta;
struct ieee80211_supported_band *sband;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
IWL_DEBUG_RATE("enter\n"); IWL_DEBUG_RATE("enter\n");
retries = tx_resp->retry_count; retries = tx_resp->retry_count;
first_index = tx_resp->control.tx_rate; first_index = &sband->bitrates[0] - tx_resp->control.tx_rate;
if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
IWL_DEBUG_RATE("leave: Rate out of bounds: %0x for %d\n", IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index);
tx_resp->control.tx_rate, first_index);
return; return;
} }
...@@ -561,14 +555,14 @@ static void rs_tx_status(void *priv_rate, ...@@ -561,14 +555,14 @@ static void rs_tx_status(void *priv_rate,
} }
static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
u8 index, u16 rate_mask, int phymode) u8 index, u16 rate_mask, enum ieee80211_band band)
{ {
u8 high = IWL_RATE_INVALID; u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID; u8 low = IWL_RATE_INVALID;
/* 802.11A walks to the next literal adjacent rate in /* 802.11A walks to the next literal adjacent rate in
* the rate table */ * the rate table */
if (unlikely(phymode == MODE_IEEE80211A)) { if (unlikely(band == IEEE80211_BAND_5GHZ)) {
int i; int i;
u32 mask; u32 mask;
...@@ -639,7 +633,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, ...@@ -639,7 +633,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
* *
*/ */
static void rs_get_rate(void *priv_rate, struct net_device *dev, static void rs_get_rate(void *priv_rate, struct net_device *dev,
struct ieee80211_hw_mode *mode, struct sk_buff *skb, struct ieee80211_supported_band *band,
struct sk_buff *skb,
struct rate_selection *sel) struct rate_selection *sel)
{ {
u8 low = IWL_RATE_INVALID; u8 low = IWL_RATE_INVALID;
...@@ -672,16 +667,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -672,16 +667,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
is_multicast_ether_addr(hdr->addr1) || is_multicast_ether_addr(hdr->addr1) ||
!sta || !sta->rate_ctrl_priv) { !sta || !sta->rate_ctrl_priv) {
IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
sel->rate = rate_lowest(local, local->oper_hw_mode, sta); sel->rate = rate_lowest(local, band, sta);
if (sta) if (sta)
sta_info_put(sta); sta_info_put(sta);
return; return;
} }
rate_mask = sta->supp_rates; rate_mask = sta->supp_rates[band->band];
index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1); index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
if (priv->phymode == (u8) MODE_IEEE80211A) if (priv->band == IEEE80211_BAND_5GHZ)
rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
rs_sta = (void *)sta->rate_ctrl_priv; rs_sta = (void *)sta->rate_ctrl_priv;
...@@ -732,7 +727,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -732,7 +727,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
current_tpt = window->average_tpt; current_tpt = window->average_tpt;
high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask,
local->hw.conf.phymode); band->band);
low = high_low & 0xff; low = high_low & 0xff;
high = (high_low >> 8) & 0xff; high = (high_low >> 8) & 0xff;
...@@ -810,11 +805,11 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -810,11 +805,11 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
out: out:
sta->last_txrate = index; sta->last_txrate_idx = index;
if (priv->phymode == (u8) MODE_IEEE80211A) if (priv->band == IEEE80211_BAND_5GHZ)
sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE; sta->txrate_idx = sta->last_txrate_idx - IWL_FIRST_OFDM_RATE;
else else
sta->txrate = sta->last_txrate; sta->txrate_idx = sta->last_txrate_idx;
sta_info_put(sta); sta_info_put(sta);
...@@ -945,8 +940,9 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) ...@@ -945,8 +940,9 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
spin_lock_irqsave(&rs_sta->lock, flags); spin_lock_irqsave(&rs_sta->lock, flags);
rs_sta->tgg = 0; rs_sta->tgg = 0;
switch (priv->phymode) { switch (priv->band) {
case MODE_IEEE80211G: case IEEE80211_BAND_2GHZ:
/* TODO: this always does G, not a regression */
if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
rs_sta->tgg = 1; rs_sta->tgg = 1;
rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
...@@ -954,14 +950,11 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) ...@@ -954,14 +950,11 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rs_sta->expected_tpt = iwl3945_expected_tpt_g; rs_sta->expected_tpt = iwl3945_expected_tpt_g;
break; break;
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
rs_sta->expected_tpt = iwl3945_expected_tpt_a; rs_sta->expected_tpt = iwl3945_expected_tpt_a;
break; break;
case IEEE80211_NUM_BANDS:
default: BUG();
IWL_WARNING("Invalid phymode. Defaulting to 802.11b\n");
case MODE_IEEE80211B:
rs_sta->expected_tpt = iwl3945_expected_tpt_b;
break; break;
} }
...@@ -974,8 +967,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) ...@@ -974,8 +967,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi);
rs_sta->start_rate = rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band);
iwl3945_get_rate_index_by_rssi(rssi, priv->phymode);
IWL_DEBUG_RATE("leave: rssi %d assign rate index: " IWL_DEBUG_RATE("leave: rssi %d assign rate index: "
"%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate,
......
...@@ -247,7 +247,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, ...@@ -247,7 +247,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
* the information provided in the skb from the hardware */ * the information provided in the skb from the hardware */
s8 signal = stats->ssi; s8 signal = stats->ssi;
s8 noise = 0; s8 noise = 0;
int rate = stats->rate; int rate = stats->rate_idx;
u64 tsf = stats->mactime; u64 tsf = stats->mactime;
__le16 phy_flags_hw = rx_hdr->phy_flags; __le16 phy_flags_hw = rx_hdr->phy_flags;
...@@ -315,7 +315,6 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, ...@@ -315,7 +315,6 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
IEEE80211_CHAN_2GHZ), IEEE80211_CHAN_2GHZ),
&iwl3945_rt->rt_chbitmask); &iwl3945_rt->rt_chbitmask);
rate = iwl3945_rate_index_from_plcp(rate);
if (rate == -1) if (rate == -1)
iwl3945_rt->rt_rate = 0; iwl3945_rt->rt_rate = 0;
else else
...@@ -387,11 +386,10 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, ...@@ -387,11 +386,10 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
struct ieee80211_rx_status stats = { struct ieee80211_rx_status stats = {
.mactime = le64_to_cpu(rx_end->timestamp), .mactime = le64_to_cpu(rx_end->timestamp),
.freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)), .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)),
.channel = le16_to_cpu(rx_hdr->channel), .band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
.phymode = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
MODE_IEEE80211G : MODE_IEEE80211A,
.antenna = 0, .antenna = 0,
.rate = rx_hdr->rate, .rate_idx = iwl3945_rate_index_from_plcp(rx_hdr->rate),
.flag = 0, .flag = 0,
}; };
u8 network_packet; u8 network_packet;
...@@ -450,8 +448,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, ...@@ -450,8 +448,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
stats.ssi, stats.noise, stats.signal, stats.ssi, stats.noise, stats.signal,
rx_stats_sig_avg, rx_stats_noise_diff); rx_stats_sig_avg, rx_stats_noise_diff);
stats.freq = ieee80211chan2mhz(stats.channel);
/* can be covered by iwl3945_report_frame() in most cases */ /* can be covered by iwl3945_report_frame() in most cases */
/* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */
...@@ -464,8 +460,9 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, ...@@ -464,8 +460,9 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
IWL_DEBUG_STATS IWL_DEBUG_STATS
("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n",
network_packet ? '*' : ' ', network_packet ? '*' : ' ',
stats.channel, stats.ssi, stats.ssi, le16_to_cpu(rx_hdr->channel),
stats.ssi, stats.rate); stats.ssi, stats.ssi,
stats.ssi, stats.rate_idx);
if (iwl3945_debug_level & (IWL_DL_RX)) if (iwl3945_debug_level & (IWL_DL_RX))
/* Set "1" to report good data frames in groups of 100 */ /* Set "1" to report good data frames in groups of 100 */
...@@ -689,7 +686,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, ...@@ -689,7 +686,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
struct ieee80211_hdr *hdr, int sta_id, int tx_id) struct ieee80211_hdr *hdr, int sta_id, int tx_id)
{ {
unsigned long flags; unsigned long flags;
u16 rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
u16 rate_mask; u16 rate_mask;
int rate; int rate;
u8 rts_retry_limit; u8 rts_retry_limit;
...@@ -1552,14 +1549,14 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) ...@@ -1552,14 +1549,14 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
.channel = priv->active_rxon.channel, .channel = priv->active_rxon.channel,
}; };
txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1; txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
ch_info = iwl3945_get_channel_info(priv, ch_info = iwl3945_get_channel_info(priv,
priv->phymode, priv->band,
le16_to_cpu(priv->active_rxon.channel)); le16_to_cpu(priv->active_rxon.channel));
if (!ch_info) { if (!ch_info) {
IWL_ERROR IWL_ERROR
("Failed to get channel info for channel %d [%d]\n", ("Failed to get channel info for channel %d [%d]\n",
le16_to_cpu(priv->active_rxon.channel), priv->phymode); le16_to_cpu(priv->active_rxon.channel), priv->band);
return -EINVAL; return -EINVAL;
} }
...@@ -2241,8 +2238,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) ...@@ -2241,8 +2238,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
} }
switch (priv->phymode) { switch (priv->band) {
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
IWL_DEBUG_RATE("Select A mode rate scale\n"); IWL_DEBUG_RATE("Select A mode rate scale\n");
/* If one of the following CCK rates is used, /* If one of the following CCK rates is used,
* have it fall back to the 6M OFDM rate */ * have it fall back to the 6M OFDM rate */
...@@ -2257,8 +2254,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) ...@@ -2257,8 +2254,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
break; break;
case MODE_IEEE80211B: case IEEE80211_BAND_2GHZ:
IWL_DEBUG_RATE("Select B mode rate scale\n"); IWL_DEBUG_RATE("Select B/G mode rate scale\n");
/* If an OFDM rate is used, have it fall back to the /* If an OFDM rate is used, have it fall back to the
* 1M CCK rates */ * 1M CCK rates */
for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
...@@ -2269,7 +2266,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) ...@@ -2269,7 +2266,7 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
break; break;
default: default:
IWL_DEBUG_RATE("Select G mode rate scale\n"); WARN_ON(1);
break; break;
} }
......
...@@ -195,7 +195,7 @@ struct iwl3945_channel_info { ...@@ -195,7 +195,7 @@ struct iwl3945_channel_info {
u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */
u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
u8 phymode; /* MODE_IEEE80211{A,B,G} */ enum ieee80211_band band;
/* Radio/DSP gain settings for each "normal" data Tx rate. /* Radio/DSP gain settings for each "normal" data Tx rate.
* These include, in addition to RF and DSP gain, a few fields for * These include, in addition to RF and DSP gain, a few fields for
...@@ -699,14 +699,14 @@ struct iwl3945_priv { ...@@ -699,14 +699,14 @@ struct iwl3945_priv {
struct list_head free_frames; struct list_head free_frames;
int frames_count; int frames_count;
u8 phymode; enum ieee80211_band band;
int alloc_rxb_skb; int alloc_rxb_skb;
bool add_radiotap; bool add_radiotap;
void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv,
struct iwl3945_rx_mem_buffer *rxb); struct iwl3945_rx_mem_buffer *rxb);
const struct ieee80211_hw_mode *modes; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT
/* spectrum measurement report caching */ /* spectrum measurement report caching */
...@@ -937,13 +937,12 @@ static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info) ...@@ -937,13 +937,12 @@ static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info)
static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info)
{ {
return ch_info->phymode == MODE_IEEE80211A; return ch_info->band == IEEE80211_BAND_5GHZ;
} }
static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info)
{ {
return ((ch_info->phymode == MODE_IEEE80211B) || return ch_info->band == IEEE80211_BAND_2GHZ;
(ch_info->phymode == MODE_IEEE80211G));
} }
static inline int is_channel_passive(const struct iwl3945_channel_info *ch) static inline int is_channel_passive(const struct iwl3945_channel_info *ch)
...@@ -967,7 +966,7 @@ static inline int iwl3945_rate_index_from_plcp(int plcp) ...@@ -967,7 +966,7 @@ static inline int iwl3945_rate_index_from_plcp(int plcp)
} }
extern const struct iwl3945_channel_info *iwl3945_get_channel_info( extern const struct iwl3945_channel_info *iwl3945_get_channel_info(
const struct iwl3945_priv *priv, int phymode, u16 channel); const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel);
/* Requires full declaration of iwl3945_priv before including */ /* Requires full declaration of iwl3945_priv before including */
#include "iwl-3945-io.h" #include "iwl-3945-io.h"
......
...@@ -139,7 +139,7 @@ struct iwl4965_lq_sta { ...@@ -139,7 +139,7 @@ struct iwl4965_lq_sta {
u8 valid_antenna; u8 valid_antenna;
u8 is_green; u8 is_green;
u8 is_dup; u8 is_dup;
u8 phymode; enum ieee80211_band band;
u8 ibss_sta_added; u8 ibss_sta_added;
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
...@@ -563,7 +563,8 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, ...@@ -563,7 +563,8 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
* fill "search" or "active" tx mode table. * fill "search" or "active" tx mode table.
*/ */
static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
int phymode, struct iwl4965_scale_tbl_info *tbl, enum ieee80211_band band,
struct iwl4965_scale_tbl_info *tbl,
int *rate_idx) int *rate_idx)
{ {
int index; int index;
...@@ -588,7 +589,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, ...@@ -588,7 +589,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
tbl->lq_type = LQ_NONE; tbl->lq_type = LQ_NONE;
else { else {
if (phymode == MODE_IEEE80211A) if (band == IEEE80211_BAND_5GHZ)
tbl->lq_type = LQ_A; tbl->lq_type = LQ_A;
else else
tbl->lq_type = LQ_G; tbl->lq_type = LQ_G;
...@@ -766,7 +767,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, ...@@ -766,7 +767,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) {
switch_to_legacy = 1; switch_to_legacy = 1;
scale_index = rs_ht_to_legacy[scale_index]; scale_index = rs_ht_to_legacy[scale_index];
if (lq_sta->phymode == MODE_IEEE80211A) if (lq_sta->band == IEEE80211_BAND_5GHZ)
tbl->lq_type = LQ_A; tbl->lq_type = LQ_A;
else else
tbl->lq_type = LQ_G; tbl->lq_type = LQ_G;
...@@ -784,7 +785,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, ...@@ -784,7 +785,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
/* Mask with station rate restriction */ /* Mask with station rate restriction */
if (is_legacy(tbl->lq_type)) { if (is_legacy(tbl->lq_type)) {
/* supp_rates has no CCK bits in A mode */ /* supp_rates has no CCK bits in A mode */
if (lq_sta->phymode == (u8) MODE_IEEE80211A) if (lq_sta->band == IEEE80211_BAND_5GHZ)
rate_mask = (u16)(rate_mask & rate_mask = (u16)(rate_mask &
(lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
else else
...@@ -883,9 +884,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -883,9 +884,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
search_win = (struct iwl4965_rate_scale_data *) search_win = (struct iwl4965_rate_scale_data *)
&(search_tbl->win[0]); &(search_tbl->win[0]);
tx_mcs.rate_n_flags = tx_resp->control.tx_rate; tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value;
rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
&tbl_type, &rs_index); &tbl_type, &rs_index);
if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) {
IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n",
...@@ -918,7 +919,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -918,7 +919,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
* Each tx attempt steps one entry deeper in the rate table. */ * Each tx attempt steps one entry deeper in the rate table. */
tx_mcs.rate_n_flags = tx_mcs.rate_n_flags =
le32_to_cpu(table->rs_table[index].rate_n_flags); le32_to_cpu(table->rs_table[index].rate_n_flags);
rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
&tbl_type, &rs_index); &tbl_type, &rs_index);
/* If type matches "search" table, /* If type matches "search" table,
...@@ -959,12 +960,12 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, ...@@ -959,12 +960,12 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
* else look up the rate that was, finally, successful. * else look up the rate that was, finally, successful.
*/ */
if (!tx_resp->retry_count) if (!tx_resp->retry_count)
tx_mcs.rate_n_flags = tx_resp->control.tx_rate; tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value;
else else
tx_mcs.rate_n_flags = tx_mcs.rate_n_flags =
le32_to_cpu(table->rs_table[index].rate_n_flags); le32_to_cpu(table->rs_table[index].rate_n_flags);
rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
&tbl_type, &rs_index); &tbl_type, &rs_index);
/* Update frame history window with "success" if Tx got ACKed ... */ /* Update frame history window with "success" if Tx got ACKed ... */
...@@ -1801,7 +1802,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, ...@@ -1801,7 +1802,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
is_green = lq_sta->is_green; is_green = lq_sta->is_green;
/* current tx rate */ /* current tx rate */
index = sta->last_txrate; index = sta->last_txrate_idx;
IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
tbl->lq_type); tbl->lq_type);
...@@ -1814,7 +1815,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, ...@@ -1814,7 +1815,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
/* mask with station rate restriction */ /* mask with station rate restriction */
if (is_legacy(tbl->lq_type)) { if (is_legacy(tbl->lq_type)) {
if (lq_sta->phymode == (u8) MODE_IEEE80211A) if (lq_sta->band == IEEE80211_BAND_5GHZ)
/* supp_rates has no CCK bits in A mode */ /* supp_rates has no CCK bits in A mode */
rate_scale_index_msk = (u16) (rate_mask & rate_scale_index_msk = (u16) (rate_mask &
(lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE));
...@@ -2134,15 +2135,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, ...@@ -2134,15 +2135,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
out: out:
rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green);
i = index; i = index;
sta->last_txrate = i; sta->last_txrate_idx = i;
/* sta->txrate is an index to A mode rates which start /* sta->txrate_idx is an index to A mode rates which start
* at IWL_FIRST_OFDM_RATE * at IWL_FIRST_OFDM_RATE
*/ */
if (lq_sta->phymode == (u8) MODE_IEEE80211A) if (lq_sta->band == IEEE80211_BAND_5GHZ)
sta->txrate = i - IWL_FIRST_OFDM_RATE; sta->txrate_idx = i - IWL_FIRST_OFDM_RATE;
else else
sta->txrate = i; sta->txrate_idx = i;
return; return;
} }
...@@ -2164,7 +2165,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, ...@@ -2164,7 +2165,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv,
goto out; goto out;
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
i = sta->last_txrate; i = sta->last_txrate_idx;
if ((lq_sta->lq.sta_id == 0xff) && if ((lq_sta->lq.sta_id == 0xff) &&
(priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
...@@ -2188,7 +2189,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, ...@@ -2188,7 +2189,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv,
mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK;
tbl->antenna_type = ANT_AUX; tbl->antenna_type = ANT_AUX;
rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx); rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx);
if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
rs_toggle_antenna(&mcs_rate, tbl); rs_toggle_antenna(&mcs_rate, tbl);
...@@ -2202,7 +2203,8 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, ...@@ -2202,7 +2203,8 @@ static void rs_initialize_lq(struct iwl4965_priv *priv,
} }
static void rs_get_rate(void *priv_rate, struct net_device *dev, static void rs_get_rate(void *priv_rate, struct net_device *dev,
struct ieee80211_hw_mode *mode, struct sk_buff *skb, struct ieee80211_supported_band *sband,
struct sk_buff *skb,
struct rate_selection *sel) struct rate_selection *sel)
{ {
...@@ -2224,14 +2226,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -2224,14 +2226,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
fc = le16_to_cpu(hdr->frame_control); fc = le16_to_cpu(hdr->frame_control);
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
!sta || !sta->rate_ctrl_priv) { !sta || !sta->rate_ctrl_priv) {
sel->rate = rate_lowest(local, local->oper_hw_mode, sta); sel->rate = rate_lowest(local, sband, sta);
if (sta) if (sta)
sta_info_put(sta); sta_info_put(sta);
return; return;
} }
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
i = sta->last_txrate; i = sta->last_txrate_idx;
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
!lq_sta->ibss_sta_added) { !lq_sta->ibss_sta_added) {
...@@ -2256,7 +2258,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, ...@@ -2256,7 +2258,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
done: done:
if ((i < 0) || (i > IWL_RATE_COUNT)) { if ((i < 0) || (i > IWL_RATE_COUNT)) {
sel->rate = rate_lowest(local, local->oper_hw_mode, sta); sel->rate = rate_lowest(local, sband, sta);
return; return;
} }
sta_info_put(sta); sta_info_put(sta);
...@@ -2291,13 +2293,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -2291,13 +2293,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
{ {
int i, j; int i, j;
struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_conf *conf = &local->hw.conf;
struct ieee80211_hw_mode *mode = local->oper_hw_mode; struct ieee80211_supported_band *sband;
struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate;
struct iwl4965_lq_sta *lq_sta = priv_sta; struct iwl4965_lq_sta *lq_sta = priv_sta;
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
lq_sta->flush_timer = 0; lq_sta->flush_timer = 0;
lq_sta->supp_rates = sta->supp_rates; lq_sta->supp_rates = sta->supp_rates[sband->band];
sta->txrate = 3; sta->txrate_idx = 3;
for (j = 0; j < LQ_SIZE; j++) for (j = 0; j < LQ_SIZE; j++)
for (i = 0; i < IWL_RATE_COUNT; i++) for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
...@@ -2332,15 +2336,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -2332,15 +2336,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
} }
/* Find highest tx rate supported by hardware and destination station */ /* Find highest tx rate supported by hardware and destination station */
for (i = 0; i < mode->num_rates; i++) { for (i = 0; i < sband->n_bitrates; i++)
if ((sta->supp_rates & BIT(i)) && if (sta->supp_rates[sband->band] & BIT(i))
(mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) sta->txrate_idx = i;
sta->txrate = i;
} sta->last_txrate_idx = sta->txrate_idx;
sta->last_txrate = sta->txrate; /* WTF is with this bogus comment? A doesn't have cck rates */
/* For MODE_IEEE80211A, cck rates are at end of rate table */ /* For MODE_IEEE80211A, cck rates are at end of rate table */
if (local->hw.conf.phymode == MODE_IEEE80211A) if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
sta->last_txrate += IWL_FIRST_OFDM_RATE; sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_dup = 0; lq_sta->is_dup = 0;
lq_sta->valid_antenna = priv->valid_antenna; lq_sta->valid_antenna = priv->valid_antenna;
...@@ -2349,7 +2353,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -2349,7 +2353,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->active_rate = priv->active_rate; lq_sta->active_rate = priv->active_rate;
lq_sta->active_rate &= ~(0x1000); lq_sta->active_rate &= ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic; lq_sta->active_rate_basic = priv->active_rate_basic;
lq_sta->phymode = priv->phymode; lq_sta->band = priv->band;
#ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT
/* /*
* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
...@@ -2401,7 +2405,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, ...@@ -2401,7 +2405,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); rs_dbgfs_set_mcs(lq_sta, tx_mcs, index);
/* Interpret rate_n_flags */ /* Interpret rate_n_flags */
rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode, rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band,
&tbl_type, &rate_idx); &tbl_type, &rate_idx);
/* How many times should we repeat the initial rate? */ /* How many times should we repeat the initial rate? */
...@@ -2455,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, ...@@ -2455,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
index++; index++;
} }
rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type, rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type,
&rate_idx); &rate_idx);
/* Indicate to uCode which entries might be MIMO. /* Indicate to uCode which entries might be MIMO.
...@@ -2542,7 +2546,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, ...@@ -2542,7 +2546,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
{ {
u32 base_rate; u32 base_rate;
if (lq_sta->phymode == (u8) MODE_IEEE80211A) if (lq_sta->band == IEEE80211_BAND_5GHZ)
base_rate = 0x800D; base_rate = 0x800D;
else else
base_rate = 0x820A; base_rate = 0x820A;
...@@ -2802,7 +2806,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) ...@@ -2802,7 +2806,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
"active_search %d rate index %d\n", lq_type, antenna, "active_search %d rate index %d\n", lq_type, antenna,
lq_sta->search_better_tbl, sta->last_txrate); lq_sta->search_better_tbl, sta->last_txrate_idx);
sta_info_put(sta); sta_info_put(sta);
return cnt; return cnt;
......
...@@ -339,14 +339,15 @@ static int iwl4965_kw_alloc(struct iwl4965_priv *priv) ...@@ -339,14 +339,15 @@ static int iwl4965_kw_alloc(struct iwl4965_priv *priv)
* *
* Does not set up a command, or touch hardware. * Does not set up a command, or touch hardware.
*/ */
int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel, int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv,
enum ieee80211_band band, u16 channel,
const struct iwl4965_eeprom_channel *eeprom_ch, const struct iwl4965_eeprom_channel *eeprom_ch,
u8 fat_extension_channel) u8 fat_extension_channel)
{ {
struct iwl4965_channel_info *ch_info; struct iwl4965_channel_info *ch_info;
ch_info = (struct iwl4965_channel_info *) ch_info = (struct iwl4965_channel_info *)
iwl4965_get_channel_info(priv, phymode, channel); iwl4965_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info)) if (!is_channel_valid(ch_info))
return -1; return -1;
...@@ -1939,11 +1940,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, ...@@ -1939,11 +1940,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
} }
static const struct iwl4965_channel_info * static const struct iwl4965_channel_info *
iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, u8 phymode, u16 channel) iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv,
enum ieee80211_band band, u16 channel)
{ {
const struct iwl4965_channel_info *ch_info; const struct iwl4965_channel_info *ch_info;
ch_info = iwl4965_get_channel_info(priv, phymode, channel); ch_info = iwl4965_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info)) if (!is_channel_valid(ch_info))
return NULL; return NULL;
...@@ -2392,7 +2394,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 chan ...@@ -2392,7 +2394,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 chan
/* Get current (RXON) channel, band, width */ /* Get current (RXON) channel, band, width */
ch_info = ch_info =
iwl4965_get_channel_txpower_info(priv, priv->phymode, channel); iwl4965_get_channel_txpower_info(priv, priv->band, channel);
IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
is_fat); is_fat);
...@@ -2619,8 +2621,7 @@ int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv) ...@@ -2619,8 +2621,7 @@ int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv)
return -EAGAIN; return -EAGAIN;
} }
band = ((priv->phymode == MODE_IEEE80211B) || band = priv->band == IEEE80211_BAND_2GHZ;
(priv->phymode == MODE_IEEE80211G));
is_fat = is_fat_channel(priv->active_rxon.flags); is_fat = is_fat_channel(priv->active_rxon.flags);
...@@ -2650,10 +2651,9 @@ int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel) ...@@ -2650,10 +2651,9 @@ int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel)
struct iwl4965_channel_switch_cmd cmd = { 0 }; struct iwl4965_channel_switch_cmd cmd = { 0 };
const struct iwl4965_channel_info *ch_info; const struct iwl4965_channel_info *ch_info;
band = ((priv->phymode == MODE_IEEE80211B) || band = priv->band == IEEE80211_BAND_2GHZ;
(priv->phymode == MODE_IEEE80211G));
ch_info = iwl4965_get_channel_info(priv, priv->phymode, channel); ch_info = iwl4965_get_channel_info(priv, priv->band, channel);
is_fat = is_fat_channel(priv->staging_rxon.flags); is_fat = is_fat_channel(priv->staging_rxon.flags);
...@@ -2698,7 +2698,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv, ...@@ -2698,7 +2698,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv,
u16 fc = le16_to_cpu(hdr->frame_control); u16 fc = le16_to_cpu(hdr->frame_control);
u8 rate_plcp; u8 rate_plcp;
u16 rate_flags = 0; u16 rate_flags = 0;
int rate_idx = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);
rate_plcp = iwl4965_rates[rate_idx].plcp; rate_plcp = iwl4965_rates[rate_idx].plcp;
...@@ -3178,7 +3178,7 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, ...@@ -3178,7 +3178,7 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv,
{ {
s8 signal = stats->ssi; s8 signal = stats->ssi;
s8 noise = 0; s8 noise = 0;
int rate = stats->rate; int rate = stats->rate_idx;
u64 tsf = stats->mactime; u64 tsf = stats->mactime;
__le16 phy_flags_hw = rx_start->phy_flags; __le16 phy_flags_hw = rx_start->phy_flags;
struct iwl4965_rt_rx_hdr { struct iwl4965_rt_rx_hdr {
...@@ -3246,7 +3246,6 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, ...@@ -3246,7 +3246,6 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv,
IEEE80211_CHAN_2GHZ), IEEE80211_CHAN_2GHZ),
&iwl4965_rt->rt_chbitmask); &iwl4965_rt->rt_chbitmask);
rate = iwl4965_rate_index_from_plcp(rate);
if (rate == -1) if (rate == -1)
iwl4965_rt->rt_rate = 0; iwl4965_rt->rt_rate = 0;
else else
...@@ -3542,12 +3541,13 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, ...@@ -3542,12 +3541,13 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
u16 fc; u16 fc;
struct ieee80211_rx_status stats = { struct ieee80211_rx_status stats = {
.mactime = le64_to_cpu(rx_start->timestamp), .mactime = le64_to_cpu(rx_start->timestamp),
.channel = le16_to_cpu(rx_start->channel), .freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel)),
.phymode = .band =
(rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
MODE_IEEE80211G : MODE_IEEE80211A, IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
.antenna = 0, .antenna = 0,
.rate = iwl4965_hw_get_rate(rx_start->rate_n_flags), .rate_idx = iwl4965_hw_get_rate(
le32_to_cpu(rx_start->rate_n_flags)),
.flag = 0, .flag = 0,
}; };
u8 network_packet; u8 network_packet;
...@@ -3598,8 +3598,6 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, ...@@ -3598,8 +3598,6 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv,
priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
stats.freq = ieee80211chan2mhz(stats.channel);
/* Find max signal strength (dBm) among 3 antenna/receiver chains */ /* Find max signal strength (dBm) among 3 antenna/receiver chains */
stats.ssi = iwl4965_calc_rssi(rx_start); stats.ssi = iwl4965_calc_rssi(rx_start);
...@@ -4185,7 +4183,7 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) ...@@ -4185,7 +4183,7 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)
* all the way down to 1M in IEEE order, and then spin on 1M */ * all the way down to 1M in IEEE order, and then spin on 1M */
if (is_ap) if (is_ap)
r = IWL_RATE_54M_INDEX; r = IWL_RATE_54M_INDEX;
else if (priv->phymode == MODE_IEEE80211A) else if (priv->band == IEEE80211_BAND_5GHZ)
r = IWL_RATE_6M_INDEX; r = IWL_RATE_6M_INDEX;
else else
r = IWL_RATE_1M_INDEX; r = IWL_RATE_1M_INDEX;
...@@ -4218,12 +4216,13 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) ...@@ -4218,12 +4216,13 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap)
#ifdef CONFIG_IWL4965_HT #ifdef CONFIG_IWL4965_HT
static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, int phymode, static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv,
enum ieee80211_band band,
u16 channel, u8 extension_chan_offset) u16 channel, u8 extension_chan_offset)
{ {
const struct iwl4965_channel_info *ch_info; const struct iwl4965_channel_info *ch_info;
ch_info = iwl4965_get_channel_info(priv, phymode, channel); ch_info = iwl4965_get_channel_info(priv, band, channel);
if (!is_channel_valid(ch_info)) if (!is_channel_valid(ch_info))
return 0; return 0;
......
...@@ -206,7 +206,7 @@ struct iwl4965_channel_info { ...@@ -206,7 +206,7 @@ struct iwl4965_channel_info {
u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */
u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
u8 phymode; /* MODE_IEEE80211{A,B,G} */ enum ieee80211_band band;
/* Radio/DSP gain settings for each "normal" data Tx rate. /* Radio/DSP gain settings for each "normal" data Tx rate.
* These include, in addition to RF and DSP gain, a few fields for * These include, in addition to RF and DSP gain, a few fields for
...@@ -764,7 +764,8 @@ extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); ...@@ -764,7 +764,8 @@ extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode);
extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv);
extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags,
u8 force); u8 force);
extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv,
enum ieee80211_band band,
u16 channel, u16 channel,
const struct iwl4965_eeprom_channel *eeprom_ch, const struct iwl4965_eeprom_channel *eeprom_ch,
u8 fat_extension_channel); u8 fat_extension_channel);
...@@ -977,14 +978,14 @@ struct iwl4965_priv { ...@@ -977,14 +978,14 @@ struct iwl4965_priv {
struct list_head free_frames; struct list_head free_frames;
int frames_count; int frames_count;
u8 phymode; enum ieee80211_band band;
int alloc_rxb_skb; int alloc_rxb_skb;
bool add_radiotap; bool add_radiotap;
void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv,
struct iwl4965_rx_mem_buffer *rxb); struct iwl4965_rx_mem_buffer *rxb);
const struct ieee80211_hw_mode *modes; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
/* spectrum measurement report caching */ /* spectrum measurement report caching */
...@@ -1243,13 +1244,12 @@ static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info) ...@@ -1243,13 +1244,12 @@ static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info)
static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info)
{ {
return ch_info->phymode == MODE_IEEE80211A; return ch_info->band == IEEE80211_BAND_5GHZ;
} }
static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info)
{ {
return ((ch_info->phymode == MODE_IEEE80211B) || return ch_info->band == IEEE80211_BAND_2GHZ;
(ch_info->phymode == MODE_IEEE80211G));
} }
static inline int is_channel_passive(const struct iwl4965_channel_info *ch) static inline int is_channel_passive(const struct iwl4965_channel_info *ch)
...@@ -1263,7 +1263,7 @@ static inline int is_channel_ibss(const struct iwl4965_channel_info *ch) ...@@ -1263,7 +1263,7 @@ static inline int is_channel_ibss(const struct iwl4965_channel_info *ch)
} }
extern const struct iwl4965_channel_info *iwl4965_get_channel_info( extern const struct iwl4965_channel_info *iwl4965_get_channel_info(
const struct iwl4965_priv *priv, int phymode, u16 channel); const struct iwl4965_priv *priv, enum ieee80211_band band, u16 channel);
/* Requires full declaration of iwl4965_priv before including */ /* Requires full declaration of iwl4965_priv before including */
#include "iwl-4965-io.h" #include "iwl-4965-io.h"
......
...@@ -64,10 +64,6 @@ struct p54_common { ...@@ -64,10 +64,6 @@ struct p54_common {
unsigned int tx_hdr_len; unsigned int tx_hdr_len;
void *cached_vdcf; void *cached_vdcf;
unsigned int fw_var; unsigned int fw_var;
/* FIXME: this channels/modes/rates stuff sucks */
struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12];
struct ieee80211_hw_mode modes[2];
struct ieee80211_tx_queue_stats tx_stats; struct ieee80211_tx_queue_stats tx_stats;
}; };
......
...@@ -27,6 +27,46 @@ MODULE_DESCRIPTION("Softmac Prism54 common code"); ...@@ -27,6 +27,46 @@ MODULE_DESCRIPTION("Softmac Prism54 common code");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("prism54common"); MODULE_ALIAS("prism54common");
static struct ieee80211_rate p54_rates[] = {
{ .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
{ .bitrate = 60, .hw_value = 4, },
{ .bitrate = 90, .hw_value = 5, },
{ .bitrate = 120, .hw_value = 6, },
{ .bitrate = 180, .hw_value = 7, },
{ .bitrate = 240, .hw_value = 8, },
{ .bitrate = 360, .hw_value = 9, },
{ .bitrate = 480, .hw_value = 10, },
{ .bitrate = 540, .hw_value = 11, },
};
static struct ieee80211_channel p54_channels[] = {
{ .center_freq = 2412, .hw_value = 1, },
{ .center_freq = 2417, .hw_value = 2, },
{ .center_freq = 2422, .hw_value = 3, },
{ .center_freq = 2427, .hw_value = 4, },
{ .center_freq = 2432, .hw_value = 5, },
{ .center_freq = 2437, .hw_value = 6, },
{ .center_freq = 2442, .hw_value = 7, },
{ .center_freq = 2447, .hw_value = 8, },
{ .center_freq = 2452, .hw_value = 9, },
{ .center_freq = 2457, .hw_value = 10, },
{ .center_freq = 2462, .hw_value = 11, },
{ .center_freq = 2467, .hw_value = 12, },
{ .center_freq = 2472, .hw_value = 13, },
{ .center_freq = 2484, .hw_value = 14, },
};
struct ieee80211_supported_band band_2GHz = {
.channels = p54_channels,
.n_channels = ARRAY_SIZE(p54_channels),
.bitrates = p54_rates,
.n_bitrates = ARRAY_SIZE(p54_rates),
};
void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
{ {
struct p54_common *priv = dev->priv; struct p54_common *priv = dev->priv;
...@@ -308,10 +348,10 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) ...@@ -308,10 +348,10 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
u16 freq = le16_to_cpu(hdr->freq); u16 freq = le16_to_cpu(hdr->freq);
rx_status.ssi = hdr->rssi; rx_status.ssi = hdr->rssi;
rx_status.rate = hdr->rate & 0x1f; /* report short preambles & CCK too */ /* XX correct? */
rx_status.channel = freq == 2484 ? 14 : (freq - 2407)/5; rx_status.rate_idx = hdr->rate & 0xf;
rx_status.freq = freq; rx_status.freq = freq;
rx_status.phymode = MODE_IEEE80211G; rx_status.band = IEEE80211_BAND_2GHZ;
rx_status.antenna = hdr->antenna; rx_status.antenna = hdr->antenna;
rx_status.mactime = le64_to_cpu(hdr->timestamp); rx_status.mactime = le64_to_cpu(hdr->timestamp);
rx_status.flag |= RX_FLAG_TSFT; rx_status.flag |= RX_FLAG_TSFT;
...@@ -547,7 +587,9 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -547,7 +587,9 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
txhdr->padding2 = 0; txhdr->padding2 = 0;
/* TODO: add support for alternate retry TX rates */ /* TODO: add support for alternate retry TX rates */
rate = control->tx_rate; rate = control->tx_rate->hw_value;
if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE)
rate |= 0x10;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS)
rate |= 0x40; rate |= 0x40;
else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
...@@ -849,7 +891,7 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) ...@@ -849,7 +891,7 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
{ {
int ret; int ret;
ret = p54_set_freq(dev, cpu_to_le16(conf->freq)); ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
p54_set_vdcf(dev); p54_set_vdcf(dev);
return ret; return ret;
} }
...@@ -944,7 +986,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) ...@@ -944,7 +986,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
{ {
struct ieee80211_hw *dev; struct ieee80211_hw *dev;
struct p54_common *priv; struct p54_common *priv;
int i;
dev = ieee80211_alloc_hw(priv_data_len, &p54_ops); dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
if (!dev) if (!dev)
...@@ -953,18 +994,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) ...@@ -953,18 +994,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
priv = dev->priv; priv = dev->priv;
priv->mode = IEEE80211_IF_TYPE_INVALID; priv->mode = IEEE80211_IF_TYPE_INVALID;
skb_queue_head_init(&priv->tx_queue); skb_queue_head_init(&priv->tx_queue);
memcpy(priv->channels, p54_channels, sizeof(p54_channels)); dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
memcpy(priv->rates, p54_rates, sizeof(p54_rates));
priv->modes[1].mode = MODE_IEEE80211B;
priv->modes[1].num_rates = 4;
priv->modes[1].rates = priv->rates;
priv->modes[1].num_channels = ARRAY_SIZE(p54_channels);
priv->modes[1].channels = priv->channels;
priv->modes[0].mode = MODE_IEEE80211G;
priv->modes[0].num_rates = ARRAY_SIZE(p54_rates);
priv->modes[0].rates = priv->rates;
priv->modes[0].num_channels = ARRAY_SIZE(p54_channels);
priv->modes[0].channels = priv->channels;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */
IEEE80211_HW_RX_INCLUDES_FCS; IEEE80211_HW_RX_INCLUDES_FCS;
dev->channel_change_time = 1000; /* TODO: find actual value */ dev->channel_change_time = 1000; /* TODO: find actual value */
...@@ -986,14 +1016,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) ...@@ -986,14 +1016,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
p54_init_vdcf(dev); p54_init_vdcf(dev);
for (i = 0; i < 2; i++) {
if (ieee80211_register_hwmode(dev, &priv->modes[i])) {
kfree(priv->cached_vdcf);
ieee80211_free_hw(dev);
return NULL;
}
}
return dev; return dev;
} }
EXPORT_SYMBOL_GPL(p54_init_common); EXPORT_SYMBOL_GPL(p54_init_common);
......
...@@ -251,79 +251,4 @@ struct p54_tx_control_vdcf { ...@@ -251,79 +251,4 @@ struct p54_tx_control_vdcf {
__le16 frameburst; __le16 frameburst;
} __attribute__ ((packed)); } __attribute__ ((packed));
static const struct ieee80211_rate p54_rates[] = {
{ .rate = 10,
.val = 0,
.val2 = 0x10,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 20,
.val = 1,
.val2 = 0x11,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 55,
.val = 2,
.val2 = 0x12,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 110,
.val = 3,
.val2 = 0x13,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 60,
.val = 4,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 90,
.val = 5,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 120,
.val = 6,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 180,
.val = 7,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 240,
.val = 8,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 360,
.val = 9,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 480,
.val = 10,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 540,
.val = 11,
.flags = IEEE80211_RATE_OFDM },
};
// TODO: just generate this..
static const struct ieee80211_channel p54_channels[] = {
{ .chan = 1,
.freq = 2412},
{ .chan = 2,
.freq = 2417},
{ .chan = 3,
.freq = 2422},
{ .chan = 4,
.freq = 2427},
{ .chan = 5,
.freq = 2432},
{ .chan = 6,
.freq = 2437},
{ .chan = 7,
.freq = 2442},
{ .chan = 8,
.freq = 2447},
{ .chan = 9,
.freq = 2452},
{ .chan = 10,
.freq = 2457},
{ .chan = 11,
.freq = 2462},
{ .chan = 12,
.freq = 2467},
{ .chan = 13,
.freq = 2472},
{ .chan = 14,
.freq = 2484}
};
#endif /* PRISM54COMMON_H */ #endif /* PRISM54COMMON_H */
...@@ -390,6 +390,10 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) ...@@ -390,6 +390,10 @@ 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;
} }
#define HWMODE_B 0
#define HWMODE_G 1
#define HWMODE_A 2
/* /*
* 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
...@@ -644,11 +648,8 @@ struct rt2x00_dev { ...@@ -644,11 +648,8 @@ struct rt2x00_dev {
* IEEE80211 control structure. * IEEE80211 control structure.
*/ */
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct ieee80211_hw_mode *hwmodes; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
unsigned int curr_hwmode; enum ieee80211_band curr_band;
#define HWMODE_B 0
#define HWMODE_G 1
#define HWMODE_A 2
/* /*
* rfkill structure for RF state switching support. * rfkill structure for RF state switching support.
......
...@@ -152,7 +152,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -152,7 +152,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf, const int force_config) struct ieee80211_conf *conf, const int force_config)
{ {
struct rt2x00lib_conf libconf; struct rt2x00lib_conf libconf;
struct ieee80211_hw_mode *mode; struct ieee80211_supported_band *band;
struct ieee80211_rate *rate; struct ieee80211_rate *rate;
struct antenna_setup *default_ant = &rt2x00dev->default_ant; struct antenna_setup *default_ant = &rt2x00dev->default_ant;
struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; struct antenna_setup *active_ant = &rt2x00dev->link.ant.active;
...@@ -172,9 +172,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -172,9 +172,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
* Check which configuration options have been * Check which configuration options have been
* updated and should be send to the device. * updated and should be send to the device.
*/ */
if (rt2x00dev->rx_status.phymode != conf->phymode) if (rt2x00dev->rx_status.band != conf->channel->band)
flags |= CONFIG_UPDATE_PHYMODE; flags |= CONFIG_UPDATE_PHYMODE;
if (rt2x00dev->rx_status.channel != conf->channel) if (rt2x00dev->rx_status.freq != conf->channel->center_freq)
flags |= CONFIG_UPDATE_CHANNEL; flags |= CONFIG_UPDATE_CHANNEL;
if (rt2x00dev->tx_power != conf->power_level) if (rt2x00dev->tx_power != conf->power_level)
flags |= CONFIG_UPDATE_TXPOWER; flags |= CONFIG_UPDATE_TXPOWER;
...@@ -229,33 +229,31 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -229,33 +229,31 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
memset(&libconf, 0, sizeof(libconf)); memset(&libconf, 0, sizeof(libconf));
if (flags & CONFIG_UPDATE_PHYMODE) { if (flags & CONFIG_UPDATE_PHYMODE) {
switch (conf->phymode) { switch (conf->channel->band) {
case MODE_IEEE80211A: case IEEE80211_BAND_5GHZ:
libconf.phymode = HWMODE_A; libconf.phymode = HWMODE_A;
break; break;
case MODE_IEEE80211B: case IEEE80211_BAND_2GHZ:
libconf.phymode = HWMODE_B; /* Uh oh. what about B? */
break;
case MODE_IEEE80211G:
libconf.phymode = HWMODE_G; libconf.phymode = HWMODE_G;
break; break;
default: default:
ERROR(rt2x00dev, ERROR(rt2x00dev,
"Attempt to configure unsupported mode (%d)" "Attempt to configure unsupported mode (%d)"
"Defaulting to 802.11b", conf->phymode); "Defaulting to 802.11b", conf->channel->band);
libconf.phymode = HWMODE_B; libconf.phymode = HWMODE_B;
} }
mode = &rt2x00dev->hwmodes[libconf.phymode]; band = &rt2x00dev->bands[conf->channel->band];
rate = &mode->rates[mode->num_rates - 1]; rate = &band->bitrates[band->n_bitrates - 1];
libconf.basic_rates = libconf.basic_rates =
DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK; DEVICE_GET_RATE_FIELD(rate->hw_value, RATEMASK) & DEV_BASIC_RATEMASK;
} }
if (flags & CONFIG_UPDATE_CHANNEL) { if (flags & CONFIG_UPDATE_CHANNEL) {
memcpy(&libconf.rf, memcpy(&libconf.rf,
&rt2x00dev->spec.channels[conf->channel_val], &rt2x00dev->spec.channels[conf->channel->hw_value],
sizeof(libconf.rf)); sizeof(libconf.rf));
} }
...@@ -301,12 +299,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, ...@@ -301,12 +299,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
rt2x00lib_reset_link_tuner(rt2x00dev); rt2x00lib_reset_link_tuner(rt2x00dev);
if (flags & CONFIG_UPDATE_PHYMODE) { if (flags & CONFIG_UPDATE_PHYMODE) {
rt2x00dev->curr_hwmode = libconf.phymode; rt2x00dev->curr_band = conf->channel->band;
rt2x00dev->rx_status.phymode = conf->phymode; rt2x00dev->rx_status.band = conf->channel->band;
} }
rt2x00dev->rx_status.freq = conf->freq; rt2x00dev->rx_status.freq = conf->channel->center_freq;
rt2x00dev->rx_status.channel = conf->channel;
rt2x00dev->tx_power = conf->power_level; rt2x00dev->tx_power = conf->power_level;
if (flags & CONFIG_UPDATE_ANTENNA) { if (flags & CONFIG_UPDATE_ANTENNA) {
......
...@@ -550,19 +550,19 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -550,19 +550,19 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
{ {
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
struct ieee80211_hw_mode *mode; struct ieee80211_supported_band *sband;
struct ieee80211_rate *rate; struct ieee80211_rate *rate;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
unsigned int i; unsigned int i;
int val = 0; int val = 0, idx = -1;
u16 fc; u16 fc;
/* /*
* Update RX statistics. * Update RX statistics.
*/ */
mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; sband = &rt2x00dev->bands[rt2x00dev->curr_band];
for (i = 0; i < mode->num_rates; i++) { for (i = 0; i < sband->n_bitrates; i++) {
rate = &mode->rates[i]; rate = &sband->bitrates[i];
/* /*
* When frame was received with an OFDM bitrate, * When frame was received with an OFDM bitrate,
...@@ -570,12 +570,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -570,12 +570,12 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
* a CCK bitrate the signal is the rate in 0.5kbit/s. * a CCK bitrate the signal is the rate in 0.5kbit/s.
*/ */
if (!rxdesc->ofdm) if (!rxdesc->ofdm)
val = DEVICE_GET_RATE_FIELD(rate->val, RATE); val = DEVICE_GET_RATE_FIELD(rate->hw_value, RATE);
else else
val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); val = DEVICE_GET_RATE_FIELD(rate->hw_value, PLCP);
if (val == rxdesc->signal) { if (val == rxdesc->signal) {
val = rate->val; idx = i;
break; break;
} }
} }
...@@ -590,7 +590,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, ...@@ -590,7 +590,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry,
rt2x00dev->link.qual.rx_success++; rt2x00dev->link.qual.rx_success++;
rx_status->rate = val; rx_status->rate_idx = idx;
rx_status->signal = rx_status->signal =
rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi);
rx_status->ssi = rxdesc->rssi; rx_status->ssi = rxdesc->rssi;
...@@ -639,7 +639,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -639,7 +639,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
frame_control = le16_to_cpu(ieee80211hdr->frame_control); frame_control = le16_to_cpu(ieee80211hdr->frame_control);
seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl);
tx_rate = control->tx_rate; tx_rate = control->tx_rate->hw_value;
/* /*
* Check whether this frame is to be acked * Check whether this frame is to be acked
...@@ -658,7 +658,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -658,7 +658,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
} else } else
__clear_bit(ENTRY_TXD_ACK, &txdesc.flags); __clear_bit(ENTRY_TXD_ACK, &txdesc.flags);
if (control->rts_cts_rate) if (control->rts_cts_rate)
tx_rate = control->rts_cts_rate; tx_rate = control->rts_cts_rate->hw_value;
} }
/* /*
...@@ -760,54 +760,45 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry, ...@@ -760,54 +760,45 @@ static void rt2x00lib_channel(struct ieee80211_channel *entry,
const int channel, const int tx_power, const int channel, const int tx_power,
const int value) const int value)
{ {
entry->chan = channel;
if (channel <= 14) if (channel <= 14)
entry->freq = 2407 + (5 * channel); entry->center_freq = 2407 + (5 * channel);
else else
entry->freq = 5000 + (5 * channel); entry->center_freq = 5000 + (5 * channel);
entry->val = value; entry->hw_value = value;
entry->flag = entry->max_power = tx_power;
IEEE80211_CHAN_W_IBSS | entry->max_antenna_gain = 0xff;
IEEE80211_CHAN_W_ACTIVE_SCAN |
IEEE80211_CHAN_W_SCAN;
entry->power_level = tx_power;
entry->antenna_max = 0xff;
} }
static void rt2x00lib_rate(struct ieee80211_rate *entry, static void rt2x00lib_rate(struct ieee80211_rate *entry,
const int rate, const int mask, const int rate, const int mask,
const int plcp, const int flags) const int plcp, const int flags)
{ {
entry->rate = rate; entry->bitrate = rate;
entry->val = entry->hw_value =
DEVICE_SET_RATE_FIELD(rate, RATE) | DEVICE_SET_RATE_FIELD(rate, RATE) |
DEVICE_SET_RATE_FIELD(mask, RATEMASK) | DEVICE_SET_RATE_FIELD(mask, RATEMASK) |
DEVICE_SET_RATE_FIELD(plcp, PLCP); DEVICE_SET_RATE_FIELD(plcp, PLCP);
entry->flags = flags; entry->flags = flags;
entry->val2 = entry->val; entry->hw_value_short = entry->hw_value;
if (entry->flags & IEEE80211_RATE_PREAMBLE2) if (entry->flags & IEEE80211_RATE_SHORT_PREAMBLE)
entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); entry->hw_value_short |= DEVICE_SET_RATE_FIELD(1, PREAMBLE);
entry->min_rssi_ack = 0;
entry->min_rssi_ack_delta = 0;
} }
static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, 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_hw_mode *hwmodes; struct ieee80211_supported_band *sbands;
struct ieee80211_channel *channels; struct ieee80211_channel *channels;
struct ieee80211_rate *rates; struct ieee80211_rate *rates;
unsigned int i; unsigned int i;
unsigned char tx_power; unsigned char tx_power;
hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); sbands = &rt2x00dev->bands[0];
if (!hwmodes)
goto exit;
channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL);
if (!channels) if (!channels)
goto exit_free_modes; return -ENOMEM;
rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL);
if (!rates) if (!rates)
...@@ -817,31 +808,31 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, ...@@ -817,31 +808,31 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
* Initialize Rate list. * Initialize Rate list.
*/ */
rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB,
0x00, IEEE80211_RATE_CCK); 0x00, 0);
rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB,
0x01, IEEE80211_RATE_CCK_2); 0x01, IEEE80211_RATE_SHORT_PREAMBLE);
rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB,
0x02, IEEE80211_RATE_CCK_2); 0x02, IEEE80211_RATE_SHORT_PREAMBLE);
rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB,
0x03, IEEE80211_RATE_CCK_2); 0x03, IEEE80211_RATE_SHORT_PREAMBLE);
if (spec->num_rates > 4) { if (spec->num_rates > 4) {
rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB,
0x0b, IEEE80211_RATE_OFDM); 0x0b, 0);
rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB,
0x0f, IEEE80211_RATE_OFDM); 0x0f, 0);
rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB,
0x0a, IEEE80211_RATE_OFDM); 0x0a, 0);
rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB,
0x0e, IEEE80211_RATE_OFDM); 0x0e, 0);
rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB,
0x09, IEEE80211_RATE_OFDM); 0x09, 0);
rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB,
0x0d, IEEE80211_RATE_OFDM); 0x0d, 0);
rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB,
0x08, IEEE80211_RATE_OFDM); 0x08, 0);
rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB,
0x0c, IEEE80211_RATE_OFDM); 0x0c, 0);
} }
/* /*
...@@ -862,27 +853,27 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, ...@@ -862,27 +853,27 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
/* /*
* Intitialize 802.11b * Intitialize 802.11b
* Rates: CCK. * Rates: CCK.
* Channels: OFDM. * Channels: 2.4 GHz
*/ */
if (spec->num_modes > HWMODE_B) { if (spec->num_modes > HWMODE_B) {
hwmodes[HWMODE_B].mode = MODE_IEEE80211B; sbands[IEEE80211_BAND_2GHZ].n_channels = 14;
hwmodes[HWMODE_B].num_channels = 14; sbands[IEEE80211_BAND_2GHZ].n_bitrates = 4;
hwmodes[HWMODE_B].num_rates = 4; sbands[IEEE80211_BAND_2GHZ].channels = channels;
hwmodes[HWMODE_B].channels = channels; sbands[IEEE80211_BAND_2GHZ].bitrates = rates;
hwmodes[HWMODE_B].rates = rates; hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
} }
/* /*
* Intitialize 802.11g * Intitialize 802.11g
* Rates: CCK, OFDM. * Rates: CCK, OFDM.
* Channels: OFDM. * Channels: 2.4 GHz
*/ */
if (spec->num_modes > HWMODE_G) { if (spec->num_modes > HWMODE_G) {
hwmodes[HWMODE_G].mode = MODE_IEEE80211G; sbands[IEEE80211_BAND_2GHZ].n_channels = 14;
hwmodes[HWMODE_G].num_channels = 14; sbands[IEEE80211_BAND_2GHZ].n_bitrates = spec->num_rates;
hwmodes[HWMODE_G].num_rates = spec->num_rates; sbands[IEEE80211_BAND_2GHZ].channels = channels;
hwmodes[HWMODE_G].channels = channels; sbands[IEEE80211_BAND_2GHZ].bitrates = rates;
hwmodes[HWMODE_G].rates = rates; hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
} }
/* /*
...@@ -891,39 +882,17 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, ...@@ -891,39 +882,17 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
* Channels: OFDM, UNII, HiperLAN2. * Channels: OFDM, UNII, HiperLAN2.
*/ */
if (spec->num_modes > HWMODE_A) { if (spec->num_modes > HWMODE_A) {
hwmodes[HWMODE_A].mode = MODE_IEEE80211A; sbands[IEEE80211_BAND_5GHZ].n_channels = spec->num_channels - 14;
hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; sbands[IEEE80211_BAND_5GHZ].n_bitrates = spec->num_rates - 4;
hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; sbands[IEEE80211_BAND_5GHZ].channels = &channels[14];
hwmodes[HWMODE_A].channels = &channels[14]; sbands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
hwmodes[HWMODE_A].rates = &rates[4]; hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
} }
if (spec->num_modes > HWMODE_G &&
ieee80211_register_hwmode(hw, &hwmodes[HWMODE_G]))
goto exit_free_rates;
if (spec->num_modes > HWMODE_B &&
ieee80211_register_hwmode(hw, &hwmodes[HWMODE_B]))
goto exit_free_rates;
if (spec->num_modes > HWMODE_A &&
ieee80211_register_hwmode(hw, &hwmodes[HWMODE_A]))
goto exit_free_rates;
rt2x00dev->hwmodes = hwmodes;
return 0; return 0;
exit_free_rates: exit_free_channels:
kfree(rates);
exit_free_channels:
kfree(channels); kfree(channels);
exit_free_modes:
kfree(hwmodes);
exit:
ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -933,11 +902,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) ...@@ -933,11 +902,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags))
ieee80211_unregister_hw(rt2x00dev->hw); ieee80211_unregister_hw(rt2x00dev->hw);
if (likely(rt2x00dev->hwmodes)) { if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) {
kfree(rt2x00dev->hwmodes->channels); kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
kfree(rt2x00dev->hwmodes->rates); kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->bitrates);
kfree(rt2x00dev->hwmodes); rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
rt2x00dev->hwmodes = NULL; rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
} }
} }
......
...@@ -426,12 +426,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, ...@@ -426,12 +426,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_HW_DIVERSITY: case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
(rt2x00dev->curr_hwmode != HWMODE_A)); (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ));
break; break;
case ANTENNA_A: case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_hwmode == HWMODE_A) if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
else else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
...@@ -446,7 +446,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, ...@@ -446,7 +446,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_B: case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_hwmode == HWMODE_A) if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
else else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
...@@ -602,7 +602,7 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -602,7 +602,7 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i; unsigned int i;
u32 reg; u32 reg;
if (rt2x00dev->curr_hwmode == HWMODE_A) { if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a; sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
} else { } else {
...@@ -616,10 +616,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -616,10 +616,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg); rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
(rt2x00dev->curr_hwmode == HWMODE_B || rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
rt2x00dev->curr_hwmode == HWMODE_G));
rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
(rt2x00dev->curr_hwmode == HWMODE_A)); rt2x00dev->curr_band == IEEE80211_BAND_5GHZ);
rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
...@@ -698,9 +697,9 @@ static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) ...@@ -698,9 +697,9 @@ static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
(rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ);
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
(rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); rt2x00dev->rx_status.band != IEEE80211_BAND_5GHZ);
arg0 = rt2x00dev->led_reg & 0xff; arg0 = rt2x00dev->led_reg & 0xff;
arg1 = (rt2x00dev->led_reg >> 8) & 0xff; arg1 = (rt2x00dev->led_reg >> 8) & 0xff;
...@@ -798,7 +797,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) ...@@ -798,7 +797,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
/* /*
* Determine r17 bounds. * Determine r17 bounds.
*/ */
if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) {
low_bound = 0x28; low_bound = 0x28;
up_bound = 0x48; up_bound = 0x48;
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
...@@ -1544,8 +1543,10 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1544,8 +1543,10 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 2, word); rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 5, &word); rt2x00_desc_read(txd, 5, &word);
/* XXX: removed for now
rt2x00_set_field32(&word, TXD_W5_TX_POWER, rt2x00_set_field32(&word, TXD_W5_TX_POWER,
TXPOWER_TO_DEV(control->power_level)); TXPOWER_TO_DEV(control->power_level));
*/
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word); rt2x00_desc_write(txd, 5, word);
...@@ -1637,7 +1638,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) ...@@ -1637,7 +1638,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0; return 0;
} }
if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
offset += 14; offset += 14;
......
...@@ -439,13 +439,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, ...@@ -439,13 +439,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_HW_DIVERSITY: case ANTENNA_HW_DIVERSITY:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
&& (rt2x00dev->curr_hwmode != HWMODE_A); && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
break; break;
case ANTENNA_A: case ANTENNA_A:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_hwmode == HWMODE_A) if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
else else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
...@@ -460,7 +460,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, ...@@ -460,7 +460,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
case ANTENNA_B: case ANTENNA_B:
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1);
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
if (rt2x00dev->curr_hwmode == HWMODE_A) if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3);
else else
rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0);
...@@ -555,7 +555,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -555,7 +555,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
unsigned int i; unsigned int i;
u32 reg; u32 reg;
if (rt2x00dev->curr_hwmode == HWMODE_A) { if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
sel = antenna_sel_a; sel = antenna_sel_a;
lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
} else { } else {
...@@ -569,10 +569,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, ...@@ -569,10 +569,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg); rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG,
(rt2x00dev->curr_hwmode == HWMODE_B || (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ));
rt2x00dev->curr_hwmode == HWMODE_G));
rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A,
(rt2x00dev->curr_hwmode == HWMODE_A)); (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ));
rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
...@@ -644,9 +643,9 @@ static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) ...@@ -644,9 +643,9 @@ static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev)
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1);
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS,
(rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ));
rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS,
(rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); (rt2x00dev->rx_status.band != IEEE80211_BAND_5GHZ));
rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000,
rt2x00dev->led_reg, REGISTER_TIMEOUT); rt2x00dev->led_reg, REGISTER_TIMEOUT);
...@@ -736,7 +735,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) ...@@ -736,7 +735,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
/* /*
* Determine r17 bounds. * Determine r17 bounds.
*/ */
if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
low_bound = 0x28; low_bound = 0x28;
up_bound = 0x48; up_bound = 0x48;
...@@ -1278,8 +1277,10 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, ...@@ -1278,8 +1277,10 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(txd, 2, word); rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 5, &word); rt2x00_desc_read(txd, 5, &word);
/* XXX: removed for now
rt2x00_set_field32(&word, TXD_W5_TX_POWER, rt2x00_set_field32(&word, TXD_W5_TX_POWER,
TXPOWER_TO_DEV(control->power_level)); TXPOWER_TO_DEV(control->power_level));
*/
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
rt2x00_desc_write(txd, 5, word); rt2x00_desc_write(txd, 5, word);
...@@ -1370,7 +1371,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) ...@@ -1370,7 +1371,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return 0; return 0;
} }
if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) {
if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
if (lna == 3 || lna == 2) if (lna == 3 || lna == 2)
offset += 10; offset += 10;
......
...@@ -102,7 +102,7 @@ struct rtl8180_priv { ...@@ -102,7 +102,7 @@ struct rtl8180_priv {
struct rtl8180_tx_ring tx_ring[4]; struct rtl8180_tx_ring tx_ring[4];
struct ieee80211_channel channels[14]; struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12]; struct ieee80211_rate rates[12];
struct ieee80211_hw_mode modes[2]; struct ieee80211_supported_band band;
struct pci_dev *pdev; struct pci_dev *pdev;
u32 rx_conf; u32 rx_conf;
......
...@@ -49,6 +49,41 @@ static struct pci_device_id rtl8180_table[] __devinitdata = { ...@@ -49,6 +49,41 @@ static struct pci_device_id rtl8180_table[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, rtl8180_table); MODULE_DEVICE_TABLE(pci, rtl8180_table);
static const struct ieee80211_rate rtl818x_rates[] = {
{ .bitrate = 10, .hw_value = 0, },
{ .bitrate = 20, .hw_value = 1, },
{ .bitrate = 55, .hw_value = 2, },
{ .bitrate = 110, .hw_value = 3, },
{ .bitrate = 60, .hw_value = 4, },
{ .bitrate = 90, .hw_value = 5, },
{ .bitrate = 120, .hw_value = 6, },
{ .bitrate = 180, .hw_value = 7, },
{ .bitrate = 240, .hw_value = 8, },
{ .bitrate = 360, .hw_value = 9, },
{ .bitrate = 480, .hw_value = 10, },
{ .bitrate = 540, .hw_value = 11, },
};
static const struct ieee80211_channel rtl818x_channels[] = {
{ .center_freq = 2412 },
{ .center_freq = 2417 },
{ .center_freq = 2422 },
{ .center_freq = 2427 },
{ .center_freq = 2432 },
{ .center_freq = 2437 },
{ .center_freq = 2442 },
{ .center_freq = 2447 },
{ .center_freq = 2452 },
{ .center_freq = 2457 },
{ .center_freq = 2462 },
{ .center_freq = 2467 },
{ .center_freq = 2472 },
{ .center_freq = 2484 },
};
void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
...@@ -99,10 +134,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) ...@@ -99,10 +134,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
/* TODO: improve signal/rssi reporting */ /* TODO: improve signal/rssi reporting */
rx_status.signal = flags2 & 0xFF; rx_status.signal = flags2 & 0xFF;
rx_status.ssi = (flags2 >> 8) & 0x7F; rx_status.ssi = (flags2 >> 8) & 0x7F;
rx_status.rate = (flags >> 20) & 0xF; /* XXX: is this correct? */
rx_status.freq = dev->conf.freq; rx_status.rate_idx = (flags >> 20) & 0xF;
rx_status.channel = dev->conf.channel; rx_status.freq = dev->conf.channel->center_freq;
rx_status.phymode = dev->conf.phymode; rx_status.band = dev->conf.channel->band;
rx_status.mactime = le64_to_cpu(entry->tsft); rx_status.mactime = le64_to_cpu(entry->tsft);
rx_status.flag |= RX_FLAG_TSFT; rx_status.flag |= RX_FLAG_TSFT;
if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR)
...@@ -223,8 +258,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -223,8 +258,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
skb->len, PCI_DMA_TODEVICE); skb->len, PCI_DMA_TODEVICE);
tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS |
RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) | RTL8180_TX_DESC_FLAG_LS |
(control->rts_cts_rate << 19) | skb->len; (control->tx_rate->hw_value << 24) |
(control->rts_cts_rate->hw_value << 19) | skb->len;
if (priv->r8185) if (priv->r8185)
tx_flags |= RTL8180_TX_DESC_FLAG_DMA | tx_flags |= RTL8180_TX_DESC_FLAG_DMA |
...@@ -246,9 +282,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -246,9 +282,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
unsigned int remainder; unsigned int remainder;
plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
(control->rate->rate * 2) / 10); (control->tx_rate->bitrate * 2) / 10);
remainder = (16 * (skb->len + 4)) % remainder = (16 * (skb->len + 4)) %
((control->rate->rate * 2) / 10); ((control->tx_rate->bitrate * 2) / 10);
if (remainder > 0 && remainder <= 6) if (remainder > 0 && remainder <= 6)
plcp_len |= 1 << 15; plcp_len |= 1 << 15;
} }
...@@ -261,8 +297,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -261,8 +297,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
entry->plcp_len = cpu_to_le16(plcp_len); entry->plcp_len = cpu_to_le16(plcp_len);
entry->tx_buf = cpu_to_le32(mapping); entry->tx_buf = cpu_to_le32(mapping);
entry->frame_len = cpu_to_le32(skb->len); entry->frame_len = cpu_to_le32(skb->len);
entry->flags2 = control->alt_retry_rate != -1 ? entry->flags2 = control->alt_retry_rate != NULL ?
control->alt_retry_rate << 4 : 0; control->alt_retry_rate->bitrate << 4 : 0;
entry->retry_limit = control->retry_limit; entry->retry_limit = control->retry_limit;
entry->flags = cpu_to_le32(tx_flags); entry->flags = cpu_to_le32(tx_flags);
__skb_queue_tail(&ring->queue, skb); __skb_queue_tail(&ring->queue, skb);
...@@ -838,19 +874,19 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, ...@@ -838,19 +874,19 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
goto err_free_dev; goto err_free_dev;
} }
BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
priv->modes[0].mode = MODE_IEEE80211G;
priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); priv->band.band = IEEE80211_BAND_2GHZ;
priv->modes[0].rates = priv->rates; priv->band.channels = priv->channels;
priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
priv->modes[0].channels = priv->channels; priv->band.bitrates = priv->rates;
priv->modes[1].mode = MODE_IEEE80211B; priv->band.n_bitrates = 4;
priv->modes[1].num_rates = 4; dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
priv->modes[1].rates = priv->rates;
priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
priv->modes[1].channels = priv->channels;
priv->mode = IEEE80211_IF_TYPE_INVALID;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_RX_INCLUDES_FCS; IEEE80211_HW_RX_INCLUDES_FCS;
dev->queues = 1; dev->queues = 1;
...@@ -879,15 +915,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, ...@@ -879,15 +915,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
if (priv->r8185) { if (priv->r8185) {
if ((err = ieee80211_register_hwmode(dev, &priv->modes[0]))) priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
goto err_iounmap;
pci_try_set_mwi(pdev); pci_try_set_mwi(pdev);
} }
if ((err = ieee80211_register_hwmode(dev, &priv->modes[1])))
goto err_iounmap;
eeprom.data = dev; eeprom.data = dev;
eeprom.register_read = rtl8180_eeprom_register_read; eeprom.register_read = rtl8180_eeprom_register_read;
eeprom.register_write = rtl8180_eeprom_register_write; eeprom.register_write = rtl8180_eeprom_register_write;
...@@ -950,8 +981,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, ...@@ -950,8 +981,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
for (i = 0; i < 14; i += 2) { for (i = 0; i < 14; i += 2) {
u16 txpwr; u16 txpwr;
eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr);
priv->channels[i].val = txpwr & 0xFF; priv->channels[i].hw_value = txpwr & 0xFF;
priv->channels[i + 1].val = txpwr >> 8; priv->channels[i + 1].hw_value = txpwr >> 8;
} }
/* OFDM TX power */ /* OFDM TX power */
...@@ -959,8 +990,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, ...@@ -959,8 +990,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
for (i = 0; i < 14; i += 2) { for (i = 0; i < 14; i += 2) {
u16 txpwr; u16 txpwr;
eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
priv->channels[i].val |= (txpwr & 0xFF) << 8; priv->channels[i].hw_value |= (txpwr & 0xFF) << 8;
priv->channels[i + 1].val |= txpwr & 0xFF00; priv->channels[i + 1].hw_value |= txpwr & 0xFF00;
} }
} }
......
...@@ -73,8 +73,9 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, ...@@ -73,8 +73,9 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
u32 chan = conf->channel - 1; u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
u32 chan = channel - 1;
/* set TX power */ /* set TX power */
write_grf5101(dev, 0x15, 0x0); write_grf5101(dev, 0x15, 0x0);
......
...@@ -78,8 +78,9 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, ...@@ -78,8 +78,9 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
unsigned int chan_idx = conf ? conf->channel - 1 : 0; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
u32 txpw = priv->channels[chan_idx].val & 0xFF; unsigned int chan_idx = channel - 1;
u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
u32 chan = max2820_chan[chan_idx]; u32 chan = max2820_chan[chan_idx];
/* While philips SA2400 drive the PA bias from /* While philips SA2400 drive the PA bias from
......
...@@ -261,8 +261,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ...@@ -261,8 +261,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg; u32 reg;
int i; int i;
cck_power = priv->channels[channel - 1].val & 0xFF; cck_power = priv->channels[channel - 1].hw_value & 0xFF;
ofdm_power = priv->channels[channel - 1].val >> 8; ofdm_power = priv->channels[channel - 1].hw_value >> 8;
cck_power = min(cck_power, (u8)35); cck_power = min(cck_power, (u8)35);
ofdm_power = min(ofdm_power, (u8)35); ofdm_power = min(ofdm_power, (u8)35);
...@@ -476,8 +476,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ...@@ -476,8 +476,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
const u8 *tmp; const u8 *tmp;
int i; int i;
cck_power = priv->channels[channel - 1].val & 0xFF; cck_power = priv->channels[channel - 1].hw_value & 0xFF;
ofdm_power = priv->channels[channel - 1].val >> 8; ofdm_power = priv->channels[channel - 1].hw_value >> 8;
if (channel == 14) if (channel == 14)
tmp = rtl8225z2_tx_power_cck_ch14; tmp = rtl8225z2_tx_power_cck_ch14;
...@@ -716,13 +716,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, ...@@ -716,13 +716,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
if (priv->rf->init == rtl8225_rf_init) if (priv->rf->init == rtl8225_rf_init)
rtl8225_rf_set_tx_power(dev, conf->channel); rtl8225_rf_set_tx_power(dev, chan);
else else
rtl8225z2_rf_set_tx_power(dev, conf->channel); rtl8225z2_rf_set_tx_power(dev, chan);
rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
msleep(10); msleep(10);
if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) {
......
...@@ -80,8 +80,9 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, ...@@ -80,8 +80,9 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
u32 chan = sa2400_chan[conf->channel - 1]; u32 txpw = priv->channels[channel - 1].hw_value & 0xFF;
u32 chan = sa2400_chan[channel - 1];
write_sa2400(dev, 7, txpw); write_sa2400(dev, 7, txpw);
......
...@@ -71,7 +71,7 @@ struct rtl8187_priv { ...@@ -71,7 +71,7 @@ struct rtl8187_priv {
/* rtl8187 specific */ /* rtl8187 specific */
struct ieee80211_channel channels[14]; struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12]; struct ieee80211_rate rates[12];
struct ieee80211_hw_mode modes[2]; struct ieee80211_supported_band band;
struct usb_device *udev; struct usb_device *udev;
u32 rx_conf; u32 rx_conf;
u16 txpwr_base; u16 txpwr_base;
......
...@@ -45,6 +45,38 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { ...@@ -45,6 +45,38 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
MODULE_DEVICE_TABLE(usb, rtl8187_table); MODULE_DEVICE_TABLE(usb, rtl8187_table);
static const struct ieee80211_rate rtl818x_rates[] = {
{ .bitrate = 10, .hw_value = 0, },
{ .bitrate = 20, .hw_value = 1, },
{ .bitrate = 55, .hw_value = 2, },
{ .bitrate = 110, .hw_value = 3, },
{ .bitrate = 60, .hw_value = 4, },
{ .bitrate = 90, .hw_value = 5, },
{ .bitrate = 120, .hw_value = 6, },
{ .bitrate = 180, .hw_value = 7, },
{ .bitrate = 240, .hw_value = 8, },
{ .bitrate = 360, .hw_value = 9, },
{ .bitrate = 480, .hw_value = 10, },
{ .bitrate = 540, .hw_value = 11, },
};
static const struct ieee80211_channel rtl818x_channels[] = {
{ .center_freq = 2412 },
{ .center_freq = 2417 },
{ .center_freq = 2422 },
{ .center_freq = 2427 },
{ .center_freq = 2432 },
{ .center_freq = 2437 },
{ .center_freq = 2442 },
{ .center_freq = 2447 },
{ .center_freq = 2452 },
{ .center_freq = 2457 },
{ .center_freq = 2462 },
{ .center_freq = 2467 },
{ .center_freq = 2472 },
{ .center_freq = 2484 },
};
static void rtl8187_iowrite_async_cb(struct urb *urb) static void rtl8187_iowrite_async_cb(struct urb *urb)
{ {
kfree(urb->context); kfree(urb->context);
...@@ -146,8 +178,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, ...@@ -146,8 +178,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
flags = skb->len; flags = skb->len;
flags |= RTL8187_TX_FLAG_NO_ENCRYPT; flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
flags |= control->rts_cts_rate << 19; flags |= control->rts_cts_rate->hw_value << 19;
flags |= control->tx_rate << 24; flags |= control->tx_rate->hw_value << 24;
if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
flags |= RTL8187_TX_FLAG_MORE_FRAG; flags |= RTL8187_TX_FLAG_MORE_FRAG;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
...@@ -225,10 +257,9 @@ static void rtl8187_rx_cb(struct urb *urb) ...@@ -225,10 +257,9 @@ static void rtl8187_rx_cb(struct urb *urb)
rx_status.antenna = (hdr->signal >> 7) & 1; rx_status.antenna = (hdr->signal >> 7) & 1;
rx_status.signal = 64 - min(hdr->noise, (u8)64); rx_status.signal = 64 - min(hdr->noise, (u8)64);
rx_status.ssi = signal; rx_status.ssi = signal;
rx_status.rate = rate; rx_status.rate_idx = rate;
rx_status.freq = dev->conf.freq; rx_status.freq = dev->conf.channel->center_freq;
rx_status.channel = dev->conf.channel; rx_status.band = dev->conf.channel->band;
rx_status.phymode = dev->conf.phymode;
rx_status.mactime = le64_to_cpu(hdr->mac_time); rx_status.mactime = le64_to_cpu(hdr->mac_time);
rx_status.flag |= RX_FLAG_TSFT; rx_status.flag |= RX_FLAG_TSFT;
if (flags & (1 << 13)) if (flags & (1 << 13))
...@@ -682,19 +713,22 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, ...@@ -682,19 +713,22 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
usb_get_dev(udev); usb_get_dev(udev);
skb_queue_head_init(&priv->rx_queue); skb_queue_head_init(&priv->rx_queue);
BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
priv->map = (struct rtl818x_csr *)0xFF00; priv->map = (struct rtl818x_csr *)0xFF00;
priv->modes[0].mode = MODE_IEEE80211G;
priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); priv->band.band = IEEE80211_BAND_2GHZ;
priv->modes[0].rates = priv->rates; priv->band.channels = priv->channels;
priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
priv->modes[0].channels = priv->channels; priv->band.bitrates = priv->rates;
priv->modes[1].mode = MODE_IEEE80211B; priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
priv->modes[1].num_rates = 4; dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
priv->modes[1].rates = priv->rates;
priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels);
priv->modes[1].channels = priv->channels;
priv->mode = IEEE80211_IF_TYPE_MNTR; priv->mode = IEEE80211_IF_TYPE_MNTR;
dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
IEEE80211_HW_RX_INCLUDES_FCS; IEEE80211_HW_RX_INCLUDES_FCS;
...@@ -703,10 +737,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, ...@@ -703,10 +737,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
dev->max_rssi = 65; dev->max_rssi = 65;
dev->max_signal = 64; dev->max_signal = 64;
for (i = 0; i < 2; i++)
if ((err = ieee80211_register_hwmode(dev, &priv->modes[i])))
goto err_free_dev;
eeprom.data = dev; eeprom.data = dev;
eeprom.register_read = rtl8187_eeprom_register_read; eeprom.register_read = rtl8187_eeprom_register_read;
eeprom.register_write = rtl8187_eeprom_register_write; eeprom.register_write = rtl8187_eeprom_register_write;
...@@ -730,20 +760,20 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, ...@@ -730,20 +760,20 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
&txpwr); &txpwr);
(*channel++).val = txpwr & 0xFF; (*channel++).hw_value = txpwr & 0xFF;
(*channel++).val = txpwr >> 8; (*channel++).hw_value = txpwr >> 8;
} }
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
&txpwr); &txpwr);
(*channel++).val = txpwr & 0xFF; (*channel++).hw_value = txpwr & 0xFF;
(*channel++).val = txpwr >> 8; (*channel++).hw_value = txpwr >> 8;
} }
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i,
&txpwr); &txpwr);
(*channel++).val = txpwr & 0xFF; (*channel++).hw_value = txpwr & 0xFF;
(*channel++).val = txpwr >> 8; (*channel++).hw_value = txpwr >> 8;
} }
eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE,
......
...@@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ...@@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg; u32 reg;
int i; int i;
cck_power = priv->channels[channel - 1].val & 0xF; cck_power = priv->channels[channel - 1].hw_value & 0xF;
ofdm_power = priv->channels[channel - 1].val >> 4; ofdm_power = priv->channels[channel - 1].hw_value >> 4;
cck_power = min(cck_power, (u8)11); cck_power = min(cck_power, (u8)11);
ofdm_power = min(ofdm_power, (u8)35); ofdm_power = min(ofdm_power, (u8)35);
...@@ -500,8 +500,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ...@@ -500,8 +500,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
u32 reg; u32 reg;
int i; int i;
cck_power = priv->channels[channel - 1].val & 0xF; cck_power = priv->channels[channel - 1].hw_value & 0xF;
ofdm_power = priv->channels[channel - 1].val >> 4; ofdm_power = priv->channels[channel - 1].hw_value >> 4;
cck_power = min(cck_power, (u8)15); cck_power = min(cck_power, (u8)15);
cck_power += priv->txpwr_base & 0xF; cck_power += priv->txpwr_base & 0xF;
...@@ -735,13 +735,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, ...@@ -735,13 +735,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
struct rtl8187_priv *priv = dev->priv; struct rtl8187_priv *priv = dev->priv;
int chan = ieee80211_frequency_to_channel(conf->channel->center_freq);
if (priv->rf->init == rtl8225_rf_init) if (priv->rf->init == rtl8225_rf_init)
rtl8225_rf_set_tx_power(dev, conf->channel); rtl8225_rf_set_tx_power(dev, chan);
else else
rtl8225z2_rf_set_tx_power(dev, conf->channel); rtl8225z2_rf_set_tx_power(dev, chan);
rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
msleep(10); msleep(10);
} }
......
...@@ -175,74 +175,4 @@ struct rtl818x_rf_ops { ...@@ -175,74 +175,4 @@ struct rtl818x_rf_ops {
void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
}; };
static const struct ieee80211_rate rtl818x_rates[] = {
{ .rate = 10,
.val = 0,
.flags = IEEE80211_RATE_CCK },
{ .rate = 20,
.val = 1,
.flags = IEEE80211_RATE_CCK },
{ .rate = 55,
.val = 2,
.flags = IEEE80211_RATE_CCK },
{ .rate = 110,
.val = 3,
.flags = IEEE80211_RATE_CCK },
{ .rate = 60,
.val = 4,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 90,
.val = 5,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 120,
.val = 6,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 180,
.val = 7,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 240,
.val = 8,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 360,
.val = 9,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 480,
.val = 10,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 540,
.val = 11,
.flags = IEEE80211_RATE_OFDM },
};
static const struct ieee80211_channel rtl818x_channels[] = {
{ .chan = 1,
.freq = 2412},
{ .chan = 2,
.freq = 2417},
{ .chan = 3,
.freq = 2422},
{ .chan = 4,
.freq = 2427},
{ .chan = 5,
.freq = 2432},
{ .chan = 6,
.freq = 2437},
{ .chan = 7,
.freq = 2442},
{ .chan = 8,
.freq = 2447},
{ .chan = 9,
.freq = 2452},
{ .chan = 10,
.freq = 2457},
{ .chan = 11,
.freq = 2462},
{ .chan = 12,
.freq = 2467},
{ .chan = 13,
.freq = 2472},
{ .chan = 14,
.freq = 2484}
};
#endif /* RTL818X_H */ #endif /* RTL818X_H */
...@@ -986,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip) ...@@ -986,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip)
return 0; return 0;
} }
static int set_mandatory_rates(struct zd_chip *chip, int mode) static int set_mandatory_rates(struct zd_chip *chip, int gmode)
{ {
u32 rates; u32 rates;
ZD_ASSERT(mutex_is_locked(&chip->mutex)); ZD_ASSERT(mutex_is_locked(&chip->mutex));
...@@ -994,17 +994,12 @@ static int set_mandatory_rates(struct zd_chip *chip, int mode) ...@@ -994,17 +994,12 @@ static int set_mandatory_rates(struct zd_chip *chip, int mode)
* that the device is supporting. Until further notice we should try * that the device is supporting. Until further notice we should try
* to support 802.11g also for full speed USB. * to support 802.11g also for full speed USB.
*/ */
switch (mode) { if (!gmode)
case MODE_IEEE80211B:
rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
break; else
case MODE_IEEE80211G:
rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
break;
default:
return -EINVAL;
}
return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
} }
...@@ -1108,7 +1103,7 @@ int zd_chip_init_hw(struct zd_chip *chip) ...@@ -1108,7 +1103,7 @@ int zd_chip_init_hw(struct zd_chip *chip)
* It might be discussed, whether we should suppport pure b mode for * It might be discussed, whether we should suppport pure b mode for
* full speed USB. * full speed USB.
*/ */
r = set_mandatory_rates(chip, MODE_IEEE80211G); r = set_mandatory_rates(chip, 1);
if (r) if (r)
goto out; goto out;
/* Disabling interrupts is certainly a smart thing here. /* Disabling interrupts is certainly a smart thing here.
......
...@@ -65,16 +65,14 @@ static const struct channel_range *zd_channel_range(u8 regdomain) ...@@ -65,16 +65,14 @@ static const struct channel_range *zd_channel_range(u8 regdomain)
static void unmask_bg_channels(struct ieee80211_hw *hw, static void unmask_bg_channels(struct ieee80211_hw *hw,
const struct channel_range *range, const struct channel_range *range,
struct ieee80211_hw_mode *mode) struct ieee80211_supported_band *sband)
{ {
u8 channel; u8 channel;
for (channel = range->start; channel < range->end; channel++) { for (channel = range->start; channel < range->end; channel++) {
struct ieee80211_channel *chan = struct ieee80211_channel *chan =
&mode->channels[CHAN_TO_IDX(channel)]; &sband->channels[CHAN_TO_IDX(channel)];
chan->flag |= IEEE80211_CHAN_W_SCAN | chan->flags = 0;
IEEE80211_CHAN_W_ACTIVE_SCAN |
IEEE80211_CHAN_W_IBSS;
} }
} }
...@@ -97,7 +95,6 @@ void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain) ...@@ -97,7 +95,6 @@ void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain)
range = zd_channel_range(ZD_REGDOMAIN_FCC); range = zd_channel_range(ZD_REGDOMAIN_FCC);
} }
unmask_bg_channels(hw, range, &mac->modes[0]); unmask_bg_channels(hw, range, &mac->band);
unmask_bg_channels(hw, range, &mac->modes[1]);
} }
...@@ -185,7 +185,7 @@ struct zd_mac { ...@@ -185,7 +185,7 @@ struct zd_mac {
struct sk_buff_head ack_wait_queue; struct sk_buff_head ack_wait_queue;
struct ieee80211_channel channels[14]; struct ieee80211_channel channels[14];
struct ieee80211_rate rates[12]; struct ieee80211_rate rates[12];
struct ieee80211_hw_mode modes[2]; struct ieee80211_supported_band band;
/* Short preamble (used for RTS/CTS) */ /* Short preamble (used for RTS/CTS) */
unsigned int short_preamble:1; unsigned int short_preamble:1;
......
此差异已折叠。
此差异已折叠。
...@@ -19,7 +19,6 @@ mac80211-y := \ ...@@ -19,7 +19,6 @@ mac80211-y := \
ieee80211_iface.o \ ieee80211_iface.o \
ieee80211_rate.o \ ieee80211_rate.o \
michael.o \ michael.o \
regdomain.o \
tkip.o \ tkip.o \
aes_ccm.o \ aes_ccm.o \
cfg.o \ cfg.o \
......
...@@ -498,7 +498,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, ...@@ -498,7 +498,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
{ {
u32 rates; u32 rates;
int i, j; int i, j;
struct ieee80211_hw_mode *mode; struct ieee80211_supported_band *sband;
if (params->station_flags & STATION_FLAG_CHANGED) { if (params->station_flags & STATION_FLAG_CHANGED) {
sta->flags &= ~WLAN_STA_AUTHORIZED; sta->flags &= ~WLAN_STA_AUTHORIZED;
...@@ -525,15 +525,16 @@ static void sta_apply_parameters(struct ieee80211_local *local, ...@@ -525,15 +525,16 @@ static void sta_apply_parameters(struct ieee80211_local *local,
if (params->supported_rates) { if (params->supported_rates) {
rates = 0; rates = 0;
mode = local->oper_hw_mode; sband = local->hw.wiphy->bands[local->oper_channel->band];
for (i = 0; i < params->supported_rates_len; i++) { for (i = 0; i < params->supported_rates_len; i++) {
int rate = (params->supported_rates[i] & 0x7f) * 5; int rate = (params->supported_rates[i] & 0x7f) * 5;
for (j = 0; j < mode->num_rates; j++) { for (j = 0; j < sband->n_bitrates; j++) {
if (mode->rates[j].rate == rate) if (sband->bitrates[j].bitrate == rate)
rates |= BIT(j); rates |= BIT(j);
} }
} }
sta->supp_rates = rates; sta->supp_rates[local->oper_channel->band] = rates;
} }
} }
......
...@@ -19,41 +19,6 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file) ...@@ -19,41 +19,6 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file)
return 0; return 0;
} }
static const char *ieee80211_mode_str(int mode)
{
switch (mode) {
case MODE_IEEE80211A:
return "IEEE 802.11a";
case MODE_IEEE80211B:
return "IEEE 802.11b";
case MODE_IEEE80211G:
return "IEEE 802.11g";
default:
return "UNKNOWN";
}
}
static ssize_t modes_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
struct ieee80211_local *local = file->private_data;
struct ieee80211_hw_mode *mode;
char buf[150], *p = buf;
/* FIXME: locking! */
list_for_each_entry(mode, &local->modes_list, list) {
p += scnprintf(p, sizeof(buf)+buf-p,
"%s\n", ieee80211_mode_str(mode->mode));
}
return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf);
}
static const struct file_operations modes_ops = {
.read = modes_read,
.open = mac80211_open_file_generic,
};
#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \
static ssize_t name## _read(struct file *file, char __user *userbuf, \ static ssize_t name## _read(struct file *file, char __user *userbuf, \
size_t count, loff_t *ppos) \ size_t count, loff_t *ppos) \
...@@ -80,10 +45,8 @@ static const struct file_operations name## _ops = { \ ...@@ -80,10 +45,8 @@ static const struct file_operations name## _ops = { \
local->debugfs.name = NULL; local->debugfs.name = NULL;
DEBUGFS_READONLY_FILE(channel, 20, "%d",
local->hw.conf.channel);
DEBUGFS_READONLY_FILE(frequency, 20, "%d", DEBUGFS_READONLY_FILE(frequency, 20, "%d",
local->hw.conf.freq); local->hw.conf.channel->center_freq);
DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d",
local->hw.conf.antenna_sel_tx); local->hw.conf.antenna_sel_tx);
DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d",
...@@ -100,8 +63,6 @@ DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", ...@@ -100,8 +63,6 @@ DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
local->long_retry_limit); local->long_retry_limit);
DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
local->total_ps_buffered); local->total_ps_buffered);
DEBUGFS_READONLY_FILE(mode, 20, "%s",
ieee80211_mode_str(local->hw.conf.phymode));
DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x",
local->wep_iv & 0xffffff); local->wep_iv & 0xffffff);
DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s",
...@@ -294,7 +255,6 @@ void debugfs_hw_add(struct ieee80211_local *local) ...@@ -294,7 +255,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
local->debugfs.stations = debugfs_create_dir("stations", phyd); local->debugfs.stations = debugfs_create_dir("stations", phyd);
local->debugfs.keys = debugfs_create_dir("keys", phyd); local->debugfs.keys = debugfs_create_dir("keys", phyd);
DEBUGFS_ADD(channel);
DEBUGFS_ADD(frequency); DEBUGFS_ADD(frequency);
DEBUGFS_ADD(antenna_sel_tx); DEBUGFS_ADD(antenna_sel_tx);
DEBUGFS_ADD(antenna_sel_rx); DEBUGFS_ADD(antenna_sel_rx);
...@@ -304,9 +264,7 @@ void debugfs_hw_add(struct ieee80211_local *local) ...@@ -304,9 +264,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD(short_retry_limit); DEBUGFS_ADD(short_retry_limit);
DEBUGFS_ADD(long_retry_limit); DEBUGFS_ADD(long_retry_limit);
DEBUGFS_ADD(total_ps_buffered); DEBUGFS_ADD(total_ps_buffered);
DEBUGFS_ADD(mode);
DEBUGFS_ADD(wep_iv); DEBUGFS_ADD(wep_iv);
DEBUGFS_ADD(modes);
statsd = debugfs_create_dir("statistics", phyd); statsd = debugfs_create_dir("statistics", phyd);
local->debugfs.statistics = statsd; local->debugfs.statistics = statsd;
...@@ -356,7 +314,6 @@ void debugfs_hw_add(struct ieee80211_local *local) ...@@ -356,7 +314,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
void debugfs_hw_del(struct ieee80211_local *local) void debugfs_hw_del(struct ieee80211_local *local)
{ {
DEBUGFS_DEL(channel);
DEBUGFS_DEL(frequency); DEBUGFS_DEL(frequency);
DEBUGFS_DEL(antenna_sel_tx); DEBUGFS_DEL(antenna_sel_tx);
DEBUGFS_DEL(antenna_sel_rx); DEBUGFS_DEL(antenna_sel_rx);
...@@ -366,9 +323,7 @@ void debugfs_hw_del(struct ieee80211_local *local) ...@@ -366,9 +323,7 @@ void debugfs_hw_del(struct ieee80211_local *local)
DEBUGFS_DEL(short_retry_limit); DEBUGFS_DEL(short_retry_limit);
DEBUGFS_DEL(long_retry_limit); DEBUGFS_DEL(long_retry_limit);
DEBUGFS_DEL(total_ps_buffered); DEBUGFS_DEL(total_ps_buffered);
DEBUGFS_DEL(mode);
DEBUGFS_DEL(wep_iv); DEBUGFS_DEL(wep_iv);
DEBUGFS_DEL(modes);
DEBUGFS_STATS_DEL(transmitted_fragment_count); DEBUGFS_STATS_DEL(transmitted_fragment_count);
DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -118,6 +118,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type) ...@@ -118,6 +118,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
sdata->bss = NULL; sdata->bss = NULL;
sdata->vif.type = type; sdata->vif.type = type;
sdata->basic_rates = 0;
switch (type) { switch (type) {
case IEEE80211_IF_TYPE_WDS: case IEEE80211_IF_TYPE_WDS:
/* nothing special */ /* nothing special */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
obj-$(CONFIG_WIRELESS_EXT) += wext.o obj-$(CONFIG_WIRELESS_EXT) += wext.o
obj-$(CONFIG_CFG80211) += cfg80211.o obj-$(CONFIG_CFG80211) += cfg80211.o
cfg80211-y += core.o sysfs.o radiotap.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
cfg80211-$(CONFIG_NL80211) += nl80211.o cfg80211-$(CONFIG_NL80211) += nl80211.o
此差异已折叠。
...@@ -78,4 +78,7 @@ extern void cfg80211_dev_free(struct cfg80211_registered_device *drv); ...@@ -78,4 +78,7 @@ extern void cfg80211_dev_free(struct cfg80211_registered_device *drv);
extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
char *newname); char *newname);
void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
void wiphy_update_regulatory(struct wiphy *wiphy);
#endif /* __NET_WIRELESS_CORE_H */ #endif /* __NET_WIRELESS_CORE_H */
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册