diff options
147 files changed, 10637 insertions, 8305 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 714a6ca30ad2..3c3ef966c95b 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -146,12 +146,15 @@ config IPW2100 | |||
146 | configure your card: | 146 | configure your card: |
147 | 147 | ||
148 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | 148 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. |
149 | |||
150 | It is recommended that you compile this driver as a module (M) | ||
151 | rather than built-in (Y). This driver requires firmware at device | ||
152 | initialization time, and when built-in this typically happens | ||
153 | before the filesystem is accessible (hence firmware will be | ||
154 | unavailable and initialization will fail). If you do choose to build | ||
155 | this driver into your kernel image, you can avoid this problem by | ||
156 | including the firmware and a firmware loader in an initramfs. | ||
149 | 157 | ||
150 | If you want to compile the driver as a module ( = code which can be | ||
151 | inserted in and removed from the running kernel whenever you want), | ||
152 | say M here and read <file:Documentation/kbuild/modules.txt>. | ||
153 | The module will be called ipw2100.ko. | ||
154 | |||
155 | config IPW2100_MONITOR | 158 | config IPW2100_MONITOR |
156 | bool "Enable promiscuous mode" | 159 | bool "Enable promiscuous mode" |
157 | depends on IPW2100 | 160 | depends on IPW2100 |
@@ -201,11 +204,14 @@ config IPW2200 | |||
201 | configure your card: | 204 | configure your card: |
202 | 205 | ||
203 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. | 206 | <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. |
204 | 207 | ||
205 | If you want to compile the driver as a module ( = code which can be | 208 | It is recommended that you compile this driver as a module (M) |
206 | inserted in and removed from the running kernel whenever you want), | 209 | rather than built-in (Y). This driver requires firmware at device |
207 | say M here and read <file:Documentation/kbuild/modules.txt>. | 210 | initialization time, and when built-in this typically happens |
208 | The module will be called ipw2200.ko. | 211 | before the filesystem is accessible (hence firmware will be |
212 | unavailable and initialization will fail). If you do choose to build | ||
213 | this driver into your kernel image, you can avoid this problem by | ||
214 | including the firmware and a firmware loader in an initramfs. | ||
209 | 215 | ||
210 | config IPW2200_MONITOR | 216 | config IPW2200_MONITOR |
211 | bool "Enable promiscuous mode" | 217 | bool "Enable promiscuous mode" |
@@ -732,23 +738,7 @@ config P54_PCI | |||
732 | 738 | ||
733 | If you choose to build a module, it'll be called p54pci. | 739 | If you choose to build a module, it'll be called p54pci. |
734 | 740 | ||
735 | config ATH5K | 741 | source "drivers/net/wireless/ath5k/Kconfig" |
736 | tristate "Atheros 5xxx wireless cards support" | ||
737 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
738 | ---help--- | ||
739 | This module adds support for wireless adapters based on | ||
740 | Atheros 5xxx chipset. | ||
741 | |||
742 | Currently the following chip versions are supported: | ||
743 | |||
744 | MAC: AR5211 AR5212 | ||
745 | PHY: RF5111/2111 RF5112/2112 RF5413/2413 | ||
746 | |||
747 | This driver uses the kernel's mac80211 subsystem. | ||
748 | |||
749 | If you choose to build a module, it'll be called ath5k. Say M if | ||
750 | unsure. | ||
751 | |||
752 | source "drivers/net/wireless/iwlwifi/Kconfig" | 742 | source "drivers/net/wireless/iwlwifi/Kconfig" |
753 | source "drivers/net/wireless/hostap/Kconfig" | 743 | source "drivers/net/wireless/hostap/Kconfig" |
754 | source "drivers/net/wireless/bcm43xx/Kconfig" | 744 | source "drivers/net/wireless/bcm43xx/Kconfig" |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 79796186713e..2e257ee2783b 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -48,6 +48,32 @@ static struct pci_device_id adm8211_pci_id_table[] __devinitdata = { | |||
48 | { 0 } | 48 | { 0 } |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static struct ieee80211_rate adm8211_rates[] = { | ||
52 | { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
53 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
54 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
55 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
56 | { .bitrate = 220, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, /* XX ?? */ | ||
57 | }; | ||
58 | |||
59 | static const struct ieee80211_channel adm8211_channels[] = { | ||
60 | { .center_freq = 2412}, | ||
61 | { .center_freq = 2417}, | ||
62 | { .center_freq = 2422}, | ||
63 | { .center_freq = 2427}, | ||
64 | { .center_freq = 2432}, | ||
65 | { .center_freq = 2437}, | ||
66 | { .center_freq = 2442}, | ||
67 | { .center_freq = 2447}, | ||
68 | { .center_freq = 2452}, | ||
69 | { .center_freq = 2457}, | ||
70 | { .center_freq = 2462}, | ||
71 | { .center_freq = 2467}, | ||
72 | { .center_freq = 2472}, | ||
73 | { .center_freq = 2484}, | ||
74 | }; | ||
75 | |||
76 | |||
51 | static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom) | 77 | static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom) |
52 | { | 78 | { |
53 | struct adm8211_priv *priv = eeprom->data; | 79 | struct adm8211_priv *priv = eeprom->data; |
@@ -155,17 +181,17 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev) | |||
155 | printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", | 181 | printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", |
156 | pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); | 182 | pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); |
157 | 183 | ||
158 | priv->modes[0].num_channels = chan_range.max - chan_range.min + 1; | 184 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels)); |
159 | priv->modes[0].channels = priv->channels; | ||
160 | 185 | ||
161 | memcpy(priv->channels, adm8211_channels, sizeof(adm8211_channels)); | 186 | memcpy(priv->channels, adm8211_channels, sizeof(priv->channels)); |
187 | priv->band.channels = priv->channels; | ||
188 | priv->band.n_channels = ARRAY_SIZE(adm8211_channels); | ||
189 | priv->band.bitrates = adm8211_rates; | ||
190 | priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates); | ||
162 | 191 | ||
163 | for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) | 192 | for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) |
164 | if (i >= chan_range.min && i <= chan_range.max) | 193 | if (i < chan_range.min || i > chan_range.max) |
165 | priv->channels[i - 1].flag = | 194 | priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED; |
166 | IEEE80211_CHAN_W_SCAN | | ||
167 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
168 | IEEE80211_CHAN_W_IBSS; | ||
169 | 195 | ||
170 | switch (priv->eeprom->specific_bbptype) { | 196 | switch (priv->eeprom->specific_bbptype) { |
171 | case ADM8211_BBP_RFMD3000: | 197 | case ADM8211_BBP_RFMD3000: |
@@ -347,7 +373,6 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
347 | unsigned int pktlen; | 373 | unsigned int pktlen; |
348 | struct sk_buff *skb, *newskb; | 374 | struct sk_buff *skb, *newskb; |
349 | unsigned int limit = priv->rx_ring_size; | 375 | unsigned int limit = priv->rx_ring_size; |
350 | static const u8 rate_tbl[] = {10, 20, 55, 110, 220}; | ||
351 | u8 rssi, rate; | 376 | u8 rssi, rate; |
352 | 377 | ||
353 | while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) { | 378 | 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 | else | 450 | else |
426 | rx_status.ssi = 100 - rssi; | 451 | rx_status.ssi = 100 - rssi; |
427 | 452 | ||
428 | if (rate <= 4) | 453 | rx_status.rate_idx = rate; |
429 | rx_status.rate = rate_tbl[rate]; | ||
430 | 454 | ||
431 | rx_status.channel = priv->channel; | 455 | rx_status.freq = adm8211_channels[priv->channel - 1].center_freq; |
432 | rx_status.freq = adm8211_channels[priv->channel - 1].freq; | 456 | rx_status.band = IEEE80211_BAND_2GHZ; |
433 | rx_status.phymode = MODE_IEEE80211B; | ||
434 | 457 | ||
435 | ieee80211_rx_irqsafe(dev, skb, &rx_status); | 458 | ieee80211_rx_irqsafe(dev, skb, &rx_status); |
436 | } | 459 | } |
@@ -1054,7 +1077,7 @@ static int adm8211_set_rate(struct ieee80211_hw *dev) | |||
1054 | if (priv->pdev->revision != ADM8211_REV_BA) { | 1077 | if (priv->pdev->revision != ADM8211_REV_BA) { |
1055 | rate_buf[0] = ARRAY_SIZE(adm8211_rates); | 1078 | rate_buf[0] = ARRAY_SIZE(adm8211_rates); |
1056 | for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++) | 1079 | for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++) |
1057 | rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80; | 1080 | rate_buf[i + 1] = (adm8211_rates[i].bitrate / 5) | 0x80; |
1058 | } else { | 1081 | } else { |
1059 | /* workaround for rev BA specific bug */ | 1082 | /* workaround for rev BA specific bug */ |
1060 | rate_buf[0] = 0x04; | 1083 | rate_buf[0] = 0x04; |
@@ -1086,7 +1109,7 @@ static void adm8211_hw_init(struct ieee80211_hw *dev) | |||
1086 | u32 reg; | 1109 | u32 reg; |
1087 | u8 cline; | 1110 | u8 cline; |
1088 | 1111 | ||
1089 | reg = le32_to_cpu(ADM8211_CSR_READ(PAR)); | 1112 | reg = ADM8211_CSR_READ(PAR); |
1090 | reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME; | 1113 | reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME; |
1091 | reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL); | 1114 | reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL); |
1092 | 1115 | ||
@@ -1303,9 +1326,10 @@ static int adm8211_set_ssid(struct ieee80211_hw *dev, u8 *ssid, size_t ssid_len) | |||
1303 | static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | 1326 | static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) |
1304 | { | 1327 | { |
1305 | struct adm8211_priv *priv = dev->priv; | 1328 | struct adm8211_priv *priv = dev->priv; |
1329 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
1306 | 1330 | ||
1307 | if (conf->channel != priv->channel) { | 1331 | if (channel != priv->channel) { |
1308 | priv->channel = conf->channel; | 1332 | priv->channel = channel; |
1309 | adm8211_rf_set_channel(dev, priv->channel); | 1333 | adm8211_rf_set_channel(dev, priv->channel); |
1310 | } | 1334 | } |
1311 | 1335 | ||
@@ -1678,13 +1702,9 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1678 | int plcp, dur, len, plcp_signal, short_preamble; | 1702 | int plcp, dur, len, plcp_signal, short_preamble; |
1679 | struct ieee80211_hdr *hdr; | 1703 | struct ieee80211_hdr *hdr; |
1680 | 1704 | ||
1681 | if (control->tx_rate < 0) { | 1705 | short_preamble = !!(control->tx_rate->flags & |
1682 | short_preamble = 1; | 1706 | IEEE80211_TXCTL_SHORT_PREAMBLE); |
1683 | plcp_signal = -control->tx_rate; | 1707 | plcp_signal = control->tx_rate->bitrate; |
1684 | } else { | ||
1685 | short_preamble = 0; | ||
1686 | plcp_signal = control->tx_rate; | ||
1687 | } | ||
1688 | 1708 | ||
1689 | hdr = (struct ieee80211_hdr *)skb->data; | 1709 | hdr = (struct ieee80211_hdr *)skb->data; |
1690 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; | 1710 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; |
@@ -1880,18 +1900,11 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1880 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | 1900 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); |
1881 | 1901 | ||
1882 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); | 1902 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); |
1883 | dev->flags = IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; | 1903 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ |
1884 | /* IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ | ||
1885 | 1904 | ||
1886 | dev->channel_change_time = 1000; | 1905 | dev->channel_change_time = 1000; |
1887 | dev->max_rssi = 100; /* FIXME: find better value */ | 1906 | dev->max_rssi = 100; /* FIXME: find better value */ |
1888 | 1907 | ||
1889 | priv->modes[0].mode = MODE_IEEE80211B; | ||
1890 | /* channel info filled in by adm8211_read_eeprom */ | ||
1891 | memcpy(priv->rates, adm8211_rates, sizeof(adm8211_rates)); | ||
1892 | priv->modes[0].num_rates = ARRAY_SIZE(adm8211_rates); | ||
1893 | priv->modes[0].rates = priv->rates; | ||
1894 | |||
1895 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ | 1908 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ |
1896 | 1909 | ||
1897 | priv->retry_limit = 3; | 1910 | priv->retry_limit = 3; |
@@ -1917,14 +1930,9 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1917 | goto err_free_desc; | 1930 | goto err_free_desc; |
1918 | } | 1931 | } |
1919 | 1932 | ||
1920 | priv->channel = priv->modes[0].channels[0].chan; | 1933 | priv->channel = 1; |
1921 | 1934 | ||
1922 | err = ieee80211_register_hwmode(dev, &priv->modes[0]); | 1935 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
1923 | if (err) { | ||
1924 | printk(KERN_ERR "%s (adm8211): Can't register hwmode\n", | ||
1925 | pci_name(pdev)); | ||
1926 | goto err_free_desc; | ||
1927 | } | ||
1928 | 1936 | ||
1929 | err = ieee80211_register_hw(dev); | 1937 | err = ieee80211_register_hw(dev); |
1930 | if (err) { | 1938 | if (err) { |
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h index ef326fed42e4..8d7c564b3b04 100644 --- a/drivers/net/wireless/adm8211.h +++ b/drivers/net/wireless/adm8211.h | |||
@@ -534,61 +534,6 @@ struct adm8211_eeprom { | |||
534 | u8 cis_data[0]; /* 0x80, 384 bytes */ | 534 | u8 cis_data[0]; /* 0x80, 384 bytes */ |
535 | } __attribute__ ((packed)); | 535 | } __attribute__ ((packed)); |
536 | 536 | ||
537 | static const struct ieee80211_rate adm8211_rates[] = { | ||
538 | { .rate = 10, | ||
539 | .val = 10, | ||
540 | .val2 = -10, | ||
541 | .flags = IEEE80211_RATE_CCK_2 }, | ||
542 | { .rate = 20, | ||
543 | .val = 20, | ||
544 | .val2 = -20, | ||
545 | .flags = IEEE80211_RATE_CCK_2 }, | ||
546 | { .rate = 55, | ||
547 | .val = 55, | ||
548 | .val2 = -55, | ||
549 | .flags = IEEE80211_RATE_CCK_2 }, | ||
550 | { .rate = 110, | ||
551 | .val = 110, | ||
552 | .val2 = -110, | ||
553 | .flags = IEEE80211_RATE_CCK_2 } | ||
554 | }; | ||
555 | |||
556 | struct ieee80211_chan_range { | ||
557 | u8 min; | ||
558 | u8 max; | ||
559 | }; | ||
560 | |||
561 | static const struct ieee80211_channel adm8211_channels[] = { | ||
562 | { .chan = 1, | ||
563 | .freq = 2412}, | ||
564 | { .chan = 2, | ||
565 | .freq = 2417}, | ||
566 | { .chan = 3, | ||
567 | .freq = 2422}, | ||
568 | { .chan = 4, | ||
569 | .freq = 2427}, | ||
570 | { .chan = 5, | ||
571 | .freq = 2432}, | ||
572 | { .chan = 6, | ||
573 | .freq = 2437}, | ||
574 | { .chan = 7, | ||
575 | .freq = 2442}, | ||
576 | { .chan = 8, | ||
577 | .freq = 2447}, | ||
578 | { .chan = 9, | ||
579 | .freq = 2452}, | ||
580 | { .chan = 10, | ||
581 | .freq = 2457}, | ||
582 | { .chan = 11, | ||
583 | .freq = 2462}, | ||
584 | { .chan = 12, | ||
585 | .freq = 2467}, | ||
586 | { .chan = 13, | ||
587 | .freq = 2472}, | ||
588 | { .chan = 14, | ||
589 | .freq = 2484}, | ||
590 | }; | ||
591 | |||
592 | struct adm8211_priv { | 537 | struct adm8211_priv { |
593 | struct pci_dev *pdev; | 538 | struct pci_dev *pdev; |
594 | spinlock_t lock; | 539 | spinlock_t lock; |
@@ -603,9 +548,8 @@ struct adm8211_priv { | |||
603 | unsigned int cur_tx, dirty_tx, cur_rx; | 548 | unsigned int cur_tx, dirty_tx, cur_rx; |
604 | 549 | ||
605 | struct ieee80211_low_level_stats stats; | 550 | struct ieee80211_low_level_stats stats; |
606 | struct ieee80211_hw_mode modes[1]; | 551 | struct ieee80211_supported_band band; |
607 | struct ieee80211_channel channels[ARRAY_SIZE(adm8211_channels)]; | 552 | struct ieee80211_channel channels[14]; |
608 | struct ieee80211_rate rates[ARRAY_SIZE(adm8211_rates)]; | ||
609 | int mode; | 553 | int mode; |
610 | 554 | ||
611 | int channel; | 555 | int channel; |
@@ -643,6 +587,11 @@ struct adm8211_priv { | |||
643 | } transceiver_type; | 587 | } transceiver_type; |
644 | }; | 588 | }; |
645 | 589 | ||
590 | struct ieee80211_chan_range { | ||
591 | u8 min; | ||
592 | u8 max; | ||
593 | }; | ||
594 | |||
646 | static const struct ieee80211_chan_range cranges[] = { | 595 | static const struct ieee80211_chan_range cranges[] = { |
647 | {1, 11}, /* FCC */ | 596 | {1, 11}, /* FCC */ |
648 | {1, 11}, /* IC */ | 597 | {1, 11}, /* IC */ |
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig new file mode 100644 index 000000000000..f1f2aea2eab4 --- /dev/null +++ b/drivers/net/wireless/ath5k/Kconfig | |||
@@ -0,0 +1,37 @@ | |||
1 | config ATH5K | ||
2 | tristate "Atheros 5xxx wireless cards support" | ||
3 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | ||
4 | ---help--- | ||
5 | This module adds support for wireless adapters based on | ||
6 | Atheros 5xxx chipset. | ||
7 | |||
8 | Currently the following chip versions are supported: | ||
9 | |||
10 | MAC: AR5211 AR5212 | ||
11 | PHY: RF5111/2111 RF5112/2112 RF5413/2413 | ||
12 | |||
13 | This driver uses the kernel's mac80211 subsystem. | ||
14 | |||
15 | If you choose to build a module, it'll be called ath5k. Say M if | ||
16 | unsure. | ||
17 | |||
18 | config ATH5K_DEBUG | ||
19 | bool "Atheros 5xxx debugging" | ||
20 | depends on ATH5K | ||
21 | ---help--- | ||
22 | Atheros 5xxx debugging messages. | ||
23 | |||
24 | Say Y, if and you will get debug options for ath5k. | ||
25 | To use this, you need to mount debugfs: | ||
26 | |||
27 | mkdir /debug/ | ||
28 | mount -t debugfs debug /debug/ | ||
29 | |||
30 | You will get access to files under: | ||
31 | /debug/ath5k/phy0/ | ||
32 | |||
33 | To enable debug, pass the debug level to the debug module | ||
34 | parameter. For example: | ||
35 | |||
36 | modprobe ath5k debug=0x00000400 | ||
37 | |||
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile index 321641f99e13..564ecd0c5d4b 100644 --- a/drivers/net/wireless/ath5k/Makefile +++ b/drivers/net/wireless/ath5k/Makefile | |||
@@ -1,2 +1,6 @@ | |||
1 | ath5k-objs = base.o hw.o regdom.o initvals.o phy.o debug.o | 1 | ath5k-y += base.o |
2 | obj-$(CONFIG_ATH5K) += ath5k.o | 2 | ath5k-y += hw.o |
3 | ath5k-y += initvals.o | ||
4 | ath5k-y += phy.o | ||
5 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | ||
6 | obj-$(CONFIG_ATH5K) += ath5k.o | ||
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 69dea3392612..18223d9833f1 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | 31 | ||
32 | #include "hw.h" | 32 | #include "hw.h" |
33 | #include "regdom.h" | ||
34 | 33 | ||
35 | /* PCI IDs */ | 34 | /* PCI IDs */ |
36 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ | 35 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ |
@@ -251,19 +250,23 @@ struct ath5k_srev_name { | |||
251 | */ | 250 | */ |
252 | #define MODULATION_TURBO 0x00000080 | 251 | #define MODULATION_TURBO 0x00000080 |
253 | 252 | ||
254 | enum ath5k_vendor_mode { | 253 | enum ath5k_driver_mode { |
255 | MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1, | 254 | AR5K_MODE_11A = 0, |
256 | MODE_ATHEROS_TURBOG | 255 | AR5K_MODE_11A_TURBO = 1, |
256 | AR5K_MODE_11B = 2, | ||
257 | AR5K_MODE_11G = 3, | ||
258 | AR5K_MODE_11G_TURBO = 4, | ||
259 | AR5K_MODE_XR = 0, | ||
260 | AR5K_MODE_MAX = 5 | ||
257 | }; | 261 | }; |
258 | 262 | ||
259 | /* Number of supported mac80211 enum ieee80211_phymode modes by this driver */ | ||
260 | #define NUM_DRIVER_MODES 3 | ||
261 | |||
262 | /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ | 263 | /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ |
263 | #define AR5K_SET_SHORT_PREAMBLE 0x04 | 264 | #define AR5K_SET_SHORT_PREAMBLE 0x04 |
264 | 265 | ||
265 | #define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2) | 266 | #define HAS_SHPREAMBLE(_ix) \ |
266 | #define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) | 267 | (rt->rates[_ix].modulation == IEEE80211_RATE_SHORT_PREAMBLE) |
268 | #define SHPREAMBLE_FLAG(_ix) \ | ||
269 | (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) | ||
267 | 270 | ||
268 | /****************\ | 271 | /****************\ |
269 | TX DEFINITIONS | 272 | TX DEFINITIONS |
@@ -560,8 +563,8 @@ struct ath5k_desc { | |||
560 | * Used internaly in OpenHAL (ar5211.c/ar5212.c | 563 | * Used internaly in OpenHAL (ar5211.c/ar5212.c |
561 | * for reset_tx_queue). Also see struct struct ieee80211_channel. | 564 | * for reset_tx_queue). Also see struct struct ieee80211_channel. |
562 | */ | 565 | */ |
563 | #define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0) | 566 | #define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) |
564 | #define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0) | 567 | #define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) |
565 | 568 | ||
566 | /* | 569 | /* |
567 | * The following structure will be used to map 2GHz channels to | 570 | * The following structure will be used to map 2GHz channels to |
@@ -584,7 +587,7 @@ struct ath5k_athchan_2ghz { | |||
584 | 587 | ||
585 | /** | 588 | /** |
586 | * struct ath5k_rate - rate structure | 589 | * struct ath5k_rate - rate structure |
587 | * @valid: is this a valid rate for the current mode | 590 | * @valid: is this a valid rate for rate control (remove) |
588 | * @modulation: respective mac80211 modulation | 591 | * @modulation: respective mac80211 modulation |
589 | * @rate_kbps: rate in kbit/s | 592 | * @rate_kbps: rate in kbit/s |
590 | * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on | 593 | * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on |
@@ -643,47 +646,48 @@ struct ath5k_rate_table { | |||
643 | 646 | ||
644 | /* | 647 | /* |
645 | * Rate tables... | 648 | * Rate tables... |
649 | * TODO: CLEAN THIS !!! | ||
646 | */ | 650 | */ |
647 | #define AR5K_RATES_11A { 8, { \ | 651 | #define AR5K_RATES_11A { 8, { \ |
648 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ | 652 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ |
649 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ | 653 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ |
650 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ | 654 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ |
651 | { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 }, \ | 655 | { 1, 0, 6000, 11, 140, 0 }, \ |
652 | { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 }, \ | 656 | { 1, 0, 9000, 15, 18, 0 }, \ |
653 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 }, \ | 657 | { 1, 0, 12000, 10, 152, 2 }, \ |
654 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 }, \ | 658 | { 1, 0, 18000, 14, 36, 2 }, \ |
655 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 }, \ | 659 | { 1, 0, 24000, 9, 176, 4 }, \ |
656 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 }, \ | 660 | { 1, 0, 36000, 13, 72, 4 }, \ |
657 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 }, \ | 661 | { 1, 0, 48000, 8, 96, 4 }, \ |
658 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } } \ | 662 | { 1, 0, 54000, 12, 108, 4 } } \ |
659 | } | 663 | } |
660 | 664 | ||
661 | #define AR5K_RATES_11B { 4, { \ | 665 | #define AR5K_RATES_11B { 4, { \ |
662 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | 666 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ |
663 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | 667 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ |
664 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | 668 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ |
665 | { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 }, \ | 669 | { 1, 0, 1000, 27, 130, 0 }, \ |
666 | { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 }, \ | 670 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 132, 1 }, \ |
667 | { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 }, \ | 671 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 139, 1 }, \ |
668 | { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } } \ | 672 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 150, 1 } } \ |
669 | } | 673 | } |
670 | 674 | ||
671 | #define AR5K_RATES_11G { 12, { \ | 675 | #define AR5K_RATES_11G { 12, { \ |
672 | 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ | 676 | 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ |
673 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ | 677 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ |
674 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | 678 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ |
675 | { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 }, \ | 679 | { 1, 0, 1000, 27, 2, 0 }, \ |
676 | { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 }, \ | 680 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 4, 1 }, \ |
677 | { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 }, \ | 681 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 11, 1 }, \ |
678 | { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 }, \ | 682 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 22, 1 }, \ |
679 | { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 }, \ | 683 | { 0, 0, 6000, 11, 12, 4 }, \ |
680 | { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ | 684 | { 0, 0, 9000, 15, 18, 4 }, \ |
681 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 }, \ | 685 | { 1, 0, 12000, 10, 24, 6 }, \ |
682 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ | 686 | { 1, 0, 18000, 14, 36, 6 }, \ |
683 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 }, \ | 687 | { 1, 0, 24000, 9, 48, 8 }, \ |
684 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ | 688 | { 1, 0, 36000, 13, 72, 8 }, \ |
685 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ | 689 | { 1, 0, 48000, 8, 96, 8 }, \ |
686 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ | 690 | { 1, 0, 54000, 12, 108, 8 } } \ |
687 | } | 691 | } |
688 | 692 | ||
689 | #define AR5K_RATES_TURBO { 8, { \ | 693 | #define AR5K_RATES_TURBO { 8, { \ |
@@ -708,14 +712,14 @@ struct ath5k_rate_table { | |||
708 | { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ | 712 | { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ |
709 | { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ | 713 | { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ |
710 | { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ | 714 | { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ |
711 | { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 }, \ | 715 | { 1, 0, 6000, 11, 140, 4 }, \ |
712 | { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \ | 716 | { 1, 0, 9000, 15, 18, 4 }, \ |
713 | { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 }, \ | 717 | { 1, 0, 12000, 10, 152, 6 }, \ |
714 | { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \ | 718 | { 1, 0, 18000, 14, 36, 6 }, \ |
715 | { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 }, \ | 719 | { 1, 0, 24000, 9, 176, 8 }, \ |
716 | { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \ | 720 | { 1, 0, 36000, 13, 72, 8 }, \ |
717 | { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \ | 721 | { 1, 0, 48000, 8, 96, 8 }, \ |
718 | { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \ | 722 | { 1, 0, 54000, 12, 108, 8 } } \ |
719 | } | 723 | } |
720 | 724 | ||
721 | /* | 725 | /* |
@@ -890,12 +894,14 @@ enum ath5k_capability_type { | |||
890 | AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ | 894 | AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */ |
891 | }; | 895 | }; |
892 | 896 | ||
897 | |||
898 | /* XXX: we *may* move cap_range stuff to struct wiphy */ | ||
893 | struct ath5k_capabilities { | 899 | struct ath5k_capabilities { |
894 | /* | 900 | /* |
895 | * Supported PHY modes | 901 | * Supported PHY modes |
896 | * (ie. CHANNEL_A, CHANNEL_B, ...) | 902 | * (ie. CHANNEL_A, CHANNEL_B, ...) |
897 | */ | 903 | */ |
898 | DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES); | 904 | DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX); |
899 | 905 | ||
900 | /* | 906 | /* |
901 | * Frequency range (without regulation restrictions) | 907 | * Frequency range (without regulation restrictions) |
@@ -908,14 +914,6 @@ struct ath5k_capabilities { | |||
908 | } cap_range; | 914 | } cap_range; |
909 | 915 | ||
910 | /* | 916 | /* |
911 | * Active regulation domain settings | ||
912 | */ | ||
913 | struct { | ||
914 | enum ath5k_regdom reg_current; | ||
915 | enum ath5k_regdom reg_hw; | ||
916 | } cap_regdomain; | ||
917 | |||
918 | /* | ||
919 | * Values stored in the EEPROM (some of them...) | 917 | * Values stored in the EEPROM (some of them...) |
920 | */ | 918 | */ |
921 | struct ath5k_eeprom_info cap_eeprom; | 919 | struct ath5k_eeprom_info cap_eeprom; |
@@ -1129,8 +1127,6 @@ extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); | |||
1129 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | 1127 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); |
1130 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1128 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1131 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1129 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); |
1132 | /* Regulatory Domain/Channels Setup */ | ||
1133 | extern u16 ath5k_get_regdomain(struct ath5k_hw *ah); | ||
1134 | /* Misc functions */ | 1130 | /* Misc functions */ |
1135 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1131 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); |
1136 | 1132 | ||
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index bef967ce34a6..393b5f3c25a7 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -80,7 +80,7 @@ MODULE_AUTHOR("Nick Kossifidis"); | |||
80 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 80 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
81 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | 81 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); |
82 | MODULE_LICENSE("Dual BSD/GPL"); | 82 | MODULE_LICENSE("Dual BSD/GPL"); |
83 | MODULE_VERSION("0.1.1 (EXPERIMENTAL)"); | 83 | MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); |
84 | 84 | ||
85 | 85 | ||
86 | /* Known PCI ids */ | 86 | /* Known PCI ids */ |
@@ -240,6 +240,8 @@ static int ath5k_chan_set(struct ath5k_softc *sc, | |||
240 | static void ath5k_setcurmode(struct ath5k_softc *sc, | 240 | static void ath5k_setcurmode(struct ath5k_softc *sc, |
241 | unsigned int mode); | 241 | unsigned int mode); |
242 | static void ath5k_mode_setup(struct ath5k_softc *sc); | 242 | static void ath5k_mode_setup(struct ath5k_softc *sc); |
243 | static void ath5k_set_total_hw_rates(struct ath5k_softc *sc); | ||
244 | |||
243 | /* Descriptor setup */ | 245 | /* Descriptor setup */ |
244 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | 246 | static int ath5k_desc_alloc(struct ath5k_softc *sc, |
245 | struct pci_dev *pdev); | 247 | struct pci_dev *pdev); |
@@ -511,35 +513,46 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
511 | sc->ah->ah_mac_srev, | 513 | sc->ah->ah_mac_srev, |
512 | sc->ah->ah_phy_revision); | 514 | sc->ah->ah_phy_revision); |
513 | 515 | ||
514 | if(!sc->ah->ah_single_chip){ | 516 | if (!sc->ah->ah_single_chip) { |
515 | /* Single chip radio (!RF5111) */ | 517 | /* Single chip radio (!RF5111) */ |
516 | if(sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) { | 518 | if (sc->ah->ah_radio_5ghz_revision && |
519 | !sc->ah->ah_radio_2ghz_revision) { | ||
517 | /* No 5GHz support -> report 2GHz radio */ | 520 | /* No 5GHz support -> report 2GHz radio */ |
518 | if(!test_bit(MODE_IEEE80211A, sc->ah->ah_capabilities.cap_mode)){ | 521 | if (!test_bit(AR5K_MODE_11A, |
522 | sc->ah->ah_capabilities.cap_mode)) { | ||
519 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | 523 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", |
520 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 524 | ath5k_chip_name(AR5K_VERSION_RAD, |
521 | sc->ah->ah_radio_5ghz_revision); | 525 | sc->ah->ah_radio_5ghz_revision), |
522 | /* No 2GHz support (5110 and some 5Ghz only cards) -> report 5Ghz radio */ | 526 | sc->ah->ah_radio_5ghz_revision); |
523 | } else if(!test_bit(MODE_IEEE80211B, sc->ah->ah_capabilities.cap_mode)){ | 527 | /* No 2GHz support (5110 and some |
528 | * 5Ghz only cards) -> report 5Ghz radio */ | ||
529 | } else if (!test_bit(AR5K_MODE_11B, | ||
530 | sc->ah->ah_capabilities.cap_mode)) { | ||
524 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | 531 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", |
525 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 532 | ath5k_chip_name(AR5K_VERSION_RAD, |
526 | sc->ah->ah_radio_5ghz_revision); | 533 | sc->ah->ah_radio_5ghz_revision), |
534 | sc->ah->ah_radio_5ghz_revision); | ||
527 | /* Multiband radio */ | 535 | /* Multiband radio */ |
528 | } else { | 536 | } else { |
529 | ATH5K_INFO(sc, "RF%s multiband radio found" | 537 | ATH5K_INFO(sc, "RF%s multiband radio found" |
530 | " (0x%x)\n", | 538 | " (0x%x)\n", |
531 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 539 | ath5k_chip_name(AR5K_VERSION_RAD, |
532 | sc->ah->ah_radio_5ghz_revision); | 540 | sc->ah->ah_radio_5ghz_revision), |
541 | sc->ah->ah_radio_5ghz_revision); | ||
533 | } | 542 | } |
534 | } | 543 | } |
535 | /* Multi chip radio (RF5111 - RF2111) -> report both 2GHz/5GHz radios */ | 544 | /* Multi chip radio (RF5111 - RF2111) -> |
536 | else if(sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision){ | 545 | * report both 2GHz/5GHz radios */ |
546 | else if (sc->ah->ah_radio_5ghz_revision && | ||
547 | sc->ah->ah_radio_2ghz_revision){ | ||
537 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", | 548 | ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", |
538 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision), | 549 | ath5k_chip_name(AR5K_VERSION_RAD, |
539 | sc->ah->ah_radio_5ghz_revision); | 550 | sc->ah->ah_radio_5ghz_revision), |
551 | sc->ah->ah_radio_5ghz_revision); | ||
540 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", | 552 | ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", |
541 | ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_2ghz_revision), | 553 | ath5k_chip_name(AR5K_VERSION_RAD, |
542 | sc->ah->ah_radio_2ghz_revision); | 554 | sc->ah->ah_radio_2ghz_revision), |
555 | sc->ah->ah_radio_2ghz_revision); | ||
543 | } | 556 | } |
544 | } | 557 | } |
545 | 558 | ||
@@ -693,11 +706,14 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
693 | goto err; | 706 | goto err; |
694 | } | 707 | } |
695 | 708 | ||
709 | /* Set *_rates so we can map hw rate index */ | ||
710 | ath5k_set_total_hw_rates(sc); | ||
711 | |||
696 | /* NB: setup here so ath5k_rate_update is happy */ | 712 | /* NB: setup here so ath5k_rate_update is happy */ |
697 | if (test_bit(MODE_IEEE80211A, ah->ah_modes)) | 713 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) |
698 | ath5k_setcurmode(sc, MODE_IEEE80211A); | 714 | ath5k_setcurmode(sc, AR5K_MODE_11A); |
699 | else | 715 | else |
700 | ath5k_setcurmode(sc, MODE_IEEE80211B); | 716 | ath5k_setcurmode(sc, AR5K_MODE_11B); |
701 | 717 | ||
702 | /* | 718 | /* |
703 | * Allocate tx+rx descriptors and populate the lists. | 719 | * Allocate tx+rx descriptors and populate the lists. |
@@ -837,12 +853,9 @@ ath5k_copy_rates(struct ieee80211_rate *rates, | |||
837 | return 0; | 853 | return 0; |
838 | 854 | ||
839 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { | 855 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { |
840 | if (!rt->rates[i].valid) | 856 | rates[count].bitrate = rt->rates[i].rate_kbps / 100; |
841 | continue; | 857 | rates[count].hw_value = rt->rates[i].rate_code; |
842 | rates->rate = rt->rates[i].rate_kbps / 100; | 858 | rates[count].flags = rt->rates[i].modulation; |
843 | rates->val = rt->rates[i].rate_code; | ||
844 | rates->flags = rt->rates[i].modulation; | ||
845 | rates++; | ||
846 | count++; | 859 | count++; |
847 | max--; | 860 | max--; |
848 | } | 861 | } |
@@ -856,43 +869,22 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
856 | unsigned int mode, | 869 | unsigned int mode, |
857 | unsigned int max) | 870 | unsigned int max) |
858 | { | 871 | { |
859 | static const struct { unsigned int mode, mask, chan; } map[] = { | 872 | unsigned int i, count, size, chfreq, freq, ch; |
860 | [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A }, | ||
861 | [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T }, | ||
862 | [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B }, | ||
863 | [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G }, | ||
864 | [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG }, | ||
865 | }; | ||
866 | static const struct ath5k_regchannel chans_2ghz[] = | ||
867 | IEEE80211_CHANNELS_2GHZ; | ||
868 | static const struct ath5k_regchannel chans_5ghz[] = | ||
869 | IEEE80211_CHANNELS_5GHZ; | ||
870 | const struct ath5k_regchannel *chans; | ||
871 | enum ath5k_regdom dmn; | ||
872 | unsigned int i, count, size, chfreq, all, f, ch; | ||
873 | 873 | ||
874 | if (!test_bit(mode, ah->ah_modes)) | 874 | if (!test_bit(mode, ah->ah_modes)) |
875 | return 0; | 875 | return 0; |
876 | 876 | ||
877 | all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1; | ||
878 | |||
879 | switch (mode) { | 877 | switch (mode) { |
880 | case MODE_IEEE80211A: | 878 | case AR5K_MODE_11A: |
881 | case MODE_ATHEROS_TURBO: | 879 | case AR5K_MODE_11A_TURBO: |
882 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ | 880 | /* 1..220, but 2GHz frequencies are filtered by check_channel */ |
883 | size = all ? 220 : ARRAY_SIZE(chans_5ghz); | 881 | size = 220 ; |
884 | chans = chans_5ghz; | ||
885 | dmn = ath5k_regdom2flag(ah->ah_regdomain, | ||
886 | IEEE80211_CHANNELS_5GHZ_MIN); | ||
887 | chfreq = CHANNEL_5GHZ; | 882 | chfreq = CHANNEL_5GHZ; |
888 | break; | 883 | break; |
889 | case MODE_IEEE80211B: | 884 | case AR5K_MODE_11B: |
890 | case MODE_IEEE80211G: | 885 | case AR5K_MODE_11G: |
891 | case MODE_ATHEROS_TURBOG: | 886 | case AR5K_MODE_11G_TURBO: |
892 | size = all ? 26 : ARRAY_SIZE(chans_2ghz); | 887 | size = 26; |
893 | chans = chans_2ghz; | ||
894 | dmn = ath5k_regdom2flag(ah->ah_regdomain, | ||
895 | IEEE80211_CHANNELS_2GHZ_MIN); | ||
896 | chfreq = CHANNEL_2GHZ; | 888 | chfreq = CHANNEL_2GHZ; |
897 | break; | 889 | break; |
898 | default: | 890 | default: |
@@ -901,25 +893,31 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
901 | } | 893 | } |
902 | 894 | ||
903 | for (i = 0, count = 0; i < size && max > 0; i++) { | 895 | for (i = 0, count = 0; i < size && max > 0; i++) { |
904 | ch = all ? i + 1 : chans[i].chan; | 896 | ch = i + 1 ; |
905 | f = ath5k_ieee2mhz(ch); | 897 | freq = ath5k_ieee2mhz(ch); |
906 | /* Check if channel is supported by the chipset */ | ||
907 | if (!ath5k_channel_ok(ah, f, chfreq)) | ||
908 | continue; | ||
909 | 898 | ||
910 | /* Match regulation domain */ | 899 | /* Check if channel is supported by the chipset */ |
911 | if (!all && !(IEEE80211_DMN(chans[i].domain) & | 900 | if (!ath5k_channel_ok(ah, freq, chfreq)) |
912 | IEEE80211_DMN(dmn))) | ||
913 | continue; | 901 | continue; |
914 | 902 | ||
915 | if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode) | 903 | /* Write channel info and increment counter */ |
916 | continue; | 904 | channels[count].center_freq = freq; |
905 | channels[count].band = (chfreq == CHANNEL_2GHZ) ? | ||
906 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | ||
907 | switch (mode) { | ||
908 | case AR5K_MODE_11A: | ||
909 | case AR5K_MODE_11G: | ||
910 | channels[count].hw_value = chfreq | CHANNEL_OFDM; | ||
911 | break; | ||
912 | case AR5K_MODE_11A_TURBO: | ||
913 | case AR5K_MODE_11G_TURBO: | ||
914 | channels[count].hw_value = chfreq | | ||
915 | CHANNEL_OFDM | CHANNEL_TURBO; | ||
916 | break; | ||
917 | case AR5K_MODE_11B: | ||
918 | channels[count].hw_value = CHANNEL_B; | ||
919 | } | ||
917 | 920 | ||
918 | /* Write channel and increment counter */ | ||
919 | channels->chan = ch; | ||
920 | channels->freq = f; | ||
921 | channels->val = map[mode].chan; | ||
922 | channels++; | ||
923 | count++; | 921 | count++; |
924 | max--; | 922 | max--; |
925 | } | 923 | } |
@@ -927,95 +925,78 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
927 | return count; | 925 | return count; |
928 | } | 926 | } |
929 | 927 | ||
930 | /* Only tries to register modes our EEPROM says it can support */ | ||
931 | #define REGISTER_MODE(m) do { \ | ||
932 | ret = ath5k_register_mode(hw, m); \ | ||
933 | if (ret) \ | ||
934 | return ret; \ | ||
935 | } while (0) \ | ||
936 | |||
937 | static inline int | ||
938 | ath5k_register_mode(struct ieee80211_hw *hw, u8 m) | ||
939 | { | ||
940 | struct ath5k_softc *sc = hw->priv; | ||
941 | struct ieee80211_hw_mode *modes = sc->modes; | ||
942 | unsigned int i; | ||
943 | int ret; | ||
944 | |||
945 | if (!test_bit(m, sc->ah->ah_capabilities.cap_mode)) | ||
946 | return 0; | ||
947 | |||
948 | for (i = 0; i < NUM_DRIVER_MODES; i++) { | ||
949 | if (modes[i].mode != m || !modes[i].num_channels) | ||
950 | continue; | ||
951 | ret = ieee80211_register_hwmode(hw, &modes[i]); | ||
952 | if (ret) { | ||
953 | ATH5K_ERR(sc, "can't register hwmode %u\n", m); | ||
954 | return ret; | ||
955 | } | ||
956 | return 0; | ||
957 | } | ||
958 | BUG(); | ||
959 | } | ||
960 | |||
961 | static int | 928 | static int |
962 | ath5k_getchannels(struct ieee80211_hw *hw) | 929 | ath5k_getchannels(struct ieee80211_hw *hw) |
963 | { | 930 | { |
964 | struct ath5k_softc *sc = hw->priv; | 931 | struct ath5k_softc *sc = hw->priv; |
965 | struct ath5k_hw *ah = sc->ah; | 932 | struct ath5k_hw *ah = sc->ah; |
966 | struct ieee80211_hw_mode *modes = sc->modes; | 933 | struct ieee80211_supported_band *sbands = sc->sbands; |
967 | unsigned int i, max_r, max_c; | 934 | const struct ath5k_rate_table *hw_rates; |
968 | int ret; | 935 | unsigned int max_r, max_c, count_r, count_c; |
969 | 936 | int mode2g = AR5K_MODE_11G; | |
970 | BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3); | ||
971 | 937 | ||
972 | /* The order here does not matter */ | 938 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); |
973 | modes[0].mode = MODE_IEEE80211G; | ||
974 | modes[1].mode = MODE_IEEE80211B; | ||
975 | modes[2].mode = MODE_IEEE80211A; | ||
976 | 939 | ||
977 | max_r = ARRAY_SIZE(sc->rates); | 940 | max_r = ARRAY_SIZE(sc->rates); |
978 | max_c = ARRAY_SIZE(sc->channels); | 941 | max_c = ARRAY_SIZE(sc->channels); |
942 | count_r = count_c = 0; | ||
979 | 943 | ||
980 | for (i = 0; i < NUM_DRIVER_MODES; i++) { | 944 | /* 2GHz band */ |
981 | struct ieee80211_hw_mode *mode = &modes[i]; | 945 | if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { |
982 | const struct ath5k_rate_table *hw_rates; | 946 | mode2g = AR5K_MODE_11B; |
947 | if (!test_bit(AR5K_MODE_11B, | ||
948 | sc->ah->ah_capabilities.cap_mode)) | ||
949 | mode2g = -1; | ||
950 | } | ||
983 | 951 | ||
984 | if (i == 0) { | 952 | if (mode2g > 0) { |
985 | modes[0].rates = sc->rates; | 953 | struct ieee80211_supported_band *sband = |
986 | modes->channels = sc->channels; | 954 | &sbands[IEEE80211_BAND_2GHZ]; |
987 | } else { | 955 | |
988 | struct ieee80211_hw_mode *prev_mode = &modes[i-1]; | 956 | sband->bitrates = sc->rates; |
989 | int prev_num_r = prev_mode->num_rates; | 957 | sband->channels = sc->channels; |
990 | int prev_num_c = prev_mode->num_channels; | 958 | |
991 | mode->rates = &prev_mode->rates[prev_num_r]; | 959 | sband->band = IEEE80211_BAND_2GHZ; |
992 | mode->channels = &prev_mode->channels[prev_num_c]; | 960 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
993 | } | 961 | mode2g, max_c); |
962 | |||
963 | hw_rates = ath5k_hw_get_rate_table(ah, mode2g); | ||
964 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
965 | hw_rates, max_r); | ||
966 | |||
967 | count_c = sband->n_channels; | ||
968 | count_r = sband->n_bitrates; | ||
969 | |||
970 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
971 | |||
972 | max_r -= count_r; | ||
973 | max_c -= count_c; | ||
994 | 974 | ||
995 | hw_rates = ath5k_hw_get_rate_table(ah, mode->mode); | ||
996 | mode->num_rates = ath5k_copy_rates(mode->rates, hw_rates, | ||
997 | max_r); | ||
998 | mode->num_channels = ath5k_copy_channels(ah, mode->channels, | ||
999 | mode->mode, max_c); | ||
1000 | max_r -= mode->num_rates; | ||
1001 | max_c -= mode->num_channels; | ||
1002 | } | 975 | } |
1003 | 976 | ||
1004 | /* We try to register all modes this driver supports. We don't bother | 977 | /* 5GHz band */ |
1005 | * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts | ||
1006 | * for that as per mac80211. Then, REGISTER_MODE() will will actually | ||
1007 | * check the eeprom reading for more reliable capability information. | ||
1008 | * Order matters here as per mac80211's latest preference. This will | ||
1009 | * all hopefullly soon go away. */ | ||
1010 | 978 | ||
1011 | REGISTER_MODE(MODE_IEEE80211G); | 979 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { |
1012 | if (ah->ah_version != AR5K_AR5212) | 980 | struct ieee80211_supported_band *sband = |
1013 | REGISTER_MODE(MODE_IEEE80211B); | 981 | &sbands[IEEE80211_BAND_5GHZ]; |
1014 | REGISTER_MODE(MODE_IEEE80211A); | ||
1015 | 982 | ||
1016 | ath5k_debug_dump_modes(sc, modes); | 983 | sband->bitrates = &sc->rates[count_r]; |
984 | sband->channels = &sc->channels[count_c]; | ||
1017 | 985 | ||
1018 | return ret; | 986 | sband->band = IEEE80211_BAND_5GHZ; |
987 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | ||
988 | AR5K_MODE_11A, max_c); | ||
989 | |||
990 | hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A); | ||
991 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
992 | hw_rates, max_r); | ||
993 | |||
994 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | ||
995 | } | ||
996 | |||
997 | ath5k_debug_dump_bands(sc); | ||
998 | |||
999 | return 0; | ||
1019 | } | 1000 | } |
1020 | 1001 | ||
1021 | /* | 1002 | /* |
@@ -1030,11 +1011,15 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1030 | struct ath5k_hw *ah = sc->ah; | 1011 | struct ath5k_hw *ah = sc->ah; |
1031 | int ret; | 1012 | int ret; |
1032 | 1013 | ||
1033 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n", | 1014 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", |
1034 | sc->curchan->chan, sc->curchan->freq, | 1015 | sc->curchan->center_freq, chan->center_freq); |
1035 | chan->chan, chan->freq); | 1016 | |
1017 | if (chan->center_freq != sc->curchan->center_freq || | ||
1018 | chan->hw_value != sc->curchan->hw_value) { | ||
1019 | |||
1020 | sc->curchan = chan; | ||
1021 | sc->curband = &sc->sbands[chan->band]; | ||
1036 | 1022 | ||
1037 | if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) { | ||
1038 | /* | 1023 | /* |
1039 | * To switch channels clear any pending DMA operations; | 1024 | * To switch channels clear any pending DMA operations; |
1040 | * wait long enough for the RX fifo to drain, reset the | 1025 | * wait long enough for the RX fifo to drain, reset the |
@@ -1044,13 +1029,13 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1044 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ | 1029 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ |
1045 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ | 1030 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ |
1046 | ath5k_rx_stop(sc); /* turn off frame recv */ | 1031 | ath5k_rx_stop(sc); /* turn off frame recv */ |
1047 | ret = ath5k_hw_reset(ah, sc->opmode, chan, true); | 1032 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); |
1048 | if (ret) { | 1033 | if (ret) { |
1049 | ATH5K_ERR(sc, "%s: unable to reset channel %u " | 1034 | ATH5K_ERR(sc, "%s: unable to reset channel " |
1050 | "(%u Mhz)\n", __func__, chan->chan, chan->freq); | 1035 | "(%u Mhz)\n", __func__, chan->center_freq); |
1051 | return ret; | 1036 | return ret; |
1052 | } | 1037 | } |
1053 | sc->curchan = chan; | 1038 | |
1054 | ath5k_hw_set_txpower_limit(sc->ah, 0); | 1039 | ath5k_hw_set_txpower_limit(sc->ah, 0); |
1055 | 1040 | ||
1056 | /* | 1041 | /* |
@@ -1081,6 +1066,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1081 | return 0; | 1066 | return 0; |
1082 | } | 1067 | } |
1083 | 1068 | ||
1069 | /* | ||
1070 | * TODO: CLEAN THIS !!! | ||
1071 | */ | ||
1084 | static void | 1072 | static void |
1085 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | 1073 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) |
1086 | { | 1074 | { |
@@ -1121,10 +1109,6 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | |||
1121 | continue; | 1109 | continue; |
1122 | } | 1110 | } |
1123 | sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; | 1111 | sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; |
1124 | if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation == | ||
1125 | IEEE80211_RATE_OFDM) | ||
1126 | sc->hwmap[i].txflags |= | ||
1127 | IEEE80211_RADIOTAP_F_SHORTPRE; | ||
1128 | /* receive frames include FCS */ | 1112 | /* receive frames include FCS */ |
1129 | sc->hwmap[i].rxflags = sc->hwmap[i].txflags | | 1113 | sc->hwmap[i].rxflags = sc->hwmap[i].txflags | |
1130 | IEEE80211_RADIOTAP_F_FCS; | 1114 | IEEE80211_RADIOTAP_F_FCS; |
@@ -1142,6 +1126,12 @@ ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | |||
1142 | } | 1126 | } |
1143 | 1127 | ||
1144 | sc->curmode = mode; | 1128 | sc->curmode = mode; |
1129 | |||
1130 | if (mode == AR5K_MODE_11A) { | ||
1131 | sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; | ||
1132 | } else { | ||
1133 | sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; | ||
1134 | } | ||
1145 | } | 1135 | } |
1146 | 1136 | ||
1147 | static void | 1137 | static void |
@@ -1164,6 +1154,72 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1164 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1154 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1165 | } | 1155 | } |
1166 | 1156 | ||
1157 | /* | ||
1158 | * Match the hw provided rate index (through descriptors) | ||
1159 | * to an index for sc->curband->bitrates, so it can be used | ||
1160 | * by the stack. | ||
1161 | * | ||
1162 | * This one is a little bit tricky but i think i'm right | ||
1163 | * about this... | ||
1164 | * | ||
1165 | * We have 4 rate tables in the following order: | ||
1166 | * XR (4 rates) | ||
1167 | * 802.11a (8 rates) | ||
1168 | * 802.11b (4 rates) | ||
1169 | * 802.11g (12 rates) | ||
1170 | * that make the hw rate table. | ||
1171 | * | ||
1172 | * Lets take a 5211 for example that supports a and b modes only. | ||
1173 | * First comes the 802.11a table and then 802.11b (total 12 rates). | ||
1174 | * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit), | ||
1175 | * if it returns 2 it points to the second 802.11a rate etc. | ||
1176 | * | ||
1177 | * Same goes for 5212 who has xr/a/b/g support (total 28 rates). | ||
1178 | * First comes the XR table, then 802.11a, 802.11b and 802.11g. | ||
1179 | * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc | ||
1180 | */ | ||
1181 | static void | ||
1182 | ath5k_set_total_hw_rates(struct ath5k_softc *sc) { | ||
1183 | |||
1184 | struct ath5k_hw *ah = sc->ah; | ||
1185 | |||
1186 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
1187 | sc->a_rates = 8; | ||
1188 | |||
1189 | if (test_bit(AR5K_MODE_11B, ah->ah_modes)) | ||
1190 | sc->b_rates = 4; | ||
1191 | |||
1192 | if (test_bit(AR5K_MODE_11G, ah->ah_modes)) | ||
1193 | sc->g_rates = 12; | ||
1194 | |||
1195 | /* XXX: Need to see what what happens when | ||
1196 | xr disable bits in eeprom are set */ | ||
1197 | if (ah->ah_version >= AR5K_AR5212) | ||
1198 | sc->xr_rates = 4; | ||
1199 | |||
1200 | } | ||
1201 | |||
1202 | static inline int | ||
1203 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) { | ||
1204 | |||
1205 | int mac80211_rix; | ||
1206 | |||
1207 | if(sc->curband->band == IEEE80211_BAND_2GHZ) { | ||
1208 | /* We setup a g ratetable for both b/g modes */ | ||
1209 | mac80211_rix = | ||
1210 | hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates; | ||
1211 | } else { | ||
1212 | mac80211_rix = hw_rix - sc->xr_rates; | ||
1213 | } | ||
1214 | |||
1215 | /* Something went wrong, fallback to basic rate for this band */ | ||
1216 | if ((mac80211_rix >= sc->curband->n_bitrates) || | ||
1217 | (mac80211_rix <= 0 )) | ||
1218 | mac80211_rix = 1; | ||
1219 | |||
1220 | return mac80211_rix; | ||
1221 | } | ||
1222 | |||
1167 | 1223 | ||
1168 | 1224 | ||
1169 | 1225 | ||
@@ -1268,7 +1324,8 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1268 | 1324 | ||
1269 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1325 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1270 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1326 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
1271 | (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0); | 1327 | (sc->power_level * 2), ctl->tx_rate->hw_value, |
1328 | ctl->retry_limit, keyidx, 0, flags, 0, 0); | ||
1272 | if (ret) | 1329 | if (ret) |
1273 | goto err_unmap; | 1330 | goto err_unmap; |
1274 | 1331 | ||
@@ -1660,11 +1717,11 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) | |||
1660 | u32 hw_tu; | 1717 | u32 hw_tu; |
1661 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1718 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1662 | 1719 | ||
1663 | if ((mgmt->frame_control & IEEE80211_FCTL_FTYPE) == | 1720 | if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) == |
1664 | IEEE80211_FTYPE_MGMT && | 1721 | IEEE80211_FTYPE_MGMT && |
1665 | (mgmt->frame_control & IEEE80211_FCTL_STYPE) == | 1722 | (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) == |
1666 | IEEE80211_STYPE_BEACON && | 1723 | IEEE80211_STYPE_BEACON && |
1667 | mgmt->u.beacon.capab_info & WLAN_CAPABILITY_IBSS && | 1724 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1668 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { | 1725 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { |
1669 | /* | 1726 | /* |
1670 | * Received an IBSS beacon with the same BSSID. Hardware might | 1727 | * Received an IBSS beacon with the same BSSID. Hardware might |
@@ -1673,7 +1730,7 @@ ath5k_check_ibss_hw_merge(struct ath5k_softc *sc, struct sk_buff *skb) | |||
1673 | hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); | 1730 | hw_tu = TSF_TO_TU(ath5k_hw_get_tsf64(sc->ah)); |
1674 | if (hw_tu >= sc->nexttbtt) { | 1731 | if (hw_tu >= sc->nexttbtt) { |
1675 | ath5k_beacon_update_timers(sc, | 1732 | ath5k_beacon_update_timers(sc, |
1676 | mgmt->u.beacon.timestamp); | 1733 | le64_to_cpu(mgmt->u.beacon.timestamp)); |
1677 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, | 1734 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, |
1678 | "detected HW merge from received beacon\n"); | 1735 | "detected HW merge from received beacon\n"); |
1679 | } | 1736 | } |
@@ -1791,9 +1848,8 @@ accept: | |||
1791 | rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); | 1848 | rxs.mactime = ath5k_extend_tsf(sc->ah, ds->ds_rxstat.rs_tstamp); |
1792 | rxs.flag |= RX_FLAG_TSFT; | 1849 | rxs.flag |= RX_FLAG_TSFT; |
1793 | 1850 | ||
1794 | rxs.freq = sc->curchan->freq; | 1851 | rxs.freq = sc->curchan->center_freq; |
1795 | rxs.channel = sc->curchan->chan; | 1852 | rxs.band = sc->curband->band; |
1796 | rxs.phymode = sc->curmode; | ||
1797 | 1853 | ||
1798 | /* | 1854 | /* |
1799 | * signal quality: | 1855 | * signal quality: |
@@ -1811,7 +1867,8 @@ accept: | |||
1811 | rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; | 1867 | rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64; |
1812 | 1868 | ||
1813 | rxs.antenna = ds->ds_rxstat.rs_antenna; | 1869 | rxs.antenna = ds->ds_rxstat.rs_antenna; |
1814 | rxs.rate = ds->ds_rxstat.rs_rate; | 1870 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, |
1871 | ds->ds_rxstat.rs_rate); | ||
1815 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); | 1872 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb); |
1816 | 1873 | ||
1817 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1874 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
@@ -1958,8 +2015,9 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1958 | ds->ds_data = bf->skbaddr; | 2015 | ds->ds_data = bf->skbaddr; |
1959 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, | 2016 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, |
1960 | ieee80211_get_hdrlen_from_skb(skb), | 2017 | ieee80211_get_hdrlen_from_skb(skb), |
1961 | AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1, | 2018 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), |
1962 | AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0); | 2019 | ctl->tx_rate->hw_value, 1, AR5K_TXKEYIX_INVALID, |
2020 | antenna, flags, 0, 0); | ||
1963 | if (ret) | 2021 | if (ret) |
1964 | goto err_unmap; | 2022 | goto err_unmap; |
1965 | 2023 | ||
@@ -2211,7 +2269,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2211 | * be followed by initialization of the appropriate bits | 2269 | * be followed by initialization of the appropriate bits |
2212 | * and then setup of the interrupt mask. | 2270 | * and then setup of the interrupt mask. |
2213 | */ | 2271 | */ |
2214 | sc->curchan = sc->hw->conf.chan; | 2272 | sc->curchan = sc->hw->conf.channel; |
2273 | sc->curband = &sc->sbands[sc->curchan->band]; | ||
2215 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); | 2274 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); |
2216 | if (ret) { | 2275 | if (ret) { |
2217 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); | 2276 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); |
@@ -2448,7 +2507,8 @@ ath5k_calibrate(unsigned long data) | |||
2448 | struct ath5k_hw *ah = sc->ah; | 2507 | struct ath5k_hw *ah = sc->ah; |
2449 | 2508 | ||
2450 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", | 2509 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", |
2451 | sc->curchan->chan, sc->curchan->val); | 2510 | ieee80211_frequency_to_channel(sc->curchan->center_freq), |
2511 | sc->curchan->hw_value); | ||
2452 | 2512 | ||
2453 | if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { | 2513 | if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) { |
2454 | /* | 2514 | /* |
@@ -2460,7 +2520,8 @@ ath5k_calibrate(unsigned long data) | |||
2460 | } | 2520 | } |
2461 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) | 2521 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) |
2462 | ATH5K_ERR(sc, "calibration of channel %u failed\n", | 2522 | ATH5K_ERR(sc, "calibration of channel %u failed\n", |
2463 | sc->curchan->chan); | 2523 | ieee80211_frequency_to_channel( |
2524 | sc->curchan->center_freq)); | ||
2464 | 2525 | ||
2465 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + | 2526 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + |
2466 | msecs_to_jiffies(ath5k_calinterval * 1000))); | 2527 | msecs_to_jiffies(ath5k_calinterval * 1000))); |
@@ -2558,7 +2619,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2558 | memmove(skb->data, skb->data+pad, hdrlen); | 2619 | memmove(skb->data, skb->data+pad, hdrlen); |
2559 | } | 2620 | } |
2560 | 2621 | ||
2561 | sc->led_txrate = ctl->tx_rate; | 2622 | sc->led_txrate = ctl->tx_rate->hw_value; |
2562 | 2623 | ||
2563 | spin_lock_irqsave(&sc->txbuflock, flags); | 2624 | spin_lock_irqsave(&sc->txbuflock, flags); |
2564 | if (list_empty(&sc->txbuf)) { | 2625 | if (list_empty(&sc->txbuf)) { |
@@ -2597,11 +2658,6 @@ ath5k_reset(struct ieee80211_hw *hw) | |||
2597 | int ret; | 2658 | int ret; |
2598 | 2659 | ||
2599 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2660 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
2600 | /* | ||
2601 | * Convert to a hw channel description with the flags | ||
2602 | * constrained to reflect the current operating mode. | ||
2603 | */ | ||
2604 | sc->curchan = hw->conf.chan; | ||
2605 | 2661 | ||
2606 | ath5k_hw_set_intr(ah, 0); | 2662 | ath5k_hw_set_intr(ah, 0); |
2607 | ath5k_txq_cleanup(sc); | 2663 | ath5k_txq_cleanup(sc); |
@@ -2692,6 +2748,9 @@ end: | |||
2692 | mutex_unlock(&sc->lock); | 2748 | mutex_unlock(&sc->lock); |
2693 | } | 2749 | } |
2694 | 2750 | ||
2751 | /* | ||
2752 | * TODO: Phy disable/diversity etc | ||
2753 | */ | ||
2695 | static int | 2754 | static int |
2696 | ath5k_config(struct ieee80211_hw *hw, | 2755 | ath5k_config(struct ieee80211_hw *hw, |
2697 | struct ieee80211_conf *conf) | 2756 | struct ieee80211_conf *conf) |
@@ -2699,9 +2758,9 @@ ath5k_config(struct ieee80211_hw *hw, | |||
2699 | struct ath5k_softc *sc = hw->priv; | 2758 | struct ath5k_softc *sc = hw->priv; |
2700 | 2759 | ||
2701 | sc->bintval = conf->beacon_int; | 2760 | sc->bintval = conf->beacon_int; |
2702 | ath5k_setcurmode(sc, conf->phymode); | 2761 | sc->power_level = conf->power_level; |
2703 | 2762 | ||
2704 | return ath5k_chan_set(sc, conf->chan); | 2763 | return ath5k_chan_set(sc, conf->channel); |
2705 | } | 2764 | } |
2706 | 2765 | ||
2707 | static int | 2766 | static int |
@@ -2869,7 +2928,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2869 | 2928 | ||
2870 | switch(key->alg) { | 2929 | switch(key->alg) { |
2871 | case ALG_WEP: | 2930 | case ALG_WEP: |
2872 | break; | 2931 | /* XXX: fix hardware encryption, its not working. For now |
2932 | * allow software encryption */ | ||
2933 | /* break; */ | ||
2873 | case ALG_TKIP: | 2934 | case ALG_TKIP: |
2874 | case ALG_CCMP: | 2935 | case ALG_CCMP: |
2875 | return -EOPNOTSUPP; | 2936 | return -EOPNOTSUPP; |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 8287ae787f12..3a9755893018 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -83,7 +83,7 @@ struct ath5k_txq { | |||
83 | #if CHAN_DEBUG | 83 | #if CHAN_DEBUG |
84 | #define ATH_CHAN_MAX (26+26+26+200+200) | 84 | #define ATH_CHAN_MAX (26+26+26+200+200) |
85 | #else | 85 | #else |
86 | #define ATH_CHAN_MAX (14+14+14+252+20) /* XXX what's the max? */ | 86 | #define ATH_CHAN_MAX (14+14+14+252+20) |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | /* Software Carrier, keeps track of the driver state | 89 | /* Software Carrier, keeps track of the driver state |
@@ -95,15 +95,22 @@ struct ath5k_softc { | |||
95 | struct ieee80211_tx_queue_stats tx_stats; | 95 | struct ieee80211_tx_queue_stats tx_stats; |
96 | struct ieee80211_low_level_stats ll_stats; | 96 | struct ieee80211_low_level_stats ll_stats; |
97 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 97 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
98 | struct ieee80211_hw_mode modes[NUM_DRIVER_MODES]; | 98 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
99 | struct ieee80211_channel channels[ATH_CHAN_MAX]; | 99 | struct ieee80211_channel channels[ATH_CHAN_MAX]; |
100 | struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_DRIVER_MODES]; | 100 | struct ieee80211_rate rates[AR5K_MAX_RATES * IEEE80211_NUM_BANDS]; |
101 | enum ieee80211_if_types opmode; | 101 | enum ieee80211_if_types opmode; |
102 | struct ath5k_hw *ah; /* Atheros HW */ | 102 | struct ath5k_hw *ah; /* Atheros HW */ |
103 | 103 | ||
104 | #if ATH5K_DEBUG | 104 | struct ieee80211_supported_band *curband; |
105 | |||
106 | u8 a_rates; | ||
107 | u8 b_rates; | ||
108 | u8 g_rates; | ||
109 | u8 xr_rates; | ||
110 | |||
111 | #ifdef CONFIG_ATH5K_DEBUG | ||
105 | struct ath5k_dbg_info debug; /* debug info */ | 112 | struct ath5k_dbg_info debug; /* debug info */ |
106 | #endif | 113 | #endif /* CONFIG_ATH5K_DEBUG */ |
107 | 114 | ||
108 | struct ath5k_buf *bufptr; /* allocated buffer ptr */ | 115 | struct ath5k_buf *bufptr; /* allocated buffer ptr */ |
109 | struct ath5k_desc *desc; /* TX/RX descriptors */ | 116 | struct ath5k_desc *desc; /* TX/RX descriptors */ |
@@ -169,6 +176,7 @@ struct ath5k_softc { | |||
169 | unsigned int nexttbtt; /* next beacon time in TU */ | 176 | unsigned int nexttbtt; /* next beacon time in TU */ |
170 | 177 | ||
171 | struct timer_list calib_tim; /* calibration timer */ | 178 | struct timer_list calib_tim; /* calibration timer */ |
179 | int power_level; /* Requested tx power in dbm */ | ||
172 | }; | 180 | }; |
173 | 181 | ||
174 | #define ath5k_hw_hasbssidmask(_ah) \ | 182 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index bb581ef6d1ef..05bf4fb8f907 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -65,7 +65,7 @@ static unsigned int ath5k_debug; | |||
65 | module_param_named(debug, ath5k_debug, uint, 0); | 65 | module_param_named(debug, ath5k_debug, uint, 0); |
66 | 66 | ||
67 | 67 | ||
68 | #if ATH5K_DEBUG | 68 | #ifdef CONFIG_ATH5K_DEBUG |
69 | 69 | ||
70 | #include <linux/seq_file.h> | 70 | #include <linux/seq_file.h> |
71 | #include "reg.h" | 71 | #include "reg.h" |
@@ -340,7 +340,7 @@ static struct { | |||
340 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, | 340 | { ATH5K_DEBUG_LED, "led", "LED mamagement" }, |
341 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, | 341 | { ATH5K_DEBUG_DUMP_RX, "dumprx", "print received skb content" }, |
342 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | 342 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, |
343 | { ATH5K_DEBUG_DUMPMODES, "dumpmodes", "dump modes" }, | 343 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
344 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, | 344 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, |
345 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, | 345 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, |
346 | }; | 346 | }; |
@@ -452,30 +452,47 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
452 | /* functions used in other places */ | 452 | /* functions used in other places */ |
453 | 453 | ||
454 | void | 454 | void |
455 | ath5k_debug_dump_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes) | 455 | ath5k_debug_dump_bands(struct ath5k_softc *sc) |
456 | { | 456 | { |
457 | unsigned int m, i; | 457 | unsigned int b, i; |
458 | 458 | ||
459 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES))) | 459 | if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS))) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | for (m = 0; m < NUM_DRIVER_MODES; m++) { | 462 | BUG_ON(!sc->sbands); |
463 | printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m, | 463 | |
464 | modes[m].num_channels, modes[m].num_rates); | 464 | for (b = 0; b < IEEE80211_NUM_BANDS; b++) { |
465 | struct ieee80211_supported_band *band = &sc->sbands[b]; | ||
466 | char bname[5]; | ||
467 | switch (band->band) { | ||
468 | case IEEE80211_BAND_2GHZ: | ||
469 | strcpy(bname, "2 GHz"); | ||
470 | break; | ||
471 | case IEEE80211_BAND_5GHZ: | ||
472 | strcpy(bname, "5 GHz"); | ||
473 | break; | ||
474 | default: | ||
475 | printk(KERN_DEBUG "Band not supported: %d\n", | ||
476 | band->band); | ||
477 | return; | ||
478 | } | ||
479 | printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname, | ||
480 | band->n_channels, band->n_bitrates); | ||
465 | printk(KERN_DEBUG " channels:\n"); | 481 | printk(KERN_DEBUG " channels:\n"); |
466 | for (i = 0; i < modes[m].num_channels; i++) | 482 | for (i = 0; i < band->n_channels; i++) |
467 | printk(KERN_DEBUG " %3d %d %.4x %.4x\n", | 483 | printk(KERN_DEBUG " %3d %d %.4x %.4x\n", |
468 | modes[m].channels[i].chan, | 484 | ieee80211_frequency_to_channel( |
469 | modes[m].channels[i].freq, | 485 | band->channels[i].center_freq), |
470 | modes[m].channels[i].val, | 486 | band->channels[i].center_freq, |
471 | modes[m].channels[i].flag); | 487 | band->channels[i].hw_value, |
488 | band->channels[i].flags); | ||
472 | printk(KERN_DEBUG " rates:\n"); | 489 | printk(KERN_DEBUG " rates:\n"); |
473 | for (i = 0; i < modes[m].num_rates; i++) | 490 | for (i = 0; i < band->n_bitrates; i++) |
474 | printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", | 491 | printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n", |
475 | modes[m].rates[i].rate, | 492 | band->bitrates[i].bitrate, |
476 | modes[m].rates[i].val, | 493 | band->bitrates[i].hw_value, |
477 | modes[m].rates[i].flags, | 494 | band->bitrates[i].flags, |
478 | modes[m].rates[i].val2); | 495 | band->bitrates[i].hw_value_short); |
479 | } | 496 | } |
480 | } | 497 | } |
481 | 498 | ||
@@ -548,4 +565,4 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, | |||
548 | !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); | 565 | !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!'); |
549 | } | 566 | } |
550 | 567 | ||
551 | #endif /* if ATH5K_DEBUG */ | 568 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ |
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h index c4fd8c43df0c..8c0b5c57c76b 100644 --- a/drivers/net/wireless/ath5k/debug.h +++ b/drivers/net/wireless/ath5k/debug.h | |||
@@ -61,11 +61,6 @@ | |||
61 | #ifndef _ATH5K_DEBUG_H | 61 | #ifndef _ATH5K_DEBUG_H |
62 | #define _ATH5K_DEBUG_H | 62 | #define _ATH5K_DEBUG_H |
63 | 63 | ||
64 | /* set this to 1 for debugging output */ | ||
65 | #ifndef ATH5K_DEBUG | ||
66 | #define ATH5K_DEBUG 0 | ||
67 | #endif | ||
68 | |||
69 | struct ath5k_softc; | 64 | struct ath5k_softc; |
70 | struct ath5k_hw; | 65 | struct ath5k_hw; |
71 | struct ieee80211_hw_mode; | 66 | struct ieee80211_hw_mode; |
@@ -96,7 +91,7 @@ struct ath5k_dbg_info { | |||
96 | * @ATH5K_DEBUG_LED: led management | 91 | * @ATH5K_DEBUG_LED: led management |
97 | * @ATH5K_DEBUG_DUMP_RX: print received skb content | 92 | * @ATH5K_DEBUG_DUMP_RX: print received skb content |
98 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content | 93 | * @ATH5K_DEBUG_DUMP_TX: print transmit skb content |
99 | * @ATH5K_DEBUG_DUMPMODES: dump modes | 94 | * @ATH5K_DEBUG_DUMPBANDS: dump bands |
100 | * @ATH5K_DEBUG_TRACE: trace function calls | 95 | * @ATH5K_DEBUG_TRACE: trace function calls |
101 | * @ATH5K_DEBUG_ANY: show at any debug level | 96 | * @ATH5K_DEBUG_ANY: show at any debug level |
102 | * | 97 | * |
@@ -118,12 +113,12 @@ enum ath5k_debug_level { | |||
118 | ATH5K_DEBUG_LED = 0x00000080, | 113 | ATH5K_DEBUG_LED = 0x00000080, |
119 | ATH5K_DEBUG_DUMP_RX = 0x00000100, | 114 | ATH5K_DEBUG_DUMP_RX = 0x00000100, |
120 | ATH5K_DEBUG_DUMP_TX = 0x00000200, | 115 | ATH5K_DEBUG_DUMP_TX = 0x00000200, |
121 | ATH5K_DEBUG_DUMPMODES = 0x00000400, | 116 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, |
122 | ATH5K_DEBUG_TRACE = 0x00001000, | 117 | ATH5K_DEBUG_TRACE = 0x00001000, |
123 | ATH5K_DEBUG_ANY = 0xffffffff | 118 | ATH5K_DEBUG_ANY = 0xffffffff |
124 | }; | 119 | }; |
125 | 120 | ||
126 | #if ATH5K_DEBUG | 121 | #ifdef CONFIG_ATH5K_DEBUG |
127 | 122 | ||
128 | #define ATH5K_TRACE(_sc) do { \ | 123 | #define ATH5K_TRACE(_sc) do { \ |
129 | if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ | 124 | if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \ |
@@ -158,8 +153,7 @@ void | |||
158 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); | 153 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah); |
159 | 154 | ||
160 | void | 155 | void |
161 | ath5k_debug_dump_modes(struct ath5k_softc *sc, | 156 | ath5k_debug_dump_bands(struct ath5k_softc *sc); |
162 | struct ieee80211_hw_mode *modes); | ||
163 | 157 | ||
164 | void | 158 | void |
165 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | 159 | ath5k_debug_dump_skb(struct ath5k_softc *sc, |
@@ -171,7 +165,9 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, | |||
171 | 165 | ||
172 | #else /* no debugging */ | 166 | #else /* no debugging */ |
173 | 167 | ||
174 | #define ATH5K_TRACE(_sc) /* empty */ | 168 | #include <linux/compiler.h> |
169 | |||
170 | #define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc)) | ||
175 | 171 | ||
176 | static inline void __attribute__ ((format (printf, 3, 4))) | 172 | static inline void __attribute__ ((format (printf, 3, 4))) |
177 | ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} | 173 | ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} |
@@ -196,8 +192,7 @@ static inline void | |||
196 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} | 192 | ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {} |
197 | 193 | ||
198 | static inline void | 194 | static inline void |
199 | ath5k_debug_dump_modes(struct ath5k_softc *sc, | 195 | ath5k_debug_dump_bands(struct ath5k_softc *sc) {} |
200 | struct ieee80211_hw_mode *modes) {} | ||
201 | 196 | ||
202 | static inline void | 197 | static inline void |
203 | ath5k_debug_dump_skb(struct ath5k_softc *sc, | 198 | ath5k_debug_dump_skb(struct ath5k_softc *sc, |
@@ -207,6 +202,6 @@ static inline void | |||
207 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, | 202 | ath5k_debug_printtxbuf(struct ath5k_softc *sc, |
208 | struct ath5k_buf *bf, int done) {} | 203 | struct ath5k_buf *bf, int done) {} |
209 | 204 | ||
210 | #endif /* if ATH5K_DEBUG */ | 205 | #endif /* ifdef CONFIG_ATH5K_DEBUG */ |
211 | 206 | ||
212 | #endif /* ifndef _ATH5K_DEBUG_H */ | 207 | #endif /* ifndef _ATH5K_DEBUG_H */ |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index c2de2d958e8e..eec2b806a0de 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -140,9 +140,6 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | |||
140 | * HW information | 140 | * HW information |
141 | */ | 141 | */ |
142 | 142 | ||
143 | /* Get reg domain from eeprom */ | ||
144 | ath5k_get_regdomain(ah); | ||
145 | |||
146 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; | 143 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; |
147 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 144 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
148 | ah->ah_turbo = false; | 145 | ah->ah_turbo = false; |
@@ -405,15 +402,15 @@ const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, | |||
405 | 402 | ||
406 | /* Get rate tables */ | 403 | /* Get rate tables */ |
407 | switch (mode) { | 404 | switch (mode) { |
408 | case MODE_IEEE80211A: | 405 | case AR5K_MODE_11A: |
409 | return &ath5k_rt_11a; | 406 | return &ath5k_rt_11a; |
410 | case MODE_ATHEROS_TURBO: | 407 | case AR5K_MODE_11A_TURBO: |
411 | return &ath5k_rt_turbo; | 408 | return &ath5k_rt_turbo; |
412 | case MODE_IEEE80211B: | 409 | case AR5K_MODE_11B: |
413 | return &ath5k_rt_11b; | 410 | return &ath5k_rt_11b; |
414 | case MODE_IEEE80211G: | 411 | case AR5K_MODE_11G: |
415 | return &ath5k_rt_11g; | 412 | return &ath5k_rt_11g; |
416 | case MODE_ATHEROS_TURBOG: | 413 | case AR5K_MODE_11G_TURBO: |
417 | return &ath5k_rt_xr; | 414 | return &ath5k_rt_xr; |
418 | } | 415 | } |
419 | 416 | ||
@@ -457,15 +454,15 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
457 | ds_coef_exp, ds_coef_man, clock; | 454 | ds_coef_exp, ds_coef_man, clock; |
458 | 455 | ||
459 | if (!(ah->ah_version == AR5K_AR5212) || | 456 | if (!(ah->ah_version == AR5K_AR5212) || |
460 | !(channel->val & CHANNEL_OFDM)) | 457 | !(channel->hw_value & CHANNEL_OFDM)) |
461 | BUG(); | 458 | BUG(); |
462 | 459 | ||
463 | /* Seems there are two PLLs, one for baseband sampling and one | 460 | /* Seems there are two PLLs, one for baseband sampling and one |
464 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | 461 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in |
465 | * turbo. */ | 462 | * turbo. */ |
466 | clock = channel->val & CHANNEL_TURBO ? 80 : 40; | 463 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; |
467 | coef_scaled = ((5 * (clock << 24)) / 2) / | 464 | coef_scaled = ((5 * (clock << 24)) / 2) / |
468 | channel->freq; | 465 | channel->center_freq; |
469 | 466 | ||
470 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | 467 | for (coef_exp = 31; coef_exp > 0; coef_exp--) |
471 | if ((coef_scaled >> coef_exp) & 0x1) | 468 | if ((coef_scaled >> coef_exp) & 0x1) |
@@ -492,8 +489,7 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
492 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | 489 | * ath5k_hw_write_rate_duration - set rate duration during hw resets |
493 | * | 490 | * |
494 | * @ah: the &struct ath5k_hw | 491 | * @ah: the &struct ath5k_hw |
495 | * @driver_mode: one of enum ieee80211_phymode or our one of our own | 492 | * @mode: one of enum ath5k_driver_mode |
496 | * vendor modes | ||
497 | * | 493 | * |
498 | * Write the rate duration table for the current mode upon hw reset. This | 494 | * Write the rate duration table for the current mode upon hw reset. This |
499 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting | 495 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting |
@@ -504,19 +500,20 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | |||
504 | * | 500 | * |
505 | */ | 501 | */ |
506 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | 502 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, |
507 | unsigned int driver_mode) | 503 | unsigned int mode) |
508 | { | 504 | { |
509 | struct ath5k_softc *sc = ah->ah_sc; | 505 | struct ath5k_softc *sc = ah->ah_sc; |
510 | const struct ath5k_rate_table *rt; | 506 | const struct ath5k_rate_table *rt; |
507 | struct ieee80211_rate srate = {}; | ||
511 | unsigned int i; | 508 | unsigned int i; |
512 | 509 | ||
513 | /* Get rate table for the current operating mode */ | 510 | /* Get rate table for the current operating mode */ |
514 | rt = ath5k_hw_get_rate_table(ah, | 511 | rt = ath5k_hw_get_rate_table(ah, mode); |
515 | driver_mode); | ||
516 | 512 | ||
517 | /* Write rate duration table */ | 513 | /* Write rate duration table */ |
518 | for (i = 0; i < rt->rate_count; i++) { | 514 | for (i = 0; i < rt->rate_count; i++) { |
519 | const struct ath5k_rate *rate, *control_rate; | 515 | const struct ath5k_rate *rate, *control_rate; |
516 | |||
520 | u32 reg; | 517 | u32 reg; |
521 | u16 tx_time; | 518 | u16 tx_time; |
522 | 519 | ||
@@ -526,14 +523,16 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | |||
526 | /* Set ACK timeout */ | 523 | /* Set ACK timeout */ |
527 | reg = AR5K_RATE_DUR(rate->rate_code); | 524 | reg = AR5K_RATE_DUR(rate->rate_code); |
528 | 525 | ||
526 | srate.bitrate = control_rate->rate_kbps/100; | ||
527 | |||
529 | /* An ACK frame consists of 10 bytes. If you add the FCS, | 528 | /* An ACK frame consists of 10 bytes. If you add the FCS, |
530 | * which ieee80211_generic_frame_duration() adds, | 529 | * which ieee80211_generic_frame_duration() adds, |
531 | * its 14 bytes. Note we use the control rate and not the | 530 | * its 14 bytes. Note we use the control rate and not the |
532 | * actual rate for this rate. See mac80211 tx.c | 531 | * actual rate for this rate. See mac80211 tx.c |
533 | * ieee80211_duration() for a brief description of | 532 | * ieee80211_duration() for a brief description of |
534 | * what rate we should choose to TX ACKs. */ | 533 | * what rate we should choose to TX ACKs. */ |
535 | tx_time = ieee80211_generic_frame_duration(sc->hw, | 534 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, |
536 | sc->vif, 10, control_rate->rate_kbps/100); | 535 | sc->vif, 10, &srate)); |
537 | 536 | ||
538 | ath5k_hw_reg_write(ah, tx_time, reg); | 537 | ath5k_hw_reg_write(ah, tx_time, reg); |
539 | 538 | ||
@@ -567,7 +566,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
567 | { | 566 | { |
568 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 567 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
569 | u32 data, s_seq, s_ant, s_led[3]; | 568 | u32 data, s_seq, s_ant, s_led[3]; |
570 | unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1; | 569 | unsigned int i, mode, freq, ee_mode, ant[2]; |
571 | int ret; | 570 | int ret; |
572 | 571 | ||
573 | ATH5K_TRACE(ah->ah_sc); | 572 | ATH5K_TRACE(ah->ah_sc); |
@@ -602,7 +601,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
602 | 601 | ||
603 | 602 | ||
604 | /*Wakeup the device*/ | 603 | /*Wakeup the device*/ |
605 | ret = ath5k_hw_nic_wakeup(ah, channel->val, false); | 604 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); |
606 | if (ret) | 605 | if (ret) |
607 | return ret; | 606 | return ret; |
608 | 607 | ||
@@ -624,37 +623,32 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
624 | return -EINVAL; | 623 | return -EINVAL; |
625 | } | 624 | } |
626 | 625 | ||
627 | switch (channel->val & CHANNEL_MODES) { | 626 | switch (channel->hw_value & CHANNEL_MODES) { |
628 | case CHANNEL_A: | 627 | case CHANNEL_A: |
629 | mode = AR5K_INI_VAL_11A; | 628 | mode = AR5K_MODE_11A; |
630 | freq = AR5K_INI_RFGAIN_5GHZ; | 629 | freq = AR5K_INI_RFGAIN_5GHZ; |
631 | ee_mode = AR5K_EEPROM_MODE_11A; | 630 | ee_mode = AR5K_EEPROM_MODE_11A; |
632 | driver_mode = MODE_IEEE80211A; | ||
633 | break; | 631 | break; |
634 | case CHANNEL_G: | 632 | case CHANNEL_G: |
635 | mode = AR5K_INI_VAL_11G; | 633 | mode = AR5K_MODE_11G; |
636 | freq = AR5K_INI_RFGAIN_2GHZ; | 634 | freq = AR5K_INI_RFGAIN_2GHZ; |
637 | ee_mode = AR5K_EEPROM_MODE_11G; | 635 | ee_mode = AR5K_EEPROM_MODE_11G; |
638 | driver_mode = MODE_IEEE80211G; | ||
639 | break; | 636 | break; |
640 | case CHANNEL_B: | 637 | case CHANNEL_B: |
641 | mode = AR5K_INI_VAL_11B; | 638 | mode = AR5K_MODE_11B; |
642 | freq = AR5K_INI_RFGAIN_2GHZ; | 639 | freq = AR5K_INI_RFGAIN_2GHZ; |
643 | ee_mode = AR5K_EEPROM_MODE_11B; | 640 | ee_mode = AR5K_EEPROM_MODE_11B; |
644 | driver_mode = MODE_IEEE80211B; | ||
645 | break; | 641 | break; |
646 | case CHANNEL_T: | 642 | case CHANNEL_T: |
647 | mode = AR5K_INI_VAL_11A_TURBO; | 643 | mode = AR5K_MODE_11A_TURBO; |
648 | freq = AR5K_INI_RFGAIN_5GHZ; | 644 | freq = AR5K_INI_RFGAIN_5GHZ; |
649 | ee_mode = AR5K_EEPROM_MODE_11A; | 645 | ee_mode = AR5K_EEPROM_MODE_11A; |
650 | driver_mode = MODE_ATHEROS_TURBO; | ||
651 | break; | 646 | break; |
652 | /*Is this ok on 5211 too ?*/ | 647 | /*Is this ok on 5211 too ?*/ |
653 | case CHANNEL_TG: | 648 | case CHANNEL_TG: |
654 | mode = AR5K_INI_VAL_11G_TURBO; | 649 | mode = AR5K_MODE_11G_TURBO; |
655 | freq = AR5K_INI_RFGAIN_2GHZ; | 650 | freq = AR5K_INI_RFGAIN_2GHZ; |
656 | ee_mode = AR5K_EEPROM_MODE_11G; | 651 | ee_mode = AR5K_EEPROM_MODE_11G; |
657 | driver_mode = MODE_ATHEROS_TURBOG; | ||
658 | break; | 652 | break; |
659 | case CHANNEL_XR: | 653 | case CHANNEL_XR: |
660 | if (ah->ah_version == AR5K_AR5211) { | 654 | if (ah->ah_version == AR5K_AR5211) { |
@@ -662,14 +656,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
662 | "XR mode not available on 5211"); | 656 | "XR mode not available on 5211"); |
663 | return -EINVAL; | 657 | return -EINVAL; |
664 | } | 658 | } |
665 | mode = AR5K_INI_VAL_XR; | 659 | mode = AR5K_MODE_XR; |
666 | freq = AR5K_INI_RFGAIN_5GHZ; | 660 | freq = AR5K_INI_RFGAIN_5GHZ; |
667 | ee_mode = AR5K_EEPROM_MODE_11A; | 661 | ee_mode = AR5K_EEPROM_MODE_11A; |
668 | driver_mode = MODE_IEEE80211A; | ||
669 | break; | 662 | break; |
670 | default: | 663 | default: |
671 | ATH5K_ERR(ah->ah_sc, | 664 | ATH5K_ERR(ah->ah_sc, |
672 | "invalid channel: %d\n", channel->freq); | 665 | "invalid channel: %d\n", channel->center_freq); |
673 | return -EINVAL; | 666 | return -EINVAL; |
674 | } | 667 | } |
675 | 668 | ||
@@ -702,7 +695,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
702 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ | 695 | if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */ |
703 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); | 696 | ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11)); |
704 | 697 | ||
705 | if (channel->val == CHANNEL_G) | 698 | if (channel->hw_value == CHANNEL_G) |
706 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ | 699 | ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */ |
707 | else | 700 | else |
708 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); | 701 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83)); |
@@ -720,7 +713,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
720 | AR5K_SREV_RAD_5112A) { | 713 | AR5K_SREV_RAD_5112A) { |
721 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | 714 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, |
722 | AR5K_PHY_CCKTXCTL); | 715 | AR5K_PHY_CCKTXCTL); |
723 | if (channel->val & CHANNEL_5GHZ) | 716 | if (channel->hw_value & CHANNEL_5GHZ) |
724 | data = 0xffb81020; | 717 | data = 0xffb81020; |
725 | else | 718 | else |
726 | data = 0xffb80d20; | 719 | data = 0xffb80d20; |
@@ -740,7 +733,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
740 | * mac80211 are integrated */ | 733 | * mac80211 are integrated */ |
741 | if (ah->ah_version == AR5K_AR5212 && | 734 | if (ah->ah_version == AR5K_AR5212 && |
742 | ah->ah_sc->vif != NULL) | 735 | ah->ah_sc->vif != NULL) |
743 | ath5k_hw_write_rate_duration(ah, driver_mode); | 736 | ath5k_hw_write_rate_duration(ah, mode); |
744 | 737 | ||
745 | /* | 738 | /* |
746 | * Write RF registers | 739 | * Write RF registers |
@@ -756,7 +749,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
756 | 749 | ||
757 | /* Write OFDM timings on 5212*/ | 750 | /* Write OFDM timings on 5212*/ |
758 | if (ah->ah_version == AR5K_AR5212 && | 751 | if (ah->ah_version == AR5K_AR5212 && |
759 | channel->val & CHANNEL_OFDM) { | 752 | channel->hw_value & CHANNEL_OFDM) { |
760 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | 753 | ret = ath5k_hw_write_ofdm_timings(ah, channel); |
761 | if (ret) | 754 | if (ret) |
762 | return ret; | 755 | return ret; |
@@ -765,7 +758,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
765 | /*Enable/disable 802.11b mode on 5111 | 758 | /*Enable/disable 802.11b mode on 5111 |
766 | (enable 2111 frequency converter + CCK)*/ | 759 | (enable 2111 frequency converter + CCK)*/ |
767 | if (ah->ah_radio == AR5K_RF5111) { | 760 | if (ah->ah_radio == AR5K_RF5111) { |
768 | if (driver_mode == MODE_IEEE80211B) | 761 | if (mode == AR5K_MODE_11B) |
769 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | 762 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, |
770 | AR5K_TXCFG_B_MODE); | 763 | AR5K_TXCFG_B_MODE); |
771 | else | 764 | else |
@@ -903,7 +896,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
903 | if (ah->ah_version != AR5K_AR5210) { | 896 | if (ah->ah_version != AR5K_AR5210) { |
904 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | 897 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & |
905 | AR5K_PHY_RX_DELAY_M; | 898 | AR5K_PHY_RX_DELAY_M; |
906 | data = (channel->val & CHANNEL_CCK) ? | 899 | data = (channel->hw_value & CHANNEL_CCK) ? |
907 | ((data << 2) / 22) : (data / 10); | 900 | ((data << 2) / 22) : (data / 10); |
908 | 901 | ||
909 | udelay(100 + data); | 902 | udelay(100 + data); |
@@ -920,11 +913,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
920 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | 913 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, |
921 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | 914 | AR5K_PHY_AGCCTL_CAL, 0, false)) { |
922 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 915 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", |
923 | channel->freq); | 916 | channel->center_freq); |
924 | return -EAGAIN; | 917 | return -EAGAIN; |
925 | } | 918 | } |
926 | 919 | ||
927 | ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); | 920 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
928 | if (ret) | 921 | if (ret) |
929 | return ret; | 922 | return ret; |
930 | 923 | ||
@@ -932,7 +925,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | |||
932 | 925 | ||
933 | /* A and G modes can use QAM modulation which requires enabling | 926 | /* A and G modes can use QAM modulation which requires enabling |
934 | * I and Q calibration. Don't bother in B mode. */ | 927 | * I and Q calibration. Don't bother in B mode. */ |
935 | if (!(driver_mode == MODE_IEEE80211B)) { | 928 | if (!(mode == AR5K_MODE_11B)) { |
936 | ah->ah_calibration = true; | 929 | ah->ah_calibration = true; |
937 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | 930 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, |
938 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | 931 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); |
@@ -1590,9 +1583,10 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | |||
1590 | /* | 1583 | /* |
1591 | * Write to eeprom - currently disabled, use at your own risk | 1584 | * Write to eeprom - currently disabled, use at your own risk |
1592 | */ | 1585 | */ |
1586 | #if 0 | ||
1593 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | 1587 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) |
1594 | { | 1588 | { |
1595 | #if 0 | 1589 | |
1596 | u32 status, timeout; | 1590 | u32 status, timeout; |
1597 | 1591 | ||
1598 | ATH5K_TRACE(ah->ah_sc); | 1592 | ATH5K_TRACE(ah->ah_sc); |
@@ -1634,10 +1628,11 @@ static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | |||
1634 | } | 1628 | } |
1635 | udelay(15); | 1629 | udelay(15); |
1636 | } | 1630 | } |
1637 | #endif | 1631 | |
1638 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); | 1632 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); |
1639 | return -EIO; | 1633 | return -EIO; |
1640 | } | 1634 | } |
1635 | #endif | ||
1641 | 1636 | ||
1642 | /* | 1637 | /* |
1643 | * Translate binary channel representation in EEPROM to frequency | 1638 | * Translate binary channel representation in EEPROM to frequency |
@@ -2043,50 +2038,6 @@ static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | |||
2043 | } | 2038 | } |
2044 | 2039 | ||
2045 | /* | 2040 | /* |
2046 | * Read/Write regulatory domain | ||
2047 | */ | ||
2048 | static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write, | ||
2049 | enum ath5k_regdom *regdomain) | ||
2050 | { | ||
2051 | u16 ee_regdomain; | ||
2052 | |||
2053 | /* Read current value */ | ||
2054 | if (write != true) { | ||
2055 | ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain; | ||
2056 | *regdomain = ath5k_regdom_to_ieee(ee_regdomain); | ||
2057 | return true; | ||
2058 | } | ||
2059 | |||
2060 | ee_regdomain = ath5k_regdom_from_ieee(*regdomain); | ||
2061 | |||
2062 | /* Try to write a new value */ | ||
2063 | if (ah->ah_capabilities.cap_eeprom.ee_protect & | ||
2064 | AR5K_EEPROM_PROTECT_WR_128_191) | ||
2065 | return false; | ||
2066 | if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0) | ||
2067 | return false; | ||
2068 | |||
2069 | ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain; | ||
2070 | |||
2071 | return true; | ||
2072 | } | ||
2073 | |||
2074 | /* | ||
2075 | * Use the above to write a new regulatory domain | ||
2076 | */ | ||
2077 | int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain) | ||
2078 | { | ||
2079 | enum ath5k_regdom ieee_regdomain; | ||
2080 | |||
2081 | ieee_regdomain = ath5k_regdom_to_ieee(regdomain); | ||
2082 | |||
2083 | if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true) | ||
2084 | return 0; | ||
2085 | |||
2086 | return -EIO; | ||
2087 | } | ||
2088 | |||
2089 | /* | ||
2090 | * Fill the capabilities struct | 2041 | * Fill the capabilities struct |
2091 | */ | 2042 | */ |
2092 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | 2043 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) |
@@ -2108,8 +2059,8 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2108 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | 2059 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; |
2109 | 2060 | ||
2110 | /* Set supported modes */ | 2061 | /* Set supported modes */ |
2111 | __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode); | 2062 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); |
2112 | __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode); | 2063 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); |
2113 | } else { | 2064 | } else { |
2114 | /* | 2065 | /* |
2115 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | 2066 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz |
@@ -2131,12 +2082,12 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2131 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | 2082 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; |
2132 | 2083 | ||
2133 | /* Set supported modes */ | 2084 | /* Set supported modes */ |
2134 | __set_bit(MODE_IEEE80211A, | 2085 | __set_bit(AR5K_MODE_11A, |
2135 | ah->ah_capabilities.cap_mode); | 2086 | ah->ah_capabilities.cap_mode); |
2136 | __set_bit(MODE_ATHEROS_TURBO, | 2087 | __set_bit(AR5K_MODE_11A_TURBO, |
2137 | ah->ah_capabilities.cap_mode); | 2088 | ah->ah_capabilities.cap_mode); |
2138 | if (ah->ah_version == AR5K_AR5212) | 2089 | if (ah->ah_version == AR5K_AR5212) |
2139 | __set_bit(MODE_ATHEROS_TURBOG, | 2090 | __set_bit(AR5K_MODE_11G_TURBO, |
2140 | ah->ah_capabilities.cap_mode); | 2091 | ah->ah_capabilities.cap_mode); |
2141 | } | 2092 | } |
2142 | 2093 | ||
@@ -2148,11 +2099,11 @@ static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | |||
2148 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | 2099 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; |
2149 | 2100 | ||
2150 | if (AR5K_EEPROM_HDR_11B(ee_header)) | 2101 | if (AR5K_EEPROM_HDR_11B(ee_header)) |
2151 | __set_bit(MODE_IEEE80211B, | 2102 | __set_bit(AR5K_MODE_11B, |
2152 | ah->ah_capabilities.cap_mode); | 2103 | ah->ah_capabilities.cap_mode); |
2153 | 2104 | ||
2154 | if (AR5K_EEPROM_HDR_11G(ee_header)) | 2105 | if (AR5K_EEPROM_HDR_11G(ee_header)) |
2155 | __set_bit(MODE_IEEE80211G, | 2106 | __set_bit(AR5K_MODE_11G, |
2156 | ah->ah_capabilities.cap_mode); | 2107 | ah->ah_capabilities.cap_mode); |
2157 | } | 2108 | } |
2158 | } | 2109 | } |
@@ -4248,35 +4199,6 @@ void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | |||
4248 | } | 4199 | } |
4249 | 4200 | ||
4250 | 4201 | ||
4251 | /*********************************\ | ||
4252 | Regulatory Domain/Channels Setup | ||
4253 | \*********************************/ | ||
4254 | |||
4255 | u16 ath5k_get_regdomain(struct ath5k_hw *ah) | ||
4256 | { | ||
4257 | u16 regdomain; | ||
4258 | enum ath5k_regdom ieee_regdomain; | ||
4259 | #ifdef COUNTRYCODE | ||
4260 | u16 code; | ||
4261 | #endif | ||
4262 | |||
4263 | ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain); | ||
4264 | ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain; | ||
4265 | |||
4266 | #ifdef COUNTRYCODE | ||
4267 | /* | ||
4268 | * Get the regulation domain by country code. This will ignore | ||
4269 | * the settings found in the EEPROM. | ||
4270 | */ | ||
4271 | code = ieee80211_name2countrycode(COUNTRYCODE); | ||
4272 | ieee_regdomain = ieee80211_countrycode2regdomain(code); | ||
4273 | #endif | ||
4274 | |||
4275 | regdomain = ath5k_regdom_from_ieee(ieee_regdomain); | ||
4276 | ah->ah_capabilities.cap_regdomain.reg_current = regdomain; | ||
4277 | |||
4278 | return regdomain; | ||
4279 | } | ||
4280 | 4202 | ||
4281 | 4203 | ||
4282 | /****************\ | 4204 | /****************\ |
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c index 2c22f1d4ee64..cfcb1fe7bd34 100644 --- a/drivers/net/wireless/ath5k/initvals.c +++ b/drivers/net/wireless/ath5k/initvals.c | |||
@@ -1317,8 +1317,10 @@ int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel) | |||
1317 | /* For AR5211 */ | 1317 | /* For AR5211 */ |
1318 | } else if (ah->ah_version == AR5K_AR5211) { | 1318 | } else if (ah->ah_version == AR5K_AR5211) { |
1319 | 1319 | ||
1320 | if(mode > 2){ /* AR5K_INI_VAL_11B */ | 1320 | /* AR5K_MODE_11B */ |
1321 | ATH5K_ERR(ah->ah_sc,"unsupported channel mode: %d\n", mode); | 1321 | if (mode > 2) { |
1322 | ATH5K_ERR(ah->ah_sc, | ||
1323 | "unsupported channel mode: %d\n", mode); | ||
1322 | return -EINVAL; | 1324 | return -EINVAL; |
1323 | } | 1325 | } |
1324 | 1326 | ||
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index b95941797141..405195ffb24d 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c | |||
@@ -1018,7 +1018,7 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1018 | int obdb = -1, bank = -1; | 1018 | int obdb = -1, bank = -1; |
1019 | u32 ee_mode; | 1019 | u32 ee_mode; |
1020 | 1020 | ||
1021 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1021 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1022 | 1022 | ||
1023 | rf = ah->ah_rf_banks; | 1023 | rf = ah->ah_rf_banks; |
1024 | 1024 | ||
@@ -1038,8 +1038,8 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | /* Modify bank 0 */ | 1040 | /* Modify bank 0 */ |
1041 | if (channel->val & CHANNEL_2GHZ) { | 1041 | if (channel->hw_value & CHANNEL_2GHZ) { |
1042 | if (channel->val & CHANNEL_CCK) | 1042 | if (channel->hw_value & CHANNEL_CCK) |
1043 | ee_mode = AR5K_EEPROM_MODE_11B; | 1043 | ee_mode = AR5K_EEPROM_MODE_11B; |
1044 | else | 1044 | else |
1045 | ee_mode = AR5K_EEPROM_MODE_11G; | 1045 | ee_mode = AR5K_EEPROM_MODE_11G; |
@@ -1058,10 +1058,10 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah, | |||
1058 | } else { | 1058 | } else { |
1059 | /* For 11a, Turbo and XR */ | 1059 | /* For 11a, Turbo and XR */ |
1060 | ee_mode = AR5K_EEPROM_MODE_11A; | 1060 | ee_mode = AR5K_EEPROM_MODE_11A; |
1061 | obdb = channel->freq >= 5725 ? 3 : | 1061 | obdb = channel->center_freq >= 5725 ? 3 : |
1062 | (channel->freq >= 5500 ? 2 : | 1062 | (channel->center_freq >= 5500 ? 2 : |
1063 | (channel->freq >= 5260 ? 1 : | 1063 | (channel->center_freq >= 5260 ? 1 : |
1064 | (channel->freq > 4000 ? 0 : -1))); | 1064 | (channel->center_freq > 4000 ? 0 : -1))); |
1065 | 1065 | ||
1066 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 1066 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], |
1067 | ee->ee_pwd_84, 1, 51, 3, true)) | 1067 | ee->ee_pwd_84, 1, 51, 3, true)) |
@@ -1119,12 +1119,12 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1119 | int obdb = -1, bank = -1; | 1119 | int obdb = -1, bank = -1; |
1120 | u32 ee_mode; | 1120 | u32 ee_mode; |
1121 | 1121 | ||
1122 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1122 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1123 | 1123 | ||
1124 | rf = ah->ah_rf_banks; | 1124 | rf = ah->ah_rf_banks; |
1125 | 1125 | ||
1126 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A | 1126 | if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A |
1127 | && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){ | 1127 | && !test_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode)) { |
1128 | rf_ini = rfregs_2112a; | 1128 | rf_ini = rfregs_2112a; |
1129 | rf_size = ARRAY_SIZE(rfregs_5112a); | 1129 | rf_size = ARRAY_SIZE(rfregs_5112a); |
1130 | if (mode < 2) { | 1130 | if (mode < 2) { |
@@ -1156,8 +1156,8 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | /* Modify bank 6 */ | 1158 | /* Modify bank 6 */ |
1159 | if (channel->val & CHANNEL_2GHZ) { | 1159 | if (channel->hw_value & CHANNEL_2GHZ) { |
1160 | if (channel->val & CHANNEL_OFDM) | 1160 | if (channel->hw_value & CHANNEL_OFDM) |
1161 | ee_mode = AR5K_EEPROM_MODE_11G; | 1161 | ee_mode = AR5K_EEPROM_MODE_11G; |
1162 | else | 1162 | else |
1163 | ee_mode = AR5K_EEPROM_MODE_11B; | 1163 | ee_mode = AR5K_EEPROM_MODE_11B; |
@@ -1173,10 +1173,13 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah, | |||
1173 | } else { | 1173 | } else { |
1174 | /* For 11a, Turbo and XR */ | 1174 | /* For 11a, Turbo and XR */ |
1175 | ee_mode = AR5K_EEPROM_MODE_11A; | 1175 | ee_mode = AR5K_EEPROM_MODE_11A; |
1176 | obdb = channel->freq >= 5725 ? 3 : | 1176 | obdb = channel->center_freq >= 5725 ? 3 : |
1177 | (channel->freq >= 5500 ? 2 : | 1177 | (channel->center_freq >= 5500 ? 2 : |
1178 | (channel->freq >= 5260 ? 1 : | 1178 | (channel->center_freq >= 5260 ? 1 : |
1179 | (channel->freq > 4000 ? 0 : -1))); | 1179 | (channel->center_freq > 4000 ? 0 : -1))); |
1180 | |||
1181 | if (obdb == -1) | ||
1182 | return -EINVAL; | ||
1180 | 1183 | ||
1181 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], | 1184 | if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], |
1182 | ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) | 1185 | ee->ee_ob[ee_mode][obdb], 3, 279, 0, true)) |
@@ -1219,7 +1222,7 @@ static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah, | |||
1219 | unsigned int rf_size, i; | 1222 | unsigned int rf_size, i; |
1220 | int bank = -1; | 1223 | int bank = -1; |
1221 | 1224 | ||
1222 | AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX); | 1225 | AR5K_ASSERT_ENTRY(mode, AR5K_MODE_MAX); |
1223 | 1226 | ||
1224 | rf = ah->ah_rf_banks; | 1227 | rf = ah->ah_rf_banks; |
1225 | 1228 | ||
@@ -1445,9 +1448,10 @@ static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel) | |||
1445 | * newer chipsets like the AR5212A who have a completely | 1448 | * newer chipsets like the AR5212A who have a completely |
1446 | * different RF/PHY part. | 1449 | * different RF/PHY part. |
1447 | */ | 1450 | */ |
1448 | athchan = (ath5k_hw_bitswap((channel->chan - 24) / 2, 5) << 1) | | 1451 | athchan = (ath5k_hw_bitswap( |
1449 | (1 << 6) | 0x1; | 1452 | (ieee80211_frequency_to_channel( |
1450 | 1453 | channel->center_freq) - 24) / 2, 5) | |
1454 | << 1) | (1 << 6) | 0x1; | ||
1451 | return athchan; | 1455 | return athchan; |
1452 | } | 1456 | } |
1453 | 1457 | ||
@@ -1506,7 +1510,8 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, | |||
1506 | struct ieee80211_channel *channel) | 1510 | struct ieee80211_channel *channel) |
1507 | { | 1511 | { |
1508 | struct ath5k_athchan_2ghz ath5k_channel_2ghz; | 1512 | struct ath5k_athchan_2ghz ath5k_channel_2ghz; |
1509 | unsigned int ath5k_channel = channel->chan; | 1513 | unsigned int ath5k_channel = |
1514 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1510 | u32 data0, data1, clock; | 1515 | u32 data0, data1, clock; |
1511 | int ret; | 1516 | int ret; |
1512 | 1517 | ||
@@ -1515,10 +1520,11 @@ static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah, | |||
1515 | */ | 1520 | */ |
1516 | data0 = data1 = 0; | 1521 | data0 = data1 = 0; |
1517 | 1522 | ||
1518 | if (channel->val & CHANNEL_2GHZ) { | 1523 | if (channel->hw_value & CHANNEL_2GHZ) { |
1519 | /* Map 2GHz channel to 5GHz Atheros channel ID */ | 1524 | /* Map 2GHz channel to 5GHz Atheros channel ID */ |
1520 | ret = ath5k_hw_rf5111_chan2athchan(channel->chan, | 1525 | ret = ath5k_hw_rf5111_chan2athchan( |
1521 | &ath5k_channel_2ghz); | 1526 | ieee80211_frequency_to_channel(channel->center_freq), |
1527 | &ath5k_channel_2ghz); | ||
1522 | if (ret) | 1528 | if (ret) |
1523 | return ret; | 1529 | return ret; |
1524 | 1530 | ||
@@ -1555,7 +1561,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
1555 | u16 c; | 1561 | u16 c; |
1556 | 1562 | ||
1557 | data = data0 = data1 = data2 = 0; | 1563 | data = data0 = data1 = data2 = 0; |
1558 | c = channel->freq; | 1564 | c = channel->center_freq; |
1559 | 1565 | ||
1560 | /* | 1566 | /* |
1561 | * Set the channel on the RF5112 or newer | 1567 | * Set the channel on the RF5112 or newer |
@@ -1599,19 +1605,17 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
1599 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | 1605 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) |
1600 | { | 1606 | { |
1601 | int ret; | 1607 | int ret; |
1602 | |||
1603 | /* | 1608 | /* |
1604 | * Check bounds supported by the PHY | 1609 | * Check bounds supported by the PHY (we don't care about regultory |
1605 | * (don't care about regulation restrictions at this point) | 1610 | * restrictions at this point). Note: hw_value already has the band |
1606 | */ | 1611 | * (CHANNEL_2GHZ, or CHANNEL_5GHZ) so we inform ath5k_channel_ok() |
1607 | if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min || | 1612 | * of the band by that */ |
1608 | channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) && | 1613 | if (!ath5k_channel_ok(ah, channel->center_freq, channel->hw_value)) { |
1609 | (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min || | ||
1610 | channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) { | ||
1611 | ATH5K_ERR(ah->ah_sc, | 1614 | ATH5K_ERR(ah->ah_sc, |
1612 | "channel out of supported range (%u MHz)\n", | 1615 | "channel frequency (%u MHz) out of supported " |
1613 | channel->freq); | 1616 | "band range\n", |
1614 | return -EINVAL; | 1617 | channel->center_freq); |
1618 | return -EINVAL; | ||
1615 | } | 1619 | } |
1616 | 1620 | ||
1617 | /* | 1621 | /* |
@@ -1632,9 +1636,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1632 | if (ret) | 1636 | if (ret) |
1633 | return ret; | 1637 | return ret; |
1634 | 1638 | ||
1635 | ah->ah_current_channel.freq = channel->freq; | 1639 | ah->ah_current_channel.center_freq = channel->center_freq; |
1636 | ah->ah_current_channel.val = channel->val; | 1640 | ah->ah_current_channel.hw_value = channel->hw_value; |
1637 | ah->ah_turbo = channel->val == CHANNEL_T ? true : false; | 1641 | ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; |
1638 | 1642 | ||
1639 | return 0; | 1643 | return 0; |
1640 | } | 1644 | } |
@@ -1797,11 +1801,11 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, | |||
1797 | 1801 | ||
1798 | if (ret) { | 1802 | if (ret) { |
1799 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", | 1803 | ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n", |
1800 | channel->freq); | 1804 | channel->center_freq); |
1801 | return ret; | 1805 | return ret; |
1802 | } | 1806 | } |
1803 | 1807 | ||
1804 | ret = ath5k_hw_noise_floor_calibration(ah, channel->freq); | 1808 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
1805 | if (ret) | 1809 | if (ret) |
1806 | return ret; | 1810 | return ret; |
1807 | 1811 | ||
@@ -1848,10 +1852,10 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1848 | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); | 1852 | ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S)); |
1849 | 1853 | ||
1850 | done: | 1854 | done: |
1851 | ath5k_hw_noise_floor_calibration(ah, channel->freq); | 1855 | ath5k_hw_noise_floor_calibration(ah, channel->center_freq); |
1852 | 1856 | ||
1853 | /* Request RF gain */ | 1857 | /* Request RF gain */ |
1854 | if (channel->val & CHANNEL_5GHZ) { | 1858 | if (channel->hw_value & CHANNEL_5GHZ) { |
1855 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, | 1859 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max, |
1856 | AR5K_PHY_PAPD_PROBE_TXPOWER) | | 1860 | AR5K_PHY_PAPD_PROBE_TXPOWER) | |
1857 | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); | 1861 | AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE); |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 63ec7a70ee76..ef2da4023d68 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/device.h> | 66 | #include <linux/device.h> |
67 | #include <linux/moduleparam.h> | 67 | #include <linux/moduleparam.h> |
68 | #include <linux/firmware.h> | 68 | #include <linux/firmware.h> |
69 | #include <linux/jiffies.h> | ||
69 | #include <net/ieee80211.h> | 70 | #include <net/ieee80211.h> |
70 | #include "atmel.h" | 71 | #include "atmel.h" |
71 | 72 | ||
@@ -516,7 +517,7 @@ struct atmel_private { | |||
516 | SITE_SURVEY_IN_PROGRESS, | 517 | SITE_SURVEY_IN_PROGRESS, |
517 | SITE_SURVEY_COMPLETED | 518 | SITE_SURVEY_COMPLETED |
518 | } site_survey_state; | 519 | } site_survey_state; |
519 | time_t last_survey; | 520 | unsigned long last_survey; |
520 | 521 | ||
521 | int station_was_associated, station_is_associated; | 522 | int station_was_associated, station_is_associated; |
522 | int fast_scan; | 523 | int fast_scan; |
@@ -2283,7 +2284,7 @@ static int atmel_set_scan(struct net_device *dev, | |||
2283 | return -EAGAIN; | 2284 | return -EAGAIN; |
2284 | 2285 | ||
2285 | /* Timeout old surveys. */ | 2286 | /* Timeout old surveys. */ |
2286 | if ((jiffies - priv->last_survey) > (20 * HZ)) | 2287 | if (time_after(jiffies, priv->last_survey + 20 * HZ)) |
2287 | priv->site_survey_state = SITE_SURVEY_IDLE; | 2288 | priv->site_survey_state = SITE_SURVEY_IDLE; |
2288 | priv->last_survey = jiffies; | 2289 | priv->last_survey = jiffies; |
2289 | 2290 | ||
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index f13346ba9dd2..33459d61a717 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -144,7 +144,8 @@ enum { | |||
144 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ | 144 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ |
145 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ | 145 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ |
146 | #define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */ | 146 | #define B43_SHM_SH_HOSTFLO 0x005E /* Hostflags for ucode options (low) */ |
147 | #define B43_SHM_SH_HOSTFHI 0x0060 /* Hostflags for ucode options (high) */ | 147 | #define B43_SHM_SH_HOSTFMI 0x0060 /* Hostflags for ucode options (middle) */ |
148 | #define B43_SHM_SH_HOSTFHI 0x0062 /* Hostflags for ucode options (high) */ | ||
148 | #define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */ | 149 | #define B43_SHM_SH_RFATT 0x0064 /* Current radio attenuation value */ |
149 | #define B43_SHM_SH_RADAR 0x0066 /* Radar register */ | 150 | #define B43_SHM_SH_RADAR 0x0066 /* Radar register */ |
150 | #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ | 151 | #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ |
@@ -232,31 +233,41 @@ enum { | |||
232 | #define B43_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4) | 233 | #define B43_MMIO_RADIO_HWENABLED_LO_MASK (1 << 4) |
233 | 234 | ||
234 | /* HostFlags. See b43_hf_read/write() */ | 235 | /* HostFlags. See b43_hf_read/write() */ |
235 | #define B43_HF_ANTDIVHELP 0x00000001 /* ucode antenna div helper */ | 236 | #define B43_HF_ANTDIVHELP 0x000000000001ULL /* ucode antenna div helper */ |
236 | #define B43_HF_SYMW 0x00000002 /* G-PHY SYM workaround */ | 237 | #define B43_HF_SYMW 0x000000000002ULL /* G-PHY SYM workaround */ |
237 | #define B43_HF_RXPULLW 0x00000004 /* RX pullup workaround */ | 238 | #define B43_HF_RXPULLW 0x000000000004ULL /* RX pullup workaround */ |
238 | #define B43_HF_CCKBOOST 0x00000008 /* 4dB CCK power boost (exclusive with OFDM boost) */ | 239 | #define B43_HF_CCKBOOST 0x000000000008ULL /* 4dB CCK power boost (exclusive with OFDM boost) */ |
239 | #define B43_HF_BTCOEX 0x00000010 /* Bluetooth coexistance */ | 240 | #define B43_HF_BTCOEX 0x000000000010ULL /* Bluetooth coexistance */ |
240 | #define B43_HF_GDCW 0x00000020 /* G-PHY DV canceller filter bw workaround */ | 241 | #define B43_HF_GDCW 0x000000000020ULL /* G-PHY DC canceller filter bw workaround */ |
241 | #define B43_HF_OFDMPABOOST 0x00000040 /* Enable PA gain boost for OFDM */ | 242 | #define B43_HF_OFDMPABOOST 0x000000000040ULL /* Enable PA gain boost for OFDM */ |
242 | #define B43_HF_ACPR 0x00000080 /* Disable for Japan, channel 14 */ | 243 | #define B43_HF_ACPR 0x000000000080ULL /* Disable for Japan, channel 14 */ |
243 | #define B43_HF_EDCF 0x00000100 /* on if WME and MAC suspended */ | 244 | #define B43_HF_EDCF 0x000000000100ULL /* on if WME and MAC suspended */ |
244 | #define B43_HF_TSSIRPSMW 0x00000200 /* TSSI reset PSM ucode workaround */ | 245 | #define B43_HF_TSSIRPSMW 0x000000000200ULL /* TSSI reset PSM ucode workaround */ |
245 | #define B43_HF_DSCRQ 0x00000400 /* Disable slow clock request in ucode */ | 246 | #define B43_HF_20IN40IQW 0x000000000200ULL /* 20 in 40 MHz I/Q workaround (rev >= 13 only) */ |
246 | #define B43_HF_ACIW 0x00000800 /* ACI workaround: shift bits by 2 on PHY CRS */ | 247 | #define B43_HF_DSCRQ 0x000000000400ULL /* Disable slow clock request in ucode */ |
247 | #define B43_HF_2060W 0x00001000 /* 2060 radio workaround */ | 248 | #define B43_HF_ACIW 0x000000000800ULL /* ACI workaround: shift bits by 2 on PHY CRS */ |
248 | #define B43_HF_RADARW 0x00002000 /* Radar workaround */ | 249 | #define B43_HF_2060W 0x000000001000ULL /* 2060 radio workaround */ |
249 | #define B43_HF_USEDEFKEYS 0x00004000 /* Enable use of default keys */ | 250 | #define B43_HF_RADARW 0x000000002000ULL /* Radar workaround */ |
250 | #define B43_HF_BT4PRIOCOEX 0x00010000 /* Bluetooth 2-priority coexistance */ | 251 | #define B43_HF_USEDEFKEYS 0x000000004000ULL /* Enable use of default keys */ |
251 | #define B43_HF_FWKUP 0x00020000 /* Fast wake-up ucode */ | 252 | #define B43_HF_AFTERBURNER 0x000000008000ULL /* Afterburner enabled */ |
252 | #define B43_HF_VCORECALC 0x00040000 /* Force VCO recalculation when powering up synthpu */ | 253 | #define B43_HF_BT4PRIOCOEX 0x000000010000ULL /* Bluetooth 4-priority coexistance */ |
253 | #define B43_HF_PCISCW 0x00080000 /* PCI slow clock workaround */ | 254 | #define B43_HF_FWKUP 0x000000020000ULL /* Fast wake-up ucode */ |
254 | #define B43_HF_4318TSSI 0x00200000 /* 4318 TSSI */ | 255 | #define B43_HF_VCORECALC 0x000000040000ULL /* Force VCO recalculation when powering up synthpu */ |
255 | #define B43_HF_FBCMCFIFO 0x00400000 /* Flush bcast/mcast FIFO immediately */ | 256 | #define B43_HF_PCISCW 0x000000080000ULL /* PCI slow clock workaround */ |
256 | #define B43_HF_HWPCTL 0x00800000 /* Enable hardwarre power control */ | 257 | #define B43_HF_4318TSSI 0x000000200000ULL /* 4318 TSSI */ |
257 | #define B43_HF_BTCOEXALT 0x01000000 /* Bluetooth coexistance in alternate pins */ | 258 | #define B43_HF_FBCMCFIFO 0x000000400000ULL /* Flush bcast/mcast FIFO immediately */ |
258 | #define B43_HF_TXBTCHECK 0x02000000 /* Bluetooth check during transmission */ | 259 | #define B43_HF_HWPCTL 0x000000800000ULL /* Enable hardwarre power control */ |
259 | #define B43_HF_SKCFPUP 0x04000000 /* Skip CFP update */ | 260 | #define B43_HF_BTCOEXALT 0x000001000000ULL /* Bluetooth coexistance in alternate pins */ |
261 | #define B43_HF_TXBTCHECK 0x000002000000ULL /* Bluetooth check during transmission */ | ||
262 | #define B43_HF_SKCFPUP 0x000004000000ULL /* Skip CFP update */ | ||
263 | #define B43_HF_N40W 0x000008000000ULL /* N PHY 40 MHz workaround (rev >= 13 only) */ | ||
264 | #define B43_HF_ANTSEL 0x000020000000ULL /* Antenna selection (for testing antenna div.) */ | ||
265 | #define B43_HF_BT3COEXT 0x000020000000ULL /* Bluetooth 3-wire coexistence (rev >= 13 only) */ | ||
266 | #define B43_HF_BTCANT 0x000040000000ULL /* Bluetooth coexistence (antenna mode) (rev >= 13 only) */ | ||
267 | #define B43_HF_ANTSELEN 0x000100000000ULL /* Antenna selection enabled (rev >= 13 only) */ | ||
268 | #define B43_HF_ANTSELMODE 0x000200000000ULL /* Antenna selection mode (rev >= 13 only) */ | ||
269 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ | ||
270 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ | ||
260 | 271 | ||
261 | /* MacFilter offsets. */ | 272 | /* MacFilter offsets. */ |
262 | #define B43_MACFILTER_SELF 0x0000 | 273 | #define B43_MACFILTER_SELF 0x0000 |
@@ -458,20 +469,13 @@ struct b43_iv { | |||
458 | } __attribute__((__packed__)); | 469 | } __attribute__((__packed__)); |
459 | 470 | ||
460 | 471 | ||
461 | #define B43_PHYMODE(phytype) (1 << (phytype)) | ||
462 | #define B43_PHYMODE_A B43_PHYMODE(B43_PHYTYPE_A) | ||
463 | #define B43_PHYMODE_B B43_PHYMODE(B43_PHYTYPE_B) | ||
464 | #define B43_PHYMODE_G B43_PHYMODE(B43_PHYTYPE_G) | ||
465 | |||
466 | struct b43_phy { | 472 | struct b43_phy { |
467 | /* Possible PHYMODEs on this PHY */ | 473 | /* Band support flags. */ |
468 | u8 possible_phymodes; | 474 | bool supports_2ghz; |
475 | bool supports_5ghz; | ||
476 | |||
469 | /* GMODE bit enabled? */ | 477 | /* GMODE bit enabled? */ |
470 | bool gmode; | 478 | bool gmode; |
471 | /* Possible ieee80211 subsystem hwmodes for this PHY. | ||
472 | * Which mode is selected, depends on thr GMODE enabled bit */ | ||
473 | #define B43_MAX_PHYHWMODES 2 | ||
474 | struct ieee80211_hw_mode hwmodes[B43_MAX_PHYHWMODES]; | ||
475 | 479 | ||
476 | /* Analog Type */ | 480 | /* Analog Type */ |
477 | u8 analog; | 481 | u8 analog; |
@@ -727,7 +731,6 @@ struct b43_wldev { | |||
727 | 731 | ||
728 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ | 732 | bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */ |
729 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ | 733 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ |
730 | bool short_preamble; /* TRUE, if short preamble is enabled. */ | ||
731 | bool short_slot; /* TRUE, if short slot timing is enabled. */ | 734 | bool short_slot; /* TRUE, if short slot timing is enabled. */ |
732 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 735 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
733 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ | 736 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 51dfce16178a..f745308faaad 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -96,25 +96,29 @@ MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); | |||
96 | * data in there. This data is the same for all devices, so we don't | 96 | * data in there. This data is the same for all devices, so we don't |
97 | * get concurrency issues */ | 97 | * get concurrency issues */ |
98 | #define RATETAB_ENT(_rateid, _flags) \ | 98 | #define RATETAB_ENT(_rateid, _flags) \ |
99 | { \ | 99 | { \ |
100 | .rate = B43_RATE_TO_BASE100KBPS(_rateid), \ | 100 | .bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \ |
101 | .val = (_rateid), \ | 101 | .hw_value = (_rateid), \ |
102 | .val2 = (_rateid), \ | 102 | .flags = (_flags), \ |
103 | .flags = (_flags), \ | ||
104 | } | 103 | } |
104 | |||
105 | /* | ||
106 | * NOTE: When changing this, sync with xmit.c's | ||
107 | * b43_plcp_get_bitrate_idx_* functions! | ||
108 | */ | ||
105 | static struct ieee80211_rate __b43_ratetable[] = { | 109 | static struct ieee80211_rate __b43_ratetable[] = { |
106 | RATETAB_ENT(B43_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 110 | RATETAB_ENT(B43_CCK_RATE_1MB, 0), |
107 | RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 112 | RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 113 | RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
110 | RATETAB_ENT(B43_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43_OFDM_RATE_6MB, 0), |
111 | RATETAB_ENT(B43_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43_OFDM_RATE_9MB, 0), |
112 | RATETAB_ENT(B43_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43_OFDM_RATE_12MB, 0), |
113 | RATETAB_ENT(B43_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43_OFDM_RATE_18MB, 0), |
114 | RATETAB_ENT(B43_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43_OFDM_RATE_24MB, 0), |
115 | RATETAB_ENT(B43_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43_OFDM_RATE_36MB, 0), |
116 | RATETAB_ENT(B43_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 120 | RATETAB_ENT(B43_OFDM_RATE_48MB, 0), |
117 | RATETAB_ENT(B43_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 121 | RATETAB_ENT(B43_OFDM_RATE_54MB, 0), |
118 | }; | 122 | }; |
119 | 123 | ||
120 | #define b43_a_ratetable (__b43_ratetable + 4) | 124 | #define b43_a_ratetable (__b43_ratetable + 4) |
@@ -124,53 +128,144 @@ static struct ieee80211_rate __b43_ratetable[] = { | |||
124 | #define b43_g_ratetable (__b43_ratetable + 0) | 128 | #define b43_g_ratetable (__b43_ratetable + 0) |
125 | #define b43_g_ratetable_size 12 | 129 | #define b43_g_ratetable_size 12 |
126 | 130 | ||
127 | #define CHANTAB_ENT(_chanid, _freq) \ | 131 | #define CHAN4G(_channel, _freq, _flags) { \ |
128 | { \ | 132 | .band = IEEE80211_BAND_2GHZ, \ |
129 | .chan = (_chanid), \ | 133 | .center_freq = (_freq), \ |
130 | .freq = (_freq), \ | 134 | .hw_value = (_channel), \ |
131 | .val = (_chanid), \ | 135 | .flags = (_flags), \ |
132 | .flag = IEEE80211_CHAN_W_SCAN | \ | 136 | .max_antenna_gain = 0, \ |
133 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | 137 | .max_power = 30, \ |
134 | IEEE80211_CHAN_W_IBSS, \ | 138 | } |
135 | .power_level = 0xFF, \ | ||
136 | .antenna_max = 0xFF, \ | ||
137 | } | ||
138 | static struct ieee80211_channel b43_2ghz_chantable[] = { | 139 | static struct ieee80211_channel b43_2ghz_chantable[] = { |
139 | CHANTAB_ENT(1, 2412), | 140 | CHAN4G(1, 2412, 0), |
140 | CHANTAB_ENT(2, 2417), | 141 | CHAN4G(2, 2417, 0), |
141 | CHANTAB_ENT(3, 2422), | 142 | CHAN4G(3, 2422, 0), |
142 | CHANTAB_ENT(4, 2427), | 143 | CHAN4G(4, 2427, 0), |
143 | CHANTAB_ENT(5, 2432), | 144 | CHAN4G(5, 2432, 0), |
144 | CHANTAB_ENT(6, 2437), | 145 | CHAN4G(6, 2437, 0), |
145 | CHANTAB_ENT(7, 2442), | 146 | CHAN4G(7, 2442, 0), |
146 | CHANTAB_ENT(8, 2447), | 147 | CHAN4G(8, 2447, 0), |
147 | CHANTAB_ENT(9, 2452), | 148 | CHAN4G(9, 2452, 0), |
148 | CHANTAB_ENT(10, 2457), | 149 | CHAN4G(10, 2457, 0), |
149 | CHANTAB_ENT(11, 2462), | 150 | CHAN4G(11, 2462, 0), |
150 | CHANTAB_ENT(12, 2467), | 151 | CHAN4G(12, 2467, 0), |
151 | CHANTAB_ENT(13, 2472), | 152 | CHAN4G(13, 2472, 0), |
152 | CHANTAB_ENT(14, 2484), | 153 | CHAN4G(14, 2484, 0), |
153 | }; | 154 | }; |
154 | #define b43_2ghz_chantable_size ARRAY_SIZE(b43_2ghz_chantable) | 155 | #undef CHAN4G |
155 | 156 | ||
156 | #if 0 | 157 | #define CHAN5G(_channel, _flags) { \ |
157 | static struct ieee80211_channel b43_5ghz_chantable[] = { | 158 | .band = IEEE80211_BAND_5GHZ, \ |
158 | CHANTAB_ENT(36, 5180), | 159 | .center_freq = 5000 + (5 * (_channel)), \ |
159 | CHANTAB_ENT(40, 5200), | 160 | .hw_value = (_channel), \ |
160 | CHANTAB_ENT(44, 5220), | 161 | .flags = (_flags), \ |
161 | CHANTAB_ENT(48, 5240), | 162 | .max_antenna_gain = 0, \ |
162 | CHANTAB_ENT(52, 5260), | 163 | .max_power = 30, \ |
163 | CHANTAB_ENT(56, 5280), | 164 | } |
164 | CHANTAB_ENT(60, 5300), | 165 | static struct ieee80211_channel b43_5ghz_nphy_chantable[] = { |
165 | CHANTAB_ENT(64, 5320), | 166 | CHAN5G(32, 0), CHAN5G(34, 0), |
166 | CHANTAB_ENT(149, 5745), | 167 | CHAN5G(36, 0), CHAN5G(38, 0), |
167 | CHANTAB_ENT(153, 5765), | 168 | CHAN5G(40, 0), CHAN5G(42, 0), |
168 | CHANTAB_ENT(157, 5785), | 169 | CHAN5G(44, 0), CHAN5G(46, 0), |
169 | CHANTAB_ENT(161, 5805), | 170 | CHAN5G(48, 0), CHAN5G(50, 0), |
170 | CHANTAB_ENT(165, 5825), | 171 | CHAN5G(52, 0), CHAN5G(54, 0), |
172 | CHAN5G(56, 0), CHAN5G(58, 0), | ||
173 | CHAN5G(60, 0), CHAN5G(62, 0), | ||
174 | CHAN5G(64, 0), CHAN5G(66, 0), | ||
175 | CHAN5G(68, 0), CHAN5G(70, 0), | ||
176 | CHAN5G(72, 0), CHAN5G(74, 0), | ||
177 | CHAN5G(76, 0), CHAN5G(78, 0), | ||
178 | CHAN5G(80, 0), CHAN5G(82, 0), | ||
179 | CHAN5G(84, 0), CHAN5G(86, 0), | ||
180 | CHAN5G(88, 0), CHAN5G(90, 0), | ||
181 | CHAN5G(92, 0), CHAN5G(94, 0), | ||
182 | CHAN5G(96, 0), CHAN5G(98, 0), | ||
183 | CHAN5G(100, 0), CHAN5G(102, 0), | ||
184 | CHAN5G(104, 0), CHAN5G(106, 0), | ||
185 | CHAN5G(108, 0), CHAN5G(110, 0), | ||
186 | CHAN5G(112, 0), CHAN5G(114, 0), | ||
187 | CHAN5G(116, 0), CHAN5G(118, 0), | ||
188 | CHAN5G(120, 0), CHAN5G(122, 0), | ||
189 | CHAN5G(124, 0), CHAN5G(126, 0), | ||
190 | CHAN5G(128, 0), CHAN5G(130, 0), | ||
191 | CHAN5G(132, 0), CHAN5G(134, 0), | ||
192 | CHAN5G(136, 0), CHAN5G(138, 0), | ||
193 | CHAN5G(140, 0), CHAN5G(142, 0), | ||
194 | CHAN5G(144, 0), CHAN5G(145, 0), | ||
195 | CHAN5G(146, 0), CHAN5G(147, 0), | ||
196 | CHAN5G(148, 0), CHAN5G(149, 0), | ||
197 | CHAN5G(150, 0), CHAN5G(151, 0), | ||
198 | CHAN5G(152, 0), CHAN5G(153, 0), | ||
199 | CHAN5G(154, 0), CHAN5G(155, 0), | ||
200 | CHAN5G(156, 0), CHAN5G(157, 0), | ||
201 | CHAN5G(158, 0), CHAN5G(159, 0), | ||
202 | CHAN5G(160, 0), CHAN5G(161, 0), | ||
203 | CHAN5G(162, 0), CHAN5G(163, 0), | ||
204 | CHAN5G(164, 0), CHAN5G(165, 0), | ||
205 | CHAN5G(166, 0), CHAN5G(168, 0), | ||
206 | CHAN5G(170, 0), CHAN5G(172, 0), | ||
207 | CHAN5G(174, 0), CHAN5G(176, 0), | ||
208 | CHAN5G(178, 0), CHAN5G(180, 0), | ||
209 | CHAN5G(182, 0), CHAN5G(184, 0), | ||
210 | CHAN5G(186, 0), CHAN5G(188, 0), | ||
211 | CHAN5G(190, 0), CHAN5G(192, 0), | ||
212 | CHAN5G(194, 0), CHAN5G(196, 0), | ||
213 | CHAN5G(198, 0), CHAN5G(200, 0), | ||
214 | CHAN5G(202, 0), CHAN5G(204, 0), | ||
215 | CHAN5G(206, 0), CHAN5G(208, 0), | ||
216 | CHAN5G(210, 0), CHAN5G(212, 0), | ||
217 | CHAN5G(214, 0), CHAN5G(216, 0), | ||
218 | CHAN5G(218, 0), CHAN5G(220, 0), | ||
219 | CHAN5G(222, 0), CHAN5G(224, 0), | ||
220 | CHAN5G(226, 0), CHAN5G(228, 0), | ||
221 | }; | ||
222 | |||
223 | static struct ieee80211_channel b43_5ghz_aphy_chantable[] = { | ||
224 | CHAN5G(34, 0), CHAN5G(36, 0), | ||
225 | CHAN5G(38, 0), CHAN5G(40, 0), | ||
226 | CHAN5G(42, 0), CHAN5G(44, 0), | ||
227 | CHAN5G(46, 0), CHAN5G(48, 0), | ||
228 | CHAN5G(52, 0), CHAN5G(56, 0), | ||
229 | CHAN5G(60, 0), CHAN5G(64, 0), | ||
230 | CHAN5G(100, 0), CHAN5G(104, 0), | ||
231 | CHAN5G(108, 0), CHAN5G(112, 0), | ||
232 | CHAN5G(116, 0), CHAN5G(120, 0), | ||
233 | CHAN5G(124, 0), CHAN5G(128, 0), | ||
234 | CHAN5G(132, 0), CHAN5G(136, 0), | ||
235 | CHAN5G(140, 0), CHAN5G(149, 0), | ||
236 | CHAN5G(153, 0), CHAN5G(157, 0), | ||
237 | CHAN5G(161, 0), CHAN5G(165, 0), | ||
238 | CHAN5G(184, 0), CHAN5G(188, 0), | ||
239 | CHAN5G(192, 0), CHAN5G(196, 0), | ||
240 | CHAN5G(200, 0), CHAN5G(204, 0), | ||
241 | CHAN5G(208, 0), CHAN5G(212, 0), | ||
242 | CHAN5G(216, 0), | ||
243 | }; | ||
244 | #undef CHAN5G | ||
245 | |||
246 | static struct ieee80211_supported_band b43_band_5GHz_nphy = { | ||
247 | .band = IEEE80211_BAND_5GHZ, | ||
248 | .channels = b43_5ghz_nphy_chantable, | ||
249 | .n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable), | ||
250 | .bitrates = b43_a_ratetable, | ||
251 | .n_bitrates = b43_a_ratetable_size, | ||
252 | }; | ||
253 | |||
254 | static struct ieee80211_supported_band b43_band_5GHz_aphy = { | ||
255 | .band = IEEE80211_BAND_5GHZ, | ||
256 | .channels = b43_5ghz_aphy_chantable, | ||
257 | .n_channels = ARRAY_SIZE(b43_5ghz_aphy_chantable), | ||
258 | .bitrates = b43_a_ratetable, | ||
259 | .n_bitrates = b43_a_ratetable_size, | ||
260 | }; | ||
261 | |||
262 | static struct ieee80211_supported_band b43_band_2GHz = { | ||
263 | .band = IEEE80211_BAND_2GHZ, | ||
264 | .channels = b43_2ghz_chantable, | ||
265 | .n_channels = ARRAY_SIZE(b43_2ghz_chantable), | ||
266 | .bitrates = b43_g_ratetable, | ||
267 | .n_bitrates = b43_g_ratetable_size, | ||
171 | }; | 268 | }; |
172 | #define b43_5ghz_chantable_size ARRAY_SIZE(b43_5ghz_chantable) | ||
173 | #endif | ||
174 | 269 | ||
175 | static void b43_wireless_core_exit(struct b43_wldev *dev); | 270 | static void b43_wireless_core_exit(struct b43_wldev *dev); |
176 | static int b43_wireless_core_init(struct b43_wldev *dev); | 271 | static int b43_wireless_core_init(struct b43_wldev *dev); |
@@ -370,24 +465,30 @@ out: | |||
370 | } | 465 | } |
371 | 466 | ||
372 | /* Read HostFlags */ | 467 | /* Read HostFlags */ |
373 | u32 b43_hf_read(struct b43_wldev * dev) | 468 | u64 b43_hf_read(struct b43_wldev * dev) |
374 | { | 469 | { |
375 | u32 ret; | 470 | u64 ret; |
376 | 471 | ||
377 | ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI); | 472 | ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI); |
378 | ret <<= 16; | 473 | ret <<= 16; |
474 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI); | ||
475 | ret <<= 16; | ||
379 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO); | 476 | ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO); |
380 | 477 | ||
381 | return ret; | 478 | return ret; |
382 | } | 479 | } |
383 | 480 | ||
384 | /* Write HostFlags */ | 481 | /* Write HostFlags */ |
385 | void b43_hf_write(struct b43_wldev *dev, u32 value) | 482 | void b43_hf_write(struct b43_wldev *dev, u64 value) |
386 | { | 483 | { |
387 | b43_shm_write16(dev, B43_SHM_SHARED, | 484 | u16 lo, mi, hi; |
388 | B43_SHM_SH_HOSTFLO, (value & 0x0000FFFF)); | 485 | |
389 | b43_shm_write16(dev, B43_SHM_SHARED, | 486 | lo = (value & 0x00000000FFFFULL); |
390 | B43_SHM_SH_HOSTFHI, ((value & 0xFFFF0000) >> 16)); | 487 | mi = (value & 0x0000FFFF0000ULL) >> 16; |
488 | hi = (value & 0xFFFF00000000ULL) >> 32; | ||
489 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFLO, lo); | ||
490 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFMI, mi); | ||
491 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | ||
391 | } | 492 | } |
392 | 493 | ||
393 | void b43_tsf_read(struct b43_wldev *dev, u64 * tsf) | 494 | void b43_tsf_read(struct b43_wldev *dev, u64 * tsf) |
@@ -1222,17 +1323,18 @@ static void b43_write_beacon_template(struct b43_wldev *dev, | |||
1222 | } | 1323 | } |
1223 | 1324 | ||
1224 | static void b43_write_probe_resp_plcp(struct b43_wldev *dev, | 1325 | static void b43_write_probe_resp_plcp(struct b43_wldev *dev, |
1225 | u16 shm_offset, u16 size, u8 rate) | 1326 | u16 shm_offset, u16 size, |
1327 | struct ieee80211_rate *rate) | ||
1226 | { | 1328 | { |
1227 | struct b43_plcp_hdr4 plcp; | 1329 | struct b43_plcp_hdr4 plcp; |
1228 | u32 tmp; | 1330 | u32 tmp; |
1229 | __le16 dur; | 1331 | __le16 dur; |
1230 | 1332 | ||
1231 | plcp.data = 0; | 1333 | plcp.data = 0; |
1232 | b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 1334 | b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value); |
1233 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1335 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1234 | dev->wl->vif, size, | 1336 | dev->wl->vif, size, |
1235 | B43_RATE_TO_BASE100KBPS(rate)); | 1337 | rate); |
1236 | /* Write PLCP in two parts and timing for packet transfer */ | 1338 | /* Write PLCP in two parts and timing for packet transfer */ |
1237 | tmp = le32_to_cpu(plcp.data); | 1339 | tmp = le32_to_cpu(plcp.data); |
1238 | b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); | 1340 | b43_shm_write16(dev, B43_SHM_SHARED, shm_offset, tmp & 0xFFFF); |
@@ -1247,7 +1349,8 @@ static void b43_write_probe_resp_plcp(struct b43_wldev *dev, | |||
1247 | * 3) Stripping TIM | 1349 | * 3) Stripping TIM |
1248 | */ | 1350 | */ |
1249 | static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | 1351 | static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, |
1250 | u16 *dest_size, u8 rate) | 1352 | u16 *dest_size, |
1353 | struct ieee80211_rate *rate) | ||
1251 | { | 1354 | { |
1252 | const u8 *src_data; | 1355 | const u8 *src_data; |
1253 | u8 *dest_data; | 1356 | u8 *dest_data; |
@@ -1292,7 +1395,7 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | |||
1292 | IEEE80211_STYPE_PROBE_RESP); | 1395 | IEEE80211_STYPE_PROBE_RESP); |
1293 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1396 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1294 | dev->wl->vif, *dest_size, | 1397 | dev->wl->vif, *dest_size, |
1295 | B43_RATE_TO_BASE100KBPS(rate)); | 1398 | rate); |
1296 | hdr->duration_id = dur; | 1399 | hdr->duration_id = dur; |
1297 | 1400 | ||
1298 | return dest_data; | 1401 | return dest_data; |
@@ -1300,7 +1403,8 @@ static const u8 * b43_generate_probe_resp(struct b43_wldev *dev, | |||
1300 | 1403 | ||
1301 | static void b43_write_probe_resp_template(struct b43_wldev *dev, | 1404 | static void b43_write_probe_resp_template(struct b43_wldev *dev, |
1302 | u16 ram_offset, | 1405 | u16 ram_offset, |
1303 | u16 shm_size_offset, u8 rate) | 1406 | u16 shm_size_offset, |
1407 | struct ieee80211_rate *rate) | ||
1304 | { | 1408 | { |
1305 | const u8 *probe_resp_data; | 1409 | const u8 *probe_resp_data; |
1306 | u16 size; | 1410 | u16 size; |
@@ -1313,14 +1417,15 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
1313 | /* Looks like PLCP headers plus packet timings are stored for | 1417 | /* Looks like PLCP headers plus packet timings are stored for |
1314 | * all possible basic rates | 1418 | * all possible basic rates |
1315 | */ | 1419 | */ |
1316 | b43_write_probe_resp_plcp(dev, 0x31A, size, B43_CCK_RATE_1MB); | 1420 | b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]); |
1317 | b43_write_probe_resp_plcp(dev, 0x32C, size, B43_CCK_RATE_2MB); | 1421 | b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]); |
1318 | b43_write_probe_resp_plcp(dev, 0x33E, size, B43_CCK_RATE_5MB); | 1422 | b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]); |
1319 | b43_write_probe_resp_plcp(dev, 0x350, size, B43_CCK_RATE_11MB); | 1423 | b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]); |
1320 | 1424 | ||
1321 | size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); | 1425 | size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); |
1322 | b43_write_template_common(dev, probe_resp_data, | 1426 | b43_write_template_common(dev, probe_resp_data, |
1323 | size, ram_offset, shm_size_offset, rate); | 1427 | size, ram_offset, shm_size_offset, |
1428 | rate->hw_value); | ||
1324 | kfree(probe_resp_data); | 1429 | kfree(probe_resp_data); |
1325 | } | 1430 | } |
1326 | 1431 | ||
@@ -1388,7 +1493,7 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
1388 | b43_write_beacon_template(dev, 0x68, 0x18, | 1493 | b43_write_beacon_template(dev, 0x68, 0x18, |
1389 | B43_CCK_RATE_1MB); | 1494 | B43_CCK_RATE_1MB); |
1390 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1495 | b43_write_probe_resp_template(dev, 0x268, 0x4A, |
1391 | B43_CCK_RATE_11MB); | 1496 | &__b43_ratetable[3]); |
1392 | wl->beacon0_uploaded = 1; | 1497 | wl->beacon0_uploaded = 1; |
1393 | } | 1498 | } |
1394 | cmd |= B43_MACCMD_BEACON0_VALID; | 1499 | cmd |= B43_MACCMD_BEACON0_VALID; |
@@ -2643,45 +2748,6 @@ static int b43_op_get_stats(struct ieee80211_hw *hw, | |||
2643 | return 0; | 2748 | return 0; |
2644 | } | 2749 | } |
2645 | 2750 | ||
2646 | static const char *phymode_to_string(unsigned int phymode) | ||
2647 | { | ||
2648 | switch (phymode) { | ||
2649 | case B43_PHYMODE_A: | ||
2650 | return "A"; | ||
2651 | case B43_PHYMODE_B: | ||
2652 | return "B"; | ||
2653 | case B43_PHYMODE_G: | ||
2654 | return "G"; | ||
2655 | default: | ||
2656 | B43_WARN_ON(1); | ||
2657 | } | ||
2658 | return ""; | ||
2659 | } | ||
2660 | |||
2661 | static int find_wldev_for_phymode(struct b43_wl *wl, | ||
2662 | unsigned int phymode, | ||
2663 | struct b43_wldev **dev, bool * gmode) | ||
2664 | { | ||
2665 | struct b43_wldev *d; | ||
2666 | |||
2667 | list_for_each_entry(d, &wl->devlist, list) { | ||
2668 | if (d->phy.possible_phymodes & phymode) { | ||
2669 | /* Ok, this device supports the PHY-mode. | ||
2670 | * Now figure out how the gmode bit has to be | ||
2671 | * set to support it. */ | ||
2672 | if (phymode == B43_PHYMODE_A) | ||
2673 | *gmode = 0; | ||
2674 | else | ||
2675 | *gmode = 1; | ||
2676 | *dev = d; | ||
2677 | |||
2678 | return 0; | ||
2679 | } | ||
2680 | } | ||
2681 | |||
2682 | return -ESRCH; | ||
2683 | } | ||
2684 | |||
2685 | static void b43_put_phy_into_reset(struct b43_wldev *dev) | 2751 | static void b43_put_phy_into_reset(struct b43_wldev *dev) |
2686 | { | 2752 | { |
2687 | struct ssb_device *sdev = dev->dev; | 2753 | struct ssb_device *sdev = dev->dev; |
@@ -2701,28 +2767,64 @@ static void b43_put_phy_into_reset(struct b43_wldev *dev) | |||
2701 | msleep(1); | 2767 | msleep(1); |
2702 | } | 2768 | } |
2703 | 2769 | ||
2770 | static const char * band_to_string(enum ieee80211_band band) | ||
2771 | { | ||
2772 | switch (band) { | ||
2773 | case IEEE80211_BAND_5GHZ: | ||
2774 | return "5"; | ||
2775 | case IEEE80211_BAND_2GHZ: | ||
2776 | return "2.4"; | ||
2777 | default: | ||
2778 | break; | ||
2779 | } | ||
2780 | B43_WARN_ON(1); | ||
2781 | return ""; | ||
2782 | } | ||
2783 | |||
2704 | /* Expects wl->mutex locked */ | 2784 | /* Expects wl->mutex locked */ |
2705 | static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | 2785 | static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) |
2706 | { | 2786 | { |
2707 | struct b43_wldev *up_dev; | 2787 | struct b43_wldev *up_dev = NULL; |
2708 | struct b43_wldev *down_dev; | 2788 | struct b43_wldev *down_dev; |
2789 | struct b43_wldev *d; | ||
2709 | int err; | 2790 | int err; |
2710 | bool gmode = 0; | 2791 | bool gmode; |
2711 | int prev_status; | 2792 | int prev_status; |
2712 | 2793 | ||
2713 | err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode); | 2794 | /* Find a device and PHY which supports the band. */ |
2714 | if (err) { | 2795 | list_for_each_entry(d, &wl->devlist, list) { |
2715 | b43err(wl, "Could not find a device for %s-PHY mode\n", | 2796 | switch (chan->band) { |
2716 | phymode_to_string(new_mode)); | 2797 | case IEEE80211_BAND_5GHZ: |
2717 | return err; | 2798 | if (d->phy.supports_5ghz) { |
2799 | up_dev = d; | ||
2800 | gmode = 0; | ||
2801 | } | ||
2802 | break; | ||
2803 | case IEEE80211_BAND_2GHZ: | ||
2804 | if (d->phy.supports_2ghz) { | ||
2805 | up_dev = d; | ||
2806 | gmode = 1; | ||
2807 | } | ||
2808 | break; | ||
2809 | default: | ||
2810 | B43_WARN_ON(1); | ||
2811 | return -EINVAL; | ||
2812 | } | ||
2813 | if (up_dev) | ||
2814 | break; | ||
2815 | } | ||
2816 | if (!up_dev) { | ||
2817 | b43err(wl, "Could not find a device for %s-GHz band operation\n", | ||
2818 | band_to_string(chan->band)); | ||
2819 | return -ENODEV; | ||
2718 | } | 2820 | } |
2719 | if ((up_dev == wl->current_dev) && | 2821 | if ((up_dev == wl->current_dev) && |
2720 | (!!wl->current_dev->phy.gmode == !!gmode)) { | 2822 | (!!wl->current_dev->phy.gmode == !!gmode)) { |
2721 | /* This device is already running. */ | 2823 | /* This device is already running. */ |
2722 | return 0; | 2824 | return 0; |
2723 | } | 2825 | } |
2724 | b43dbg(wl, "Reconfiguring PHYmode to %s-PHY\n", | 2826 | b43dbg(wl, "Switching to %s-GHz band\n", |
2725 | phymode_to_string(new_mode)); | 2827 | band_to_string(chan->band)); |
2726 | down_dev = wl->current_dev; | 2828 | down_dev = wl->current_dev; |
2727 | 2829 | ||
2728 | prev_status = b43_status(down_dev); | 2830 | prev_status = b43_status(down_dev); |
@@ -2744,8 +2846,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2744 | err = b43_wireless_core_init(up_dev); | 2846 | err = b43_wireless_core_init(up_dev); |
2745 | if (err) { | 2847 | if (err) { |
2746 | b43err(wl, "Fatal: Could not initialize device for " | 2848 | b43err(wl, "Fatal: Could not initialize device for " |
2747 | "newly selected %s-PHY mode\n", | 2849 | "selected %s-GHz band\n", |
2748 | phymode_to_string(new_mode)); | 2850 | band_to_string(chan->band)); |
2749 | goto init_failure; | 2851 | goto init_failure; |
2750 | } | 2852 | } |
2751 | } | 2853 | } |
@@ -2753,8 +2855,8 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2753 | err = b43_wireless_core_start(up_dev); | 2855 | err = b43_wireless_core_start(up_dev); |
2754 | if (err) { | 2856 | if (err) { |
2755 | b43err(wl, "Fatal: Coult not start device for " | 2857 | b43err(wl, "Fatal: Coult not start device for " |
2756 | "newly selected %s-PHY mode\n", | 2858 | "selected %s-GHz band\n", |
2757 | phymode_to_string(new_mode)); | 2859 | band_to_string(chan->band)); |
2758 | b43_wireless_core_exit(up_dev); | 2860 | b43_wireless_core_exit(up_dev); |
2759 | goto init_failure; | 2861 | goto init_failure; |
2760 | } | 2862 | } |
@@ -2764,7 +2866,7 @@ static int b43_switch_phymode(struct b43_wl *wl, unsigned int new_mode) | |||
2764 | wl->current_dev = up_dev; | 2866 | wl->current_dev = up_dev; |
2765 | 2867 | ||
2766 | return 0; | 2868 | return 0; |
2767 | init_failure: | 2869 | init_failure: |
2768 | /* Whoops, failed to init the new core. No core is operating now. */ | 2870 | /* Whoops, failed to init the new core. No core is operating now. */ |
2769 | wl->current_dev = NULL; | 2871 | wl->current_dev = NULL; |
2770 | return err; | 2872 | return err; |
@@ -2822,28 +2924,14 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
2822 | struct b43_wldev *dev; | 2924 | struct b43_wldev *dev; |
2823 | struct b43_phy *phy; | 2925 | struct b43_phy *phy; |
2824 | unsigned long flags; | 2926 | unsigned long flags; |
2825 | unsigned int new_phymode = 0xFFFF; | ||
2826 | int antenna; | 2927 | int antenna; |
2827 | int err = 0; | 2928 | int err = 0; |
2828 | u32 savedirqs; | 2929 | u32 savedirqs; |
2829 | 2930 | ||
2830 | mutex_lock(&wl->mutex); | 2931 | mutex_lock(&wl->mutex); |
2831 | 2932 | ||
2832 | /* Switch the PHY mode (if necessary). */ | 2933 | /* Switch the band (if necessary). This might change the active core. */ |
2833 | switch (conf->phymode) { | 2934 | err = b43_switch_band(wl, conf->channel); |
2834 | case MODE_IEEE80211A: | ||
2835 | new_phymode = B43_PHYMODE_A; | ||
2836 | break; | ||
2837 | case MODE_IEEE80211B: | ||
2838 | new_phymode = B43_PHYMODE_B; | ||
2839 | break; | ||
2840 | case MODE_IEEE80211G: | ||
2841 | new_phymode = B43_PHYMODE_G; | ||
2842 | break; | ||
2843 | default: | ||
2844 | B43_WARN_ON(1); | ||
2845 | } | ||
2846 | err = b43_switch_phymode(wl, new_phymode); | ||
2847 | if (err) | 2935 | if (err) |
2848 | goto out_unlock_mutex; | 2936 | goto out_unlock_mutex; |
2849 | dev = wl->current_dev; | 2937 | dev = wl->current_dev; |
@@ -2863,8 +2951,8 @@ static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | |||
2863 | 2951 | ||
2864 | /* Switch to the requested channel. | 2952 | /* Switch to the requested channel. |
2865 | * The firmware takes care of races with the TX handler. */ | 2953 | * The firmware takes care of races with the TX handler. */ |
2866 | if (conf->channel_val != phy->channel) | 2954 | if (conf->channel->hw_value != phy->channel) |
2867 | b43_radio_selectchannel(dev, conf->channel_val, 0); | 2955 | b43_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2868 | 2956 | ||
2869 | /* Enable/Disable ShortSlot timing. */ | 2957 | /* Enable/Disable ShortSlot timing. */ |
2870 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != | 2958 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) != |
@@ -3806,31 +3894,23 @@ static void b43_chip_reset(struct work_struct *work) | |||
3806 | b43info(wl, "Controller restarted\n"); | 3894 | b43info(wl, "Controller restarted\n"); |
3807 | } | 3895 | } |
3808 | 3896 | ||
3809 | static int b43_setup_modes(struct b43_wldev *dev, | 3897 | static int b43_setup_bands(struct b43_wldev *dev, |
3810 | bool have_2ghz_phy, bool have_5ghz_phy) | 3898 | bool have_2ghz_phy, bool have_5ghz_phy) |
3811 | { | 3899 | { |
3812 | struct ieee80211_hw *hw = dev->wl->hw; | 3900 | struct ieee80211_hw *hw = dev->wl->hw; |
3813 | struct ieee80211_hw_mode *mode; | ||
3814 | struct b43_phy *phy = &dev->phy; | ||
3815 | int err; | ||
3816 | 3901 | ||
3817 | /* XXX: This function will go away soon, when mac80211 | 3902 | if (have_2ghz_phy) |
3818 | * band stuff is rewritten. So this is just a hack. | 3903 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz; |
3819 | * For now we always claim GPHY mode, as there is no | 3904 | if (dev->phy.type == B43_PHYTYPE_N) { |
3820 | * support for NPHY and APHY in the device, yet. | 3905 | if (have_5ghz_phy) |
3821 | * This assumption is OK, as any B, N or A PHY will already | 3906 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy; |
3822 | * have died a horrible sanity check death earlier. */ | 3907 | } else { |
3823 | 3908 | if (have_5ghz_phy) | |
3824 | mode = &phy->hwmodes[0]; | 3909 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy; |
3825 | mode->mode = MODE_IEEE80211G; | 3910 | } |
3826 | mode->num_channels = b43_2ghz_chantable_size; | 3911 | |
3827 | mode->channels = b43_2ghz_chantable; | 3912 | dev->phy.supports_2ghz = have_2ghz_phy; |
3828 | mode->num_rates = b43_g_ratetable_size; | 3913 | dev->phy.supports_5ghz = have_5ghz_phy; |
3829 | mode->rates = b43_g_ratetable; | ||
3830 | err = ieee80211_register_hwmode(hw, mode); | ||
3831 | if (err) | ||
3832 | return err; | ||
3833 | phy->possible_phymodes |= B43_PHYMODE_G; | ||
3834 | 3914 | ||
3835 | return 0; | 3915 | return 0; |
3836 | } | 3916 | } |
@@ -3912,7 +3992,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
3912 | err = b43_validate_chipaccess(dev); | 3992 | err = b43_validate_chipaccess(dev); |
3913 | if (err) | 3993 | if (err) |
3914 | goto err_powerdown; | 3994 | goto err_powerdown; |
3915 | err = b43_setup_modes(dev, have_2ghz_phy, have_5ghz_phy); | 3995 | err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy); |
3916 | if (err) | 3996 | if (err) |
3917 | goto err_powerdown; | 3997 | goto err_powerdown; |
3918 | 3998 | ||
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 2d52d9de9305..24a79f5d6ff5 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -95,8 +95,8 @@ u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); | |||
95 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); | 95 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); |
96 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); | 96 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); |
97 | 97 | ||
98 | u32 b43_hf_read(struct b43_wldev *dev); | 98 | u64 b43_hf_read(struct b43_wldev *dev); |
99 | void b43_hf_write(struct b43_wldev *dev, u32 value); | 99 | void b43_hf_write(struct b43_wldev *dev, u64 value); |
100 | 100 | ||
101 | void b43_dummy_transmission(struct b43_wldev *dev); | 101 | void b43_dummy_transmission(struct b43_wldev *dev); |
102 | 102 | ||
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index f4faff6a7d6c..275095b8cbe7 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c | |||
@@ -47,29 +47,6 @@ static int get_integer(const char *buf, size_t count) | |||
47 | return ret; | 47 | return ret; |
48 | } | 48 | } |
49 | 49 | ||
50 | static int get_boolean(const char *buf, size_t count) | ||
51 | { | ||
52 | if (count != 0) { | ||
53 | if (buf[0] == '1') | ||
54 | return 1; | ||
55 | if (buf[0] == '0') | ||
56 | return 0; | ||
57 | if (count >= 4 && memcmp(buf, "true", 4) == 0) | ||
58 | return 1; | ||
59 | if (count >= 5 && memcmp(buf, "false", 5) == 0) | ||
60 | return 0; | ||
61 | if (count >= 3 && memcmp(buf, "yes", 3) == 0) | ||
62 | return 1; | ||
63 | if (count >= 2 && memcmp(buf, "no", 2) == 0) | ||
64 | return 0; | ||
65 | if (count >= 2 && memcmp(buf, "on", 2) == 0) | ||
66 | return 1; | ||
67 | if (count >= 3 && memcmp(buf, "off", 3) == 0) | ||
68 | return 0; | ||
69 | } | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | static ssize_t b43_attr_interfmode_show(struct device *dev, | 50 | static ssize_t b43_attr_interfmode_show(struct device *dev, |
74 | struct device_attribute *attr, | 51 | struct device_attribute *attr, |
75 | char *buf) | 52 | char *buf) |
@@ -155,82 +132,18 @@ static ssize_t b43_attr_interfmode_store(struct device *dev, | |||
155 | static DEVICE_ATTR(interference, 0644, | 132 | static DEVICE_ATTR(interference, 0644, |
156 | b43_attr_interfmode_show, b43_attr_interfmode_store); | 133 | b43_attr_interfmode_show, b43_attr_interfmode_store); |
157 | 134 | ||
158 | static ssize_t b43_attr_preamble_show(struct device *dev, | ||
159 | struct device_attribute *attr, char *buf) | ||
160 | { | ||
161 | struct b43_wldev *wldev = dev_to_b43_wldev(dev); | ||
162 | ssize_t count; | ||
163 | |||
164 | if (!capable(CAP_NET_ADMIN)) | ||
165 | return -EPERM; | ||
166 | |||
167 | mutex_lock(&wldev->wl->mutex); | ||
168 | |||
169 | if (wldev->short_preamble) | ||
170 | count = | ||
171 | snprintf(buf, PAGE_SIZE, "1 (Short Preamble enabled)\n"); | ||
172 | else | ||
173 | count = | ||
174 | snprintf(buf, PAGE_SIZE, "0 (Short Preamble disabled)\n"); | ||
175 | |||
176 | mutex_unlock(&wldev->wl->mutex); | ||
177 | |||
178 | return count; | ||
179 | } | ||
180 | |||
181 | static ssize_t b43_attr_preamble_store(struct device *dev, | ||
182 | struct device_attribute *attr, | ||
183 | const char *buf, size_t count) | ||
184 | { | ||
185 | struct b43_wldev *wldev = dev_to_b43_wldev(dev); | ||
186 | unsigned long flags; | ||
187 | int value; | ||
188 | |||
189 | if (!capable(CAP_NET_ADMIN)) | ||
190 | return -EPERM; | ||
191 | |||
192 | value = get_boolean(buf, count); | ||
193 | if (value < 0) | ||
194 | return value; | ||
195 | mutex_lock(&wldev->wl->mutex); | ||
196 | spin_lock_irqsave(&wldev->wl->irq_lock, flags); | ||
197 | |||
198 | wldev->short_preamble = !!value; | ||
199 | |||
200 | spin_unlock_irqrestore(&wldev->wl->irq_lock, flags); | ||
201 | mutex_unlock(&wldev->wl->mutex); | ||
202 | |||
203 | return count; | ||
204 | } | ||
205 | |||
206 | static DEVICE_ATTR(shortpreamble, 0644, | ||
207 | b43_attr_preamble_show, b43_attr_preamble_store); | ||
208 | |||
209 | int b43_sysfs_register(struct b43_wldev *wldev) | 135 | int b43_sysfs_register(struct b43_wldev *wldev) |
210 | { | 136 | { |
211 | struct device *dev = wldev->dev->dev; | 137 | struct device *dev = wldev->dev->dev; |
212 | int err; | ||
213 | 138 | ||
214 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); | 139 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); |
215 | 140 | ||
216 | err = device_create_file(dev, &dev_attr_interference); | 141 | return device_create_file(dev, &dev_attr_interference); |
217 | if (err) | ||
218 | goto out; | ||
219 | err = device_create_file(dev, &dev_attr_shortpreamble); | ||
220 | if (err) | ||
221 | goto err_remove_interfmode; | ||
222 | |||
223 | out: | ||
224 | return err; | ||
225 | err_remove_interfmode: | ||
226 | device_remove_file(dev, &dev_attr_interference); | ||
227 | goto out; | ||
228 | } | 142 | } |
229 | 143 | ||
230 | void b43_sysfs_unregister(struct b43_wldev *wldev) | 144 | void b43_sysfs_unregister(struct b43_wldev *wldev) |
231 | { | 145 | { |
232 | struct device *dev = wldev->dev->dev; | 146 | struct device *dev = wldev->dev->dev; |
233 | 147 | ||
234 | device_remove_file(dev, &dev_attr_shortpreamble); | ||
235 | device_remove_file(dev, &dev_attr_interference); | 148 | device_remove_file(dev, &dev_attr_interference); |
236 | } | 149 | } |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 7caa26eb4105..187c11bee0f1 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -32,46 +32,48 @@ | |||
32 | #include "dma.h" | 32 | #include "dma.h" |
33 | 33 | ||
34 | 34 | ||
35 | /* Extract the bitrate out of a CCK PLCP header. */ | 35 | /* Extract the bitrate index out of a CCK PLCP header. */ |
36 | static u8 b43_plcp_get_bitrate_cck(struct b43_plcp_hdr6 *plcp) | 36 | static int b43_plcp_get_bitrate_idx_cck(struct b43_plcp_hdr6 *plcp) |
37 | { | 37 | { |
38 | switch (plcp->raw[0]) { | 38 | switch (plcp->raw[0]) { |
39 | case 0x0A: | 39 | case 0x0A: |
40 | return B43_CCK_RATE_1MB; | 40 | return 0; |
41 | case 0x14: | 41 | case 0x14: |
42 | return B43_CCK_RATE_2MB; | 42 | return 1; |
43 | case 0x37: | 43 | case 0x37: |
44 | return B43_CCK_RATE_5MB; | 44 | return 2; |
45 | case 0x6E: | 45 | case 0x6E: |
46 | return B43_CCK_RATE_11MB; | 46 | return 3; |
47 | } | 47 | } |
48 | B43_WARN_ON(1); | 48 | B43_WARN_ON(1); |
49 | return 0; | 49 | return -1; |
50 | } | 50 | } |
51 | 51 | ||
52 | /* Extract the bitrate out of an OFDM PLCP header. */ | 52 | /* Extract the bitrate index out of an OFDM PLCP header. */ |
53 | static u8 b43_plcp_get_bitrate_ofdm(struct b43_plcp_hdr6 *plcp) | 53 | static u8 b43_plcp_get_bitrate_idx_ofdm(struct b43_plcp_hdr6 *plcp, bool aphy) |
54 | { | 54 | { |
55 | int base = aphy ? 0 : 4; | ||
56 | |||
55 | switch (plcp->raw[0] & 0xF) { | 57 | switch (plcp->raw[0] & 0xF) { |
56 | case 0xB: | 58 | case 0xB: |
57 | return B43_OFDM_RATE_6MB; | 59 | return base + 0; |
58 | case 0xF: | 60 | case 0xF: |
59 | return B43_OFDM_RATE_9MB; | 61 | return base + 1; |
60 | case 0xA: | 62 | case 0xA: |
61 | return B43_OFDM_RATE_12MB; | 63 | return base + 2; |
62 | case 0xE: | 64 | case 0xE: |
63 | return B43_OFDM_RATE_18MB; | 65 | return base + 3; |
64 | case 0x9: | 66 | case 0x9: |
65 | return B43_OFDM_RATE_24MB; | 67 | return base + 4; |
66 | case 0xD: | 68 | case 0xD: |
67 | return B43_OFDM_RATE_36MB; | 69 | return base + 5; |
68 | case 0x8: | 70 | case 0x8: |
69 | return B43_OFDM_RATE_48MB; | 71 | return base + 6; |
70 | case 0xC: | 72 | case 0xC: |
71 | return B43_OFDM_RATE_54MB; | 73 | return base + 7; |
72 | } | 74 | } |
73 | B43_WARN_ON(1); | 75 | B43_WARN_ON(1); |
74 | return 0; | 76 | return -1; |
75 | } | 77 | } |
76 | 78 | ||
77 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) | 79 | u8 b43_plcp_get_ratecode_cck(const u8 bitrate) |
@@ -191,6 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
191 | (const struct ieee80211_hdr *)fragment_data; | 193 | (const struct ieee80211_hdr *)fragment_data; |
192 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); | 194 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); |
193 | u16 fctl = le16_to_cpu(wlhdr->frame_control); | 195 | u16 fctl = le16_to_cpu(wlhdr->frame_control); |
196 | struct ieee80211_rate *fbrate; | ||
194 | u8 rate, rate_fb; | 197 | u8 rate, rate_fb; |
195 | int rate_ofdm, rate_fb_ofdm; | 198 | int rate_ofdm, rate_fb_ofdm; |
196 | unsigned int plcp_fragment_len; | 199 | unsigned int plcp_fragment_len; |
@@ -200,9 +203,11 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
200 | 203 | ||
201 | memset(txhdr, 0, sizeof(*txhdr)); | 204 | memset(txhdr, 0, sizeof(*txhdr)); |
202 | 205 | ||
203 | rate = txctl->tx_rate; | 206 | WARN_ON(!txctl->tx_rate); |
207 | rate = txctl->tx_rate ? txctl->tx_rate->hw_value : B43_CCK_RATE_1MB; | ||
204 | rate_ofdm = b43_is_ofdm_rate(rate); | 208 | rate_ofdm = b43_is_ofdm_rate(rate); |
205 | rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; | 209 | fbrate = txctl->alt_retry_rate ? : txctl->tx_rate; |
210 | rate_fb = fbrate->hw_value; | ||
206 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); | 211 | rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); |
207 | 212 | ||
208 | if (rate_ofdm) | 213 | if (rate_ofdm) |
@@ -221,11 +226,10 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
221 | * use the original dur_id field. */ | 226 | * use the original dur_id field. */ |
222 | txhdr->dur_fb = wlhdr->duration_id; | 227 | txhdr->dur_fb = wlhdr->duration_id; |
223 | } else { | 228 | } else { |
224 | int fbrate_base100kbps = B43_RATE_TO_BASE100KBPS(rate_fb); | ||
225 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, | 229 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, |
226 | txctl->vif, | 230 | txctl->vif, |
227 | fragment_len, | 231 | fragment_len, |
228 | fbrate_base100kbps); | 232 | fbrate); |
229 | } | 233 | } |
230 | 234 | ||
231 | plcp_fragment_len = fragment_len + FCS_LEN; | 235 | plcp_fragment_len = fragment_len + FCS_LEN; |
@@ -287,7 +291,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
287 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; | 291 | phy_ctl |= B43_TXH_PHY_ENC_OFDM; |
288 | else | 292 | else |
289 | phy_ctl |= B43_TXH_PHY_ENC_CCK; | 293 | phy_ctl |= B43_TXH_PHY_ENC_CCK; |
290 | if (dev->short_preamble) | 294 | if (txctl->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) |
291 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; | 295 | phy_ctl |= B43_TXH_PHY_SHORTPRMBL; |
292 | 296 | ||
293 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { | 297 | switch (b43_ieee80211_antenna_sanitize(dev, txctl->antenna_sel_tx)) { |
@@ -332,7 +336,8 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
332 | int rts_rate_ofdm, rts_rate_fb_ofdm; | 336 | int rts_rate_ofdm, rts_rate_fb_ofdm; |
333 | struct b43_plcp_hdr6 *plcp; | 337 | struct b43_plcp_hdr6 *plcp; |
334 | 338 | ||
335 | rts_rate = txctl->rts_cts_rate; | 339 | WARN_ON(!txctl->rts_cts_rate); |
340 | rts_rate = txctl->rts_cts_rate ? txctl->rts_cts_rate->hw_value : B43_CCK_RATE_1MB; | ||
336 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); | 341 | rts_rate_ofdm = b43_is_ofdm_rate(rts_rate); |
337 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); | 342 | rts_rate_fb = b43_calc_fallback_rate(rts_rate); |
338 | rts_rate_fb_ofdm = b43_is_ofdm_rate(rts_rate_fb); | 343 | 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 | u16 phystat0, phystat3, chanstat, mactime; | 511 | u16 phystat0, phystat3, chanstat, mactime; |
507 | u32 macstat; | 512 | u32 macstat; |
508 | u16 chanid; | 513 | u16 chanid; |
514 | u16 phytype; | ||
509 | u8 jssi; | 515 | u8 jssi; |
510 | int padding; | 516 | int padding; |
511 | 517 | ||
@@ -518,6 +524,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
518 | macstat = le32_to_cpu(rxhdr->mac_status); | 524 | macstat = le32_to_cpu(rxhdr->mac_status); |
519 | mactime = le16_to_cpu(rxhdr->mac_time); | 525 | mactime = le16_to_cpu(rxhdr->mac_time); |
520 | chanstat = le16_to_cpu(rxhdr->channel); | 526 | chanstat = le16_to_cpu(rxhdr->channel); |
527 | phytype = chanstat & B43_RX_CHAN_PHYTYPE; | ||
521 | 528 | ||
522 | if (macstat & B43_RX_MAC_FCSERR) | 529 | if (macstat & B43_RX_MAC_FCSERR) |
523 | dev->wl->ieee_stats.dot11FCSErrorCount++; | 530 | dev->wl->ieee_stats.dot11FCSErrorCount++; |
@@ -575,18 +582,23 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
575 | /* the next line looks wrong, but is what mac80211 wants */ | 582 | /* the next line looks wrong, but is what mac80211 wants */ |
576 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; | 583 | status.signal = (jssi * 100) / B43_RX_MAX_SSI; |
577 | if (phystat0 & B43_RX_PHYST0_OFDM) | 584 | if (phystat0 & B43_RX_PHYST0_OFDM) |
578 | status.rate = b43_plcp_get_bitrate_ofdm(plcp); | 585 | status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, |
586 | phytype == B43_PHYTYPE_A); | ||
579 | else | 587 | else |
580 | status.rate = b43_plcp_get_bitrate_cck(plcp); | 588 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); |
581 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); | 589 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); |
582 | 590 | ||
583 | /* | 591 | /* |
584 | * If monitors are present get full 64-bit timestamp. This | 592 | * All frames on monitor interfaces and beacons always need a full |
585 | * code assumes we get to process the packet within 16 bits | 593 | * 64-bit timestamp. Monitor interfaces need it for diagnostic |
586 | * of timestamp, i.e. about 65 milliseconds after the PHY | 594 | * purposes and beacons for IBSS merging. |
587 | * received the first symbol. | 595 | * This code assumes we get to process the packet within 16 bits |
596 | * of timestamp, i.e. about 65 milliseconds after the PHY received | ||
597 | * the first symbol. | ||
588 | */ | 598 | */ |
589 | if (dev->wl->radiotap_enabled) { | 599 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) |
600 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
601 | dev->wl->radiotap_enabled) { | ||
590 | u16 low_mactime_now; | 602 | u16 low_mactime_now; |
591 | 603 | ||
592 | b43_tsf_read(dev, &status.mactime); | 604 | b43_tsf_read(dev, &status.mactime); |
@@ -601,29 +613,28 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
601 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; | 613 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; |
602 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { | 614 | switch (chanstat & B43_RX_CHAN_PHYTYPE) { |
603 | case B43_PHYTYPE_A: | 615 | case B43_PHYTYPE_A: |
604 | status.phymode = MODE_IEEE80211A; | 616 | status.band = IEEE80211_BAND_5GHZ; |
605 | B43_WARN_ON(1); | 617 | B43_WARN_ON(1); |
606 | /* FIXME: We don't really know which value the "chanid" contains. | 618 | /* FIXME: We don't really know which value the "chanid" contains. |
607 | * So the following assignment might be wrong. */ | 619 | * So the following assignment might be wrong. */ |
608 | status.channel = chanid; | 620 | status.freq = b43_channel_to_freq_5ghz(chanid); |
609 | status.freq = b43_channel_to_freq_5ghz(status.channel); | ||
610 | break; | 621 | break; |
611 | case B43_PHYTYPE_G: | 622 | case B43_PHYTYPE_G: |
612 | status.phymode = MODE_IEEE80211G; | 623 | status.band = IEEE80211_BAND_2GHZ; |
613 | /* chanid is the radio channel cookie value as used | 624 | /* chanid is the radio channel cookie value as used |
614 | * to tune the radio. */ | 625 | * to tune the radio. */ |
615 | status.freq = chanid + 2400; | 626 | status.freq = chanid + 2400; |
616 | status.channel = b43_freq_to_channel_2ghz(status.freq); | ||
617 | break; | 627 | break; |
618 | case B43_PHYTYPE_N: | 628 | case B43_PHYTYPE_N: |
619 | status.phymode = 0xDEAD /*FIXME MODE_IEEE80211N*/; | ||
620 | /* chanid is the SHM channel cookie. Which is the plain | 629 | /* chanid is the SHM channel cookie. Which is the plain |
621 | * channel number in b43. */ | 630 | * channel number in b43. */ |
622 | status.channel = chanid; | 631 | if (chanstat & B43_RX_CHAN_5GHZ) { |
623 | if (chanstat & B43_RX_CHAN_5GHZ) | 632 | status.band = IEEE80211_BAND_5GHZ; |
624 | status.freq = b43_freq_to_channel_5ghz(status.freq); | 633 | status.freq = b43_freq_to_channel_5ghz(chanid); |
625 | else | 634 | } else { |
626 | status.freq = b43_freq_to_channel_2ghz(status.freq); | 635 | status.band = IEEE80211_BAND_2GHZ; |
636 | status.freq = b43_freq_to_channel_2ghz(chanid); | ||
637 | } | ||
627 | break; | 638 | break; |
628 | default: | 639 | default: |
629 | B43_WARN_ON(1); | 640 | B43_WARN_ON(1); |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 93d45b71799a..242b8ad4e33c 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -130,13 +130,19 @@ | |||
130 | #define B43legacy_SHM_SH_HOSTFHI 0x0060 /* Hostflags ucode opts (high) */ | 130 | #define B43legacy_SHM_SH_HOSTFHI 0x0060 /* Hostflags ucode opts (high) */ |
131 | /* SHM_SHARED crypto engine */ | 131 | /* SHM_SHARED crypto engine */ |
132 | #define B43legacy_SHM_SH_KEYIDXBLOCK 0x05D4 /* Key index/algorithm block */ | 132 | #define B43legacy_SHM_SH_KEYIDXBLOCK 0x05D4 /* Key index/algorithm block */ |
133 | /* SHM_SHARED beacon variables */ | 133 | /* SHM_SHARED beacon/AP variables */ |
134 | #define B43legacy_SHM_SH_DTIMP 0x0012 /* DTIM period */ | ||
135 | #define B43legacy_SHM_SH_BTL0 0x0018 /* Beacon template length 0 */ | ||
136 | #define B43legacy_SHM_SH_BTL1 0x001A /* Beacon template length 1 */ | ||
137 | #define B43legacy_SHM_SH_BTSFOFF 0x001C /* Beacon TSF offset */ | ||
138 | #define B43legacy_SHM_SH_TIMPOS 0x001E /* TIM position in beacon */ | ||
134 | #define B43legacy_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word */ | 139 | #define B43legacy_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word */ |
135 | /* SHM_SHARED ACK/CTS control */ | 140 | /* SHM_SHARED ACK/CTS control */ |
136 | #define B43legacy_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word */ | 141 | #define B43legacy_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word */ |
137 | /* SHM_SHARED probe response variables */ | 142 | /* SHM_SHARED probe response variables */ |
138 | #define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ | 143 | #define B43legacy_SHM_SH_PRTLEN 0x004A /* Probe Response template length */ |
139 | #define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ | 144 | #define B43legacy_SHM_SH_PRMAXTIME 0x0074 /* Probe Response max time */ |
145 | #define B43legacy_SHM_SH_PRPHYCTL 0x0188 /* Probe Resp PHY TX control */ | ||
140 | /* SHM_SHARED rate tables */ | 146 | /* SHM_SHARED rate tables */ |
141 | /* SHM_SHARED microcode soft registers */ | 147 | /* SHM_SHARED microcode soft registers */ |
142 | #define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ | 148 | #define B43legacy_SHM_SH_UCODEREV 0x0000 /* Microcode revision */ |
@@ -199,6 +205,13 @@ | |||
199 | #define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */ | 205 | #define B43legacy_MACCTL_TBTTHOLD 0x10000000 /* TBTT Hold */ |
200 | #define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */ | 206 | #define B43legacy_MACCTL_GMODE 0x80000000 /* G Mode */ |
201 | 207 | ||
208 | /* MAC Command bitfield */ | ||
209 | #define B43legacy_MACCMD_BEACON0_VALID 0x00000001 /* Beacon 0 in template RAM is busy/valid */ | ||
210 | #define B43legacy_MACCMD_BEACON1_VALID 0x00000002 /* Beacon 1 in template RAM is busy/valid */ | ||
211 | #define B43legacy_MACCMD_DFQ_VALID 0x00000004 /* Directed frame queue valid (IBSS PS mode, ATIM) */ | ||
212 | #define B43legacy_MACCMD_CCA 0x00000008 /* Clear channel assessment */ | ||
213 | #define B43legacy_MACCMD_BGNOISE 0x00000010 /* Background noise */ | ||
214 | |||
202 | /* 802.11 core specific TM State Low flags */ | 215 | /* 802.11 core specific TM State Low flags */ |
203 | #define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ | 216 | #define B43legacy_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ |
204 | #define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */ | 217 | #define B43legacy_TMSLOW_PLLREFSEL 0x00200000 /* PLL Freq Ref Select */ |
@@ -317,15 +330,7 @@ enum { | |||
317 | # undef assert | 330 | # undef assert |
318 | #endif | 331 | #endif |
319 | #ifdef CONFIG_B43LEGACY_DEBUG | 332 | #ifdef CONFIG_B43LEGACY_DEBUG |
320 | # define B43legacy_WARN_ON(expr) \ | 333 | # define B43legacy_WARN_ON(x) WARN_ON(x) |
321 | do { \ | ||
322 | if (unlikely((expr))) { \ | ||
323 | printk(KERN_INFO PFX "Test (%s) failed at:" \ | ||
324 | " %s:%d:%s()\n", \ | ||
325 | #expr, __FILE__, \ | ||
326 | __LINE__, __FUNCTION__); \ | ||
327 | } \ | ||
328 | } while (0) | ||
329 | # define B43legacy_BUG_ON(expr) \ | 334 | # define B43legacy_BUG_ON(expr) \ |
330 | do { \ | 335 | do { \ |
331 | if (unlikely((expr))) { \ | 336 | if (unlikely((expr))) { \ |
@@ -336,7 +341,9 @@ enum { | |||
336 | } while (0) | 341 | } while (0) |
337 | # define B43legacy_DEBUG 1 | 342 | # define B43legacy_DEBUG 1 |
338 | #else | 343 | #else |
339 | # define B43legacy_WARN_ON(x) do { /* nothing */ } while (0) | 344 | /* This will evaluate the argument even if debugging is disabled. */ |
345 | static inline bool __b43legacy_warn_on_dummy(bool x) { return x; } | ||
346 | # define B43legacy_WARN_ON(x) __b43legacy_warn_on_dummy(unlikely(!!(x))) | ||
340 | # define B43legacy_BUG_ON(x) do { /* nothing */ } while (0) | 347 | # define B43legacy_BUG_ON(x) do { /* nothing */ } while (0) |
341 | # define B43legacy_DEBUG 0 | 348 | # define B43legacy_DEBUG 0 |
342 | #endif | 349 | #endif |
@@ -392,10 +399,6 @@ struct b43legacy_phy { | |||
392 | u8 possible_phymodes; | 399 | u8 possible_phymodes; |
393 | /* GMODE bit enabled in MACCTL? */ | 400 | /* GMODE bit enabled in MACCTL? */ |
394 | bool gmode; | 401 | bool gmode; |
395 | /* Possible ieee80211 subsystem hwmodes for this PHY. | ||
396 | * Which mode is selected, depends on thr GMODE enabled bit */ | ||
397 | #define B43legacy_MAX_PHYHWMODES 2 | ||
398 | struct ieee80211_hw_mode hwmodes[B43legacy_MAX_PHYHWMODES]; | ||
399 | 402 | ||
400 | /* Analog Type */ | 403 | /* Analog Type */ |
401 | u8 analog; | 404 | u8 analog; |
@@ -598,6 +601,12 @@ struct b43legacy_wl { | |||
598 | u8 nr_devs; | 601 | u8 nr_devs; |
599 | 602 | ||
600 | bool radiotap_enabled; | 603 | bool radiotap_enabled; |
604 | |||
605 | /* The beacon we are currently using (AP or IBSS mode). | ||
606 | * This beacon stuff is protected by the irq_lock. */ | ||
607 | struct sk_buff *current_beacon; | ||
608 | bool beacon0_uploaded; | ||
609 | bool beacon1_uploaded; | ||
601 | }; | 610 | }; |
602 | 611 | ||
603 | /* Pointers to the firmware data and meta information about it. */ | 612 | /* Pointers to the firmware data and meta information about it. */ |
@@ -649,7 +658,7 @@ struct b43legacy_wldev { | |||
649 | 658 | ||
650 | bool __using_pio; /* Using pio rather than dma. */ | 659 | bool __using_pio; /* Using pio rather than dma. */ |
651 | bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ | 660 | bool bad_frames_preempt;/* Use "Bad Frames Preemption". */ |
652 | bool reg124_set_0x4; /* Variable to keep track of IRQ. */ | 661 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM). */ |
653 | bool short_preamble; /* TRUE if using short preamble. */ | 662 | bool short_preamble; /* TRUE if using short preamble. */ |
654 | bool short_slot; /* TRUE if using short slot timing. */ | 663 | bool short_slot; /* TRUE if using short slot timing. */ |
655 | bool radio_hw_enable; /* State of radio hardware enable bit. */ | 664 | bool radio_hw_enable; /* State of radio hardware enable bit. */ |
@@ -696,9 +705,6 @@ struct b43legacy_wldev { | |||
696 | u8 max_nr_keys; | 705 | u8 max_nr_keys; |
697 | struct b43legacy_key key[58]; | 706 | struct b43legacy_key key[58]; |
698 | 707 | ||
699 | /* Cached beacon template while uploading the template. */ | ||
700 | struct sk_buff *cached_beacon; | ||
701 | |||
702 | /* Firmware data */ | 708 | /* Firmware data */ |
703 | struct b43legacy_firmware fw; | 709 | struct b43legacy_firmware fw; |
704 | 710 | ||
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index c39de422e220..82953dd0bae0 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -95,28 +95,29 @@ MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl); | |||
95 | * data in there. This data is the same for all devices, so we don't | 95 | * data in there. This data is the same for all devices, so we don't |
96 | * get concurrency issues */ | 96 | * get concurrency issues */ |
97 | #define RATETAB_ENT(_rateid, _flags) \ | 97 | #define RATETAB_ENT(_rateid, _flags) \ |
98 | { \ | 98 | { \ |
99 | .rate = B43legacy_RATE_TO_100KBPS(_rateid), \ | 99 | .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \ |
100 | .val = (_rateid), \ | 100 | .hw_value = (_rateid), \ |
101 | .val2 = (_rateid), \ | 101 | .flags = (_flags), \ |
102 | .flags = (_flags), \ | ||
103 | } | 102 | } |
103 | /* | ||
104 | * NOTE: When changing this, sync with xmit.c's | ||
105 | * b43legacy_plcp_get_bitrate_idx_* functions! | ||
106 | */ | ||
104 | static struct ieee80211_rate __b43legacy_ratetable[] = { | 107 | static struct ieee80211_rate __b43legacy_ratetable[] = { |
105 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, IEEE80211_RATE_CCK), | 108 | RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0), |
106 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_CCK_2), | 109 | RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE), |
107 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_CCK_2), | 110 | RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE), |
108 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_CCK_2), | 111 | RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE), |
109 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, IEEE80211_RATE_OFDM), | 112 | RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0), |
110 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, IEEE80211_RATE_OFDM), | 113 | RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0), |
111 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, IEEE80211_RATE_OFDM), | 114 | RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0), |
112 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, IEEE80211_RATE_OFDM), | 115 | RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0), |
113 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, IEEE80211_RATE_OFDM), | 116 | RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0), |
114 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, IEEE80211_RATE_OFDM), | 117 | RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0), |
115 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, IEEE80211_RATE_OFDM), | 118 | RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0), |
116 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, IEEE80211_RATE_OFDM), | 119 | RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0), |
117 | }; | 120 | }; |
118 | #define b43legacy_a_ratetable (__b43legacy_ratetable + 4) | ||
119 | #define b43legacy_a_ratetable_size 8 | ||
120 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) | 121 | #define b43legacy_b_ratetable (__b43legacy_ratetable + 0) |
121 | #define b43legacy_b_ratetable_size 4 | 122 | #define b43legacy_b_ratetable_size 4 |
122 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) | 123 | #define b43legacy_g_ratetable (__b43legacy_ratetable + 0) |
@@ -124,14 +125,8 @@ static struct ieee80211_rate __b43legacy_ratetable[] = { | |||
124 | 125 | ||
125 | #define CHANTAB_ENT(_chanid, _freq) \ | 126 | #define CHANTAB_ENT(_chanid, _freq) \ |
126 | { \ | 127 | { \ |
127 | .chan = (_chanid), \ | 128 | .center_freq = (_freq), \ |
128 | .freq = (_freq), \ | 129 | .hw_value = (_chanid), \ |
129 | .val = (_chanid), \ | ||
130 | .flag = IEEE80211_CHAN_W_SCAN | \ | ||
131 | IEEE80211_CHAN_W_ACTIVE_SCAN | \ | ||
132 | IEEE80211_CHAN_W_IBSS, \ | ||
133 | .power_level = 0x0A, \ | ||
134 | .antenna_max = 0xFF, \ | ||
135 | } | 130 | } |
136 | static struct ieee80211_channel b43legacy_bg_chantable[] = { | 131 | static struct ieee80211_channel b43legacy_bg_chantable[] = { |
137 | CHANTAB_ENT(1, 2412), | 132 | CHANTAB_ENT(1, 2412), |
@@ -149,7 +144,20 @@ static struct ieee80211_channel b43legacy_bg_chantable[] = { | |||
149 | CHANTAB_ENT(13, 2472), | 144 | CHANTAB_ENT(13, 2472), |
150 | CHANTAB_ENT(14, 2484), | 145 | CHANTAB_ENT(14, 2484), |
151 | }; | 146 | }; |
152 | #define b43legacy_bg_chantable_size ARRAY_SIZE(b43legacy_bg_chantable) | 147 | |
148 | static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = { | ||
149 | .channels = b43legacy_bg_chantable, | ||
150 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
151 | .bitrates = b43legacy_b_ratetable, | ||
152 | .n_bitrates = b43legacy_b_ratetable_size, | ||
153 | }; | ||
154 | |||
155 | static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = { | ||
156 | .channels = b43legacy_bg_chantable, | ||
157 | .n_channels = ARRAY_SIZE(b43legacy_bg_chantable), | ||
158 | .bitrates = b43legacy_g_ratetable, | ||
159 | .n_bitrates = b43legacy_g_ratetable_size, | ||
160 | }; | ||
153 | 161 | ||
154 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); | 162 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev); |
155 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); | 163 | static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev); |
@@ -797,9 +805,8 @@ static void b43legacy_generate_noise_sample(struct b43legacy_wldev *dev) | |||
797 | { | 805 | { |
798 | b43legacy_jssi_write(dev, 0x7F7F7F7F); | 806 | b43legacy_jssi_write(dev, 0x7F7F7F7F); |
799 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 807 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, |
800 | b43legacy_read32(dev, | 808 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) |
801 | B43legacy_MMIO_MACCMD) | 809 | | B43legacy_MACCMD_BGNOISE); |
802 | | (1 << 4)); | ||
803 | B43legacy_WARN_ON(dev->noisecalc.channel_at_start != | 810 | B43legacy_WARN_ON(dev->noisecalc.channel_at_start != |
804 | dev->phy.channel); | 811 | dev->phy.channel); |
805 | } | 812 | } |
@@ -888,18 +895,18 @@ static void handle_irq_tbtt_indication(struct b43legacy_wldev *dev) | |||
888 | if (1/*FIXME: the last PSpoll frame was sent successfully */) | 895 | if (1/*FIXME: the last PSpoll frame was sent successfully */) |
889 | b43legacy_power_saving_ctl_bits(dev, -1, -1); | 896 | b43legacy_power_saving_ctl_bits(dev, -1, -1); |
890 | } | 897 | } |
891 | dev->reg124_set_0x4 = 0; | ||
892 | if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS)) | 898 | if (b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_IBSS)) |
893 | dev->reg124_set_0x4 = 1; | 899 | dev->dfq_valid = 1; |
894 | } | 900 | } |
895 | 901 | ||
896 | static void handle_irq_atim_end(struct b43legacy_wldev *dev) | 902 | static void handle_irq_atim_end(struct b43legacy_wldev *dev) |
897 | { | 903 | { |
898 | if (!dev->reg124_set_0x4) /*FIXME rename this variable*/ | 904 | if (dev->dfq_valid) { |
899 | return; | 905 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, |
900 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 906 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) |
901 | b43legacy_read32(dev, B43legacy_MMIO_MACCMD) | 907 | | B43legacy_MACCMD_DFQ_VALID); |
902 | | 0x4); | 908 | dev->dfq_valid = 0; |
909 | } | ||
903 | } | 910 | } |
904 | 911 | ||
905 | static void handle_irq_pmq(struct b43legacy_wldev *dev) | 912 | static void handle_irq_pmq(struct b43legacy_wldev *dev) |
@@ -955,32 +962,77 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev, | |||
955 | u16 ram_offset, | 962 | u16 ram_offset, |
956 | u16 shm_size_offset, u8 rate) | 963 | u16 shm_size_offset, u8 rate) |
957 | { | 964 | { |
958 | int len; | ||
959 | const u8 *data; | ||
960 | 965 | ||
961 | B43legacy_WARN_ON(!dev->cached_beacon); | 966 | unsigned int i, len, variable_len; |
962 | len = min((size_t)dev->cached_beacon->len, | 967 | const struct ieee80211_mgmt *bcn; |
968 | const u8 *ie; | ||
969 | bool tim_found = 0; | ||
970 | |||
971 | bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); | ||
972 | len = min((size_t)dev->wl->current_beacon->len, | ||
963 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 973 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
964 | data = (const u8 *)(dev->cached_beacon->data); | 974 | |
965 | b43legacy_write_template_common(dev, data, | 975 | b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset, |
966 | len, ram_offset, | ||
967 | shm_size_offset, rate); | 976 | shm_size_offset, rate); |
977 | |||
978 | /* Find the position of the TIM and the DTIM_period value | ||
979 | * and write them to SHM. */ | ||
980 | ie = bcn->u.beacon.variable; | ||
981 | variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable); | ||
982 | for (i = 0; i < variable_len - 2; ) { | ||
983 | uint8_t ie_id, ie_len; | ||
984 | |||
985 | ie_id = ie[i]; | ||
986 | ie_len = ie[i + 1]; | ||
987 | if (ie_id == 5) { | ||
988 | u16 tim_position; | ||
989 | u16 dtim_period; | ||
990 | /* This is the TIM Information Element */ | ||
991 | |||
992 | /* Check whether the ie_len is in the beacon data range. */ | ||
993 | if (variable_len < ie_len + 2 + i) | ||
994 | break; | ||
995 | /* A valid TIM is at least 4 bytes long. */ | ||
996 | if (ie_len < 4) | ||
997 | break; | ||
998 | tim_found = 1; | ||
999 | |||
1000 | tim_position = sizeof(struct b43legacy_plcp_hdr6); | ||
1001 | tim_position += offsetof(struct ieee80211_mgmt, | ||
1002 | u.beacon.variable); | ||
1003 | tim_position += i; | ||
1004 | |||
1005 | dtim_period = ie[i + 3]; | ||
1006 | |||
1007 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, | ||
1008 | B43legacy_SHM_SH_TIMPOS, tim_position); | ||
1009 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, | ||
1010 | B43legacy_SHM_SH_DTIMP, dtim_period); | ||
1011 | break; | ||
1012 | } | ||
1013 | i += ie_len + 2; | ||
1014 | } | ||
1015 | if (!tim_found) { | ||
1016 | b43legacywarn(dev->wl, "Did not find a valid TIM IE in the " | ||
1017 | "beacon template packet. AP or IBSS operation " | ||
1018 | "may be broken.\n"); | ||
1019 | } | ||
968 | } | 1020 | } |
969 | 1021 | ||
970 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | 1022 | static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, |
971 | u16 shm_offset, u16 size, | 1023 | u16 shm_offset, u16 size, |
972 | u8 rate) | 1024 | struct ieee80211_rate *rate) |
973 | { | 1025 | { |
974 | struct b43legacy_plcp_hdr4 plcp; | 1026 | struct b43legacy_plcp_hdr4 plcp; |
975 | u32 tmp; | 1027 | u32 tmp; |
976 | __le16 dur; | 1028 | __le16 dur; |
977 | 1029 | ||
978 | plcp.data = 0; | 1030 | plcp.data = 0; |
979 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); | 1031 | b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate); |
980 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1032 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
981 | dev->wl->vif, | 1033 | dev->wl->vif, |
982 | size, | 1034 | size, |
983 | B43legacy_RATE_TO_100KBPS(rate)); | 1035 | rate); |
984 | /* Write PLCP in two parts and timing for packet transfer */ | 1036 | /* Write PLCP in two parts and timing for packet transfer */ |
985 | tmp = le32_to_cpu(plcp.data); | 1037 | tmp = le32_to_cpu(plcp.data); |
986 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, | 1038 | b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, shm_offset, |
@@ -997,45 +1049,44 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev, | |||
997 | * 2) Patching duration field | 1049 | * 2) Patching duration field |
998 | * 3) Stripping TIM | 1050 | * 3) Stripping TIM |
999 | */ | 1051 | */ |
1000 | static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | 1052 | static const u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, |
1001 | u16 *dest_size, u8 rate) | 1053 | u16 *dest_size, |
1054 | struct ieee80211_rate *rate) | ||
1002 | { | 1055 | { |
1003 | const u8 *src_data; | 1056 | const u8 *src_data; |
1004 | u8 *dest_data; | 1057 | u8 *dest_data; |
1005 | u16 src_size; | 1058 | u16 src_size, elem_size, src_pos, dest_pos; |
1006 | u16 elem_size; | ||
1007 | u16 src_pos; | ||
1008 | u16 dest_pos; | ||
1009 | __le16 dur; | 1059 | __le16 dur; |
1010 | struct ieee80211_hdr *hdr; | 1060 | struct ieee80211_hdr *hdr; |
1061 | size_t ie_start; | ||
1062 | |||
1063 | src_size = dev->wl->current_beacon->len; | ||
1064 | src_data = (const u8 *)dev->wl->current_beacon->data; | ||
1011 | 1065 | ||
1012 | B43legacy_WARN_ON(!dev->cached_beacon); | 1066 | /* Get the start offset of the variable IEs in the packet. */ |
1013 | src_size = dev->cached_beacon->len; | 1067 | ie_start = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); |
1014 | src_data = (const u8 *)dev->cached_beacon->data; | 1068 | B43legacy_WARN_ON(ie_start != offsetof(struct ieee80211_mgmt, |
1069 | u.beacon.variable)); | ||
1015 | 1070 | ||
1016 | if (unlikely(src_size < 0x24)) { | 1071 | if (B43legacy_WARN_ON(src_size < ie_start)) |
1017 | b43legacydbg(dev->wl, "b43legacy_generate_probe_resp: " | ||
1018 | "invalid beacon\n"); | ||
1019 | return NULL; | 1072 | return NULL; |
1020 | } | ||
1021 | 1073 | ||
1022 | dest_data = kmalloc(src_size, GFP_ATOMIC); | 1074 | dest_data = kmalloc(src_size, GFP_ATOMIC); |
1023 | if (unlikely(!dest_data)) | 1075 | if (unlikely(!dest_data)) |
1024 | return NULL; | 1076 | return NULL; |
1025 | 1077 | ||
1026 | /* 0x24 is offset of first variable-len Information-Element | 1078 | /* Copy the static data and all Information Elements, except the TIM. */ |
1027 | * in beacon frame. | 1079 | memcpy(dest_data, src_data, ie_start); |
1028 | */ | 1080 | src_pos = ie_start; |
1029 | memcpy(dest_data, src_data, 0x24); | 1081 | dest_pos = ie_start; |
1030 | src_pos = 0x24; | 1082 | for ( ; src_pos < src_size - 2; src_pos += elem_size) { |
1031 | dest_pos = 0x24; | ||
1032 | for (; src_pos < src_size - 2; src_pos += elem_size) { | ||
1033 | elem_size = src_data[src_pos + 1] + 2; | 1083 | elem_size = src_data[src_pos + 1] + 2; |
1034 | if (src_data[src_pos] != 0x05) { /* TIM */ | 1084 | if (src_data[src_pos] == 5) { |
1035 | memcpy(dest_data + dest_pos, src_data + src_pos, | 1085 | /* This is the TIM. */ |
1036 | elem_size); | 1086 | continue; |
1037 | dest_pos += elem_size; | ||
1038 | } | 1087 | } |
1088 | memcpy(dest_data + dest_pos, src_data + src_pos, elem_size); | ||
1089 | dest_pos += elem_size; | ||
1039 | } | 1090 | } |
1040 | *dest_size = dest_pos; | 1091 | *dest_size = dest_pos; |
1041 | hdr = (struct ieee80211_hdr *)dest_data; | 1092 | hdr = (struct ieee80211_hdr *)dest_data; |
@@ -1046,7 +1097,7 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1046 | dur = ieee80211_generic_frame_duration(dev->wl->hw, | 1097 | dur = ieee80211_generic_frame_duration(dev->wl->hw, |
1047 | dev->wl->vif, | 1098 | dev->wl->vif, |
1048 | *dest_size, | 1099 | *dest_size, |
1049 | B43legacy_RATE_TO_100KBPS(rate)); | 1100 | rate); |
1050 | hdr->duration_id = dur; | 1101 | hdr->duration_id = dur; |
1051 | 1102 | ||
1052 | return dest_data; | 1103 | return dest_data; |
@@ -1054,13 +1105,13 @@ static u8 *b43legacy_generate_probe_resp(struct b43legacy_wldev *dev, | |||
1054 | 1105 | ||
1055 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | 1106 | static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, |
1056 | u16 ram_offset, | 1107 | u16 ram_offset, |
1057 | u16 shm_size_offset, u8 rate) | 1108 | u16 shm_size_offset, |
1109 | struct ieee80211_rate *rate) | ||
1058 | { | 1110 | { |
1059 | u8 *probe_resp_data; | 1111 | const u8 *probe_resp_data; |
1060 | u16 size; | 1112 | u16 size; |
1061 | 1113 | ||
1062 | B43legacy_WARN_ON(!dev->cached_beacon); | 1114 | size = dev->wl->current_beacon->len; |
1063 | size = dev->cached_beacon->len; | ||
1064 | probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate); | 1115 | probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate); |
1065 | if (unlikely(!probe_resp_data)) | 1116 | if (unlikely(!probe_resp_data)) |
1066 | return; | 1117 | return; |
@@ -1069,59 +1120,37 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev, | |||
1069 | * all possible basic rates | 1120 | * all possible basic rates |
1070 | */ | 1121 | */ |
1071 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, | 1122 | b43legacy_write_probe_resp_plcp(dev, 0x31A, size, |
1072 | B43legacy_CCK_RATE_1MB); | 1123 | &b43legacy_b_ratetable[0]); |
1073 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, | 1124 | b43legacy_write_probe_resp_plcp(dev, 0x32C, size, |
1074 | B43legacy_CCK_RATE_2MB); | 1125 | &b43legacy_b_ratetable[1]); |
1075 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, | 1126 | b43legacy_write_probe_resp_plcp(dev, 0x33E, size, |
1076 | B43legacy_CCK_RATE_5MB); | 1127 | &b43legacy_b_ratetable[2]); |
1077 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, | 1128 | b43legacy_write_probe_resp_plcp(dev, 0x350, size, |
1078 | B43legacy_CCK_RATE_11MB); | 1129 | &b43legacy_b_ratetable[3]); |
1079 | 1130 | ||
1080 | size = min((size_t)size, | 1131 | size = min((size_t)size, |
1081 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); | 1132 | 0x200 - sizeof(struct b43legacy_plcp_hdr6)); |
1082 | b43legacy_write_template_common(dev, probe_resp_data, | 1133 | b43legacy_write_template_common(dev, probe_resp_data, |
1083 | size, ram_offset, | 1134 | size, ram_offset, |
1084 | shm_size_offset, rate); | 1135 | shm_size_offset, rate->bitrate); |
1085 | kfree(probe_resp_data); | 1136 | kfree(probe_resp_data); |
1086 | } | 1137 | } |
1087 | 1138 | ||
1088 | static int b43legacy_refresh_cached_beacon(struct b43legacy_wldev *dev, | 1139 | /* Asynchronously update the packet templates in template RAM. |
1089 | struct sk_buff *beacon) | 1140 | * Locking: Requires wl->irq_lock to be locked. */ |
1090 | { | 1141 | static void b43legacy_update_templates(struct b43legacy_wl *wl, |
1091 | if (dev->cached_beacon) | 1142 | struct sk_buff *beacon) |
1092 | kfree_skb(dev->cached_beacon); | ||
1093 | dev->cached_beacon = beacon; | ||
1094 | |||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1098 | static void b43legacy_update_templates(struct b43legacy_wldev *dev) | ||
1099 | { | ||
1100 | u32 status; | ||
1101 | |||
1102 | B43legacy_WARN_ON(!dev->cached_beacon); | ||
1103 | |||
1104 | b43legacy_write_beacon_template(dev, 0x68, 0x18, | ||
1105 | B43legacy_CCK_RATE_1MB); | ||
1106 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | ||
1107 | B43legacy_CCK_RATE_1MB); | ||
1108 | b43legacy_write_probe_resp_template(dev, 0x268, 0x4A, | ||
1109 | B43legacy_CCK_RATE_11MB); | ||
1110 | |||
1111 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | ||
1112 | status |= 0x03; | ||
1113 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, status); | ||
1114 | } | ||
1115 | |||
1116 | static void b43legacy_refresh_templates(struct b43legacy_wldev *dev, | ||
1117 | struct sk_buff *beacon) | ||
1118 | { | 1143 | { |
1119 | int err; | 1144 | /* This is the top half of the ansynchronous beacon update. The bottom |
1145 | * half is the beacon IRQ. Beacon update must be asynchronous to avoid | ||
1146 | * sending an invalid beacon. This can happen for example, if the | ||
1147 | * firmware transmits a beacon while we are updating it. */ | ||
1120 | 1148 | ||
1121 | err = b43legacy_refresh_cached_beacon(dev, beacon); | 1149 | if (wl->current_beacon) |
1122 | if (unlikely(err)) | 1150 | dev_kfree_skb_any(wl->current_beacon); |
1123 | return; | 1151 | wl->current_beacon = beacon; |
1124 | b43legacy_update_templates(dev); | 1152 | wl->beacon0_uploaded = 0; |
1153 | wl->beacon1_uploaded = 0; | ||
1125 | } | 1154 | } |
1126 | 1155 | ||
1127 | static void b43legacy_set_ssid(struct b43legacy_wldev *dev, | 1156 | static void b43legacy_set_ssid(struct b43legacy_wldev *dev, |
@@ -1162,38 +1191,37 @@ static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, | |||
1162 | 1191 | ||
1163 | static void handle_irq_beacon(struct b43legacy_wldev *dev) | 1192 | static void handle_irq_beacon(struct b43legacy_wldev *dev) |
1164 | { | 1193 | { |
1165 | u32 status; | 1194 | struct b43legacy_wl *wl = dev->wl; |
1195 | u32 cmd; | ||
1166 | 1196 | ||
1167 | if (!b43legacy_is_mode(dev->wl, IEEE80211_IF_TYPE_AP)) | 1197 | if (!b43legacy_is_mode(wl, IEEE80211_IF_TYPE_AP)) |
1168 | return; | 1198 | return; |
1169 | 1199 | ||
1170 | dev->irq_savedstate &= ~B43legacy_IRQ_BEACON; | 1200 | /* This is the bottom half of the asynchronous beacon update. */ |
1171 | status = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | 1201 | |
1172 | 1202 | cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD); | |
1173 | if (!dev->cached_beacon || ((status & 0x1) && (status & 0x2))) { | 1203 | if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) { |
1174 | /* ACK beacon IRQ. */ | 1204 | if (!wl->beacon0_uploaded) { |
1175 | b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, | 1205 | b43legacy_write_beacon_template(dev, 0x68, |
1176 | B43legacy_IRQ_BEACON); | 1206 | B43legacy_SHM_SH_BTL0, |
1177 | dev->irq_savedstate |= B43legacy_IRQ_BEACON; | 1207 | B43legacy_CCK_RATE_1MB); |
1178 | if (dev->cached_beacon) | 1208 | b43legacy_write_probe_resp_template(dev, 0x268, |
1179 | kfree_skb(dev->cached_beacon); | 1209 | B43legacy_SHM_SH_PRTLEN, |
1180 | dev->cached_beacon = NULL; | 1210 | &__b43legacy_ratetable[3]); |
1181 | return; | 1211 | wl->beacon0_uploaded = 1; |
1182 | } | 1212 | } |
1183 | if (!(status & 0x1)) { | 1213 | cmd |= B43legacy_MACCMD_BEACON0_VALID; |
1184 | b43legacy_write_beacon_template(dev, 0x68, 0x18, | 1214 | } |
1185 | B43legacy_CCK_RATE_1MB); | 1215 | if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) { |
1186 | status |= 0x1; | 1216 | if (!wl->beacon1_uploaded) { |
1187 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | 1217 | b43legacy_write_beacon_template(dev, 0x468, |
1188 | status); | 1218 | B43legacy_SHM_SH_BTL1, |
1189 | } | 1219 | B43legacy_CCK_RATE_1MB); |
1190 | if (!(status & 0x2)) { | 1220 | wl->beacon1_uploaded = 1; |
1191 | b43legacy_write_beacon_template(dev, 0x468, 0x1A, | 1221 | } |
1192 | B43legacy_CCK_RATE_1MB); | 1222 | cmd |= B43legacy_MACCMD_BEACON1_VALID; |
1193 | status |= 0x2; | ||
1194 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, | ||
1195 | status); | ||
1196 | } | 1223 | } |
1224 | b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd); | ||
1197 | } | 1225 | } |
1198 | 1226 | ||
1199 | static void handle_irq_ucode_debug(struct b43legacy_wldev *dev) | 1227 | static void handle_irq_ucode_debug(struct b43legacy_wldev *dev) |
@@ -2550,14 +2578,16 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2550 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); | 2578 | antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx); |
2551 | 2579 | ||
2552 | mutex_lock(&wl->mutex); | 2580 | mutex_lock(&wl->mutex); |
2581 | dev = wl->current_dev; | ||
2582 | phy = &dev->phy; | ||
2553 | 2583 | ||
2554 | /* Switch the PHY mode (if necessary). */ | 2584 | /* Switch the PHY mode (if necessary). */ |
2555 | switch (conf->phymode) { | 2585 | switch (conf->channel->band) { |
2556 | case MODE_IEEE80211B: | 2586 | case IEEE80211_BAND_2GHZ: |
2557 | new_phymode = B43legacy_PHYMODE_B; | 2587 | if (phy->type == B43legacy_PHYTYPE_B) |
2558 | break; | 2588 | new_phymode = B43legacy_PHYMODE_B; |
2559 | case MODE_IEEE80211G: | 2589 | else |
2560 | new_phymode = B43legacy_PHYMODE_G; | 2590 | new_phymode = B43legacy_PHYMODE_G; |
2561 | break; | 2591 | break; |
2562 | default: | 2592 | default: |
2563 | B43legacy_WARN_ON(1); | 2593 | B43legacy_WARN_ON(1); |
@@ -2565,8 +2595,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2565 | err = b43legacy_switch_phymode(wl, new_phymode); | 2595 | err = b43legacy_switch_phymode(wl, new_phymode); |
2566 | if (err) | 2596 | if (err) |
2567 | goto out_unlock_mutex; | 2597 | goto out_unlock_mutex; |
2568 | dev = wl->current_dev; | ||
2569 | phy = &dev->phy; | ||
2570 | 2598 | ||
2571 | /* Disable IRQs while reconfiguring the device. | 2599 | /* Disable IRQs while reconfiguring the device. |
2572 | * This makes it possible to drop the spinlock throughout | 2600 | * This makes it possible to drop the spinlock throughout |
@@ -2582,8 +2610,8 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
2582 | 2610 | ||
2583 | /* Switch to the requested channel. | 2611 | /* Switch to the requested channel. |
2584 | * The firmware takes care of races with the TX handler. */ | 2612 | * The firmware takes care of races with the TX handler. */ |
2585 | if (conf->channel_val != phy->channel) | 2613 | if (conf->channel->hw_value != phy->channel) |
2586 | b43legacy_radio_selectchannel(dev, conf->channel_val, 0); | 2614 | b43legacy_radio_selectchannel(dev, conf->channel->hw_value, 0); |
2587 | 2615 | ||
2588 | /* Enable/Disable ShortSlot timing. */ | 2616 | /* Enable/Disable ShortSlot timing. */ |
2589 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) | 2617 | if ((!!(conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME)) |
@@ -2700,7 +2728,7 @@ static int b43legacy_op_config_interface(struct ieee80211_hw *hw, | |||
2700 | B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); | 2728 | B43legacy_WARN_ON(conf->type != IEEE80211_IF_TYPE_AP); |
2701 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); | 2729 | b43legacy_set_ssid(dev, conf->ssid, conf->ssid_len); |
2702 | if (conf->beacon) | 2730 | if (conf->beacon) |
2703 | b43legacy_refresh_templates(dev, conf->beacon); | 2731 | b43legacy_update_templates(wl, conf->beacon); |
2704 | } | 2732 | } |
2705 | b43legacy_write_mac_bssid_templates(dev); | 2733 | b43legacy_write_mac_bssid_templates(dev); |
2706 | } | 2734 | } |
@@ -2918,7 +2946,7 @@ static void setup_struct_phy_for_init(struct b43legacy_wldev *dev, | |||
2918 | static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) | 2946 | static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev) |
2919 | { | 2947 | { |
2920 | /* Flags */ | 2948 | /* Flags */ |
2921 | dev->reg124_set_0x4 = 0; | 2949 | dev->dfq_valid = 0; |
2922 | 2950 | ||
2923 | /* Stats */ | 2951 | /* Stats */ |
2924 | memset(&dev->stats, 0, sizeof(dev->stats)); | 2952 | memset(&dev->stats, 0, sizeof(dev->stats)); |
@@ -3013,6 +3041,11 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3013 | kfree(phy->tssi2dbm); | 3041 | kfree(phy->tssi2dbm); |
3014 | kfree(phy->lo_control); | 3042 | kfree(phy->lo_control); |
3015 | phy->lo_control = NULL; | 3043 | phy->lo_control = NULL; |
3044 | if (dev->wl->current_beacon) { | ||
3045 | dev_kfree_skb_any(dev->wl->current_beacon); | ||
3046 | dev->wl->current_beacon = NULL; | ||
3047 | } | ||
3048 | |||
3016 | ssb_device_disable(dev->dev, 0); | 3049 | ssb_device_disable(dev->dev, 0); |
3017 | ssb_bus_may_powerdown(dev->dev->bus); | 3050 | ssb_bus_may_powerdown(dev->dev->bus); |
3018 | } | 3051 | } |
@@ -3337,6 +3370,41 @@ out_unlock: | |||
3337 | return err; | 3370 | return err; |
3338 | } | 3371 | } |
3339 | 3372 | ||
3373 | static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw, | ||
3374 | int aid, int set) | ||
3375 | { | ||
3376 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3377 | struct sk_buff *beacon; | ||
3378 | unsigned long flags; | ||
3379 | |||
3380 | /* We could modify the existing beacon and set the aid bit in the TIM | ||
3381 | * field, but that would probably require resizing and moving of data | ||
3382 | * within the beacon template. Simply request a new beacon and let | ||
3383 | * mac80211 do the hard work. */ | ||
3384 | beacon = ieee80211_beacon_get(hw, wl->vif, NULL); | ||
3385 | if (unlikely(!beacon)) | ||
3386 | return -ENOMEM; | ||
3387 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3388 | b43legacy_update_templates(wl, beacon); | ||
3389 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3390 | |||
3391 | return 0; | ||
3392 | } | ||
3393 | |||
3394 | static int b43legacy_op_ibss_beacon_update(struct ieee80211_hw *hw, | ||
3395 | struct sk_buff *beacon, | ||
3396 | struct ieee80211_tx_control *ctl) | ||
3397 | { | ||
3398 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | ||
3399 | unsigned long flags; | ||
3400 | |||
3401 | spin_lock_irqsave(&wl->irq_lock, flags); | ||
3402 | b43legacy_update_templates(wl, beacon); | ||
3403 | spin_unlock_irqrestore(&wl->irq_lock, flags); | ||
3404 | |||
3405 | return 0; | ||
3406 | } | ||
3407 | |||
3340 | static const struct ieee80211_ops b43legacy_hw_ops = { | 3408 | static const struct ieee80211_ops b43legacy_hw_ops = { |
3341 | .tx = b43legacy_op_tx, | 3409 | .tx = b43legacy_op_tx, |
3342 | .conf_tx = b43legacy_op_conf_tx, | 3410 | .conf_tx = b43legacy_op_conf_tx, |
@@ -3350,6 +3418,8 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3350 | .start = b43legacy_op_start, | 3418 | .start = b43legacy_op_start, |
3351 | .stop = b43legacy_op_stop, | 3419 | .stop = b43legacy_op_stop, |
3352 | .set_retry_limit = b43legacy_op_set_retry_limit, | 3420 | .set_retry_limit = b43legacy_op_set_retry_limit, |
3421 | .set_tim = b43legacy_op_beacon_set_tim, | ||
3422 | .beacon_update = b43legacy_op_ibss_beacon_update, | ||
3353 | }; | 3423 | }; |
3354 | 3424 | ||
3355 | /* Hard-reset the chip. Do not call this directly. | 3425 | /* Hard-reset the chip. Do not call this directly. |
@@ -3398,48 +3468,19 @@ static int b43legacy_setup_modes(struct b43legacy_wldev *dev, | |||
3398 | int have_gphy) | 3468 | int have_gphy) |
3399 | { | 3469 | { |
3400 | struct ieee80211_hw *hw = dev->wl->hw; | 3470 | struct ieee80211_hw *hw = dev->wl->hw; |
3401 | struct ieee80211_hw_mode *mode; | ||
3402 | struct b43legacy_phy *phy = &dev->phy; | 3471 | struct b43legacy_phy *phy = &dev->phy; |
3403 | int cnt = 0; | ||
3404 | int err; | ||
3405 | 3472 | ||
3406 | phy->possible_phymodes = 0; | 3473 | phy->possible_phymodes = 0; |
3407 | for (; 1; cnt++) { | 3474 | if (have_bphy) { |
3408 | if (have_bphy) { | 3475 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3409 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | 3476 | &b43legacy_band_2GHz_BPHY; |
3410 | mode = &phy->hwmodes[cnt]; | 3477 | phy->possible_phymodes |= B43legacy_PHYMODE_B; |
3411 | 3478 | } | |
3412 | mode->mode = MODE_IEEE80211B; | 3479 | |
3413 | mode->num_channels = b43legacy_bg_chantable_size; | 3480 | if (have_gphy) { |
3414 | mode->channels = b43legacy_bg_chantable; | 3481 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
3415 | mode->num_rates = b43legacy_b_ratetable_size; | 3482 | &b43legacy_band_2GHz_GPHY; |
3416 | mode->rates = b43legacy_b_ratetable; | 3483 | phy->possible_phymodes |= B43legacy_PHYMODE_G; |
3417 | err = ieee80211_register_hwmode(hw, mode); | ||
3418 | if (err) | ||
3419 | return err; | ||
3420 | |||
3421 | phy->possible_phymodes |= B43legacy_PHYMODE_B; | ||
3422 | have_bphy = 0; | ||
3423 | continue; | ||
3424 | } | ||
3425 | if (have_gphy) { | ||
3426 | B43legacy_WARN_ON(cnt >= B43legacy_MAX_PHYHWMODES); | ||
3427 | mode = &phy->hwmodes[cnt]; | ||
3428 | |||
3429 | mode->mode = MODE_IEEE80211G; | ||
3430 | mode->num_channels = b43legacy_bg_chantable_size; | ||
3431 | mode->channels = b43legacy_bg_chantable; | ||
3432 | mode->num_rates = b43legacy_g_ratetable_size; | ||
3433 | mode->rates = b43legacy_g_ratetable; | ||
3434 | err = ieee80211_register_hwmode(hw, mode); | ||
3435 | if (err) | ||
3436 | return err; | ||
3437 | |||
3438 | phy->possible_phymodes |= B43legacy_PHYMODE_G; | ||
3439 | have_gphy = 0; | ||
3440 | continue; | ||
3441 | } | ||
3442 | break; | ||
3443 | } | 3484 | } |
3444 | 3485 | ||
3445 | return 0; | 3486 | return 0; |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index d84408a82db9..dcad2491a606 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -37,45 +37,48 @@ | |||
37 | 37 | ||
38 | 38 | ||
39 | /* Extract the bitrate out of a CCK PLCP header. */ | 39 | /* Extract the bitrate out of a CCK PLCP header. */ |
40 | static u8 b43legacy_plcp_get_bitrate_cck(struct b43legacy_plcp_hdr6 *plcp) | 40 | static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp) |
41 | { | 41 | { |
42 | switch (plcp->raw[0]) { | 42 | switch (plcp->raw[0]) { |
43 | case 0x0A: | 43 | case 0x0A: |
44 | return B43legacy_CCK_RATE_1MB; | 44 | return 0; |
45 | case 0x14: | 45 | case 0x14: |
46 | return B43legacy_CCK_RATE_2MB; | 46 | return 1; |
47 | case 0x37: | 47 | case 0x37: |
48 | return B43legacy_CCK_RATE_5MB; | 48 | return 2; |
49 | case 0x6E: | 49 | case 0x6E: |
50 | return B43legacy_CCK_RATE_11MB; | 50 | return 3; |
51 | } | 51 | } |
52 | B43legacy_BUG_ON(1); | 52 | B43legacy_BUG_ON(1); |
53 | return 0; | 53 | return -1; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* Extract the bitrate out of an OFDM PLCP header. */ | 56 | /* Extract the bitrate out of an OFDM PLCP header. */ |
57 | static u8 b43legacy_plcp_get_bitrate_ofdm(struct b43legacy_plcp_hdr6 *plcp) | 57 | static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp, |
58 | bool aphy) | ||
58 | { | 59 | { |
60 | int base = aphy ? 0 : 4; | ||
61 | |||
59 | switch (plcp->raw[0] & 0xF) { | 62 | switch (plcp->raw[0] & 0xF) { |
60 | case 0xB: | 63 | case 0xB: |
61 | return B43legacy_OFDM_RATE_6MB; | 64 | return base + 0; |
62 | case 0xF: | 65 | case 0xF: |
63 | return B43legacy_OFDM_RATE_9MB; | 66 | return base + 1; |
64 | case 0xA: | 67 | case 0xA: |
65 | return B43legacy_OFDM_RATE_12MB; | 68 | return base + 2; |
66 | case 0xE: | 69 | case 0xE: |
67 | return B43legacy_OFDM_RATE_18MB; | 70 | return base + 3; |
68 | case 0x9: | 71 | case 0x9: |
69 | return B43legacy_OFDM_RATE_24MB; | 72 | return base + 4; |
70 | case 0xD: | 73 | case 0xD: |
71 | return B43legacy_OFDM_RATE_36MB; | 74 | return base + 5; |
72 | case 0x8: | 75 | case 0x8: |
73 | return B43legacy_OFDM_RATE_48MB; | 76 | return base + 6; |
74 | case 0xC: | 77 | case 0xC: |
75 | return B43legacy_OFDM_RATE_54MB; | 78 | return base + 7; |
76 | } | 79 | } |
77 | B43legacy_BUG_ON(1); | 80 | B43legacy_BUG_ON(1); |
78 | return 0; | 81 | return -1; |
79 | } | 82 | } |
80 | 83 | ||
81 | u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate) | 84 | u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate) |
@@ -192,7 +195,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
192 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); | 195 | int use_encryption = (!(txctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)); |
193 | u16 fctl; | 196 | u16 fctl; |
194 | u8 rate; | 197 | u8 rate; |
195 | u8 rate_fb; | 198 | struct ieee80211_rate *rate_fb; |
196 | int rate_ofdm; | 199 | int rate_ofdm; |
197 | int rate_fb_ofdm; | 200 | int rate_fb_ofdm; |
198 | unsigned int plcp_fragment_len; | 201 | unsigned int plcp_fragment_len; |
@@ -204,16 +207,16 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
204 | 207 | ||
205 | memset(txhdr, 0, sizeof(*txhdr)); | 208 | memset(txhdr, 0, sizeof(*txhdr)); |
206 | 209 | ||
207 | rate = txctl->tx_rate; | 210 | rate = txctl->tx_rate->hw_value; |
208 | rate_ofdm = b43legacy_is_ofdm_rate(rate); | 211 | rate_ofdm = b43legacy_is_ofdm_rate(rate); |
209 | rate_fb = (txctl->alt_retry_rate == -1) ? rate : txctl->alt_retry_rate; | 212 | rate_fb = txctl->alt_retry_rate ? : txctl->tx_rate; |
210 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb); | 213 | rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); |
211 | 214 | ||
212 | txhdr->mac_frame_ctl = wlhdr->frame_control; | 215 | txhdr->mac_frame_ctl = wlhdr->frame_control; |
213 | memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); | 216 | memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); |
214 | 217 | ||
215 | /* Calculate duration for fallback rate */ | 218 | /* Calculate duration for fallback rate */ |
216 | if ((rate_fb == rate) || | 219 | if ((rate_fb->hw_value == rate) || |
217 | (wlhdr->duration_id & cpu_to_le16(0x8000)) || | 220 | (wlhdr->duration_id & cpu_to_le16(0x8000)) || |
218 | (wlhdr->duration_id == cpu_to_le16(0))) { | 221 | (wlhdr->duration_id == cpu_to_le16(0))) { |
219 | /* If the fallback rate equals the normal rate or the | 222 | /* If the fallback rate equals the normal rate or the |
@@ -221,11 +224,10 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
221 | * use the original dur_id field. */ | 224 | * use the original dur_id field. */ |
222 | txhdr->dur_fb = wlhdr->duration_id; | 225 | txhdr->dur_fb = wlhdr->duration_id; |
223 | } else { | 226 | } else { |
224 | int fbrate_base100kbps = B43legacy_RATE_TO_100KBPS(rate_fb); | ||
225 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, | 227 | txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw, |
226 | txctl->vif, | 228 | txctl->vif, |
227 | fragment_len, | 229 | fragment_len, |
228 | fbrate_base100kbps); | 230 | rate_fb); |
229 | } | 231 | } |
230 | 232 | ||
231 | plcp_fragment_len = fragment_len + FCS_LEN; | 233 | plcp_fragment_len = fragment_len + FCS_LEN; |
@@ -266,7 +268,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
266 | rate); | 268 | rate); |
267 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) | 269 | b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *) |
268 | (&txhdr->plcp_fb), plcp_fragment_len, | 270 | (&txhdr->plcp_fb), plcp_fragment_len, |
269 | rate_fb); | 271 | rate_fb->hw_value); |
270 | 272 | ||
271 | /* PHY TX Control word */ | 273 | /* PHY TX Control word */ |
272 | if (rate_ofdm) | 274 | if (rate_ofdm) |
@@ -310,7 +312,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
310 | int rts_rate_ofdm; | 312 | int rts_rate_ofdm; |
311 | int rts_rate_fb_ofdm; | 313 | int rts_rate_fb_ofdm; |
312 | 314 | ||
313 | rts_rate = txctl->rts_cts_rate; | 315 | rts_rate = txctl->rts_cts_rate->hw_value; |
314 | rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); | 316 | rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); |
315 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); | 317 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); |
316 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); | 318 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); |
@@ -536,19 +538,24 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
536 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); | 538 | (phystat3 & B43legacy_RX_PHYST3_TRSTATE)); |
537 | status.noise = dev->stats.link_noise; | 539 | status.noise = dev->stats.link_noise; |
538 | status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; | 540 | status.signal = (jssi * 100) / B43legacy_RX_MAX_SSI; |
541 | /* change to support A PHY */ | ||
539 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) | 542 | if (phystat0 & B43legacy_RX_PHYST0_OFDM) |
540 | status.rate = b43legacy_plcp_get_bitrate_ofdm(plcp); | 543 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false); |
541 | else | 544 | else |
542 | status.rate = b43legacy_plcp_get_bitrate_cck(plcp); | 545 | status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp); |
543 | status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); | 546 | status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); |
544 | 547 | ||
545 | /* | 548 | /* |
546 | * If monitors are present get full 64-bit timestamp. This | 549 | * All frames on monitor interfaces and beacons always need a full |
547 | * code assumes we get to process the packet within 16 bits | 550 | * 64-bit timestamp. Monitor interfaces need it for diagnostic |
548 | * of timestamp, i.e. about 65 milliseconds after the PHY | 551 | * purposes and beacons for IBSS merging. |
549 | * received the first symbol. | 552 | * This code assumes we get to process the packet within 16 bits |
553 | * of timestamp, i.e. about 65 milliseconds after the PHY received | ||
554 | * the first symbol. | ||
550 | */ | 555 | */ |
551 | if (dev->wl->radiotap_enabled) { | 556 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) |
557 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
558 | dev->wl->radiotap_enabled) { | ||
552 | u16 low_mactime_now; | 559 | u16 low_mactime_now; |
553 | 560 | ||
554 | b43legacy_tsf_read(dev, &status.mactime); | 561 | b43legacy_tsf_read(dev, &status.mactime); |
@@ -564,14 +571,9 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
564 | B43legacy_RX_CHAN_ID_SHIFT; | 571 | B43legacy_RX_CHAN_ID_SHIFT; |
565 | switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) { | 572 | switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) { |
566 | case B43legacy_PHYTYPE_B: | 573 | case B43legacy_PHYTYPE_B: |
567 | status.phymode = MODE_IEEE80211B; | ||
568 | status.freq = chanid + 2400; | ||
569 | status.channel = b43legacy_freq_to_channel_bg(chanid + 2400); | ||
570 | break; | ||
571 | case B43legacy_PHYTYPE_G: | 574 | case B43legacy_PHYTYPE_G: |
572 | status.phymode = MODE_IEEE80211G; | 575 | status.band = IEEE80211_BAND_2GHZ; |
573 | status.freq = chanid + 2400; | 576 | status.freq = chanid + 2400; |
574 | status.channel = b43legacy_freq_to_channel_bg(chanid + 2400); | ||
575 | break; | 577 | break; |
576 | default: | 578 | default: |
577 | b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", | 579 | b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n", |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index a56d9fc6354f..3d4b590046a8 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -10349,9 +10349,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
10349 | remaining_bytes, | 10349 | remaining_bytes, |
10350 | PCI_DMA_TODEVICE)); | 10350 | PCI_DMA_TODEVICE)); |
10351 | 10351 | ||
10352 | tfd->u.data.num_chunks = | 10352 | le32_add_cpu(&tfd->u.data.num_chunks, 1); |
10353 | cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) + | ||
10354 | 1); | ||
10355 | } | 10353 | } |
10356 | } | 10354 | } |
10357 | 10355 | ||
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index d1af938b9aa6..24c3e3ddafc6 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -24,18 +24,10 @@ config IWL4965 | |||
24 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 24 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
25 | module will be called iwl4965.ko. | 25 | module will be called iwl4965.ko. |
26 | 26 | ||
27 | config IWL4965_QOS | ||
28 | bool "Enable Wireless QoS in iwl4965 driver" | ||
29 | depends on IWL4965 | ||
30 | ---help--- | ||
31 | This option will enable wireless quality of service (QoS) for the | ||
32 | iwl4965 driver. | ||
33 | |||
34 | config IWL4965_HT | 27 | config IWL4965_HT |
35 | bool "Enable 802.11n HT features in iwl4965 driver" | 28 | bool "Enable 802.11n HT features in iwl4965 driver" |
36 | depends on EXPERIMENTAL | 29 | depends on EXPERIMENTAL |
37 | depends on IWL4965 && IWL4965_QOS | 30 | depends on IWL4965 |
38 | depends on n | ||
39 | ---help--- | 31 | ---help--- |
40 | This option enables IEEE 802.11n High Throughput features | 32 | This option enables IEEE 802.11n High Throughput features |
41 | for the iwl4965 driver. | 33 | for the iwl4965 driver. |
@@ -105,13 +97,6 @@ config IWL3945 | |||
105 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 97 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
106 | module will be called iwl3945.ko. | 98 | module will be called iwl3945.ko. |
107 | 99 | ||
108 | config IWL3945_QOS | ||
109 | bool "Enable Wireless QoS in iwl3945 driver" | ||
110 | depends on IWL3945 | ||
111 | ---help--- | ||
112 | This option will enable wireless quality of service (QoS) for the | ||
113 | iwl3945 driver. | ||
114 | |||
115 | config IWL3945_SPECTRUM_MEASUREMENT | 100 | config IWL3945_SPECTRUM_MEASUREMENT |
116 | bool "Enable Spectrum Measurement in iwl3945 drivers" | 101 | bool "Enable Spectrum Measurement in iwl3945 drivers" |
117 | depends on IWL3945 | 102 | depends on IWL3945 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h index 46bb2c7d11dd..20fbb32c33bd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h | |||
@@ -515,14 +515,20 @@ struct iwl3945_qosparam_cmd { | |||
515 | #define STA_CONTROL_MODIFY_MSK 0x01 | 515 | #define STA_CONTROL_MODIFY_MSK 0x01 |
516 | 516 | ||
517 | /* key flags __le16*/ | 517 | /* key flags __le16*/ |
518 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) | 518 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) |
519 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) | 519 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) |
520 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) | 520 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) |
521 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) | 521 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) |
522 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) | 522 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) |
523 | 523 | ||
524 | #define STA_KEY_FLG_KEYID_POS 8 | 524 | #define STA_KEY_FLG_KEYID_POS 8 |
525 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 525 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) |
526 | /* wep key is either from global key (0) or from station info array (1) */ | ||
527 | #define STA_KEY_FLG_WEP_KEY_MAP_MSK __constant_cpu_to_le16(0x0008) | ||
528 | |||
529 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | ||
530 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | ||
531 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | ||
526 | 532 | ||
527 | /* Flags indicate whether to modify vs. don't change various station params */ | 533 | /* Flags indicate whether to modify vs. don't change various station params */ |
528 | #define STA_MODIFY_KEY_MASK 0x01 | 534 | #define STA_MODIFY_KEY_MASK 0x01 |
@@ -546,7 +552,8 @@ struct iwl3945_keyinfo { | |||
546 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | 552 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ |
547 | u8 reserved1; | 553 | u8 reserved1; |
548 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | 554 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ |
549 | __le16 reserved2; | 555 | u8 key_offset; |
556 | u8 reserved2; | ||
550 | u8 key[16]; /* 16-byte unicast decryption key */ | 557 | u8 key[16]; /* 16-byte unicast decryption key */ |
551 | } __attribute__ ((packed)); | 558 | } __attribute__ ((packed)); |
552 | 559 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 571815d7e8bf..6693767adc9f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h | |||
@@ -324,7 +324,6 @@ struct iwl3945_eeprom { | |||
324 | /*=== CSR (control and status registers) ===*/ | 324 | /*=== CSR (control and status registers) ===*/ |
325 | #define CSR_BASE (0x000) | 325 | #define CSR_BASE (0x000) |
326 | 326 | ||
327 | #define CSR_SW_VER (CSR_BASE+0x000) | ||
328 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ | 327 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ |
329 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ | 328 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ |
330 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ | 329 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h index 75e20d0a20d1..4a1872982027 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h | |||
@@ -59,28 +59,28 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define _iwl3945_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) | 62 | #define _iwl3945_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) |
63 | #ifdef CONFIG_IWL3945_DEBUG | 63 | #ifdef CONFIG_IWL3945_DEBUG |
64 | static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *iwl, | 64 | static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *priv, |
65 | u32 ofs, u32 val) | 65 | u32 ofs, u32 val) |
66 | { | 66 | { |
67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); | 67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); |
68 | _iwl3945_write32(iwl, ofs, val); | 68 | _iwl3945_write32(priv, ofs, val); |
69 | } | 69 | } |
70 | #define iwl3945_write32(iwl, ofs, val) \ | 70 | #define iwl3945_write32(priv, ofs, val) \ |
71 | __iwl3945_write32(__FILE__, __LINE__, iwl, ofs, val) | 71 | __iwl3945_write32(__FILE__, __LINE__, priv, ofs, val) |
72 | #else | 72 | #else |
73 | #define iwl3945_write32(iwl, ofs, val) _iwl3945_write32(iwl, ofs, val) | 73 | #define iwl3945_write32(priv, ofs, val) _iwl3945_write32(priv, ofs, val) |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #define _iwl3945_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) | 76 | #define _iwl3945_read32(priv, ofs) readl((priv)->hw_base + (ofs)) |
77 | #ifdef CONFIG_IWL3945_DEBUG | 77 | #ifdef CONFIG_IWL3945_DEBUG |
78 | static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *iwl, u32 ofs) | 78 | static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *priv, u32 ofs) |
79 | { | 79 | { |
80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); | 80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); |
81 | return _iwl3945_read32(iwl, ofs); | 81 | return _iwl3945_read32(priv, ofs); |
82 | } | 82 | } |
83 | #define iwl3945_read32(iwl, ofs) __iwl3945_read32(__FILE__, __LINE__, iwl, ofs) | 83 | #define iwl3945_read32(priv, ofs) __iwl3945_read32(__FILE__, __LINE__, priv, ofs) |
84 | #else | 84 | #else |
85 | #define iwl3945_read32(p, o) _iwl3945_read32(p, o) | 85 | #define iwl3945_read32(p, o) _iwl3945_read32(p, o) |
86 | #endif | 86 | #endif |
@@ -105,18 +105,13 @@ static inline int __iwl3945_poll_bit(const char *f, u32 l, | |||
105 | u32 bits, u32 mask, int timeout) | 105 | u32 bits, u32 mask, int timeout) |
106 | { | 106 | { |
107 | int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); | 107 | int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); |
108 | if (unlikely(ret == -ETIMEDOUT)) | 108 | IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", |
109 | IWL_DEBUG_IO | 109 | addr, bits, mask, |
110 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", | 110 | unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l); |
111 | addr, bits, mask, f, l); | ||
112 | else | ||
113 | IWL_DEBUG_IO | ||
114 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", | ||
115 | addr, bits, mask, ret, f, l); | ||
116 | return ret; | 111 | return ret; |
117 | } | 112 | } |
118 | #define iwl3945_poll_bit(iwl, addr, bits, mask, timeout) \ | 113 | #define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \ |
119 | __iwl3945_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) | 114 | __iwl3945_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) |
120 | #else | 115 | #else |
121 | #define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) | 116 | #define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) |
122 | #endif | 117 | #endif |
@@ -321,8 +316,8 @@ static inline int __iwl3945_poll_direct_bit(const char *f, u32 l, | |||
321 | "- %s %d\n", addr, mask, ret, f, l); | 316 | "- %s %d\n", addr, mask, ret, f, l); |
322 | return ret; | 317 | return ret; |
323 | } | 318 | } |
324 | #define iwl3945_poll_direct_bit(iwl, addr, mask, timeout) \ | 319 | #define iwl3945_poll_direct_bit(priv, addr, mask, timeout) \ |
325 | __iwl3945_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) | 320 | __iwl3945_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) |
326 | #else | 321 | #else |
327 | #define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit | 322 | #define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit |
328 | #endif | 323 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 80d31ae51e77..a8223c4cc97c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c | |||
@@ -100,14 +100,6 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { | |||
100 | {-89, IWL_RATE_6M_INDEX} | 100 | {-89, IWL_RATE_6M_INDEX} |
101 | }; | 101 | }; |
102 | 102 | ||
103 | static struct iwl3945_tpt_entry iwl3945_tpt_table_b[] = { | ||
104 | {-86, IWL_RATE_11M_INDEX}, | ||
105 | {-88, IWL_RATE_5M_INDEX}, | ||
106 | {-90, IWL_RATE_2M_INDEX}, | ||
107 | {-92, IWL_RATE_1M_INDEX} | ||
108 | |||
109 | }; | ||
110 | |||
111 | static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | 103 | static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { |
112 | {-60, IWL_RATE_54M_INDEX}, | 104 | {-60, IWL_RATE_54M_INDEX}, |
113 | {-64, IWL_RATE_48M_INDEX}, | 105 | {-64, IWL_RATE_48M_INDEX}, |
@@ -129,7 +121,7 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { | |||
129 | #define IWL_RATE_MIN_SUCCESS_TH 8 | 121 | #define IWL_RATE_MIN_SUCCESS_TH 8 |
130 | #define IWL_RATE_DECREASE_TH 1920 | 122 | #define IWL_RATE_DECREASE_TH 1920 |
131 | 123 | ||
132 | static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) | 124 | static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, enum ieee80211_band band) |
133 | { | 125 | { |
134 | u32 index = 0; | 126 | u32 index = 0; |
135 | u32 table_size = 0; | 127 | u32 table_size = 0; |
@@ -138,21 +130,19 @@ static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) | |||
138 | if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) | 130 | if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) |
139 | rssi = IWL_MIN_RSSI_VAL; | 131 | rssi = IWL_MIN_RSSI_VAL; |
140 | 132 | ||
141 | switch (mode) { | 133 | switch (band) { |
142 | case MODE_IEEE80211G: | 134 | case IEEE80211_BAND_2GHZ: |
143 | tpt_table = iwl3945_tpt_table_g; | 135 | tpt_table = iwl3945_tpt_table_g; |
144 | table_size = ARRAY_SIZE(iwl3945_tpt_table_g); | 136 | table_size = ARRAY_SIZE(iwl3945_tpt_table_g); |
145 | break; | 137 | break; |
146 | 138 | ||
147 | case MODE_IEEE80211A: | 139 | case IEEE80211_BAND_5GHZ: |
148 | tpt_table = iwl3945_tpt_table_a; | 140 | tpt_table = iwl3945_tpt_table_a; |
149 | table_size = ARRAY_SIZE(iwl3945_tpt_table_a); | 141 | table_size = ARRAY_SIZE(iwl3945_tpt_table_a); |
150 | break; | 142 | break; |
151 | 143 | ||
152 | default: | 144 | default: |
153 | case MODE_IEEE80211B: | 145 | BUG(); |
154 | tpt_table = iwl3945_tpt_table_b; | ||
155 | table_size = ARRAY_SIZE(iwl3945_tpt_table_b); | ||
156 | break; | 146 | break; |
157 | } | 147 | } |
158 | 148 | ||
@@ -340,17 +330,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
340 | * after assoc.. */ | 330 | * after assoc.. */ |
341 | 331 | ||
342 | for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { | 332 | for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { |
343 | if (sta->supp_rates & (1 << i)) { | 333 | if (sta->supp_rates[local->hw.conf.channel->band] & (1 << i)) { |
344 | sta->txrate = i; | 334 | sta->txrate_idx = i; |
345 | break; | 335 | break; |
346 | } | 336 | } |
347 | } | 337 | } |
348 | 338 | ||
349 | sta->last_txrate = sta->txrate; | 339 | sta->last_txrate_idx = sta->txrate_idx; |
350 | 340 | ||
351 | /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */ | 341 | /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ |
352 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 342 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
353 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 343 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
354 | 344 | ||
355 | IWL_DEBUG_RATE("leave\n"); | 345 | IWL_DEBUG_RATE("leave\n"); |
356 | } | 346 | } |
@@ -429,17 +419,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) | |||
429 | { | 419 | { |
430 | int next_rate = iwl3945_get_prev_ieee_rate(rate); | 420 | int next_rate = iwl3945_get_prev_ieee_rate(rate); |
431 | 421 | ||
432 | switch (priv->phymode) { | 422 | switch (priv->band) { |
433 | case MODE_IEEE80211A: | 423 | case IEEE80211_BAND_5GHZ: |
434 | if (rate == IWL_RATE_12M_INDEX) | 424 | if (rate == IWL_RATE_12M_INDEX) |
435 | next_rate = IWL_RATE_9M_INDEX; | 425 | next_rate = IWL_RATE_9M_INDEX; |
436 | else if (rate == IWL_RATE_6M_INDEX) | 426 | else if (rate == IWL_RATE_6M_INDEX) |
437 | next_rate = IWL_RATE_6M_INDEX; | 427 | next_rate = IWL_RATE_6M_INDEX; |
438 | break; | 428 | break; |
429 | /* XXX cannot be invoked in current mac80211 so not a regression | ||
439 | case MODE_IEEE80211B: | 430 | case MODE_IEEE80211B: |
440 | if (rate == IWL_RATE_11M_INDEX_TABLE) | 431 | if (rate == IWL_RATE_11M_INDEX_TABLE) |
441 | next_rate = IWL_RATE_5M_INDEX_TABLE; | 432 | next_rate = IWL_RATE_5M_INDEX_TABLE; |
442 | break; | 433 | break; |
434 | */ | ||
443 | default: | 435 | default: |
444 | break; | 436 | break; |
445 | } | 437 | } |
@@ -465,15 +457,17 @@ static void rs_tx_status(void *priv_rate, | |||
465 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; | 457 | struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; |
466 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 458 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
467 | struct iwl3945_rs_sta *rs_sta; | 459 | struct iwl3945_rs_sta *rs_sta; |
460 | struct ieee80211_supported_band *sband; | ||
461 | |||
462 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
468 | 463 | ||
469 | IWL_DEBUG_RATE("enter\n"); | 464 | IWL_DEBUG_RATE("enter\n"); |
470 | 465 | ||
471 | retries = tx_resp->retry_count; | 466 | retries = tx_resp->retry_count; |
472 | 467 | /* FIXME : this is wrong */ | |
473 | first_index = tx_resp->control.tx_rate; | 468 | first_index = &sband->bitrates[0] - tx_resp->control.tx_rate; |
474 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { | 469 | if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { |
475 | IWL_DEBUG_RATE("leave: Rate out of bounds: %0x for %d\n", | 470 | IWL_DEBUG_RATE("leave: Rate out of bounds: %d\n", first_index); |
476 | tx_resp->control.tx_rate, first_index); | ||
477 | return; | 471 | return; |
478 | } | 472 | } |
479 | 473 | ||
@@ -561,14 +555,14 @@ static void rs_tx_status(void *priv_rate, | |||
561 | } | 555 | } |
562 | 556 | ||
563 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | 557 | static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, |
564 | u8 index, u16 rate_mask, int phymode) | 558 | u8 index, u16 rate_mask, enum ieee80211_band band) |
565 | { | 559 | { |
566 | u8 high = IWL_RATE_INVALID; | 560 | u8 high = IWL_RATE_INVALID; |
567 | u8 low = IWL_RATE_INVALID; | 561 | u8 low = IWL_RATE_INVALID; |
568 | 562 | ||
569 | /* 802.11A walks to the next literal adjacent rate in | 563 | /* 802.11A walks to the next literal adjacent rate in |
570 | * the rate table */ | 564 | * the rate table */ |
571 | if (unlikely(phymode == MODE_IEEE80211A)) { | 565 | if (unlikely(band == IEEE80211_BAND_5GHZ)) { |
572 | int i; | 566 | int i; |
573 | u32 mask; | 567 | u32 mask; |
574 | 568 | ||
@@ -639,7 +633,8 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, | |||
639 | * | 633 | * |
640 | */ | 634 | */ |
641 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 635 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
642 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 636 | struct ieee80211_supported_band *band, |
637 | struct sk_buff *skb, | ||
643 | struct rate_selection *sel) | 638 | struct rate_selection *sel) |
644 | { | 639 | { |
645 | u8 low = IWL_RATE_INVALID; | 640 | u8 low = IWL_RATE_INVALID; |
@@ -672,16 +667,16 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
672 | is_multicast_ether_addr(hdr->addr1) || | 667 | is_multicast_ether_addr(hdr->addr1) || |
673 | !sta || !sta->rate_ctrl_priv) { | 668 | !sta || !sta->rate_ctrl_priv) { |
674 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); | 669 | IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); |
675 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 670 | sel->rate = rate_lowest(local, band, sta); |
676 | if (sta) | 671 | if (sta) |
677 | sta_info_put(sta); | 672 | sta_info_put(sta); |
678 | return; | 673 | return; |
679 | } | 674 | } |
680 | 675 | ||
681 | rate_mask = sta->supp_rates; | 676 | rate_mask = sta->supp_rates[band->band]; |
682 | index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1); | 677 | index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); |
683 | 678 | ||
684 | if (priv->phymode == (u8) MODE_IEEE80211A) | 679 | if (priv->band == IEEE80211_BAND_5GHZ) |
685 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; | 680 | rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; |
686 | 681 | ||
687 | rs_sta = (void *)sta->rate_ctrl_priv; | 682 | rs_sta = (void *)sta->rate_ctrl_priv; |
@@ -732,7 +727,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
732 | current_tpt = window->average_tpt; | 727 | current_tpt = window->average_tpt; |
733 | 728 | ||
734 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, | 729 | high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, |
735 | local->hw.conf.phymode); | 730 | band->band); |
736 | low = high_low & 0xff; | 731 | low = high_low & 0xff; |
737 | high = (high_low >> 8) & 0xff; | 732 | high = (high_low >> 8) & 0xff; |
738 | 733 | ||
@@ -810,11 +805,11 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
810 | 805 | ||
811 | out: | 806 | out: |
812 | 807 | ||
813 | sta->last_txrate = index; | 808 | sta->last_txrate_idx = index; |
814 | if (priv->phymode == (u8) MODE_IEEE80211A) | 809 | if (priv->band == IEEE80211_BAND_5GHZ) |
815 | sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE; | 810 | sta->txrate_idx = sta->last_txrate_idx - IWL_FIRST_OFDM_RATE; |
816 | else | 811 | else |
817 | sta->txrate = sta->last_txrate; | 812 | sta->txrate_idx = sta->last_txrate_idx; |
818 | 813 | ||
819 | sta_info_put(sta); | 814 | sta_info_put(sta); |
820 | 815 | ||
@@ -945,8 +940,9 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
945 | spin_lock_irqsave(&rs_sta->lock, flags); | 940 | spin_lock_irqsave(&rs_sta->lock, flags); |
946 | 941 | ||
947 | rs_sta->tgg = 0; | 942 | rs_sta->tgg = 0; |
948 | switch (priv->phymode) { | 943 | switch (priv->band) { |
949 | case MODE_IEEE80211G: | 944 | case IEEE80211_BAND_2GHZ: |
945 | /* TODO: this always does G, not a regression */ | ||
950 | if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { | 946 | if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { |
951 | rs_sta->tgg = 1; | 947 | rs_sta->tgg = 1; |
952 | rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; | 948 | 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 | rs_sta->expected_tpt = iwl3945_expected_tpt_g; | 950 | rs_sta->expected_tpt = iwl3945_expected_tpt_g; |
955 | break; | 951 | break; |
956 | 952 | ||
957 | case MODE_IEEE80211A: | 953 | case IEEE80211_BAND_5GHZ: |
958 | rs_sta->expected_tpt = iwl3945_expected_tpt_a; | 954 | rs_sta->expected_tpt = iwl3945_expected_tpt_a; |
959 | break; | 955 | break; |
960 | 956 | case IEEE80211_NUM_BANDS: | |
961 | default: | 957 | BUG(); |
962 | IWL_WARNING("Invalid phymode. Defaulting to 802.11b\n"); | ||
963 | case MODE_IEEE80211B: | ||
964 | rs_sta->expected_tpt = iwl3945_expected_tpt_b; | ||
965 | break; | 958 | break; |
966 | } | 959 | } |
967 | 960 | ||
@@ -974,8 +967,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) | |||
974 | 967 | ||
975 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); | 968 | IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); |
976 | 969 | ||
977 | rs_sta->start_rate = | 970 | rs_sta->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->band); |
978 | iwl3945_get_rate_index_by_rssi(rssi, priv->phymode); | ||
979 | 971 | ||
980 | IWL_DEBUG_RATE("leave: rssi %d assign rate index: " | 972 | IWL_DEBUG_RATE("leave: rssi %d assign rate index: " |
981 | "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, | 973 | "%d (plcp 0x%x)\n", rssi, rs_sta->start_rate, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8d4d91d35fd2..82d282730b75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -247,7 +247,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
247 | * the information provided in the skb from the hardware */ | 247 | * the information provided in the skb from the hardware */ |
248 | s8 signal = stats->ssi; | 248 | s8 signal = stats->ssi; |
249 | s8 noise = 0; | 249 | s8 noise = 0; |
250 | int rate = stats->rate; | 250 | int rate = stats->rate_idx; |
251 | u64 tsf = stats->mactime; | 251 | u64 tsf = stats->mactime; |
252 | __le16 phy_flags_hw = rx_hdr->phy_flags; | 252 | __le16 phy_flags_hw = rx_hdr->phy_flags; |
253 | 253 | ||
@@ -315,7 +315,6 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | |||
315 | IEEE80211_CHAN_2GHZ), | 315 | IEEE80211_CHAN_2GHZ), |
316 | &iwl3945_rt->rt_chbitmask); | 316 | &iwl3945_rt->rt_chbitmask); |
317 | 317 | ||
318 | rate = iwl3945_rate_index_from_plcp(rate); | ||
319 | if (rate == -1) | 318 | if (rate == -1) |
320 | iwl3945_rt->rt_rate = 0; | 319 | iwl3945_rt->rt_rate = 0; |
321 | else | 320 | else |
@@ -387,11 +386,10 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
387 | struct ieee80211_rx_status stats = { | 386 | struct ieee80211_rx_status stats = { |
388 | .mactime = le64_to_cpu(rx_end->timestamp), | 387 | .mactime = le64_to_cpu(rx_end->timestamp), |
389 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)), | 388 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)), |
390 | .channel = le16_to_cpu(rx_hdr->channel), | 389 | .band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
391 | .phymode = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 390 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ, |
392 | MODE_IEEE80211G : MODE_IEEE80211A, | ||
393 | .antenna = 0, | 391 | .antenna = 0, |
394 | .rate = rx_hdr->rate, | 392 | .rate_idx = iwl3945_rate_index_from_plcp(rx_hdr->rate), |
395 | .flag = 0, | 393 | .flag = 0, |
396 | }; | 394 | }; |
397 | u8 network_packet; | 395 | u8 network_packet; |
@@ -450,8 +448,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
450 | stats.ssi, stats.noise, stats.signal, | 448 | stats.ssi, stats.noise, stats.signal, |
451 | rx_stats_sig_avg, rx_stats_noise_diff); | 449 | rx_stats_sig_avg, rx_stats_noise_diff); |
452 | 450 | ||
453 | stats.freq = ieee80211chan2mhz(stats.channel); | ||
454 | |||
455 | /* can be covered by iwl3945_report_frame() in most cases */ | 451 | /* can be covered by iwl3945_report_frame() in most cases */ |
456 | /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ | 452 | /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ |
457 | 453 | ||
@@ -464,8 +460,9 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
464 | IWL_DEBUG_STATS | 460 | IWL_DEBUG_STATS |
465 | ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", | 461 | ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", |
466 | network_packet ? '*' : ' ', | 462 | network_packet ? '*' : ' ', |
467 | stats.channel, stats.ssi, stats.ssi, | 463 | le16_to_cpu(rx_hdr->channel), |
468 | stats.ssi, stats.rate); | 464 | stats.ssi, stats.ssi, |
465 | stats.ssi, stats.rate_idx); | ||
469 | 466 | ||
470 | if (iwl3945_debug_level & (IWL_DL_RX)) | 467 | if (iwl3945_debug_level & (IWL_DL_RX)) |
471 | /* Set "1" to report good data frames in groups of 100 */ | 468 | /* 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 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) | 686 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) |
690 | { | 687 | { |
691 | unsigned long flags; | 688 | unsigned long flags; |
692 | u16 rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); | 689 | u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); |
693 | u16 rate_mask; | 690 | u16 rate_mask; |
694 | int rate; | 691 | int rate; |
695 | u8 rts_retry_limit; | 692 | u8 rts_retry_limit; |
@@ -1552,14 +1549,14 @@ int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) | |||
1552 | .channel = priv->active_rxon.channel, | 1549 | .channel = priv->active_rxon.channel, |
1553 | }; | 1550 | }; |
1554 | 1551 | ||
1555 | txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1; | 1552 | txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; |
1556 | ch_info = iwl3945_get_channel_info(priv, | 1553 | ch_info = iwl3945_get_channel_info(priv, |
1557 | priv->phymode, | 1554 | priv->band, |
1558 | le16_to_cpu(priv->active_rxon.channel)); | 1555 | le16_to_cpu(priv->active_rxon.channel)); |
1559 | if (!ch_info) { | 1556 | if (!ch_info) { |
1560 | IWL_ERROR | 1557 | IWL_ERROR |
1561 | ("Failed to get channel info for channel %d [%d]\n", | 1558 | ("Failed to get channel info for channel %d [%d]\n", |
1562 | le16_to_cpu(priv->active_rxon.channel), priv->phymode); | 1559 | le16_to_cpu(priv->active_rxon.channel), priv->band); |
1563 | return -EINVAL; | 1560 | return -EINVAL; |
1564 | } | 1561 | } |
1565 | 1562 | ||
@@ -2241,8 +2238,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2241 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; | 2238 | table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; |
2242 | } | 2239 | } |
2243 | 2240 | ||
2244 | switch (priv->phymode) { | 2241 | switch (priv->band) { |
2245 | case MODE_IEEE80211A: | 2242 | case IEEE80211_BAND_5GHZ: |
2246 | IWL_DEBUG_RATE("Select A mode rate scale\n"); | 2243 | IWL_DEBUG_RATE("Select A mode rate scale\n"); |
2247 | /* If one of the following CCK rates is used, | 2244 | /* If one of the following CCK rates is used, |
2248 | * have it fall back to the 6M OFDM rate */ | 2245 | * have it fall back to the 6M OFDM rate */ |
@@ -2257,8 +2254,8 @@ int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) | |||
2257 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; | 2254 | iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; |
2258 | break; | 2255 | break; |
2259 | 2256 | ||
2260 | case MODE_IEEE80211B: | 2257 | case IEEE80211_BAND_2GHZ: |
2261 | IWL_DEBUG_RATE("Select B mode rate scale\n"); | 2258 | IWL_DEBUG_RATE("Select B/G mode rate scale\n"); |
2262 | /* If an OFDM rate is used, have it fall back to the | 2259 | /* If an OFDM rate is used, have it fall back to the |
2263 | * 1M CCK rates */ | 2260 | * 1M CCK rates */ |
2264 | for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) | 2261 | 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 | break; | 2266 | break; |
2270 | 2267 | ||
2271 | default: | 2268 | default: |
2272 | IWL_DEBUG_RATE("Select G mode rate scale\n"); | 2269 | WARN_ON(1); |
2273 | break; | 2270 | break; |
2274 | } | 2271 | } |
2275 | 2272 | ||
@@ -2303,7 +2300,6 @@ int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) | |||
2303 | return -ENOMEM; | 2300 | return -ENOMEM; |
2304 | } | 2301 | } |
2305 | 2302 | ||
2306 | priv->hw_setting.ac_queue_count = AC_NUM; | ||
2307 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; | 2303 | priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; |
2308 | priv->hw_setting.max_pkt_size = 2342; | 2304 | priv->hw_setting.max_pkt_size = 2342; |
2309 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); | 2305 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); |
@@ -2311,6 +2307,8 @@ int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) | |||
2311 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | 2307 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; |
2312 | priv->hw_setting.max_stations = IWL3945_STATION_COUNT; | 2308 | priv->hw_setting.max_stations = IWL3945_STATION_COUNT; |
2313 | priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; | 2309 | priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; |
2310 | |||
2311 | priv->hw_setting.tx_ant_num = 2; | ||
2314 | return 0; | 2312 | return 0; |
2315 | } | 2313 | } |
2316 | 2314 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 1da14f9bbe0f..dde389d31637 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -195,7 +195,7 @@ struct iwl3945_channel_info { | |||
195 | 195 | ||
196 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | 196 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ |
197 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | 197 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ |
198 | u8 phymode; /* MODE_IEEE80211{A,B,G} */ | 198 | enum ieee80211_band band; |
199 | 199 | ||
200 | /* Radio/DSP gain settings for each "normal" data Tx rate. | 200 | /* Radio/DSP gain settings for each "normal" data Tx rate. |
201 | * These include, in addition to RF and DSP gain, a few fields for | 201 | * These include, in addition to RF and DSP gain, a few fields for |
@@ -431,8 +431,6 @@ union iwl3945_ht_rate_supp { | |||
431 | }; | 431 | }; |
432 | }; | 432 | }; |
433 | 433 | ||
434 | #ifdef CONFIG_IWL3945_QOS | ||
435 | |||
436 | union iwl3945_qos_capabity { | 434 | union iwl3945_qos_capabity { |
437 | struct { | 435 | struct { |
438 | u8 edca_count:4; /* bit 0-3 */ | 436 | u8 edca_count:4; /* bit 0-3 */ |
@@ -460,7 +458,6 @@ struct iwl3945_qos_info { | |||
460 | union iwl3945_qos_capabity qos_cap; | 458 | union iwl3945_qos_capabity qos_cap; |
461 | struct iwl3945_qosparam_cmd def_qos_parm; | 459 | struct iwl3945_qosparam_cmd def_qos_parm; |
462 | }; | 460 | }; |
463 | #endif /*CONFIG_IWL3945_QOS */ | ||
464 | 461 | ||
465 | #define STA_PS_STATUS_WAKE 0 | 462 | #define STA_PS_STATUS_WAKE 0 |
466 | #define STA_PS_STATUS_SLEEP 1 | 463 | #define STA_PS_STATUS_SLEEP 1 |
@@ -511,8 +508,8 @@ struct iwl3945_ibss_seq { | |||
511 | /** | 508 | /** |
512 | * struct iwl3945_driver_hw_info | 509 | * struct iwl3945_driver_hw_info |
513 | * @max_txq_num: Max # Tx queues supported | 510 | * @max_txq_num: Max # Tx queues supported |
514 | * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) | ||
515 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | 511 | * @tx_cmd_len: Size of Tx command (but not including frame itself) |
512 | * @tx_ant_num: Number of TX antennas | ||
516 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 513 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
517 | * @rx_buf_size: | 514 | * @rx_buf_size: |
518 | * @max_pkt_size: | 515 | * @max_pkt_size: |
@@ -524,8 +521,8 @@ struct iwl3945_ibss_seq { | |||
524 | */ | 521 | */ |
525 | struct iwl3945_driver_hw_info { | 522 | struct iwl3945_driver_hw_info { |
526 | u16 max_txq_num; | 523 | u16 max_txq_num; |
527 | u16 ac_queue_count; | ||
528 | u16 tx_cmd_len; | 524 | u16 tx_cmd_len; |
525 | u16 tx_ant_num; | ||
529 | u16 max_rxq_size; | 526 | u16 max_rxq_size; |
530 | u32 rx_buf_size; | 527 | u32 rx_buf_size; |
531 | u32 max_pkt_size; | 528 | u32 max_pkt_size; |
@@ -699,14 +696,14 @@ struct iwl3945_priv { | |||
699 | struct list_head free_frames; | 696 | struct list_head free_frames; |
700 | int frames_count; | 697 | int frames_count; |
701 | 698 | ||
702 | u8 phymode; | 699 | enum ieee80211_band band; |
703 | int alloc_rxb_skb; | 700 | int alloc_rxb_skb; |
704 | bool add_radiotap; | 701 | bool add_radiotap; |
705 | 702 | ||
706 | void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, | 703 | void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, |
707 | struct iwl3945_rx_mem_buffer *rxb); | 704 | struct iwl3945_rx_mem_buffer *rxb); |
708 | 705 | ||
709 | const struct ieee80211_hw_mode *modes; | 706 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
710 | 707 | ||
711 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 708 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
712 | /* spectrum measurement report caching */ | 709 | /* spectrum measurement report caching */ |
@@ -869,9 +866,7 @@ struct iwl3945_priv { | |||
869 | u16 assoc_capability; | 866 | u16 assoc_capability; |
870 | u8 ps_mode; | 867 | u8 ps_mode; |
871 | 868 | ||
872 | #ifdef CONFIG_IWL3945_QOS | ||
873 | struct iwl3945_qos_info qos_data; | 869 | struct iwl3945_qos_info qos_data; |
874 | #endif /*CONFIG_IWL3945_QOS */ | ||
875 | 870 | ||
876 | struct workqueue_struct *workqueue; | 871 | struct workqueue_struct *workqueue; |
877 | 872 | ||
@@ -937,13 +932,12 @@ static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info) | |||
937 | 932 | ||
938 | static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) | 933 | static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) |
939 | { | 934 | { |
940 | return ch_info->phymode == MODE_IEEE80211A; | 935 | return ch_info->band == IEEE80211_BAND_5GHZ; |
941 | } | 936 | } |
942 | 937 | ||
943 | static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) | 938 | static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) |
944 | { | 939 | { |
945 | return ((ch_info->phymode == MODE_IEEE80211B) || | 940 | return ch_info->band == IEEE80211_BAND_2GHZ; |
946 | (ch_info->phymode == MODE_IEEE80211G)); | ||
947 | } | 941 | } |
948 | 942 | ||
949 | static inline int is_channel_passive(const struct iwl3945_channel_info *ch) | 943 | static inline int is_channel_passive(const struct iwl3945_channel_info *ch) |
@@ -967,7 +961,7 @@ static inline int iwl3945_rate_index_from_plcp(int plcp) | |||
967 | } | 961 | } |
968 | 962 | ||
969 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( | 963 | extern const struct iwl3945_channel_info *iwl3945_get_channel_info( |
970 | const struct iwl3945_priv *priv, int phymode, u16 channel); | 964 | const struct iwl3945_priv *priv, enum ieee80211_band band, u16 channel); |
971 | 965 | ||
972 | /* Requires full declaration of iwl3945_priv before including */ | 966 | /* Requires full declaration of iwl3945_priv before including */ |
973 | #include "iwl-3945-io.h" | 967 | #include "iwl-3945-io.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h index f3470c896d9a..b21ffea325cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h | |||
@@ -727,14 +727,20 @@ struct iwl4965_qosparam_cmd { | |||
727 | #define STA_CONTROL_MODIFY_MSK 0x01 | 727 | #define STA_CONTROL_MODIFY_MSK 0x01 |
728 | 728 | ||
729 | /* key flags __le16*/ | 729 | /* key flags __le16*/ |
730 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) | 730 | #define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) |
731 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) | 731 | #define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) |
732 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) | 732 | #define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) |
733 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) | 733 | #define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) |
734 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) | 734 | #define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) |
735 | 735 | ||
736 | #define STA_KEY_FLG_KEYID_POS 8 | 736 | #define STA_KEY_FLG_KEYID_POS 8 |
737 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) | 737 | #define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) |
738 | /* wep key is either from global key (0) or from station info array (1) */ | ||
739 | #define STA_KEY_FLG_MAP_KEY_MSK __constant_cpu_to_le16(0x0008) | ||
740 | |||
741 | /* wep key in STA: 5-bytes (0) or 13-bytes (1) */ | ||
742 | #define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) | ||
743 | #define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) | ||
738 | 744 | ||
739 | /* Flags indicate whether to modify vs. don't change various station params */ | 745 | /* Flags indicate whether to modify vs. don't change various station params */ |
740 | #define STA_MODIFY_KEY_MASK 0x01 | 746 | #define STA_MODIFY_KEY_MASK 0x01 |
@@ -752,7 +758,8 @@ struct iwl4965_keyinfo { | |||
752 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ | 758 | u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ |
753 | u8 reserved1; | 759 | u8 reserved1; |
754 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ | 760 | __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ |
755 | __le16 reserved2; | 761 | u8 key_offset; |
762 | u8 reserved2; | ||
756 | u8 key[16]; /* 16-byte unicast decryption key */ | 763 | u8 key[16]; /* 16-byte unicast decryption key */ |
757 | } __attribute__ ((packed)); | 764 | } __attribute__ ((packed)); |
758 | 765 | ||
@@ -1300,6 +1307,25 @@ struct iwl4965_tx_resp { | |||
1300 | __le32 status; /* TX status (for aggregation status of 1st frame) */ | 1307 | __le32 status; /* TX status (for aggregation status of 1st frame) */ |
1301 | } __attribute__ ((packed)); | 1308 | } __attribute__ ((packed)); |
1302 | 1309 | ||
1310 | struct agg_tx_status { | ||
1311 | __le16 status; | ||
1312 | __le16 sequence; | ||
1313 | } __attribute__ ((packed)); | ||
1314 | |||
1315 | struct iwl4965_tx_resp_agg { | ||
1316 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ | ||
1317 | u8 reserved1; | ||
1318 | u8 failure_rts; | ||
1319 | u8 failure_frame; | ||
1320 | __le32 rate_n_flags; | ||
1321 | __le16 wireless_media_time; | ||
1322 | __le16 reserved3; | ||
1323 | __le32 pa_power1; | ||
1324 | __le32 pa_power2; | ||
1325 | struct agg_tx_status status; /* TX status (for aggregation status */ | ||
1326 | /* of 1st frame) */ | ||
1327 | } __attribute__ ((packed)); | ||
1328 | |||
1303 | /* | 1329 | /* |
1304 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) | 1330 | * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) |
1305 | * | 1331 | * |
@@ -1313,9 +1339,8 @@ struct iwl4965_compressed_ba_resp { | |||
1313 | /* Index of recipient (BA-sending) station in uCode's station table */ | 1339 | /* Index of recipient (BA-sending) station in uCode's station table */ |
1314 | u8 sta_id; | 1340 | u8 sta_id; |
1315 | u8 tid; | 1341 | u8 tid; |
1316 | __le16 ba_seq_ctl; | 1342 | __le16 seq_ctl; |
1317 | __le32 ba_bitmap0; | 1343 | __le64 bitmap; |
1318 | __le32 ba_bitmap1; | ||
1319 | __le16 scd_flow; | 1344 | __le16 scd_flow; |
1320 | __le16 scd_ssn; | 1345 | __le16 scd_ssn; |
1321 | } __attribute__ ((packed)); | 1346 | } __attribute__ ((packed)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index ffe1e9dfdec7..cc726215ab93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -413,7 +413,6 @@ struct iwl4965_eeprom { | |||
413 | /*=== CSR (control and status registers) ===*/ | 413 | /*=== CSR (control and status registers) ===*/ |
414 | #define CSR_BASE (0x000) | 414 | #define CSR_BASE (0x000) |
415 | 415 | ||
416 | #define CSR_SW_VER (CSR_BASE+0x000) | ||
417 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ | 416 | #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ |
418 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ | 417 | #define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ |
419 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ | 418 | #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-io.h b/drivers/net/wireless/iwlwifi/iwl-4965-io.h index 34a0b57eea0c..4af0c0175da2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-io.h | |||
@@ -59,28 +59,28 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #define _iwl4965_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) | 62 | #define _iwl4965_write32(priv, ofs, val) writel((val), (priv)->hw_base + (ofs)) |
63 | #ifdef CONFIG_IWL4965_DEBUG | 63 | #ifdef CONFIG_IWL4965_DEBUG |
64 | static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *iwl, | 64 | static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *priv, |
65 | u32 ofs, u32 val) | 65 | u32 ofs, u32 val) |
66 | { | 66 | { |
67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); | 67 | IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); |
68 | _iwl4965_write32(iwl, ofs, val); | 68 | _iwl4965_write32(priv, ofs, val); |
69 | } | 69 | } |
70 | #define iwl4965_write32(iwl, ofs, val) \ | 70 | #define iwl4965_write32(priv, ofs, val) \ |
71 | __iwl4965_write32(__FILE__, __LINE__, iwl, ofs, val) | 71 | __iwl4965_write32(__FILE__, __LINE__, priv, ofs, val) |
72 | #else | 72 | #else |
73 | #define iwl4965_write32(iwl, ofs, val) _iwl4965_write32(iwl, ofs, val) | 73 | #define iwl4965_write32(priv, ofs, val) _iwl4965_write32(priv, ofs, val) |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #define _iwl4965_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) | 76 | #define _iwl4965_read32(priv, ofs) readl((priv)->hw_base + (ofs)) |
77 | #ifdef CONFIG_IWL4965_DEBUG | 77 | #ifdef CONFIG_IWL4965_DEBUG |
78 | static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *iwl, u32 ofs) | 78 | static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *priv, u32 ofs) |
79 | { | 79 | { |
80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); | 80 | IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); |
81 | return _iwl4965_read32(iwl, ofs); | 81 | return _iwl4965_read32(priv, ofs); |
82 | } | 82 | } |
83 | #define iwl4965_read32(iwl, ofs) __iwl4965_read32(__FILE__, __LINE__, iwl, ofs) | 83 | #define iwl4965_read32(priv, ofs) __iwl4965_read32(__FILE__, __LINE__, priv, ofs) |
84 | #else | 84 | #else |
85 | #define iwl4965_read32(p, o) _iwl4965_read32(p, o) | 85 | #define iwl4965_read32(p, o) _iwl4965_read32(p, o) |
86 | #endif | 86 | #endif |
@@ -105,18 +105,13 @@ static inline int __iwl4965_poll_bit(const char *f, u32 l, | |||
105 | u32 bits, u32 mask, int timeout) | 105 | u32 bits, u32 mask, int timeout) |
106 | { | 106 | { |
107 | int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout); | 107 | int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout); |
108 | if (unlikely(ret == -ETIMEDOUT)) | 108 | IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n", |
109 | IWL_DEBUG_IO | 109 | addr, bits, mask, |
110 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", | 110 | unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l); |
111 | addr, bits, mask, f, l); | ||
112 | else | ||
113 | IWL_DEBUG_IO | ||
114 | ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", | ||
115 | addr, bits, mask, ret, f, l); | ||
116 | return ret; | 111 | return ret; |
117 | } | 112 | } |
118 | #define iwl4965_poll_bit(iwl, addr, bits, mask, timeout) \ | 113 | #define iwl4965_poll_bit(priv, addr, bits, mask, timeout) \ |
119 | __iwl4965_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) | 114 | __iwl4965_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout) |
120 | #else | 115 | #else |
121 | #define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t) | 116 | #define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t) |
122 | #endif | 117 | #endif |
@@ -321,8 +316,8 @@ static inline int __iwl4965_poll_direct_bit(const char *f, u32 l, | |||
321 | "- %s %d\n", addr, mask, ret, f, l); | 316 | "- %s %d\n", addr, mask, ret, f, l); |
322 | return ret; | 317 | return ret; |
323 | } | 318 | } |
324 | #define iwl4965_poll_direct_bit(iwl, addr, mask, timeout) \ | 319 | #define iwl4965_poll_direct_bit(priv, addr, mask, timeout) \ |
325 | __iwl4965_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) | 320 | __iwl4965_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout) |
326 | #else | 321 | #else |
327 | #define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit | 322 | #define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit |
328 | #endif | 323 | #endif |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d06462264147..48a6a85355ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -83,7 +83,7 @@ struct iwl4965_rate_scale_data { | |||
83 | /** | 83 | /** |
84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates | 84 | * struct iwl4965_scale_tbl_info -- tx params and success history for all rates |
85 | * | 85 | * |
86 | * There are two of these in struct iwl_rate_scale_priv, | 86 | * There are two of these in struct iwl4965_lq_sta, |
87 | * one for "active", and one for "search". | 87 | * one for "active", and one for "search". |
88 | */ | 88 | */ |
89 | struct iwl4965_scale_tbl_info { | 89 | struct iwl4965_scale_tbl_info { |
@@ -98,8 +98,23 @@ struct iwl4965_scale_tbl_info { | |||
98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 98 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
99 | }; | 99 | }; |
100 | 100 | ||
101 | #ifdef CONFIG_IWL4965_HT | ||
102 | |||
103 | struct iwl4965_traffic_load { | ||
104 | unsigned long time_stamp; /* age of the oldest statistics */ | ||
105 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | ||
106 | * slice */ | ||
107 | u32 total; /* total num of packets during the | ||
108 | * last TID_MAX_TIME_DIFF */ | ||
109 | u8 queue_count; /* number of queues that has | ||
110 | * been used since the last cleanup */ | ||
111 | u8 head; /* start of the circular buffer */ | ||
112 | }; | ||
113 | |||
114 | #endif /* CONFIG_IWL4965_HT */ | ||
115 | |||
101 | /** | 116 | /** |
102 | * struct iwl_rate_scale_priv -- driver's rate scaling private structure | 117 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
103 | * | 118 | * |
104 | * Pointer to this gets passed back and forth between driver and mac80211. | 119 | * Pointer to this gets passed back and forth between driver and mac80211. |
105 | */ | 120 | */ |
@@ -124,7 +139,7 @@ struct iwl4965_lq_sta { | |||
124 | u8 valid_antenna; | 139 | u8 valid_antenna; |
125 | u8 is_green; | 140 | u8 is_green; |
126 | u8 is_dup; | 141 | u8 is_dup; |
127 | u8 phymode; | 142 | enum ieee80211_band band; |
128 | u8 ibss_sta_added; | 143 | u8 ibss_sta_added; |
129 | 144 | ||
130 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 145 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
@@ -136,9 +151,16 @@ struct iwl4965_lq_sta { | |||
136 | 151 | ||
137 | struct iwl4965_link_quality_cmd lq; | 152 | struct iwl4965_link_quality_cmd lq; |
138 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 153 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
154 | #ifdef CONFIG_IWL4965_HT | ||
155 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | ||
156 | u8 tx_agg_tid_en; | ||
157 | #endif | ||
139 | #ifdef CONFIG_MAC80211_DEBUGFS | 158 | #ifdef CONFIG_MAC80211_DEBUGFS |
140 | struct dentry *rs_sta_dbgfs_scale_table_file; | 159 | struct dentry *rs_sta_dbgfs_scale_table_file; |
141 | struct dentry *rs_sta_dbgfs_stats_table_file; | 160 | struct dentry *rs_sta_dbgfs_stats_table_file; |
161 | #ifdef CONFIG_IWL4965_HT | ||
162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | ||
163 | #endif | ||
142 | struct iwl4965_rate dbg_fixed; | 164 | struct iwl4965_rate dbg_fixed; |
143 | struct iwl4965_priv *drv; | 165 | struct iwl4965_priv *drv; |
144 | #endif | 166 | #endif |
@@ -269,6 +291,135 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
269 | window->stamp = 0; | 291 | window->stamp = 0; |
270 | } | 292 | } |
271 | 293 | ||
294 | #ifdef CONFIG_IWL4965_HT | ||
295 | /* | ||
296 | * removes the old data from the statistics. All data that is older than | ||
297 | * TID_MAX_TIME_DIFF, will be deleted. | ||
298 | */ | ||
299 | static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | ||
300 | { | ||
301 | /* The oldest age we want to keep */ | ||
302 | u32 oldest_time = curr_time - TID_MAX_TIME_DIFF; | ||
303 | |||
304 | while (tl->queue_count && | ||
305 | (tl->time_stamp < oldest_time)) { | ||
306 | tl->total -= tl->packet_count[tl->head]; | ||
307 | tl->packet_count[tl->head] = 0; | ||
308 | tl->time_stamp += TID_QUEUE_CELL_SPACING; | ||
309 | tl->queue_count--; | ||
310 | tl->head++; | ||
311 | if (tl->head >= TID_QUEUE_MAX_SIZE) | ||
312 | tl->head = 0; | ||
313 | } | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * increment traffic load value for tid and also remove | ||
318 | * any old values if passed the certain time period | ||
319 | */ | ||
320 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
321 | { | ||
322 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
323 | u32 time_diff; | ||
324 | s32 index; | ||
325 | struct iwl4965_traffic_load *tl = NULL; | ||
326 | |||
327 | if (tid >= TID_MAX_LOAD_COUNT) | ||
328 | return; | ||
329 | |||
330 | tl = &lq_data->load[tid]; | ||
331 | |||
332 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
333 | |||
334 | /* Happens only for the first packet. Initialize the data */ | ||
335 | if (!(tl->queue_count)) { | ||
336 | tl->total = 1; | ||
337 | tl->time_stamp = curr_time; | ||
338 | tl->queue_count = 1; | ||
339 | tl->head = 0; | ||
340 | tl->packet_count[0] = 1; | ||
341 | return; | ||
342 | } | ||
343 | |||
344 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
345 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
346 | |||
347 | /* The history is too long: remove data that is older than */ | ||
348 | /* TID_MAX_TIME_DIFF */ | ||
349 | if (index >= TID_QUEUE_MAX_SIZE) | ||
350 | rs_tl_rm_old_stats(tl, curr_time); | ||
351 | |||
352 | index = (tl->head + index) % TID_QUEUE_MAX_SIZE; | ||
353 | tl->packet_count[index] = tl->packet_count[index] + 1; | ||
354 | tl->total = tl->total + 1; | ||
355 | |||
356 | if ((index + 1) > tl->queue_count) | ||
357 | tl->queue_count = index + 1; | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | get the traffic load value for tid | ||
362 | */ | ||
363 | static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid) | ||
364 | { | ||
365 | u32 curr_time = jiffies_to_msecs(jiffies); | ||
366 | u32 time_diff; | ||
367 | s32 index; | ||
368 | struct iwl4965_traffic_load *tl = NULL; | ||
369 | |||
370 | if (tid >= TID_MAX_LOAD_COUNT) | ||
371 | return 0; | ||
372 | |||
373 | tl = &(lq_data->load[tid]); | ||
374 | |||
375 | curr_time -= curr_time % TID_ROUND_VALUE; | ||
376 | |||
377 | if (!(tl->queue_count)) | ||
378 | return 0; | ||
379 | |||
380 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | ||
381 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
382 | |||
383 | /* The history is too long: remove data that is older than */ | ||
384 | /* TID_MAX_TIME_DIFF */ | ||
385 | if (index >= TID_QUEUE_MAX_SIZE) | ||
386 | rs_tl_rm_old_stats(tl, curr_time); | ||
387 | |||
388 | return tl->total; | ||
389 | } | ||
390 | |||
391 | static void rs_tl_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
392 | struct iwl4965_lq_sta *lq_data, u8 tid, | ||
393 | struct sta_info *sta) | ||
394 | { | ||
395 | unsigned long state; | ||
396 | DECLARE_MAC_BUF(mac); | ||
397 | |||
398 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
399 | state = sta->ampdu_mlme.tid_tx[tid].state; | ||
400 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
401 | |||
402 | if (state == HT_AGG_STATE_IDLE && | ||
403 | rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | ||
404 | IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", | ||
405 | print_mac(mac, sta->addr), tid); | ||
406 | ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void rs_tl_turn_on_agg(struct iwl4965_priv *priv, u8 tid, | ||
411 | struct iwl4965_lq_sta *lq_data, | ||
412 | struct sta_info *sta) | ||
413 | { | ||
414 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
415 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
416 | else if (tid == IWL_AGG_ALL_TID) | ||
417 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
418 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | ||
419 | } | ||
420 | |||
421 | #endif /* CONFIG_IWLWIFI_HT */ | ||
422 | |||
272 | /** | 423 | /** |
273 | * rs_collect_tx_data - Update the success/failure sliding window | 424 | * rs_collect_tx_data - Update the success/failure sliding window |
274 | * | 425 | * |
@@ -277,7 +428,8 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) | |||
277 | * packets. | 428 | * packets. |
278 | */ | 429 | */ |
279 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | 430 | static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, |
280 | int scale_index, s32 tpt, u32 status) | 431 | int scale_index, s32 tpt, int retries, |
432 | int successes) | ||
281 | { | 433 | { |
282 | struct iwl4965_rate_scale_data *window = NULL; | 434 | struct iwl4965_rate_scale_data *window = NULL; |
283 | u64 mask; | 435 | u64 mask; |
@@ -298,26 +450,33 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, | |||
298 | * subtract "1" from the success counter (this is the main reason | 450 | * subtract "1" from the success counter (this is the main reason |
299 | * we keep these bitmaps!). | 451 | * we keep these bitmaps!). |
300 | */ | 452 | */ |
301 | if (window->counter >= win_size) { | 453 | while (retries > 0) { |
302 | window->counter = win_size - 1; | 454 | if (window->counter >= win_size) { |
303 | mask = 1; | 455 | window->counter = win_size - 1; |
304 | mask = (mask << (win_size - 1)); | 456 | mask = 1; |
305 | if ((window->data & mask)) { | 457 | mask = (mask << (win_size - 1)); |
306 | window->data &= ~mask; | 458 | if (window->data & mask) { |
307 | window->success_counter = window->success_counter - 1; | 459 | window->data &= ~mask; |
460 | window->success_counter = | ||
461 | window->success_counter - 1; | ||
462 | } | ||
308 | } | 463 | } |
309 | } | ||
310 | 464 | ||
311 | /* Increment frames-attempted counter */ | 465 | /* Increment frames-attempted counter */ |
312 | window->counter = window->counter + 1; | 466 | window->counter++; |
467 | |||
468 | /* Shift bitmap by one frame (throw away oldest history), | ||
469 | * OR in "1", and increment "success" if this | ||
470 | * frame was successful. */ | ||
471 | mask = window->data; | ||
472 | window->data = (mask << 1); | ||
473 | if (successes > 0) { | ||
474 | window->success_counter = window->success_counter + 1; | ||
475 | window->data |= 0x1; | ||
476 | successes--; | ||
477 | } | ||
313 | 478 | ||
314 | /* Shift bitmap by one frame (throw away oldest history), | 479 | retries--; |
315 | * OR in "1", and increment "success" if this frame was successful. */ | ||
316 | mask = window->data; | ||
317 | window->data = (mask << 1); | ||
318 | if (status != 0) { | ||
319 | window->success_counter = window->success_counter + 1; | ||
320 | window->data |= 0x1; | ||
321 | } | 480 | } |
322 | 481 | ||
323 | /* Calculate current success ratio, avoid divide-by-0! */ | 482 | /* Calculate current success ratio, avoid divide-by-0! */ |
@@ -404,7 +563,8 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, | |||
404 | * fill "search" or "active" tx mode table. | 563 | * fill "search" or "active" tx mode table. |
405 | */ | 564 | */ |
406 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 565 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, |
407 | int phymode, struct iwl4965_scale_tbl_info *tbl, | 566 | enum ieee80211_band band, |
567 | struct iwl4965_scale_tbl_info *tbl, | ||
408 | int *rate_idx) | 568 | int *rate_idx) |
409 | { | 569 | { |
410 | int index; | 570 | int index; |
@@ -429,7 +589,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | |||
429 | tbl->lq_type = LQ_NONE; | 589 | tbl->lq_type = LQ_NONE; |
430 | else { | 590 | else { |
431 | 591 | ||
432 | if (phymode == MODE_IEEE80211A) | 592 | if (band == IEEE80211_BAND_5GHZ) |
433 | tbl->lq_type = LQ_A; | 593 | tbl->lq_type = LQ_A; |
434 | else | 594 | else |
435 | tbl->lq_type = LQ_G; | 595 | tbl->lq_type = LQ_G; |
@@ -607,7 +767,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
607 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { | 767 | if (!is_legacy(tbl->lq_type) && (!ht_possible || !scale_index)) { |
608 | switch_to_legacy = 1; | 768 | switch_to_legacy = 1; |
609 | scale_index = rs_ht_to_legacy[scale_index]; | 769 | scale_index = rs_ht_to_legacy[scale_index]; |
610 | if (lq_sta->phymode == MODE_IEEE80211A) | 770 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
611 | tbl->lq_type = LQ_A; | 771 | tbl->lq_type = LQ_A; |
612 | else | 772 | else |
613 | tbl->lq_type = LQ_G; | 773 | tbl->lq_type = LQ_G; |
@@ -625,7 +785,7 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | |||
625 | /* Mask with station rate restriction */ | 785 | /* Mask with station rate restriction */ |
626 | if (is_legacy(tbl->lq_type)) { | 786 | if (is_legacy(tbl->lq_type)) { |
627 | /* supp_rates has no CCK bits in A mode */ | 787 | /* supp_rates has no CCK bits in A mode */ |
628 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 788 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
629 | rate_mask = (u16)(rate_mask & | 789 | rate_mask = (u16)(rate_mask & |
630 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 790 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
631 | else | 791 | else |
@@ -677,6 +837,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
677 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) | 837 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) |
678 | return; | 838 | return; |
679 | 839 | ||
840 | /* This packet was aggregated but doesn't carry rate scale info */ | ||
841 | if ((tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) && | ||
842 | !(tx_resp->flags & IEEE80211_TX_STATUS_AMPDU)) | ||
843 | return; | ||
844 | |||
680 | retries = tx_resp->retry_count; | 845 | retries = tx_resp->retry_count; |
681 | 846 | ||
682 | if (retries > 15) | 847 | if (retries > 15) |
@@ -719,9 +884,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
719 | search_win = (struct iwl4965_rate_scale_data *) | 884 | search_win = (struct iwl4965_rate_scale_data *) |
720 | &(search_tbl->win[0]); | 885 | &(search_tbl->win[0]); |
721 | 886 | ||
722 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 887 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; |
723 | 888 | ||
724 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 889 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
725 | &tbl_type, &rs_index); | 890 | &tbl_type, &rs_index); |
726 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { | 891 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { |
727 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", | 892 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", |
@@ -754,7 +919,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
754 | * Each tx attempt steps one entry deeper in the rate table. */ | 919 | * Each tx attempt steps one entry deeper in the rate table. */ |
755 | tx_mcs.rate_n_flags = | 920 | tx_mcs.rate_n_flags = |
756 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 921 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
757 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 922 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
758 | &tbl_type, &rs_index); | 923 | &tbl_type, &rs_index); |
759 | 924 | ||
760 | /* If type matches "search" table, | 925 | /* If type matches "search" table, |
@@ -766,7 +931,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
766 | tpt = search_tbl->expected_tpt[rs_index]; | 931 | tpt = search_tbl->expected_tpt[rs_index]; |
767 | else | 932 | else |
768 | tpt = 0; | 933 | tpt = 0; |
769 | rs_collect_tx_data(search_win, rs_index, tpt, 0); | 934 | rs_collect_tx_data(search_win, rs_index, tpt, 1, 0); |
770 | 935 | ||
771 | /* Else if type matches "current/active" table, | 936 | /* Else if type matches "current/active" table, |
772 | * add failure to "current/active" history */ | 937 | * add failure to "current/active" history */ |
@@ -777,7 +942,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
777 | tpt = curr_tbl->expected_tpt[rs_index]; | 942 | tpt = curr_tbl->expected_tpt[rs_index]; |
778 | else | 943 | else |
779 | tpt = 0; | 944 | tpt = 0; |
780 | rs_collect_tx_data(window, rs_index, tpt, 0); | 945 | rs_collect_tx_data(window, rs_index, tpt, 1, 0); |
781 | } | 946 | } |
782 | 947 | ||
783 | /* If not searching for a new mode, increment failed counter | 948 | /* If not searching for a new mode, increment failed counter |
@@ -795,12 +960,12 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
795 | * else look up the rate that was, finally, successful. | 960 | * else look up the rate that was, finally, successful. |
796 | */ | 961 | */ |
797 | if (!tx_resp->retry_count) | 962 | if (!tx_resp->retry_count) |
798 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate; | 963 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; |
799 | else | 964 | else |
800 | tx_mcs.rate_n_flags = | 965 | tx_mcs.rate_n_flags = |
801 | le32_to_cpu(table->rs_table[index].rate_n_flags); | 966 | le32_to_cpu(table->rs_table[index].rate_n_flags); |
802 | 967 | ||
803 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, | 968 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, |
804 | &tbl_type, &rs_index); | 969 | &tbl_type, &rs_index); |
805 | 970 | ||
806 | /* Update frame history window with "success" if Tx got ACKed ... */ | 971 | /* Update frame history window with "success" if Tx got ACKed ... */ |
@@ -818,9 +983,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
818 | tpt = search_tbl->expected_tpt[rs_index]; | 983 | tpt = search_tbl->expected_tpt[rs_index]; |
819 | else | 984 | else |
820 | tpt = 0; | 985 | tpt = 0; |
821 | rs_collect_tx_data(search_win, | 986 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
822 | rs_index, tpt, status); | 987 | rs_collect_tx_data(search_win, rs_index, tpt, |
823 | 988 | tx_resp->ampdu_ack_len, | |
989 | tx_resp->ampdu_ack_map); | ||
990 | else | ||
991 | rs_collect_tx_data(search_win, rs_index, tpt, | ||
992 | 1, status); | ||
824 | /* Else if type matches "current/active" table, | 993 | /* Else if type matches "current/active" table, |
825 | * add final tx status to "current/active" history */ | 994 | * add final tx status to "current/active" history */ |
826 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && | 995 | } else if ((tbl_type.lq_type == curr_tbl->lq_type) && |
@@ -830,16 +999,28 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
830 | tpt = curr_tbl->expected_tpt[rs_index]; | 999 | tpt = curr_tbl->expected_tpt[rs_index]; |
831 | else | 1000 | else |
832 | tpt = 0; | 1001 | tpt = 0; |
833 | rs_collect_tx_data(window, rs_index, tpt, status); | 1002 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) |
1003 | rs_collect_tx_data(window, rs_index, tpt, | ||
1004 | tx_resp->ampdu_ack_len, | ||
1005 | tx_resp->ampdu_ack_map); | ||
1006 | else | ||
1007 | rs_collect_tx_data(window, rs_index, tpt, | ||
1008 | 1, status); | ||
834 | } | 1009 | } |
835 | 1010 | ||
836 | /* If not searching for new mode, increment success/failed counter | 1011 | /* If not searching for new mode, increment success/failed counter |
837 | * ... these help determine when to start searching again */ | 1012 | * ... these help determine when to start searching again */ |
838 | if (lq_sta->stay_in_tbl) { | 1013 | if (lq_sta->stay_in_tbl) { |
839 | if (status) | 1014 | if (tx_resp->control.flags & IEEE80211_TXCTL_AMPDU) { |
840 | lq_sta->total_success++; | 1015 | lq_sta->total_success += tx_resp->ampdu_ack_map; |
841 | else | 1016 | lq_sta->total_failed += |
842 | lq_sta->total_failed++; | 1017 | (tx_resp->ampdu_ack_len - tx_resp->ampdu_ack_map); |
1018 | } else { | ||
1019 | if (status) | ||
1020 | lq_sta->total_success++; | ||
1021 | else | ||
1022 | lq_sta->total_failed++; | ||
1023 | } | ||
843 | } | 1024 | } |
844 | 1025 | ||
845 | /* See if there's a better rate or modulation mode to try. */ | 1026 | /* See if there's a better rate or modulation mode to try. */ |
@@ -1105,7 +1286,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv, | |||
1105 | return 0; | 1286 | return 0; |
1106 | #else | 1287 | #else |
1107 | return -1; | 1288 | return -1; |
1108 | #endif /*CONFIG_IWL4965_HT */ | 1289 | #endif /*CONFIG_IWL4965_HT */ |
1109 | } | 1290 | } |
1110 | 1291 | ||
1111 | /* | 1292 | /* |
@@ -1168,7 +1349,7 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv, | |||
1168 | #else | 1349 | #else |
1169 | return -1; | 1350 | return -1; |
1170 | 1351 | ||
1171 | #endif /*CONFIG_IWL4965_HT */ | 1352 | #endif /*CONFIG_IWL4965_HT */ |
1172 | } | 1353 | } |
1173 | 1354 | ||
1174 | /* | 1355 | /* |
@@ -1325,6 +1506,7 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv, | |||
1325 | break; | 1506 | break; |
1326 | case IWL_SISO_SWITCH_GI: | 1507 | case IWL_SISO_SWITCH_GI: |
1327 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); | 1508 | IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); |
1509 | |||
1328 | memcpy(search_tbl, tbl, sz); | 1510 | memcpy(search_tbl, tbl, sz); |
1329 | search_tbl->action = 0; | 1511 | search_tbl->action = 0; |
1330 | if (search_tbl->is_SGI) | 1512 | if (search_tbl->is_SGI) |
@@ -1390,6 +1572,7 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv, | |||
1390 | case IWL_MIMO_SWITCH_ANTENNA_B: | 1572 | case IWL_MIMO_SWITCH_ANTENNA_B: |
1391 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); | 1573 | IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); |
1392 | 1574 | ||
1575 | |||
1393 | /* Set up new search table for SISO */ | 1576 | /* Set up new search table for SISO */ |
1394 | memcpy(search_tbl, tbl, sz); | 1577 | memcpy(search_tbl, tbl, sz); |
1395 | search_tbl->lq_type = LQ_SISO; | 1578 | search_tbl->lq_type = LQ_SISO; |
@@ -1574,6 +1757,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1574 | u8 active_tbl = 0; | 1757 | u8 active_tbl = 0; |
1575 | u8 done_search = 0; | 1758 | u8 done_search = 0; |
1576 | u16 high_low; | 1759 | u16 high_low; |
1760 | #ifdef CONFIG_IWL4965_HT | ||
1761 | u8 tid = MAX_TID_COUNT; | ||
1762 | __le16 *qc; | ||
1763 | #endif | ||
1577 | 1764 | ||
1578 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1765 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1579 | 1766 | ||
@@ -1594,6 +1781,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1594 | } | 1781 | } |
1595 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1782 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1596 | 1783 | ||
1784 | #ifdef CONFIG_IWL4965_HT | ||
1785 | qc = ieee80211_get_qos_ctrl(hdr); | ||
1786 | if (qc) { | ||
1787 | tid = (u8)(le16_to_cpu(*qc) & 0xf); | ||
1788 | rs_tl_add_packet(lq_sta, tid); | ||
1789 | } | ||
1790 | #endif | ||
1597 | /* | 1791 | /* |
1598 | * Select rate-scale / modulation-mode table to work with in | 1792 | * Select rate-scale / modulation-mode table to work with in |
1599 | * the rest of this function: "search" if searching for better | 1793 | * the rest of this function: "search" if searching for better |
@@ -1608,7 +1802,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1608 | is_green = lq_sta->is_green; | 1802 | is_green = lq_sta->is_green; |
1609 | 1803 | ||
1610 | /* current tx rate */ | 1804 | /* current tx rate */ |
1611 | index = sta->last_txrate; | 1805 | index = sta->last_txrate_idx; |
1612 | 1806 | ||
1613 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, | 1807 | IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, |
1614 | tbl->lq_type); | 1808 | tbl->lq_type); |
@@ -1621,7 +1815,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1621 | 1815 | ||
1622 | /* mask with station rate restriction */ | 1816 | /* mask with station rate restriction */ |
1623 | if (is_legacy(tbl->lq_type)) { | 1817 | if (is_legacy(tbl->lq_type)) { |
1624 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 1818 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1625 | /* supp_rates has no CCK bits in A mode */ | 1819 | /* supp_rates has no CCK bits in A mode */ |
1626 | rate_scale_index_msk = (u16) (rate_mask & | 1820 | rate_scale_index_msk = (u16) (rate_mask & |
1627 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); | 1821 | (lq_sta->supp_rates << IWL_FIRST_OFDM_RATE)); |
@@ -1914,15 +2108,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1914 | * mode for a while before next round of mode comparisons. */ | 2108 | * mode for a while before next round of mode comparisons. */ |
1915 | if (lq_sta->enable_counter && | 2109 | if (lq_sta->enable_counter && |
1916 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 2110 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
1917 | #ifdef CONFIG_IWL4965_HT_AGG | 2111 | #ifdef CONFIG_IWL4965_HT |
1918 | /* If appropriate, set up aggregation! */ | 2112 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
1919 | if ((lq_sta->last_tpt > TID_AGG_TPT_THREHOLD) && | 2113 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
1920 | (priv->lq_mngr.agg_ctrl.auto_agg)) { | 2114 | (tid != MAX_TID_COUNT)) { |
1921 | priv->lq_mngr.agg_ctrl.tid_retry = | 2115 | IWL_DEBUG_HT("try to aggregate tid %d\n", tid); |
1922 | TID_ALL_SPECIFIED; | 2116 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
1923 | schedule_work(&priv->agg_work); | ||
1924 | } | 2117 | } |
1925 | #endif /*CONFIG_IWL4965_HT_AGG */ | 2118 | #endif /*CONFIG_IWL4965_HT */ |
1926 | lq_sta->action_counter = 0; | 2119 | lq_sta->action_counter = 0; |
1927 | rs_set_stay_in_table(0, lq_sta); | 2120 | rs_set_stay_in_table(0, lq_sta); |
1928 | } | 2121 | } |
@@ -1942,15 +2135,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv, | |||
1942 | out: | 2135 | out: |
1943 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); | 2136 | rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); |
1944 | i = index; | 2137 | i = index; |
1945 | sta->last_txrate = i; | 2138 | sta->last_txrate_idx = i; |
1946 | 2139 | ||
1947 | /* sta->txrate is an index to A mode rates which start | 2140 | /* sta->txrate_idx is an index to A mode rates which start |
1948 | * at IWL_FIRST_OFDM_RATE | 2141 | * at IWL_FIRST_OFDM_RATE |
1949 | */ | 2142 | */ |
1950 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2143 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
1951 | sta->txrate = i - IWL_FIRST_OFDM_RATE; | 2144 | sta->txrate_idx = i - IWL_FIRST_OFDM_RATE; |
1952 | else | 2145 | else |
1953 | sta->txrate = i; | 2146 | sta->txrate_idx = i; |
1954 | 2147 | ||
1955 | return; | 2148 | return; |
1956 | } | 2149 | } |
@@ -1972,7 +2165,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1972 | goto out; | 2165 | goto out; |
1973 | 2166 | ||
1974 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2167 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1975 | i = sta->last_txrate; | 2168 | i = sta->last_txrate_idx; |
1976 | 2169 | ||
1977 | if ((lq_sta->lq.sta_id == 0xff) && | 2170 | if ((lq_sta->lq.sta_id == 0xff) && |
1978 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) | 2171 | (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) |
@@ -1996,7 +2189,7 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
1996 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; | 2189 | mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; |
1997 | 2190 | ||
1998 | tbl->antenna_type = ANT_AUX; | 2191 | tbl->antenna_type = ANT_AUX; |
1999 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx); | 2192 | rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); |
2000 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) | 2193 | if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) |
2001 | rs_toggle_antenna(&mcs_rate, tbl); | 2194 | rs_toggle_antenna(&mcs_rate, tbl); |
2002 | 2195 | ||
@@ -2010,7 +2203,8 @@ static void rs_initialize_lq(struct iwl4965_priv *priv, | |||
2010 | } | 2203 | } |
2011 | 2204 | ||
2012 | static void rs_get_rate(void *priv_rate, struct net_device *dev, | 2205 | static void rs_get_rate(void *priv_rate, struct net_device *dev, |
2013 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 2206 | struct ieee80211_supported_band *sband, |
2207 | struct sk_buff *skb, | ||
2014 | struct rate_selection *sel) | 2208 | struct rate_selection *sel) |
2015 | { | 2209 | { |
2016 | 2210 | ||
@@ -2032,14 +2226,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2032 | fc = le16_to_cpu(hdr->frame_control); | 2226 | fc = le16_to_cpu(hdr->frame_control); |
2033 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2227 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2034 | !sta || !sta->rate_ctrl_priv) { | 2228 | !sta || !sta->rate_ctrl_priv) { |
2035 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2229 | sel->rate = rate_lowest(local, sband, sta); |
2036 | if (sta) | 2230 | if (sta) |
2037 | sta_info_put(sta); | 2231 | sta_info_put(sta); |
2038 | return; | 2232 | return; |
2039 | } | 2233 | } |
2040 | 2234 | ||
2041 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 2235 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
2042 | i = sta->last_txrate; | 2236 | i = sta->last_txrate_idx; |
2043 | 2237 | ||
2044 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 2238 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && |
2045 | !lq_sta->ibss_sta_added) { | 2239 | !lq_sta->ibss_sta_added) { |
@@ -2064,7 +2258,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2064 | 2258 | ||
2065 | done: | 2259 | done: |
2066 | if ((i < 0) || (i > IWL_RATE_COUNT)) { | 2260 | if ((i < 0) || (i > IWL_RATE_COUNT)) { |
2067 | sel->rate = rate_lowest(local, local->oper_hw_mode, sta); | 2261 | sel->rate = rate_lowest(local, sband, sta); |
2068 | return; | 2262 | return; |
2069 | } | 2263 | } |
2070 | sta_info_put(sta); | 2264 | sta_info_put(sta); |
@@ -2099,13 +2293,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2099 | { | 2293 | { |
2100 | int i, j; | 2294 | int i, j; |
2101 | struct ieee80211_conf *conf = &local->hw.conf; | 2295 | struct ieee80211_conf *conf = &local->hw.conf; |
2102 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; | 2296 | struct ieee80211_supported_band *sband; |
2103 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 2297 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; |
2104 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2298 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2105 | 2299 | ||
2300 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2301 | |||
2106 | lq_sta->flush_timer = 0; | 2302 | lq_sta->flush_timer = 0; |
2107 | lq_sta->supp_rates = sta->supp_rates; | 2303 | lq_sta->supp_rates = sta->supp_rates[sband->band]; |
2108 | sta->txrate = 3; | 2304 | sta->txrate_idx = 3; |
2109 | for (j = 0; j < LQ_SIZE; j++) | 2305 | for (j = 0; j < LQ_SIZE; j++) |
2110 | for (i = 0; i < IWL_RATE_COUNT; i++) | 2306 | for (i = 0; i < IWL_RATE_COUNT; i++) |
2111 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); | 2307 | rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i])); |
@@ -2140,15 +2336,15 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2140 | } | 2336 | } |
2141 | 2337 | ||
2142 | /* Find highest tx rate supported by hardware and destination station */ | 2338 | /* Find highest tx rate supported by hardware and destination station */ |
2143 | for (i = 0; i < mode->num_rates; i++) { | 2339 | for (i = 0; i < sband->n_bitrates; i++) |
2144 | if ((sta->supp_rates & BIT(i)) && | 2340 | if (sta->supp_rates[sband->band] & BIT(i)) |
2145 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) | 2341 | sta->txrate_idx = i; |
2146 | sta->txrate = i; | 2342 | |
2147 | } | 2343 | sta->last_txrate_idx = sta->txrate_idx; |
2148 | sta->last_txrate = sta->txrate; | 2344 | /* WTF is with this bogus comment? A doesn't have cck rates */ |
2149 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ | 2345 | /* For MODE_IEEE80211A, cck rates are at end of rate table */ |
2150 | if (local->hw.conf.phymode == MODE_IEEE80211A) | 2346 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) |
2151 | sta->last_txrate += IWL_FIRST_OFDM_RATE; | 2347 | sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; |
2152 | 2348 | ||
2153 | lq_sta->is_dup = 0; | 2349 | lq_sta->is_dup = 0; |
2154 | lq_sta->valid_antenna = priv->valid_antenna; | 2350 | lq_sta->valid_antenna = priv->valid_antenna; |
@@ -2157,7 +2353,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2157 | lq_sta->active_rate = priv->active_rate; | 2353 | lq_sta->active_rate = priv->active_rate; |
2158 | lq_sta->active_rate &= ~(0x1000); | 2354 | lq_sta->active_rate &= ~(0x1000); |
2159 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2355 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2160 | lq_sta->phymode = priv->phymode; | 2356 | lq_sta->band = priv->band; |
2161 | #ifdef CONFIG_IWL4965_HT | 2357 | #ifdef CONFIG_IWL4965_HT |
2162 | /* | 2358 | /* |
2163 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2359 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
@@ -2180,6 +2376,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2180 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", | 2376 | IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", |
2181 | lq_sta->active_siso_rate, | 2377 | lq_sta->active_siso_rate, |
2182 | lq_sta->active_mimo_rate); | 2378 | lq_sta->active_mimo_rate); |
2379 | /* as default allow aggregation for all tids */ | ||
2380 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | ||
2183 | #endif /*CONFIG_IWL4965_HT*/ | 2381 | #endif /*CONFIG_IWL4965_HT*/ |
2184 | #ifdef CONFIG_MAC80211_DEBUGFS | 2382 | #ifdef CONFIG_MAC80211_DEBUGFS |
2185 | lq_sta->drv = priv; | 2383 | lq_sta->drv = priv; |
@@ -2207,7 +2405,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2207 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); | 2405 | rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); |
2208 | 2406 | ||
2209 | /* Interpret rate_n_flags */ | 2407 | /* Interpret rate_n_flags */ |
2210 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->phymode, | 2408 | rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, |
2211 | &tbl_type, &rate_idx); | 2409 | &tbl_type, &rate_idx); |
2212 | 2410 | ||
2213 | /* How many times should we repeat the initial rate? */ | 2411 | /* How many times should we repeat the initial rate? */ |
@@ -2261,7 +2459,7 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, | |||
2261 | index++; | 2459 | index++; |
2262 | } | 2460 | } |
2263 | 2461 | ||
2264 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->phymode, &tbl_type, | 2462 | rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, |
2265 | &rate_idx); | 2463 | &rate_idx); |
2266 | 2464 | ||
2267 | /* Indicate to uCode which entries might be MIMO. | 2465 | /* Indicate to uCode which entries might be MIMO. |
@@ -2323,12 +2521,6 @@ static void rs_clear(void *priv_rate) | |||
2323 | IWL_DEBUG_RATE("enter\n"); | 2521 | IWL_DEBUG_RATE("enter\n"); |
2324 | 2522 | ||
2325 | priv->lq_mngr.lq_ready = 0; | 2523 | priv->lq_mngr.lq_ready = 0; |
2326 | #ifdef CONFIG_IWL4965_HT | ||
2327 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2328 | if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
2329 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); | ||
2330 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
2331 | #endif /* CONFIG_IWL4965_HT */ | ||
2332 | 2524 | ||
2333 | IWL_DEBUG_RATE("leave\n"); | 2525 | IWL_DEBUG_RATE("leave\n"); |
2334 | } | 2526 | } |
@@ -2354,7 +2546,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | |||
2354 | { | 2546 | { |
2355 | u32 base_rate; | 2547 | u32 base_rate; |
2356 | 2548 | ||
2357 | if (lq_sta->phymode == (u8) MODE_IEEE80211A) | 2549 | if (lq_sta->band == IEEE80211_BAND_5GHZ) |
2358 | base_rate = 0x800D; | 2550 | base_rate = 0x800D; |
2359 | else | 2551 | else |
2360 | base_rate = 0x820A; | 2552 | base_rate = 0x820A; |
@@ -2495,6 +2687,12 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2495 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2687 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2496 | debugfs_create_file("rate_stats_table", 0600, dir, | 2688 | debugfs_create_file("rate_stats_table", 0600, dir, |
2497 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2689 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2690 | #ifdef CONFIG_IWL4965_HT | ||
2691 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | ||
2692 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | ||
2693 | &lq_sta->tx_agg_tid_en); | ||
2694 | #endif | ||
2695 | |||
2498 | } | 2696 | } |
2499 | 2697 | ||
2500 | static void rs_remove_debugfs(void *priv, void *priv_sta) | 2698 | static void rs_remove_debugfs(void *priv, void *priv_sta) |
@@ -2502,6 +2700,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2502 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2700 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2503 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2701 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2504 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2702 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2703 | #ifdef CONFIG_IWL4965_HT | ||
2704 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | ||
2705 | #endif | ||
2505 | } | 2706 | } |
2506 | #endif | 2707 | #endif |
2507 | 2708 | ||
@@ -2605,7 +2806,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) | |||
2605 | 2806 | ||
2606 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " | 2807 | cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d " |
2607 | "active_search %d rate index %d\n", lq_type, antenna, | 2808 | "active_search %d rate index %d\n", lq_type, antenna, |
2608 | lq_sta->search_better_tbl, sta->last_txrate); | 2809 | lq_sta->search_better_tbl, sta->last_txrate_idx); |
2609 | 2810 | ||
2610 | sta_info_put(sta); | 2811 | sta_info_put(sta); |
2611 | return cnt; | 2812 | return cnt; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index 55f707382787..13b6c72eeb73 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h | |||
@@ -212,6 +212,18 @@ enum { | |||
212 | 212 | ||
213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ | 213 | #define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ |
214 | 214 | ||
215 | /* load per tid defines for A-MPDU activation */ | ||
216 | #define IWL_AGG_TPT_THREHOLD 0 | ||
217 | #define IWL_AGG_LOAD_THRESHOLD 10 | ||
218 | #define IWL_AGG_ALL_TID 0xff | ||
219 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
220 | #define TID_QUEUE_MAX_SIZE 20 | ||
221 | #define TID_ROUND_VALUE 5 /* mS */ | ||
222 | #define TID_MAX_LOAD_COUNT 8 | ||
223 | |||
224 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
225 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
226 | |||
215 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; | 227 | extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; |
216 | 228 | ||
217 | enum iwl4965_table_type { | 229 | enum iwl4965_table_type { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d727de8b96fe..a9c30bcb65b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -79,6 +79,30 @@ const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = { | |||
79 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ | 79 | IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #ifdef CONFIG_IWL4965_HT | ||
83 | |||
84 | static const u16 default_tid_to_tx_fifo[] = { | ||
85 | IWL_TX_FIFO_AC1, | ||
86 | IWL_TX_FIFO_AC0, | ||
87 | IWL_TX_FIFO_AC0, | ||
88 | IWL_TX_FIFO_AC1, | ||
89 | IWL_TX_FIFO_AC2, | ||
90 | IWL_TX_FIFO_AC2, | ||
91 | IWL_TX_FIFO_AC3, | ||
92 | IWL_TX_FIFO_AC3, | ||
93 | IWL_TX_FIFO_NONE, | ||
94 | IWL_TX_FIFO_NONE, | ||
95 | IWL_TX_FIFO_NONE, | ||
96 | IWL_TX_FIFO_NONE, | ||
97 | IWL_TX_FIFO_NONE, | ||
98 | IWL_TX_FIFO_NONE, | ||
99 | IWL_TX_FIFO_NONE, | ||
100 | IWL_TX_FIFO_NONE, | ||
101 | IWL_TX_FIFO_AC3 | ||
102 | }; | ||
103 | |||
104 | #endif /*CONFIG_IWL4965_HT */ | ||
105 | |||
82 | static int is_fat_channel(__le32 rxon_flags) | 106 | static int is_fat_channel(__le32 rxon_flags) |
83 | { | 107 | { |
84 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || | 108 | return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) || |
@@ -315,14 +339,15 @@ static int iwl4965_kw_alloc(struct iwl4965_priv *priv) | |||
315 | * | 339 | * |
316 | * Does not set up a command, or touch hardware. | 340 | * Does not set up a command, or touch hardware. |
317 | */ | 341 | */ |
318 | int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel, | 342 | int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, |
343 | enum ieee80211_band band, u16 channel, | ||
319 | const struct iwl4965_eeprom_channel *eeprom_ch, | 344 | const struct iwl4965_eeprom_channel *eeprom_ch, |
320 | u8 fat_extension_channel) | 345 | u8 fat_extension_channel) |
321 | { | 346 | { |
322 | struct iwl4965_channel_info *ch_info; | 347 | struct iwl4965_channel_info *ch_info; |
323 | 348 | ||
324 | ch_info = (struct iwl4965_channel_info *) | 349 | ch_info = (struct iwl4965_channel_info *) |
325 | iwl4965_get_channel_info(priv, phymode, channel); | 350 | iwl4965_get_channel_info(priv, band, channel); |
326 | 351 | ||
327 | if (!is_channel_valid(ch_info)) | 352 | if (!is_channel_valid(ch_info)) |
328 | return -1; | 353 | return -1; |
@@ -520,9 +545,10 @@ int iwl4965_hw_nic_init(struct iwl4965_priv *priv) | |||
520 | 545 | ||
521 | /* set CSR_HW_CONFIG_REG for uCode use */ | 546 | /* set CSR_HW_CONFIG_REG for uCode use */ |
522 | 547 | ||
523 | iwl4965_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | | 548 | iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG, |
524 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | | 549 | CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | |
525 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | 550 | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | |
551 | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); | ||
526 | 552 | ||
527 | rc = iwl4965_grab_nic_access(priv); | 553 | rc = iwl4965_grab_nic_access(priv); |
528 | if (rc < 0) { | 554 | if (rc < 0) { |
@@ -1769,7 +1795,6 @@ int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv) | |||
1769 | memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); | 1795 | memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); |
1770 | 1796 | ||
1771 | priv->hw_setting.max_txq_num = iwl4965_param_queues_num; | 1797 | priv->hw_setting.max_txq_num = iwl4965_param_queues_num; |
1772 | priv->hw_setting.ac_queue_count = AC_NUM; | ||
1773 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); | 1798 | priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); |
1774 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; | 1799 | priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; |
1775 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; | 1800 | priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; |
@@ -1780,6 +1805,9 @@ int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv) | |||
1780 | priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; | 1805 | priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; |
1781 | priv->hw_setting.max_stations = IWL4965_STATION_COUNT; | 1806 | priv->hw_setting.max_stations = IWL4965_STATION_COUNT; |
1782 | priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; | 1807 | priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; |
1808 | |||
1809 | priv->hw_setting.tx_ant_num = 2; | ||
1810 | |||
1783 | return 0; | 1811 | return 0; |
1784 | } | 1812 | } |
1785 | 1813 | ||
@@ -1915,11 +1943,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, | |||
1915 | } | 1943 | } |
1916 | 1944 | ||
1917 | static const struct iwl4965_channel_info * | 1945 | static const struct iwl4965_channel_info * |
1918 | iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, u8 phymode, u16 channel) | 1946 | iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, |
1947 | enum ieee80211_band band, u16 channel) | ||
1919 | { | 1948 | { |
1920 | const struct iwl4965_channel_info *ch_info; | 1949 | const struct iwl4965_channel_info *ch_info; |
1921 | 1950 | ||
1922 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | 1951 | ch_info = iwl4965_get_channel_info(priv, band, channel); |
1923 | 1952 | ||
1924 | if (!is_channel_valid(ch_info)) | 1953 | if (!is_channel_valid(ch_info)) |
1925 | return NULL; | 1954 | return NULL; |
@@ -2368,7 +2397,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 chan | |||
2368 | 2397 | ||
2369 | /* Get current (RXON) channel, band, width */ | 2398 | /* Get current (RXON) channel, band, width */ |
2370 | ch_info = | 2399 | ch_info = |
2371 | iwl4965_get_channel_txpower_info(priv, priv->phymode, channel); | 2400 | iwl4965_get_channel_txpower_info(priv, priv->band, channel); |
2372 | 2401 | ||
2373 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, | 2402 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, |
2374 | is_fat); | 2403 | is_fat); |
@@ -2595,8 +2624,7 @@ int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv) | |||
2595 | return -EAGAIN; | 2624 | return -EAGAIN; |
2596 | } | 2625 | } |
2597 | 2626 | ||
2598 | band = ((priv->phymode == MODE_IEEE80211B) || | 2627 | band = priv->band == IEEE80211_BAND_2GHZ; |
2599 | (priv->phymode == MODE_IEEE80211G)); | ||
2600 | 2628 | ||
2601 | is_fat = is_fat_channel(priv->active_rxon.flags); | 2629 | is_fat = is_fat_channel(priv->active_rxon.flags); |
2602 | 2630 | ||
@@ -2626,10 +2654,9 @@ int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel) | |||
2626 | struct iwl4965_channel_switch_cmd cmd = { 0 }; | 2654 | struct iwl4965_channel_switch_cmd cmd = { 0 }; |
2627 | const struct iwl4965_channel_info *ch_info; | 2655 | const struct iwl4965_channel_info *ch_info; |
2628 | 2656 | ||
2629 | band = ((priv->phymode == MODE_IEEE80211B) || | 2657 | band = priv->band == IEEE80211_BAND_2GHZ; |
2630 | (priv->phymode == MODE_IEEE80211G)); | ||
2631 | 2658 | ||
2632 | ch_info = iwl4965_get_channel_info(priv, priv->phymode, channel); | 2659 | ch_info = iwl4965_get_channel_info(priv, priv->band, channel); |
2633 | 2660 | ||
2634 | is_fat = is_fat_channel(priv->staging_rxon.flags); | 2661 | is_fat = is_fat_channel(priv->staging_rxon.flags); |
2635 | 2662 | ||
@@ -2674,7 +2701,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv, | |||
2674 | u16 fc = le16_to_cpu(hdr->frame_control); | 2701 | u16 fc = le16_to_cpu(hdr->frame_control); |
2675 | u8 rate_plcp; | 2702 | u8 rate_plcp; |
2676 | u16 rate_flags = 0; | 2703 | u16 rate_flags = 0; |
2677 | int rate_idx = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); | 2704 | int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); |
2678 | 2705 | ||
2679 | rate_plcp = iwl4965_rates[rate_idx].plcp; | 2706 | rate_plcp = iwl4965_rates[rate_idx].plcp; |
2680 | 2707 | ||
@@ -2922,378 +2949,6 @@ void iwl4965_set_rxon_chain(struct iwl4965_priv *priv) | |||
2922 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); | 2949 | IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); |
2923 | } | 2950 | } |
2924 | 2951 | ||
2925 | #ifdef CONFIG_IWL4965_HT | ||
2926 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2927 | /* | ||
2928 | get the traffic load value for tid | ||
2929 | */ | ||
2930 | static u32 iwl4965_tl_get_load(struct iwl4965_priv *priv, u8 tid) | ||
2931 | { | ||
2932 | u32 load = 0; | ||
2933 | u32 current_time = jiffies_to_msecs(jiffies); | ||
2934 | u32 time_diff; | ||
2935 | s32 index; | ||
2936 | unsigned long flags; | ||
2937 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
2938 | |||
2939 | if (tid >= TID_MAX_LOAD_COUNT) | ||
2940 | return 0; | ||
2941 | |||
2942 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
2943 | |||
2944 | current_time -= current_time % TID_ROUND_VALUE; | ||
2945 | |||
2946 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
2947 | if (!(tid_ptr->queue_count)) | ||
2948 | goto out; | ||
2949 | |||
2950 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
2951 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
2952 | |||
2953 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
2954 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
2955 | |||
2956 | while (tid_ptr->queue_count && | ||
2957 | (tid_ptr->time_stamp < oldest_time)) { | ||
2958 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
2959 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
2960 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
2961 | tid_ptr->queue_count--; | ||
2962 | tid_ptr->head++; | ||
2963 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
2964 | tid_ptr->head = 0; | ||
2965 | } | ||
2966 | } | ||
2967 | load = tid_ptr->total; | ||
2968 | |||
2969 | out: | ||
2970 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
2971 | return load; | ||
2972 | } | ||
2973 | |||
2974 | /* | ||
2975 | increment traffic load value for tid and also remove | ||
2976 | any old values if passed the certian time period | ||
2977 | */ | ||
2978 | static void iwl4965_tl_add_packet(struct iwl4965_priv *priv, u8 tid) | ||
2979 | { | ||
2980 | u32 current_time = jiffies_to_msecs(jiffies); | ||
2981 | u32 time_diff; | ||
2982 | s32 index; | ||
2983 | unsigned long flags; | ||
2984 | struct iwl4965_traffic_load *tid_ptr = NULL; | ||
2985 | |||
2986 | if (tid >= TID_MAX_LOAD_COUNT) | ||
2987 | return; | ||
2988 | |||
2989 | tid_ptr = &(priv->lq_mngr.agg_ctrl.traffic_load[tid]); | ||
2990 | |||
2991 | current_time -= current_time % TID_ROUND_VALUE; | ||
2992 | |||
2993 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
2994 | if (!(tid_ptr->queue_count)) { | ||
2995 | tid_ptr->total = 1; | ||
2996 | tid_ptr->time_stamp = current_time; | ||
2997 | tid_ptr->queue_count = 1; | ||
2998 | tid_ptr->head = 0; | ||
2999 | tid_ptr->packet_count[0] = 1; | ||
3000 | goto out; | ||
3001 | } | ||
3002 | |||
3003 | time_diff = TIME_WRAP_AROUND(tid_ptr->time_stamp, current_time); | ||
3004 | index = time_diff / TID_QUEUE_CELL_SPACING; | ||
3005 | |||
3006 | if (index >= TID_QUEUE_MAX_SIZE) { | ||
3007 | u32 oldest_time = current_time - TID_MAX_TIME_DIFF; | ||
3008 | |||
3009 | while (tid_ptr->queue_count && | ||
3010 | (tid_ptr->time_stamp < oldest_time)) { | ||
3011 | tid_ptr->total -= tid_ptr->packet_count[tid_ptr->head]; | ||
3012 | tid_ptr->packet_count[tid_ptr->head] = 0; | ||
3013 | tid_ptr->time_stamp += TID_QUEUE_CELL_SPACING; | ||
3014 | tid_ptr->queue_count--; | ||
3015 | tid_ptr->head++; | ||
3016 | if (tid_ptr->head >= TID_QUEUE_MAX_SIZE) | ||
3017 | tid_ptr->head = 0; | ||
3018 | } | ||
3019 | } | ||
3020 | |||
3021 | index = (tid_ptr->head + index) % TID_QUEUE_MAX_SIZE; | ||
3022 | tid_ptr->packet_count[index] = tid_ptr->packet_count[index] + 1; | ||
3023 | tid_ptr->total = tid_ptr->total + 1; | ||
3024 | |||
3025 | if ((index + 1) > tid_ptr->queue_count) | ||
3026 | tid_ptr->queue_count = index + 1; | ||
3027 | out: | ||
3028 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3029 | |||
3030 | } | ||
3031 | |||
3032 | #define MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS 7 | ||
3033 | enum HT_STATUS { | ||
3034 | BA_STATUS_FAILURE = 0, | ||
3035 | BA_STATUS_INITIATOR_DELBA, | ||
3036 | BA_STATUS_RECIPIENT_DELBA, | ||
3037 | BA_STATUS_RENEW_ADDBA_REQUEST, | ||
3038 | BA_STATUS_ACTIVE, | ||
3039 | }; | ||
3040 | |||
3041 | /** | ||
3042 | * iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available | ||
3043 | */ | ||
3044 | static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv) | ||
3045 | { | ||
3046 | int i; | ||
3047 | struct iwl4965_lq_mngr *lq; | ||
3048 | u8 count = 0; | ||
3049 | u16 msk; | ||
3050 | |||
3051 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3052 | |||
3053 | /* Find out how many agg queues are in use */ | ||
3054 | for (i = 0; i < TID_MAX_LOAD_COUNT ; i++) { | ||
3055 | msk = 1 << i; | ||
3056 | if ((lq->agg_ctrl.granted_ba & msk) || | ||
3057 | (lq->agg_ctrl.wait_for_agg_status & msk)) | ||
3058 | count++; | ||
3059 | } | ||
3060 | |||
3061 | if (count < MMAC_SCHED_MAX_NUMBER_OF_HT_BACK_FLOWS) | ||
3062 | return 1; | ||
3063 | |||
3064 | return 0; | ||
3065 | } | ||
3066 | |||
3067 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3068 | u8 tid, enum HT_STATUS status); | ||
3069 | |||
3070 | static int iwl4965_perform_addba(struct iwl4965_priv *priv, u8 tid, u32 length, | ||
3071 | u32 ba_timeout) | ||
3072 | { | ||
3073 | int rc; | ||
3074 | |||
3075 | rc = ieee80211_start_BA_session(priv->hw, priv->bssid, tid); | ||
3076 | if (rc) | ||
3077 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3078 | |||
3079 | return rc; | ||
3080 | } | ||
3081 | |||
3082 | static int iwl4965_perform_delba(struct iwl4965_priv *priv, u8 tid) | ||
3083 | { | ||
3084 | int rc; | ||
3085 | |||
3086 | rc = ieee80211_stop_BA_session(priv->hw, priv->bssid, tid); | ||
3087 | if (rc) | ||
3088 | iwl4965_ba_status(priv, tid, BA_STATUS_FAILURE); | ||
3089 | |||
3090 | return rc; | ||
3091 | } | ||
3092 | |||
3093 | static void iwl4965_turn_on_agg_for_tid(struct iwl4965_priv *priv, | ||
3094 | struct iwl4965_lq_mngr *lq, | ||
3095 | u8 auto_agg, u8 tid) | ||
3096 | { | ||
3097 | u32 tid_msk = (1 << tid); | ||
3098 | unsigned long flags; | ||
3099 | |||
3100 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3101 | /* | ||
3102 | if ((auto_agg) && (!lq->enable_counter)){ | ||
3103 | lq->agg_ctrl.next_retry = 0; | ||
3104 | lq->agg_ctrl.tid_retry = 0; | ||
3105 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3106 | return; | ||
3107 | } | ||
3108 | */ | ||
3109 | if (!(lq->agg_ctrl.granted_ba & tid_msk) && | ||
3110 | (lq->agg_ctrl.requested_ba & tid_msk)) { | ||
3111 | u8 available_queues; | ||
3112 | u32 load; | ||
3113 | |||
3114 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3115 | available_queues = iwl4964_tl_ba_avail(priv); | ||
3116 | load = iwl4965_tl_get_load(priv, tid); | ||
3117 | |||
3118 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3119 | if (!available_queues) { | ||
3120 | if (auto_agg) | ||
3121 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3122 | else { | ||
3123 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3124 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3125 | } | ||
3126 | } else if ((auto_agg) && | ||
3127 | ((load <= lq->agg_ctrl.tid_traffic_load_threshold) || | ||
3128 | ((lq->agg_ctrl.wait_for_agg_status & tid_msk)))) | ||
3129 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3130 | else { | ||
3131 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3132 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3133 | iwl4965_perform_addba(priv, tid, 0x40, | ||
3134 | lq->agg_ctrl.ba_timeout); | ||
3135 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3136 | } | ||
3137 | } | ||
3138 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3139 | } | ||
3140 | |||
3141 | static void iwl4965_turn_on_agg(struct iwl4965_priv *priv, u8 tid) | ||
3142 | { | ||
3143 | struct iwl4965_lq_mngr *lq; | ||
3144 | unsigned long flags; | ||
3145 | |||
3146 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3147 | |||
3148 | if ((tid < TID_MAX_LOAD_COUNT)) | ||
3149 | iwl4965_turn_on_agg_for_tid(priv, lq, lq->agg_ctrl.auto_agg, | ||
3150 | tid); | ||
3151 | else if (tid == TID_ALL_SPECIFIED) { | ||
3152 | if (lq->agg_ctrl.requested_ba) { | ||
3153 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) | ||
3154 | iwl4965_turn_on_agg_for_tid(priv, lq, | ||
3155 | lq->agg_ctrl.auto_agg, tid); | ||
3156 | } else { | ||
3157 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3158 | lq->agg_ctrl.tid_retry = 0; | ||
3159 | lq->agg_ctrl.next_retry = 0; | ||
3160 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3161 | } | ||
3162 | } | ||
3163 | |||
3164 | } | ||
3165 | |||
3166 | void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid) | ||
3167 | { | ||
3168 | u32 tid_msk; | ||
3169 | struct iwl4965_lq_mngr *lq; | ||
3170 | unsigned long flags; | ||
3171 | |||
3172 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3173 | |||
3174 | if ((tid < TID_MAX_LOAD_COUNT)) { | ||
3175 | tid_msk = 1 << tid; | ||
3176 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3177 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3178 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3179 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3180 | iwl4965_perform_delba(priv, tid); | ||
3181 | } else if (tid == TID_ALL_SPECIFIED) { | ||
3182 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3183 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3184 | tid_msk = 1 << tid; | ||
3185 | lq->agg_ctrl.wait_for_agg_status |= tid_msk; | ||
3186 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3187 | iwl4965_perform_delba(priv, tid); | ||
3188 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3189 | } | ||
3190 | lq->agg_ctrl.requested_ba = 0; | ||
3191 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3192 | } | ||
3193 | } | ||
3194 | |||
3195 | /** | ||
3196 | * iwl4965_ba_status - Update driver's link quality mgr with tid's HT status | ||
3197 | */ | ||
3198 | static void iwl4965_ba_status(struct iwl4965_priv *priv, | ||
3199 | u8 tid, enum HT_STATUS status) | ||
3200 | { | ||
3201 | struct iwl4965_lq_mngr *lq; | ||
3202 | u32 tid_msk = (1 << tid); | ||
3203 | unsigned long flags; | ||
3204 | |||
3205 | lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3206 | |||
3207 | if ((tid >= TID_MAX_LOAD_COUNT)) | ||
3208 | goto out; | ||
3209 | |||
3210 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3211 | switch (status) { | ||
3212 | case BA_STATUS_ACTIVE: | ||
3213 | if (!(lq->agg_ctrl.granted_ba & tid_msk)) | ||
3214 | lq->agg_ctrl.granted_ba |= tid_msk; | ||
3215 | break; | ||
3216 | default: | ||
3217 | if ((lq->agg_ctrl.granted_ba & tid_msk)) | ||
3218 | lq->agg_ctrl.granted_ba &= ~tid_msk; | ||
3219 | break; | ||
3220 | } | ||
3221 | |||
3222 | lq->agg_ctrl.wait_for_agg_status &= ~tid_msk; | ||
3223 | if (status != BA_STATUS_ACTIVE) { | ||
3224 | if (lq->agg_ctrl.auto_agg) { | ||
3225 | lq->agg_ctrl.tid_retry |= tid_msk; | ||
3226 | lq->agg_ctrl.next_retry = | ||
3227 | jiffies + msecs_to_jiffies(500); | ||
3228 | } else | ||
3229 | lq->agg_ctrl.requested_ba &= ~tid_msk; | ||
3230 | } | ||
3231 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3232 | out: | ||
3233 | return; | ||
3234 | } | ||
3235 | |||
3236 | static void iwl4965_bg_agg_work(struct work_struct *work) | ||
3237 | { | ||
3238 | struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, | ||
3239 | agg_work); | ||
3240 | |||
3241 | u32 tid; | ||
3242 | u32 retry_tid; | ||
3243 | u32 tid_msk; | ||
3244 | unsigned long flags; | ||
3245 | struct iwl4965_lq_mngr *lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); | ||
3246 | |||
3247 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3248 | retry_tid = lq->agg_ctrl.tid_retry; | ||
3249 | lq->agg_ctrl.tid_retry = 0; | ||
3250 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3251 | |||
3252 | if (retry_tid == TID_ALL_SPECIFIED) | ||
3253 | iwl4965_turn_on_agg(priv, TID_ALL_SPECIFIED); | ||
3254 | else { | ||
3255 | for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++) { | ||
3256 | tid_msk = (1 << tid); | ||
3257 | if (retry_tid & tid_msk) | ||
3258 | iwl4965_turn_on_agg(priv, tid); | ||
3259 | } | ||
3260 | } | ||
3261 | |||
3262 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3263 | if (lq->agg_ctrl.tid_retry) | ||
3264 | lq->agg_ctrl.next_retry = jiffies + msecs_to_jiffies(500); | ||
3265 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3266 | return; | ||
3267 | } | ||
3268 | |||
3269 | /* TODO: move this functionality to rate scaling */ | ||
3270 | void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
3271 | struct ieee80211_hdr *hdr) | ||
3272 | { | ||
3273 | __le16 *qc = ieee80211_get_qos_ctrl(hdr); | ||
3274 | |||
3275 | if (qc && | ||
3276 | (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) { | ||
3277 | u8 tid = 0; | ||
3278 | tid = (u8) (le16_to_cpu(*qc) & 0xF); | ||
3279 | if (tid < TID_MAX_LOAD_COUNT) | ||
3280 | iwl4965_tl_add_packet(priv, tid); | ||
3281 | } | ||
3282 | |||
3283 | if (priv->lq_mngr.agg_ctrl.next_retry && | ||
3284 | (time_after(priv->lq_mngr.agg_ctrl.next_retry, jiffies))) { | ||
3285 | unsigned long flags; | ||
3286 | |||
3287 | spin_lock_irqsave(&priv->lq_mngr.lock, flags); | ||
3288 | priv->lq_mngr.agg_ctrl.next_retry = 0; | ||
3289 | spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); | ||
3290 | schedule_work(&priv->agg_work); | ||
3291 | } | ||
3292 | } | ||
3293 | |||
3294 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
3295 | #endif /* CONFIG_IWL4965_HT */ | ||
3296 | |||
3297 | /** | 2952 | /** |
3298 | * sign_extend - Sign extend a value using specified bit as sign-bit | 2953 | * sign_extend - Sign extend a value using specified bit as sign-bit |
3299 | * | 2954 | * |
@@ -3526,7 +3181,7 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, | |||
3526 | { | 3181 | { |
3527 | s8 signal = stats->ssi; | 3182 | s8 signal = stats->ssi; |
3528 | s8 noise = 0; | 3183 | s8 noise = 0; |
3529 | int rate = stats->rate; | 3184 | int rate = stats->rate_idx; |
3530 | u64 tsf = stats->mactime; | 3185 | u64 tsf = stats->mactime; |
3531 | __le16 phy_flags_hw = rx_start->phy_flags; | 3186 | __le16 phy_flags_hw = rx_start->phy_flags; |
3532 | struct iwl4965_rt_rx_hdr { | 3187 | struct iwl4965_rt_rx_hdr { |
@@ -3594,7 +3249,6 @@ static void iwl4965_add_radiotap(struct iwl4965_priv *priv, | |||
3594 | IEEE80211_CHAN_2GHZ), | 3249 | IEEE80211_CHAN_2GHZ), |
3595 | &iwl4965_rt->rt_chbitmask); | 3250 | &iwl4965_rt->rt_chbitmask); |
3596 | 3251 | ||
3597 | rate = iwl4965_rate_index_from_plcp(rate); | ||
3598 | if (rate == -1) | 3252 | if (rate == -1) |
3599 | iwl4965_rt->rt_rate = 0; | 3253 | iwl4965_rt->rt_rate = 0; |
3600 | else | 3254 | else |
@@ -3808,14 +3462,15 @@ static int parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems) | |||
3808 | return 0; | 3462 | return 0; |
3809 | } | 3463 | } |
3810 | 3464 | ||
3811 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, int mode) | 3465 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
3466 | enum ieee80211_band band) | ||
3812 | { | 3467 | { |
3813 | ht_info->cap = 0; | 3468 | ht_info->cap = 0; |
3814 | memset(ht_info->supp_mcs_set, 0, 16); | 3469 | memset(ht_info->supp_mcs_set, 0, 16); |
3815 | 3470 | ||
3816 | ht_info->ht_supported = 1; | 3471 | ht_info->ht_supported = 1; |
3817 | 3472 | ||
3818 | if (mode == MODE_IEEE80211A) { | 3473 | if (band == IEEE80211_BAND_5GHZ) { |
3819 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; | 3474 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; |
3820 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; | 3475 | ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; |
3821 | ht_info->supp_mcs_set[4] = 0x01; | 3476 | ht_info->supp_mcs_set[4] = 0x01; |
@@ -3890,12 +3545,13 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, | |||
3890 | u16 fc; | 3545 | u16 fc; |
3891 | struct ieee80211_rx_status stats = { | 3546 | struct ieee80211_rx_status stats = { |
3892 | .mactime = le64_to_cpu(rx_start->timestamp), | 3547 | .mactime = le64_to_cpu(rx_start->timestamp), |
3893 | .channel = le16_to_cpu(rx_start->channel), | 3548 | .freq = ieee80211chan2mhz(le16_to_cpu(rx_start->channel)), |
3894 | .phymode = | 3549 | .band = |
3895 | (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 3550 | (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
3896 | MODE_IEEE80211G : MODE_IEEE80211A, | 3551 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ, |
3897 | .antenna = 0, | 3552 | .antenna = 0, |
3898 | .rate = iwl4965_hw_get_rate(rx_start->rate_n_flags), | 3553 | .rate_idx = iwl4965_rate_index_from_plcp( |
3554 | le32_to_cpu(rx_start->rate_n_flags)), | ||
3899 | .flag = 0, | 3555 | .flag = 0, |
3900 | }; | 3556 | }; |
3901 | u8 network_packet; | 3557 | u8 network_packet; |
@@ -3946,8 +3602,6 @@ static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, | |||
3946 | 3602 | ||
3947 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); | 3603 | priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp); |
3948 | 3604 | ||
3949 | stats.freq = ieee80211chan2mhz(stats.channel); | ||
3950 | |||
3951 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ | 3605 | /* Find max signal strength (dBm) among 3 antenna/receiver chains */ |
3952 | stats.ssi = iwl4965_calc_rssi(rx_start); | 3606 | stats.ssi = iwl4965_calc_rssi(rx_start); |
3953 | 3607 | ||
@@ -4167,24 +3821,6 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv, | |||
4167 | } | 3821 | } |
4168 | 3822 | ||
4169 | #ifdef CONFIG_IWL4965_HT | 3823 | #ifdef CONFIG_IWL4965_HT |
4170 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4171 | |||
4172 | /** | ||
4173 | * iwl4965_set_tx_status - Update driver's record of one Tx frame's status | ||
4174 | * | ||
4175 | * This will get sent to mac80211. | ||
4176 | */ | ||
4177 | static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx, | ||
4178 | u32 status, u32 retry_count, u32 rate) | ||
4179 | { | ||
4180 | struct ieee80211_tx_status *tx_status = | ||
4181 | &(priv->txq[txq_id].txb[idx].status); | ||
4182 | |||
4183 | tx_status->flags = status ? IEEE80211_TX_STATUS_ACK : 0; | ||
4184 | tx_status->retry_count += retry_count; | ||
4185 | tx_status->control.tx_rate = rate; | ||
4186 | } | ||
4187 | |||
4188 | 3824 | ||
4189 | /** | 3825 | /** |
4190 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table | 3826 | * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table |
@@ -4204,7 +3840,6 @@ static void iwl4965_sta_modify_enable_tid_tx(struct iwl4965_priv *priv, | |||
4204 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 3840 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
4205 | } | 3841 | } |
4206 | 3842 | ||
4207 | |||
4208 | /** | 3843 | /** |
4209 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack | 3844 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack |
4210 | * | 3845 | * |
@@ -4218,10 +3853,11 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4218 | 3853 | ||
4219 | { | 3854 | { |
4220 | int i, sh, ack; | 3855 | int i, sh, ack; |
4221 | u16 ba_seq_ctl = le16_to_cpu(ba_resp->ba_seq_ctl); | 3856 | u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl); |
4222 | u32 bitmap0, bitmap1; | 3857 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); |
4223 | u32 resp_bitmap0 = le32_to_cpu(ba_resp->ba_bitmap0); | 3858 | u64 bitmap; |
4224 | u32 resp_bitmap1 = le32_to_cpu(ba_resp->ba_bitmap1); | 3859 | int successes = 0; |
3860 | struct ieee80211_tx_status *tx_status; | ||
4225 | 3861 | ||
4226 | if (unlikely(!agg->wait_for_ba)) { | 3862 | if (unlikely(!agg->wait_for_ba)) { |
4227 | IWL_ERROR("Received BA when not expected\n"); | 3863 | IWL_ERROR("Received BA when not expected\n"); |
@@ -4230,17 +3866,15 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4230 | 3866 | ||
4231 | /* Mark that the expected block-ack response arrived */ | 3867 | /* Mark that the expected block-ack response arrived */ |
4232 | agg->wait_for_ba = 0; | 3868 | agg->wait_for_ba = 0; |
4233 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->ba_seq_ctl); | 3869 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); |
4234 | 3870 | ||
4235 | /* Calculate shift to align block-ack bits with our Tx window bits */ | 3871 | /* Calculate shift to align block-ack bits with our Tx window bits */ |
4236 | sh = agg->start_idx - SEQ_TO_INDEX(ba_seq_ctl >> 4); | 3872 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); |
4237 | if (sh < 0) /* tbw something is wrong with indices */ | 3873 | if (sh < 0) /* tbw something is wrong with indices */ |
4238 | sh += 0x100; | 3874 | sh += 0x100; |
4239 | 3875 | ||
4240 | /* don't use 64-bit values for now */ | 3876 | /* don't use 64-bit values for now */ |
4241 | bitmap0 = resp_bitmap0 >> sh; | 3877 | bitmap = le64_to_cpu(ba_resp->bitmap) >> sh; |
4242 | bitmap1 = resp_bitmap1 >> sh; | ||
4243 | bitmap0 |= (resp_bitmap1 & ((1 << sh) | ((1 << sh) - 1))) << (32 - sh); | ||
4244 | 3878 | ||
4245 | if (agg->frame_count > (64 - sh)) { | 3879 | if (agg->frame_count > (64 - sh)) { |
4246 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); | 3880 | IWL_DEBUG_TX_REPLY("more frames than bitmap size"); |
@@ -4249,26 +3883,108 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4249 | 3883 | ||
4250 | /* check for success or failure according to the | 3884 | /* check for success or failure according to the |
4251 | * transmitted bitmap and block-ack bitmap */ | 3885 | * transmitted bitmap and block-ack bitmap */ |
4252 | bitmap0 &= agg->bitmap0; | 3886 | bitmap &= agg->bitmap; |
4253 | bitmap1 &= agg->bitmap1; | ||
4254 | 3887 | ||
4255 | /* For each frame attempted in aggregation, | 3888 | /* For each frame attempted in aggregation, |
4256 | * update driver's record of tx frame's status. */ | 3889 | * update driver's record of tx frame's status. */ |
4257 | for (i = 0; i < agg->frame_count ; i++) { | 3890 | for (i = 0; i < agg->frame_count ; i++) { |
4258 | int idx = (agg->start_idx + i) & 0xff; | 3891 | ack = bitmap & (1 << i); |
4259 | ack = bitmap0 & (1 << i); | 3892 | successes += !!ack; |
4260 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", | 3893 | IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n", |
4261 | ack? "ACK":"NACK", i, idx, agg->start_idx + i); | 3894 | ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff, |
4262 | iwl4965_set_tx_status(priv, agg->txq_id, idx, ack, 0, | 3895 | agg->start_idx + i); |
4263 | agg->rate_n_flags); | 3896 | } |
3897 | |||
3898 | tx_status = &priv->txq[scd_flow].txb[agg->start_idx].status; | ||
3899 | tx_status->flags = IEEE80211_TX_STATUS_ACK; | ||
3900 | tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; | ||
3901 | tx_status->ampdu_ack_map = successes; | ||
3902 | tx_status->ampdu_ack_len = agg->frame_count; | ||
3903 | /* FIXME Wrong rate | ||
3904 | tx_status->control.tx_rate = agg->rate_n_flags; | ||
3905 | */ | ||
3906 | |||
3907 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); | ||
3908 | |||
3909 | return 0; | ||
3910 | } | ||
3911 | |||
3912 | /** | ||
3913 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration | ||
3914 | */ | ||
3915 | static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, | ||
3916 | u16 txq_id) | ||
3917 | { | ||
3918 | /* Simply stop the queue, but don't change any configuration; | ||
3919 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
3920 | iwl4965_write_prph(priv, | ||
3921 | KDR_SCD_QUEUE_STATUS_BITS(txq_id), | ||
3922 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
3923 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
3924 | } | ||
4264 | 3925 | ||
3926 | /** | ||
3927 | * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID | ||
3928 | */ | ||
3929 | static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, | ||
3930 | u16 ssn_idx, u8 tx_fifo) | ||
3931 | { | ||
3932 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { | ||
3933 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
3934 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | ||
3935 | return -EINVAL; | ||
4265 | } | 3936 | } |
4266 | 3937 | ||
4267 | IWL_DEBUG_TX_REPLY("Bitmap %x%x\n", bitmap0, bitmap1); | 3938 | iwl4965_tx_queue_stop_scheduler(priv, txq_id); |
3939 | |||
3940 | iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); | ||
3941 | |||
3942 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
3943 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
3944 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
3945 | iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
3946 | |||
3947 | iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
3948 | iwl4965_txq_ctx_deactivate(priv, txq_id); | ||
3949 | iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | ||
4268 | 3950 | ||
4269 | return 0; | 3951 | return 0; |
4270 | } | 3952 | } |
4271 | 3953 | ||
3954 | int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, | ||
3955 | u8 tid, int txq_id) | ||
3956 | { | ||
3957 | struct iwl4965_queue *q = &priv->txq[txq_id].q; | ||
3958 | u8 *addr = priv->stations[sta_id].sta.sta.addr; | ||
3959 | struct iwl4965_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; | ||
3960 | |||
3961 | switch (priv->stations[sta_id].tid[tid].agg.state) { | ||
3962 | case IWL_EMPTYING_HW_QUEUE_DELBA: | ||
3963 | /* We are reclaiming the last packet of the */ | ||
3964 | /* aggregated HW queue */ | ||
3965 | if (txq_id == tid_data->agg.txq_id && | ||
3966 | q->read_ptr == q->write_ptr) { | ||
3967 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); | ||
3968 | int tx_fifo = default_tid_to_tx_fifo[tid]; | ||
3969 | IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); | ||
3970 | iwl4965_tx_queue_agg_disable(priv, txq_id, | ||
3971 | ssn, tx_fifo); | ||
3972 | tid_data->agg.state = IWL_AGG_OFF; | ||
3973 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, addr, tid); | ||
3974 | } | ||
3975 | break; | ||
3976 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | ||
3977 | /* We are reclaiming the last packet of the queue */ | ||
3978 | if (tid_data->tfds_in_queue == 0) { | ||
3979 | IWL_DEBUG_HT("HW queue empty: continue ADDBA flow\n"); | ||
3980 | tid_data->agg.state = IWL_AGG_ON; | ||
3981 | ieee80211_start_tx_ba_cb_irqsafe(priv->hw, addr, tid); | ||
3982 | } | ||
3983 | break; | ||
3984 | } | ||
3985 | return 0; | ||
3986 | } | ||
3987 | |||
4272 | /** | 3988 | /** |
4273 | * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed | 3989 | * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed |
4274 | * @index -- current index | 3990 | * @index -- current index |
@@ -4293,48 +4009,43 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4293 | int index; | 4009 | int index; |
4294 | struct iwl4965_tx_queue *txq = NULL; | 4010 | struct iwl4965_tx_queue *txq = NULL; |
4295 | struct iwl4965_ht_agg *agg; | 4011 | struct iwl4965_ht_agg *agg; |
4012 | DECLARE_MAC_BUF(mac); | ||
4296 | 4013 | ||
4297 | /* "flow" corresponds to Tx queue */ | 4014 | /* "flow" corresponds to Tx queue */ |
4298 | u16 ba_resp_scd_flow = le16_to_cpu(ba_resp->scd_flow); | 4015 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); |
4299 | 4016 | ||
4300 | /* "ssn" is start of block-ack Tx window, corresponds to index | 4017 | /* "ssn" is start of block-ack Tx window, corresponds to index |
4301 | * (in Tx queue's circular buffer) of first TFD/frame in window */ | 4018 | * (in Tx queue's circular buffer) of first TFD/frame in window */ |
4302 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); | 4019 | u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); |
4303 | 4020 | ||
4304 | if (ba_resp_scd_flow >= ARRAY_SIZE(priv->txq)) { | 4021 | if (scd_flow >= ARRAY_SIZE(priv->txq)) { |
4305 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); | 4022 | IWL_ERROR("BUG_ON scd_flow is bigger than number of queues"); |
4306 | return; | 4023 | return; |
4307 | } | 4024 | } |
4308 | 4025 | ||
4309 | txq = &priv->txq[ba_resp_scd_flow]; | 4026 | txq = &priv->txq[scd_flow]; |
4310 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; | 4027 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; |
4311 | 4028 | ||
4312 | /* Find index just before block-ack window */ | 4029 | /* Find index just before block-ack window */ |
4313 | index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | 4030 | index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); |
4314 | 4031 | ||
4315 | /* TODO: Need to get this copy more safely - now good for debug */ | 4032 | /* TODO: Need to get this copy more safely - now good for debug */ |
4316 | /* | 4033 | |
4317 | { | ||
4318 | DECLARE_MAC_BUF(mac); | ||
4319 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " | 4034 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %s, " |
4320 | "sta_id = %d\n", | 4035 | "sta_id = %d\n", |
4321 | agg->wait_for_ba, | 4036 | agg->wait_for_ba, |
4322 | print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), | 4037 | print_mac(mac, (u8*) &ba_resp->sta_addr_lo32), |
4323 | ba_resp->sta_id); | 4038 | ba_resp->sta_id); |
4324 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%X%X, scd_flow = " | 4039 | IWL_DEBUG_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx, scd_flow = " |
4325 | "%d, scd_ssn = %d\n", | 4040 | "%d, scd_ssn = %d\n", |
4326 | ba_resp->tid, | 4041 | ba_resp->tid, |
4327 | ba_resp->ba_seq_ctl, | 4042 | ba_resp->seq_ctl, |
4328 | ba_resp->ba_bitmap1, | 4043 | ba_resp->bitmap, |
4329 | ba_resp->ba_bitmap0, | ||
4330 | ba_resp->scd_flow, | 4044 | ba_resp->scd_flow, |
4331 | ba_resp->scd_ssn); | 4045 | ba_resp->scd_ssn); |
4332 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%X%X \n", | 4046 | IWL_DEBUG_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx \n", |
4333 | agg->start_idx, | 4047 | agg->start_idx, |
4334 | agg->bitmap1, | 4048 | agg->bitmap); |
4335 | agg->bitmap0); | ||
4336 | } | ||
4337 | */ | ||
4338 | 4049 | ||
4339 | /* Update driver's record of ACK vs. not for each frame in window */ | 4050 | /* Update driver's record of ACK vs. not for each frame in window */ |
4340 | iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); | 4051 | iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); |
@@ -4342,23 +4053,17 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4342 | /* Release all TFDs before the SSN, i.e. all TFDs in front of | 4053 | /* Release all TFDs before the SSN, i.e. all TFDs in front of |
4343 | * block-ack window (we assume that they've been successfully | 4054 | * block-ack window (we assume that they've been successfully |
4344 | * transmitted ... if not, it's too late anyway). */ | 4055 | * transmitted ... if not, it's too late anyway). */ |
4345 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) | 4056 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
4346 | iwl4965_tx_queue_reclaim(priv, ba_resp_scd_flow, index); | 4057 | int freed = iwl4965_tx_queue_reclaim(priv, scd_flow, index); |
4347 | 4058 | priv->stations[ba_resp->sta_id]. | |
4348 | } | 4059 | tid[ba_resp->tid].tfds_in_queue -= freed; |
4349 | 4060 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | |
4350 | 4061 | priv->mac80211_registered && | |
4351 | /** | 4062 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) |
4352 | * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration | 4063 | ieee80211_wake_queue(priv->hw, scd_flow); |
4353 | */ | 4064 | iwl4965_check_empty_hw_queue(priv, ba_resp->sta_id, |
4354 | static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, u16 txq_id) | 4065 | ba_resp->tid, scd_flow); |
4355 | { | 4066 | } |
4356 | /* Simply stop the queue, but don't change any configuration; | ||
4357 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
4358 | iwl4965_write_prph(priv, | ||
4359 | KDR_SCD_QUEUE_STATUS_BITS(txq_id), | ||
4360 | (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
4361 | (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
4362 | } | 4067 | } |
4363 | 4068 | ||
4364 | /** | 4069 | /** |
@@ -4388,6 +4093,7 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl4965_priv *priv, u16 ra_tid, | |||
4388 | return 0; | 4093 | return 0; |
4389 | } | 4094 | } |
4390 | 4095 | ||
4096 | |||
4391 | /** | 4097 | /** |
4392 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue | 4098 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue |
4393 | * | 4099 | * |
@@ -4455,48 +4161,6 @@ static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id, | |||
4455 | return 0; | 4161 | return 0; |
4456 | } | 4162 | } |
4457 | 4163 | ||
4458 | /** | ||
4459 | * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID | ||
4460 | */ | ||
4461 | static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, | ||
4462 | u16 ssn_idx, u8 tx_fifo) | ||
4463 | { | ||
4464 | unsigned long flags; | ||
4465 | int rc; | ||
4466 | |||
4467 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { | ||
4468 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
4469 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | ||
4470 | return -EINVAL; | ||
4471 | } | ||
4472 | |||
4473 | spin_lock_irqsave(&priv->lock, flags); | ||
4474 | rc = iwl4965_grab_nic_access(priv); | ||
4475 | if (rc) { | ||
4476 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4477 | return rc; | ||
4478 | } | ||
4479 | |||
4480 | iwl4965_tx_queue_stop_scheduler(priv, txq_id); | ||
4481 | |||
4482 | iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); | ||
4483 | |||
4484 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
4485 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
4486 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
4487 | iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
4488 | |||
4489 | iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
4490 | iwl4965_txq_ctx_deactivate(priv, txq_id); | ||
4491 | iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | ||
4492 | |||
4493 | iwl4965_release_nic_access(priv); | ||
4494 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4495 | |||
4496 | return 0; | ||
4497 | } | ||
4498 | |||
4499 | #endif/* CONFIG_IWL4965_HT_AGG */ | ||
4500 | #endif /* CONFIG_IWL4965_HT */ | 4164 | #endif /* CONFIG_IWL4965_HT */ |
4501 | 4165 | ||
4502 | /** | 4166 | /** |
@@ -4525,7 +4189,7 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) | |||
4525 | * all the way down to 1M in IEEE order, and then spin on 1M */ | 4189 | * all the way down to 1M in IEEE order, and then spin on 1M */ |
4526 | if (is_ap) | 4190 | if (is_ap) |
4527 | r = IWL_RATE_54M_INDEX; | 4191 | r = IWL_RATE_54M_INDEX; |
4528 | else if (priv->phymode == MODE_IEEE80211A) | 4192 | else if (priv->band == IEEE80211_BAND_5GHZ) |
4529 | r = IWL_RATE_6M_INDEX; | 4193 | r = IWL_RATE_6M_INDEX; |
4530 | else | 4194 | else |
4531 | r = IWL_RATE_1M_INDEX; | 4195 | r = IWL_RATE_1M_INDEX; |
@@ -4558,12 +4222,13 @@ void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) | |||
4558 | 4222 | ||
4559 | #ifdef CONFIG_IWL4965_HT | 4223 | #ifdef CONFIG_IWL4965_HT |
4560 | 4224 | ||
4561 | static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, int phymode, | 4225 | static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, |
4562 | u16 channel, u8 extension_chan_offset) | 4226 | enum ieee80211_band band, |
4227 | u16 channel, u8 extension_chan_offset) | ||
4563 | { | 4228 | { |
4564 | const struct iwl4965_channel_info *ch_info; | 4229 | const struct iwl4965_channel_info *ch_info; |
4565 | 4230 | ||
4566 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | 4231 | ch_info = iwl4965_get_channel_info(priv, band, channel); |
4567 | if (!is_channel_valid(ch_info)) | 4232 | if (!is_channel_valid(ch_info)) |
4568 | return 0; | 4233 | return 0; |
4569 | 4234 | ||
@@ -4589,11 +4254,11 @@ static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv, | |||
4589 | 4254 | ||
4590 | if (sta_ht_inf) { | 4255 | if (sta_ht_inf) { |
4591 | if ((!sta_ht_inf->ht_supported) || | 4256 | if ((!sta_ht_inf->ht_supported) || |
4592 | (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)) | 4257 | (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) |
4593 | return 0; | 4258 | return 0; |
4594 | } | 4259 | } |
4595 | 4260 | ||
4596 | return (iwl4965_is_channel_extension(priv, priv->phymode, | 4261 | return (iwl4965_is_channel_extension(priv, priv->band, |
4597 | iwl_ht_conf->control_channel, | 4262 | iwl_ht_conf->control_channel, |
4598 | iwl_ht_conf->extension_chan_offset)); | 4263 | iwl_ht_conf->extension_chan_offset)); |
4599 | } | 4264 | } |
@@ -4730,56 +4395,6 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl4965_priv *priv, | |||
4730 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 4395 | iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
4731 | } | 4396 | } |
4732 | 4397 | ||
4733 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | ||
4734 | enum ieee80211_ampdu_mlme_action action, | ||
4735 | const u8 *addr, u16 tid, u16 ssn) | ||
4736 | { | ||
4737 | struct iwl4965_priv *priv = hw->priv; | ||
4738 | int sta_id; | ||
4739 | DECLARE_MAC_BUF(mac); | ||
4740 | |||
4741 | IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ", | ||
4742 | print_mac(mac, addr), tid); | ||
4743 | sta_id = iwl4965_hw_find_station(priv, addr); | ||
4744 | switch (action) { | ||
4745 | case IEEE80211_AMPDU_RX_START: | ||
4746 | IWL_DEBUG_HT("start Rx\n"); | ||
4747 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, ssn); | ||
4748 | break; | ||
4749 | case IEEE80211_AMPDU_RX_STOP: | ||
4750 | IWL_DEBUG_HT("stop Rx\n"); | ||
4751 | iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); | ||
4752 | break; | ||
4753 | default: | ||
4754 | IWL_DEBUG_HT("unknown\n"); | ||
4755 | return -EINVAL; | ||
4756 | break; | ||
4757 | } | ||
4758 | return 0; | ||
4759 | } | ||
4760 | |||
4761 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4762 | |||
4763 | static const u16 default_tid_to_tx_fifo[] = { | ||
4764 | IWL_TX_FIFO_AC1, | ||
4765 | IWL_TX_FIFO_AC0, | ||
4766 | IWL_TX_FIFO_AC0, | ||
4767 | IWL_TX_FIFO_AC1, | ||
4768 | IWL_TX_FIFO_AC2, | ||
4769 | IWL_TX_FIFO_AC2, | ||
4770 | IWL_TX_FIFO_AC3, | ||
4771 | IWL_TX_FIFO_AC3, | ||
4772 | IWL_TX_FIFO_NONE, | ||
4773 | IWL_TX_FIFO_NONE, | ||
4774 | IWL_TX_FIFO_NONE, | ||
4775 | IWL_TX_FIFO_NONE, | ||
4776 | IWL_TX_FIFO_NONE, | ||
4777 | IWL_TX_FIFO_NONE, | ||
4778 | IWL_TX_FIFO_NONE, | ||
4779 | IWL_TX_FIFO_NONE, | ||
4780 | IWL_TX_FIFO_AC3 | ||
4781 | }; | ||
4782 | |||
4783 | /* | 4398 | /* |
4784 | * Find first available (lowest unused) Tx Queue, mark it "active". | 4399 | * Find first available (lowest unused) Tx Queue, mark it "active". |
4785 | * Called only when finding queue for aggregation. | 4400 | * Called only when finding queue for aggregation. |
@@ -4796,70 +4411,78 @@ static int iwl4965_txq_ctx_activate_free(struct iwl4965_priv *priv) | |||
4796 | return -1; | 4411 | return -1; |
4797 | } | 4412 | } |
4798 | 4413 | ||
4799 | int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, | 4414 | static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da, |
4800 | u16 *start_seq_num) | 4415 | u16 tid, u16 *start_seq_num) |
4801 | { | 4416 | { |
4802 | |||
4803 | struct iwl4965_priv *priv = hw->priv; | 4417 | struct iwl4965_priv *priv = hw->priv; |
4804 | int sta_id; | 4418 | int sta_id; |
4805 | int tx_fifo; | 4419 | int tx_fifo; |
4806 | int txq_id; | 4420 | int txq_id; |
4807 | int ssn = -1; | 4421 | int ssn = -1; |
4422 | int rc = 0; | ||
4808 | unsigned long flags; | 4423 | unsigned long flags; |
4809 | struct iwl4965_tid_data *tid_data; | 4424 | struct iwl4965_tid_data *tid_data; |
4810 | DECLARE_MAC_BUF(mac); | 4425 | DECLARE_MAC_BUF(mac); |
4811 | 4426 | ||
4812 | /* Determine Tx DMA/FIFO channel for this Traffic ID */ | ||
4813 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) | 4427 | if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) |
4814 | tx_fifo = default_tid_to_tx_fifo[tid]; | 4428 | tx_fifo = default_tid_to_tx_fifo[tid]; |
4815 | else | 4429 | else |
4816 | return -EINVAL; | 4430 | return -EINVAL; |
4817 | 4431 | ||
4818 | IWL_WARNING("iwl-AGG iwl4965_mac_ht_tx_agg_start on da=%s" | 4432 | IWL_WARNING("%s on da = %s tid = %d\n", |
4819 | " tid=%d\n", print_mac(mac, da), tid); | 4433 | __func__, print_mac(mac, da), tid); |
4820 | 4434 | ||
4821 | /* Get index into station table */ | ||
4822 | sta_id = iwl4965_hw_find_station(priv, da); | 4435 | sta_id = iwl4965_hw_find_station(priv, da); |
4823 | if (sta_id == IWL_INVALID_STATION) | 4436 | if (sta_id == IWL_INVALID_STATION) |
4824 | return -ENXIO; | 4437 | return -ENXIO; |
4825 | 4438 | ||
4826 | /* Find available Tx queue for aggregation */ | 4439 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { |
4440 | IWL_ERROR("Start AGG when state is not IWL_AGG_OFF !\n"); | ||
4441 | return -ENXIO; | ||
4442 | } | ||
4443 | |||
4827 | txq_id = iwl4965_txq_ctx_activate_free(priv); | 4444 | txq_id = iwl4965_txq_ctx_activate_free(priv); |
4828 | if (txq_id == -1) | 4445 | if (txq_id == -1) |
4829 | return -ENXIO; | 4446 | return -ENXIO; |
4830 | 4447 | ||
4831 | spin_lock_irqsave(&priv->sta_lock, flags); | 4448 | spin_lock_irqsave(&priv->sta_lock, flags); |
4832 | tid_data = &priv->stations[sta_id].tid[tid]; | 4449 | tid_data = &priv->stations[sta_id].tid[tid]; |
4833 | |||
4834 | /* Get starting sequence number for 1st frame in block ack window. | ||
4835 | * We'll use least signif byte as 1st frame's index into Tx queue. */ | ||
4836 | ssn = SEQ_TO_SN(tid_data->seq_number); | 4450 | ssn = SEQ_TO_SN(tid_data->seq_number); |
4837 | tid_data->agg.txq_id = txq_id; | 4451 | tid_data->agg.txq_id = txq_id; |
4838 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 4452 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
4839 | 4453 | ||
4840 | *start_seq_num = ssn; | 4454 | *start_seq_num = ssn; |
4841 | 4455 | rc = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, | |
4842 | /* Update driver's link quality manager */ | ||
4843 | iwl4965_ba_status(priv, tid, BA_STATUS_ACTIVE); | ||
4844 | |||
4845 | /* Set up and enable aggregation for selected Tx queue and FIFO */ | ||
4846 | return iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, | ||
4847 | sta_id, tid, ssn); | 4456 | sta_id, tid, ssn); |
4848 | } | 4457 | if (rc) |
4458 | return rc; | ||
4849 | 4459 | ||
4460 | rc = 0; | ||
4461 | if (tid_data->tfds_in_queue == 0) { | ||
4462 | printk(KERN_ERR "HW queue is empty\n"); | ||
4463 | tid_data->agg.state = IWL_AGG_ON; | ||
4464 | ieee80211_start_tx_ba_cb_irqsafe(hw, da, tid); | ||
4465 | } else { | ||
4466 | IWL_DEBUG_HT("HW queue is NOT empty: %d packets in HW queue\n", | ||
4467 | tid_data->tfds_in_queue); | ||
4468 | tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; | ||
4469 | } | ||
4470 | return rc; | ||
4471 | } | ||
4850 | 4472 | ||
4851 | int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, | 4473 | static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, |
4852 | int generator) | 4474 | u16 tid) |
4853 | { | 4475 | { |
4854 | 4476 | ||
4855 | struct iwl4965_priv *priv = hw->priv; | 4477 | struct iwl4965_priv *priv = hw->priv; |
4856 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 4478 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
4857 | struct iwl4965_tid_data *tid_data; | 4479 | struct iwl4965_tid_data *tid_data; |
4858 | int rc; | 4480 | int rc, write_ptr, read_ptr; |
4481 | unsigned long flags; | ||
4859 | DECLARE_MAC_BUF(mac); | 4482 | DECLARE_MAC_BUF(mac); |
4860 | 4483 | ||
4861 | if (!da) { | 4484 | if (!da) { |
4862 | IWL_ERROR("%s: da = NULL\n", __func__); | 4485 | IWL_ERROR("da = NULL\n"); |
4863 | return -EINVAL; | 4486 | return -EINVAL; |
4864 | } | 4487 | } |
4865 | 4488 | ||
@@ -4873,24 +4496,81 @@ int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, | |||
4873 | if (sta_id == IWL_INVALID_STATION) | 4496 | if (sta_id == IWL_INVALID_STATION) |
4874 | return -ENXIO; | 4497 | return -ENXIO; |
4875 | 4498 | ||
4499 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) | ||
4500 | IWL_WARNING("Stopping AGG while state not IWL_AGG_ON\n"); | ||
4501 | |||
4876 | tid_data = &priv->stations[sta_id].tid[tid]; | 4502 | tid_data = &priv->stations[sta_id].tid[tid]; |
4877 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | 4503 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; |
4878 | txq_id = tid_data->agg.txq_id; | 4504 | txq_id = tid_data->agg.txq_id; |
4505 | write_ptr = priv->txq[txq_id].q.write_ptr; | ||
4506 | read_ptr = priv->txq[txq_id].q.read_ptr; | ||
4507 | |||
4508 | /* The queue is not empty */ | ||
4509 | if (write_ptr != read_ptr) { | ||
4510 | IWL_DEBUG_HT("Stopping a non empty AGG HW QUEUE\n"); | ||
4511 | priv->stations[sta_id].tid[tid].agg.state = | ||
4512 | IWL_EMPTYING_HW_QUEUE_DELBA; | ||
4513 | return 0; | ||
4514 | } | ||
4515 | |||
4516 | IWL_DEBUG_HT("HW queue empty\n");; | ||
4517 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; | ||
4879 | 4518 | ||
4519 | spin_lock_irqsave(&priv->lock, flags); | ||
4520 | rc = iwl4965_grab_nic_access(priv); | ||
4521 | if (rc) { | ||
4522 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4523 | return rc; | ||
4524 | } | ||
4880 | rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id); | 4525 | rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id); |
4881 | /* FIXME: need more safe way to handle error condition */ | 4526 | iwl4965_release_nic_access(priv); |
4527 | spin_unlock_irqrestore(&priv->lock, flags); | ||
4528 | |||
4882 | if (rc) | 4529 | if (rc) |
4883 | return rc; | 4530 | return rc; |
4884 | 4531 | ||
4885 | iwl4965_ba_status(priv, tid, BA_STATUS_INITIATOR_DELBA); | 4532 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid); |
4533 | |||
4886 | IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n", | 4534 | IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n", |
4887 | print_mac(mac, da), tid); | 4535 | print_mac(mac, da), tid); |
4888 | 4536 | ||
4889 | return 0; | 4537 | return 0; |
4890 | } | 4538 | } |
4891 | 4539 | ||
4540 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | ||
4541 | enum ieee80211_ampdu_mlme_action action, | ||
4542 | const u8 *addr, u16 tid, u16 *ssn) | ||
4543 | { | ||
4544 | struct iwl4965_priv *priv = hw->priv; | ||
4545 | int sta_id; | ||
4546 | DECLARE_MAC_BUF(mac); | ||
4547 | |||
4548 | IWL_DEBUG_HT("A-MPDU action on da=%s tid=%d ", | ||
4549 | print_mac(mac, addr), tid); | ||
4550 | sta_id = iwl4965_hw_find_station(priv, addr); | ||
4551 | switch (action) { | ||
4552 | case IEEE80211_AMPDU_RX_START: | ||
4553 | IWL_DEBUG_HT("start Rx\n"); | ||
4554 | iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, *ssn); | ||
4555 | break; | ||
4556 | case IEEE80211_AMPDU_RX_STOP: | ||
4557 | IWL_DEBUG_HT("stop Rx\n"); | ||
4558 | iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); | ||
4559 | break; | ||
4560 | case IEEE80211_AMPDU_TX_START: | ||
4561 | IWL_DEBUG_HT("start Tx\n"); | ||
4562 | return iwl4965_mac_ht_tx_agg_start(hw, addr, tid, ssn); | ||
4563 | case IEEE80211_AMPDU_TX_STOP: | ||
4564 | IWL_DEBUG_HT("stop Tx\n"); | ||
4565 | return iwl4965_mac_ht_tx_agg_stop(hw, addr, tid); | ||
4566 | default: | ||
4567 | IWL_DEBUG_HT("unknown\n"); | ||
4568 | return -EINVAL; | ||
4569 | break; | ||
4570 | } | ||
4571 | return 0; | ||
4572 | } | ||
4892 | 4573 | ||
4893 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4894 | #endif /* CONFIG_IWL4965_HT */ | 4574 | #endif /* CONFIG_IWL4965_HT */ |
4895 | 4575 | ||
4896 | /* Set up 4965-specific Rx frame reply handlers */ | 4576 | /* Set up 4965-specific Rx frame reply handlers */ |
@@ -4907,9 +4587,7 @@ void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv) | |||
4907 | iwl4965_rx_missed_beacon_notif; | 4587 | iwl4965_rx_missed_beacon_notif; |
4908 | 4588 | ||
4909 | #ifdef CONFIG_IWL4965_HT | 4589 | #ifdef CONFIG_IWL4965_HT |
4910 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4911 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; | 4590 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; |
4912 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4913 | #endif /* CONFIG_IWL4965_HT */ | 4591 | #endif /* CONFIG_IWL4965_HT */ |
4914 | } | 4592 | } |
4915 | 4593 | ||
@@ -4920,11 +4598,6 @@ void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv) | |||
4920 | #ifdef CONFIG_IWL4965_SENSITIVITY | 4598 | #ifdef CONFIG_IWL4965_SENSITIVITY |
4921 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); | 4599 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); |
4922 | #endif | 4600 | #endif |
4923 | #ifdef CONFIG_IWL4965_HT | ||
4924 | #ifdef CONFIG_IWL4965_HT_AGG | ||
4925 | INIT_WORK(&priv->agg_work, iwl4965_bg_agg_work); | ||
4926 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
4927 | #endif /* CONFIG_IWL4965_HT */ | ||
4928 | init_timer(&priv->statistics_periodic); | 4601 | init_timer(&priv->statistics_periodic); |
4929 | priv->statistics_periodic.data = (unsigned long)priv; | 4602 | priv->statistics_periodic.data = (unsigned long)priv; |
4930 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | 4603 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 9cb82be0ff80..ce17e4fec838 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -206,7 +206,7 @@ struct iwl4965_channel_info { | |||
206 | 206 | ||
207 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ | 207 | u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ |
208 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | 208 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ |
209 | u8 phymode; /* MODE_IEEE80211{A,B,G} */ | 209 | enum ieee80211_band band; |
210 | 210 | ||
211 | /* Radio/DSP gain settings for each "normal" data Tx rate. | 211 | /* Radio/DSP gain settings for each "normal" data Tx rate. |
212 | * These include, in addition to RF and DSP gain, a few fields for | 212 | * These include, in addition to RF and DSP gain, a few fields for |
@@ -433,7 +433,6 @@ struct iwl4965_rx_queue { | |||
433 | #define IWL_INVALID_VALUE -1 | 433 | #define IWL_INVALID_VALUE -1 |
434 | 434 | ||
435 | #ifdef CONFIG_IWL4965_HT | 435 | #ifdef CONFIG_IWL4965_HT |
436 | #ifdef CONFIG_IWL4965_HT_AGG | ||
437 | /** | 436 | /** |
438 | * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack | 437 | * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack |
439 | * @txq_id: Tx queue used for Tx attempt | 438 | * @txq_id: Tx queue used for Tx attempt |
@@ -453,19 +452,22 @@ struct iwl4965_ht_agg { | |||
453 | u16 frame_count; | 452 | u16 frame_count; |
454 | u16 wait_for_ba; | 453 | u16 wait_for_ba; |
455 | u16 start_idx; | 454 | u16 start_idx; |
456 | u32 bitmap0; | 455 | u64 bitmap; |
457 | u32 bitmap1; | ||
458 | u32 rate_n_flags; | 456 | u32 rate_n_flags; |
457 | #define IWL_AGG_OFF 0 | ||
458 | #define IWL_AGG_ON 1 | ||
459 | #define IWL_EMPTYING_HW_QUEUE_ADDBA 2 | ||
460 | #define IWL_EMPTYING_HW_QUEUE_DELBA 3 | ||
461 | u8 state; | ||
459 | }; | 462 | }; |
460 | #endif /* CONFIG_IWL4965_HT_AGG */ | 463 | |
461 | #endif /* CONFIG_IWL4965_HT */ | 464 | #endif /* CONFIG_IWL4965_HT */ |
462 | 465 | ||
463 | struct iwl4965_tid_data { | 466 | struct iwl4965_tid_data { |
464 | u16 seq_number; | 467 | u16 seq_number; |
468 | u16 tfds_in_queue; | ||
465 | #ifdef CONFIG_IWL4965_HT | 469 | #ifdef CONFIG_IWL4965_HT |
466 | #ifdef CONFIG_IWL4965_HT_AGG | ||
467 | struct iwl4965_ht_agg agg; | 470 | struct iwl4965_ht_agg agg; |
468 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
469 | #endif /* CONFIG_IWL4965_HT */ | 471 | #endif /* CONFIG_IWL4965_HT */ |
470 | }; | 472 | }; |
471 | 473 | ||
@@ -508,8 +510,6 @@ struct iwl_ht_info { | |||
508 | }; | 510 | }; |
509 | #endif /*CONFIG_IWL4965_HT */ | 511 | #endif /*CONFIG_IWL4965_HT */ |
510 | 512 | ||
511 | #ifdef CONFIG_IWL4965_QOS | ||
512 | |||
513 | union iwl4965_qos_capabity { | 513 | union iwl4965_qos_capabity { |
514 | struct { | 514 | struct { |
515 | u8 edca_count:4; /* bit 0-3 */ | 515 | u8 edca_count:4; /* bit 0-3 */ |
@@ -537,7 +537,6 @@ struct iwl4965_qos_info { | |||
537 | union iwl4965_qos_capabity qos_cap; | 537 | union iwl4965_qos_capabity qos_cap; |
538 | struct iwl4965_qosparam_cmd def_qos_parm; | 538 | struct iwl4965_qosparam_cmd def_qos_parm; |
539 | }; | 539 | }; |
540 | #endif /*CONFIG_IWL4965_QOS */ | ||
541 | 540 | ||
542 | #define STA_PS_STATUS_WAKE 0 | 541 | #define STA_PS_STATUS_WAKE 0 |
543 | #define STA_PS_STATUS_SLEEP 1 | 542 | #define STA_PS_STATUS_SLEEP 1 |
@@ -581,8 +580,8 @@ struct iwl4965_ibss_seq { | |||
581 | /** | 580 | /** |
582 | * struct iwl4965_driver_hw_info | 581 | * struct iwl4965_driver_hw_info |
583 | * @max_txq_num: Max # Tx queues supported | 582 | * @max_txq_num: Max # Tx queues supported |
584 | * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) | ||
585 | * @tx_cmd_len: Size of Tx command (but not including frame itself) | 583 | * @tx_cmd_len: Size of Tx command (but not including frame itself) |
584 | * @tx_ant_num: Number of TX antennas | ||
586 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) | 585 | * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) |
587 | * @rx_buffer_size: | 586 | * @rx_buffer_size: |
588 | * @max_rxq_log: Log-base-2 of max_rxq_size | 587 | * @max_rxq_log: Log-base-2 of max_rxq_size |
@@ -593,8 +592,8 @@ struct iwl4965_ibss_seq { | |||
593 | */ | 592 | */ |
594 | struct iwl4965_driver_hw_info { | 593 | struct iwl4965_driver_hw_info { |
595 | u16 max_txq_num; | 594 | u16 max_txq_num; |
596 | u16 ac_queue_count; | ||
597 | u16 tx_cmd_len; | 595 | u16 tx_cmd_len; |
596 | u16 tx_ant_num; | ||
598 | u16 max_rxq_size; | 597 | u16 max_rxq_size; |
599 | u32 rx_buf_size; | 598 | u32 rx_buf_size; |
600 | u32 max_pkt_size; | 599 | u32 max_pkt_size; |
@@ -743,7 +742,7 @@ extern u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *bssid); | |||
743 | 742 | ||
744 | extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel); | 743 | extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel); |
745 | extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index); | 744 | extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index); |
746 | 745 | extern int iwl4965_queue_space(const struct iwl4965_queue *q); | |
747 | struct iwl4965_priv; | 746 | struct iwl4965_priv; |
748 | 747 | ||
749 | /* | 748 | /* |
@@ -762,31 +761,29 @@ extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); | |||
762 | extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); | 761 | extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); |
763 | extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, | 762 | extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, |
764 | u8 force); | 763 | u8 force); |
765 | extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, | 764 | extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, |
765 | enum ieee80211_band band, | ||
766 | u16 channel, | 766 | u16 channel, |
767 | const struct iwl4965_eeprom_channel *eeprom_ch, | 767 | const struct iwl4965_eeprom_channel *eeprom_ch, |
768 | u8 fat_extension_channel); | 768 | u8 fat_extension_channel); |
769 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); | 769 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); |
770 | 770 | ||
771 | #ifdef CONFIG_IWL4965_HT | 771 | #ifdef CONFIG_IWL4965_HT |
772 | extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, | 772 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
773 | int mode); | 773 | enum ieee80211_band band); |
774 | extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, | 774 | void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, |
775 | struct iwl_ht_info *ht_info); | 775 | struct iwl_ht_info *ht_info); |
776 | extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, | 776 | void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, |
777 | struct ieee80211_ht_info *sta_ht_inf); | 777 | struct ieee80211_ht_info *sta_ht_inf); |
778 | extern int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 778 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
779 | enum ieee80211_ampdu_mlme_action action, | 779 | enum ieee80211_ampdu_mlme_action action, |
780 | const u8 *addr, u16 tid, u16 ssn); | 780 | const u8 *addr, u16 tid, u16 *ssn); |
781 | #ifdef CONFIG_IWL4965_HT_AGG | 781 | int iwl4965_check_empty_hw_queue(struct iwl4965_priv *priv, int sta_id, |
782 | extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, | 782 | u8 tid, int txq_id); |
783 | u16 tid, u16 *start_seq_num); | 783 | #else |
784 | extern int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, | 784 | static inline void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
785 | u16 tid, int generator); | 785 | enum ieee80211_band band) {} |
786 | extern void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid); | 786 | |
787 | extern void iwl4965_tl_get_stats(struct iwl4965_priv *priv, | ||
788 | struct ieee80211_hdr *hdr); | ||
789 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
790 | #endif /*CONFIG_IWL4965_HT */ | 787 | #endif /*CONFIG_IWL4965_HT */ |
791 | /* Structures, enum, and defines specific to the 4965 */ | 788 | /* Structures, enum, and defines specific to the 4965 */ |
792 | 789 | ||
@@ -798,18 +795,6 @@ struct iwl4965_kw { | |||
798 | size_t size; | 795 | size_t size; |
799 | }; | 796 | }; |
800 | 797 | ||
801 | #define TID_QUEUE_CELL_SPACING 50 /*mS */ | ||
802 | #define TID_QUEUE_MAX_SIZE 20 | ||
803 | #define TID_ROUND_VALUE 5 /* mS */ | ||
804 | #define TID_MAX_LOAD_COUNT 8 | ||
805 | |||
806 | #define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING) | ||
807 | #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) | ||
808 | |||
809 | #define TID_ALL_ENABLED 0x7f | ||
810 | #define TID_ALL_SPECIFIED 0xff | ||
811 | #define TID_AGG_TPT_THREHOLD 0x0 | ||
812 | |||
813 | #define IWL_CHANNEL_WIDTH_20MHZ 0 | 798 | #define IWL_CHANNEL_WIDTH_20MHZ 0 |
814 | #define IWL_CHANNEL_WIDTH_40MHZ 1 | 799 | #define IWL_CHANNEL_WIDTH_40MHZ 1 |
815 | 800 | ||
@@ -834,37 +819,7 @@ struct iwl4965_kw { | |||
834 | 819 | ||
835 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 | 820 | #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 |
836 | 821 | ||
837 | struct iwl4965_traffic_load { | ||
838 | unsigned long time_stamp; | ||
839 | u32 packet_count[TID_QUEUE_MAX_SIZE]; | ||
840 | u8 queue_count; | ||
841 | u8 head; | ||
842 | u32 total; | ||
843 | }; | ||
844 | |||
845 | #ifdef CONFIG_IWL4965_HT_AGG | ||
846 | /** | ||
847 | * struct iwl4965_agg_control | ||
848 | * @requested_ba: bit map of tids requesting aggregation/block-ack | ||
849 | * @granted_ba: bit map of tids granted aggregation/block-ack | ||
850 | */ | ||
851 | struct iwl4965_agg_control { | ||
852 | unsigned long next_retry; | ||
853 | u32 wait_for_agg_status; | ||
854 | u32 tid_retry; | ||
855 | u32 requested_ba; | ||
856 | u32 granted_ba; | ||
857 | u8 auto_agg; | ||
858 | u32 tid_traffic_load_threshold; | ||
859 | u32 ba_timeout; | ||
860 | struct iwl4965_traffic_load traffic_load[TID_MAX_LOAD_COUNT]; | ||
861 | }; | ||
862 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
863 | |||
864 | struct iwl4965_lq_mngr { | 822 | struct iwl4965_lq_mngr { |
865 | #ifdef CONFIG_IWL4965_HT_AGG | ||
866 | struct iwl4965_agg_control agg_ctrl; | ||
867 | #endif | ||
868 | spinlock_t lock; | 823 | spinlock_t lock; |
869 | s32 max_window_size; | 824 | s32 max_window_size; |
870 | s32 *expected_tpt; | 825 | s32 *expected_tpt; |
@@ -877,7 +832,6 @@ struct iwl4965_lq_mngr { | |||
877 | u8 lq_ready; | 832 | u8 lq_ready; |
878 | }; | 833 | }; |
879 | 834 | ||
880 | |||
881 | /* Sensitivity and chain noise calibration */ | 835 | /* Sensitivity and chain noise calibration */ |
882 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) | 836 | #define INTERFERENCE_DATA_AVAILABLE __constant_cpu_to_le32(1) |
883 | #define INITIALIZATION_VALUE 0xFFFF | 837 | #define INITIALIZATION_VALUE 0xFFFF |
@@ -1025,14 +979,14 @@ struct iwl4965_priv { | |||
1025 | struct list_head free_frames; | 979 | struct list_head free_frames; |
1026 | int frames_count; | 980 | int frames_count; |
1027 | 981 | ||
1028 | u8 phymode; | 982 | enum ieee80211_band band; |
1029 | int alloc_rxb_skb; | 983 | int alloc_rxb_skb; |
1030 | bool add_radiotap; | 984 | bool add_radiotap; |
1031 | 985 | ||
1032 | void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, | 986 | void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, |
1033 | struct iwl4965_rx_mem_buffer *rxb); | 987 | struct iwl4965_rx_mem_buffer *rxb); |
1034 | 988 | ||
1035 | const struct ieee80211_hw_mode *modes; | 989 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
1036 | 990 | ||
1037 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 991 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
1038 | /* spectrum measurement report caching */ | 992 | /* spectrum measurement report caching */ |
@@ -1216,9 +1170,7 @@ struct iwl4965_priv { | |||
1216 | u16 assoc_capability; | 1170 | u16 assoc_capability; |
1217 | u8 ps_mode; | 1171 | u8 ps_mode; |
1218 | 1172 | ||
1219 | #ifdef CONFIG_IWL4965_QOS | ||
1220 | struct iwl4965_qos_info qos_data; | 1173 | struct iwl4965_qos_info qos_data; |
1221 | #endif /*CONFIG_IWL4965_QOS */ | ||
1222 | 1174 | ||
1223 | struct workqueue_struct *workqueue; | 1175 | struct workqueue_struct *workqueue; |
1224 | 1176 | ||
@@ -1265,11 +1217,7 @@ struct iwl4965_priv { | |||
1265 | #endif | 1217 | #endif |
1266 | struct work_struct statistics_work; | 1218 | struct work_struct statistics_work; |
1267 | struct timer_list statistics_periodic; | 1219 | struct timer_list statistics_periodic; |
1268 | 1220 | }; /*iwl4965_priv */ | |
1269 | #ifdef CONFIG_IWL4965_HT_AGG | ||
1270 | struct work_struct agg_work; | ||
1271 | #endif | ||
1272 | }; /*iwl4965_priv */ | ||
1273 | 1221 | ||
1274 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) | 1222 | static inline int iwl4965_is_associated(struct iwl4965_priv *priv) |
1275 | { | 1223 | { |
@@ -1295,13 +1243,12 @@ static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info) | |||
1295 | 1243 | ||
1296 | static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) | 1244 | static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) |
1297 | { | 1245 | { |
1298 | return ch_info->phymode == MODE_IEEE80211A; | 1246 | return ch_info->band == IEEE80211_BAND_5GHZ; |
1299 | } | 1247 | } |
1300 | 1248 | ||
1301 | static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) | 1249 | static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) |
1302 | { | 1250 | { |
1303 | return ((ch_info->phymode == MODE_IEEE80211B) || | 1251 | return ch_info->band == IEEE80211_BAND_2GHZ; |
1304 | (ch_info->phymode == MODE_IEEE80211G)); | ||
1305 | } | 1252 | } |
1306 | 1253 | ||
1307 | static inline int is_channel_passive(const struct iwl4965_channel_info *ch) | 1254 | static inline int is_channel_passive(const struct iwl4965_channel_info *ch) |
@@ -1315,7 +1262,7 @@ static inline int is_channel_ibss(const struct iwl4965_channel_info *ch) | |||
1315 | } | 1262 | } |
1316 | 1263 | ||
1317 | extern const struct iwl4965_channel_info *iwl4965_get_channel_info( | 1264 | extern const struct iwl4965_channel_info *iwl4965_get_channel_info( |
1318 | const struct iwl4965_priv *priv, int phymode, u16 channel); | 1265 | const struct iwl4965_priv *priv, enum ieee80211_band band, u16 channel); |
1319 | 1266 | ||
1320 | /* Requires full declaration of iwl4965_priv before including */ | 1267 | /* Requires full declaration of iwl4965_priv before including */ |
1321 | #include "iwl-4965-io.h" | 1268 | #include "iwl-4965-io.h" |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 40b71bc2c4a4..0fab832ce8c2 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -91,7 +91,7 @@ int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ | |||
91 | #define VS | 91 | #define VS |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | #define IWLWIFI_VERSION "1.2.23k" VD VS | 94 | #define IWLWIFI_VERSION "1.2.26k" VD VS |
95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" | 95 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" |
96 | #define DRV_VERSION IWLWIFI_VERSION | 96 | #define DRV_VERSION IWLWIFI_VERSION |
97 | 97 | ||
@@ -116,16 +116,10 @@ static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
116 | return NULL; | 116 | return NULL; |
117 | } | 117 | } |
118 | 118 | ||
119 | static const struct ieee80211_hw_mode *iwl3945_get_hw_mode( | 119 | static const struct ieee80211_supported_band *iwl3945_get_band( |
120 | struct iwl3945_priv *priv, int mode) | 120 | struct iwl3945_priv *priv, enum ieee80211_band band) |
121 | { | 121 | { |
122 | int i; | 122 | return priv->hw->wiphy->bands[band]; |
123 | |||
124 | for (i = 0; i < 3; i++) | ||
125 | if (priv->modes[i].mode == mode) | ||
126 | return &priv->modes[i]; | ||
127 | |||
128 | return NULL; | ||
129 | } | 123 | } |
130 | 124 | ||
131 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) | 125 | static int iwl3945_is_empty_essid(const char *essid, int essid_len) |
@@ -547,7 +541,7 @@ u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 | |||
547 | station->sta.sta.sta_id = index; | 541 | station->sta.sta.sta_id = index; |
548 | station->sta.station_flags = 0; | 542 | station->sta.station_flags = 0; |
549 | 543 | ||
550 | if (priv->phymode == MODE_IEEE80211A) | 544 | if (priv->band == IEEE80211_BAND_5GHZ) |
551 | rate = IWL_RATE_6M_PLCP; | 545 | rate = IWL_RATE_6M_PLCP; |
552 | else | 546 | else |
553 | rate = IWL_RATE_1M_PLCP; | 547 | rate = IWL_RATE_1M_PLCP; |
@@ -894,35 +888,37 @@ int iwl3945_send_statistics_request(struct iwl3945_priv *priv) | |||
894 | 888 | ||
895 | /** | 889 | /** |
896 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON | 890 | * iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON |
897 | * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz | 891 | * @band: 2.4 or 5 GHz band |
898 | * @channel: Any channel valid for the requested phymode | 892 | * @channel: Any channel valid for the requested band |
899 | 893 | ||
900 | * In addition to setting the staging RXON, priv->phymode is also set. | 894 | * In addition to setting the staging RXON, priv->band is also set. |
901 | * | 895 | * |
902 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 896 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
903 | * in the staging RXON flag structure based on the phymode | 897 | * in the staging RXON flag structure based on the band |
904 | */ | 898 | */ |
905 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel) | 899 | static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, |
900 | enum ieee80211_band band, | ||
901 | u16 channel) | ||
906 | { | 902 | { |
907 | if (!iwl3945_get_channel_info(priv, phymode, channel)) { | 903 | if (!iwl3945_get_channel_info(priv, band, channel)) { |
908 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 904 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
909 | channel, phymode); | 905 | channel, band); |
910 | return -EINVAL; | 906 | return -EINVAL; |
911 | } | 907 | } |
912 | 908 | ||
913 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 909 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
914 | (priv->phymode == phymode)) | 910 | (priv->band == band)) |
915 | return 0; | 911 | return 0; |
916 | 912 | ||
917 | priv->staging_rxon.channel = cpu_to_le16(channel); | 913 | priv->staging_rxon.channel = cpu_to_le16(channel); |
918 | if (phymode == MODE_IEEE80211A) | 914 | if (band == IEEE80211_BAND_5GHZ) |
919 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 915 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
920 | else | 916 | else |
921 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 917 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
922 | 918 | ||
923 | priv->phymode = phymode; | 919 | priv->band = band; |
924 | 920 | ||
925 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 921 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
926 | 922 | ||
927 | return 0; | 923 | return 0; |
928 | } | 924 | } |
@@ -1210,8 +1206,7 @@ static int iwl3945_commit_rxon(struct iwl3945_priv *priv) | |||
1210 | return -EIO; | 1206 | return -EIO; |
1211 | } | 1207 | } |
1212 | 1208 | ||
1213 | /* Init the hardware's rate fallback order based on the | 1209 | /* Init the hardware's rate fallback order based on the band */ |
1214 | * phymode */ | ||
1215 | rc = iwl3945_init_hw_rate_table(priv); | 1210 | rc = iwl3945_init_hw_rate_table(priv); |
1216 | if (rc) { | 1211 | if (rc) { |
1217 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); | 1212 | IWL_ERROR("Error setting HW rate table: %02X\n", rc); |
@@ -1915,7 +1910,6 @@ static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv, | |||
1915 | /* | 1910 | /* |
1916 | * QoS support | 1911 | * QoS support |
1917 | */ | 1912 | */ |
1918 | #ifdef CONFIG_IWL3945_QOS | ||
1919 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, | 1913 | static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, |
1920 | struct iwl3945_qosparam_cmd *qos) | 1914 | struct iwl3945_qosparam_cmd *qos) |
1921 | { | 1915 | { |
@@ -2044,7 +2038,6 @@ static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) | |||
2044 | } | 2038 | } |
2045 | } | 2039 | } |
2046 | 2040 | ||
2047 | #endif /* CONFIG_IWL3945_QOS */ | ||
2048 | /* | 2041 | /* |
2049 | * Power management (not Tx power!) functions | 2042 | * Power management (not Tx power!) functions |
2050 | */ | 2043 | */ |
@@ -2461,9 +2454,10 @@ static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) | |||
2461 | return 0; | 2454 | return 0; |
2462 | } | 2455 | } |
2463 | 2456 | ||
2464 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode) | 2457 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, |
2458 | enum ieee80211_band band) | ||
2465 | { | 2459 | { |
2466 | if (phymode == MODE_IEEE80211A) { | 2460 | if (band == IEEE80211_BAND_5GHZ) { |
2467 | priv->staging_rxon.flags &= | 2461 | priv->staging_rxon.flags &= |
2468 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2462 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2469 | | RXON_FLG_CCK_MSK); | 2463 | | RXON_FLG_CCK_MSK); |
@@ -2526,7 +2520,7 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2526 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2520 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2527 | #endif | 2521 | #endif |
2528 | 2522 | ||
2529 | ch_info = iwl3945_get_channel_info(priv, priv->phymode, | 2523 | ch_info = iwl3945_get_channel_info(priv, priv->band, |
2530 | le16_to_cpu(priv->staging_rxon.channel)); | 2524 | le16_to_cpu(priv->staging_rxon.channel)); |
2531 | 2525 | ||
2532 | if (!ch_info) | 2526 | if (!ch_info) |
@@ -2542,11 +2536,11 @@ static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) | |||
2542 | 2536 | ||
2543 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2537 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2544 | if (is_channel_a_band(ch_info)) | 2538 | if (is_channel_a_band(ch_info)) |
2545 | priv->phymode = MODE_IEEE80211A; | 2539 | priv->band = IEEE80211_BAND_5GHZ; |
2546 | else | 2540 | else |
2547 | priv->phymode = MODE_IEEE80211G; | 2541 | priv->band = IEEE80211_BAND_2GHZ; |
2548 | 2542 | ||
2549 | iwl3945_set_flags_for_phymode(priv, priv->phymode); | 2543 | iwl3945_set_flags_for_phymode(priv, priv->band); |
2550 | 2544 | ||
2551 | priv->staging_rxon.ofdm_basic_rates = | 2545 | priv->staging_rxon.ofdm_basic_rates = |
2552 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2546 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2560,7 +2554,7 @@ static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) | |||
2560 | const struct iwl3945_channel_info *ch_info; | 2554 | const struct iwl3945_channel_info *ch_info; |
2561 | 2555 | ||
2562 | ch_info = iwl3945_get_channel_info(priv, | 2556 | ch_info = iwl3945_get_channel_info(priv, |
2563 | priv->phymode, | 2557 | priv->band, |
2564 | le16_to_cpu(priv->staging_rxon.channel)); | 2558 | le16_to_cpu(priv->staging_rxon.channel)); |
2565 | 2559 | ||
2566 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2560 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2792,7 +2786,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, | |||
2792 | goto drop_unlock; | 2786 | goto drop_unlock; |
2793 | } | 2787 | } |
2794 | 2788 | ||
2795 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2789 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2796 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2790 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2797 | goto drop_unlock; | 2791 | goto drop_unlock; |
2798 | } | 2792 | } |
@@ -2992,12 +2986,12 @@ drop: | |||
2992 | 2986 | ||
2993 | static void iwl3945_set_rate(struct iwl3945_priv *priv) | 2987 | static void iwl3945_set_rate(struct iwl3945_priv *priv) |
2994 | { | 2988 | { |
2995 | const struct ieee80211_hw_mode *hw = NULL; | 2989 | const struct ieee80211_supported_band *sband = NULL; |
2996 | struct ieee80211_rate *rate; | 2990 | struct ieee80211_rate *rate; |
2997 | int i; | 2991 | int i; |
2998 | 2992 | ||
2999 | hw = iwl3945_get_hw_mode(priv, priv->phymode); | 2993 | sband = iwl3945_get_band(priv, priv->band); |
3000 | if (!hw) { | 2994 | if (!sband) { |
3001 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 2995 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3002 | return; | 2996 | return; |
3003 | } | 2997 | } |
@@ -3005,24 +2999,17 @@ static void iwl3945_set_rate(struct iwl3945_priv *priv) | |||
3005 | priv->active_rate = 0; | 2999 | priv->active_rate = 0; |
3006 | priv->active_rate_basic = 0; | 3000 | priv->active_rate_basic = 0; |
3007 | 3001 | ||
3008 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3002 | IWL_DEBUG_RATE("Setting rates for %s GHz\n", |
3009 | hw->mode == MODE_IEEE80211A ? | 3003 | sband->band == IEEE80211_BAND_2GHZ ? "2.4" : "5"); |
3010 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3004 | |
3011 | 3005 | for (i = 0; i < sband->n_bitrates; i++) { | |
3012 | for (i = 0; i < hw->num_rates; i++) { | 3006 | rate = &sband->bitrates[i]; |
3013 | rate = &(hw->rates[i]); | 3007 | if ((rate->hw_value < IWL_RATE_COUNT) && |
3014 | if ((rate->val < IWL_RATE_COUNT) && | 3008 | !(rate->flags & IEEE80211_CHAN_DISABLED)) { |
3015 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | 3009 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)\n", |
3016 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | 3010 | rate->hw_value, iwl3945_rates[rate->hw_value].plcp); |
3017 | rate->val, iwl3945_rates[rate->val].plcp, | 3011 | priv->active_rate |= (1 << rate->hw_value); |
3018 | (rate->flags & IEEE80211_RATE_BASIC) ? | 3012 | } |
3019 | "*" : ""); | ||
3020 | priv->active_rate |= (1 << rate->val); | ||
3021 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3022 | priv->active_rate_basic |= (1 << rate->val); | ||
3023 | } else | ||
3024 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3025 | rate->val, iwl3945_rates[rate->val].plcp); | ||
3026 | } | 3013 | } |
3027 | 3014 | ||
3028 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3015 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3436,8 +3423,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
3436 | tx_status->flags = | 3423 | tx_status->flags = |
3437 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3424 | iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3438 | 3425 | ||
3439 | tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate); | ||
3440 | |||
3441 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", | 3426 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", |
3442 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 3427 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
3443 | tx_resp->rate, tx_resp->failure_frame); | 3428 | tx_resp->rate, tx_resp->failure_frame); |
@@ -4792,7 +4777,7 @@ static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) | |||
4792 | /* Queue restart only if RF_KILL switch was set to "kill" | 4777 | /* Queue restart only if RF_KILL switch was set to "kill" |
4793 | * when we loaded driver, and is now set to "enable". | 4778 | * when we loaded driver, and is now set to "enable". |
4794 | * After we're Alive, RF_KILL gets handled by | 4779 | * After we're Alive, RF_KILL gets handled by |
4795 | * iwl_rx_card_state_notif() */ | 4780 | * iwl3945_rx_card_state_notif() */ |
4796 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 4781 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { |
4797 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 4782 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
4798 | queue_work(priv->workqueue, &priv->restart); | 4783 | queue_work(priv->workqueue, &priv->restart); |
@@ -5026,24 +5011,24 @@ static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int ban | |||
5026 | * Based on band and channel number. | 5011 | * Based on band and channel number. |
5027 | */ | 5012 | */ |
5028 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, | 5013 | const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, |
5029 | int phymode, u16 channel) | 5014 | enum ieee80211_band band, u16 channel) |
5030 | { | 5015 | { |
5031 | int i; | 5016 | int i; |
5032 | 5017 | ||
5033 | switch (phymode) { | 5018 | switch (band) { |
5034 | case MODE_IEEE80211A: | 5019 | case IEEE80211_BAND_5GHZ: |
5035 | for (i = 14; i < priv->channel_count; i++) { | 5020 | for (i = 14; i < priv->channel_count; i++) { |
5036 | if (priv->channel_info[i].channel == channel) | 5021 | if (priv->channel_info[i].channel == channel) |
5037 | return &priv->channel_info[i]; | 5022 | return &priv->channel_info[i]; |
5038 | } | 5023 | } |
5039 | break; | 5024 | break; |
5040 | 5025 | ||
5041 | case MODE_IEEE80211B: | 5026 | case IEEE80211_BAND_2GHZ: |
5042 | case MODE_IEEE80211G: | ||
5043 | if (channel >= 1 && channel <= 14) | 5027 | if (channel >= 1 && channel <= 14) |
5044 | return &priv->channel_info[channel - 1]; | 5028 | return &priv->channel_info[channel - 1]; |
5045 | break; | 5029 | break; |
5046 | 5030 | case IEEE80211_NUM_BANDS: | |
5031 | WARN_ON(1); | ||
5047 | } | 5032 | } |
5048 | 5033 | ||
5049 | return NULL; | 5034 | return NULL; |
@@ -5106,8 +5091,8 @@ static int iwl3945_init_channel_map(struct iwl3945_priv *priv) | |||
5106 | /* Loop through each band adding each of the channels */ | 5091 | /* Loop through each band adding each of the channels */ |
5107 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5092 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5108 | ch_info->channel = eeprom_ch_index[ch]; | 5093 | ch_info->channel = eeprom_ch_index[ch]; |
5109 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5094 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5110 | MODE_IEEE80211A; | 5095 | IEEE80211_BAND_5GHZ; |
5111 | 5096 | ||
5112 | /* permanently store EEPROM's channel regulatory flags | 5097 | /* permanently store EEPROM's channel regulatory flags |
5113 | * and max power in channel info database. */ | 5098 | * and max power in channel info database. */ |
@@ -5203,18 +5188,20 @@ static void iwl3945_free_channel_map(struct iwl3945_priv *priv) | |||
5203 | #define IWL_PASSIVE_DWELL_BASE (100) | 5188 | #define IWL_PASSIVE_DWELL_BASE (100) |
5204 | #define IWL_CHANNEL_TUNE_TIME 5 | 5189 | #define IWL_CHANNEL_TUNE_TIME 5 |
5205 | 5190 | ||
5206 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode) | 5191 | static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, |
5192 | enum ieee80211_band band) | ||
5207 | { | 5193 | { |
5208 | if (phymode == MODE_IEEE80211A) | 5194 | if (band == IEEE80211_BAND_5GHZ) |
5209 | return IWL_ACTIVE_DWELL_TIME_52; | 5195 | return IWL_ACTIVE_DWELL_TIME_52; |
5210 | else | 5196 | else |
5211 | return IWL_ACTIVE_DWELL_TIME_24; | 5197 | return IWL_ACTIVE_DWELL_TIME_24; |
5212 | } | 5198 | } |
5213 | 5199 | ||
5214 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode) | 5200 | static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, |
5201 | enum ieee80211_band band) | ||
5215 | { | 5202 | { |
5216 | u16 active = iwl3945_get_active_dwell_time(priv, phymode); | 5203 | u16 active = iwl3945_get_active_dwell_time(priv, band); |
5217 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5204 | u16 passive = (band == IEEE80211_BAND_2GHZ) ? |
5218 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5205 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5219 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5206 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5220 | 5207 | ||
@@ -5234,28 +5221,29 @@ static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode | |||
5234 | return passive; | 5221 | return passive; |
5235 | } | 5222 | } |
5236 | 5223 | ||
5237 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | 5224 | static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, |
5225 | enum ieee80211_band band, | ||
5238 | u8 is_active, u8 direct_mask, | 5226 | u8 is_active, u8 direct_mask, |
5239 | struct iwl3945_scan_channel *scan_ch) | 5227 | struct iwl3945_scan_channel *scan_ch) |
5240 | { | 5228 | { |
5241 | const struct ieee80211_channel *channels = NULL; | 5229 | const struct ieee80211_channel *channels = NULL; |
5242 | const struct ieee80211_hw_mode *hw_mode; | 5230 | const struct ieee80211_supported_band *sband; |
5243 | const struct iwl3945_channel_info *ch_info; | 5231 | const struct iwl3945_channel_info *ch_info; |
5244 | u16 passive_dwell = 0; | 5232 | u16 passive_dwell = 0; |
5245 | u16 active_dwell = 0; | 5233 | u16 active_dwell = 0; |
5246 | int added, i; | 5234 | int added, i; |
5247 | 5235 | ||
5248 | hw_mode = iwl3945_get_hw_mode(priv, phymode); | 5236 | sband = iwl3945_get_band(priv, band); |
5249 | if (!hw_mode) | 5237 | if (!sband) |
5250 | return 0; | 5238 | return 0; |
5251 | 5239 | ||
5252 | channels = hw_mode->channels; | 5240 | channels = sband->channels; |
5253 | 5241 | ||
5254 | active_dwell = iwl3945_get_active_dwell_time(priv, phymode); | 5242 | active_dwell = iwl3945_get_active_dwell_time(priv, band); |
5255 | passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode); | 5243 | passive_dwell = iwl3945_get_passive_dwell_time(priv, band); |
5256 | 5244 | ||
5257 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5245 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5258 | if (channels[i].chan == | 5246 | if (channels[i].hw_value == |
5259 | le16_to_cpu(priv->active_rxon.channel)) { | 5247 | le16_to_cpu(priv->active_rxon.channel)) { |
5260 | if (iwl3945_is_associated(priv)) { | 5248 | if (iwl3945_is_associated(priv)) { |
5261 | IWL_DEBUG_SCAN | 5249 | IWL_DEBUG_SCAN |
@@ -5266,9 +5254,9 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5266 | } else if (priv->only_active_channel) | 5254 | } else if (priv->only_active_channel) |
5267 | continue; | 5255 | continue; |
5268 | 5256 | ||
5269 | scan_ch->channel = channels[i].chan; | 5257 | scan_ch->channel = channels[i].hw_value; |
5270 | 5258 | ||
5271 | ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel); | 5259 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
5272 | if (!is_channel_valid(ch_info)) { | 5260 | if (!is_channel_valid(ch_info)) { |
5273 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5261 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
5274 | scan_ch->channel); | 5262 | scan_ch->channel); |
@@ -5276,7 +5264,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5276 | } | 5264 | } |
5277 | 5265 | ||
5278 | if (!is_active || is_channel_passive(ch_info) || | 5266 | if (!is_active || is_channel_passive(ch_info) || |
5279 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5267 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5280 | scan_ch->type = 0; /* passive */ | 5268 | scan_ch->type = 0; /* passive */ |
5281 | else | 5269 | else |
5282 | scan_ch->type = 1; /* active */ | 5270 | scan_ch->type = 1; /* active */ |
@@ -5295,7 +5283,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5295 | /* scan_pwr_info->tpc.dsp_atten; */ | 5283 | /* scan_pwr_info->tpc.dsp_atten; */ |
5296 | 5284 | ||
5297 | /*scan_pwr_info->tpc.tx_gain; */ | 5285 | /*scan_pwr_info->tpc.tx_gain; */ |
5298 | if (phymode == MODE_IEEE80211A) | 5286 | if (band == IEEE80211_BAND_5GHZ) |
5299 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5287 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5300 | else { | 5288 | else { |
5301 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5289 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5319,41 +5307,23 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, | |||
5319 | return added; | 5307 | return added; |
5320 | } | 5308 | } |
5321 | 5309 | ||
5322 | static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv) | ||
5323 | { | ||
5324 | int i, j; | ||
5325 | for (i = 0; i < 3; i++) { | ||
5326 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5327 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5328 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5329 | } | ||
5330 | } | ||
5331 | |||
5332 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | 5310 | static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, |
5333 | struct ieee80211_rate *rates) | 5311 | struct ieee80211_rate *rates) |
5334 | { | 5312 | { |
5335 | int i; | 5313 | int i; |
5336 | 5314 | ||
5337 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5315 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5338 | rates[i].rate = iwl3945_rates[i].ieee * 5; | 5316 | rates[i].bitrate = iwl3945_rates[i].ieee * 5; |
5339 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5317 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5340 | rates[i].val2 = i; | 5318 | rates[i].hw_value_short = i; |
5341 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5319 | rates[i].flags = 0; |
5342 | /* Only OFDM have the bits-per-symbol set */ | 5320 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5343 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5344 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5345 | else { | ||
5346 | /* | 5321 | /* |
5347 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5322 | * If CCK != 1M then set short preamble rate flag. |
5348 | * which is CCK | PREAMBLE2 | ||
5349 | */ | 5323 | */ |
5350 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? | 5324 | rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? |
5351 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5325 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5352 | } | 5326 | } |
5353 | |||
5354 | /* Set up which ones are basic rates... */ | ||
5355 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5356 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5357 | } | 5327 | } |
5358 | } | 5328 | } |
5359 | 5329 | ||
@@ -5363,67 +5333,41 @@ static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, | |||
5363 | static int iwl3945_init_geos(struct iwl3945_priv *priv) | 5333 | static int iwl3945_init_geos(struct iwl3945_priv *priv) |
5364 | { | 5334 | { |
5365 | struct iwl3945_channel_info *ch; | 5335 | struct iwl3945_channel_info *ch; |
5366 | struct ieee80211_hw_mode *modes; | 5336 | struct ieee80211_supported_band *band; |
5367 | struct ieee80211_channel *channels; | 5337 | struct ieee80211_channel *channels; |
5368 | struct ieee80211_channel *geo_ch; | 5338 | struct ieee80211_channel *geo_ch; |
5369 | struct ieee80211_rate *rates; | 5339 | struct ieee80211_rate *rates; |
5370 | int i = 0; | 5340 | int i = 0; |
5371 | enum { | ||
5372 | A = 0, | ||
5373 | B = 1, | ||
5374 | G = 2, | ||
5375 | }; | ||
5376 | int mode_count = 3; | ||
5377 | 5341 | ||
5378 | if (priv->modes) { | 5342 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5343 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5379 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5344 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5380 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5345 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5381 | return 0; | 5346 | return 0; |
5382 | } | 5347 | } |
5383 | 5348 | ||
5384 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5385 | GFP_KERNEL); | ||
5386 | if (!modes) | ||
5387 | return -ENOMEM; | ||
5388 | |||
5389 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5349 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5390 | priv->channel_count, GFP_KERNEL); | 5350 | priv->channel_count, GFP_KERNEL); |
5391 | if (!channels) { | 5351 | if (!channels) |
5392 | kfree(modes); | ||
5393 | return -ENOMEM; | 5352 | return -ENOMEM; |
5394 | } | ||
5395 | 5353 | ||
5396 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5354 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5397 | GFP_KERNEL); | 5355 | GFP_KERNEL); |
5398 | if (!rates) { | 5356 | if (!rates) { |
5399 | kfree(modes); | ||
5400 | kfree(channels); | 5357 | kfree(channels); |
5401 | return -ENOMEM; | 5358 | return -ENOMEM; |
5402 | } | 5359 | } |
5403 | 5360 | ||
5404 | /* 0 = 802.11a | ||
5405 | * 1 = 802.11b | ||
5406 | * 2 = 802.11g | ||
5407 | */ | ||
5408 | |||
5409 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5361 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5410 | modes[A].mode = MODE_IEEE80211A; | 5362 | band = &priv->bands[IEEE80211_BAND_5GHZ]; |
5411 | modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; | 5363 | band->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; |
5412 | modes[A].rates = &rates[4]; | 5364 | band->bitrates = &rates[4]; |
5413 | modes[A].num_rates = 8; /* just OFDM */ | 5365 | band->n_bitrates = 8; /* just OFDM */ |
5414 | modes[A].num_channels = 0; | 5366 | |
5415 | 5367 | band = &priv->bands[IEEE80211_BAND_2GHZ]; | |
5416 | modes[B].mode = MODE_IEEE80211B; | 5368 | band->channels = channels; |
5417 | modes[B].channels = channels; | 5369 | band->bitrates = rates; |
5418 | modes[B].rates = rates; | 5370 | band->n_bitrates = 12; /* OFDM & CCK */ |
5419 | modes[B].num_rates = 4; /* just CCK */ | ||
5420 | modes[B].num_channels = 0; | ||
5421 | |||
5422 | modes[G].mode = MODE_IEEE80211G; | ||
5423 | modes[G].channels = channels; | ||
5424 | modes[G].rates = rates; | ||
5425 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5426 | modes[G].num_channels = 0; | ||
5427 | 5371 | ||
5428 | priv->ieee_channels = channels; | 5372 | priv->ieee_channels = channels; |
5429 | priv->ieee_rates = rates; | 5373 | priv->ieee_rates = rates; |
@@ -5442,37 +5386,33 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5442 | } | 5386 | } |
5443 | 5387 | ||
5444 | if (is_channel_a_band(ch)) | 5388 | if (is_channel_a_band(ch)) |
5445 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5389 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5446 | else { | 5390 | else |
5447 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5391 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5448 | modes[G].num_channels++; | ||
5449 | } | ||
5450 | 5392 | ||
5451 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5393 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5452 | geo_ch->chan = ch->channel; | 5394 | geo_ch->max_power = ch->max_power_avg; |
5453 | geo_ch->power_level = ch->max_power_avg; | 5395 | geo_ch->max_antenna_gain = 0xff; |
5454 | geo_ch->antenna_max = 0xff; | 5396 | geo_ch->hw_value = ch->channel; |
5455 | 5397 | ||
5456 | if (is_channel_valid(ch)) { | 5398 | if (is_channel_valid(ch)) { |
5457 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5399 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5458 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5400 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5459 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5460 | 5401 | ||
5461 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5402 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5462 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5403 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5463 | 5404 | ||
5464 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5405 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5465 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5406 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5466 | 5407 | ||
5467 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5408 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5468 | priv->max_channel_txpower_limit = | 5409 | priv->max_channel_txpower_limit = |
5469 | ch->max_power_avg; | 5410 | ch->max_power_avg; |
5470 | } | 5411 | } else |
5471 | 5412 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5472 | geo_ch->val = geo_ch->flag; | ||
5473 | } | 5413 | } |
5474 | 5414 | ||
5475 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5415 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5476 | printk(KERN_INFO DRV_NAME | 5416 | printk(KERN_INFO DRV_NAME |
5477 | ": Incorrectly detected BG card as ABG. Please send " | 5417 | ": Incorrectly detected BG card as ABG. Please send " |
5478 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5418 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5482,24 +5422,12 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5482 | 5422 | ||
5483 | printk(KERN_INFO DRV_NAME | 5423 | printk(KERN_INFO DRV_NAME |
5484 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5424 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5485 | modes[G].num_channels, modes[A].num_channels); | 5425 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5486 | 5426 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5487 | /* | ||
5488 | * NOTE: We register these in preference of order -- the | ||
5489 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5490 | * a phymode based on rates or AP capabilities but seems to | ||
5491 | * configure it purely on if the channel being configured | ||
5492 | * is supported by a mode -- and the first match is taken | ||
5493 | */ | ||
5494 | 5427 | ||
5495 | if (modes[G].num_channels) | 5428 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5496 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5429 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5497 | if (modes[B].num_channels) | ||
5498 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5499 | if (modes[A].num_channels) | ||
5500 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5501 | 5430 | ||
5502 | priv->modes = modes; | ||
5503 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5431 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5504 | 5432 | ||
5505 | return 0; | 5433 | return 0; |
@@ -5510,7 +5438,6 @@ static int iwl3945_init_geos(struct iwl3945_priv *priv) | |||
5510 | */ | 5438 | */ |
5511 | static void iwl3945_free_geos(struct iwl3945_priv *priv) | 5439 | static void iwl3945_free_geos(struct iwl3945_priv *priv) |
5512 | { | 5440 | { |
5513 | kfree(priv->modes); | ||
5514 | kfree(priv->ieee_channels); | 5441 | kfree(priv->ieee_channels); |
5515 | kfree(priv->ieee_rates); | 5442 | kfree(priv->ieee_rates); |
5516 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5443 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6519,7 +6446,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6519 | struct iwl3945_scan_cmd *scan; | 6446 | struct iwl3945_scan_cmd *scan; |
6520 | struct ieee80211_conf *conf = NULL; | 6447 | struct ieee80211_conf *conf = NULL; |
6521 | u8 direct_mask; | 6448 | u8 direct_mask; |
6522 | int phymode; | 6449 | enum ieee80211_band band; |
6523 | 6450 | ||
6524 | conf = ieee80211_get_hw_conf(priv->hw); | 6451 | conf = ieee80211_get_hw_conf(priv->hw); |
6525 | 6452 | ||
@@ -6651,13 +6578,13 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6651 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6578 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6652 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6579 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6653 | scan->good_CRC_th = 0; | 6580 | scan->good_CRC_th = 0; |
6654 | phymode = MODE_IEEE80211G; | 6581 | band = IEEE80211_BAND_2GHZ; |
6655 | break; | 6582 | break; |
6656 | 6583 | ||
6657 | case 1: | 6584 | case 1: |
6658 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6585 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6659 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6586 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6660 | phymode = MODE_IEEE80211A; | 6587 | band = IEEE80211_BAND_5GHZ; |
6661 | break; | 6588 | break; |
6662 | 6589 | ||
6663 | default: | 6590 | default: |
@@ -6680,7 +6607,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6680 | 6607 | ||
6681 | scan->channel_count = | 6608 | scan->channel_count = |
6682 | iwl3945_get_channels_for_scan( | 6609 | iwl3945_get_channels_for_scan( |
6683 | priv, phymode, 1, /* active */ | 6610 | priv, band, 1, /* active */ |
6684 | direct_mask, | 6611 | direct_mask, |
6685 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 6612 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
6686 | 6613 | ||
@@ -6825,7 +6752,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6825 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); | 6752 | iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); |
6826 | iwl3945_add_station(priv, priv->bssid, 0, 0); | 6753 | iwl3945_add_station(priv, priv->bssid, 0, 0); |
6827 | iwl3945_sync_sta(priv, IWL_STA_ID, | 6754 | iwl3945_sync_sta(priv, IWL_STA_ID, |
6828 | (priv->phymode == MODE_IEEE80211A)? | 6755 | (priv->band == IEEE80211_BAND_5GHZ) ? |
6829 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 6756 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
6830 | CMD_ASYNC); | 6757 | CMD_ASYNC); |
6831 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); | 6758 | iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); |
@@ -6841,9 +6768,8 @@ static void iwl3945_bg_post_associate(struct work_struct *data) | |||
6841 | 6768 | ||
6842 | iwl3945_sequence_reset(priv); | 6769 | iwl3945_sequence_reset(priv); |
6843 | 6770 | ||
6844 | #ifdef CONFIG_IWL3945_QOS | ||
6845 | iwl3945_activate_qos(priv, 0); | 6771 | iwl3945_activate_qos(priv, 0); |
6846 | #endif /* CONFIG_IWL3945_QOS */ | 6772 | |
6847 | /* we have just associated, don't start scan too early */ | 6773 | /* we have just associated, don't start scan too early */ |
6848 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 6774 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
6849 | mutex_unlock(&priv->mutex); | 6775 | mutex_unlock(&priv->mutex); |
@@ -7020,7 +6946,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7020 | } | 6946 | } |
7021 | 6947 | ||
7022 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 6948 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7023 | ctl->tx_rate); | 6949 | ctl->tx_rate->bitrate); |
7024 | 6950 | ||
7025 | if (iwl3945_tx_skb(priv, skb, ctl)) | 6951 | if (iwl3945_tx_skb(priv, skb, ctl)) |
7026 | dev_kfree_skb_any(skb); | 6952 | dev_kfree_skb_any(skb); |
@@ -7079,7 +7005,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7079 | int ret = 0; | 7005 | int ret = 0; |
7080 | 7006 | ||
7081 | mutex_lock(&priv->mutex); | 7007 | mutex_lock(&priv->mutex); |
7082 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7008 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7083 | 7009 | ||
7084 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7010 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7085 | 7011 | ||
@@ -7099,19 +7025,20 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7099 | 7025 | ||
7100 | spin_lock_irqsave(&priv->lock, flags); | 7026 | spin_lock_irqsave(&priv->lock, flags); |
7101 | 7027 | ||
7102 | ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel); | 7028 | ch_info = iwl3945_get_channel_info(priv, conf->channel->band, |
7029 | conf->channel->hw_value); | ||
7103 | if (!is_channel_valid(ch_info)) { | 7030 | if (!is_channel_valid(ch_info)) { |
7104 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | 7031 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", |
7105 | conf->channel, conf->phymode); | 7032 | conf->channel->hw_value, conf->channel->band); |
7106 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7033 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7107 | spin_unlock_irqrestore(&priv->lock, flags); | 7034 | spin_unlock_irqrestore(&priv->lock, flags); |
7108 | ret = -EINVAL; | 7035 | ret = -EINVAL; |
7109 | goto out; | 7036 | goto out; |
7110 | } | 7037 | } |
7111 | 7038 | ||
7112 | iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); | 7039 | iwl3945_set_rxon_channel(priv, conf->channel->band, conf->channel->hw_value); |
7113 | 7040 | ||
7114 | iwl3945_set_flags_for_phymode(priv, conf->phymode); | 7041 | iwl3945_set_flags_for_phymode(priv, conf->channel->band); |
7115 | 7042 | ||
7116 | /* The list of supported rates and rate mask can be different | 7043 | /* The list of supported rates and rate mask can be different |
7117 | * for each phymode; since the phymode may have changed, reset | 7044 | * for each phymode; since the phymode may have changed, reset |
@@ -7487,10 +7414,8 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7487 | const struct ieee80211_tx_queue_params *params) | 7414 | const struct ieee80211_tx_queue_params *params) |
7488 | { | 7415 | { |
7489 | struct iwl3945_priv *priv = hw->priv; | 7416 | struct iwl3945_priv *priv = hw->priv; |
7490 | #ifdef CONFIG_IWL3945_QOS | ||
7491 | unsigned long flags; | 7417 | unsigned long flags; |
7492 | int q; | 7418 | int q; |
7493 | #endif /* CONFIG_IWL3945_QOS */ | ||
7494 | 7419 | ||
7495 | IWL_DEBUG_MAC80211("enter\n"); | 7420 | IWL_DEBUG_MAC80211("enter\n"); |
7496 | 7421 | ||
@@ -7504,7 +7429,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7504 | return 0; | 7429 | return 0; |
7505 | } | 7430 | } |
7506 | 7431 | ||
7507 | #ifdef CONFIG_IWL3945_QOS | ||
7508 | if (!priv->qos_data.qos_enable) { | 7432 | if (!priv->qos_data.qos_enable) { |
7509 | priv->qos_data.qos_active = 0; | 7433 | priv->qos_data.qos_active = 0; |
7510 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); | 7434 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); |
@@ -7518,7 +7442,7 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7518 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | 7442 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); |
7519 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | 7443 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; |
7520 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | 7444 | priv->qos_data.def_qos_parm.ac[q].edca_txop = |
7521 | cpu_to_le16((params->burst_time * 100)); | 7445 | cpu_to_le16((params->txop * 32)); |
7522 | 7446 | ||
7523 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 7447 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
7524 | priv->qos_data.qos_active = 1; | 7448 | priv->qos_data.qos_active = 1; |
@@ -7533,8 +7457,6 @@ static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7533 | 7457 | ||
7534 | mutex_unlock(&priv->mutex); | 7458 | mutex_unlock(&priv->mutex); |
7535 | 7459 | ||
7536 | #endif /*CONFIG_IWL3945_QOS */ | ||
7537 | |||
7538 | IWL_DEBUG_MAC80211("leave\n"); | 7460 | IWL_DEBUG_MAC80211("leave\n"); |
7539 | return 0; | 7461 | return 0; |
7540 | } | 7462 | } |
@@ -7599,9 +7521,8 @@ static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) | |||
7599 | mutex_lock(&priv->mutex); | 7521 | mutex_lock(&priv->mutex); |
7600 | IWL_DEBUG_MAC80211("enter\n"); | 7522 | IWL_DEBUG_MAC80211("enter\n"); |
7601 | 7523 | ||
7602 | #ifdef CONFIG_IWL3945_QOS | ||
7603 | iwl3945_reset_qos(priv); | 7524 | iwl3945_reset_qos(priv); |
7604 | #endif | 7525 | |
7605 | cancel_delayed_work(&priv->post_associate); | 7526 | cancel_delayed_work(&priv->post_associate); |
7606 | 7527 | ||
7607 | spin_lock_irqsave(&priv->lock, flags); | 7528 | spin_lock_irqsave(&priv->lock, flags); |
@@ -7689,9 +7610,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
7689 | IWL_DEBUG_MAC80211("leave\n"); | 7610 | IWL_DEBUG_MAC80211("leave\n"); |
7690 | spin_unlock_irqrestore(&priv->lock, flags); | 7611 | spin_unlock_irqrestore(&priv->lock, flags); |
7691 | 7612 | ||
7692 | #ifdef CONFIG_IWL3945_QOS | ||
7693 | iwl3945_reset_qos(priv); | 7613 | iwl3945_reset_qos(priv); |
7694 | #endif | ||
7695 | 7614 | ||
7696 | queue_work(priv->workqueue, &priv->post_associate.work); | 7615 | queue_work(priv->workqueue, &priv->post_associate.work); |
7697 | 7616 | ||
@@ -7892,65 +7811,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
7892 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 7811 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
7893 | store_filter_flags); | 7812 | store_filter_flags); |
7894 | 7813 | ||
7895 | static ssize_t show_tune(struct device *d, | ||
7896 | struct device_attribute *attr, char *buf) | ||
7897 | { | ||
7898 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7899 | |||
7900 | return sprintf(buf, "0x%04X\n", | ||
7901 | (priv->phymode << 8) | | ||
7902 | le16_to_cpu(priv->active_rxon.channel)); | ||
7903 | } | ||
7904 | |||
7905 | static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode); | ||
7906 | |||
7907 | static ssize_t store_tune(struct device *d, | ||
7908 | struct device_attribute *attr, | ||
7909 | const char *buf, size_t count) | ||
7910 | { | ||
7911 | struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; | ||
7912 | char *p = (char *)buf; | ||
7913 | u16 tune = simple_strtoul(p, &p, 0); | ||
7914 | u8 phymode = (tune >> 8) & 0xff; | ||
7915 | u16 channel = tune & 0xff; | ||
7916 | |||
7917 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
7918 | |||
7919 | mutex_lock(&priv->mutex); | ||
7920 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
7921 | (priv->phymode != phymode)) { | ||
7922 | const struct iwl3945_channel_info *ch_info; | ||
7923 | |||
7924 | ch_info = iwl3945_get_channel_info(priv, phymode, channel); | ||
7925 | if (!ch_info) { | ||
7926 | IWL_WARNING("Requested invalid phymode/channel " | ||
7927 | "combination: %d %d\n", phymode, channel); | ||
7928 | mutex_unlock(&priv->mutex); | ||
7929 | return -EINVAL; | ||
7930 | } | ||
7931 | |||
7932 | /* Cancel any currently running scans... */ | ||
7933 | if (iwl3945_scan_cancel_timeout(priv, 100)) | ||
7934 | IWL_WARNING("Could not cancel scan.\n"); | ||
7935 | else { | ||
7936 | IWL_DEBUG_INFO("Committing phymode and " | ||
7937 | "rxon.channel = %d %d\n", | ||
7938 | phymode, channel); | ||
7939 | |||
7940 | iwl3945_set_rxon_channel(priv, phymode, channel); | ||
7941 | iwl3945_set_flags_for_phymode(priv, phymode); | ||
7942 | |||
7943 | iwl3945_set_rate(priv); | ||
7944 | iwl3945_commit_rxon(priv); | ||
7945 | } | ||
7946 | } | ||
7947 | mutex_unlock(&priv->mutex); | ||
7948 | |||
7949 | return count; | ||
7950 | } | ||
7951 | |||
7952 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
7953 | |||
7954 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT | 7814 | #ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT |
7955 | 7815 | ||
7956 | static ssize_t show_measurement(struct device *d, | 7816 | static ssize_t show_measurement(struct device *d, |
@@ -8165,73 +8025,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8165 | static ssize_t show_channels(struct device *d, | 8025 | static ssize_t show_channels(struct device *d, |
8166 | struct device_attribute *attr, char *buf) | 8026 | struct device_attribute *attr, char *buf) |
8167 | { | 8027 | { |
8168 | struct iwl3945_priv *priv = dev_get_drvdata(d); | 8028 | /* all this shit doesn't belong into sysfs anyway */ |
8169 | int len = 0, i; | 8029 | return 0; |
8170 | struct ieee80211_channel *channels = NULL; | ||
8171 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8172 | int count = 0; | ||
8173 | |||
8174 | if (!iwl3945_is_ready(priv)) | ||
8175 | return -EAGAIN; | ||
8176 | |||
8177 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G); | ||
8178 | if (!hw_mode) | ||
8179 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B); | ||
8180 | if (hw_mode) { | ||
8181 | channels = hw_mode->channels; | ||
8182 | count = hw_mode->num_channels; | ||
8183 | } | ||
8184 | |||
8185 | len += | ||
8186 | sprintf(&buf[len], | ||
8187 | "Displaying %d channels in 2.4GHz band " | ||
8188 | "(802.11bg):\n", count); | ||
8189 | |||
8190 | for (i = 0; i < count; i++) | ||
8191 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8192 | channels[i].chan, | ||
8193 | channels[i].power_level, | ||
8194 | channels[i]. | ||
8195 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8196 | " (IEEE 802.11h required)" : "", | ||
8197 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8198 | || (channels[i]. | ||
8199 | flag & | ||
8200 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8201 | ", IBSS", | ||
8202 | channels[i]. | ||
8203 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8204 | "active/passive" : "passive only"); | ||
8205 | |||
8206 | hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A); | ||
8207 | if (hw_mode) { | ||
8208 | channels = hw_mode->channels; | ||
8209 | count = hw_mode->num_channels; | ||
8210 | } else { | ||
8211 | channels = NULL; | ||
8212 | count = 0; | ||
8213 | } | ||
8214 | |||
8215 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8216 | "(802.11a):\n", count); | ||
8217 | |||
8218 | for (i = 0; i < count; i++) | ||
8219 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8220 | channels[i].chan, | ||
8221 | channels[i].power_level, | ||
8222 | channels[i]. | ||
8223 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8224 | " (IEEE 802.11h required)" : "", | ||
8225 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8226 | || (channels[i]. | ||
8227 | flag & | ||
8228 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8229 | ", IBSS", | ||
8230 | channels[i]. | ||
8231 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8232 | "active/passive" : "passive only"); | ||
8233 | |||
8234 | return len; | ||
8235 | } | 8030 | } |
8236 | 8031 | ||
8237 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8032 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8411,7 +8206,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { | |||
8411 | &dev_attr_statistics.attr, | 8206 | &dev_attr_statistics.attr, |
8412 | &dev_attr_status.attr, | 8207 | &dev_attr_status.attr, |
8413 | &dev_attr_temperature.attr, | 8208 | &dev_attr_temperature.attr, |
8414 | &dev_attr_tune.attr, | ||
8415 | &dev_attr_tx_power.attr, | 8209 | &dev_attr_tx_power.attr, |
8416 | 8210 | ||
8417 | NULL | 8211 | NULL |
@@ -8532,7 +8326,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8532 | priv->data_retry_limit = -1; | 8326 | priv->data_retry_limit = -1; |
8533 | priv->ieee_channels = NULL; | 8327 | priv->ieee_channels = NULL; |
8534 | priv->ieee_rates = NULL; | 8328 | priv->ieee_rates = NULL; |
8535 | priv->phymode = -1; | 8329 | priv->band = IEEE80211_BAND_2GHZ; |
8536 | 8330 | ||
8537 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8331 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
8538 | if (!err) | 8332 | if (!err) |
@@ -8604,7 +8398,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8604 | goto out_iounmap; | 8398 | goto out_iounmap; |
8605 | } | 8399 | } |
8606 | 8400 | ||
8607 | #ifdef CONFIG_IWL3945_QOS | ||
8608 | if (iwl3945_param_qos_enable) | 8401 | if (iwl3945_param_qos_enable) |
8609 | priv->qos_data.qos_enable = 1; | 8402 | priv->qos_data.qos_enable = 1; |
8610 | 8403 | ||
@@ -8612,9 +8405,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8612 | 8405 | ||
8613 | priv->qos_data.qos_active = 0; | 8406 | priv->qos_data.qos_active = 0; |
8614 | priv->qos_data.qos_cap.val = 0; | 8407 | priv->qos_data.qos_cap.val = 0; |
8615 | #endif /* CONFIG_IWL3945_QOS */ | ||
8616 | 8408 | ||
8617 | iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8409 | iwl3945_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
8618 | iwl3945_setup_deferred_work(priv); | 8410 | iwl3945_setup_deferred_work(priv); |
8619 | iwl3945_setup_rx_handlers(priv); | 8411 | iwl3945_setup_rx_handlers(priv); |
8620 | 8412 | ||
@@ -8665,7 +8457,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
8665 | IWL_ERROR("initializing geos failed: %d\n", err); | 8457 | IWL_ERROR("initializing geos failed: %d\n", err); |
8666 | goto out_free_channel_map; | 8458 | goto out_free_channel_map; |
8667 | } | 8459 | } |
8668 | iwl3945_reset_channel_flag(priv); | ||
8669 | 8460 | ||
8670 | iwl3945_rate_control_register(priv->hw); | 8461 | iwl3945_rate_control_register(priv->hw); |
8671 | err = ieee80211_register_hw(priv->hw); | 8462 | err = ieee80211_register_hw(priv->hw); |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index a23d4798653b..20d012d4f37e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -90,7 +90,7 @@ int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */ | |||
90 | #define VS | 90 | #define VS |
91 | #endif | 91 | #endif |
92 | 92 | ||
93 | #define IWLWIFI_VERSION "1.2.23k" VD VS | 93 | #define IWLWIFI_VERSION "1.2.26k" VD VS |
94 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" | 94 | #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" |
95 | #define DRV_VERSION IWLWIFI_VERSION | 95 | #define DRV_VERSION IWLWIFI_VERSION |
96 | 96 | ||
@@ -115,16 +115,10 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
115 | return NULL; | 115 | return NULL; |
116 | } | 116 | } |
117 | 117 | ||
118 | static const struct ieee80211_hw_mode *iwl4965_get_hw_mode( | 118 | static const struct ieee80211_supported_band *iwl4965_get_hw_mode( |
119 | struct iwl4965_priv *priv, int mode) | 119 | struct iwl4965_priv *priv, enum ieee80211_band band) |
120 | { | 120 | { |
121 | int i; | 121 | return priv->hw->wiphy->bands[band]; |
122 | |||
123 | for (i = 0; i < 3; i++) | ||
124 | if (priv->modes[i].mode == mode) | ||
125 | return &priv->modes[i]; | ||
126 | |||
127 | return NULL; | ||
128 | } | 122 | } |
129 | 123 | ||
130 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) | 124 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) |
@@ -205,7 +199,7 @@ static void iwl4965_print_hex_dump(int level, void *p, u32 len) | |||
205 | * See more detailed info in iwl-4965-hw.h. | 199 | * See more detailed info in iwl-4965-hw.h. |
206 | ***************************************************/ | 200 | ***************************************************/ |
207 | 201 | ||
208 | static int iwl4965_queue_space(const struct iwl4965_queue *q) | 202 | int iwl4965_queue_space(const struct iwl4965_queue *q) |
209 | { | 203 | { |
210 | int s = q->read_ptr - q->write_ptr; | 204 | int s = q->read_ptr - q->write_ptr; |
211 | 205 | ||
@@ -937,28 +931,29 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, | |||
937 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields | 931 | * NOTE: Does not commit to the hardware; it sets appropriate bit fields |
938 | * in the staging RXON flag structure based on the phymode | 932 | * in the staging RXON flag structure based on the phymode |
939 | */ | 933 | */ |
940 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode, | 934 | static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, |
935 | enum ieee80211_band band, | ||
941 | u16 channel) | 936 | u16 channel) |
942 | { | 937 | { |
943 | if (!iwl4965_get_channel_info(priv, phymode, channel)) { | 938 | if (!iwl4965_get_channel_info(priv, band, channel)) { |
944 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", | 939 | IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", |
945 | channel, phymode); | 940 | channel, band); |
946 | return -EINVAL; | 941 | return -EINVAL; |
947 | } | 942 | } |
948 | 943 | ||
949 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && | 944 | if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && |
950 | (priv->phymode == phymode)) | 945 | (priv->band == band)) |
951 | return 0; | 946 | return 0; |
952 | 947 | ||
953 | priv->staging_rxon.channel = cpu_to_le16(channel); | 948 | priv->staging_rxon.channel = cpu_to_le16(channel); |
954 | if (phymode == MODE_IEEE80211A) | 949 | if (band == IEEE80211_BAND_5GHZ) |
955 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; | 950 | priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; |
956 | else | 951 | else |
957 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; | 952 | priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; |
958 | 953 | ||
959 | priv->phymode = phymode; | 954 | priv->band = band; |
960 | 955 | ||
961 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode); | 956 | IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band); |
962 | 957 | ||
963 | return 0; | 958 | return 0; |
964 | } | 959 | } |
@@ -1898,24 +1893,20 @@ static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, | |||
1898 | return ret_rates; | 1893 | return ret_rates; |
1899 | } | 1894 | } |
1900 | 1895 | ||
1901 | #ifdef CONFIG_IWL4965_HT | ||
1902 | void static iwl4965_set_ht_capab(struct ieee80211_hw *hw, | ||
1903 | struct ieee80211_ht_cap *ht_cap, | ||
1904 | u8 use_current_config); | ||
1905 | #endif | ||
1906 | |||
1907 | /** | 1896 | /** |
1908 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request | 1897 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request |
1909 | */ | 1898 | */ |
1910 | static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | 1899 | static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, |
1911 | struct ieee80211_mgmt *frame, | 1900 | enum ieee80211_band band, |
1912 | int left, int is_direct) | 1901 | struct ieee80211_mgmt *frame, |
1902 | int left, int is_direct) | ||
1913 | { | 1903 | { |
1914 | int len = 0; | 1904 | int len = 0; |
1915 | u8 *pos = NULL; | 1905 | u8 *pos = NULL; |
1916 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | 1906 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; |
1917 | #ifdef CONFIG_IWL4965_HT | 1907 | #ifdef CONFIG_IWL4965_HT |
1918 | struct ieee80211_hw_mode *mode; | 1908 | const struct ieee80211_supported_band *sband = |
1909 | iwl4965_get_hw_mode(priv, band); | ||
1919 | #endif /* CONFIG_IWL4965_HT */ | 1910 | #endif /* CONFIG_IWL4965_HT */ |
1920 | 1911 | ||
1921 | /* Make sure there is enough space for the probe request, | 1912 | /* Make sure there is enough space for the probe request, |
@@ -2000,13 +1991,18 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | |||
2000 | len += 2 + *pos; | 1991 | len += 2 + *pos; |
2001 | 1992 | ||
2002 | #ifdef CONFIG_IWL4965_HT | 1993 | #ifdef CONFIG_IWL4965_HT |
2003 | mode = priv->hw->conf.mode; | 1994 | if (sband && sband->ht_info.ht_supported) { |
2004 | if (mode->ht_info.ht_supported) { | 1995 | struct ieee80211_ht_cap *ht_cap; |
2005 | pos += (*pos) + 1; | 1996 | pos += (*pos) + 1; |
2006 | *pos++ = WLAN_EID_HT_CAPABILITY; | 1997 | *pos++ = WLAN_EID_HT_CAPABILITY; |
2007 | *pos++ = sizeof(struct ieee80211_ht_cap); | 1998 | *pos++ = sizeof(struct ieee80211_ht_cap); |
2008 | iwl4965_set_ht_capab(priv->hw, | 1999 | ht_cap = (struct ieee80211_ht_cap *)pos; |
2009 | (struct ieee80211_ht_cap *)pos, 0); | 2000 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); |
2001 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
2002 | ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor & | ||
2003 | IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
2004 | ((sband->ht_info.ampdu_density << 2) & | ||
2005 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
2010 | len += 2 + sizeof(struct ieee80211_ht_cap); | 2006 | len += 2 + sizeof(struct ieee80211_ht_cap); |
2011 | } | 2007 | } |
2012 | #endif /*CONFIG_IWL4965_HT */ | 2008 | #endif /*CONFIG_IWL4965_HT */ |
@@ -2018,7 +2014,6 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, | |||
2018 | /* | 2014 | /* |
2019 | * QoS support | 2015 | * QoS support |
2020 | */ | 2016 | */ |
2021 | #ifdef CONFIG_IWL4965_QOS | ||
2022 | static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv, | 2017 | static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv, |
2023 | struct iwl4965_qosparam_cmd *qos) | 2018 | struct iwl4965_qosparam_cmd *qos) |
2024 | { | 2019 | { |
@@ -2152,7 +2147,6 @@ static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force) | |||
2152 | } | 2147 | } |
2153 | } | 2148 | } |
2154 | 2149 | ||
2155 | #endif /* CONFIG_IWL4965_QOS */ | ||
2156 | /* | 2150 | /* |
2157 | * Power management (not Tx power!) functions | 2151 | * Power management (not Tx power!) functions |
2158 | */ | 2152 | */ |
@@ -2571,9 +2565,10 @@ static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt) | |||
2571 | return 0; | 2565 | return 0; |
2572 | } | 2566 | } |
2573 | 2567 | ||
2574 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode) | 2568 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, |
2569 | enum ieee80211_band band) | ||
2575 | { | 2570 | { |
2576 | if (phymode == MODE_IEEE80211A) { | 2571 | if (band == IEEE80211_BAND_5GHZ) { |
2577 | priv->staging_rxon.flags &= | 2572 | priv->staging_rxon.flags &= |
2578 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | 2573 | ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
2579 | | RXON_FLG_CCK_MSK); | 2574 | | RXON_FLG_CCK_MSK); |
@@ -2636,7 +2631,7 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2636 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; | 2631 | priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; |
2637 | #endif | 2632 | #endif |
2638 | 2633 | ||
2639 | ch_info = iwl4965_get_channel_info(priv, priv->phymode, | 2634 | ch_info = iwl4965_get_channel_info(priv, priv->band, |
2640 | le16_to_cpu(priv->staging_rxon.channel)); | 2635 | le16_to_cpu(priv->staging_rxon.channel)); |
2641 | 2636 | ||
2642 | if (!ch_info) | 2637 | if (!ch_info) |
@@ -2651,12 +2646,9 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) | |||
2651 | ch_info = &priv->channel_info[0]; | 2646 | ch_info = &priv->channel_info[0]; |
2652 | 2647 | ||
2653 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); | 2648 | priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); |
2654 | if (is_channel_a_band(ch_info)) | 2649 | priv->band = ch_info->band; |
2655 | priv->phymode = MODE_IEEE80211A; | ||
2656 | else | ||
2657 | priv->phymode = MODE_IEEE80211G; | ||
2658 | 2650 | ||
2659 | iwl4965_set_flags_for_phymode(priv, priv->phymode); | 2651 | iwl4965_set_flags_for_phymode(priv, priv->band); |
2660 | 2652 | ||
2661 | priv->staging_rxon.ofdm_basic_rates = | 2653 | priv->staging_rxon.ofdm_basic_rates = |
2662 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 2654 | (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
@@ -2678,7 +2670,7 @@ static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode) | |||
2678 | const struct iwl4965_channel_info *ch_info; | 2670 | const struct iwl4965_channel_info *ch_info; |
2679 | 2671 | ||
2680 | ch_info = iwl4965_get_channel_info(priv, | 2672 | ch_info = iwl4965_get_channel_info(priv, |
2681 | priv->phymode, | 2673 | priv->band, |
2682 | le16_to_cpu(priv->staging_rxon.channel)); | 2674 | le16_to_cpu(priv->staging_rxon.channel)); |
2683 | 2675 | ||
2684 | if (!ch_info || !is_channel_ibss(ch_info)) { | 2676 | if (!ch_info || !is_channel_ibss(ch_info)) { |
@@ -2918,7 +2910,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2918 | goto drop_unlock; | 2910 | goto drop_unlock; |
2919 | } | 2911 | } |
2920 | 2912 | ||
2921 | if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) { | 2913 | if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) { |
2922 | IWL_ERROR("ERROR: No TX rate available.\n"); | 2914 | IWL_ERROR("ERROR: No TX rate available.\n"); |
2923 | goto drop_unlock; | 2915 | goto drop_unlock; |
2924 | } | 2916 | } |
@@ -2972,11 +2964,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
2972 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); | 2964 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); |
2973 | seq_number += 0x10; | 2965 | seq_number += 0x10; |
2974 | #ifdef CONFIG_IWL4965_HT | 2966 | #ifdef CONFIG_IWL4965_HT |
2975 | #ifdef CONFIG_IWL4965_HT_AGG | ||
2976 | /* aggregation is on for this <sta,tid> */ | 2967 | /* aggregation is on for this <sta,tid> */ |
2977 | if (ctl->flags & IEEE80211_TXCTL_HT_MPDU_AGG) | 2968 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) |
2978 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 2969 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
2979 | #endif /* CONFIG_IWL4965_HT_AGG */ | 2970 | priv->stations[sta_id].tid[tid].tfds_in_queue++; |
2980 | #endif /* CONFIG_IWL4965_HT */ | 2971 | #endif /* CONFIG_IWL4965_HT */ |
2981 | } | 2972 | } |
2982 | 2973 | ||
@@ -3076,14 +3067,6 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv, | |||
3076 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); | 3067 | out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys); |
3077 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); | 3068 | out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); |
3078 | 3069 | ||
3079 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3080 | #ifdef CONFIG_IWL4965_HT | ||
3081 | /* TODO: move this functionality to rate scaling */ | ||
3082 | iwl4965_tl_get_stats(priv, hdr); | ||
3083 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3084 | #endif /*CONFIG_IWL4965_HT */ | ||
3085 | |||
3086 | |||
3087 | if (!ieee80211_get_morefrag(hdr)) { | 3070 | if (!ieee80211_get_morefrag(hdr)) { |
3088 | txq->need_update = 1; | 3071 | txq->need_update = 1; |
3089 | if (qc) { | 3072 | if (qc) { |
@@ -3134,11 +3117,11 @@ drop: | |||
3134 | 3117 | ||
3135 | static void iwl4965_set_rate(struct iwl4965_priv *priv) | 3118 | static void iwl4965_set_rate(struct iwl4965_priv *priv) |
3136 | { | 3119 | { |
3137 | const struct ieee80211_hw_mode *hw = NULL; | 3120 | const struct ieee80211_supported_band *hw = NULL; |
3138 | struct ieee80211_rate *rate; | 3121 | struct ieee80211_rate *rate; |
3139 | int i; | 3122 | int i; |
3140 | 3123 | ||
3141 | hw = iwl4965_get_hw_mode(priv, priv->phymode); | 3124 | hw = iwl4965_get_hw_mode(priv, priv->band); |
3142 | if (!hw) { | 3125 | if (!hw) { |
3143 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 3126 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
3144 | return; | 3127 | return; |
@@ -3147,24 +3130,10 @@ static void iwl4965_set_rate(struct iwl4965_priv *priv) | |||
3147 | priv->active_rate = 0; | 3130 | priv->active_rate = 0; |
3148 | priv->active_rate_basic = 0; | 3131 | priv->active_rate_basic = 0; |
3149 | 3132 | ||
3150 | IWL_DEBUG_RATE("Setting rates for 802.11%c\n", | 3133 | for (i = 0; i < hw->n_bitrates; i++) { |
3151 | hw->mode == MODE_IEEE80211A ? | 3134 | rate = &(hw->bitrates[i]); |
3152 | 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g')); | 3135 | if (rate->hw_value < IWL_RATE_COUNT) |
3153 | 3136 | priv->active_rate |= (1 << rate->hw_value); | |
3154 | for (i = 0; i < hw->num_rates; i++) { | ||
3155 | rate = &(hw->rates[i]); | ||
3156 | if ((rate->val < IWL_RATE_COUNT) && | ||
3157 | (rate->flags & IEEE80211_RATE_SUPPORTED)) { | ||
3158 | IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", | ||
3159 | rate->val, iwl4965_rates[rate->val].plcp, | ||
3160 | (rate->flags & IEEE80211_RATE_BASIC) ? | ||
3161 | "*" : ""); | ||
3162 | priv->active_rate |= (1 << rate->val); | ||
3163 | if (rate->flags & IEEE80211_RATE_BASIC) | ||
3164 | priv->active_rate_basic |= (1 << rate->val); | ||
3165 | } else | ||
3166 | IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", | ||
3167 | rate->val, iwl4965_rates[rate->val].plcp); | ||
3168 | } | 3137 | } |
3169 | 3138 | ||
3170 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", | 3139 | IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", |
@@ -3528,10 +3497,10 @@ int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index) | |||
3528 | nfreed++; | 3497 | nfreed++; |
3529 | } | 3498 | } |
3530 | 3499 | ||
3531 | if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && | 3500 | /* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && |
3532 | (txq_id != IWL_CMD_QUEUE_NUM) && | 3501 | (txq_id != IWL_CMD_QUEUE_NUM) && |
3533 | priv->mac80211_registered) | 3502 | priv->mac80211_registered) |
3534 | ieee80211_wake_queue(priv->hw, txq_id); | 3503 | ieee80211_wake_queue(priv->hw, txq_id); */ |
3535 | 3504 | ||
3536 | 3505 | ||
3537 | return nfreed; | 3506 | return nfreed; |
@@ -3550,7 +3519,6 @@ static int iwl4965_is_tx_success(u32 status) | |||
3550 | * | 3519 | * |
3551 | ******************************************************************************/ | 3520 | ******************************************************************************/ |
3552 | #ifdef CONFIG_IWL4965_HT | 3521 | #ifdef CONFIG_IWL4965_HT |
3553 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3554 | 3522 | ||
3555 | static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv, | 3523 | static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv, |
3556 | struct ieee80211_hdr *hdr) | 3524 | struct ieee80211_hdr *hdr) |
@@ -3585,11 +3553,11 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | |||
3585 | */ | 3553 | */ |
3586 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | 3554 | static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, |
3587 | struct iwl4965_ht_agg *agg, | 3555 | struct iwl4965_ht_agg *agg, |
3588 | struct iwl4965_tx_resp *tx_resp, | 3556 | struct iwl4965_tx_resp_agg *tx_resp, |
3589 | u16 start_idx) | 3557 | u16 start_idx) |
3590 | { | 3558 | { |
3591 | u32 status; | 3559 | u16 status; |
3592 | __le32 *frame_status = &tx_resp->status; | 3560 | struct agg_tx_status *frame_status = &tx_resp->status; |
3593 | struct ieee80211_tx_status *tx_status = NULL; | 3561 | struct ieee80211_tx_status *tx_status = NULL; |
3594 | struct ieee80211_hdr *hdr = NULL; | 3562 | struct ieee80211_hdr *hdr = NULL; |
3595 | int i, sh; | 3563 | int i, sh; |
@@ -3602,30 +3570,30 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3602 | agg->frame_count = tx_resp->frame_count; | 3570 | agg->frame_count = tx_resp->frame_count; |
3603 | agg->start_idx = start_idx; | 3571 | agg->start_idx = start_idx; |
3604 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3572 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3605 | agg->bitmap0 = agg->bitmap1 = 0; | 3573 | agg->bitmap = 0; |
3606 | 3574 | ||
3607 | /* # frames attempted by Tx command */ | 3575 | /* # frames attempted by Tx command */ |
3608 | if (agg->frame_count == 1) { | 3576 | if (agg->frame_count == 1) { |
3609 | /* Only one frame was attempted; no block-ack will arrive */ | 3577 | /* Only one frame was attempted; no block-ack will arrive */ |
3610 | struct iwl4965_tx_queue *txq ; | 3578 | status = le16_to_cpu(frame_status[0].status); |
3611 | status = le32_to_cpu(frame_status[0]); | 3579 | seq = le16_to_cpu(frame_status[0].sequence); |
3580 | idx = SEQ_TO_INDEX(seq); | ||
3581 | txq_id = SEQ_TO_QUEUE(seq); | ||
3612 | 3582 | ||
3613 | txq_id = agg->txq_id; | ||
3614 | txq = &priv->txq[txq_id]; | ||
3615 | /* FIXME: code repetition */ | 3583 | /* FIXME: code repetition */ |
3616 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d \n", | 3584 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", |
3617 | agg->frame_count, agg->start_idx); | 3585 | agg->frame_count, agg->start_idx, idx); |
3618 | 3586 | ||
3619 | tx_status = &(priv->txq[txq_id].txb[txq->q.read_ptr].status); | 3587 | tx_status = &(priv->txq[txq_id].txb[idx].status); |
3620 | tx_status->retry_count = tx_resp->failure_frame; | 3588 | tx_status->retry_count = tx_resp->failure_frame; |
3621 | tx_status->queue_number = status & 0xff; | 3589 | tx_status->queue_number = status & 0xff; |
3622 | tx_status->queue_length = tx_resp->bt_kill_count; | 3590 | tx_status->queue_length = tx_resp->failure_rts; |
3623 | tx_status->queue_length |= tx_resp->failure_rts; | 3591 | tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; |
3624 | |||
3625 | tx_status->flags = iwl4965_is_tx_success(status)? | 3592 | tx_status->flags = iwl4965_is_tx_success(status)? |
3626 | IEEE80211_TX_STATUS_ACK : 0; | 3593 | IEEE80211_TX_STATUS_ACK : 0; |
3594 | /* FIXME Wrong Rate | ||
3627 | tx_status->control.tx_rate = | 3595 | tx_status->control.tx_rate = |
3628 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); | 3596 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); */ |
3629 | /* FIXME: code repetition end */ | 3597 | /* FIXME: code repetition end */ |
3630 | 3598 | ||
3631 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | 3599 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", |
@@ -3642,8 +3610,8 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3642 | /* Construct bit-map of pending frames within Tx window */ | 3610 | /* Construct bit-map of pending frames within Tx window */ |
3643 | for (i = 0; i < agg->frame_count; i++) { | 3611 | for (i = 0; i < agg->frame_count; i++) { |
3644 | u16 sc; | 3612 | u16 sc; |
3645 | status = le32_to_cpu(frame_status[i]); | 3613 | status = le16_to_cpu(frame_status[i].status); |
3646 | seq = status >> 16; | 3614 | seq = le16_to_cpu(frame_status[i].sequence); |
3647 | idx = SEQ_TO_INDEX(seq); | 3615 | idx = SEQ_TO_INDEX(seq); |
3648 | txq_id = SEQ_TO_QUEUE(seq); | 3616 | txq_id = SEQ_TO_QUEUE(seq); |
3649 | 3617 | ||
@@ -3687,13 +3655,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3687 | start, (u32)(bitmap & 0xFFFFFFFF)); | 3655 | start, (u32)(bitmap & 0xFFFFFFFF)); |
3688 | } | 3656 | } |
3689 | 3657 | ||
3690 | agg->bitmap0 = bitmap & 0xFFFFFFFF; | 3658 | agg->bitmap = bitmap; |
3691 | agg->bitmap1 = bitmap >> 32; | ||
3692 | agg->start_idx = start; | 3659 | agg->start_idx = start; |
3693 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3660 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3694 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%x\n", | 3661 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", |
3695 | agg->frame_count, agg->start_idx, | 3662 | agg->frame_count, agg->start_idx, |
3696 | agg->bitmap0); | 3663 | agg->bitmap); |
3697 | 3664 | ||
3698 | if (bitmap) | 3665 | if (bitmap) |
3699 | agg->wait_for_ba = 1; | 3666 | agg->wait_for_ba = 1; |
@@ -3701,7 +3668,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3701 | return 0; | 3668 | return 0; |
3702 | } | 3669 | } |
3703 | #endif | 3670 | #endif |
3704 | #endif | ||
3705 | 3671 | ||
3706 | /** | 3672 | /** |
3707 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | 3673 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response |
@@ -3718,9 +3684,9 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3718 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 3684 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
3719 | u32 status = le32_to_cpu(tx_resp->status); | 3685 | u32 status = le32_to_cpu(tx_resp->status); |
3720 | #ifdef CONFIG_IWL4965_HT | 3686 | #ifdef CONFIG_IWL4965_HT |
3721 | #ifdef CONFIG_IWL4965_HT_AGG | 3687 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; |
3722 | int tid, sta_id; | 3688 | struct ieee80211_hdr *hdr; |
3723 | #endif | 3689 | __le16 *qc; |
3724 | #endif | 3690 | #endif |
3725 | 3691 | ||
3726 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { | 3692 | if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { |
@@ -3732,44 +3698,51 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3732 | } | 3698 | } |
3733 | 3699 | ||
3734 | #ifdef CONFIG_IWL4965_HT | 3700 | #ifdef CONFIG_IWL4965_HT |
3735 | #ifdef CONFIG_IWL4965_HT_AGG | 3701 | hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index); |
3702 | qc = ieee80211_get_qos_ctrl(hdr); | ||
3703 | |||
3704 | if (qc) | ||
3705 | tid = le16_to_cpu(*qc) & 0xf; | ||
3706 | |||
3707 | sta_id = iwl4965_get_ra_sta_id(priv, hdr); | ||
3708 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { | ||
3709 | IWL_ERROR("Station not known\n"); | ||
3710 | return; | ||
3711 | } | ||
3712 | |||
3736 | if (txq->sched_retry) { | 3713 | if (txq->sched_retry) { |
3737 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); | 3714 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); |
3738 | struct ieee80211_hdr *hdr = | ||
3739 | iwl4965_tx_queue_get_hdr(priv, txq_id, index); | ||
3740 | struct iwl4965_ht_agg *agg = NULL; | 3715 | struct iwl4965_ht_agg *agg = NULL; |
3741 | __le16 *qc = ieee80211_get_qos_ctrl(hdr); | ||
3742 | |||
3743 | if (qc == NULL) { | ||
3744 | IWL_ERROR("BUG_ON qc is null!!!!\n"); | ||
3745 | return; | ||
3746 | } | ||
3747 | |||
3748 | tid = le16_to_cpu(*qc) & 0xf; | ||
3749 | 3716 | ||
3750 | sta_id = iwl4965_get_ra_sta_id(priv, hdr); | 3717 | if (!qc) |
3751 | if (unlikely(sta_id == IWL_INVALID_STATION)) { | ||
3752 | IWL_ERROR("Station not known for\n"); | ||
3753 | return; | 3718 | return; |
3754 | } | ||
3755 | 3719 | ||
3756 | agg = &priv->stations[sta_id].tid[tid].agg; | 3720 | agg = &priv->stations[sta_id].tid[tid].agg; |
3757 | 3721 | ||
3758 | iwl4965_tx_status_reply_tx(priv, agg, tx_resp, index); | 3722 | iwl4965_tx_status_reply_tx(priv, agg, |
3723 | (struct iwl4965_tx_resp_agg *)tx_resp, index); | ||
3759 | 3724 | ||
3760 | if ((tx_resp->frame_count == 1) && | 3725 | if ((tx_resp->frame_count == 1) && |
3761 | !iwl4965_is_tx_success(status)) { | 3726 | !iwl4965_is_tx_success(status)) { |
3762 | /* TODO: send BAR */ | 3727 | /* TODO: send BAR */ |
3763 | } | 3728 | } |
3764 | 3729 | ||
3765 | if ((txq->q.read_ptr != (scd_ssn & 0xff))) { | 3730 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { |
3731 | int freed; | ||
3766 | index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | 3732 | index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); |
3767 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | 3733 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " |
3768 | "%d index %d\n", scd_ssn , index); | 3734 | "%d index %d\n", scd_ssn , index); |
3769 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | 3735 | freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); |
3736 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3737 | |||
3738 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3739 | txq_id >= 0 && priv->mac80211_registered && | ||
3740 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | ||
3741 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3742 | |||
3743 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3770 | } | 3744 | } |
3771 | } else { | 3745 | } else { |
3772 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3773 | #endif /* CONFIG_IWL4965_HT */ | 3746 | #endif /* CONFIG_IWL4965_HT */ |
3774 | tx_status = &(txq->txb[txq->q.read_ptr].status); | 3747 | tx_status = &(txq->txb[txq->q.read_ptr].status); |
3775 | 3748 | ||
@@ -3781,21 +3754,27 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3781 | tx_status->flags = | 3754 | tx_status->flags = |
3782 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3755 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3783 | 3756 | ||
3784 | tx_status->control.tx_rate = | ||
3785 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); | ||
3786 | |||
3787 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 3757 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " |
3788 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), | 3758 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), |
3789 | status, le32_to_cpu(tx_resp->rate_n_flags), | 3759 | status, le32_to_cpu(tx_resp->rate_n_flags), |
3790 | tx_resp->failure_frame); | 3760 | tx_resp->failure_frame); |
3791 | 3761 | ||
3792 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 3762 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
3793 | if (index != -1) | 3763 | if (index != -1) { |
3794 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | 3764 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); |
3765 | #ifdef CONFIG_IWL4965_HT | ||
3766 | if (tid != MAX_TID_COUNT) | ||
3767 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | ||
3768 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | ||
3769 | (txq_id >= 0) && | ||
3770 | priv->mac80211_registered) | ||
3771 | ieee80211_wake_queue(priv->hw, txq_id); | ||
3772 | if (tid != MAX_TID_COUNT) | ||
3773 | iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id); | ||
3774 | #endif | ||
3775 | } | ||
3795 | #ifdef CONFIG_IWL4965_HT | 3776 | #ifdef CONFIG_IWL4965_HT |
3796 | #ifdef CONFIG_IWL4965_HT_AGG | ||
3797 | } | 3777 | } |
3798 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
3799 | #endif /* CONFIG_IWL4965_HT */ | 3778 | #endif /* CONFIG_IWL4965_HT */ |
3800 | 3779 | ||
3801 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 3780 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
@@ -5170,7 +5149,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv) | |||
5170 | /* Queue restart only if RF_KILL switch was set to "kill" | 5149 | /* Queue restart only if RF_KILL switch was set to "kill" |
5171 | * when we loaded driver, and is now set to "enable". | 5150 | * when we loaded driver, and is now set to "enable". |
5172 | * After we're Alive, RF_KILL gets handled by | 5151 | * After we're Alive, RF_KILL gets handled by |
5173 | * iwl_rx_card_state_notif() */ | 5152 | * iwl4965_rx_card_state_notif() */ |
5174 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { | 5153 | if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { |
5175 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 5154 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
5176 | queue_work(priv->workqueue, &priv->restart); | 5155 | queue_work(priv->workqueue, &priv->restart); |
@@ -5416,24 +5395,23 @@ static void iwl4965_init_band_reference(const struct iwl4965_priv *priv, | |||
5416 | * Based on band and channel number. | 5395 | * Based on band and channel number. |
5417 | */ | 5396 | */ |
5418 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, | 5397 | const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, |
5419 | int phymode, u16 channel) | 5398 | enum ieee80211_band band, u16 channel) |
5420 | { | 5399 | { |
5421 | int i; | 5400 | int i; |
5422 | 5401 | ||
5423 | switch (phymode) { | 5402 | switch (band) { |
5424 | case MODE_IEEE80211A: | 5403 | case IEEE80211_BAND_5GHZ: |
5425 | for (i = 14; i < priv->channel_count; i++) { | 5404 | for (i = 14; i < priv->channel_count; i++) { |
5426 | if (priv->channel_info[i].channel == channel) | 5405 | if (priv->channel_info[i].channel == channel) |
5427 | return &priv->channel_info[i]; | 5406 | return &priv->channel_info[i]; |
5428 | } | 5407 | } |
5429 | break; | 5408 | break; |
5430 | 5409 | case IEEE80211_BAND_2GHZ: | |
5431 | case MODE_IEEE80211B: | ||
5432 | case MODE_IEEE80211G: | ||
5433 | if (channel >= 1 && channel <= 14) | 5410 | if (channel >= 1 && channel <= 14) |
5434 | return &priv->channel_info[channel - 1]; | 5411 | return &priv->channel_info[channel - 1]; |
5435 | break; | 5412 | break; |
5436 | 5413 | default: | |
5414 | BUG(); | ||
5437 | } | 5415 | } |
5438 | 5416 | ||
5439 | return NULL; | 5417 | return NULL; |
@@ -5496,8 +5474,8 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5496 | /* Loop through each band adding each of the channels */ | 5474 | /* Loop through each band adding each of the channels */ |
5497 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5475 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
5498 | ch_info->channel = eeprom_ch_index[ch]; | 5476 | ch_info->channel = eeprom_ch_index[ch]; |
5499 | ch_info->phymode = (band == 1) ? MODE_IEEE80211B : | 5477 | ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ : |
5500 | MODE_IEEE80211A; | 5478 | IEEE80211_BAND_5GHZ; |
5501 | 5479 | ||
5502 | /* permanently store EEPROM's channel regulatory flags | 5480 | /* permanently store EEPROM's channel regulatory flags |
5503 | * and max power in channel info database. */ | 5481 | * and max power in channel info database. */ |
@@ -5556,14 +5534,14 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5556 | 5534 | ||
5557 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ | 5535 | /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ |
5558 | for (band = 6; band <= 7; band++) { | 5536 | for (band = 6; band <= 7; band++) { |
5559 | int phymode; | 5537 | enum ieee80211_band ieeeband; |
5560 | u8 fat_extension_chan; | 5538 | u8 fat_extension_chan; |
5561 | 5539 | ||
5562 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, | 5540 | iwl4965_init_band_reference(priv, band, &eeprom_ch_count, |
5563 | &eeprom_ch_info, &eeprom_ch_index); | 5541 | &eeprom_ch_info, &eeprom_ch_index); |
5564 | 5542 | ||
5565 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ | 5543 | /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ |
5566 | phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; | 5544 | ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
5567 | 5545 | ||
5568 | /* Loop through each band adding each of the channels */ | 5546 | /* Loop through each band adding each of the channels */ |
5569 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 5547 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
@@ -5577,13 +5555,13 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv) | |||
5577 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; | 5555 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; |
5578 | 5556 | ||
5579 | /* Set up driver's info for lower half */ | 5557 | /* Set up driver's info for lower half */ |
5580 | iwl4965_set_fat_chan_info(priv, phymode, | 5558 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5581 | eeprom_ch_index[ch], | 5559 | eeprom_ch_index[ch], |
5582 | &(eeprom_ch_info[ch]), | 5560 | &(eeprom_ch_info[ch]), |
5583 | fat_extension_chan); | 5561 | fat_extension_chan); |
5584 | 5562 | ||
5585 | /* Set up driver's info for upper half */ | 5563 | /* Set up driver's info for upper half */ |
5586 | iwl4965_set_fat_chan_info(priv, phymode, | 5564 | iwl4965_set_fat_chan_info(priv, ieeeband, |
5587 | (eeprom_ch_index[ch] + 4), | 5565 | (eeprom_ch_index[ch] + 4), |
5588 | &(eeprom_ch_info[ch]), | 5566 | &(eeprom_ch_info[ch]), |
5589 | HT_IE_EXT_CHANNEL_BELOW); | 5567 | HT_IE_EXT_CHANNEL_BELOW); |
@@ -5625,18 +5603,20 @@ static void iwl4965_free_channel_map(struct iwl4965_priv *priv) | |||
5625 | #define IWL_PASSIVE_DWELL_BASE (100) | 5603 | #define IWL_PASSIVE_DWELL_BASE (100) |
5626 | #define IWL_CHANNEL_TUNE_TIME 5 | 5604 | #define IWL_CHANNEL_TUNE_TIME 5 |
5627 | 5605 | ||
5628 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode) | 5606 | static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, |
5607 | enum ieee80211_band band) | ||
5629 | { | 5608 | { |
5630 | if (phymode == MODE_IEEE80211A) | 5609 | if (band == IEEE80211_BAND_5GHZ) |
5631 | return IWL_ACTIVE_DWELL_TIME_52; | 5610 | return IWL_ACTIVE_DWELL_TIME_52; |
5632 | else | 5611 | else |
5633 | return IWL_ACTIVE_DWELL_TIME_24; | 5612 | return IWL_ACTIVE_DWELL_TIME_24; |
5634 | } | 5613 | } |
5635 | 5614 | ||
5636 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode) | 5615 | static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, |
5616 | enum ieee80211_band band) | ||
5637 | { | 5617 | { |
5638 | u16 active = iwl4965_get_active_dwell_time(priv, phymode); | 5618 | u16 active = iwl4965_get_active_dwell_time(priv, band); |
5639 | u16 passive = (phymode != MODE_IEEE80211A) ? | 5619 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? |
5640 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | 5620 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : |
5641 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | 5621 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; |
5642 | 5622 | ||
@@ -5656,28 +5636,29 @@ static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode | |||
5656 | return passive; | 5636 | return passive; |
5657 | } | 5637 | } |
5658 | 5638 | ||
5659 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | 5639 | static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, |
5640 | enum ieee80211_band band, | ||
5660 | u8 is_active, u8 direct_mask, | 5641 | u8 is_active, u8 direct_mask, |
5661 | struct iwl4965_scan_channel *scan_ch) | 5642 | struct iwl4965_scan_channel *scan_ch) |
5662 | { | 5643 | { |
5663 | const struct ieee80211_channel *channels = NULL; | 5644 | const struct ieee80211_channel *channels = NULL; |
5664 | const struct ieee80211_hw_mode *hw_mode; | 5645 | const struct ieee80211_supported_band *sband; |
5665 | const struct iwl4965_channel_info *ch_info; | 5646 | const struct iwl4965_channel_info *ch_info; |
5666 | u16 passive_dwell = 0; | 5647 | u16 passive_dwell = 0; |
5667 | u16 active_dwell = 0; | 5648 | u16 active_dwell = 0; |
5668 | int added, i; | 5649 | int added, i; |
5669 | 5650 | ||
5670 | hw_mode = iwl4965_get_hw_mode(priv, phymode); | 5651 | sband = iwl4965_get_hw_mode(priv, band); |
5671 | if (!hw_mode) | 5652 | if (!sband) |
5672 | return 0; | 5653 | return 0; |
5673 | 5654 | ||
5674 | channels = hw_mode->channels; | 5655 | channels = sband->channels; |
5675 | 5656 | ||
5676 | active_dwell = iwl4965_get_active_dwell_time(priv, phymode); | 5657 | active_dwell = iwl4965_get_active_dwell_time(priv, band); |
5677 | passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode); | 5658 | passive_dwell = iwl4965_get_passive_dwell_time(priv, band); |
5678 | 5659 | ||
5679 | for (i = 0, added = 0; i < hw_mode->num_channels; i++) { | 5660 | for (i = 0, added = 0; i < sband->n_channels; i++) { |
5680 | if (channels[i].chan == | 5661 | if (ieee80211_frequency_to_channel(channels[i].center_freq) == |
5681 | le16_to_cpu(priv->active_rxon.channel)) { | 5662 | le16_to_cpu(priv->active_rxon.channel)) { |
5682 | if (iwl4965_is_associated(priv)) { | 5663 | if (iwl4965_is_associated(priv)) { |
5683 | IWL_DEBUG_SCAN | 5664 | IWL_DEBUG_SCAN |
@@ -5688,9 +5669,9 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5688 | } else if (priv->only_active_channel) | 5669 | } else if (priv->only_active_channel) |
5689 | continue; | 5670 | continue; |
5690 | 5671 | ||
5691 | scan_ch->channel = channels[i].chan; | 5672 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); |
5692 | 5673 | ||
5693 | ch_info = iwl4965_get_channel_info(priv, phymode, | 5674 | ch_info = iwl4965_get_channel_info(priv, band, |
5694 | scan_ch->channel); | 5675 | scan_ch->channel); |
5695 | if (!is_channel_valid(ch_info)) { | 5676 | if (!is_channel_valid(ch_info)) { |
5696 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 5677 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", |
@@ -5699,7 +5680,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5699 | } | 5680 | } |
5700 | 5681 | ||
5701 | if (!is_active || is_channel_passive(ch_info) || | 5682 | if (!is_active || is_channel_passive(ch_info) || |
5702 | !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN)) | 5683 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) |
5703 | scan_ch->type = 0; /* passive */ | 5684 | scan_ch->type = 0; /* passive */ |
5704 | else | 5685 | else |
5705 | scan_ch->type = 1; /* active */ | 5686 | scan_ch->type = 1; /* active */ |
@@ -5718,7 +5699,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5718 | /* scan_pwr_info->tpc.dsp_atten; */ | 5699 | /* scan_pwr_info->tpc.dsp_atten; */ |
5719 | 5700 | ||
5720 | /*scan_pwr_info->tpc.tx_gain; */ | 5701 | /*scan_pwr_info->tpc.tx_gain; */ |
5721 | if (phymode == MODE_IEEE80211A) | 5702 | if (band == IEEE80211_BAND_5GHZ) |
5722 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | 5703 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; |
5723 | else { | 5704 | else { |
5724 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | 5705 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); |
@@ -5742,41 +5723,23 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, | |||
5742 | return added; | 5723 | return added; |
5743 | } | 5724 | } |
5744 | 5725 | ||
5745 | static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv) | ||
5746 | { | ||
5747 | int i, j; | ||
5748 | for (i = 0; i < 3; i++) { | ||
5749 | struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i]; | ||
5750 | for (j = 0; j < hw_mode->num_channels; j++) | ||
5751 | hw_mode->channels[j].flag = hw_mode->channels[j].val; | ||
5752 | } | ||
5753 | } | ||
5754 | |||
5755 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | 5726 | static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, |
5756 | struct ieee80211_rate *rates) | 5727 | struct ieee80211_rate *rates) |
5757 | { | 5728 | { |
5758 | int i; | 5729 | int i; |
5759 | 5730 | ||
5760 | for (i = 0; i < IWL_RATE_COUNT; i++) { | 5731 | for (i = 0; i < IWL_RATE_COUNT; i++) { |
5761 | rates[i].rate = iwl4965_rates[i].ieee * 5; | 5732 | rates[i].bitrate = iwl4965_rates[i].ieee * 5; |
5762 | rates[i].val = i; /* Rate scaling will work on indexes */ | 5733 | rates[i].hw_value = i; /* Rate scaling will work on indexes */ |
5763 | rates[i].val2 = i; | 5734 | rates[i].hw_value_short = i; |
5764 | rates[i].flags = IEEE80211_RATE_SUPPORTED; | 5735 | rates[i].flags = 0; |
5765 | /* Only OFDM have the bits-per-symbol set */ | 5736 | if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) { |
5766 | if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE)) | ||
5767 | rates[i].flags |= IEEE80211_RATE_OFDM; | ||
5768 | else { | ||
5769 | /* | 5737 | /* |
5770 | * If CCK 1M then set rate flag to CCK else CCK_2 | 5738 | * If CCK != 1M then set short preamble rate flag. |
5771 | * which is CCK | PREAMBLE2 | ||
5772 | */ | 5739 | */ |
5773 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? | 5740 | rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? |
5774 | IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; | 5741 | 0 : IEEE80211_RATE_SHORT_PREAMBLE; |
5775 | } | 5742 | } |
5776 | |||
5777 | /* Set up which ones are basic rates... */ | ||
5778 | if (IWL_BASIC_RATES_MASK & (1 << i)) | ||
5779 | rates[i].flags |= IEEE80211_RATE_BASIC; | ||
5780 | } | 5743 | } |
5781 | } | 5744 | } |
5782 | 5745 | ||
@@ -5786,74 +5749,45 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, | |||
5786 | static int iwl4965_init_geos(struct iwl4965_priv *priv) | 5749 | static int iwl4965_init_geos(struct iwl4965_priv *priv) |
5787 | { | 5750 | { |
5788 | struct iwl4965_channel_info *ch; | 5751 | struct iwl4965_channel_info *ch; |
5789 | struct ieee80211_hw_mode *modes; | 5752 | struct ieee80211_supported_band *band; |
5790 | struct ieee80211_channel *channels; | 5753 | struct ieee80211_channel *channels; |
5791 | struct ieee80211_channel *geo_ch; | 5754 | struct ieee80211_channel *geo_ch; |
5792 | struct ieee80211_rate *rates; | 5755 | struct ieee80211_rate *rates; |
5793 | int i = 0; | 5756 | int i = 0; |
5794 | enum { | ||
5795 | A = 0, | ||
5796 | B = 1, | ||
5797 | G = 2, | ||
5798 | }; | ||
5799 | int mode_count = 3; | ||
5800 | 5757 | ||
5801 | if (priv->modes) { | 5758 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
5759 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||
5802 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); | 5760 | IWL_DEBUG_INFO("Geography modes already initialized.\n"); |
5803 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5761 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5804 | return 0; | 5762 | return 0; |
5805 | } | 5763 | } |
5806 | 5764 | ||
5807 | modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count, | ||
5808 | GFP_KERNEL); | ||
5809 | if (!modes) | ||
5810 | return -ENOMEM; | ||
5811 | |||
5812 | channels = kzalloc(sizeof(struct ieee80211_channel) * | 5765 | channels = kzalloc(sizeof(struct ieee80211_channel) * |
5813 | priv->channel_count, GFP_KERNEL); | 5766 | priv->channel_count, GFP_KERNEL); |
5814 | if (!channels) { | 5767 | if (!channels) |
5815 | kfree(modes); | ||
5816 | return -ENOMEM; | 5768 | return -ENOMEM; |
5817 | } | ||
5818 | 5769 | ||
5819 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), | 5770 | rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)), |
5820 | GFP_KERNEL); | 5771 | GFP_KERNEL); |
5821 | if (!rates) { | 5772 | if (!rates) { |
5822 | kfree(modes); | ||
5823 | kfree(channels); | 5773 | kfree(channels); |
5824 | return -ENOMEM; | 5774 | return -ENOMEM; |
5825 | } | 5775 | } |
5826 | 5776 | ||
5827 | /* 0 = 802.11a | ||
5828 | * 1 = 802.11b | ||
5829 | * 2 = 802.11g | ||
5830 | */ | ||
5831 | |||
5832 | /* 5.2GHz channels start after the 2.4GHz channels */ | 5777 | /* 5.2GHz channels start after the 2.4GHz channels */ |
5833 | modes[A].mode = MODE_IEEE80211A; | 5778 | band = &priv->bands[IEEE80211_BAND_5GHZ]; |
5834 | modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; | 5779 | band->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; |
5835 | modes[A].rates = rates; | 5780 | band->bitrates = &rates[4]; |
5836 | modes[A].num_rates = 8; /* just OFDM */ | 5781 | band->n_bitrates = 8; /* just OFDM */ |
5837 | modes[A].rates = &rates[4]; | ||
5838 | modes[A].num_channels = 0; | ||
5839 | #ifdef CONFIG_IWL4965_HT | ||
5840 | iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A); | ||
5841 | #endif | ||
5842 | 5782 | ||
5843 | modes[B].mode = MODE_IEEE80211B; | 5783 | iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_5GHZ); |
5844 | modes[B].channels = channels; | 5784 | |
5845 | modes[B].rates = rates; | 5785 | band = &priv->bands[IEEE80211_BAND_2GHZ]; |
5846 | modes[B].num_rates = 4; /* just CCK */ | 5786 | band->channels = channels; |
5847 | modes[B].num_channels = 0; | 5787 | band->bitrates = rates; |
5848 | 5788 | band->n_bitrates = 12; /* OFDM & CCK */ | |
5849 | modes[G].mode = MODE_IEEE80211G; | 5789 | |
5850 | modes[G].channels = channels; | 5790 | iwl4965_init_ht_hw_capab(&band->ht_info, IEEE80211_BAND_2GHZ); |
5851 | modes[G].rates = rates; | ||
5852 | modes[G].num_rates = 12; /* OFDM & CCK */ | ||
5853 | modes[G].num_channels = 0; | ||
5854 | #ifdef CONFIG_IWL4965_HT | ||
5855 | iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G); | ||
5856 | #endif | ||
5857 | 5791 | ||
5858 | priv->ieee_channels = channels; | 5792 | priv->ieee_channels = channels; |
5859 | priv->ieee_rates = rates; | 5793 | priv->ieee_rates = rates; |
@@ -5872,37 +5806,33 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5872 | } | 5806 | } |
5873 | 5807 | ||
5874 | if (is_channel_a_band(ch)) { | 5808 | if (is_channel_a_band(ch)) { |
5875 | geo_ch = &modes[A].channels[modes[A].num_channels++]; | 5809 | geo_ch = &priv->bands[IEEE80211_BAND_5GHZ].channels[priv->bands[IEEE80211_BAND_5GHZ].n_channels++]; |
5876 | } else { | 5810 | } else |
5877 | geo_ch = &modes[B].channels[modes[B].num_channels++]; | 5811 | geo_ch = &priv->bands[IEEE80211_BAND_2GHZ].channels[priv->bands[IEEE80211_BAND_2GHZ].n_channels++]; |
5878 | modes[G].num_channels++; | ||
5879 | } | ||
5880 | 5812 | ||
5881 | geo_ch->freq = ieee80211chan2mhz(ch->channel); | 5813 | geo_ch->center_freq = ieee80211chan2mhz(ch->channel); |
5882 | geo_ch->chan = ch->channel; | 5814 | geo_ch->max_power = ch->max_power_avg; |
5883 | geo_ch->power_level = ch->max_power_avg; | 5815 | geo_ch->max_antenna_gain = 0xff; |
5884 | geo_ch->antenna_max = 0xff; | 5816 | geo_ch->hw_value = ch->channel; |
5885 | 5817 | ||
5886 | if (is_channel_valid(ch)) { | 5818 | if (is_channel_valid(ch)) { |
5887 | geo_ch->flag = IEEE80211_CHAN_W_SCAN; | 5819 | if (!(ch->flags & EEPROM_CHANNEL_IBSS)) |
5888 | if (ch->flags & EEPROM_CHANNEL_IBSS) | 5820 | geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; |
5889 | geo_ch->flag |= IEEE80211_CHAN_W_IBSS; | ||
5890 | 5821 | ||
5891 | if (ch->flags & EEPROM_CHANNEL_ACTIVE) | 5822 | if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) |
5892 | geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN; | 5823 | geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; |
5893 | 5824 | ||
5894 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 5825 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
5895 | geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT; | 5826 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
5896 | 5827 | ||
5897 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 5828 | if (ch->max_power_avg > priv->max_channel_txpower_limit) |
5898 | priv->max_channel_txpower_limit = | 5829 | priv->max_channel_txpower_limit = |
5899 | ch->max_power_avg; | 5830 | ch->max_power_avg; |
5900 | } | 5831 | } else |
5901 | 5832 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | |
5902 | geo_ch->val = geo_ch->flag; | ||
5903 | } | 5833 | } |
5904 | 5834 | ||
5905 | if ((modes[A].num_channels == 0) && priv->is_abg) { | 5835 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && priv->is_abg) { |
5906 | printk(KERN_INFO DRV_NAME | 5836 | printk(KERN_INFO DRV_NAME |
5907 | ": Incorrectly detected BG card as ABG. Please send " | 5837 | ": Incorrectly detected BG card as ABG. Please send " |
5908 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", | 5838 | "your PCI ID 0x%04X:0x%04X to maintainer.\n", |
@@ -5912,24 +5842,12 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5912 | 5842 | ||
5913 | printk(KERN_INFO DRV_NAME | 5843 | printk(KERN_INFO DRV_NAME |
5914 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", | 5844 | ": Tunable channels: %d 802.11bg, %d 802.11a channels\n", |
5915 | modes[G].num_channels, modes[A].num_channels); | 5845 | priv->bands[IEEE80211_BAND_2GHZ].n_channels, |
5916 | 5846 | priv->bands[IEEE80211_BAND_5GHZ].n_channels); | |
5917 | /* | ||
5918 | * NOTE: We register these in preference of order -- the | ||
5919 | * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick | ||
5920 | * a phymode based on rates or AP capabilities but seems to | ||
5921 | * configure it purely on if the channel being configured | ||
5922 | * is supported by a mode -- and the first match is taken | ||
5923 | */ | ||
5924 | 5847 | ||
5925 | if (modes[G].num_channels) | 5848 | priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ]; |
5926 | ieee80211_register_hwmode(priv->hw, &modes[G]); | 5849 | priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; |
5927 | if (modes[B].num_channels) | ||
5928 | ieee80211_register_hwmode(priv->hw, &modes[B]); | ||
5929 | if (modes[A].num_channels) | ||
5930 | ieee80211_register_hwmode(priv->hw, &modes[A]); | ||
5931 | 5850 | ||
5932 | priv->modes = modes; | ||
5933 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5851 | set_bit(STATUS_GEO_CONFIGURED, &priv->status); |
5934 | 5852 | ||
5935 | return 0; | 5853 | return 0; |
@@ -5940,7 +5858,6 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv) | |||
5940 | */ | 5858 | */ |
5941 | static void iwl4965_free_geos(struct iwl4965_priv *priv) | 5859 | static void iwl4965_free_geos(struct iwl4965_priv *priv) |
5942 | { | 5860 | { |
5943 | kfree(priv->modes); | ||
5944 | kfree(priv->ieee_channels); | 5861 | kfree(priv->ieee_channels); |
5945 | kfree(priv->ieee_rates); | 5862 | kfree(priv->ieee_rates); |
5946 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 5863 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
@@ -6941,8 +6858,9 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
6941 | int rc = 0; | 6858 | int rc = 0; |
6942 | struct iwl4965_scan_cmd *scan; | 6859 | struct iwl4965_scan_cmd *scan; |
6943 | struct ieee80211_conf *conf = NULL; | 6860 | struct ieee80211_conf *conf = NULL; |
6861 | u16 cmd_len; | ||
6862 | enum ieee80211_band band; | ||
6944 | u8 direct_mask; | 6863 | u8 direct_mask; |
6945 | int phymode; | ||
6946 | 6864 | ||
6947 | conf = ieee80211_get_hw_conf(priv->hw); | 6865 | conf = ieee80211_get_hw_conf(priv->hw); |
6948 | 6866 | ||
@@ -7051,18 +6969,10 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7051 | } else | 6969 | } else |
7052 | direct_mask = 0; | 6970 | direct_mask = 0; |
7053 | 6971 | ||
7054 | /* We don't build a direct scan probe request; the uCode will do | ||
7055 | * that based on the direct_mask added to each channel entry */ | ||
7056 | scan->tx_cmd.len = cpu_to_le16( | ||
7057 | iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, | ||
7058 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0)); | ||
7059 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 6972 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; |
7060 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; | 6973 | scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; |
7061 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 6974 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
7062 | 6975 | ||
7063 | /* flags + rate selection */ | ||
7064 | |||
7065 | scan->tx_cmd.tx_flags |= cpu_to_le32(0x200); | ||
7066 | 6976 | ||
7067 | switch (priv->scan_bands) { | 6977 | switch (priv->scan_bands) { |
7068 | case 2: | 6978 | case 2: |
@@ -7072,7 +6982,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7072 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); | 6982 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); |
7073 | 6983 | ||
7074 | scan->good_CRC_th = 0; | 6984 | scan->good_CRC_th = 0; |
7075 | phymode = MODE_IEEE80211G; | 6985 | band = IEEE80211_BAND_2GHZ; |
7076 | break; | 6986 | break; |
7077 | 6987 | ||
7078 | case 1: | 6988 | case 1: |
@@ -7080,7 +6990,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7080 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 6990 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, |
7081 | RATE_MCS_ANT_B_MSK); | 6991 | RATE_MCS_ANT_B_MSK); |
7082 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6992 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
7083 | phymode = MODE_IEEE80211A; | 6993 | band = IEEE80211_BAND_5GHZ; |
7084 | break; | 6994 | break; |
7085 | 6995 | ||
7086 | default: | 6996 | default: |
@@ -7088,6 +6998,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7088 | goto done; | 6998 | goto done; |
7089 | } | 6999 | } |
7090 | 7000 | ||
7001 | /* We don't build a direct scan probe request; the uCode will do | ||
7002 | * that based on the direct_mask added to each channel entry */ | ||
7003 | cmd_len = iwl4965_fill_probe_req(priv, band, | ||
7004 | (struct ieee80211_mgmt *)scan->data, | ||
7005 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0); | ||
7006 | |||
7007 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | ||
7091 | /* select Rx chains */ | 7008 | /* select Rx chains */ |
7092 | 7009 | ||
7093 | /* Force use of chains B and C (0x6) for scan Rx. | 7010 | /* Force use of chains B and C (0x6) for scan Rx. |
@@ -7110,7 +7027,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
7110 | 7027 | ||
7111 | scan->channel_count = | 7028 | scan->channel_count = |
7112 | iwl4965_get_channels_for_scan( | 7029 | iwl4965_get_channels_for_scan( |
7113 | priv, phymode, 1, /* active */ | 7030 | priv, band, 1, /* active */ |
7114 | direct_mask, | 7031 | direct_mask, |
7115 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | 7032 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); |
7116 | 7033 | ||
@@ -7281,9 +7198,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
7281 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | 7198 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) |
7282 | priv->assoc_station_added = 1; | 7199 | priv->assoc_station_added = 1; |
7283 | 7200 | ||
7284 | #ifdef CONFIG_IWL4965_QOS | ||
7285 | iwl4965_activate_qos(priv, 0); | 7201 | iwl4965_activate_qos(priv, 0); |
7286 | #endif /* CONFIG_IWL4965_QOS */ | 7202 | |
7287 | /* we have just associated, don't start scan too early */ | 7203 | /* we have just associated, don't start scan too early */ |
7288 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; | 7204 | priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; |
7289 | mutex_unlock(&priv->mutex); | 7205 | mutex_unlock(&priv->mutex); |
@@ -7460,7 +7376,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
7460 | } | 7376 | } |
7461 | 7377 | ||
7462 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | 7378 | IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, |
7463 | ctl->tx_rate); | 7379 | ctl->tx_rate->bitrate); |
7464 | 7380 | ||
7465 | if (iwl4965_tx_skb(priv, skb, ctl)) | 7381 | if (iwl4965_tx_skb(priv, skb, ctl)) |
7466 | dev_kfree_skb_any(skb); | 7382 | dev_kfree_skb_any(skb); |
@@ -7519,7 +7435,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7519 | int ret = 0; | 7435 | int ret = 0; |
7520 | 7436 | ||
7521 | mutex_lock(&priv->mutex); | 7437 | mutex_lock(&priv->mutex); |
7522 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); | 7438 | IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value); |
7523 | 7439 | ||
7524 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 7440 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
7525 | 7441 | ||
@@ -7539,10 +7455,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7539 | 7455 | ||
7540 | spin_lock_irqsave(&priv->lock, flags); | 7456 | spin_lock_irqsave(&priv->lock, flags); |
7541 | 7457 | ||
7542 | ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel); | 7458 | ch_info = iwl4965_get_channel_info(priv, conf->channel->band, |
7459 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7543 | if (!is_channel_valid(ch_info)) { | 7460 | if (!is_channel_valid(ch_info)) { |
7544 | IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", | ||
7545 | conf->channel, conf->phymode); | ||
7546 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); | 7461 | IWL_DEBUG_MAC80211("leave - invalid channel\n"); |
7547 | spin_unlock_irqrestore(&priv->lock, flags); | 7462 | spin_unlock_irqrestore(&priv->lock, flags); |
7548 | ret = -EINVAL; | 7463 | ret = -EINVAL; |
@@ -7550,10 +7465,10 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7550 | } | 7465 | } |
7551 | 7466 | ||
7552 | #ifdef CONFIG_IWL4965_HT | 7467 | #ifdef CONFIG_IWL4965_HT |
7553 | /* if we are switching fron ht to 2.4 clear flags | 7468 | /* if we are switching from ht to 2.4 clear flags |
7554 | * from any ht related info since 2.4 does not | 7469 | * from any ht related info since 2.4 does not |
7555 | * support ht */ | 7470 | * support ht */ |
7556 | if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel) | 7471 | if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel->hw_value) |
7557 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH | 7472 | #ifdef IEEE80211_CONF_CHANNEL_SWITCH |
7558 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) | 7473 | && !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) |
7559 | #endif | 7474 | #endif |
@@ -7561,12 +7476,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
7561 | priv->staging_rxon.flags = 0; | 7476 | priv->staging_rxon.flags = 0; |
7562 | #endif /* CONFIG_IWL4965_HT */ | 7477 | #endif /* CONFIG_IWL4965_HT */ |
7563 | 7478 | ||
7564 | iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel); | 7479 | iwl4965_set_rxon_channel(priv, conf->channel->band, |
7480 | ieee80211_frequency_to_channel(conf->channel->center_freq)); | ||
7565 | 7481 | ||
7566 | iwl4965_set_flags_for_phymode(priv, conf->phymode); | 7482 | iwl4965_set_flags_for_phymode(priv, conf->channel->band); |
7567 | 7483 | ||
7568 | /* The list of supported rates and rate mask can be different | 7484 | /* The list of supported rates and rate mask can be different |
7569 | * for each phymode; since the phymode may have changed, reset | 7485 | * for each band; since the band may have changed, reset |
7570 | * the rate mask to what mac80211 lists */ | 7486 | * the rate mask to what mac80211 lists */ |
7571 | iwl4965_set_rate(priv); | 7487 | iwl4965_set_rate(priv); |
7572 | 7488 | ||
@@ -7658,9 +7574,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv) | |||
7658 | /* restore RXON assoc */ | 7574 | /* restore RXON assoc */ |
7659 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 7575 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
7660 | iwl4965_commit_rxon(priv); | 7576 | iwl4965_commit_rxon(priv); |
7661 | #ifdef CONFIG_IWL4965_QOS | ||
7662 | iwl4965_activate_qos(priv, 1); | 7577 | iwl4965_activate_qos(priv, 1); |
7663 | #endif | ||
7664 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); | 7578 | iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); |
7665 | } | 7579 | } |
7666 | iwl4965_send_beacon_cmd(priv); | 7580 | iwl4965_send_beacon_cmd(priv); |
@@ -7836,7 +7750,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | |||
7836 | } | 7750 | } |
7837 | 7751 | ||
7838 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { | 7752 | if (changes & BSS_CHANGED_ERP_CTS_PROT) { |
7839 | if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A)) | 7753 | if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) |
7840 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; | 7754 | priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; |
7841 | else | 7755 | else |
7842 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; | 7756 | priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; |
@@ -7974,10 +7888,8 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7974 | const struct ieee80211_tx_queue_params *params) | 7888 | const struct ieee80211_tx_queue_params *params) |
7975 | { | 7889 | { |
7976 | struct iwl4965_priv *priv = hw->priv; | 7890 | struct iwl4965_priv *priv = hw->priv; |
7977 | #ifdef CONFIG_IWL4965_QOS | ||
7978 | unsigned long flags; | 7891 | unsigned long flags; |
7979 | int q; | 7892 | int q; |
7980 | #endif /* CONFIG_IWL4965_QOS */ | ||
7981 | 7893 | ||
7982 | IWL_DEBUG_MAC80211("enter\n"); | 7894 | IWL_DEBUG_MAC80211("enter\n"); |
7983 | 7895 | ||
@@ -7991,7 +7903,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
7991 | return 0; | 7903 | return 0; |
7992 | } | 7904 | } |
7993 | 7905 | ||
7994 | #ifdef CONFIG_IWL4965_QOS | ||
7995 | if (!priv->qos_data.qos_enable) { | 7906 | if (!priv->qos_data.qos_enable) { |
7996 | priv->qos_data.qos_active = 0; | 7907 | priv->qos_data.qos_active = 0; |
7997 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); | 7908 | IWL_DEBUG_MAC80211("leave - qos not enabled\n"); |
@@ -8005,7 +7916,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
8005 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); | 7916 | priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); |
8006 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; | 7917 | priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; |
8007 | priv->qos_data.def_qos_parm.ac[q].edca_txop = | 7918 | priv->qos_data.def_qos_parm.ac[q].edca_txop = |
8008 | cpu_to_le16((params->burst_time * 100)); | 7919 | cpu_to_le16((params->txop * 32)); |
8009 | 7920 | ||
8010 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; | 7921 | priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; |
8011 | priv->qos_data.qos_active = 1; | 7922 | priv->qos_data.qos_active = 1; |
@@ -8020,8 +7931,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, | |||
8020 | 7931 | ||
8021 | mutex_unlock(&priv->mutex); | 7932 | mutex_unlock(&priv->mutex); |
8022 | 7933 | ||
8023 | #endif /*CONFIG_IWL4965_QOS */ | ||
8024 | |||
8025 | IWL_DEBUG_MAC80211("leave\n"); | 7934 | IWL_DEBUG_MAC80211("leave\n"); |
8026 | return 0; | 7935 | return 0; |
8027 | } | 7936 | } |
@@ -8091,23 +8000,9 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
8091 | spin_lock_irqsave(&priv->lock, flags); | 8000 | spin_lock_irqsave(&priv->lock, flags); |
8092 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 8001 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
8093 | spin_unlock_irqrestore(&priv->lock, flags); | 8002 | spin_unlock_irqrestore(&priv->lock, flags); |
8094 | #ifdef CONFIG_IWL4965_HT_AGG | ||
8095 | /* if (priv->lq_mngr.agg_ctrl.granted_ba) | ||
8096 | iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/ | ||
8097 | |||
8098 | memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control)); | ||
8099 | priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10; | ||
8100 | priv->lq_mngr.agg_ctrl.ba_timeout = 5000; | ||
8101 | priv->lq_mngr.agg_ctrl.auto_agg = 1; | ||
8102 | |||
8103 | if (priv->lq_mngr.agg_ctrl.auto_agg) | ||
8104 | priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED; | ||
8105 | #endif /*CONFIG_IWL4965_HT_AGG */ | ||
8106 | #endif /* CONFIG_IWL4965_HT */ | 8003 | #endif /* CONFIG_IWL4965_HT */ |
8107 | 8004 | ||
8108 | #ifdef CONFIG_IWL4965_QOS | ||
8109 | iwl4965_reset_qos(priv); | 8005 | iwl4965_reset_qos(priv); |
8110 | #endif | ||
8111 | 8006 | ||
8112 | cancel_delayed_work(&priv->post_associate); | 8007 | cancel_delayed_work(&priv->post_associate); |
8113 | 8008 | ||
@@ -8196,9 +8091,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
8196 | IWL_DEBUG_MAC80211("leave\n"); | 8091 | IWL_DEBUG_MAC80211("leave\n"); |
8197 | spin_unlock_irqrestore(&priv->lock, flags); | 8092 | spin_unlock_irqrestore(&priv->lock, flags); |
8198 | 8093 | ||
8199 | #ifdef CONFIG_IWL4965_QOS | ||
8200 | iwl4965_reset_qos(priv); | 8094 | iwl4965_reset_qos(priv); |
8201 | #endif | ||
8202 | 8095 | ||
8203 | queue_work(priv->workqueue, &priv->post_associate.work); | 8096 | queue_work(priv->workqueue, &priv->post_associate.work); |
8204 | 8097 | ||
@@ -8281,28 +8174,6 @@ static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, | |||
8281 | return 0; | 8174 | return 0; |
8282 | } | 8175 | } |
8283 | 8176 | ||
8284 | static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, | ||
8285 | struct ieee80211_ht_cap *ht_cap, | ||
8286 | u8 use_current_config) | ||
8287 | { | ||
8288 | struct ieee80211_conf *conf = &hw->conf; | ||
8289 | struct ieee80211_hw_mode *mode = conf->mode; | ||
8290 | |||
8291 | if (use_current_config) { | ||
8292 | ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap); | ||
8293 | memcpy(ht_cap->supp_mcs_set, | ||
8294 | conf->ht_conf.supp_mcs_set, 16); | ||
8295 | } else { | ||
8296 | ht_cap->cap_info = cpu_to_le16(mode->ht_info.cap); | ||
8297 | memcpy(ht_cap->supp_mcs_set, | ||
8298 | mode->ht_info.supp_mcs_set, 16); | ||
8299 | } | ||
8300 | ht_cap->ampdu_params_info = | ||
8301 | (mode->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
8302 | ((mode->ht_info.ampdu_density << 2) & | ||
8303 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
8304 | } | ||
8305 | |||
8306 | #endif /*CONFIG_IWL4965_HT*/ | 8177 | #endif /*CONFIG_IWL4965_HT*/ |
8307 | 8178 | ||
8308 | /***************************************************************************** | 8179 | /***************************************************************************** |
@@ -8497,65 +8368,6 @@ static ssize_t store_filter_flags(struct device *d, | |||
8497 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, | 8368 | static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, |
8498 | store_filter_flags); | 8369 | store_filter_flags); |
8499 | 8370 | ||
8500 | static ssize_t show_tune(struct device *d, | ||
8501 | struct device_attribute *attr, char *buf) | ||
8502 | { | ||
8503 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8504 | |||
8505 | return sprintf(buf, "0x%04X\n", | ||
8506 | (priv->phymode << 8) | | ||
8507 | le16_to_cpu(priv->active_rxon.channel)); | ||
8508 | } | ||
8509 | |||
8510 | static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode); | ||
8511 | |||
8512 | static ssize_t store_tune(struct device *d, | ||
8513 | struct device_attribute *attr, | ||
8514 | const char *buf, size_t count) | ||
8515 | { | ||
8516 | struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; | ||
8517 | char *p = (char *)buf; | ||
8518 | u16 tune = simple_strtoul(p, &p, 0); | ||
8519 | u8 phymode = (tune >> 8) & 0xff; | ||
8520 | u16 channel = tune & 0xff; | ||
8521 | |||
8522 | IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel); | ||
8523 | |||
8524 | mutex_lock(&priv->mutex); | ||
8525 | if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || | ||
8526 | (priv->phymode != phymode)) { | ||
8527 | const struct iwl4965_channel_info *ch_info; | ||
8528 | |||
8529 | ch_info = iwl4965_get_channel_info(priv, phymode, channel); | ||
8530 | if (!ch_info) { | ||
8531 | IWL_WARNING("Requested invalid phymode/channel " | ||
8532 | "combination: %d %d\n", phymode, channel); | ||
8533 | mutex_unlock(&priv->mutex); | ||
8534 | return -EINVAL; | ||
8535 | } | ||
8536 | |||
8537 | /* Cancel any currently running scans... */ | ||
8538 | if (iwl4965_scan_cancel_timeout(priv, 100)) | ||
8539 | IWL_WARNING("Could not cancel scan.\n"); | ||
8540 | else { | ||
8541 | IWL_DEBUG_INFO("Committing phymode and " | ||
8542 | "rxon.channel = %d %d\n", | ||
8543 | phymode, channel); | ||
8544 | |||
8545 | iwl4965_set_rxon_channel(priv, phymode, channel); | ||
8546 | iwl4965_set_flags_for_phymode(priv, phymode); | ||
8547 | |||
8548 | iwl4965_set_rate(priv); | ||
8549 | iwl4965_commit_rxon(priv); | ||
8550 | } | ||
8551 | } | ||
8552 | mutex_unlock(&priv->mutex); | ||
8553 | |||
8554 | return count; | ||
8555 | } | ||
8556 | |||
8557 | static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); | ||
8558 | |||
8559 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT | 8371 | #ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT |
8560 | 8372 | ||
8561 | static ssize_t show_measurement(struct device *d, | 8373 | static ssize_t show_measurement(struct device *d, |
@@ -8745,73 +8557,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
8745 | static ssize_t show_channels(struct device *d, | 8557 | static ssize_t show_channels(struct device *d, |
8746 | struct device_attribute *attr, char *buf) | 8558 | struct device_attribute *attr, char *buf) |
8747 | { | 8559 | { |
8748 | struct iwl4965_priv *priv = dev_get_drvdata(d); | 8560 | /* all this shit doesn't belong into sysfs anyway */ |
8749 | int len = 0, i; | 8561 | return 0; |
8750 | struct ieee80211_channel *channels = NULL; | ||
8751 | const struct ieee80211_hw_mode *hw_mode = NULL; | ||
8752 | int count = 0; | ||
8753 | |||
8754 | if (!iwl4965_is_ready(priv)) | ||
8755 | return -EAGAIN; | ||
8756 | |||
8757 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G); | ||
8758 | if (!hw_mode) | ||
8759 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B); | ||
8760 | if (hw_mode) { | ||
8761 | channels = hw_mode->channels; | ||
8762 | count = hw_mode->num_channels; | ||
8763 | } | ||
8764 | |||
8765 | len += | ||
8766 | sprintf(&buf[len], | ||
8767 | "Displaying %d channels in 2.4GHz band " | ||
8768 | "(802.11bg):\n", count); | ||
8769 | |||
8770 | for (i = 0; i < count; i++) | ||
8771 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8772 | channels[i].chan, | ||
8773 | channels[i].power_level, | ||
8774 | channels[i]. | ||
8775 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8776 | " (IEEE 802.11h required)" : "", | ||
8777 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8778 | || (channels[i]. | ||
8779 | flag & | ||
8780 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8781 | ", IBSS", | ||
8782 | channels[i]. | ||
8783 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8784 | "active/passive" : "passive only"); | ||
8785 | |||
8786 | hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A); | ||
8787 | if (hw_mode) { | ||
8788 | channels = hw_mode->channels; | ||
8789 | count = hw_mode->num_channels; | ||
8790 | } else { | ||
8791 | channels = NULL; | ||
8792 | count = 0; | ||
8793 | } | ||
8794 | |||
8795 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
8796 | "(802.11a):\n", count); | ||
8797 | |||
8798 | for (i = 0; i < count; i++) | ||
8799 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
8800 | channels[i].chan, | ||
8801 | channels[i].power_level, | ||
8802 | channels[i]. | ||
8803 | flag & IEEE80211_CHAN_W_RADAR_DETECT ? | ||
8804 | " (IEEE 802.11h required)" : "", | ||
8805 | (!(channels[i].flag & IEEE80211_CHAN_W_IBSS) | ||
8806 | || (channels[i]. | ||
8807 | flag & | ||
8808 | IEEE80211_CHAN_W_RADAR_DETECT)) ? "" : | ||
8809 | ", IBSS", | ||
8810 | channels[i]. | ||
8811 | flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? | ||
8812 | "active/passive" : "passive only"); | ||
8813 | |||
8814 | return len; | ||
8815 | } | 8562 | } |
8816 | 8563 | ||
8817 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 8564 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -8990,7 +8737,6 @@ static struct attribute *iwl4965_sysfs_entries[] = { | |||
8990 | &dev_attr_statistics.attr, | 8737 | &dev_attr_statistics.attr, |
8991 | &dev_attr_status.attr, | 8738 | &dev_attr_status.attr, |
8992 | &dev_attr_temperature.attr, | 8739 | &dev_attr_temperature.attr, |
8993 | &dev_attr_tune.attr, | ||
8994 | &dev_attr_tx_power.attr, | 8740 | &dev_attr_tx_power.attr, |
8995 | 8741 | ||
8996 | NULL | 8742 | NULL |
@@ -9021,10 +8767,6 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
9021 | #ifdef CONFIG_IWL4965_HT | 8767 | #ifdef CONFIG_IWL4965_HT |
9022 | .conf_ht = iwl4965_mac_conf_ht, | 8768 | .conf_ht = iwl4965_mac_conf_ht, |
9023 | .ampdu_action = iwl4965_mac_ampdu_action, | 8769 | .ampdu_action = iwl4965_mac_ampdu_action, |
9024 | #ifdef CONFIG_IWL4965_HT_AGG | ||
9025 | .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start, | ||
9026 | .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop, | ||
9027 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
9028 | #endif /* CONFIG_IWL4965_HT */ | 8770 | #endif /* CONFIG_IWL4965_HT */ |
9029 | .hw_scan = iwl4965_mac_hw_scan | 8771 | .hw_scan = iwl4965_mac_hw_scan |
9030 | }; | 8772 | }; |
@@ -9093,10 +8835,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9093 | /* Default value; 4 EDCA QOS priorities */ | 8835 | /* Default value; 4 EDCA QOS priorities */ |
9094 | hw->queues = 4; | 8836 | hw->queues = 4; |
9095 | #ifdef CONFIG_IWL4965_HT | 8837 | #ifdef CONFIG_IWL4965_HT |
9096 | #ifdef CONFIG_IWL4965_HT_AGG | ||
9097 | /* Enhanced value; more queues, to support 11n aggregation */ | 8838 | /* Enhanced value; more queues, to support 11n aggregation */ |
9098 | hw->queues = 16; | 8839 | hw->queues = 16; |
9099 | #endif /* CONFIG_IWL4965_HT_AGG */ | ||
9100 | #endif /* CONFIG_IWL4965_HT */ | 8840 | #endif /* CONFIG_IWL4965_HT */ |
9101 | 8841 | ||
9102 | spin_lock_init(&priv->lock); | 8842 | spin_lock_init(&priv->lock); |
@@ -9124,7 +8864,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9124 | priv->data_retry_limit = -1; | 8864 | priv->data_retry_limit = -1; |
9125 | priv->ieee_channels = NULL; | 8865 | priv->ieee_channels = NULL; |
9126 | priv->ieee_rates = NULL; | 8866 | priv->ieee_rates = NULL; |
9127 | priv->phymode = -1; | 8867 | priv->band = IEEE80211_BAND_2GHZ; |
9128 | 8868 | ||
9129 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | 8869 | err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); |
9130 | if (!err) | 8870 | if (!err) |
@@ -9180,7 +8920,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9180 | goto out_iounmap; | 8920 | goto out_iounmap; |
9181 | } | 8921 | } |
9182 | 8922 | ||
9183 | #ifdef CONFIG_IWL4965_QOS | ||
9184 | if (iwl4965_param_qos_enable) | 8923 | if (iwl4965_param_qos_enable) |
9185 | priv->qos_data.qos_enable = 1; | 8924 | priv->qos_data.qos_enable = 1; |
9186 | 8925 | ||
@@ -9188,9 +8927,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9188 | 8927 | ||
9189 | priv->qos_data.qos_active = 0; | 8928 | priv->qos_data.qos_active = 0; |
9190 | priv->qos_data.qos_cap.val = 0; | 8929 | priv->qos_data.qos_cap.val = 0; |
9191 | #endif /* CONFIG_IWL4965_QOS */ | ||
9192 | 8930 | ||
9193 | iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6); | 8931 | iwl4965_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); |
9194 | iwl4965_setup_deferred_work(priv); | 8932 | iwl4965_setup_deferred_work(priv); |
9195 | iwl4965_setup_rx_handlers(priv); | 8933 | iwl4965_setup_rx_handlers(priv); |
9196 | 8934 | ||
@@ -9241,7 +8979,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
9241 | IWL_ERROR("initializing geos failed: %d\n", err); | 8979 | IWL_ERROR("initializing geos failed: %d\n", err); |
9242 | goto out_free_channel_map; | 8980 | goto out_free_channel_map; |
9243 | } | 8981 | } |
9244 | iwl4965_reset_channel_flag(priv); | ||
9245 | 8982 | ||
9246 | iwl4965_rate_control_register(priv->hw); | 8983 | iwl4965_rate_control_register(priv->hw); |
9247 | err = ieee80211_register_hw(priv->hw); | 8984 | err = ieee80211_register_hw(priv->hw); |
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 87e145ffe8f1..75f6191e718d 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -181,17 +181,6 @@ int lbs_update_channel(struct lbs_private *priv) | |||
181 | return ret; | 181 | return ret; |
182 | } | 182 | } |
183 | 183 | ||
184 | void lbs_sync_channel(struct work_struct *work) | ||
185 | { | ||
186 | struct lbs_private *priv = container_of(work, struct lbs_private, | ||
187 | sync_channel); | ||
188 | |||
189 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
190 | if (lbs_update_channel(priv)) | ||
191 | lbs_pr_info("Channel synchronization failed."); | ||
192 | lbs_deb_leave(LBS_DEB_ASSOC); | ||
193 | } | ||
194 | |||
195 | static int assoc_helper_channel(struct lbs_private *priv, | 184 | static int assoc_helper_channel(struct lbs_private *priv, |
196 | struct assoc_request * assoc_req) | 185 | struct assoc_request * assoc_req) |
197 | { | 186 | { |
@@ -413,11 +402,10 @@ static int should_deauth_infrastructure(struct lbs_private *priv, | |||
413 | { | 402 | { |
414 | int ret = 0; | 403 | int ret = 0; |
415 | 404 | ||
416 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
417 | |||
418 | if (priv->connect_status != LBS_CONNECTED) | 405 | if (priv->connect_status != LBS_CONNECTED) |
419 | return 0; | 406 | return 0; |
420 | 407 | ||
408 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
421 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 409 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
422 | lbs_deb_assoc("Deauthenticating due to new SSID\n"); | 410 | lbs_deb_assoc("Deauthenticating due to new SSID\n"); |
423 | ret = 1; | 411 | ret = 1; |
@@ -456,7 +444,7 @@ static int should_deauth_infrastructure(struct lbs_private *priv, | |||
456 | 444 | ||
457 | out: | 445 | out: |
458 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 446 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
459 | return 0; | 447 | return ret; |
460 | } | 448 | } |
461 | 449 | ||
462 | 450 | ||
@@ -643,9 +631,7 @@ void lbs_association_worker(struct work_struct *work) | |||
643 | } | 631 | } |
644 | 632 | ||
645 | if (success) { | 633 | if (success) { |
646 | lbs_deb_assoc("ASSOC: associated to '%s', %s\n", | 634 | lbs_deb_assoc("associated to %s\n", |
647 | escape_essid(priv->curbssparams.ssid, | ||
648 | priv->curbssparams.ssid_len), | ||
649 | print_mac(mac, priv->curbssparams.bssid)); | 635 | print_mac(mac, priv->curbssparams.bssid)); |
650 | lbs_prepare_and_send_command(priv, | 636 | lbs_prepare_and_send_command(priv, |
651 | CMD_802_11_RSSI, | 637 | CMD_802_11_RSSI, |
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index 08372bbf3761..d489cf4cc1e2 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h | |||
@@ -7,6 +7,5 @@ | |||
7 | 7 | ||
8 | void lbs_association_worker(struct work_struct *work); | 8 | void lbs_association_worker(struct work_struct *work); |
9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); | 9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); |
10 | void lbs_sync_channel(struct work_struct *work); | ||
11 | 10 | ||
12 | #endif /* _LBS_ASSOC_H */ | 11 | #endif /* _LBS_ASSOC_H */ |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index b3c1acbcc655..3f9074df91e4 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1153,9 +1153,9 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1153 | command == CMD_802_11_AUTHENTICATE) | 1153 | command == CMD_802_11_AUTHENTICATE) |
1154 | timeo = 10 * HZ; | 1154 | timeo = 10 * HZ; |
1155 | 1155 | ||
1156 | lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", | 1156 | lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n", |
1157 | command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); | 1157 | command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies); |
1158 | lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); | 1158 | lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize); |
1159 | 1159 | ||
1160 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); | 1160 | ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize); |
1161 | 1161 | ||
@@ -1164,9 +1164,7 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1164 | /* Let the timer kick in and retry, and potentially reset | 1164 | /* Let the timer kick in and retry, and potentially reset |
1165 | the whole thing if the condition persists */ | 1165 | the whole thing if the condition persists */ |
1166 | timeo = HZ; | 1166 | timeo = HZ; |
1167 | } else | 1167 | } |
1168 | lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", | ||
1169 | command, jiffies); | ||
1170 | 1168 | ||
1171 | /* Setup the timer after transmit command */ | 1169 | /* Setup the timer after transmit command */ |
1172 | mod_timer(&priv->command_timer, jiffies + timeo); | 1170 | mod_timer(&priv->command_timer, jiffies + timeo); |
@@ -1185,7 +1183,7 @@ static int lbs_cmd_mac_control(struct lbs_private *priv, | |||
1185 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); | 1183 | cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_control) + S_DS_GEN); |
1186 | mac->action = cpu_to_le16(priv->currentpacketfilter); | 1184 | mac->action = cpu_to_le16(priv->currentpacketfilter); |
1187 | 1185 | ||
1188 | lbs_deb_cmd("MAC_CONTROL: action 0x%x, size %d\n", | 1186 | lbs_deb_cmd("MAC_CONTROL: action 0x%04x, size %d\n", |
1189 | le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); | 1187 | le16_to_cpu(mac->action), le16_to_cpu(cmd->size)); |
1190 | 1188 | ||
1191 | lbs_deb_leave(LBS_DEB_CMD); | 1189 | lbs_deb_leave(LBS_DEB_CMD); |
@@ -1741,9 +1739,9 @@ int lbs_execute_next_command(struct lbs_private *priv) | |||
1741 | unsigned long flags; | 1739 | unsigned long flags; |
1742 | int ret = 0; | 1740 | int ret = 0; |
1743 | 1741 | ||
1744 | // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the | 1742 | /* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the |
1745 | // only caller to us is lbs_thread() and we get even when a | 1743 | * only caller to us is lbs_thread() and we get even when a |
1746 | // data packet is received | 1744 | * data packet is received */ |
1747 | lbs_deb_enter(LBS_DEB_THREAD); | 1745 | lbs_deb_enter(LBS_DEB_THREAD); |
1748 | 1746 | ||
1749 | spin_lock_irqsave(&priv->driver_lock, flags); | 1747 | spin_lock_irqsave(&priv->driver_lock, flags); |
@@ -2043,15 +2041,8 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | |||
2043 | struct cmd_header *buf = (void *)extra; | 2041 | struct cmd_header *buf = (void *)extra; |
2044 | uint16_t copy_len; | 2042 | uint16_t copy_len; |
2045 | 2043 | ||
2046 | lbs_deb_enter(LBS_DEB_CMD); | ||
2047 | |||
2048 | copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); | 2044 | copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size)); |
2049 | lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, " | ||
2050 | "copy back buffer was %u bytes\n", copy_len, | ||
2051 | le16_to_cpu(resp->size), le16_to_cpu(buf->size)); | ||
2052 | memcpy(buf, resp, copy_len); | 2045 | memcpy(buf, resp, copy_len); |
2053 | |||
2054 | lbs_deb_leave(LBS_DEB_CMD); | ||
2055 | return 0; | 2046 | return 0; |
2056 | } | 2047 | } |
2057 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | 2048 | EXPORT_SYMBOL_GPL(lbs_cmd_copyback); |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 159216a91903..a0a5dbe81b3b 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -74,7 +74,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) | |||
74 | lbs_deb_cmd("disconnected, so exit PS mode\n"); | 74 | lbs_deb_cmd("disconnected, so exit PS mode\n"); |
75 | lbs_ps_wakeup(priv, 0); | 75 | lbs_ps_wakeup(priv, 0); |
76 | } | 76 | } |
77 | lbs_deb_leave(LBS_DEB_CMD); | 77 | lbs_deb_leave(LBS_DEB_ASSOC); |
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
@@ -568,9 +568,9 @@ int lbs_process_rx_command(struct lbs_private *priv) | |||
568 | respcmd = le16_to_cpu(resp->command); | 568 | respcmd = le16_to_cpu(resp->command); |
569 | result = le16_to_cpu(resp->result); | 569 | result = le16_to_cpu(resp->result); |
570 | 570 | ||
571 | lbs_deb_host("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n", | 571 | lbs_deb_cmd("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n", |
572 | respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); | 572 | respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies); |
573 | lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len); | 573 | lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, priv->upld_len); |
574 | 574 | ||
575 | if (resp->seqnum != resp->seqnum) { | 575 | if (resp->seqnum != resp->seqnum) { |
576 | lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", | 576 | lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n", |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index fd67b770dd78..b600f2439b57 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -315,7 +315,7 @@ static ssize_t lbs_setuserscan(struct file *file, | |||
315 | 315 | ||
316 | lbs_scan_networks(priv, scan_cfg, 1); | 316 | lbs_scan_networks(priv, scan_cfg, 1); |
317 | wait_event_interruptible(priv->cmd_pending, | 317 | wait_event_interruptible(priv->cmd_pending, |
318 | priv->surpriseremoved || !priv->last_scanned_channel); | 318 | priv->surpriseremoved || !priv->scan_channel); |
319 | 319 | ||
320 | if (priv->surpriseremoved) | 320 | if (priv->surpriseremoved) |
321 | goto out_scan_cfg; | 321 | goto out_scan_cfg; |
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 5a69f2b60865..fd1fcc748010 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -143,9 +143,12 @@ struct lbs_private { | |||
143 | wait_queue_head_t waitq; | 143 | wait_queue_head_t waitq; |
144 | struct workqueue_struct *work_thread; | 144 | struct workqueue_struct *work_thread; |
145 | 145 | ||
146 | /** Scanning */ | ||
146 | struct delayed_work scan_work; | 147 | struct delayed_work scan_work; |
147 | struct delayed_work assoc_work; | 148 | struct delayed_work assoc_work; |
148 | struct work_struct sync_channel; | 149 | struct work_struct sync_channel; |
150 | /* remember which channel was scanned last, != 0 if currently scanning */ | ||
151 | int scan_channel; | ||
149 | 152 | ||
150 | /** Hardware access */ | 153 | /** Hardware access */ |
151 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); | 154 | int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); |
@@ -321,7 +324,6 @@ struct lbs_private { | |||
321 | struct cmd_ds_802_11_get_log logmsg; | 324 | struct cmd_ds_802_11_get_log logmsg; |
322 | 325 | ||
323 | u32 monitormode; | 326 | u32 monitormode; |
324 | int last_scanned_channel; | ||
325 | u8 fw_ready; | 327 | u8 fw_ready; |
326 | }; | 328 | }; |
327 | 329 | ||
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index 2d4508048b68..56e64a697c37 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c | |||
@@ -99,23 +99,6 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | /** | 101 | /** |
102 | * @brief Unsets the MSB on basic rates | ||
103 | * | ||
104 | * Scan through an array and unset the MSB for basic data rates. | ||
105 | * | ||
106 | * @param rates buffer of data rates | ||
107 | * @param len size of buffer | ||
108 | */ | ||
109 | void lbs_unset_basic_rate_flags(u8 *rates, size_t len) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | for (i = 0; i < len; i++) | ||
114 | rates[i] &= 0x7f; | ||
115 | } | ||
116 | |||
117 | |||
118 | /** | ||
119 | * @brief Associate to a specific BSS discovered in a scan | 102 | * @brief Associate to a specific BSS discovered in a scan |
120 | * | 103 | * |
121 | * @param priv A pointer to struct lbs_private structure | 104 | * @param priv A pointer to struct lbs_private structure |
@@ -769,9 +752,6 @@ int lbs_ret_80211_associate(struct lbs_private *priv, | |||
769 | priv->curbssparams.ssid_len = bss->ssid_len; | 752 | priv->curbssparams.ssid_len = bss->ssid_len; |
770 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); | 753 | memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN); |
771 | 754 | ||
772 | lbs_deb_assoc("ASSOC_RESP: currentpacketfilter is 0x%x\n", | ||
773 | priv->currentpacketfilter); | ||
774 | |||
775 | priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; | 755 | priv->SNR[TYPE_RXPD][TYPE_AVG] = 0; |
776 | priv->NF[TYPE_RXPD][TYPE_AVG] = 0; | 756 | priv->NF[TYPE_RXPD][TYPE_AVG] = 0; |
777 | 757 | ||
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index c617d071f781..792c64fe3514 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h | |||
@@ -48,6 +48,4 @@ int lbs_send_deauthentication(struct lbs_private *priv); | |||
48 | 48 | ||
49 | int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); | 49 | int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); |
50 | 50 | ||
51 | void lbs_unset_basic_rate_flags(u8 *rates, size_t len); | ||
52 | |||
53 | #endif | 51 | #endif |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 4d4e2f3b66ac..2e5bac826c48 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -985,6 +985,18 @@ out: | |||
985 | lbs_deb_leave(LBS_DEB_CMD); | 985 | lbs_deb_leave(LBS_DEB_CMD); |
986 | } | 986 | } |
987 | 987 | ||
988 | static void lbs_sync_channel_worker(struct work_struct *work) | ||
989 | { | ||
990 | struct lbs_private *priv = container_of(work, struct lbs_private, | ||
991 | sync_channel); | ||
992 | |||
993 | lbs_deb_enter(LBS_DEB_MAIN); | ||
994 | if (lbs_update_channel(priv)) | ||
995 | lbs_pr_info("Channel synchronization failed."); | ||
996 | lbs_deb_leave(LBS_DEB_MAIN); | ||
997 | } | ||
998 | |||
999 | |||
988 | static int lbs_init_adapter(struct lbs_private *priv) | 1000 | static int lbs_init_adapter(struct lbs_private *priv) |
989 | { | 1001 | { |
990 | size_t bufsize; | 1002 | size_t bufsize; |
@@ -1128,7 +1140,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | |||
1128 | priv->work_thread = create_singlethread_workqueue("lbs_worker"); | 1140 | priv->work_thread = create_singlethread_workqueue("lbs_worker"); |
1129 | INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); | 1141 | INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); |
1130 | INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); | 1142 | INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); |
1131 | INIT_WORK(&priv->sync_channel, lbs_sync_channel); | 1143 | INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker); |
1132 | 1144 | ||
1133 | sprintf(priv->mesh_ssid, "mesh"); | 1145 | sprintf(priv->mesh_ssid, "mesh"); |
1134 | priv->mesh_ssid_len = 4; | 1146 | priv->mesh_ssid_len = 4; |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 69f94c92b32d..7d4f3afa8cc5 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -73,6 +73,23 @@ static const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | |||
73 | /* */ | 73 | /* */ |
74 | /*********************************************************************/ | 74 | /*********************************************************************/ |
75 | 75 | ||
76 | /** | ||
77 | * @brief Unsets the MSB on basic rates | ||
78 | * | ||
79 | * Scan through an array and unset the MSB for basic data rates. | ||
80 | * | ||
81 | * @param rates buffer of data rates | ||
82 | * @param len size of buffer | ||
83 | */ | ||
84 | static void lbs_unset_basic_rate_flags(u8 *rates, size_t len) | ||
85 | { | ||
86 | int i; | ||
87 | |||
88 | for (i = 0; i < len; i++) | ||
89 | rates[i] &= 0x7f; | ||
90 | } | ||
91 | |||
92 | |||
76 | static inline void clear_bss_descriptor (struct bss_descriptor * bss) | 93 | static inline void clear_bss_descriptor (struct bss_descriptor * bss) |
77 | { | 94 | { |
78 | /* Don't blow away ->list, just BSS data */ | 95 | /* Don't blow away ->list, just BSS data */ |
@@ -595,13 +612,13 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
595 | } | 612 | } |
596 | 613 | ||
597 | /* Prepare to continue an interrupted scan */ | 614 | /* Prepare to continue an interrupted scan */ |
598 | lbs_deb_scan("chan_count %d, last_scanned_channel %d\n", | 615 | lbs_deb_scan("chan_count %d, scan_channel %d\n", |
599 | chan_count, priv->last_scanned_channel); | 616 | chan_count, priv->scan_channel); |
600 | curr_chans = chan_list; | 617 | curr_chans = chan_list; |
601 | /* advance channel list by already-scanned-channels */ | 618 | /* advance channel list by already-scanned-channels */ |
602 | if (priv->last_scanned_channel > 0) { | 619 | if (priv->scan_channel > 0) { |
603 | curr_chans += priv->last_scanned_channel; | 620 | curr_chans += priv->scan_channel; |
604 | chan_count -= priv->last_scanned_channel; | 621 | chan_count -= priv->scan_channel; |
605 | } | 622 | } |
606 | 623 | ||
607 | /* Send scan command(s) | 624 | /* Send scan command(s) |
@@ -627,10 +644,10 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
627 | !full_scan && | 644 | !full_scan && |
628 | !priv->surpriseremoved) { | 645 | !priv->surpriseremoved) { |
629 | /* -1 marks just that we're currently scanning */ | 646 | /* -1 marks just that we're currently scanning */ |
630 | if (priv->last_scanned_channel < 0) | 647 | if (priv->scan_channel < 0) |
631 | priv->last_scanned_channel = to_scan; | 648 | priv->scan_channel = to_scan; |
632 | else | 649 | else |
633 | priv->last_scanned_channel += to_scan; | 650 | priv->scan_channel += to_scan; |
634 | cancel_delayed_work(&priv->scan_work); | 651 | cancel_delayed_work(&priv->scan_work); |
635 | queue_delayed_work(priv->work_thread, &priv->scan_work, | 652 | queue_delayed_work(priv->work_thread, &priv->scan_work, |
636 | msecs_to_jiffies(300)); | 653 | msecs_to_jiffies(300)); |
@@ -654,7 +671,7 @@ int lbs_scan_networks(struct lbs_private *priv, | |||
654 | #endif | 671 | #endif |
655 | 672 | ||
656 | out2: | 673 | out2: |
657 | priv->last_scanned_channel = 0; | 674 | priv->scan_channel = 0; |
658 | 675 | ||
659 | out: | 676 | out: |
660 | if (priv->connect_status == LBS_CONNECTED) { | 677 | if (priv->connect_status == LBS_CONNECTED) { |
@@ -1376,7 +1393,7 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, | |||
1376 | queue_delayed_work(priv->work_thread, &priv->scan_work, | 1393 | queue_delayed_work(priv->work_thread, &priv->scan_work, |
1377 | msecs_to_jiffies(50)); | 1394 | msecs_to_jiffies(50)); |
1378 | /* set marker that currently a scan is taking place */ | 1395 | /* set marker that currently a scan is taking place */ |
1379 | priv->last_scanned_channel = -1; | 1396 | priv->scan_channel = -1; |
1380 | 1397 | ||
1381 | if (priv->surpriseremoved) | 1398 | if (priv->surpriseremoved) |
1382 | return -EIO; | 1399 | return -EIO; |
@@ -1410,7 +1427,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1410 | lbs_deb_enter(LBS_DEB_SCAN); | 1427 | lbs_deb_enter(LBS_DEB_SCAN); |
1411 | 1428 | ||
1412 | /* iwlist should wait until the current scan is finished */ | 1429 | /* iwlist should wait until the current scan is finished */ |
1413 | if (priv->last_scanned_channel) | 1430 | if (priv->scan_channel) |
1414 | return -EAGAIN; | 1431 | return -EAGAIN; |
1415 | 1432 | ||
1416 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ | 1433 | /* Update RSSI if current BSS is a locally created ad-hoc BSS */ |
diff --git a/drivers/net/wireless/p54.h b/drivers/net/wireless/p54.h index 744c866066c5..06d2c67f4c81 100644 --- a/drivers/net/wireless/p54.h +++ b/drivers/net/wireless/p54.h | |||
@@ -64,10 +64,6 @@ struct p54_common { | |||
64 | unsigned int tx_hdr_len; | 64 | unsigned int tx_hdr_len; |
65 | void *cached_vdcf; | 65 | void *cached_vdcf; |
66 | unsigned int fw_var; | 66 | unsigned int fw_var; |
67 | /* FIXME: this channels/modes/rates stuff sucks */ | ||
68 | struct ieee80211_channel channels[14]; | ||
69 | struct ieee80211_rate rates[12]; | ||
70 | struct ieee80211_hw_mode modes[2]; | ||
71 | struct ieee80211_tx_queue_stats tx_stats; | 67 | struct ieee80211_tx_queue_stats tx_stats; |
72 | }; | 68 | }; |
73 | 69 | ||
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c index 5cda49aff3a8..84cc000e71aa 100644 --- a/drivers/net/wireless/p54common.c +++ b/drivers/net/wireless/p54common.c | |||
@@ -27,6 +27,46 @@ MODULE_DESCRIPTION("Softmac Prism54 common code"); | |||
27 | MODULE_LICENSE("GPL"); | 27 | MODULE_LICENSE("GPL"); |
28 | MODULE_ALIAS("prism54common"); | 28 | MODULE_ALIAS("prism54common"); |
29 | 29 | ||
30 | static struct ieee80211_rate p54_rates[] = { | ||
31 | { .bitrate = 10, .hw_value = 0, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
32 | { .bitrate = 20, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
33 | { .bitrate = 55, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
34 | { .bitrate = 110, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
35 | { .bitrate = 60, .hw_value = 4, }, | ||
36 | { .bitrate = 90, .hw_value = 5, }, | ||
37 | { .bitrate = 120, .hw_value = 6, }, | ||
38 | { .bitrate = 180, .hw_value = 7, }, | ||
39 | { .bitrate = 240, .hw_value = 8, }, | ||
40 | { .bitrate = 360, .hw_value = 9, }, | ||
41 | { .bitrate = 480, .hw_value = 10, }, | ||
42 | { .bitrate = 540, .hw_value = 11, }, | ||
43 | }; | ||
44 | |||
45 | static struct ieee80211_channel p54_channels[] = { | ||
46 | { .center_freq = 2412, .hw_value = 1, }, | ||
47 | { .center_freq = 2417, .hw_value = 2, }, | ||
48 | { .center_freq = 2422, .hw_value = 3, }, | ||
49 | { .center_freq = 2427, .hw_value = 4, }, | ||
50 | { .center_freq = 2432, .hw_value = 5, }, | ||
51 | { .center_freq = 2437, .hw_value = 6, }, | ||
52 | { .center_freq = 2442, .hw_value = 7, }, | ||
53 | { .center_freq = 2447, .hw_value = 8, }, | ||
54 | { .center_freq = 2452, .hw_value = 9, }, | ||
55 | { .center_freq = 2457, .hw_value = 10, }, | ||
56 | { .center_freq = 2462, .hw_value = 11, }, | ||
57 | { .center_freq = 2467, .hw_value = 12, }, | ||
58 | { .center_freq = 2472, .hw_value = 13, }, | ||
59 | { .center_freq = 2484, .hw_value = 14, }, | ||
60 | }; | ||
61 | |||
62 | static struct ieee80211_supported_band band_2GHz = { | ||
63 | .channels = p54_channels, | ||
64 | .n_channels = ARRAY_SIZE(p54_channels), | ||
65 | .bitrates = p54_rates, | ||
66 | .n_bitrates = ARRAY_SIZE(p54_rates), | ||
67 | }; | ||
68 | |||
69 | |||
30 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | 70 | void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) |
31 | { | 71 | { |
32 | struct p54_common *priv = dev->priv; | 72 | struct p54_common *priv = dev->priv; |
@@ -251,6 +291,10 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
251 | case PDR_END: | 291 | case PDR_END: |
252 | i = len; | 292 | i = len; |
253 | break; | 293 | break; |
294 | default: | ||
295 | printk(KERN_INFO "p54: unknown eeprom code : 0x%x\n", | ||
296 | le16_to_cpu(entry->code)); | ||
297 | break; | ||
254 | } | 298 | } |
255 | 299 | ||
256 | entry = (void *)entry + (entry_len + 1)*2; | 300 | entry = (void *)entry + (entry_len + 1)*2; |
@@ -308,10 +352,10 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
308 | u16 freq = le16_to_cpu(hdr->freq); | 352 | u16 freq = le16_to_cpu(hdr->freq); |
309 | 353 | ||
310 | rx_status.ssi = hdr->rssi; | 354 | rx_status.ssi = hdr->rssi; |
311 | rx_status.rate = hdr->rate & 0x1f; /* report short preambles & CCK too */ | 355 | /* XX correct? */ |
312 | rx_status.channel = freq == 2484 ? 14 : (freq - 2407)/5; | 356 | rx_status.rate_idx = hdr->rate & 0xf; |
313 | rx_status.freq = freq; | 357 | rx_status.freq = freq; |
314 | rx_status.phymode = MODE_IEEE80211G; | 358 | rx_status.band = IEEE80211_BAND_2GHZ; |
315 | rx_status.antenna = hdr->antenna; | 359 | rx_status.antenna = hdr->antenna; |
316 | rx_status.mactime = le64_to_cpu(hdr->timestamp); | 360 | rx_status.mactime = le64_to_cpu(hdr->timestamp); |
317 | rx_status.flag |= RX_FLAG_TSFT; | 361 | rx_status.flag |= RX_FLAG_TSFT; |
@@ -349,7 +393,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
349 | while (entry != (struct sk_buff *)&priv->tx_queue) { | 393 | while (entry != (struct sk_buff *)&priv->tx_queue) { |
350 | range = (struct memrecord *)&entry->cb; | 394 | range = (struct memrecord *)&entry->cb; |
351 | if (range->start_addr == addr) { | 395 | if (range->start_addr == addr) { |
352 | struct ieee80211_tx_status status = {{0}}; | 396 | struct ieee80211_tx_status status; |
353 | struct p54_control_hdr *entry_hdr; | 397 | struct p54_control_hdr *entry_hdr; |
354 | struct p54_tx_control_allocdata *entry_data; | 398 | struct p54_tx_control_allocdata *entry_data; |
355 | int pad = 0; | 399 | int pad = 0; |
@@ -365,6 +409,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
365 | kfree_skb(entry); | 409 | kfree_skb(entry); |
366 | break; | 410 | break; |
367 | } | 411 | } |
412 | memset(&status, 0, sizeof(status)); | ||
368 | memcpy(&status.control, range->control, | 413 | memcpy(&status.control, range->control, |
369 | sizeof(status.control)); | 414 | sizeof(status.control)); |
370 | kfree(range->control); | 415 | kfree(range->control); |
@@ -547,7 +592,9 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
547 | txhdr->padding2 = 0; | 592 | txhdr->padding2 = 0; |
548 | 593 | ||
549 | /* TODO: add support for alternate retry TX rates */ | 594 | /* TODO: add support for alternate retry TX rates */ |
550 | rate = control->tx_rate; | 595 | rate = control->tx_rate->hw_value; |
596 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | ||
597 | rate |= 0x10; | ||
551 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 598 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) |
552 | rate |= 0x40; | 599 | rate |= 0x40; |
553 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 600 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
@@ -717,13 +764,12 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) | |||
717 | return 0; | 764 | return 0; |
718 | } | 765 | } |
719 | 766 | ||
720 | #define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, burst) \ | 767 | #define P54_SET_QUEUE(queue, ai_fs, cw_min, cw_max, _txop) \ |
721 | do { \ | 768 | do { \ |
722 | queue.aifs = cpu_to_le16(ai_fs); \ | 769 | queue.aifs = cpu_to_le16(ai_fs); \ |
723 | queue.cwmin = cpu_to_le16(cw_min); \ | 770 | queue.cwmin = cpu_to_le16(cw_min); \ |
724 | queue.cwmax = cpu_to_le16(cw_max); \ | 771 | queue.cwmax = cpu_to_le16(cw_max); \ |
725 | queue.txop = (burst == 0) ? \ | 772 | queue.txop = cpu_to_le16(_txop); \ |
726 | 0 : cpu_to_le16((burst * 100) / 32 + 1); \ | ||
727 | } while(0) | 773 | } while(0) |
728 | 774 | ||
729 | static void p54_init_vdcf(struct ieee80211_hw *dev) | 775 | static void p54_init_vdcf(struct ieee80211_hw *dev) |
@@ -741,10 +787,10 @@ static void p54_init_vdcf(struct ieee80211_hw *dev) | |||
741 | 787 | ||
742 | vdcf = (struct p54_tx_control_vdcf *) hdr->data; | 788 | vdcf = (struct p54_tx_control_vdcf *) hdr->data; |
743 | 789 | ||
744 | P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 0x000f); | 790 | P54_SET_QUEUE(vdcf->queue[0], 0x0002, 0x0003, 0x0007, 47); |
745 | P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 0x001e); | 791 | P54_SET_QUEUE(vdcf->queue[1], 0x0002, 0x0007, 0x000f, 94); |
746 | P54_SET_QUEUE(vdcf->queue[2], 0x0002, 0x000f, 0x03ff, 0x0014); | 792 | P54_SET_QUEUE(vdcf->queue[2], 0x0003, 0x000f, 0x03ff, 0); |
747 | P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0x0000); | 793 | P54_SET_QUEUE(vdcf->queue[3], 0x0007, 0x000f, 0x03ff, 0); |
748 | } | 794 | } |
749 | 795 | ||
750 | static void p54_set_vdcf(struct ieee80211_hw *dev) | 796 | static void p54_set_vdcf(struct ieee80211_hw *dev) |
@@ -849,7 +895,7 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) | |||
849 | { | 895 | { |
850 | int ret; | 896 | int ret; |
851 | 897 | ||
852 | ret = p54_set_freq(dev, cpu_to_le16(conf->freq)); | 898 | ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq)); |
853 | p54_set_vdcf(dev); | 899 | p54_set_vdcf(dev); |
854 | return ret; | 900 | return ret; |
855 | } | 901 | } |
@@ -897,7 +943,7 @@ static int p54_conf_tx(struct ieee80211_hw *dev, int queue, | |||
897 | 943 | ||
898 | if ((params) && !((queue < 0) || (queue > 4))) { | 944 | if ((params) && !((queue < 0) || (queue > 4))) { |
899 | P54_SET_QUEUE(vdcf->queue[queue], params->aifs, | 945 | P54_SET_QUEUE(vdcf->queue[queue], params->aifs, |
900 | params->cw_min, params->cw_max, params->burst_time); | 946 | params->cw_min, params->cw_max, params->txop); |
901 | } else | 947 | } else |
902 | return -EINVAL; | 948 | return -EINVAL; |
903 | 949 | ||
@@ -944,7 +990,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
944 | { | 990 | { |
945 | struct ieee80211_hw *dev; | 991 | struct ieee80211_hw *dev; |
946 | struct p54_common *priv; | 992 | struct p54_common *priv; |
947 | int i; | ||
948 | 993 | ||
949 | dev = ieee80211_alloc_hw(priv_data_len, &p54_ops); | 994 | dev = ieee80211_alloc_hw(priv_data_len, &p54_ops); |
950 | if (!dev) | 995 | if (!dev) |
@@ -953,18 +998,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
953 | priv = dev->priv; | 998 | priv = dev->priv; |
954 | priv->mode = IEEE80211_IF_TYPE_INVALID; | 999 | priv->mode = IEEE80211_IF_TYPE_INVALID; |
955 | skb_queue_head_init(&priv->tx_queue); | 1000 | skb_queue_head_init(&priv->tx_queue); |
956 | memcpy(priv->channels, p54_channels, sizeof(p54_channels)); | 1001 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; |
957 | memcpy(priv->rates, p54_rates, sizeof(p54_rates)); | ||
958 | priv->modes[1].mode = MODE_IEEE80211B; | ||
959 | priv->modes[1].num_rates = 4; | ||
960 | priv->modes[1].rates = priv->rates; | ||
961 | priv->modes[1].num_channels = ARRAY_SIZE(p54_channels); | ||
962 | priv->modes[1].channels = priv->channels; | ||
963 | priv->modes[0].mode = MODE_IEEE80211G; | ||
964 | priv->modes[0].num_rates = ARRAY_SIZE(p54_rates); | ||
965 | priv->modes[0].rates = priv->rates; | ||
966 | priv->modes[0].num_channels = ARRAY_SIZE(p54_channels); | ||
967 | priv->modes[0].channels = priv->channels; | ||
968 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ | 1002 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | /* not sure */ |
969 | IEEE80211_HW_RX_INCLUDES_FCS; | 1003 | IEEE80211_HW_RX_INCLUDES_FCS; |
970 | dev->channel_change_time = 1000; /* TODO: find actual value */ | 1004 | dev->channel_change_time = 1000; /* TODO: find actual value */ |
@@ -986,14 +1020,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
986 | 1020 | ||
987 | p54_init_vdcf(dev); | 1021 | p54_init_vdcf(dev); |
988 | 1022 | ||
989 | for (i = 0; i < 2; i++) { | ||
990 | if (ieee80211_register_hwmode(dev, &priv->modes[i])) { | ||
991 | kfree(priv->cached_vdcf); | ||
992 | ieee80211_free_hw(dev); | ||
993 | return NULL; | ||
994 | } | ||
995 | } | ||
996 | |||
997 | return dev; | 1023 | return dev; |
998 | } | 1024 | } |
999 | EXPORT_SYMBOL_GPL(p54_init_common); | 1025 | EXPORT_SYMBOL_GPL(p54_init_common); |
diff --git a/drivers/net/wireless/p54common.h b/drivers/net/wireless/p54common.h index a721334e20d9..dc9f4cef585e 100644 --- a/drivers/net/wireless/p54common.h +++ b/drivers/net/wireless/p54common.h | |||
@@ -251,79 +251,4 @@ struct p54_tx_control_vdcf { | |||
251 | __le16 frameburst; | 251 | __le16 frameburst; |
252 | } __attribute__ ((packed)); | 252 | } __attribute__ ((packed)); |
253 | 253 | ||
254 | static const struct ieee80211_rate p54_rates[] = { | ||
255 | { .rate = 10, | ||
256 | .val = 0, | ||
257 | .val2 = 0x10, | ||
258 | .flags = IEEE80211_RATE_CCK_2 }, | ||
259 | { .rate = 20, | ||
260 | .val = 1, | ||
261 | .val2 = 0x11, | ||
262 | .flags = IEEE80211_RATE_CCK_2 }, | ||
263 | { .rate = 55, | ||
264 | .val = 2, | ||
265 | .val2 = 0x12, | ||
266 | .flags = IEEE80211_RATE_CCK_2 }, | ||
267 | { .rate = 110, | ||
268 | .val = 3, | ||
269 | .val2 = 0x13, | ||
270 | .flags = IEEE80211_RATE_CCK_2 }, | ||
271 | { .rate = 60, | ||
272 | .val = 4, | ||
273 | .flags = IEEE80211_RATE_OFDM }, | ||
274 | { .rate = 90, | ||
275 | .val = 5, | ||
276 | .flags = IEEE80211_RATE_OFDM }, | ||
277 | { .rate = 120, | ||
278 | .val = 6, | ||
279 | .flags = IEEE80211_RATE_OFDM }, | ||
280 | { .rate = 180, | ||
281 | .val = 7, | ||
282 | .flags = IEEE80211_RATE_OFDM }, | ||
283 | { .rate = 240, | ||
284 | .val = 8, | ||
285 | .flags = IEEE80211_RATE_OFDM }, | ||
286 | { .rate = 360, | ||
287 | .val = 9, | ||
288 | .flags = IEEE80211_RATE_OFDM }, | ||
289 | { .rate = 480, | ||
290 | .val = 10, | ||
291 | .flags = IEEE80211_RATE_OFDM }, | ||
292 | { .rate = 540, | ||
293 | .val = 11, | ||
294 | .flags = IEEE80211_RATE_OFDM }, | ||
295 | }; | ||
296 | |||
297 | // TODO: just generate this.. | ||
298 | static const struct ieee80211_channel p54_channels[] = { | ||
299 | { .chan = 1, | ||
300 | .freq = 2412}, | ||
301 | { .chan = 2, | ||
302 | .freq = 2417}, | ||
303 | { .chan = 3, | ||
304 | .freq = 2422}, | ||
305 | { .chan = 4, | ||
306 | .freq = 2427}, | ||
307 | { .chan = 5, | ||
308 | .freq = 2432}, | ||
309 | { .chan = 6, | ||
310 | .freq = 2437}, | ||
311 | { .chan = 7, | ||
312 | .freq = 2442}, | ||
313 | { .chan = 8, | ||
314 | .freq = 2447}, | ||
315 | { .chan = 9, | ||
316 | .freq = 2452}, | ||
317 | { .chan = 10, | ||
318 | .freq = 2457}, | ||
319 | { .chan = 11, | ||
320 | .freq = 2462}, | ||
321 | { .chan = 12, | ||
322 | .freq = 2467}, | ||
323 | { .chan = 13, | ||
324 | .freq = 2472}, | ||
325 | { .chan = 14, | ||
326 | .freq = 2484} | ||
327 | }; | ||
328 | |||
329 | #endif /* PRISM54COMMON_H */ | 254 | #endif /* PRISM54COMMON_H */ |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 1b595a6525f4..2d91a56d6a39 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -165,7 +165,7 @@ prism54_update_stats(struct work_struct *work) | |||
165 | struct obj_bss bss, *bss2; | 165 | struct obj_bss bss, *bss2; |
166 | union oid_res_t r; | 166 | union oid_res_t r; |
167 | 167 | ||
168 | down(&priv->stats_sem); | 168 | mutex_lock(&priv->stats_lock); |
169 | 169 | ||
170 | /* Noise floor. | 170 | /* Noise floor. |
171 | * I'm not sure if the unit is dBm. | 171 | * I'm not sure if the unit is dBm. |
@@ -207,7 +207,7 @@ prism54_update_stats(struct work_struct *work) | |||
207 | mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r); | 207 | mgt_get_request(priv, DOT11_OID_MPDUTXFAILED, 0, NULL, &r); |
208 | priv->local_iwstatistics.discard.retries = r.u; | 208 | priv->local_iwstatistics.discard.retries = r.u; |
209 | 209 | ||
210 | up(&priv->stats_sem); | 210 | mutex_unlock(&priv->stats_lock); |
211 | 211 | ||
212 | return; | 212 | return; |
213 | } | 213 | } |
@@ -218,12 +218,12 @@ prism54_get_wireless_stats(struct net_device *ndev) | |||
218 | islpci_private *priv = netdev_priv(ndev); | 218 | islpci_private *priv = netdev_priv(ndev); |
219 | 219 | ||
220 | /* If the stats are being updated return old data */ | 220 | /* If the stats are being updated return old data */ |
221 | if (down_trylock(&priv->stats_sem) == 0) { | 221 | if (mutex_trylock(&priv->stats_lock) == 0) { |
222 | memcpy(&priv->iwstatistics, &priv->local_iwstatistics, | 222 | memcpy(&priv->iwstatistics, &priv->local_iwstatistics, |
223 | sizeof (struct iw_statistics)); | 223 | sizeof (struct iw_statistics)); |
224 | /* They won't be marked updated for the next time */ | 224 | /* They won't be marked updated for the next time */ |
225 | priv->local_iwstatistics.qual.updated = 0; | 225 | priv->local_iwstatistics.qual.updated = 0; |
226 | up(&priv->stats_sem); | 226 | mutex_unlock(&priv->stats_lock); |
227 | } else | 227 | } else |
228 | priv->iwstatistics.qual.updated = 0; | 228 | priv->iwstatistics.qual.updated = 0; |
229 | 229 | ||
@@ -1780,7 +1780,7 @@ prism54_set_raw(struct net_device *ndev, struct iw_request_info *info, | |||
1780 | void | 1780 | void |
1781 | prism54_acl_init(struct islpci_acl *acl) | 1781 | prism54_acl_init(struct islpci_acl *acl) |
1782 | { | 1782 | { |
1783 | sema_init(&acl->sem, 1); | 1783 | mutex_init(&acl->lock); |
1784 | INIT_LIST_HEAD(&acl->mac_list); | 1784 | INIT_LIST_HEAD(&acl->mac_list); |
1785 | acl->size = 0; | 1785 | acl->size = 0; |
1786 | acl->policy = MAC_POLICY_OPEN; | 1786 | acl->policy = MAC_POLICY_OPEN; |
@@ -1792,10 +1792,10 @@ prism54_clear_mac(struct islpci_acl *acl) | |||
1792 | struct list_head *ptr, *next; | 1792 | struct list_head *ptr, *next; |
1793 | struct mac_entry *entry; | 1793 | struct mac_entry *entry; |
1794 | 1794 | ||
1795 | down(&acl->sem); | 1795 | mutex_lock(&acl->lock); |
1796 | 1796 | ||
1797 | if (acl->size == 0) { | 1797 | if (acl->size == 0) { |
1798 | up(&acl->sem); | 1798 | mutex_unlock(&acl->lock); |
1799 | return; | 1799 | return; |
1800 | } | 1800 | } |
1801 | 1801 | ||
@@ -1806,7 +1806,7 @@ prism54_clear_mac(struct islpci_acl *acl) | |||
1806 | kfree(entry); | 1806 | kfree(entry); |
1807 | } | 1807 | } |
1808 | acl->size = 0; | 1808 | acl->size = 0; |
1809 | up(&acl->sem); | 1809 | mutex_unlock(&acl->lock); |
1810 | } | 1810 | } |
1811 | 1811 | ||
1812 | void | 1812 | void |
@@ -1833,13 +1833,13 @@ prism54_add_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1833 | 1833 | ||
1834 | memcpy(entry->addr, addr->sa_data, ETH_ALEN); | 1834 | memcpy(entry->addr, addr->sa_data, ETH_ALEN); |
1835 | 1835 | ||
1836 | if (down_interruptible(&acl->sem)) { | 1836 | if (mutex_lock_interruptible(&acl->lock)) { |
1837 | kfree(entry); | 1837 | kfree(entry); |
1838 | return -ERESTARTSYS; | 1838 | return -ERESTARTSYS; |
1839 | } | 1839 | } |
1840 | list_add_tail(&entry->_list, &acl->mac_list); | 1840 | list_add_tail(&entry->_list, &acl->mac_list); |
1841 | acl->size++; | 1841 | acl->size++; |
1842 | up(&acl->sem); | 1842 | mutex_unlock(&acl->lock); |
1843 | 1843 | ||
1844 | return 0; | 1844 | return 0; |
1845 | } | 1845 | } |
@@ -1856,18 +1856,18 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1856 | if (addr->sa_family != ARPHRD_ETHER) | 1856 | if (addr->sa_family != ARPHRD_ETHER) |
1857 | return -EOPNOTSUPP; | 1857 | return -EOPNOTSUPP; |
1858 | 1858 | ||
1859 | if (down_interruptible(&acl->sem)) | 1859 | if (mutex_lock_interruptible(&acl->lock)) |
1860 | return -ERESTARTSYS; | 1860 | return -ERESTARTSYS; |
1861 | list_for_each_entry(entry, &acl->mac_list, _list) { | 1861 | list_for_each_entry(entry, &acl->mac_list, _list) { |
1862 | if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { | 1862 | if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) { |
1863 | list_del(&entry->_list); | 1863 | list_del(&entry->_list); |
1864 | acl->size--; | 1864 | acl->size--; |
1865 | kfree(entry); | 1865 | kfree(entry); |
1866 | up(&acl->sem); | 1866 | mutex_unlock(&acl->lock); |
1867 | return 0; | 1867 | return 0; |
1868 | } | 1868 | } |
1869 | } | 1869 | } |
1870 | up(&acl->sem); | 1870 | mutex_unlock(&acl->lock); |
1871 | return -EINVAL; | 1871 | return -EINVAL; |
1872 | } | 1872 | } |
1873 | 1873 | ||
@@ -1882,7 +1882,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1882 | 1882 | ||
1883 | dwrq->length = 0; | 1883 | dwrq->length = 0; |
1884 | 1884 | ||
1885 | if (down_interruptible(&acl->sem)) | 1885 | if (mutex_lock_interruptible(&acl->lock)) |
1886 | return -ERESTARTSYS; | 1886 | return -ERESTARTSYS; |
1887 | 1887 | ||
1888 | list_for_each_entry(entry, &acl->mac_list, _list) { | 1888 | list_for_each_entry(entry, &acl->mac_list, _list) { |
@@ -1891,7 +1891,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info, | |||
1891 | dwrq->length++; | 1891 | dwrq->length++; |
1892 | dst++; | 1892 | dst++; |
1893 | } | 1893 | } |
1894 | up(&acl->sem); | 1894 | mutex_unlock(&acl->lock); |
1895 | return 0; | 1895 | return 0; |
1896 | } | 1896 | } |
1897 | 1897 | ||
@@ -1955,11 +1955,11 @@ prism54_mac_accept(struct islpci_acl *acl, char *mac) | |||
1955 | struct mac_entry *entry; | 1955 | struct mac_entry *entry; |
1956 | int res = 0; | 1956 | int res = 0; |
1957 | 1957 | ||
1958 | if (down_interruptible(&acl->sem)) | 1958 | if (mutex_lock_interruptible(&acl->lock)) |
1959 | return -ERESTARTSYS; | 1959 | return -ERESTARTSYS; |
1960 | 1960 | ||
1961 | if (acl->policy == MAC_POLICY_OPEN) { | 1961 | if (acl->policy == MAC_POLICY_OPEN) { |
1962 | up(&acl->sem); | 1962 | mutex_unlock(&acl->lock); |
1963 | return 1; | 1963 | return 1; |
1964 | } | 1964 | } |
1965 | 1965 | ||
@@ -1970,7 +1970,7 @@ prism54_mac_accept(struct islpci_acl *acl, char *mac) | |||
1970 | } | 1970 | } |
1971 | } | 1971 | } |
1972 | res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res; | 1972 | res = (acl->policy == MAC_POLICY_ACCEPT) ? !res : res; |
1973 | up(&acl->sem); | 1973 | mutex_unlock(&acl->lock); |
1974 | 1974 | ||
1975 | return res; | 1975 | return res; |
1976 | } | 1976 | } |
@@ -2114,7 +2114,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, | |||
2114 | if (wpa_ie_len > MAX_WPA_IE_LEN) | 2114 | if (wpa_ie_len > MAX_WPA_IE_LEN) |
2115 | wpa_ie_len = MAX_WPA_IE_LEN; | 2115 | wpa_ie_len = MAX_WPA_IE_LEN; |
2116 | 2116 | ||
2117 | down(&priv->wpa_sem); | 2117 | mutex_lock(&priv->wpa_lock); |
2118 | 2118 | ||
2119 | /* try to use existing entry */ | 2119 | /* try to use existing entry */ |
2120 | list_for_each(ptr, &priv->bss_wpa_list) { | 2120 | list_for_each(ptr, &priv->bss_wpa_list) { |
@@ -2165,7 +2165,7 @@ prism54_wpa_bss_ie_add(islpci_private *priv, u8 *bssid, | |||
2165 | kfree(bss); | 2165 | kfree(bss); |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | up(&priv->wpa_sem); | 2168 | mutex_unlock(&priv->wpa_lock); |
2169 | } | 2169 | } |
2170 | 2170 | ||
2171 | static size_t | 2171 | static size_t |
@@ -2175,7 +2175,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | |||
2175 | struct islpci_bss_wpa_ie *bss = NULL; | 2175 | struct islpci_bss_wpa_ie *bss = NULL; |
2176 | size_t len = 0; | 2176 | size_t len = 0; |
2177 | 2177 | ||
2178 | down(&priv->wpa_sem); | 2178 | mutex_lock(&priv->wpa_lock); |
2179 | 2179 | ||
2180 | list_for_each(ptr, &priv->bss_wpa_list) { | 2180 | list_for_each(ptr, &priv->bss_wpa_list) { |
2181 | bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); | 2181 | bss = list_entry(ptr, struct islpci_bss_wpa_ie, list); |
@@ -2187,7 +2187,7 @@ prism54_wpa_bss_ie_get(islpci_private *priv, u8 *bssid, u8 *wpa_ie) | |||
2187 | len = bss->wpa_ie_len; | 2187 | len = bss->wpa_ie_len; |
2188 | memcpy(wpa_ie, bss->wpa_ie, len); | 2188 | memcpy(wpa_ie, bss->wpa_ie, len); |
2189 | } | 2189 | } |
2190 | up(&priv->wpa_sem); | 2190 | mutex_unlock(&priv->wpa_lock); |
2191 | 2191 | ||
2192 | return len; | 2192 | return len; |
2193 | } | 2193 | } |
@@ -2196,7 +2196,7 @@ void | |||
2196 | prism54_wpa_bss_ie_init(islpci_private *priv) | 2196 | prism54_wpa_bss_ie_init(islpci_private *priv) |
2197 | { | 2197 | { |
2198 | INIT_LIST_HEAD(&priv->bss_wpa_list); | 2198 | INIT_LIST_HEAD(&priv->bss_wpa_list); |
2199 | sema_init(&priv->wpa_sem, 1); | 2199 | mutex_init(&priv->wpa_lock); |
2200 | } | 2200 | } |
2201 | 2201 | ||
2202 | void | 2202 | void |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index dbb538ccb4ec..eb7c1c6bcd8a 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -864,7 +864,7 @@ islpci_setup(struct pci_dev *pdev) | |||
864 | mutex_init(&priv->mgmt_lock); | 864 | mutex_init(&priv->mgmt_lock); |
865 | priv->mgmt_received = NULL; | 865 | priv->mgmt_received = NULL; |
866 | init_waitqueue_head(&priv->mgmt_wqueue); | 866 | init_waitqueue_head(&priv->mgmt_wqueue); |
867 | sema_init(&priv->stats_sem, 1); | 867 | mutex_init(&priv->stats_lock); |
868 | spin_lock_init(&priv->slock); | 868 | spin_lock_init(&priv->slock); |
869 | 869 | ||
870 | /* init state machine with off#1 state */ | 870 | /* init state machine with off#1 state */ |
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index 4e0182ce835b..8e55a5fcffae 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h | |||
@@ -55,7 +55,7 @@ struct islpci_acl { | |||
55 | enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy; | 55 | enum { MAC_POLICY_OPEN=0, MAC_POLICY_ACCEPT=1, MAC_POLICY_REJECT=2 } policy; |
56 | struct list_head mac_list; /* a list of mac_entry */ | 56 | struct list_head mac_list; /* a list of mac_entry */ |
57 | int size; /* size of queue */ | 57 | int size; /* size of queue */ |
58 | struct semaphore sem; /* accessed in ioctls and trap_work */ | 58 | struct mutex lock; /* accessed in ioctls and trap_work */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct islpci_membuf { | 61 | struct islpci_membuf { |
@@ -88,7 +88,7 @@ typedef struct { | |||
88 | 88 | ||
89 | /* Take care of the wireless stats */ | 89 | /* Take care of the wireless stats */ |
90 | struct work_struct stats_work; | 90 | struct work_struct stats_work; |
91 | struct semaphore stats_sem; | 91 | struct mutex stats_lock; |
92 | /* remember when we last updated the stats */ | 92 | /* remember when we last updated the stats */ |
93 | unsigned long stats_timestamp; | 93 | unsigned long stats_timestamp; |
94 | /* The first is accessed under semaphore locking. | 94 | /* The first is accessed under semaphore locking. |
@@ -178,7 +178,7 @@ typedef struct { | |||
178 | int wpa; /* WPA mode enabled */ | 178 | int wpa; /* WPA mode enabled */ |
179 | struct list_head bss_wpa_list; | 179 | struct list_head bss_wpa_list; |
180 | int num_bss_wpa; | 180 | int num_bss_wpa; |
181 | struct semaphore wpa_sem; | 181 | struct mutex wpa_lock; |
182 | u8 wpa_ie[MAX_WPA_IE_LEN]; | 182 | u8 wpa_ie[MAX_WPA_IE_LEN]; |
183 | size_t wpa_ie_len; | 183 | size_t wpa_ie_len; |
184 | 184 | ||
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index da05b1faf60d..d5240aa06233 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -5,29 +5,29 @@ config RT2X00 | |||
5 | This will enable the experimental support for the Ralink drivers, | 5 | This will enable the experimental support for the Ralink drivers, |
6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. | 6 | developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. |
7 | 7 | ||
8 | These drivers will make use of the Devicescape ieee80211 stack. | 8 | These drivers will make use of the mac80211 stack. |
9 | 9 | ||
10 | When building one of the individual drivers, the rt2x00 library | 10 | When building one of the individual drivers, the rt2x00 library |
11 | will also be created. That library (when the driver is built as | 11 | will also be created. That library (when the driver is built as |
12 | a module) will be called "rt2x00lib.ko". | 12 | a module) will be called "rt2x00lib.ko". |
13 | 13 | ||
14 | if RT2X00 | ||
15 | |||
14 | config RT2X00_LIB | 16 | config RT2X00_LIB |
15 | tristate | 17 | tristate |
16 | depends on RT2X00 | ||
17 | 18 | ||
18 | config RT2X00_LIB_PCI | 19 | config RT2X00_LIB_PCI |
19 | tristate | 20 | tristate |
20 | depends on RT2X00 | ||
21 | select RT2X00_LIB | 21 | select RT2X00_LIB |
22 | 22 | ||
23 | config RT2X00_LIB_USB | 23 | config RT2X00_LIB_USB |
24 | tristate | 24 | tristate |
25 | depends on RT2X00 | ||
26 | select RT2X00_LIB | 25 | select RT2X00_LIB |
27 | 26 | ||
28 | config RT2X00_LIB_FIRMWARE | 27 | config RT2X00_LIB_FIRMWARE |
29 | boolean | 28 | boolean |
30 | depends on RT2X00_LIB | 29 | depends on RT2X00_LIB |
30 | select CRC_CCITT | ||
31 | select CRC_ITU_T | 31 | select CRC_ITU_T |
32 | select FW_LOADER | 32 | select FW_LOADER |
33 | 33 | ||
@@ -37,9 +37,17 @@ config RT2X00_LIB_RFKILL | |||
37 | select RFKILL | 37 | select RFKILL |
38 | select INPUT_POLLDEV | 38 | select INPUT_POLLDEV |
39 | 39 | ||
40 | config RT2X00_LIB_LEDS | ||
41 | boolean | ||
42 | depends on RT2X00_LIB | ||
43 | select NEW_LEDS | ||
44 | select LEDS_CLASS | ||
45 | select LEDS_TRIGGERS | ||
46 | select MAC80211_LEDS | ||
47 | |||
40 | config RT2400PCI | 48 | config RT2400PCI |
41 | tristate "Ralink rt2400 pci/pcmcia support" | 49 | tristate "Ralink rt2400 pci/pcmcia support" |
42 | depends on RT2X00 && PCI | 50 | depends on PCI |
43 | select RT2X00_LIB_PCI | 51 | select RT2X00_LIB_PCI |
44 | select EEPROM_93CX6 | 52 | select EEPROM_93CX6 |
45 | ---help--- | 53 | ---help--- |
@@ -56,9 +64,16 @@ config RT2400PCI_RFKILL | |||
56 | hardware button to control the radio state. | 64 | hardware button to control the radio state. |
57 | This feature depends on the RF switch subsystem rfkill. | 65 | This feature depends on the RF switch subsystem rfkill. |
58 | 66 | ||
67 | config RT2400PCI_LEDS | ||
68 | bool "RT2400 leds support" | ||
69 | depends on RT2400PCI | ||
70 | select RT2X00_LIB_LEDS | ||
71 | ---help--- | ||
72 | This adds support for led triggers provided my mac80211. | ||
73 | |||
59 | config RT2500PCI | 74 | config RT2500PCI |
60 | tristate "Ralink rt2500 pci/pcmcia support" | 75 | tristate "Ralink rt2500 pci/pcmcia support" |
61 | depends on RT2X00 && PCI | 76 | depends on PCI |
62 | select RT2X00_LIB_PCI | 77 | select RT2X00_LIB_PCI |
63 | select EEPROM_93CX6 | 78 | select EEPROM_93CX6 |
64 | ---help--- | 79 | ---help--- |
@@ -75,9 +90,16 @@ config RT2500PCI_RFKILL | |||
75 | hardware button to control the radio state. | 90 | hardware button to control the radio state. |
76 | This feature depends on the RF switch subsystem rfkill. | 91 | This feature depends on the RF switch subsystem rfkill. |
77 | 92 | ||
93 | config RT2500PCI_LEDS | ||
94 | bool "RT2500 leds support" | ||
95 | depends on RT2500PCI | ||
96 | select RT2X00_LIB_LEDS | ||
97 | ---help--- | ||
98 | This adds support for led triggers provided my mac80211. | ||
99 | |||
78 | config RT61PCI | 100 | config RT61PCI |
79 | tristate "Ralink rt61 pci/pcmcia support" | 101 | tristate "Ralink rt61 pci/pcmcia support" |
80 | depends on RT2X00 && PCI | 102 | depends on PCI |
81 | select RT2X00_LIB_PCI | 103 | select RT2X00_LIB_PCI |
82 | select RT2X00_LIB_FIRMWARE | 104 | select RT2X00_LIB_FIRMWARE |
83 | select EEPROM_93CX6 | 105 | select EEPROM_93CX6 |
@@ -95,18 +117,32 @@ config RT61PCI_RFKILL | |||
95 | hardware button to control the radio state. | 117 | hardware button to control the radio state. |
96 | This feature depends on the RF switch subsystem rfkill. | 118 | This feature depends on the RF switch subsystem rfkill. |
97 | 119 | ||
120 | config RT61PCI_LEDS | ||
121 | bool "RT61 leds support" | ||
122 | depends on RT61PCI | ||
123 | select RT2X00_LIB_LEDS | ||
124 | ---help--- | ||
125 | This adds support for led triggers provided my mac80211. | ||
126 | |||
98 | config RT2500USB | 127 | config RT2500USB |
99 | tristate "Ralink rt2500 usb support" | 128 | tristate "Ralink rt2500 usb support" |
100 | depends on RT2X00 && USB | 129 | depends on USB |
101 | select RT2X00_LIB_USB | 130 | select RT2X00_LIB_USB |
102 | ---help--- | 131 | ---help--- |
103 | This is an experimental driver for the Ralink rt2500 wireless chip. | 132 | This is an experimental driver for the Ralink rt2500 wireless chip. |
104 | 133 | ||
105 | When compiled as a module, this driver will be called "rt2500usb.ko". | 134 | When compiled as a module, this driver will be called "rt2500usb.ko". |
106 | 135 | ||
136 | config RT2500USB_LEDS | ||
137 | bool "RT2500 leds support" | ||
138 | depends on RT2500USB | ||
139 | select RT2X00_LIB_LEDS | ||
140 | ---help--- | ||
141 | This adds support for led triggers provided my mac80211. | ||
142 | |||
107 | config RT73USB | 143 | config RT73USB |
108 | tristate "Ralink rt73 usb support" | 144 | tristate "Ralink rt73 usb support" |
109 | depends on RT2X00 && USB | 145 | depends on USB |
110 | select RT2X00_LIB_USB | 146 | select RT2X00_LIB_USB |
111 | select RT2X00_LIB_FIRMWARE | 147 | select RT2X00_LIB_FIRMWARE |
112 | ---help--- | 148 | ---help--- |
@@ -114,6 +150,13 @@ config RT73USB | |||
114 | 150 | ||
115 | When compiled as a module, this driver will be called "rt73usb.ko". | 151 | When compiled as a module, this driver will be called "rt73usb.ko". |
116 | 152 | ||
153 | config RT73USB_LEDS | ||
154 | bool "RT73 leds support" | ||
155 | depends on RT73USB | ||
156 | select RT2X00_LIB_LEDS | ||
157 | ---help--- | ||
158 | This adds support for led triggers provided my mac80211. | ||
159 | |||
117 | config RT2X00_LIB_DEBUGFS | 160 | config RT2X00_LIB_DEBUGFS |
118 | bool "Ralink debugfs support" | 161 | bool "Ralink debugfs support" |
119 | depends on RT2X00_LIB && MAC80211_DEBUGFS | 162 | depends on RT2X00_LIB && MAC80211_DEBUGFS |
@@ -128,3 +171,4 @@ config RT2X00_DEBUG | |||
128 | ---help--- | 171 | ---help--- |
129 | Enable debugging output for all rt2x00 modules | 172 | Enable debugging output for all rt2x00 modules |
130 | 173 | ||
174 | endif | ||
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 30d654a42eea..1087dbcf1a04 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile | |||
@@ -1,22 +1,17 @@ | |||
1 | rt2x00lib-objs := rt2x00dev.o rt2x00mac.o rt2x00config.o | 1 | rt2x00lib-y += rt2x00dev.o |
2 | rt2x00lib-y += rt2x00mac.o | ||
3 | rt2x00lib-y += rt2x00config.o | ||
4 | rt2x00lib-y += rt2x00queue.o | ||
5 | rt2x00lib-$(CONFIG_RT2X00_LIB_DEBUGFS) += rt2x00debug.o | ||
6 | rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL) += rt2x00rfkill.o | ||
7 | rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o | ||
8 | rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o | ||
2 | 9 | ||
3 | ifeq ($(CONFIG_RT2X00_LIB_DEBUGFS),y) | 10 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o |
4 | rt2x00lib-objs += rt2x00debug.o | 11 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o |
5 | endif | 12 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o |
6 | 13 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | |
7 | ifeq ($(CONFIG_RT2X00_LIB_RFKILL),y) | 14 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o |
8 | rt2x00lib-objs += rt2x00rfkill.o | 15 | obj-$(CONFIG_RT61PCI) += rt61pci.o |
9 | endif | 16 | obj-$(CONFIG_RT2500USB) += rt2500usb.o |
10 | 17 | obj-$(CONFIG_RT73USB) += rt73usb.o | |
11 | ifeq ($(CONFIG_RT2X00_LIB_FIRMWARE),y) | ||
12 | rt2x00lib-objs += rt2x00firmware.o | ||
13 | endif | ||
14 | |||
15 | obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o | ||
16 | obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o | ||
17 | obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o | ||
18 | obj-$(CONFIG_RT2400PCI) += rt2400pci.o | ||
19 | obj-$(CONFIG_RT2500PCI) += rt2500pci.o | ||
20 | obj-$(CONFIG_RT61PCI) += rt61pci.o | ||
21 | obj-$(CONFIG_RT2500USB) += rt2500usb.o | ||
22 | obj-$(CONFIG_RT73USB) += rt73usb.o | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index c69f85ed7669..460ef2fb5104 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,53 +243,77 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2400pci_rfkill_poll NULL | 243 | #define rt2400pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2400PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2400PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2400PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2400pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2400pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2400pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | unsigned int bcn_preload; | ||
266 | u32 reg; | 279 | u32 reg; |
267 | 280 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 281 | if (flags & CONFIG_UPDATE_TYPE) { |
282 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | 283 | ||
270 | /* | 284 | /* |
271 | * Enable beacon config | 285 | * Enable beacon config |
272 | */ | 286 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 287 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 288 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 289 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
276 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 290 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
277 | 291 | ||
278 | /* | 292 | /* |
279 | * Enable synchronisation. | 293 | * Enable synchronisation. |
280 | */ | 294 | */ |
281 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 295 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
282 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 296 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
283 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 297 | rt2x00_set_field32(®, CSR14_TBCN, |
284 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 298 | (conf->sync == TSF_SYNC_BEACON)); |
285 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 299 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
286 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 300 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
301 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
302 | } | ||
303 | |||
304 | if (flags & CONFIG_UPDATE_MAC) | ||
305 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
306 | conf->mac, sizeof(conf->mac)); | ||
307 | |||
308 | if (flags & CONFIG_UPDATE_BSSID) | ||
309 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
310 | conf->bssid, sizeof(conf->bssid)); | ||
287 | } | 311 | } |
288 | 312 | ||
289 | static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 313 | static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
290 | const int short_preamble, | 314 | const int short_preamble, |
291 | const int ack_timeout, | 315 | const int ack_timeout, |
292 | const int ack_consume_time) | 316 | const int ack_consume_time) |
293 | { | 317 | { |
294 | int preamble_mask; | 318 | int preamble_mask; |
295 | u32 reg; | 319 | u32 reg; |
@@ -327,6 +351,8 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
327 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 351 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
328 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 352 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
329 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 353 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
354 | |||
355 | return 0; | ||
330 | } | 356 | } |
331 | 357 | ||
332 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 358 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -481,8 +507,8 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
481 | } | 507 | } |
482 | 508 | ||
483 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 509 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
484 | const unsigned int flags, | 510 | struct rt2x00lib_conf *libconf, |
485 | struct rt2x00lib_conf *libconf) | 511 | const unsigned int flags) |
486 | { | 512 | { |
487 | if (flags & CONFIG_UPDATE_PHYMODE) | 513 | if (flags & CONFIG_UPDATE_PHYMODE) |
488 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); | 514 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -498,45 +524,17 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | |||
498 | } | 524 | } |
499 | 525 | ||
500 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, | 526 | static void rt2400pci_config_cw(struct rt2x00_dev *rt2x00dev, |
501 | struct ieee80211_tx_queue_params *params) | 527 | const int cw_min, const int cw_max) |
502 | { | 528 | { |
503 | u32 reg; | 529 | u32 reg; |
504 | 530 | ||
505 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); | 531 | rt2x00pci_register_read(rt2x00dev, CSR11, ®); |
506 | rt2x00_set_field32(®, CSR11_CWMIN, params->cw_min); | 532 | rt2x00_set_field32(®, CSR11_CWMIN, cw_min); |
507 | rt2x00_set_field32(®, CSR11_CWMAX, params->cw_max); | 533 | rt2x00_set_field32(®, CSR11_CWMAX, cw_max); |
508 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 534 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
509 | } | 535 | } |
510 | 536 | ||
511 | /* | 537 | /* |
512 | * LED functions. | ||
513 | */ | ||
514 | static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
515 | { | ||
516 | u32 reg; | ||
517 | |||
518 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
519 | |||
520 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
521 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
522 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
523 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
524 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
525 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
526 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
527 | } | ||
528 | |||
529 | static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
530 | { | ||
531 | u32 reg; | ||
532 | |||
533 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
534 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
535 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
536 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Link tuning | 538 | * Link tuning |
541 | */ | 539 | */ |
542 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | 540 | static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -593,90 +591,94 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
593 | * Initialization functions. | 591 | * Initialization functions. |
594 | */ | 592 | */ |
595 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 593 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
596 | struct data_entry *entry) | 594 | struct queue_entry *entry) |
597 | { | 595 | { |
598 | __le32 *rxd = entry->priv; | 596 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
599 | u32 word; | 597 | u32 word; |
600 | 598 | ||
601 | rt2x00_desc_read(rxd, 2, &word); | 599 | rt2x00_desc_read(priv_rx->desc, 2, &word); |
602 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 600 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, |
603 | rt2x00_desc_write(rxd, 2, word); | 601 | entry->queue->data_size); |
602 | rt2x00_desc_write(priv_rx->desc, 2, word); | ||
604 | 603 | ||
605 | rt2x00_desc_read(rxd, 1, &word); | 604 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
606 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 605 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
607 | rt2x00_desc_write(rxd, 1, word); | 606 | rt2x00_desc_write(priv_rx->desc, 1, word); |
608 | 607 | ||
609 | rt2x00_desc_read(rxd, 0, &word); | 608 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
610 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 609 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
611 | rt2x00_desc_write(rxd, 0, word); | 610 | rt2x00_desc_write(priv_rx->desc, 0, word); |
612 | } | 611 | } |
613 | 612 | ||
614 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 613 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
615 | struct data_entry *entry) | 614 | struct queue_entry *entry) |
616 | { | 615 | { |
617 | __le32 *txd = entry->priv; | 616 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
618 | u32 word; | 617 | u32 word; |
619 | 618 | ||
620 | rt2x00_desc_read(txd, 1, &word); | 619 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
621 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 620 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
622 | rt2x00_desc_write(txd, 1, word); | 621 | rt2x00_desc_write(priv_tx->desc, 1, word); |
623 | 622 | ||
624 | rt2x00_desc_read(txd, 2, &word); | 623 | rt2x00_desc_read(priv_tx->desc, 2, &word); |
625 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, entry->ring->data_size); | 624 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, |
626 | rt2x00_desc_write(txd, 2, word); | 625 | entry->queue->data_size); |
626 | rt2x00_desc_write(priv_tx->desc, 2, word); | ||
627 | 627 | ||
628 | rt2x00_desc_read(txd, 0, &word); | 628 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 629 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 630 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
631 | rt2x00_desc_write(txd, 0, word); | 631 | rt2x00_desc_write(priv_tx->desc, 0, word); |
632 | } | 632 | } |
633 | 633 | ||
634 | static int rt2400pci_init_rings(struct rt2x00_dev *rt2x00dev) | 634 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
635 | { | 635 | { |
636 | struct queue_entry_priv_pci_rx *priv_rx; | ||
637 | struct queue_entry_priv_pci_tx *priv_tx; | ||
636 | u32 reg; | 638 | u32 reg; |
637 | 639 | ||
638 | /* | 640 | /* |
639 | * Initialize registers. | 641 | * Initialize registers. |
640 | */ | 642 | */ |
641 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 643 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
642 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 644 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
643 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 645 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
644 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 646 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
645 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 647 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
646 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
647 | rt2x00dev->bcn[1].stats.limit); | ||
648 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
649 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
650 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 648 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
651 | 649 | ||
650 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
652 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 651 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
653 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 652 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
654 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 653 | priv_tx->desc_dma); |
655 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 654 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
656 | 655 | ||
656 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 657 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 658 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
659 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 659 | priv_tx->desc_dma); |
660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 660 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
661 | 661 | ||
662 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
662 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 663 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
663 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 664 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
664 | rt2x00dev->bcn[1].data_dma); | 665 | priv_tx->desc_dma); |
665 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 666 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
666 | 667 | ||
668 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
667 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 669 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
668 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 670 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
669 | rt2x00dev->bcn[0].data_dma); | 671 | priv_tx->desc_dma); |
670 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 672 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
671 | 673 | ||
672 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 674 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
673 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 675 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
674 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 676 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
675 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 677 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
676 | 678 | ||
679 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
677 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 680 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
678 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 681 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma); |
679 | rt2x00dev->rx->data_dma); | ||
680 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 682 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
681 | 683 | ||
682 | return 0; | 684 | return 0; |
@@ -702,6 +704,11 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
702 | (rt2x00dev->rx->data_size / 128)); | 704 | (rt2x00dev->rx->data_size / 128)); |
703 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); | 705 | rt2x00pci_register_write(rt2x00dev, CSR9, reg); |
704 | 706 | ||
707 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
708 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
709 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
710 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
711 | |||
705 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); | 712 | rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000); |
706 | 713 | ||
707 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); | 714 | rt2x00pci_register_read(rt2x00dev, ARCSR0, ®); |
@@ -795,19 +802,15 @@ continue_csr_init: | |||
795 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); | 802 | rt2400pci_bbp_write(rt2x00dev, 30, 0x21); |
796 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); | 803 | rt2400pci_bbp_write(rt2x00dev, 31, 0x00); |
797 | 804 | ||
798 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
799 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 805 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
800 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 806 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
801 | 807 | ||
802 | if (eeprom != 0xffff && eeprom != 0x0000) { | 808 | if (eeprom != 0xffff && eeprom != 0x0000) { |
803 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 809 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
804 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 810 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
805 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
806 | reg_id, value); | ||
807 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); | 811 | rt2400pci_bbp_write(rt2x00dev, reg_id, value); |
808 | } | 812 | } |
809 | } | 813 | } |
810 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
811 | 814 | ||
812 | return 0; | 815 | return 0; |
813 | } | 816 | } |
@@ -859,7 +862,7 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
859 | /* | 862 | /* |
860 | * Initialize all registers. | 863 | * Initialize all registers. |
861 | */ | 864 | */ |
862 | if (rt2400pci_init_rings(rt2x00dev) || | 865 | if (rt2400pci_init_queues(rt2x00dev) || |
863 | rt2400pci_init_registers(rt2x00dev) || | 866 | rt2400pci_init_registers(rt2x00dev) || |
864 | rt2400pci_init_bbp(rt2x00dev)) { | 867 | rt2400pci_init_bbp(rt2x00dev)) { |
865 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 868 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -871,11 +874,6 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
871 | */ | 874 | */ |
872 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 875 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
873 | 876 | ||
874 | /* | ||
875 | * Enable LED | ||
876 | */ | ||
877 | rt2400pci_enable_led(rt2x00dev); | ||
878 | |||
879 | return 0; | 877 | return 0; |
880 | } | 878 | } |
881 | 879 | ||
@@ -883,11 +881,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
883 | { | 881 | { |
884 | u32 reg; | 882 | u32 reg; |
885 | 883 | ||
886 | /* | ||
887 | * Disable LED | ||
888 | */ | ||
889 | rt2400pci_disable_led(rt2x00dev); | ||
890 | |||
891 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 884 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
892 | 885 | ||
893 | /* | 886 | /* |
@@ -986,10 +979,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
986 | */ | 979 | */ |
987 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 980 | static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
988 | struct sk_buff *skb, | 981 | struct sk_buff *skb, |
989 | struct txdata_entry_desc *desc, | 982 | struct txentry_desc *txdesc, |
990 | struct ieee80211_tx_control *control) | 983 | struct ieee80211_tx_control *control) |
991 | { | 984 | { |
992 | struct skb_desc *skbdesc = get_skb_desc(skb); | 985 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
993 | __le32 *txd = skbdesc->desc; | 986 | __le32 *txd = skbdesc->desc; |
994 | u32 word; | 987 | u32 word; |
995 | 988 | ||
@@ -1001,19 +994,19 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1001 | rt2x00_desc_write(txd, 2, word); | 994 | rt2x00_desc_write(txd, 2, word); |
1002 | 995 | ||
1003 | rt2x00_desc_read(txd, 3, &word); | 996 | rt2x00_desc_read(txd, 3, &word); |
1004 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 997 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1005 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); | 998 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); |
1006 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); | 999 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); |
1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1000 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); | 1001 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); |
1009 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); | 1002 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); |
1010 | rt2x00_desc_write(txd, 3, word); | 1003 | rt2x00_desc_write(txd, 3, word); |
1011 | 1004 | ||
1012 | rt2x00_desc_read(txd, 4, &word); | 1005 | rt2x00_desc_read(txd, 4, &word); |
1013 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low); | 1006 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, txdesc->length_low); |
1014 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); | 1007 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); |
1015 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); | 1008 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); |
1016 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high); | 1009 | rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, txdesc->length_high); |
1017 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); | 1010 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); |
1018 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); | 1011 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); |
1019 | rt2x00_desc_write(txd, 4, word); | 1012 | rt2x00_desc_write(txd, 4, word); |
@@ -1022,14 +1015,14 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1022 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1015 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1023 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1016 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1024 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1017 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1025 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1018 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1026 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1019 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1027 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1020 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1028 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1021 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1029 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1022 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1030 | rt2x00_set_field32(&word, TXD_W0_RTS, | 1023 | rt2x00_set_field32(&word, TXD_W0_RTS, |
1031 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1024 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1032 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1025 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1033 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1026 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1034 | !!(control->flags & | 1027 | !!(control->flags & |
1035 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1028 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1040,11 +1033,11 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1040 | * TX data initialization | 1033 | * TX data initialization |
1041 | */ | 1034 | */ |
1042 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1035 | static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1043 | unsigned int queue) | 1036 | const unsigned int queue) |
1044 | { | 1037 | { |
1045 | u32 reg; | 1038 | u32 reg; |
1046 | 1039 | ||
1047 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1040 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1048 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1041 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1049 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1042 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1050 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1043 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
@@ -1059,56 +1052,56 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1059 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1052 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1060 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1053 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1061 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1054 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1062 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1055 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1063 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1056 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1064 | } | 1057 | } |
1065 | 1058 | ||
1066 | /* | 1059 | /* |
1067 | * RX control handlers | 1060 | * RX control handlers |
1068 | */ | 1061 | */ |
1069 | static void rt2400pci_fill_rxdone(struct data_entry *entry, | 1062 | static void rt2400pci_fill_rxdone(struct queue_entry *entry, |
1070 | struct rxdata_entry_desc *desc) | 1063 | struct rxdone_entry_desc *rxdesc) |
1071 | { | 1064 | { |
1072 | __le32 *rxd = entry->priv; | 1065 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1073 | u32 word0; | 1066 | u32 word0; |
1074 | u32 word2; | 1067 | u32 word2; |
1075 | 1068 | ||
1076 | rt2x00_desc_read(rxd, 0, &word0); | 1069 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1077 | rt2x00_desc_read(rxd, 2, &word2); | 1070 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1078 | 1071 | ||
1079 | desc->flags = 0; | 1072 | rxdesc->flags = 0; |
1080 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1073 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1081 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1074 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1082 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1075 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1083 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1076 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1084 | 1077 | ||
1085 | /* | 1078 | /* |
1086 | * Obtain the status about this packet. | 1079 | * Obtain the status about this packet. |
1087 | */ | 1080 | */ |
1088 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1081 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); |
1089 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1082 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - |
1090 | entry->ring->rt2x00dev->rssi_offset; | 1083 | entry->queue->rt2x00dev->rssi_offset; |
1091 | desc->ofdm = 0; | 1084 | rxdesc->ofdm = 0; |
1092 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1085 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1093 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1086 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1094 | } | 1087 | } |
1095 | 1088 | ||
1096 | /* | 1089 | /* |
1097 | * Interrupt functions. | 1090 | * Interrupt functions. |
1098 | */ | 1091 | */ |
1099 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1092 | static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, |
1093 | const enum ieee80211_tx_queue queue_idx) | ||
1100 | { | 1094 | { |
1101 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1095 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1102 | struct data_entry *entry; | 1096 | struct queue_entry_priv_pci_tx *priv_tx; |
1103 | __le32 *txd; | 1097 | struct queue_entry *entry; |
1098 | struct txdone_entry_desc txdesc; | ||
1104 | u32 word; | 1099 | u32 word; |
1105 | int tx_status; | ||
1106 | int retry; | ||
1107 | 1100 | ||
1108 | while (!rt2x00_ring_empty(ring)) { | 1101 | while (!rt2x00queue_empty(queue)) { |
1109 | entry = rt2x00_get_data_entry_done(ring); | 1102 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1110 | txd = entry->priv; | 1103 | priv_tx = entry->priv_data; |
1111 | rt2x00_desc_read(txd, 0, &word); | 1104 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1112 | 1105 | ||
1113 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1106 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1114 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1107 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1117,10 +1110,10 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1117 | /* | 1110 | /* |
1118 | * Obtain the status about this packet. | 1111 | * Obtain the status about this packet. |
1119 | */ | 1112 | */ |
1120 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1113 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1121 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1114 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1122 | 1115 | ||
1123 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1116 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1124 | } | 1117 | } |
1125 | } | 1118 | } |
1126 | 1119 | ||
@@ -1164,7 +1157,7 @@ static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) | |||
1164 | * 3 - Atim ring transmit done interrupt. | 1157 | * 3 - Atim ring transmit done interrupt. |
1165 | */ | 1158 | */ |
1166 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1159 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1167 | rt2400pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1160 | rt2400pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1168 | 1161 | ||
1169 | /* | 1162 | /* |
1170 | * 4 - Priority ring transmit done interrupt. | 1163 | * 4 - Priority ring transmit done interrupt. |
@@ -1272,8 +1265,24 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1272 | /* | 1265 | /* |
1273 | * Store led mode, for correct led behaviour. | 1266 | * Store led mode, for correct led behaviour. |
1274 | */ | 1267 | */ |
1275 | rt2x00dev->led_mode = | 1268 | #ifdef CONFIG_RT2400PCI_LEDS |
1276 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1269 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1270 | |||
1271 | switch (value) { | ||
1272 | case LED_MODE_ASUS: | ||
1273 | case LED_MODE_ALPHA: | ||
1274 | case LED_MODE_DEFAULT: | ||
1275 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1276 | break; | ||
1277 | case LED_MODE_TXRX_ACTIVITY: | ||
1278 | rt2x00dev->led_flags = | ||
1279 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1280 | break; | ||
1281 | case LED_MODE_SIGNAL_STRENGTH: | ||
1282 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1283 | break; | ||
1284 | } | ||
1285 | #endif /* CONFIG_RT2400PCI_LEDS */ | ||
1277 | 1286 | ||
1278 | /* | 1287 | /* |
1279 | * Detect if this device has an hardware controlled radio. | 1288 | * Detect if this device has an hardware controlled radio. |
@@ -1343,8 +1352,8 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1343 | /* | 1352 | /* |
1344 | * Initialize hw_mode information. | 1353 | * Initialize hw_mode information. |
1345 | */ | 1354 | */ |
1346 | spec->num_modes = 1; | 1355 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1347 | spec->num_rates = 4; | 1356 | spec->supported_rates = SUPPORT_RATE_CCK; |
1348 | spec->tx_power_a = NULL; | 1357 | spec->tx_power_a = NULL; |
1349 | spec->tx_power_bg = txpower; | 1358 | spec->tx_power_bg = txpower; |
1350 | spec->tx_power_default = DEFAULT_TXPOWER; | 1359 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1374,9 +1383,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1374 | rt2400pci_probe_hw_mode(rt2x00dev); | 1383 | rt2400pci_probe_hw_mode(rt2x00dev); |
1375 | 1384 | ||
1376 | /* | 1385 | /* |
1377 | * This device requires the beacon ring | 1386 | * This device requires the atim queue |
1378 | */ | 1387 | */ |
1379 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1388 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1380 | 1389 | ||
1381 | /* | 1390 | /* |
1382 | * Set the rssi offset. | 1391 | * Set the rssi offset. |
@@ -1481,7 +1490,8 @@ static int rt2400pci_conf_tx(struct ieee80211_hw *hw, | |||
1481 | /* | 1490 | /* |
1482 | * Write configuration to register. | 1491 | * Write configuration to register. |
1483 | */ | 1492 | */ |
1484 | rt2400pci_config_cw(rt2x00dev, &rt2x00dev->tx->tx_params); | 1493 | rt2400pci_config_cw(rt2x00dev, |
1494 | rt2x00dev->tx->cw_min, rt2x00dev->tx->cw_max); | ||
1485 | 1495 | ||
1486 | return 0; | 1496 | return 0; |
1487 | } | 1497 | } |
@@ -1500,12 +1510,48 @@ static u64 rt2400pci_get_tsf(struct ieee80211_hw *hw) | |||
1500 | return tsf; | 1510 | return tsf; |
1501 | } | 1511 | } |
1502 | 1512 | ||
1503 | static void rt2400pci_reset_tsf(struct ieee80211_hw *hw) | 1513 | static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1514 | struct ieee80211_tx_control *control) | ||
1504 | { | 1515 | { |
1505 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1516 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1517 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1518 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1519 | struct skb_frame_desc *skbdesc; | ||
1520 | |||
1521 | if (unlikely(!intf->beacon)) | ||
1522 | return -ENOBUFS; | ||
1523 | |||
1524 | priv_tx = intf->beacon->priv_data; | ||
1525 | |||
1526 | /* | ||
1527 | * Fill in skb descriptor | ||
1528 | */ | ||
1529 | skbdesc = get_skb_frame_desc(skb); | ||
1530 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1531 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1532 | skbdesc->data = skb->data; | ||
1533 | skbdesc->data_len = skb->len; | ||
1534 | skbdesc->desc = priv_tx->desc; | ||
1535 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1536 | skbdesc->entry = intf->beacon; | ||
1506 | 1537 | ||
1507 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1538 | /* |
1508 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1539 | * mac80211 doesn't provide the control->queue variable |
1540 | * for beacons. Set our own queue identification so | ||
1541 | * it can be used during descriptor initialization. | ||
1542 | */ | ||
1543 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1544 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1545 | |||
1546 | /* | ||
1547 | * Enable beacon generation. | ||
1548 | * Write entire beacon with descriptor to register, | ||
1549 | * and kick the beacon generator. | ||
1550 | */ | ||
1551 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1552 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1553 | |||
1554 | return 0; | ||
1509 | } | 1555 | } |
1510 | 1556 | ||
1511 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) | 1557 | static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1532,8 +1578,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { | |||
1532 | .conf_tx = rt2400pci_conf_tx, | 1578 | .conf_tx = rt2400pci_conf_tx, |
1533 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1579 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1534 | .get_tsf = rt2400pci_get_tsf, | 1580 | .get_tsf = rt2400pci_get_tsf, |
1535 | .reset_tsf = rt2400pci_reset_tsf, | 1581 | .beacon_update = rt2400pci_beacon_update, |
1536 | .beacon_update = rt2x00pci_beacon_update, | ||
1537 | .tx_last_beacon = rt2400pci_tx_last_beacon, | 1582 | .tx_last_beacon = rt2400pci_tx_last_beacon, |
1538 | }; | 1583 | }; |
1539 | 1584 | ||
@@ -1549,23 +1594,54 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1549 | .link_stats = rt2400pci_link_stats, | 1594 | .link_stats = rt2400pci_link_stats, |
1550 | .reset_tuner = rt2400pci_reset_tuner, | 1595 | .reset_tuner = rt2400pci_reset_tuner, |
1551 | .link_tuner = rt2400pci_link_tuner, | 1596 | .link_tuner = rt2400pci_link_tuner, |
1597 | .led_brightness = rt2400pci_led_brightness, | ||
1552 | .write_tx_desc = rt2400pci_write_tx_desc, | 1598 | .write_tx_desc = rt2400pci_write_tx_desc, |
1553 | .write_tx_data = rt2x00pci_write_tx_data, | 1599 | .write_tx_data = rt2x00pci_write_tx_data, |
1554 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1600 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1555 | .fill_rxdone = rt2400pci_fill_rxdone, | 1601 | .fill_rxdone = rt2400pci_fill_rxdone, |
1556 | .config_mac_addr = rt2400pci_config_mac_addr, | 1602 | .config_intf = rt2400pci_config_intf, |
1557 | .config_bssid = rt2400pci_config_bssid, | ||
1558 | .config_type = rt2400pci_config_type, | ||
1559 | .config_preamble = rt2400pci_config_preamble, | 1603 | .config_preamble = rt2400pci_config_preamble, |
1560 | .config = rt2400pci_config, | 1604 | .config = rt2400pci_config, |
1561 | }; | 1605 | }; |
1562 | 1606 | ||
1607 | static const struct data_queue_desc rt2400pci_queue_rx = { | ||
1608 | .entry_num = RX_ENTRIES, | ||
1609 | .data_size = DATA_FRAME_SIZE, | ||
1610 | .desc_size = RXD_DESC_SIZE, | ||
1611 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1612 | }; | ||
1613 | |||
1614 | static const struct data_queue_desc rt2400pci_queue_tx = { | ||
1615 | .entry_num = TX_ENTRIES, | ||
1616 | .data_size = DATA_FRAME_SIZE, | ||
1617 | .desc_size = TXD_DESC_SIZE, | ||
1618 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1619 | }; | ||
1620 | |||
1621 | static const struct data_queue_desc rt2400pci_queue_bcn = { | ||
1622 | .entry_num = BEACON_ENTRIES, | ||
1623 | .data_size = MGMT_FRAME_SIZE, | ||
1624 | .desc_size = TXD_DESC_SIZE, | ||
1625 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1626 | }; | ||
1627 | |||
1628 | static const struct data_queue_desc rt2400pci_queue_atim = { | ||
1629 | .entry_num = ATIM_ENTRIES, | ||
1630 | .data_size = DATA_FRAME_SIZE, | ||
1631 | .desc_size = TXD_DESC_SIZE, | ||
1632 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1633 | }; | ||
1634 | |||
1563 | static const struct rt2x00_ops rt2400pci_ops = { | 1635 | static const struct rt2x00_ops rt2400pci_ops = { |
1564 | .name = KBUILD_MODNAME, | 1636 | .name = KBUILD_MODNAME, |
1565 | .rxd_size = RXD_DESC_SIZE, | 1637 | .max_sta_intf = 1, |
1566 | .txd_size = TXD_DESC_SIZE, | 1638 | .max_ap_intf = 1, |
1567 | .eeprom_size = EEPROM_SIZE, | 1639 | .eeprom_size = EEPROM_SIZE, |
1568 | .rf_size = RF_SIZE, | 1640 | .rf_size = RF_SIZE, |
1641 | .rx = &rt2400pci_queue_rx, | ||
1642 | .tx = &rt2400pci_queue_tx, | ||
1643 | .bcn = &rt2400pci_queue_bcn, | ||
1644 | .atim = &rt2400pci_queue_atim, | ||
1569 | .lib = &rt2400pci_rt2x00_ops, | 1645 | .lib = &rt2400pci_rt2x00_ops, |
1570 | .hw = &rt2400pci_mac80211_ops, | 1646 | .hw = &rt2400pci_mac80211_ops, |
1571 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1647 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index 369aac6d0336..da178d44660e 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -923,13 +923,13 @@ | |||
923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) | 923 | #define RXD_W7_RESERVED FIELD32(0xffffffff) |
924 | 924 | ||
925 | /* | 925 | /* |
926 | * Macro's for converting txpower from EEPROM to dscape value | 926 | * Macro's for converting txpower from EEPROM to mac80211 value |
927 | * and from dscape value to register value. | 927 | * and from mac80211 value to register value. |
928 | * NOTE: Logics in rt2400pci for txpower are reversed | 928 | * NOTE: Logics in rt2400pci for txpower are reversed |
929 | * compared to the other rt2x00 drivers. A higher txpower | 929 | * compared to the other rt2x00 drivers. A higher txpower |
930 | * value means that the txpower must be lowered. This is | 930 | * value means that the txpower must be lowered. This is |
931 | * important when converting the value coming from the | 931 | * important when converting the value coming from the |
932 | * dscape stack to the rt2400 acceptable value. | 932 | * mac80211 stack to the rt2400 acceptable value. |
933 | */ | 933 | */ |
934 | #define MIN_TXPOWER 31 | 934 | #define MIN_TXPOWER 31 |
935 | #define MAX_TXPOWER 62 | 935 | #define MAX_TXPOWER 62 |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 91e87b53374f..ffcd996df064 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -243,57 +243,80 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
243 | #define rt2500pci_rfkill_poll NULL | 243 | #define rt2500pci_rfkill_poll NULL |
244 | #endif /* CONFIG_RT2500PCI_RFKILL */ | 244 | #endif /* CONFIG_RT2500PCI_RFKILL */ |
245 | 245 | ||
246 | /* | 246 | #ifdef CONFIG_RT2500PCI_LEDS |
247 | * Configuration handlers. | 247 | static void rt2500pci_led_brightness(struct led_classdev *led_cdev, |
248 | */ | 248 | enum led_brightness brightness) |
249 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
250 | __le32 *mac) | ||
251 | { | 249 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 250 | struct rt2x00_led *led = |
253 | (2 * sizeof(__le32))); | 251 | container_of(led_cdev, struct rt2x00_led, led_dev); |
254 | } | 252 | unsigned int enabled = brightness != LED_OFF; |
253 | unsigned int activity = | ||
254 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
255 | u32 reg; | ||
255 | 256 | ||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | rt2x00pci_register_read(led->rt2x00dev, LEDCSR, ®); |
257 | __le32 *bssid) | 258 | |
258 | { | 259 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { |
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | 260 | rt2x00_set_field32(®, LEDCSR_LINK, enabled); |
260 | (2 * sizeof(__le32))); | 261 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, enabled && activity); |
262 | } | ||
263 | |||
264 | rt2x00pci_register_write(led->rt2x00dev, LEDCSR, reg); | ||
261 | } | 265 | } |
266 | #else | ||
267 | #define rt2500pci_led_brightness NULL | ||
268 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
262 | 269 | ||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 270 | /* |
264 | const int tsf_sync) | 271 | * Configuration handlers. |
272 | */ | ||
273 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, | ||
274 | struct rt2x00_intf *intf, | ||
275 | struct rt2x00intf_conf *conf, | ||
276 | const unsigned int flags) | ||
265 | { | 277 | { |
278 | struct data_queue *queue = | ||
279 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); | ||
280 | unsigned int bcn_preload; | ||
266 | u32 reg; | 281 | u32 reg; |
267 | 282 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 283 | if (flags & CONFIG_UPDATE_TYPE) { |
284 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
269 | 285 | ||
270 | /* | 286 | /* |
271 | * Enable beacon config | 287 | * Enable beacon config |
272 | */ | 288 | */ |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 289 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 290 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 291 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
276 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, | 292 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); |
277 | rt2x00lib_get_ring(rt2x00dev, | 293 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
278 | IEEE80211_TX_QUEUE_BEACON) | ||
279 | ->tx_params.cw_min); | ||
280 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
281 | 294 | ||
282 | /* | 295 | /* |
283 | * Enable synchronisation. | 296 | * Enable synchronisation. |
284 | */ | 297 | */ |
285 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 298 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
286 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 299 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
287 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 300 | rt2x00_set_field32(®, CSR14_TBCN, |
288 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 301 | (conf->sync == TSF_SYNC_BEACON)); |
289 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 302 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
290 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 303 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
304 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
305 | } | ||
306 | |||
307 | if (flags & CONFIG_UPDATE_MAC) | ||
308 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
309 | conf->mac, sizeof(conf->mac)); | ||
310 | |||
311 | if (flags & CONFIG_UPDATE_BSSID) | ||
312 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
313 | conf->bssid, sizeof(conf->bssid)); | ||
291 | } | 314 | } |
292 | 315 | ||
293 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 316 | static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
294 | const int short_preamble, | 317 | const int short_preamble, |
295 | const int ack_timeout, | 318 | const int ack_timeout, |
296 | const int ack_consume_time) | 319 | const int ack_consume_time) |
297 | { | 320 | { |
298 | int preamble_mask; | 321 | int preamble_mask; |
299 | u32 reg; | 322 | u32 reg; |
@@ -331,6 +354,8 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
331 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 354 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
332 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 355 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
333 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 356 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
357 | |||
358 | return 0; | ||
334 | } | 359 | } |
335 | 360 | ||
336 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 361 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -530,8 +555,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
530 | } | 555 | } |
531 | 556 | ||
532 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 557 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
533 | const unsigned int flags, | 558 | struct rt2x00lib_conf *libconf, |
534 | struct rt2x00lib_conf *libconf) | 559 | const unsigned int flags) |
535 | { | 560 | { |
536 | if (flags & CONFIG_UPDATE_PHYMODE) | 561 | if (flags & CONFIG_UPDATE_PHYMODE) |
537 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 562 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -548,34 +573,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | |||
548 | } | 573 | } |
549 | 574 | ||
550 | /* | 575 | /* |
551 | * LED functions. | ||
552 | */ | ||
553 | static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
554 | { | ||
555 | u32 reg; | ||
556 | |||
557 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
558 | |||
559 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
560 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
561 | rt2x00_set_field32(®, LEDCSR_LINK, | ||
562 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
563 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, | ||
564 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
565 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
566 | } | ||
567 | |||
568 | static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
569 | { | ||
570 | u32 reg; | ||
571 | |||
572 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
573 | rt2x00_set_field32(®, LEDCSR_LINK, 0); | ||
574 | rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); | ||
575 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Link tuning | 576 | * Link tuning |
580 | */ | 577 | */ |
581 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | 578 | static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -610,9 +607,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
610 | /* | 607 | /* |
611 | * To prevent collisions with MAC ASIC on chipsets | 608 | * To prevent collisions with MAC ASIC on chipsets |
612 | * up to version C the link tuning should halt after 20 | 609 | * up to version C the link tuning should halt after 20 |
613 | * seconds. | 610 | * seconds while being associated. |
614 | */ | 611 | */ |
615 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 612 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
613 | rt2x00dev->intf_associated && | ||
616 | rt2x00dev->link.count > 20) | 614 | rt2x00dev->link.count > 20) |
617 | return; | 615 | return; |
618 | 616 | ||
@@ -620,9 +618,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
620 | 618 | ||
621 | /* | 619 | /* |
622 | * Chipset versions C and lower should directly continue | 620 | * Chipset versions C and lower should directly continue |
623 | * to the dynamic CCA tuning. | 621 | * to the dynamic CCA tuning. Chipset version D and higher |
622 | * should go straight to dynamic CCA tuning when they | ||
623 | * are not associated. | ||
624 | */ | 624 | */ |
625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 625 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
626 | !rt2x00dev->intf_associated) | ||
626 | goto dynamic_cca_tune; | 627 | goto dynamic_cca_tune; |
627 | 628 | ||
628 | /* | 629 | /* |
@@ -684,82 +685,84 @@ dynamic_cca_tune: | |||
684 | * Initialization functions. | 685 | * Initialization functions. |
685 | */ | 686 | */ |
686 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 687 | static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
687 | struct data_entry *entry) | 688 | struct queue_entry *entry) |
688 | { | 689 | { |
689 | __le32 *rxd = entry->priv; | 690 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
690 | u32 word; | 691 | u32 word; |
691 | 692 | ||
692 | rt2x00_desc_read(rxd, 1, &word); | 693 | rt2x00_desc_read(priv_rx->desc, 1, &word); |
693 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry->data_dma); | 694 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, priv_rx->data_dma); |
694 | rt2x00_desc_write(rxd, 1, word); | 695 | rt2x00_desc_write(priv_rx->desc, 1, word); |
695 | 696 | ||
696 | rt2x00_desc_read(rxd, 0, &word); | 697 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
697 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 698 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
698 | rt2x00_desc_write(rxd, 0, word); | 699 | rt2x00_desc_write(priv_rx->desc, 0, word); |
699 | } | 700 | } |
700 | 701 | ||
701 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 702 | static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
702 | struct data_entry *entry) | 703 | struct queue_entry *entry) |
703 | { | 704 | { |
704 | __le32 *txd = entry->priv; | 705 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
705 | u32 word; | 706 | u32 word; |
706 | 707 | ||
707 | rt2x00_desc_read(txd, 1, &word); | 708 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
708 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry->data_dma); | 709 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, priv_tx->data_dma); |
709 | rt2x00_desc_write(txd, 1, word); | 710 | rt2x00_desc_write(priv_tx->desc, 1, word); |
710 | 711 | ||
711 | rt2x00_desc_read(txd, 0, &word); | 712 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
712 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 713 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
713 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 714 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
714 | rt2x00_desc_write(txd, 0, word); | 715 | rt2x00_desc_write(priv_tx->desc, 0, word); |
715 | } | 716 | } |
716 | 717 | ||
717 | static int rt2500pci_init_rings(struct rt2x00_dev *rt2x00dev) | 718 | static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) |
718 | { | 719 | { |
720 | struct queue_entry_priv_pci_rx *priv_rx; | ||
721 | struct queue_entry_priv_pci_tx *priv_tx; | ||
719 | u32 reg; | 722 | u32 reg; |
720 | 723 | ||
721 | /* | 724 | /* |
722 | * Initialize registers. | 725 | * Initialize registers. |
723 | */ | 726 | */ |
724 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); | 727 | rt2x00pci_register_read(rt2x00dev, TXCSR2, ®); |
725 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, | 728 | rt2x00_set_field32(®, TXCSR2_TXD_SIZE, rt2x00dev->tx[0].desc_size); |
726 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size); | 729 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, rt2x00dev->tx[1].limit); |
727 | rt2x00_set_field32(®, TXCSR2_NUM_TXD, | 730 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, rt2x00dev->bcn[1].limit); |
728 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, rt2x00dev->tx[0].limit); |
729 | rt2x00_set_field32(®, TXCSR2_NUM_ATIM, | ||
730 | rt2x00dev->bcn[1].stats.limit); | ||
731 | rt2x00_set_field32(®, TXCSR2_NUM_PRIO, | ||
732 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | ||
733 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); | 732 | rt2x00pci_register_write(rt2x00dev, TXCSR2, reg); |
734 | 733 | ||
734 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); | 735 | rt2x00pci_register_read(rt2x00dev, TXCSR3, ®); |
736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, | 736 | rt2x00_set_field32(®, TXCSR3_TX_RING_REGISTER, |
737 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 737 | priv_tx->desc_dma); |
738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); | 738 | rt2x00pci_register_write(rt2x00dev, TXCSR3, reg); |
739 | 739 | ||
740 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
740 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); | 741 | rt2x00pci_register_read(rt2x00dev, TXCSR5, ®); |
741 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, | 742 | rt2x00_set_field32(®, TXCSR5_PRIO_RING_REGISTER, |
742 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 743 | priv_tx->desc_dma); |
743 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); | 744 | rt2x00pci_register_write(rt2x00dev, TXCSR5, reg); |
744 | 745 | ||
746 | priv_tx = rt2x00dev->bcn[1].entries[0].priv_data; | ||
745 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); | 747 | rt2x00pci_register_read(rt2x00dev, TXCSR4, ®); |
746 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, | 748 | rt2x00_set_field32(®, TXCSR4_ATIM_RING_REGISTER, |
747 | rt2x00dev->bcn[1].data_dma); | 749 | priv_tx->desc_dma); |
748 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); | 750 | rt2x00pci_register_write(rt2x00dev, TXCSR4, reg); |
749 | 751 | ||
752 | priv_tx = rt2x00dev->bcn[0].entries[0].priv_data; | ||
750 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); | 753 | rt2x00pci_register_read(rt2x00dev, TXCSR6, ®); |
751 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, | 754 | rt2x00_set_field32(®, TXCSR6_BEACON_RING_REGISTER, |
752 | rt2x00dev->bcn[0].data_dma); | 755 | priv_tx->desc_dma); |
753 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); | 756 | rt2x00pci_register_write(rt2x00dev, TXCSR6, reg); |
754 | 757 | ||
755 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); | 758 | rt2x00pci_register_read(rt2x00dev, RXCSR1, ®); |
756 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); | 759 | rt2x00_set_field32(®, RXCSR1_RXD_SIZE, rt2x00dev->rx->desc_size); |
757 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->stats.limit); | 760 | rt2x00_set_field32(®, RXCSR1_NUM_RXD, rt2x00dev->rx->limit); |
758 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); | 761 | rt2x00pci_register_write(rt2x00dev, RXCSR1, reg); |
759 | 762 | ||
763 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
760 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); | 764 | rt2x00pci_register_read(rt2x00dev, RXCSR2, ®); |
761 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, | 765 | rt2x00_set_field32(®, RXCSR2_RX_RING_REGISTER, priv_tx->desc_dma); |
762 | rt2x00dev->rx->data_dma); | ||
763 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); | 766 | rt2x00pci_register_write(rt2x00dev, RXCSR2, reg); |
764 | 767 | ||
765 | return 0; | 768 | return 0; |
@@ -792,6 +795,11 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
792 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); | 795 | rt2x00_set_field32(®, CSR11_CW_SELECT, 0); |
793 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); | 796 | rt2x00pci_register_write(rt2x00dev, CSR11, reg); |
794 | 797 | ||
798 | rt2x00pci_register_read(rt2x00dev, LEDCSR, ®); | ||
799 | rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); | ||
800 | rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); | ||
801 | rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); | ||
802 | |||
795 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); | 803 | rt2x00pci_register_write(rt2x00dev, CNT3, 0); |
796 | 804 | ||
797 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); | 805 | rt2x00pci_register_read(rt2x00dev, TXCSR8, ®); |
@@ -947,19 +955,15 @@ continue_csr_init: | |||
947 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); | 955 | rt2500pci_bbp_write(rt2x00dev, 61, 0x6d); |
948 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); | 956 | rt2500pci_bbp_write(rt2x00dev, 62, 0x10); |
949 | 957 | ||
950 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
951 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 958 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
952 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 959 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
953 | 960 | ||
954 | if (eeprom != 0xffff && eeprom != 0x0000) { | 961 | if (eeprom != 0xffff && eeprom != 0x0000) { |
955 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 962 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
956 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 963 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
957 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
958 | reg_id, value); | ||
959 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); | 964 | rt2500pci_bbp_write(rt2x00dev, reg_id, value); |
960 | } | 965 | } |
961 | } | 966 | } |
962 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
963 | 967 | ||
964 | return 0; | 968 | return 0; |
965 | } | 969 | } |
@@ -1011,7 +1015,7 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1011 | /* | 1015 | /* |
1012 | * Initialize all registers. | 1016 | * Initialize all registers. |
1013 | */ | 1017 | */ |
1014 | if (rt2500pci_init_rings(rt2x00dev) || | 1018 | if (rt2500pci_init_queues(rt2x00dev) || |
1015 | rt2500pci_init_registers(rt2x00dev) || | 1019 | rt2500pci_init_registers(rt2x00dev) || |
1016 | rt2500pci_init_bbp(rt2x00dev)) { | 1020 | rt2500pci_init_bbp(rt2x00dev)) { |
1017 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1021 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1023,11 +1027,6 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1023 | */ | 1027 | */ |
1024 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | 1028 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); |
1025 | 1029 | ||
1026 | /* | ||
1027 | * Enable LED | ||
1028 | */ | ||
1029 | rt2500pci_enable_led(rt2x00dev); | ||
1030 | |||
1031 | return 0; | 1030 | return 0; |
1032 | } | 1031 | } |
1033 | 1032 | ||
@@ -1035,11 +1034,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1035 | { | 1034 | { |
1036 | u32 reg; | 1035 | u32 reg; |
1037 | 1036 | ||
1038 | /* | ||
1039 | * Disable LED | ||
1040 | */ | ||
1041 | rt2500pci_disable_led(rt2x00dev); | ||
1042 | |||
1043 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); | 1037 | rt2x00pci_register_write(rt2x00dev, PWRCSR0, 0); |
1044 | 1038 | ||
1045 | /* | 1039 | /* |
@@ -1138,10 +1132,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1138 | */ | 1132 | */ |
1139 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1133 | static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1140 | struct sk_buff *skb, | 1134 | struct sk_buff *skb, |
1141 | struct txdata_entry_desc *desc, | 1135 | struct txentry_desc *txdesc, |
1142 | struct ieee80211_tx_control *control) | 1136 | struct ieee80211_tx_control *control) |
1143 | { | 1137 | { |
1144 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1138 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1145 | __le32 *txd = skbdesc->desc; | 1139 | __le32 *txd = skbdesc->desc; |
1146 | u32 word; | 1140 | u32 word; |
1147 | 1141 | ||
@@ -1150,36 +1144,36 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1150 | */ | 1144 | */ |
1151 | rt2x00_desc_read(txd, 2, &word); | 1145 | rt2x00_desc_read(txd, 2, &word); |
1152 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); | 1146 | rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER); |
1153 | rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs); | 1147 | rt2x00_set_field32(&word, TXD_W2_AIFS, txdesc->aifs); |
1154 | rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min); | 1148 | rt2x00_set_field32(&word, TXD_W2_CWMIN, txdesc->cw_min); |
1155 | rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max); | 1149 | rt2x00_set_field32(&word, TXD_W2_CWMAX, txdesc->cw_max); |
1156 | rt2x00_desc_write(txd, 2, word); | 1150 | rt2x00_desc_write(txd, 2, word); |
1157 | 1151 | ||
1158 | rt2x00_desc_read(txd, 3, &word); | 1152 | rt2x00_desc_read(txd, 3, &word); |
1159 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); | 1153 | rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, txdesc->signal); |
1160 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); | 1154 | rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, txdesc->service); |
1161 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, desc->length_low); | 1155 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW, txdesc->length_low); |
1162 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, desc->length_high); | 1156 | rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH, txdesc->length_high); |
1163 | rt2x00_desc_write(txd, 3, word); | 1157 | rt2x00_desc_write(txd, 3, word); |
1164 | 1158 | ||
1165 | rt2x00_desc_read(txd, 10, &word); | 1159 | rt2x00_desc_read(txd, 10, &word); |
1166 | rt2x00_set_field32(&word, TXD_W10_RTS, | 1160 | rt2x00_set_field32(&word, TXD_W10_RTS, |
1167 | test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags)); | 1161 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags)); |
1168 | rt2x00_desc_write(txd, 10, word); | 1162 | rt2x00_desc_write(txd, 10, word); |
1169 | 1163 | ||
1170 | rt2x00_desc_read(txd, 0, &word); | 1164 | rt2x00_desc_read(txd, 0, &word); |
1171 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1165 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1172 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1166 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1173 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1167 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1174 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1168 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1175 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1169 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1176 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1170 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1177 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1171 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1178 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1172 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1179 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1173 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1180 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1174 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1181 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); | 1175 | rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1); |
1182 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1176 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1183 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1177 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1184 | !!(control->flags & | 1178 | !!(control->flags & |
1185 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1179 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
@@ -1192,11 +1186,11 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1192 | * TX data initialization | 1186 | * TX data initialization |
1193 | */ | 1187 | */ |
1194 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1188 | static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1195 | unsigned int queue) | 1189 | const unsigned int queue) |
1196 | { | 1190 | { |
1197 | u32 reg; | 1191 | u32 reg; |
1198 | 1192 | ||
1199 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1193 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1200 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 1194 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
1201 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { | 1195 | if (!rt2x00_get_field32(reg, CSR14_BEACON_GEN)) { |
1202 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1196 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); |
@@ -1211,53 +1205,53 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1211 | rt2x00_set_field32(®, TXCSR0_KICK_TX, | 1205 | rt2x00_set_field32(®, TXCSR0_KICK_TX, |
1212 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1206 | (queue == IEEE80211_TX_QUEUE_DATA1)); |
1213 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, | 1207 | rt2x00_set_field32(®, TXCSR0_KICK_ATIM, |
1214 | (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); | 1208 | (queue == RT2X00_BCN_QUEUE_ATIM)); |
1215 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1209 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1216 | } | 1210 | } |
1217 | 1211 | ||
1218 | /* | 1212 | /* |
1219 | * RX control handlers | 1213 | * RX control handlers |
1220 | */ | 1214 | */ |
1221 | static void rt2500pci_fill_rxdone(struct data_entry *entry, | 1215 | static void rt2500pci_fill_rxdone(struct queue_entry *entry, |
1222 | struct rxdata_entry_desc *desc) | 1216 | struct rxdone_entry_desc *rxdesc) |
1223 | { | 1217 | { |
1224 | __le32 *rxd = entry->priv; | 1218 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1225 | u32 word0; | 1219 | u32 word0; |
1226 | u32 word2; | 1220 | u32 word2; |
1227 | 1221 | ||
1228 | rt2x00_desc_read(rxd, 0, &word0); | 1222 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1229 | rt2x00_desc_read(rxd, 2, &word2); | 1223 | rt2x00_desc_read(priv_rx->desc, 2, &word2); |
1230 | 1224 | ||
1231 | desc->flags = 0; | 1225 | rxdesc->flags = 0; |
1232 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1226 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1233 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1227 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1234 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1228 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1235 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1229 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1236 | 1230 | ||
1237 | desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); | 1231 | rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL); |
1238 | desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - | 1232 | rxdesc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) - |
1239 | entry->ring->rt2x00dev->rssi_offset; | 1233 | entry->queue->rt2x00dev->rssi_offset; |
1240 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1234 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1241 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1235 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1242 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1236 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1243 | } | 1237 | } |
1244 | 1238 | ||
1245 | /* | 1239 | /* |
1246 | * Interrupt functions. | 1240 | * Interrupt functions. |
1247 | */ | 1241 | */ |
1248 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | 1242 | static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, |
1243 | const enum ieee80211_tx_queue queue_idx) | ||
1249 | { | 1244 | { |
1250 | struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); | 1245 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
1251 | struct data_entry *entry; | 1246 | struct queue_entry_priv_pci_tx *priv_tx; |
1252 | __le32 *txd; | 1247 | struct queue_entry *entry; |
1248 | struct txdone_entry_desc txdesc; | ||
1253 | u32 word; | 1249 | u32 word; |
1254 | int tx_status; | ||
1255 | int retry; | ||
1256 | 1250 | ||
1257 | while (!rt2x00_ring_empty(ring)) { | 1251 | while (!rt2x00queue_empty(queue)) { |
1258 | entry = rt2x00_get_data_entry_done(ring); | 1252 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1259 | txd = entry->priv; | 1253 | priv_tx = entry->priv_data; |
1260 | rt2x00_desc_read(txd, 0, &word); | 1254 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1261 | 1255 | ||
1262 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1256 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1263 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1257 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1266,10 +1260,10 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) | |||
1266 | /* | 1260 | /* |
1267 | * Obtain the status about this packet. | 1261 | * Obtain the status about this packet. |
1268 | */ | 1262 | */ |
1269 | tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); | 1263 | txdesc.status = rt2x00_get_field32(word, TXD_W0_RESULT); |
1270 | retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1264 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1271 | 1265 | ||
1272 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1266 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1273 | } | 1267 | } |
1274 | } | 1268 | } |
1275 | 1269 | ||
@@ -1313,7 +1307,7 @@ static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) | |||
1313 | * 3 - Atim ring transmit done interrupt. | 1307 | * 3 - Atim ring transmit done interrupt. |
1314 | */ | 1308 | */ |
1315 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) | 1309 | if (rt2x00_get_field32(reg, CSR7_TXDONE_ATIMRING)) |
1316 | rt2500pci_txdone(rt2x00dev, IEEE80211_TX_QUEUE_AFTER_BEACON); | 1310 | rt2500pci_txdone(rt2x00dev, RT2X00_BCN_QUEUE_ATIM); |
1317 | 1311 | ||
1318 | /* | 1312 | /* |
1319 | * 4 - Priority ring transmit done interrupt. | 1313 | * 4 - Priority ring transmit done interrupt. |
@@ -1442,8 +1436,24 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1442 | /* | 1436 | /* |
1443 | * Store led mode, for correct led behaviour. | 1437 | * Store led mode, for correct led behaviour. |
1444 | */ | 1438 | */ |
1445 | rt2x00dev->led_mode = | 1439 | #ifdef CONFIG_RT2500PCI_LEDS |
1446 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1440 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1441 | |||
1442 | switch (value) { | ||
1443 | case LED_MODE_ASUS: | ||
1444 | case LED_MODE_ALPHA: | ||
1445 | case LED_MODE_DEFAULT: | ||
1446 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1447 | break; | ||
1448 | case LED_MODE_TXRX_ACTIVITY: | ||
1449 | rt2x00dev->led_flags = | ||
1450 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1451 | break; | ||
1452 | case LED_MODE_SIGNAL_STRENGTH: | ||
1453 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1454 | break; | ||
1455 | } | ||
1456 | #endif /* CONFIG_RT2500PCI_LEDS */ | ||
1447 | 1457 | ||
1448 | /* | 1458 | /* |
1449 | * Detect if this device has an hardware controlled radio. | 1459 | * Detect if this device has an hardware controlled radio. |
@@ -1656,8 +1666,8 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1666 | /* |
1657 | * Initialize hw_mode information. | 1667 | * Initialize hw_mode information. |
1658 | */ | 1668 | */ |
1659 | spec->num_modes = 2; | 1669 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1660 | spec->num_rates = 12; | 1670 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1661 | spec->tx_power_a = NULL; | 1671 | spec->tx_power_a = NULL; |
1662 | spec->tx_power_bg = txpower; | 1672 | spec->tx_power_bg = txpower; |
1663 | spec->tx_power_default = DEFAULT_TXPOWER; | 1673 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1678,9 +1688,9 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1678 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1688 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1679 | spec->channels = rf_vals_bg_2525e; | 1689 | spec->channels = rf_vals_bg_2525e; |
1680 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1690 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1691 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1681 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1692 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1682 | spec->channels = rf_vals_5222; | 1693 | spec->channels = rf_vals_5222; |
1683 | spec->num_modes = 3; | ||
1684 | } | 1694 | } |
1685 | } | 1695 | } |
1686 | 1696 | ||
@@ -1705,9 +1715,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1705 | rt2500pci_probe_hw_mode(rt2x00dev); | 1715 | rt2500pci_probe_hw_mode(rt2x00dev); |
1706 | 1716 | ||
1707 | /* | 1717 | /* |
1708 | * This device requires the beacon ring | 1718 | * This device requires the atim queue |
1709 | */ | 1719 | */ |
1710 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1720 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1711 | 1721 | ||
1712 | /* | 1722 | /* |
1713 | * Set the rssi offset. | 1723 | * Set the rssi offset. |
@@ -1811,12 +1821,48 @@ static u64 rt2500pci_get_tsf(struct ieee80211_hw *hw) | |||
1811 | return tsf; | 1821 | return tsf; |
1812 | } | 1822 | } |
1813 | 1823 | ||
1814 | static void rt2500pci_reset_tsf(struct ieee80211_hw *hw) | 1824 | static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1825 | struct ieee80211_tx_control *control) | ||
1815 | { | 1826 | { |
1816 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1827 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1828 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1829 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1830 | struct skb_frame_desc *skbdesc; | ||
1831 | |||
1832 | if (unlikely(!intf->beacon)) | ||
1833 | return -ENOBUFS; | ||
1834 | |||
1835 | priv_tx = intf->beacon->priv_data; | ||
1836 | |||
1837 | /* | ||
1838 | * Fill in skb descriptor | ||
1839 | */ | ||
1840 | skbdesc = get_skb_frame_desc(skb); | ||
1841 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
1842 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1843 | skbdesc->data = skb->data; | ||
1844 | skbdesc->data_len = skb->len; | ||
1845 | skbdesc->desc = priv_tx->desc; | ||
1846 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
1847 | skbdesc->entry = intf->beacon; | ||
1817 | 1848 | ||
1818 | rt2x00pci_register_write(rt2x00dev, CSR16, 0); | 1849 | /* |
1819 | rt2x00pci_register_write(rt2x00dev, CSR17, 0); | 1850 | * mac80211 doesn't provide the control->queue variable |
1851 | * for beacons. Set our own queue identification so | ||
1852 | * it can be used during descriptor initialization. | ||
1853 | */ | ||
1854 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1855 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
1856 | |||
1857 | /* | ||
1858 | * Enable beacon generation. | ||
1859 | * Write entire beacon with descriptor to register, | ||
1860 | * and kick the beacon generator. | ||
1861 | */ | ||
1862 | memcpy(priv_tx->data, skb->data, skb->len); | ||
1863 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
1864 | |||
1865 | return 0; | ||
1820 | } | 1866 | } |
1821 | 1867 | ||
1822 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) | 1868 | static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw) |
@@ -1843,8 +1889,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { | |||
1843 | .conf_tx = rt2x00mac_conf_tx, | 1889 | .conf_tx = rt2x00mac_conf_tx, |
1844 | .get_tx_stats = rt2x00mac_get_tx_stats, | 1890 | .get_tx_stats = rt2x00mac_get_tx_stats, |
1845 | .get_tsf = rt2500pci_get_tsf, | 1891 | .get_tsf = rt2500pci_get_tsf, |
1846 | .reset_tsf = rt2500pci_reset_tsf, | 1892 | .beacon_update = rt2500pci_beacon_update, |
1847 | .beacon_update = rt2x00pci_beacon_update, | ||
1848 | .tx_last_beacon = rt2500pci_tx_last_beacon, | 1893 | .tx_last_beacon = rt2500pci_tx_last_beacon, |
1849 | }; | 1894 | }; |
1850 | 1895 | ||
@@ -1860,23 +1905,54 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1860 | .link_stats = rt2500pci_link_stats, | 1905 | .link_stats = rt2500pci_link_stats, |
1861 | .reset_tuner = rt2500pci_reset_tuner, | 1906 | .reset_tuner = rt2500pci_reset_tuner, |
1862 | .link_tuner = rt2500pci_link_tuner, | 1907 | .link_tuner = rt2500pci_link_tuner, |
1908 | .led_brightness = rt2500pci_led_brightness, | ||
1863 | .write_tx_desc = rt2500pci_write_tx_desc, | 1909 | .write_tx_desc = rt2500pci_write_tx_desc, |
1864 | .write_tx_data = rt2x00pci_write_tx_data, | 1910 | .write_tx_data = rt2x00pci_write_tx_data, |
1865 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1911 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1866 | .fill_rxdone = rt2500pci_fill_rxdone, | 1912 | .fill_rxdone = rt2500pci_fill_rxdone, |
1867 | .config_mac_addr = rt2500pci_config_mac_addr, | 1913 | .config_intf = rt2500pci_config_intf, |
1868 | .config_bssid = rt2500pci_config_bssid, | ||
1869 | .config_type = rt2500pci_config_type, | ||
1870 | .config_preamble = rt2500pci_config_preamble, | 1914 | .config_preamble = rt2500pci_config_preamble, |
1871 | .config = rt2500pci_config, | 1915 | .config = rt2500pci_config, |
1872 | }; | 1916 | }; |
1873 | 1917 | ||
1918 | static const struct data_queue_desc rt2500pci_queue_rx = { | ||
1919 | .entry_num = RX_ENTRIES, | ||
1920 | .data_size = DATA_FRAME_SIZE, | ||
1921 | .desc_size = RXD_DESC_SIZE, | ||
1922 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
1923 | }; | ||
1924 | |||
1925 | static const struct data_queue_desc rt2500pci_queue_tx = { | ||
1926 | .entry_num = TX_ENTRIES, | ||
1927 | .data_size = DATA_FRAME_SIZE, | ||
1928 | .desc_size = TXD_DESC_SIZE, | ||
1929 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1930 | }; | ||
1931 | |||
1932 | static const struct data_queue_desc rt2500pci_queue_bcn = { | ||
1933 | .entry_num = BEACON_ENTRIES, | ||
1934 | .data_size = MGMT_FRAME_SIZE, | ||
1935 | .desc_size = TXD_DESC_SIZE, | ||
1936 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1937 | }; | ||
1938 | |||
1939 | static const struct data_queue_desc rt2500pci_queue_atim = { | ||
1940 | .entry_num = ATIM_ENTRIES, | ||
1941 | .data_size = DATA_FRAME_SIZE, | ||
1942 | .desc_size = TXD_DESC_SIZE, | ||
1943 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
1944 | }; | ||
1945 | |||
1874 | static const struct rt2x00_ops rt2500pci_ops = { | 1946 | static const struct rt2x00_ops rt2500pci_ops = { |
1875 | .name = KBUILD_MODNAME, | 1947 | .name = KBUILD_MODNAME, |
1876 | .rxd_size = RXD_DESC_SIZE, | 1948 | .max_sta_intf = 1, |
1877 | .txd_size = TXD_DESC_SIZE, | 1949 | .max_ap_intf = 1, |
1878 | .eeprom_size = EEPROM_SIZE, | 1950 | .eeprom_size = EEPROM_SIZE, |
1879 | .rf_size = RF_SIZE, | 1951 | .rf_size = RF_SIZE, |
1952 | .rx = &rt2500pci_queue_rx, | ||
1953 | .tx = &rt2500pci_queue_tx, | ||
1954 | .bcn = &rt2500pci_queue_bcn, | ||
1955 | .atim = &rt2500pci_queue_atim, | ||
1880 | .lib = &rt2500pci_rt2x00_ops, | 1956 | .lib = &rt2500pci_rt2x00_ops, |
1881 | .hw = &rt2500pci_mac80211_ops, | 1957 | .hw = &rt2500pci_mac80211_ops, |
1882 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1958 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index 92ba0902d107..13899550465a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -1213,8 +1213,8 @@ | |||
1213 | #define RXD_W10_DROP FIELD32(0x00000001) | 1213 | #define RXD_W10_DROP FIELD32(0x00000001) |
1214 | 1214 | ||
1215 | /* | 1215 | /* |
1216 | * Macro's for converting txpower from EEPROM to dscape value | 1216 | * Macro's for converting txpower from EEPROM to mac80211 value |
1217 | * and from dscape value to register value. | 1217 | * and from mac80211 value to register value. |
1218 | */ | 1218 | */ |
1219 | #define MIN_TXPOWER 0 | 1219 | #define MIN_TXPOWER 0 |
1220 | #define MAX_TXPOWER 31 | 1220 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 638c3d243108..9f59db91cfc2 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -282,73 +282,98 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { | |||
282 | }; | 282 | }; |
283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 283 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
284 | 284 | ||
285 | /* | 285 | #ifdef CONFIG_RT2500USB_LEDS |
286 | * Configuration handlers. | 286 | static void rt2500usb_led_brightness(struct led_classdev *led_cdev, |
287 | */ | 287 | enum led_brightness brightness) |
288 | static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, | ||
289 | __le32 *mac) | ||
290 | { | 288 | { |
291 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 289 | struct rt2x00_led *led = |
292 | (3 * sizeof(__le16))); | 290 | container_of(led_cdev, struct rt2x00_led, led_dev); |
293 | } | 291 | unsigned int enabled = brightness != LED_OFF; |
292 | unsigned int activity = | ||
293 | led->rt2x00dev->led_flags & LED_SUPPORT_ACTIVITY; | ||
294 | 294 | ||
295 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, | 295 | if (in_atomic()) { |
296 | __le32 *bssid) | 296 | NOTICE(led->rt2x00dev, |
297 | { | 297 | "Ignoring LED brightness command for led %d", led->type); |
298 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, bssid, | 298 | return; |
299 | (3 * sizeof(__le16))); | 299 | } |
300 | |||
301 | if (led->type == LED_TYPE_RADIO || led->type == LED_TYPE_ASSOC) { | ||
302 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
303 | MAC_CSR20_LINK, enabled); | ||
304 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
305 | MAC_CSR20_ACTIVITY, enabled && activity); | ||
306 | } | ||
307 | |||
308 | rt2500usb_register_write(led->rt2x00dev, MAC_CSR20, | ||
309 | led->rt2x00dev->led_mcu_reg); | ||
300 | } | 310 | } |
311 | #else | ||
312 | #define rt2500usb_led_brightness NULL | ||
313 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
301 | 314 | ||
302 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 315 | /* |
303 | const int tsf_sync) | 316 | * Configuration handlers. |
317 | */ | ||
318 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
319 | struct rt2x00_intf *intf, | ||
320 | struct rt2x00intf_conf *conf, | ||
321 | const unsigned int flags) | ||
304 | { | 322 | { |
323 | unsigned int bcn_preload; | ||
305 | u16 reg; | 324 | u16 reg; |
306 | 325 | ||
307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | 326 | if (flags & CONFIG_UPDATE_TYPE) { |
327 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
308 | 328 | ||
309 | /* | 329 | /* |
310 | * Enable beacon config | 330 | * Enable beacon config |
311 | */ | 331 | */ |
312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | 332 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
313 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | 333 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); |
314 | (PREAMBLE + get_duration(IEEE80211_HEADER, 20)) >> 6); | 334 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); |
315 | if (type == IEEE80211_IF_TYPE_STA) | 335 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, |
316 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | 336 | 2 * (conf->type != IEEE80211_IF_TYPE_STA)); |
317 | else | 337 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); |
318 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | ||
319 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
320 | 338 | ||
321 | /* | 339 | /* |
322 | * Enable synchronisation. | 340 | * Enable synchronisation. |
323 | */ | 341 | */ |
324 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 342 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
325 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | 343 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); |
326 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 344 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
345 | |||
346 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
347 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
348 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | ||
349 | (conf->sync == TSF_SYNC_BEACON)); | ||
350 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
351 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | ||
352 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
353 | } | ||
327 | 354 | ||
328 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 355 | if (flags & CONFIG_UPDATE_MAC) |
329 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | 356 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, conf->mac, |
330 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | 357 | (3 * sizeof(__le16))); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 358 | |
332 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | 359 | if (flags & CONFIG_UPDATE_BSSID) |
333 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, tsf_sync); | 360 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, conf->bssid, |
334 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 361 | (3 * sizeof(__le16))); |
335 | } | 362 | } |
336 | 363 | ||
337 | static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 364 | static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 365 | const int short_preamble, |
339 | const int ack_timeout, | 366 | const int ack_timeout, |
340 | const int ack_consume_time) | 367 | const int ack_consume_time) |
341 | { | 368 | { |
342 | u16 reg; | 369 | u16 reg; |
343 | 370 | ||
344 | /* | 371 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 372 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 373 | * try this configuration again later. |
347 | */ | 374 | */ |
348 | if (in_atomic()) { | 375 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 376 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 377 | ||
353 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 378 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
354 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); | 379 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); |
@@ -358,21 +383,14 @@ static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 383 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 384 | !!short_preamble); |
360 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 385 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
386 | |||
387 | return 0; | ||
361 | } | 388 | } |
362 | 389 | ||
363 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 390 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
364 | const int phymode, | ||
365 | const int basic_rate_mask) | 391 | const int basic_rate_mask) |
366 | { | 392 | { |
367 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); | 393 | rt2500usb_register_write(rt2x00dev, TXRX_CSR11, basic_rate_mask); |
368 | |||
369 | if (phymode == HWMODE_B) { | ||
370 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x000b); | ||
371 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x0040); | ||
372 | } else { | ||
373 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, 0x0005); | ||
374 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, 0x016c); | ||
375 | } | ||
376 | } | 394 | } |
377 | 395 | ||
378 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, | 396 | static void rt2500usb_config_channel(struct rt2x00_dev *rt2x00dev, |
@@ -510,6 +528,8 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
510 | u16 reg; | 528 | u16 reg; |
511 | 529 | ||
512 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); | 530 | rt2500usb_register_write(rt2x00dev, MAC_CSR10, libconf->slot_time); |
531 | rt2500usb_register_write(rt2x00dev, MAC_CSR11, libconf->sifs); | ||
532 | rt2500usb_register_write(rt2x00dev, MAC_CSR12, libconf->eifs); | ||
513 | 533 | ||
514 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 534 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
515 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, | 535 | rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, |
@@ -518,12 +538,11 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
518 | } | 538 | } |
519 | 539 | ||
520 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 540 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
521 | const unsigned int flags, | 541 | struct rt2x00lib_conf *libconf, |
522 | struct rt2x00lib_conf *libconf) | 542 | const unsigned int flags) |
523 | { | 543 | { |
524 | if (flags & CONFIG_UPDATE_PHYMODE) | 544 | if (flags & CONFIG_UPDATE_PHYMODE) |
525 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, | 545 | rt2500usb_config_phymode(rt2x00dev, libconf->basic_rates); |
526 | libconf->basic_rates); | ||
527 | if (flags & CONFIG_UPDATE_CHANNEL) | 546 | if (flags & CONFIG_UPDATE_CHANNEL) |
528 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, | 547 | rt2500usb_config_channel(rt2x00dev, &libconf->rf, |
529 | libconf->conf->power_level); | 548 | libconf->conf->power_level); |
@@ -537,36 +556,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | |||
537 | } | 556 | } |
538 | 557 | ||
539 | /* | 558 | /* |
540 | * LED functions. | ||
541 | */ | ||
542 | static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
543 | { | ||
544 | u16 reg; | ||
545 | |||
546 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
547 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
548 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
549 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
550 | |||
551 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
552 | rt2x00_set_field16(®, MAC_CSR20_LINK, | ||
553 | (rt2x00dev->led_mode != LED_MODE_ASUS)); | ||
554 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, | ||
555 | (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); | ||
556 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
557 | } | ||
558 | |||
559 | static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
560 | { | ||
561 | u16 reg; | ||
562 | |||
563 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); | ||
564 | rt2x00_set_field16(®, MAC_CSR20_LINK, 0); | ||
565 | rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); | ||
566 | rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * Link tuning | 559 | * Link tuning |
571 | */ | 560 | */ |
572 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | 561 | static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -626,6 +615,24 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | u8 low_bound; | 615 | u8 low_bound; |
627 | 616 | ||
628 | /* | 617 | /* |
618 | * Read current r17 value, as well as the sensitivity values | ||
619 | * for the r17 register. | ||
620 | */ | ||
621 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
622 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
623 | |||
624 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
625 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
626 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
627 | |||
628 | /* | ||
629 | * If we are not associated, we should go straight to the | ||
630 | * dynamic CCA tuning. | ||
631 | */ | ||
632 | if (!rt2x00dev->intf_associated) | ||
633 | goto dynamic_cca_tune; | ||
634 | |||
635 | /* | ||
629 | * Determine the BBP tuning threshold and correctly | 636 | * Determine the BBP tuning threshold and correctly |
630 | * set BBP 24, 25 and 61. | 637 | * set BBP 24, 25 and 61. |
631 | */ | 638 | */ |
@@ -651,13 +658,6 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
651 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | 658 | rt2500usb_bbp_write(rt2x00dev, 61, r61); |
652 | 659 | ||
653 | /* | 660 | /* |
654 | * Read current r17 value, as well as the sensitivity values | ||
655 | * for the r17 register. | ||
656 | */ | ||
657 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
658 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
659 | |||
660 | /* | ||
661 | * A too low RSSI will cause too much false CCA which will | 661 | * A too low RSSI will cause too much false CCA which will |
662 | * then corrupt the R17 tuning. To remidy this the tuning should | 662 | * then corrupt the R17 tuning. To remidy this the tuning should |
663 | * be stopped (While making sure the R17 value will not exceed limits) | 663 | * be stopped (While making sure the R17 value will not exceed limits) |
@@ -692,14 +692,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
692 | * Leave short or middle distance condition, restore r17 | 692 | * Leave short or middle distance condition, restore r17 |
693 | * to the dynamic tuning range. | 693 | * to the dynamic tuning range. |
694 | */ | 694 | */ |
695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
696 | vgc_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
697 | |||
698 | low_bound = 0x32; | 695 | low_bound = 0x32; |
699 | if (rssi >= -77) | 696 | if (rssi < -77) |
700 | up_bound = vgc_bound; | 697 | up_bound -= (-77 - rssi); |
701 | else | ||
702 | up_bound = vgc_bound - (-77 - rssi); | ||
703 | 698 | ||
704 | if (up_bound < low_bound) | 699 | if (up_bound < low_bound) |
705 | up_bound = low_bound; | 700 | up_bound = low_bound; |
@@ -707,7 +702,16 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | if (r17 > up_bound) { | 702 | if (r17 > up_bound) { |
708 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | 703 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); |
709 | rt2x00dev->link.vgc_level = up_bound; | 704 | rt2x00dev->link.vgc_level = up_bound; |
710 | } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 705 | return; |
706 | } | ||
707 | |||
708 | dynamic_cca_tune: | ||
709 | |||
710 | /* | ||
711 | * R17 is inside the dynamic tuning range, | ||
712 | * start tuning the link based on the false cca counter. | ||
713 | */ | ||
714 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
711 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | 715 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); |
712 | rt2x00dev->link.vgc_level = r17; | 716 | rt2x00dev->link.vgc_level = r17; |
713 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 717 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { |
@@ -747,6 +751,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
747 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); | 751 | rt2x00_set_field16(®, MAC_CSR1_HOST_READY, 0); |
748 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); | 752 | rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg); |
749 | 753 | ||
754 | rt2500usb_register_read(rt2x00dev, MAC_CSR21, ®); | ||
755 | rt2x00_set_field16(®, MAC_CSR21_ON_PERIOD, 70); | ||
756 | rt2x00_set_field16(®, MAC_CSR21_OFF_PERIOD, 30); | ||
757 | rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); | ||
758 | |||
750 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); | 759 | rt2500usb_register_read(rt2x00dev, TXRX_CSR5, ®); |
751 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); | 760 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0, 13); |
752 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); | 761 | rt2x00_set_field16(®, TXRX_CSR5_BBP_ID0_VALID, 1); |
@@ -878,19 +887,15 @@ continue_csr_init: | |||
878 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); | 887 | rt2500usb_bbp_write(rt2x00dev, 62, 0x10); |
879 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); | 888 | rt2500usb_bbp_write(rt2x00dev, 75, 0xff); |
880 | 889 | ||
881 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
882 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 890 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
883 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 891 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
884 | 892 | ||
885 | if (eeprom != 0xffff && eeprom != 0x0000) { | 893 | if (eeprom != 0xffff && eeprom != 0x0000) { |
886 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 894 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
887 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 895 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
888 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
889 | reg_id, value); | ||
890 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); | 896 | rt2500usb_bbp_write(rt2x00dev, reg_id, value); |
891 | } | 897 | } |
892 | } | 898 | } |
893 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
894 | 899 | ||
895 | return 0; | 900 | return 0; |
896 | } | 901 | } |
@@ -920,21 +925,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
920 | return -EIO; | 925 | return -EIO; |
921 | } | 926 | } |
922 | 927 | ||
923 | /* | ||
924 | * Enable LED | ||
925 | */ | ||
926 | rt2500usb_enable_led(rt2x00dev); | ||
927 | |||
928 | return 0; | 928 | return 0; |
929 | } | 929 | } |
930 | 930 | ||
931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 931 | static void rt2500usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
932 | { | 932 | { |
933 | /* | ||
934 | * Disable LED | ||
935 | */ | ||
936 | rt2500usb_disable_led(rt2x00dev); | ||
937 | |||
938 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); | 933 | rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x2121); |
939 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); | 934 | rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x2121); |
940 | 935 | ||
@@ -1027,10 +1022,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1027 | */ | 1022 | */ |
1028 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1023 | static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1029 | struct sk_buff *skb, | 1024 | struct sk_buff *skb, |
1030 | struct txdata_entry_desc *desc, | 1025 | struct txentry_desc *txdesc, |
1031 | struct ieee80211_tx_control *control) | 1026 | struct ieee80211_tx_control *control) |
1032 | { | 1027 | { |
1033 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1028 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1034 | __le32 *txd = skbdesc->desc; | 1029 | __le32 *txd = skbdesc->desc; |
1035 | u32 word; | 1030 | u32 word; |
1036 | 1031 | ||
@@ -1039,31 +1034,31 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1039 | */ | 1034 | */ |
1040 | rt2x00_desc_read(txd, 1, &word); | 1035 | rt2x00_desc_read(txd, 1, &word); |
1041 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1036 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1042 | rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs); | 1037 | rt2x00_set_field32(&word, TXD_W1_AIFS, txdesc->aifs); |
1043 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1038 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1044 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1039 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1045 | rt2x00_desc_write(txd, 1, word); | 1040 | rt2x00_desc_write(txd, 1, word); |
1046 | 1041 | ||
1047 | rt2x00_desc_read(txd, 2, &word); | 1042 | rt2x00_desc_read(txd, 2, &word); |
1048 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1043 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1049 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1044 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1050 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1045 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1051 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1046 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1052 | rt2x00_desc_write(txd, 2, word); | 1047 | rt2x00_desc_write(txd, 2, word); |
1053 | 1048 | ||
1054 | rt2x00_desc_read(txd, 0, &word); | 1049 | rt2x00_desc_read(txd, 0, &word); |
1055 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); | 1050 | rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit); |
1056 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1051 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1057 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1052 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1058 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1053 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1059 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1054 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1060 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1055 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1061 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1056 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1062 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1057 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1063 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1058 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1064 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1059 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1065 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); | 1060 | !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT)); |
1066 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1061 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1067 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1062 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1068 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1063 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
1069 | rt2x00_desc_write(txd, 0, word); | 1064 | rt2x00_desc_write(txd, 0, word); |
@@ -1088,11 +1083,11 @@ static int rt2500usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1088 | * TX data initialization | 1083 | * TX data initialization |
1089 | */ | 1084 | */ |
1090 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1085 | static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1091 | unsigned int queue) | 1086 | const unsigned int queue) |
1092 | { | 1087 | { |
1093 | u16 reg; | 1088 | u16 reg; |
1094 | 1089 | ||
1095 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1090 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1096 | return; | 1091 | return; |
1097 | 1092 | ||
1098 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1093 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
@@ -1114,42 +1109,61 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1114 | /* | 1109 | /* |
1115 | * RX control handlers | 1110 | * RX control handlers |
1116 | */ | 1111 | */ |
1117 | static void rt2500usb_fill_rxdone(struct data_entry *entry, | 1112 | static void rt2500usb_fill_rxdone(struct queue_entry *entry, |
1118 | struct rxdata_entry_desc *desc) | 1113 | struct rxdone_entry_desc *rxdesc) |
1119 | { | 1114 | { |
1120 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1115 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
1121 | struct urb *urb = entry->priv; | 1116 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1122 | __le32 *rxd = (__le32 *)(entry->skb->data + | 1117 | __le32 *rxd = |
1123 | (urb->actual_length - entry->ring->desc_size)); | 1118 | (__le32 *)(entry->skb->data + |
1119 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | ||
1120 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
1121 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1124 | u32 word0; | 1122 | u32 word0; |
1125 | u32 word1; | 1123 | u32 word1; |
1126 | 1124 | ||
1127 | rt2x00_desc_read(rxd, 0, &word0); | 1125 | rt2x00_desc_read(rxd, 0, &word0); |
1128 | rt2x00_desc_read(rxd, 1, &word1); | 1126 | rt2x00_desc_read(rxd, 1, &word1); |
1129 | 1127 | ||
1130 | desc->flags = 0; | 1128 | rxdesc->flags = 0; |
1131 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1129 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1132 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1130 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1133 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) | 1131 | if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR)) |
1134 | desc->flags |= RX_FLAG_FAILED_PLCP_CRC; | 1132 | rxdesc->flags |= RX_FLAG_FAILED_PLCP_CRC; |
1135 | 1133 | ||
1136 | /* | 1134 | /* |
1137 | * Obtain the status about this packet. | 1135 | * Obtain the status about this packet. |
1138 | */ | 1136 | */ |
1139 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1137 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1140 | desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - | 1138 | rxdesc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) - |
1141 | entry->ring->rt2x00dev->rssi_offset; | 1139 | entry->queue->rt2x00dev->rssi_offset; |
1142 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1140 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1143 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1141 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1144 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1142 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1143 | |||
1144 | /* | ||
1145 | * The data behind the ieee80211 header must be | ||
1146 | * aligned on a 4 byte boundary. | ||
1147 | */ | ||
1148 | if (header_size % 4 == 0) { | ||
1149 | skb_push(entry->skb, 2); | ||
1150 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1151 | entry->skb->len - 2); | ||
1152 | } | ||
1145 | 1153 | ||
1146 | /* | 1154 | /* |
1147 | * Set descriptor and data pointer. | 1155 | * Set descriptor pointer. |
1148 | */ | 1156 | */ |
1149 | skbdesc->desc = entry->skb->data + desc->size; | ||
1150 | skbdesc->desc_len = entry->ring->desc_size; | ||
1151 | skbdesc->data = entry->skb->data; | 1157 | skbdesc->data = entry->skb->data; |
1152 | skbdesc->data_len = desc->size; | 1158 | skbdesc->data_len = rxdesc->size; |
1159 | skbdesc->desc = entry->skb->data + rxdesc->size; | ||
1160 | skbdesc->desc_len = entry->queue->desc_size; | ||
1161 | |||
1162 | /* | ||
1163 | * Remove descriptor from skb buffer and trim the whole thing | ||
1164 | * down to only contain data. | ||
1165 | */ | ||
1166 | skb_trim(entry->skb, rxdesc->size); | ||
1153 | } | 1167 | } |
1154 | 1168 | ||
1155 | /* | 1169 | /* |
@@ -1157,10 +1171,10 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry, | |||
1157 | */ | 1171 | */ |
1158 | static void rt2500usb_beacondone(struct urb *urb) | 1172 | static void rt2500usb_beacondone(struct urb *urb) |
1159 | { | 1173 | { |
1160 | struct data_entry *entry = (struct data_entry *)urb->context; | 1174 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
1161 | struct data_ring *ring = entry->ring; | 1175 | struct queue_entry_priv_usb_bcn *priv_bcn = entry->priv_data; |
1162 | 1176 | ||
1163 | if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) | 1177 | if (!test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) |
1164 | return; | 1178 | return; |
1165 | 1179 | ||
1166 | /* | 1180 | /* |
@@ -1169,18 +1183,11 @@ static void rt2500usb_beacondone(struct urb *urb) | |||
1169 | * Otherwise we should free the sk_buffer, the device | 1183 | * Otherwise we should free the sk_buffer, the device |
1170 | * should be doing the rest of the work now. | 1184 | * should be doing the rest of the work now. |
1171 | */ | 1185 | */ |
1172 | if (ring->index == 1) { | 1186 | if (priv_bcn->guardian_urb == urb) { |
1173 | rt2x00_ring_index_done_inc(ring); | 1187 | usb_submit_urb(priv_bcn->urb, GFP_ATOMIC); |
1174 | entry = rt2x00_get_data_entry(ring); | 1188 | } else if (priv_bcn->urb == urb) { |
1175 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 1189 | dev_kfree_skb(entry->skb); |
1176 | rt2x00_ring_index_inc(ring); | 1190 | entry->skb = NULL; |
1177 | } else if (ring->index_done == 1) { | ||
1178 | entry = rt2x00_get_data_entry_done(ring); | ||
1179 | if (entry->skb) { | ||
1180 | dev_kfree_skb(entry->skb); | ||
1181 | entry->skb = NULL; | ||
1182 | } | ||
1183 | rt2x00_ring_index_done_inc(ring); | ||
1184 | } | 1191 | } |
1185 | } | 1192 | } |
1186 | 1193 | ||
@@ -1191,6 +1198,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1191 | { | 1198 | { |
1192 | u16 word; | 1199 | u16 word; |
1193 | u8 *mac; | 1200 | u8 *mac; |
1201 | u8 bbp; | ||
1194 | 1202 | ||
1195 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 1203 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); |
1196 | 1204 | ||
@@ -1245,9 +1253,17 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1245 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1253 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); |
1246 | } | 1254 | } |
1247 | 1255 | ||
1256 | /* | ||
1257 | * Switch lower vgc bound to current BBP R17 value, | ||
1258 | * lower the value a bit for better quality. | ||
1259 | */ | ||
1260 | rt2500usb_bbp_read(rt2x00dev, 17, &bbp); | ||
1261 | bbp -= 6; | ||
1262 | |||
1248 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | 1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); |
1249 | if (word == 0xffff) { | 1264 | if (word == 0xffff) { |
1250 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1265 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
1266 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1251 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1267 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
1252 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1268 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
1253 | } | 1269 | } |
@@ -1258,6 +1274,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1258 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1274 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
1259 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1275 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
1260 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1276 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
1277 | } else { | ||
1278 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1279 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
1261 | } | 1280 | } |
1262 | 1281 | ||
1263 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1282 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
@@ -1342,8 +1361,31 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1342 | /* | 1361 | /* |
1343 | * Store led mode, for correct led behaviour. | 1362 | * Store led mode, for correct led behaviour. |
1344 | */ | 1363 | */ |
1345 | rt2x00dev->led_mode = | 1364 | #ifdef CONFIG_RT2500USB_LEDS |
1346 | rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1365 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1366 | |||
1367 | switch (value) { | ||
1368 | case LED_MODE_ASUS: | ||
1369 | case LED_MODE_ALPHA: | ||
1370 | case LED_MODE_DEFAULT: | ||
1371 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1372 | break; | ||
1373 | case LED_MODE_TXRX_ACTIVITY: | ||
1374 | rt2x00dev->led_flags = | ||
1375 | LED_SUPPORT_RADIO | LED_SUPPORT_ACTIVITY; | ||
1376 | break; | ||
1377 | case LED_MODE_SIGNAL_STRENGTH: | ||
1378 | rt2x00dev->led_flags = LED_SUPPORT_RADIO; | ||
1379 | break; | ||
1380 | } | ||
1381 | |||
1382 | /* | ||
1383 | * Store the current led register value, we need it later | ||
1384 | * in set_brightness but that is called in irq context which | ||
1385 | * means we can't use rt2500usb_register_read() at that time. | ||
1386 | */ | ||
1387 | rt2500usb_register_read(rt2x00dev, MAC_CSR20, &rt2x00dev->led_mcu_reg); | ||
1388 | #endif /* CONFIG_RT2500USB_LEDS */ | ||
1347 | 1389 | ||
1348 | /* | 1390 | /* |
1349 | * Check if the BBP tuning should be disabled. | 1391 | * Check if the BBP tuning should be disabled. |
@@ -1550,8 +1592,8 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1550 | /* | 1592 | /* |
1551 | * Initialize hw_mode information. | 1593 | * Initialize hw_mode information. |
1552 | */ | 1594 | */ |
1553 | spec->num_modes = 2; | 1595 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1554 | spec->num_rates = 12; | 1596 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1555 | spec->tx_power_a = NULL; | 1597 | spec->tx_power_a = NULL; |
1556 | spec->tx_power_bg = txpower; | 1598 | spec->tx_power_bg = txpower; |
1557 | spec->tx_power_default = DEFAULT_TXPOWER; | 1599 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1572,9 +1614,9 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1572 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); | 1614 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2525e); |
1573 | spec->channels = rf_vals_bg_2525e; | 1615 | spec->channels = rf_vals_bg_2525e; |
1574 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { | 1616 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5222)) { |
1617 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1575 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); | 1618 | spec->num_channels = ARRAY_SIZE(rf_vals_5222); |
1576 | spec->channels = rf_vals_5222; | 1619 | spec->channels = rf_vals_5222; |
1577 | spec->num_modes = 3; | ||
1578 | } | 1620 | } |
1579 | } | 1621 | } |
1580 | 1622 | ||
@@ -1599,9 +1641,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1599 | rt2500usb_probe_hw_mode(rt2x00dev); | 1641 | rt2500usb_probe_hw_mode(rt2x00dev); |
1600 | 1642 | ||
1601 | /* | 1643 | /* |
1602 | * This device requires the beacon ring | 1644 | * This device requires the atim queue |
1603 | */ | 1645 | */ |
1604 | __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | 1646 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1647 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
1605 | 1648 | ||
1606 | /* | 1649 | /* |
1607 | * Set the rssi offset. | 1650 | * Set the rssi offset. |
@@ -1691,48 +1734,42 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1691 | struct ieee80211_tx_control *control) | 1734 | struct ieee80211_tx_control *control) |
1692 | { | 1735 | { |
1693 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1736 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1694 | struct usb_device *usb_dev = | 1737 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1695 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 1738 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1696 | struct skb_desc *desc; | 1739 | struct queue_entry_priv_usb_bcn *priv_bcn; |
1697 | struct data_ring *ring; | 1740 | struct skb_frame_desc *skbdesc; |
1698 | struct data_entry *beacon; | ||
1699 | struct data_entry *guardian; | ||
1700 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1741 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1701 | int length; | 1742 | int length; |
1702 | 1743 | ||
1703 | /* | 1744 | if (unlikely(!intf->beacon)) |
1704 | * Just in case the ieee80211 doesn't set this, | 1745 | return -ENOBUFS; |
1705 | * but we need this queue set for the descriptor | ||
1706 | * initialization. | ||
1707 | */ | ||
1708 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1709 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1710 | 1746 | ||
1711 | /* | 1747 | priv_bcn = intf->beacon->priv_data; |
1712 | * Obtain 2 entries, one for the guardian byte, | ||
1713 | * the second for the actual beacon. | ||
1714 | */ | ||
1715 | guardian = rt2x00_get_data_entry(ring); | ||
1716 | rt2x00_ring_index_inc(ring); | ||
1717 | beacon = rt2x00_get_data_entry(ring); | ||
1718 | 1748 | ||
1719 | /* | 1749 | /* |
1720 | * Add the descriptor in front of the skb. | 1750 | * Add the descriptor in front of the skb. |
1721 | */ | 1751 | */ |
1722 | skb_push(skb, ring->desc_size); | 1752 | skb_push(skb, intf->beacon->queue->desc_size); |
1723 | memset(skb->data, 0, ring->desc_size); | 1753 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1724 | 1754 | ||
1725 | /* | 1755 | /* |
1726 | * Fill in skb descriptor | 1756 | * Fill in skb descriptor |
1727 | */ | 1757 | */ |
1728 | desc = get_skb_desc(skb); | 1758 | skbdesc = get_skb_frame_desc(skb); |
1729 | desc->desc_len = ring->desc_size; | 1759 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1730 | desc->data_len = skb->len - ring->desc_size; | 1760 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1731 | desc->desc = skb->data; | 1761 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1732 | desc->data = skb->data + ring->desc_size; | 1762 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1733 | desc->ring = ring; | 1763 | skbdesc->desc = skb->data; |
1734 | desc->entry = beacon; | 1764 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1765 | skbdesc->entry = intf->beacon; | ||
1735 | 1766 | ||
1767 | /* | ||
1768 | * mac80211 doesn't provide the control->queue variable | ||
1769 | * for beacons. Set our own queue identification so | ||
1770 | * it can be used during descriptor initialization. | ||
1771 | */ | ||
1772 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
1736 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 1773 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
1737 | 1774 | ||
1738 | /* | 1775 | /* |
@@ -1742,27 +1779,29 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1742 | */ | 1779 | */ |
1743 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1780 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1744 | 1781 | ||
1745 | usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, | 1782 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, |
1746 | skb->data, length, rt2500usb_beacondone, beacon); | 1783 | skb->data, length, rt2500usb_beacondone, |
1784 | intf->beacon); | ||
1747 | 1785 | ||
1748 | /* | 1786 | /* |
1749 | * Second we need to create the guardian byte. | 1787 | * Second we need to create the guardian byte. |
1750 | * We only need a single byte, so lets recycle | 1788 | * We only need a single byte, so lets recycle |
1751 | * the 'flags' field we are not using for beacons. | 1789 | * the 'flags' field we are not using for beacons. |
1752 | */ | 1790 | */ |
1753 | guardian->flags = 0; | 1791 | priv_bcn->guardian_data = 0; |
1754 | usb_fill_bulk_urb(guardian->priv, usb_dev, pipe, | 1792 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, |
1755 | &guardian->flags, 1, rt2500usb_beacondone, guardian); | 1793 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, |
1794 | intf->beacon); | ||
1756 | 1795 | ||
1757 | /* | 1796 | /* |
1758 | * Send out the guardian byte. | 1797 | * Send out the guardian byte. |
1759 | */ | 1798 | */ |
1760 | usb_submit_urb(guardian->priv, GFP_ATOMIC); | 1799 | usb_submit_urb(priv_bcn->guardian_urb, GFP_ATOMIC); |
1761 | 1800 | ||
1762 | /* | 1801 | /* |
1763 | * Enable beacon generation. | 1802 | * Enable beacon generation. |
1764 | */ | 1803 | */ |
1765 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 1804 | rt2500usb_kick_tx_queue(rt2x00dev, control->queue); |
1766 | 1805 | ||
1767 | return 0; | 1806 | return 0; |
1768 | } | 1807 | } |
@@ -1793,24 +1832,55 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1793 | .link_stats = rt2500usb_link_stats, | 1832 | .link_stats = rt2500usb_link_stats, |
1794 | .reset_tuner = rt2500usb_reset_tuner, | 1833 | .reset_tuner = rt2500usb_reset_tuner, |
1795 | .link_tuner = rt2500usb_link_tuner, | 1834 | .link_tuner = rt2500usb_link_tuner, |
1835 | .led_brightness = rt2500usb_led_brightness, | ||
1796 | .write_tx_desc = rt2500usb_write_tx_desc, | 1836 | .write_tx_desc = rt2500usb_write_tx_desc, |
1797 | .write_tx_data = rt2x00usb_write_tx_data, | 1837 | .write_tx_data = rt2x00usb_write_tx_data, |
1798 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1838 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1799 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1839 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1800 | .fill_rxdone = rt2500usb_fill_rxdone, | 1840 | .fill_rxdone = rt2500usb_fill_rxdone, |
1801 | .config_mac_addr = rt2500usb_config_mac_addr, | 1841 | .config_intf = rt2500usb_config_intf, |
1802 | .config_bssid = rt2500usb_config_bssid, | ||
1803 | .config_type = rt2500usb_config_type, | ||
1804 | .config_preamble = rt2500usb_config_preamble, | 1842 | .config_preamble = rt2500usb_config_preamble, |
1805 | .config = rt2500usb_config, | 1843 | .config = rt2500usb_config, |
1806 | }; | 1844 | }; |
1807 | 1845 | ||
1846 | static const struct data_queue_desc rt2500usb_queue_rx = { | ||
1847 | .entry_num = RX_ENTRIES, | ||
1848 | .data_size = DATA_FRAME_SIZE, | ||
1849 | .desc_size = RXD_DESC_SIZE, | ||
1850 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
1851 | }; | ||
1852 | |||
1853 | static const struct data_queue_desc rt2500usb_queue_tx = { | ||
1854 | .entry_num = TX_ENTRIES, | ||
1855 | .data_size = DATA_FRAME_SIZE, | ||
1856 | .desc_size = TXD_DESC_SIZE, | ||
1857 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1858 | }; | ||
1859 | |||
1860 | static const struct data_queue_desc rt2500usb_queue_bcn = { | ||
1861 | .entry_num = BEACON_ENTRIES, | ||
1862 | .data_size = MGMT_FRAME_SIZE, | ||
1863 | .desc_size = TXD_DESC_SIZE, | ||
1864 | .priv_size = sizeof(struct queue_entry_priv_usb_bcn), | ||
1865 | }; | ||
1866 | |||
1867 | static const struct data_queue_desc rt2500usb_queue_atim = { | ||
1868 | .entry_num = ATIM_ENTRIES, | ||
1869 | .data_size = DATA_FRAME_SIZE, | ||
1870 | .desc_size = TXD_DESC_SIZE, | ||
1871 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
1872 | }; | ||
1873 | |||
1808 | static const struct rt2x00_ops rt2500usb_ops = { | 1874 | static const struct rt2x00_ops rt2500usb_ops = { |
1809 | .name = KBUILD_MODNAME, | 1875 | .name = KBUILD_MODNAME, |
1810 | .rxd_size = RXD_DESC_SIZE, | 1876 | .max_sta_intf = 1, |
1811 | .txd_size = TXD_DESC_SIZE, | 1877 | .max_ap_intf = 1, |
1812 | .eeprom_size = EEPROM_SIZE, | 1878 | .eeprom_size = EEPROM_SIZE, |
1813 | .rf_size = RF_SIZE, | 1879 | .rf_size = RF_SIZE, |
1880 | .rx = &rt2500usb_queue_rx, | ||
1881 | .tx = &rt2500usb_queue_tx, | ||
1882 | .bcn = &rt2500usb_queue_bcn, | ||
1883 | .atim = &rt2500usb_queue_atim, | ||
1814 | .lib = &rt2500usb_rt2x00_ops, | 1884 | .lib = &rt2500usb_rt2x00_ops, |
1815 | .hw = &rt2500usb_mac80211_ops, | 1885 | .hw = &rt2500usb_mac80211_ops, |
1816 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 1886 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 9e0433722e3d..a37a068d0c71 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -135,7 +135,7 @@ | |||
135 | * Misc MAC_CSR registers. | 135 | * Misc MAC_CSR registers. |
136 | * MAC_CSR9: Timer control. | 136 | * MAC_CSR9: Timer control. |
137 | * MAC_CSR10: Slot time. | 137 | * MAC_CSR10: Slot time. |
138 | * MAC_CSR11: IFS. | 138 | * MAC_CSR11: SIFS. |
139 | * MAC_CSR12: EIFS. | 139 | * MAC_CSR12: EIFS. |
140 | * MAC_CSR13: Power mode0. | 140 | * MAC_CSR13: Power mode0. |
141 | * MAC_CSR14: Power mode1. | 141 | * MAC_CSR14: Power mode1. |
@@ -686,6 +686,7 @@ | |||
686 | */ | 686 | */ |
687 | #define EEPROM_BBPTUNE_VGC 0x0034 | 687 | #define EEPROM_BBPTUNE_VGC 0x0034 |
688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) | 688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) |
689 | #define EEPROM_BBPTUNE_VGCLOWER FIELD16(0xff00) | ||
689 | 690 | ||
690 | /* | 691 | /* |
691 | * EEPROM BBP R17 Tuning. | 692 | * EEPROM BBP R17 Tuning. |
@@ -786,8 +787,8 @@ | |||
786 | #define RXD_W3_EIV FIELD32(0xffffffff) | 787 | #define RXD_W3_EIV FIELD32(0xffffffff) |
787 | 788 | ||
788 | /* | 789 | /* |
789 | * Macro's for converting txpower from EEPROM to dscape value | 790 | * Macro's for converting txpower from EEPROM to mac80211 value |
790 | * and from dscape value to register value. | 791 | * and from mac80211 value to register value. |
791 | */ | 792 | */ |
792 | #define MIN_TXPOWER 0 | 793 | #define MIN_TXPOWER 0 |
793 | #define MAX_TXPOWER 31 | 794 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 05927b908f80..fd65fccbdae7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -27,23 +27,24 @@ | |||
27 | #define RT2X00_H | 27 | #define RT2X00_H |
28 | 28 | ||
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <linux/prefetch.h> | ||
31 | #include <linux/skbuff.h> | 30 | #include <linux/skbuff.h> |
32 | #include <linux/workqueue.h> | 31 | #include <linux/workqueue.h> |
33 | #include <linux/firmware.h> | 32 | #include <linux/firmware.h> |
33 | #include <linux/leds.h> | ||
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | 36 | ||
37 | #include <net/mac80211.h> | 37 | #include <net/mac80211.h> |
38 | 38 | ||
39 | #include "rt2x00debug.h" | 39 | #include "rt2x00debug.h" |
40 | #include "rt2x00leds.h" | ||
40 | #include "rt2x00reg.h" | 41 | #include "rt2x00reg.h" |
41 | #include "rt2x00ring.h" | 42 | #include "rt2x00queue.h" |
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Module information. | 45 | * Module information. |
45 | */ | 46 | */ |
46 | #define DRV_VERSION "2.0.14" | 47 | #define DRV_VERSION "2.1.3" |
47 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -91,26 +92,6 @@ | |||
91 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) | 92 | DEBUG_PRINTK(__dev, KERN_DEBUG, "EEPROM recovery", __msg, ##__args) |
92 | 93 | ||
93 | /* | 94 | /* |
94 | * Ring sizes. | ||
95 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes. | ||
96 | * DATA_FRAME_SIZE is used for TX, RX, ATIM and PRIO rings. | ||
97 | * MGMT_FRAME_SIZE is used for the BEACON ring. | ||
98 | */ | ||
99 | #define DATA_FRAME_SIZE 2432 | ||
100 | #define MGMT_FRAME_SIZE 256 | ||
101 | |||
102 | /* | ||
103 | * Number of entries in a packet ring. | ||
104 | * PCI devices only need 1 Beacon entry, | ||
105 | * but USB devices require a second because they | ||
106 | * have to send a Guardian byte first. | ||
107 | */ | ||
108 | #define RX_ENTRIES 12 | ||
109 | #define TX_ENTRIES 12 | ||
110 | #define ATIM_ENTRIES 1 | ||
111 | #define BEACON_ENTRIES 2 | ||
112 | |||
113 | /* | ||
114 | * Standard timing and size defines. | 95 | * Standard timing and size defines. |
115 | * These values should follow the ieee80211 specifications. | 96 | * These values should follow the ieee80211 specifications. |
116 | */ | 97 | */ |
@@ -364,20 +345,22 @@ static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) | |||
364 | 345 | ||
365 | /* | 346 | /* |
366 | * Interface structure | 347 | * Interface structure |
367 | * Configuration details about the current interface. | 348 | * Per interface configuration details, this structure |
349 | * is allocated as the private data for ieee80211_vif. | ||
368 | */ | 350 | */ |
369 | struct interface { | 351 | struct rt2x00_intf { |
370 | /* | 352 | /* |
371 | * Interface identification. The value is assigned | 353 | * All fields within the rt2x00_intf structure |
372 | * to us by the 80211 stack, and is used to request | 354 | * must be protected with a spinlock. |
373 | * new beacons. | ||
374 | */ | 355 | */ |
375 | struct ieee80211_vif *id; | 356 | spinlock_t lock; |
376 | 357 | ||
377 | /* | 358 | /* |
378 | * Current working type (IEEE80211_IF_TYPE_*). | 359 | * BSS configuration. Copied from the structure |
360 | * passed to us through the bss_info_changed() | ||
361 | * callback funtion. | ||
379 | */ | 362 | */ |
380 | int type; | 363 | struct ieee80211_bss_conf conf; |
381 | 364 | ||
382 | /* | 365 | /* |
383 | * MAC of the device. | 366 | * MAC of the device. |
@@ -388,42 +371,59 @@ struct interface { | |||
388 | * BBSID of the AP to associate with. | 371 | * BBSID of the AP to associate with. |
389 | */ | 372 | */ |
390 | u8 bssid[ETH_ALEN]; | 373 | u8 bssid[ETH_ALEN]; |
391 | }; | ||
392 | 374 | ||
393 | static inline int is_interface_present(struct interface *intf) | 375 | /* |
394 | { | 376 | * Entry in the beacon queue which belongs to |
395 | return !!intf->id; | 377 | * this interface. Each interface has its own |
396 | } | 378 | * dedicated beacon entry. |
379 | */ | ||
380 | struct queue_entry *beacon; | ||
381 | |||
382 | /* | ||
383 | * Actions that needed rescheduling. | ||
384 | */ | ||
385 | unsigned int delayed_flags; | ||
386 | #define DELAYED_UPDATE_BEACON 0x00000001 | ||
387 | #define DELAYED_CONFIG_PREAMBLE 0x00000002 | ||
388 | }; | ||
397 | 389 | ||
398 | static inline int is_interface_type(struct interface *intf, int type) | 390 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) |
399 | { | 391 | { |
400 | return intf->type == type; | 392 | return (struct rt2x00_intf *)vif->drv_priv; |
401 | } | 393 | } |
402 | 394 | ||
403 | /* | 395 | /** |
396 | * struct hw_mode_spec: Hardware specifications structure | ||
397 | * | ||
404 | * Details about the supported modes, rates and channels | 398 | * Details about the supported modes, rates and channels |
405 | * of a particular chipset. This is used by rt2x00lib | 399 | * of a particular chipset. This is used by rt2x00lib |
406 | * to build the ieee80211_hw_mode array for mac80211. | 400 | * to build the ieee80211_hw_mode array for mac80211. |
401 | * | ||
402 | * @supported_bands: Bitmask contained the supported bands (2.4GHz, 5.2GHz). | ||
403 | * @supported_rates: Rate types which are supported (CCK, OFDM). | ||
404 | * @num_channels: Number of supported channels. This is used as array size | ||
405 | * for @tx_power_a, @tx_power_bg and @channels. | ||
406 | * channels: Device/chipset specific channel values (See &struct rf_channel). | ||
407 | * @tx_power_a: TX power values for all 5.2GHz channels (may be NULL). | ||
408 | * @tx_power_bg: TX power values for all 2.4GHz channels (may be NULL). | ||
409 | * @tx_power_default: Default TX power value to use when either | ||
410 | * @tx_power_a or @tx_power_bg is missing. | ||
407 | */ | 411 | */ |
408 | struct hw_mode_spec { | 412 | struct hw_mode_spec { |
409 | /* | 413 | unsigned int supported_bands; |
410 | * Number of modes, rates and channels. | 414 | #define SUPPORT_BAND_2GHZ 0x00000001 |
411 | */ | 415 | #define SUPPORT_BAND_5GHZ 0x00000002 |
412 | int num_modes; | 416 | |
413 | int num_rates; | 417 | unsigned int supported_rates; |
414 | int num_channels; | 418 | #define SUPPORT_RATE_CCK 0x00000001 |
419 | #define SUPPORT_RATE_OFDM 0x00000002 | ||
420 | |||
421 | unsigned int num_channels; | ||
422 | const struct rf_channel *channels; | ||
415 | 423 | ||
416 | /* | ||
417 | * txpower values. | ||
418 | */ | ||
419 | const u8 *tx_power_a; | 424 | const u8 *tx_power_a; |
420 | const u8 *tx_power_bg; | 425 | const u8 *tx_power_bg; |
421 | u8 tx_power_default; | 426 | u8 tx_power_default; |
422 | |||
423 | /* | ||
424 | * Device/chipset specific value. | ||
425 | */ | ||
426 | const struct rf_channel *channels; | ||
427 | }; | 427 | }; |
428 | 428 | ||
429 | /* | 429 | /* |
@@ -439,7 +439,7 @@ struct rt2x00lib_conf { | |||
439 | 439 | ||
440 | struct antenna_setup ant; | 440 | struct antenna_setup ant; |
441 | 441 | ||
442 | int phymode; | 442 | enum ieee80211_band band; |
443 | 443 | ||
444 | int basic_rates; | 444 | int basic_rates; |
445 | int slot_time; | 445 | int slot_time; |
@@ -451,6 +451,37 @@ struct rt2x00lib_conf { | |||
451 | }; | 451 | }; |
452 | 452 | ||
453 | /* | 453 | /* |
454 | * Configuration structure wrapper around the | ||
455 | * rt2x00 interface configuration handler. | ||
456 | */ | ||
457 | struct rt2x00intf_conf { | ||
458 | /* | ||
459 | * Interface type | ||
460 | */ | ||
461 | enum ieee80211_if_types type; | ||
462 | |||
463 | /* | ||
464 | * TSF sync value, this is dependant on the operation type. | ||
465 | */ | ||
466 | enum tsf_sync sync; | ||
467 | |||
468 | /* | ||
469 | * The MAC and BSSID addressess are simple array of bytes, | ||
470 | * these arrays are little endian, so when sending the addressess | ||
471 | * to the drivers, copy the it into a endian-signed variable. | ||
472 | * | ||
473 | * Note that all devices (except rt2500usb) have 32 bits | ||
474 | * register word sizes. This means that whatever variable we | ||
475 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
476 | * might not accept what we are sending to it. | ||
477 | * This will also make it easier for the driver to write | ||
478 | * the data to the device. | ||
479 | */ | ||
480 | __le32 mac[2]; | ||
481 | __le32 bssid[2]; | ||
482 | }; | ||
483 | |||
484 | /* | ||
454 | * rt2x00lib callback functions. | 485 | * rt2x00lib callback functions. |
455 | */ | 486 | */ |
456 | struct rt2x00lib_ops { | 487 | struct rt2x00lib_ops { |
@@ -474,12 +505,12 @@ struct rt2x00lib_ops { | |||
474 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); | 505 | void (*uninitialize) (struct rt2x00_dev *rt2x00dev); |
475 | 506 | ||
476 | /* | 507 | /* |
477 | * Ring initialization handlers | 508 | * queue initialization handlers |
478 | */ | 509 | */ |
479 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, | 510 | void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, |
480 | struct data_entry *entry); | 511 | struct queue_entry *entry); |
481 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, | 512 | void (*init_txentry) (struct rt2x00_dev *rt2x00dev, |
482 | struct data_entry *entry); | 513 | struct queue_entry *entry); |
483 | 514 | ||
484 | /* | 515 | /* |
485 | * Radio control handlers. | 516 | * Radio control handlers. |
@@ -491,41 +522,48 @@ struct rt2x00lib_ops { | |||
491 | struct link_qual *qual); | 522 | struct link_qual *qual); |
492 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | 523 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); |
493 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | 524 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); |
525 | void (*led_brightness) (struct led_classdev *led_cdev, | ||
526 | enum led_brightness brightness); | ||
494 | 527 | ||
495 | /* | 528 | /* |
496 | * TX control handlers | 529 | * TX control handlers |
497 | */ | 530 | */ |
498 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 531 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
499 | struct sk_buff *skb, | 532 | struct sk_buff *skb, |
500 | struct txdata_entry_desc *desc, | 533 | struct txentry_desc *txdesc, |
501 | struct ieee80211_tx_control *control); | 534 | struct ieee80211_tx_control *control); |
502 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 535 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, |
503 | struct data_ring *ring, struct sk_buff *skb, | 536 | struct data_queue *queue, struct sk_buff *skb, |
504 | struct ieee80211_tx_control *control); | 537 | struct ieee80211_tx_control *control); |
505 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 538 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
506 | struct sk_buff *skb); | 539 | struct sk_buff *skb); |
507 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 540 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
508 | unsigned int queue); | 541 | const unsigned int queue); |
509 | 542 | ||
510 | /* | 543 | /* |
511 | * RX control handlers | 544 | * RX control handlers |
512 | */ | 545 | */ |
513 | void (*fill_rxdone) (struct data_entry *entry, | 546 | void (*fill_rxdone) (struct queue_entry *entry, |
514 | struct rxdata_entry_desc *desc); | 547 | struct rxdone_entry_desc *rxdesc); |
515 | 548 | ||
516 | /* | 549 | /* |
517 | * Configuration handlers. | 550 | * Configuration handlers. |
518 | */ | 551 | */ |
519 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, __le32 *mac); | 552 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
520 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, __le32 *bssid); | 553 | struct rt2x00_intf *intf, |
521 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type, | 554 | struct rt2x00intf_conf *conf, |
522 | const int tsf_sync); | 555 | const unsigned int flags); |
523 | void (*config_preamble) (struct rt2x00_dev *rt2x00dev, | 556 | #define CONFIG_UPDATE_TYPE ( 1 << 1 ) |
524 | const int short_preamble, | 557 | #define CONFIG_UPDATE_MAC ( 1 << 2 ) |
525 | const int ack_timeout, | 558 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
526 | const int ack_consume_time); | 559 | |
527 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | 560 | int (*config_preamble) (struct rt2x00_dev *rt2x00dev, |
528 | struct rt2x00lib_conf *libconf); | 561 | const int short_preamble, |
562 | const int ack_timeout, | ||
563 | const int ack_consume_time); | ||
564 | void (*config) (struct rt2x00_dev *rt2x00dev, | ||
565 | struct rt2x00lib_conf *libconf, | ||
566 | const unsigned int flags); | ||
529 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | 567 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) |
530 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | 568 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) |
531 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | 569 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) |
@@ -540,10 +578,14 @@ struct rt2x00lib_ops { | |||
540 | */ | 578 | */ |
541 | struct rt2x00_ops { | 579 | struct rt2x00_ops { |
542 | const char *name; | 580 | const char *name; |
543 | const unsigned int rxd_size; | 581 | const unsigned int max_sta_intf; |
544 | const unsigned int txd_size; | 582 | const unsigned int max_ap_intf; |
545 | const unsigned int eeprom_size; | 583 | const unsigned int eeprom_size; |
546 | const unsigned int rf_size; | 584 | const unsigned int rf_size; |
585 | const struct data_queue_desc *rx; | ||
586 | const struct data_queue_desc *tx; | ||
587 | const struct data_queue_desc *bcn; | ||
588 | const struct data_queue_desc *atim; | ||
547 | const struct rt2x00lib_ops *lib; | 589 | const struct rt2x00lib_ops *lib; |
548 | const struct ieee80211_ops *hw; | 590 | const struct ieee80211_ops *hw; |
549 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 591 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
@@ -569,8 +611,12 @@ enum rt2x00_flags { | |||
569 | /* | 611 | /* |
570 | * Driver features | 612 | * Driver features |
571 | */ | 613 | */ |
614 | DRIVER_SUPPORT_MIXED_INTERFACES, | ||
572 | DRIVER_REQUIRE_FIRMWARE, | 615 | DRIVER_REQUIRE_FIRMWARE, |
573 | DRIVER_REQUIRE_BEACON_RING, | 616 | DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, |
617 | DRIVER_REQUIRE_FIRMWARE_CCITT, | ||
618 | DRIVER_REQUIRE_BEACON_GUARD, | ||
619 | DRIVER_REQUIRE_ATIM_QUEUE, | ||
574 | 620 | ||
575 | /* | 621 | /* |
576 | * Driver configuration | 622 | * Driver configuration |
@@ -582,7 +628,6 @@ enum rt2x00_flags { | |||
582 | CONFIG_EXTERNAL_LNA_BG, | 628 | CONFIG_EXTERNAL_LNA_BG, |
583 | CONFIG_DOUBLE_ANTENNA, | 629 | CONFIG_DOUBLE_ANTENNA, |
584 | CONFIG_DISABLE_LINK_TUNING, | 630 | CONFIG_DISABLE_LINK_TUNING, |
585 | CONFIG_SHORT_PREAMBLE, | ||
586 | }; | 631 | }; |
587 | 632 | ||
588 | /* | 633 | /* |
@@ -597,8 +642,10 @@ struct rt2x00_dev { | |||
597 | * macro's should be used for correct typecasting. | 642 | * macro's should be used for correct typecasting. |
598 | */ | 643 | */ |
599 | void *dev; | 644 | void *dev; |
600 | #define rt2x00dev_pci(__dev) ( (struct pci_dev*)(__dev)->dev ) | 645 | #define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) |
601 | #define rt2x00dev_usb(__dev) ( (struct usb_interface*)(__dev)->dev ) | 646 | #define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) |
647 | #define rt2x00dev_usb_dev(__dev)\ | ||
648 | ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) | ||
602 | 649 | ||
603 | /* | 650 | /* |
604 | * Callback functions. | 651 | * Callback functions. |
@@ -609,11 +656,8 @@ struct rt2x00_dev { | |||
609 | * IEEE80211 control structure. | 656 | * IEEE80211 control structure. |
610 | */ | 657 | */ |
611 | struct ieee80211_hw *hw; | 658 | struct ieee80211_hw *hw; |
612 | struct ieee80211_hw_mode *hwmodes; | 659 | struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; |
613 | unsigned int curr_hwmode; | 660 | enum ieee80211_band curr_band; |
614 | #define HWMODE_B 0 | ||
615 | #define HWMODE_G 1 | ||
616 | #define HWMODE_A 2 | ||
617 | 661 | ||
618 | /* | 662 | /* |
619 | * rfkill structure for RF state switching support. | 663 | * rfkill structure for RF state switching support. |
@@ -633,6 +677,19 @@ struct rt2x00_dev { | |||
633 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 677 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
634 | 678 | ||
635 | /* | 679 | /* |
680 | * LED structure for changing the LED status | ||
681 | * by mac8011 or the kernel. | ||
682 | */ | ||
683 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
684 | unsigned int led_flags; | ||
685 | struct rt2x00_trigger trigger_qual; | ||
686 | struct rt2x00_led led_radio; | ||
687 | struct rt2x00_led led_assoc; | ||
688 | struct rt2x00_led led_qual; | ||
689 | u16 led_mcu_reg; | ||
690 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
691 | |||
692 | /* | ||
636 | * Device flags. | 693 | * Device flags. |
637 | * In these flags the current status and some | 694 | * In these flags the current status and some |
638 | * of the device capabilities are stored. | 695 | * of the device capabilities are stored. |
@@ -658,11 +715,13 @@ struct rt2x00_dev { | |||
658 | 715 | ||
659 | /* | 716 | /* |
660 | * Register pointers | 717 | * Register pointers |
661 | * csr_addr: Base register address. (PCI) | 718 | * csr.base: CSR base register address. (PCI) |
662 | * csr_cache: CSR cache for usb_control_msg. (USB) | 719 | * csr.cache: CSR cache for usb_control_msg. (USB) |
663 | */ | 720 | */ |
664 | void __iomem *csr_addr; | 721 | union csr { |
665 | void *csr_cache; | 722 | void __iomem *base; |
723 | void *cache; | ||
724 | } csr; | ||
666 | 725 | ||
667 | /* | 726 | /* |
668 | * Mutex to protect register accesses on USB devices. | 727 | * Mutex to protect register accesses on USB devices. |
@@ -684,9 +743,14 @@ struct rt2x00_dev { | |||
684 | unsigned int packet_filter; | 743 | unsigned int packet_filter; |
685 | 744 | ||
686 | /* | 745 | /* |
687 | * Interface configuration. | 746 | * Interface details: |
747 | * - Open ap interface count. | ||
748 | * - Open sta interface count. | ||
749 | * - Association count. | ||
688 | */ | 750 | */ |
689 | struct interface interface; | 751 | unsigned int intf_ap_count; |
752 | unsigned int intf_sta_count; | ||
753 | unsigned int intf_associated; | ||
690 | 754 | ||
691 | /* | 755 | /* |
692 | * Link quality | 756 | * Link quality |
@@ -719,16 +783,6 @@ struct rt2x00_dev { | |||
719 | u16 tx_power; | 783 | u16 tx_power; |
720 | 784 | ||
721 | /* | 785 | /* |
722 | * LED register (for rt61pci & rt73usb). | ||
723 | */ | ||
724 | u16 led_reg; | ||
725 | |||
726 | /* | ||
727 | * Led mode (LED_MODE_*) | ||
728 | */ | ||
729 | u8 led_mode; | ||
730 | |||
731 | /* | ||
732 | * Rssi <-> Dbm offset | 786 | * Rssi <-> Dbm offset |
733 | */ | 787 | */ |
734 | u8 rssi_offset; | 788 | u8 rssi_offset; |
@@ -752,19 +806,18 @@ struct rt2x00_dev { | |||
752 | /* | 806 | /* |
753 | * Scheduled work. | 807 | * Scheduled work. |
754 | */ | 808 | */ |
755 | struct work_struct beacon_work; | 809 | struct work_struct intf_work; |
756 | struct work_struct filter_work; | 810 | struct work_struct filter_work; |
757 | struct work_struct config_work; | ||
758 | 811 | ||
759 | /* | 812 | /* |
760 | * Data ring arrays for RX, TX and Beacon. | 813 | * Data queue arrays for RX, TX and Beacon. |
761 | * The Beacon array also contains the Atim ring | 814 | * The Beacon array also contains the Atim queue |
762 | * if that is supported by the device. | 815 | * if that is supported by the device. |
763 | */ | 816 | */ |
764 | int data_rings; | 817 | int data_queues; |
765 | struct data_ring *rx; | 818 | struct data_queue *rx; |
766 | struct data_ring *tx; | 819 | struct data_queue *tx; |
767 | struct data_ring *bcn; | 820 | struct data_queue *bcn; |
768 | 821 | ||
769 | /* | 822 | /* |
770 | * Firmware image. | 823 | * Firmware image. |
@@ -773,37 +826,6 @@ struct rt2x00_dev { | |||
773 | }; | 826 | }; |
774 | 827 | ||
775 | /* | 828 | /* |
776 | * For-each loop for the ring array. | ||
777 | * All rings have been allocated as a single array, | ||
778 | * this means we can create a very simply loop macro | ||
779 | * that is capable of looping through all rings. | ||
780 | * ring_end(), txring_end() and ring_loop() are helper macro's which | ||
781 | * should not be used directly. Instead the following should be used: | ||
782 | * ring_for_each() - Loops through all rings (RX, TX, Beacon & Atim) | ||
783 | * txring_for_each() - Loops through TX data rings (TX only) | ||
784 | * txringall_for_each() - Loops through all TX rings (TX, Beacon & Atim) | ||
785 | */ | ||
786 | #define ring_end(__dev) \ | ||
787 | &(__dev)->rx[(__dev)->data_rings] | ||
788 | |||
789 | #define txring_end(__dev) \ | ||
790 | &(__dev)->tx[(__dev)->hw->queues] | ||
791 | |||
792 | #define ring_loop(__entry, __start, __end) \ | ||
793 | for ((__entry) = (__start); \ | ||
794 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
795 | (__entry) = &(__entry)[1]) | ||
796 | |||
797 | #define ring_for_each(__dev, __entry) \ | ||
798 | ring_loop(__entry, (__dev)->rx, ring_end(__dev)) | ||
799 | |||
800 | #define txring_for_each(__dev, __entry) \ | ||
801 | ring_loop(__entry, (__dev)->tx, txring_end(__dev)) | ||
802 | |||
803 | #define txringall_for_each(__dev, __entry) \ | ||
804 | ring_loop(__entry, (__dev)->tx, ring_end(__dev)) | ||
805 | |||
806 | /* | ||
807 | * Generic RF access. | 829 | * Generic RF access. |
808 | * The RF is being accessed by word index. | 830 | * The RF is being accessed by word index. |
809 | */ | 831 | */ |
@@ -895,20 +917,43 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
895 | return ((size * 8 * 10) % rate); | 917 | return ((size * 8 * 10) % rate); |
896 | } | 918 | } |
897 | 919 | ||
898 | /* | 920 | /** |
899 | * Library functions. | 921 | * rt2x00queue_get_queue - Convert mac80211 queue index to rt2x00 queue |
922 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
923 | * @queue: mac80211/rt2x00 queue index | ||
924 | * (see &enum ieee80211_tx_queue and &enum rt2x00_bcn_queue). | ||
925 | */ | ||
926 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
927 | const unsigned int queue); | ||
928 | |||
929 | /** | ||
930 | * rt2x00queue_get_entry - Get queue entry where the given index points to. | ||
931 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
932 | * @index: Index identifier for obtaining the correct index. | ||
900 | */ | 933 | */ |
901 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | 934 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, |
902 | const unsigned int queue); | 935 | enum queue_index index); |
936 | |||
937 | /** | ||
938 | * rt2x00queue_index_inc - Index incrementation function | ||
939 | * @queue: Queue (&struct data_queue) to perform the action on. | ||
940 | * @action: Index type (&enum queue_index) to perform the action on. | ||
941 | * | ||
942 | * This function will increase the requested index on the queue, | ||
943 | * it will grab the appropriate locks and handle queue overflow events by | ||
944 | * resetting the index to the start of the queue. | ||
945 | */ | ||
946 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | ||
947 | |||
903 | 948 | ||
904 | /* | 949 | /* |
905 | * Interrupt context handlers. | 950 | * Interrupt context handlers. |
906 | */ | 951 | */ |
907 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 952 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
908 | void rt2x00lib_txdone(struct data_entry *entry, | 953 | void rt2x00lib_txdone(struct queue_entry *entry, |
909 | const int status, const int retry); | 954 | struct txdone_entry_desc *txdesc); |
910 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 955 | void rt2x00lib_rxdone(struct queue_entry *entry, |
911 | struct rxdata_entry_desc *desc); | 956 | struct rxdone_entry_desc *rxdesc); |
912 | 957 | ||
913 | /* | 958 | /* |
914 | * TX descriptor initializer | 959 | * TX descriptor initializer |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 07adc576db49..69959124d25d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,64 +29,89 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | 32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |
33 | /* | 33 | struct rt2x00_intf *intf, |
34 | * The MAC and BSSID addressess are simple array of bytes, | 34 | enum ieee80211_if_types type, |
35 | * these arrays are little endian, so when sending the addressess | 35 | u8 *mac, u8 *bssid) |
36 | * to the drivers, copy the it into a endian-signed variable. | ||
37 | * | ||
38 | * Note that all devices (except rt2500usb) have 32 bits | ||
39 | * register word sizes. This means that whatever variable we | ||
40 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
41 | * might not accept what we are sending to it. | ||
42 | * This will also make it easier for the driver to write | ||
43 | * the data to the device. | ||
44 | * | ||
45 | * Also note that when NULL is passed as address the | ||
46 | * we will send 00:00:00:00:00 to the device to clear the address. | ||
47 | * This will prevent the device being confused when it wants | ||
48 | * to ACK frames or consideres itself associated. | ||
49 | */ | ||
50 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) | ||
51 | { | ||
52 | __le32 reg[2]; | ||
53 | |||
54 | memset(®, 0, sizeof(reg)); | ||
55 | if (mac) | ||
56 | memcpy(®, mac, ETH_ALEN); | ||
57 | |||
58 | rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]); | ||
59 | } | ||
60 | |||
61 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | ||
62 | { | 36 | { |
63 | __le32 reg[2]; | 37 | struct rt2x00intf_conf conf; |
64 | 38 | unsigned int flags = 0; | |
65 | memset(®, 0, sizeof(reg)); | ||
66 | if (bssid) | ||
67 | memcpy(®, bssid, ETH_ALEN); | ||
68 | |||
69 | rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]); | ||
70 | } | ||
71 | 39 | ||
72 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) | 40 | conf.type = type; |
73 | { | ||
74 | int tsf_sync; | ||
75 | 41 | ||
76 | switch (type) { | 42 | switch (type) { |
77 | case IEEE80211_IF_TYPE_IBSS: | 43 | case IEEE80211_IF_TYPE_IBSS: |
78 | case IEEE80211_IF_TYPE_AP: | 44 | case IEEE80211_IF_TYPE_AP: |
79 | tsf_sync = TSF_SYNC_BEACON; | 45 | conf.sync = TSF_SYNC_BEACON; |
80 | break; | 46 | break; |
81 | case IEEE80211_IF_TYPE_STA: | 47 | case IEEE80211_IF_TYPE_STA: |
82 | tsf_sync = TSF_SYNC_INFRA; | 48 | conf.sync = TSF_SYNC_INFRA; |
83 | break; | 49 | break; |
84 | default: | 50 | default: |
85 | tsf_sync = TSF_SYNC_NONE; | 51 | conf.sync = TSF_SYNC_NONE; |
86 | break; | 52 | break; |
87 | } | 53 | } |
88 | 54 | ||
89 | rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); | 55 | /* |
56 | * Note that when NULL is passed as address we will send | ||
57 | * 00:00:00:00:00 to the device to clear the address. | ||
58 | * This will prevent the device being confused when it wants | ||
59 | * to ACK frames or consideres itself associated. | ||
60 | */ | ||
61 | memset(&conf.mac, 0, sizeof(conf.mac)); | ||
62 | if (mac) | ||
63 | memcpy(&conf.mac, mac, ETH_ALEN); | ||
64 | |||
65 | memset(&conf.bssid, 0, sizeof(conf.bssid)); | ||
66 | if (bssid) | ||
67 | memcpy(&conf.bssid, bssid, ETH_ALEN); | ||
68 | |||
69 | flags |= CONFIG_UPDATE_TYPE; | ||
70 | if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
71 | flags |= CONFIG_UPDATE_MAC; | ||
72 | if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
73 | flags |= CONFIG_UPDATE_BSSID; | ||
74 | |||
75 | rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags); | ||
76 | } | ||
77 | |||
78 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
79 | struct rt2x00_intf *intf, | ||
80 | const unsigned int short_preamble) | ||
81 | { | ||
82 | int retval; | ||
83 | int ack_timeout; | ||
84 | int ack_consume_time; | ||
85 | |||
86 | ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | ||
87 | ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | ||
88 | |||
89 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
90 | ack_timeout += SHORT_DIFS; | ||
91 | else | ||
92 | ack_timeout += DIFS; | ||
93 | |||
94 | if (short_preamble) { | ||
95 | ack_timeout += SHORT_PREAMBLE; | ||
96 | ack_consume_time += SHORT_PREAMBLE; | ||
97 | } else { | ||
98 | ack_timeout += PREAMBLE; | ||
99 | ack_consume_time += PREAMBLE; | ||
100 | } | ||
101 | |||
102 | retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev, | ||
103 | short_preamble, | ||
104 | ack_timeout, | ||
105 | ack_consume_time); | ||
106 | |||
107 | spin_lock(&intf->lock); | ||
108 | |||
109 | if (retval) { | ||
110 | intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE; | ||
111 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
112 | } | ||
113 | |||
114 | spin_unlock(&intf->lock); | ||
90 | } | 115 | } |
91 | 116 | ||
92 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 117 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
@@ -113,7 +138,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
113 | * The latter is required since we need to recalibrate the | 138 | * The latter is required since we need to recalibrate the |
114 | * noise-sensitivity ratio for the new setup. | 139 | * noise-sensitivity ratio for the new setup. |
115 | */ | 140 | */ |
116 | rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); | 141 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
117 | rt2x00lib_reset_link_tuner(rt2x00dev); | 142 | rt2x00lib_reset_link_tuner(rt2x00dev); |
118 | 143 | ||
119 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 144 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
@@ -127,7 +152,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
127 | struct ieee80211_conf *conf, const int force_config) | 152 | struct ieee80211_conf *conf, const int force_config) |
128 | { | 153 | { |
129 | struct rt2x00lib_conf libconf; | 154 | struct rt2x00lib_conf libconf; |
130 | struct ieee80211_hw_mode *mode; | 155 | struct ieee80211_supported_band *band; |
131 | struct ieee80211_rate *rate; | 156 | struct ieee80211_rate *rate; |
132 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; | 157 | struct antenna_setup *default_ant = &rt2x00dev->default_ant; |
133 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; | 158 | struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; |
@@ -147,9 +172,9 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
147 | * Check which configuration options have been | 172 | * Check which configuration options have been |
148 | * updated and should be send to the device. | 173 | * updated and should be send to the device. |
149 | */ | 174 | */ |
150 | if (rt2x00dev->rx_status.phymode != conf->phymode) | 175 | if (rt2x00dev->rx_status.band != conf->channel->band) |
151 | flags |= CONFIG_UPDATE_PHYMODE; | 176 | flags |= CONFIG_UPDATE_PHYMODE; |
152 | if (rt2x00dev->rx_status.channel != conf->channel) | 177 | if (rt2x00dev->rx_status.freq != conf->channel->center_freq) |
153 | flags |= CONFIG_UPDATE_CHANNEL; | 178 | flags |= CONFIG_UPDATE_CHANNEL; |
154 | if (rt2x00dev->tx_power != conf->power_level) | 179 | if (rt2x00dev->tx_power != conf->power_level) |
155 | flags |= CONFIG_UPDATE_TXPOWER; | 180 | flags |= CONFIG_UPDATE_TXPOWER; |
@@ -204,33 +229,16 @@ config: | |||
204 | memset(&libconf, 0, sizeof(libconf)); | 229 | memset(&libconf, 0, sizeof(libconf)); |
205 | 230 | ||
206 | if (flags & CONFIG_UPDATE_PHYMODE) { | 231 | if (flags & CONFIG_UPDATE_PHYMODE) { |
207 | switch (conf->phymode) { | 232 | band = &rt2x00dev->bands[conf->channel->band]; |
208 | case MODE_IEEE80211A: | 233 | rate = &band->bitrates[band->n_bitrates - 1]; |
209 | libconf.phymode = HWMODE_A; | 234 | |
210 | break; | 235 | libconf.band = conf->channel->band; |
211 | case MODE_IEEE80211B: | 236 | libconf.basic_rates = rt2x00_get_rate(rate->hw_value)->ratemask; |
212 | libconf.phymode = HWMODE_B; | ||
213 | break; | ||
214 | case MODE_IEEE80211G: | ||
215 | libconf.phymode = HWMODE_G; | ||
216 | break; | ||
217 | default: | ||
218 | ERROR(rt2x00dev, | ||
219 | "Attempt to configure unsupported mode (%d)" | ||
220 | "Defaulting to 802.11b", conf->phymode); | ||
221 | libconf.phymode = HWMODE_B; | ||
222 | } | ||
223 | |||
224 | mode = &rt2x00dev->hwmodes[libconf.phymode]; | ||
225 | rate = &mode->rates[mode->num_rates - 1]; | ||
226 | |||
227 | libconf.basic_rates = | ||
228 | DEVICE_GET_RATE_FIELD(rate->val, RATEMASK) & DEV_BASIC_RATEMASK; | ||
229 | } | 237 | } |
230 | 238 | ||
231 | if (flags & CONFIG_UPDATE_CHANNEL) { | 239 | if (flags & CONFIG_UPDATE_CHANNEL) { |
232 | memcpy(&libconf.rf, | 240 | memcpy(&libconf.rf, |
233 | &rt2x00dev->spec.channels[conf->channel_val], | 241 | &rt2x00dev->spec.channels[conf->channel->hw_value], |
234 | sizeof(libconf.rf)); | 242 | sizeof(libconf.rf)); |
235 | } | 243 | } |
236 | 244 | ||
@@ -266,7 +274,7 @@ config: | |||
266 | /* | 274 | /* |
267 | * Start configuration. | 275 | * Start configuration. |
268 | */ | 276 | */ |
269 | rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); | 277 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); |
270 | 278 | ||
271 | /* | 279 | /* |
272 | * Some configuration changes affect the link quality | 280 | * Some configuration changes affect the link quality |
@@ -276,12 +284,11 @@ config: | |||
276 | rt2x00lib_reset_link_tuner(rt2x00dev); | 284 | rt2x00lib_reset_link_tuner(rt2x00dev); |
277 | 285 | ||
278 | if (flags & CONFIG_UPDATE_PHYMODE) { | 286 | if (flags & CONFIG_UPDATE_PHYMODE) { |
279 | rt2x00dev->curr_hwmode = libconf.phymode; | 287 | rt2x00dev->curr_band = conf->channel->band; |
280 | rt2x00dev->rx_status.phymode = conf->phymode; | 288 | rt2x00dev->rx_status.band = conf->channel->band; |
281 | } | 289 | } |
282 | 290 | ||
283 | rt2x00dev->rx_status.freq = conf->freq; | 291 | rt2x00dev->rx_status.freq = conf->channel->center_freq; |
284 | rt2x00dev->rx_status.channel = conf->channel; | ||
285 | rt2x00dev->tx_power = conf->power_level; | 292 | rt2x00dev->tx_power = conf->power_level; |
286 | 293 | ||
287 | if (flags & CONFIG_UPDATE_ANTENNA) { | 294 | if (flags & CONFIG_UPDATE_ANTENNA) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index b44a9f4b9b7f..21af11a97334 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -33,7 +33,7 @@ | |||
33 | #include "rt2x00lib.h" | 33 | #include "rt2x00lib.h" |
34 | #include "rt2x00dump.h" | 34 | #include "rt2x00dump.h" |
35 | 35 | ||
36 | #define PRINT_LINE_LEN_MAX 32 | 36 | #define MAX_LINE_LENGTH 64 |
37 | 37 | ||
38 | struct rt2x00debug_intf { | 38 | struct rt2x00debug_intf { |
39 | /* | 39 | /* |
@@ -60,8 +60,9 @@ struct rt2x00debug_intf { | |||
60 | * - eeprom offset/value files | 60 | * - eeprom offset/value files |
61 | * - bbp offset/value files | 61 | * - bbp offset/value files |
62 | * - rf offset/value files | 62 | * - rf offset/value files |
63 | * - frame dump folder | 63 | * - queue folder |
64 | * - frame dump file | 64 | * - frame dump file |
65 | * - queue stats file | ||
65 | */ | 66 | */ |
66 | struct dentry *driver_folder; | 67 | struct dentry *driver_folder; |
67 | struct dentry *driver_entry; | 68 | struct dentry *driver_entry; |
@@ -76,8 +77,9 @@ struct rt2x00debug_intf { | |||
76 | struct dentry *bbp_val_entry; | 77 | struct dentry *bbp_val_entry; |
77 | struct dentry *rf_off_entry; | 78 | struct dentry *rf_off_entry; |
78 | struct dentry *rf_val_entry; | 79 | struct dentry *rf_val_entry; |
79 | struct dentry *frame_folder; | 80 | struct dentry *queue_folder; |
80 | struct dentry *frame_dump_entry; | 81 | struct dentry *queue_frame_dump_entry; |
82 | struct dentry *queue_stats_entry; | ||
81 | 83 | ||
82 | /* | 84 | /* |
83 | * The frame dump file only allows a single reader, | 85 | * The frame dump file only allows a single reader, |
@@ -116,7 +118,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
116 | struct sk_buff *skb) | 118 | struct sk_buff *skb) |
117 | { | 119 | { |
118 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; | 120 | struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; |
119 | struct skb_desc *desc = get_skb_desc(skb); | 121 | struct skb_frame_desc *desc = get_skb_frame_desc(skb); |
120 | struct sk_buff *skbcopy; | 122 | struct sk_buff *skbcopy; |
121 | struct rt2x00dump_hdr *dump_hdr; | 123 | struct rt2x00dump_hdr *dump_hdr; |
122 | struct timeval timestamp; | 124 | struct timeval timestamp; |
@@ -147,7 +149,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
147 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); | 149 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); |
148 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); | 150 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); |
149 | dump_hdr->type = cpu_to_le16(desc->frame_type); | 151 | dump_hdr->type = cpu_to_le16(desc->frame_type); |
150 | dump_hdr->ring_index = desc->ring->queue_idx; | 152 | dump_hdr->queue_index = desc->entry->queue->qid; |
151 | dump_hdr->entry_index = desc->entry->entry_idx; | 153 | dump_hdr->entry_index = desc->entry->entry_idx; |
152 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); | 154 | dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); |
153 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); | 155 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); |
@@ -186,7 +188,7 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file) | |||
186 | return 0; | 188 | return 0; |
187 | } | 189 | } |
188 | 190 | ||
189 | static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | 191 | static int rt2x00debug_open_queue_dump(struct inode *inode, struct file *file) |
190 | { | 192 | { |
191 | struct rt2x00debug_intf *intf = inode->i_private; | 193 | struct rt2x00debug_intf *intf = inode->i_private; |
192 | int retval; | 194 | int retval; |
@@ -203,7 +205,7 @@ static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) | |||
203 | return 0; | 205 | return 0; |
204 | } | 206 | } |
205 | 207 | ||
206 | static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | 208 | static int rt2x00debug_release_queue_dump(struct inode *inode, struct file *file) |
207 | { | 209 | { |
208 | struct rt2x00debug_intf *intf = inode->i_private; | 210 | struct rt2x00debug_intf *intf = inode->i_private; |
209 | 211 | ||
@@ -214,10 +216,10 @@ static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) | |||
214 | return rt2x00debug_file_release(inode, file); | 216 | return rt2x00debug_file_release(inode, file); |
215 | } | 217 | } |
216 | 218 | ||
217 | static ssize_t rt2x00debug_read_ring_dump(struct file *file, | 219 | static ssize_t rt2x00debug_read_queue_dump(struct file *file, |
218 | char __user *buf, | 220 | char __user *buf, |
219 | size_t length, | 221 | size_t length, |
220 | loff_t *offset) | 222 | loff_t *offset) |
221 | { | 223 | { |
222 | struct rt2x00debug_intf *intf = file->private_data; | 224 | struct rt2x00debug_intf *intf = file->private_data; |
223 | struct sk_buff *skb; | 225 | struct sk_buff *skb; |
@@ -248,8 +250,8 @@ exit: | |||
248 | return status; | 250 | return status; |
249 | } | 251 | } |
250 | 252 | ||
251 | static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | 253 | static unsigned int rt2x00debug_poll_queue_dump(struct file *file, |
252 | poll_table *wait) | 254 | poll_table *wait) |
253 | { | 255 | { |
254 | struct rt2x00debug_intf *intf = file->private_data; | 256 | struct rt2x00debug_intf *intf = file->private_data; |
255 | 257 | ||
@@ -261,12 +263,67 @@ static unsigned int rt2x00debug_poll_ring_dump(struct file *file, | |||
261 | return 0; | 263 | return 0; |
262 | } | 264 | } |
263 | 265 | ||
264 | static const struct file_operations rt2x00debug_fop_ring_dump = { | 266 | static const struct file_operations rt2x00debug_fop_queue_dump = { |
265 | .owner = THIS_MODULE, | 267 | .owner = THIS_MODULE, |
266 | .read = rt2x00debug_read_ring_dump, | 268 | .read = rt2x00debug_read_queue_dump, |
267 | .poll = rt2x00debug_poll_ring_dump, | 269 | .poll = rt2x00debug_poll_queue_dump, |
268 | .open = rt2x00debug_open_ring_dump, | 270 | .open = rt2x00debug_open_queue_dump, |
269 | .release = rt2x00debug_release_ring_dump, | 271 | .release = rt2x00debug_release_queue_dump, |
272 | }; | ||
273 | |||
274 | static ssize_t rt2x00debug_read_queue_stats(struct file *file, | ||
275 | char __user *buf, | ||
276 | size_t length, | ||
277 | loff_t *offset) | ||
278 | { | ||
279 | struct rt2x00debug_intf *intf = file->private_data; | ||
280 | struct data_queue *queue; | ||
281 | unsigned int lines = 1 + intf->rt2x00dev->data_queues; | ||
282 | size_t size; | ||
283 | char *data; | ||
284 | char *temp; | ||
285 | |||
286 | if (*offset) | ||
287 | return 0; | ||
288 | |||
289 | data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); | ||
290 | if (!data) | ||
291 | return -ENOMEM; | ||
292 | |||
293 | temp = data + | ||
294 | sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); | ||
295 | |||
296 | queue_for_each(intf->rt2x00dev, queue) { | ||
297 | spin_lock(&queue->lock); | ||
298 | |||
299 | temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, | ||
300 | queue->count, queue->limit, queue->length, | ||
301 | queue->index[Q_INDEX], | ||
302 | queue->index[Q_INDEX_DONE], | ||
303 | queue->index[Q_INDEX_CRYPTO]); | ||
304 | |||
305 | spin_unlock(&queue->lock); | ||
306 | } | ||
307 | |||
308 | size = strlen(data); | ||
309 | size = min(size, length); | ||
310 | |||
311 | if (copy_to_user(buf, data, size)) { | ||
312 | kfree(data); | ||
313 | return -EFAULT; | ||
314 | } | ||
315 | |||
316 | kfree(data); | ||
317 | |||
318 | *offset += size; | ||
319 | return size; | ||
320 | } | ||
321 | |||
322 | static const struct file_operations rt2x00debug_fop_queue_stats = { | ||
323 | .owner = THIS_MODULE, | ||
324 | .read = rt2x00debug_read_queue_stats, | ||
325 | .open = rt2x00debug_file_open, | ||
326 | .release = rt2x00debug_file_release, | ||
270 | }; | 327 | }; |
271 | 328 | ||
272 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ | 329 | #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ |
@@ -386,7 +443,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name, | |||
386 | { | 443 | { |
387 | char *data; | 444 | char *data; |
388 | 445 | ||
389 | data = kzalloc(3 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 446 | data = kzalloc(3 * MAX_LINE_LENGTH, GFP_KERNEL); |
390 | if (!data) | 447 | if (!data) |
391 | return NULL; | 448 | return NULL; |
392 | 449 | ||
@@ -409,7 +466,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, | |||
409 | const struct rt2x00debug *debug = intf->debug; | 466 | const struct rt2x00debug *debug = intf->debug; |
410 | char *data; | 467 | char *data; |
411 | 468 | ||
412 | data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL); | 469 | data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL); |
413 | if (!data) | 470 | if (!data) |
414 | return NULL; | 471 | return NULL; |
415 | 472 | ||
@@ -496,20 +553,24 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) | |||
496 | 553 | ||
497 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY | 554 | #undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY |
498 | 555 | ||
499 | intf->frame_folder = | 556 | intf->queue_folder = |
500 | debugfs_create_dir("frame", intf->driver_folder); | 557 | debugfs_create_dir("queue", intf->driver_folder); |
501 | if (IS_ERR(intf->frame_folder)) | 558 | if (IS_ERR(intf->queue_folder)) |
502 | goto exit; | 559 | goto exit; |
503 | 560 | ||
504 | intf->frame_dump_entry = | 561 | intf->queue_frame_dump_entry = |
505 | debugfs_create_file("dump", S_IRUGO, intf->frame_folder, | 562 | debugfs_create_file("dump", S_IRUGO, intf->queue_folder, |
506 | intf, &rt2x00debug_fop_ring_dump); | 563 | intf, &rt2x00debug_fop_queue_dump); |
507 | if (IS_ERR(intf->frame_dump_entry)) | 564 | if (IS_ERR(intf->queue_frame_dump_entry)) |
508 | goto exit; | 565 | goto exit; |
509 | 566 | ||
510 | skb_queue_head_init(&intf->frame_dump_skbqueue); | 567 | skb_queue_head_init(&intf->frame_dump_skbqueue); |
511 | init_waitqueue_head(&intf->frame_dump_waitqueue); | 568 | init_waitqueue_head(&intf->frame_dump_waitqueue); |
512 | 569 | ||
570 | intf->queue_stats_entry = | ||
571 | debugfs_create_file("queue", S_IRUGO, intf->queue_folder, | ||
572 | intf, &rt2x00debug_fop_queue_stats); | ||
573 | |||
513 | return; | 574 | return; |
514 | 575 | ||
515 | exit: | 576 | exit: |
@@ -528,8 +589,9 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
528 | 589 | ||
529 | skb_queue_purge(&intf->frame_dump_skbqueue); | 590 | skb_queue_purge(&intf->frame_dump_skbqueue); |
530 | 591 | ||
531 | debugfs_remove(intf->frame_dump_entry); | 592 | debugfs_remove(intf->queue_stats_entry); |
532 | debugfs_remove(intf->frame_folder); | 593 | debugfs_remove(intf->queue_frame_dump_entry); |
594 | debugfs_remove(intf->queue_folder); | ||
533 | debugfs_remove(intf->rf_val_entry); | 595 | debugfs_remove(intf->rf_val_entry); |
534 | debugfs_remove(intf->rf_off_entry); | 596 | debugfs_remove(intf->rf_off_entry); |
535 | debugfs_remove(intf->bbp_val_entry); | 597 | debugfs_remove(intf->bbp_val_entry); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index d37efbd09c41..c4ce895aa1c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.h +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 0d51f478bcdf..b3a639aa0540 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -31,34 +31,6 @@ | |||
31 | #include "rt2x00dump.h" | 31 | #include "rt2x00dump.h" |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * Ring handler. | ||
35 | */ | ||
36 | struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev, | ||
37 | const unsigned int queue) | ||
38 | { | ||
39 | int beacon = test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags); | ||
40 | |||
41 | /* | ||
42 | * Check if we are requesting a reqular TX ring, | ||
43 | * or if we are requesting a Beacon or Atim ring. | ||
44 | * For Atim rings, we should check if it is supported. | ||
45 | */ | ||
46 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
47 | return &rt2x00dev->tx[queue]; | ||
48 | |||
49 | if (!rt2x00dev->bcn || !beacon) | ||
50 | return NULL; | ||
51 | |||
52 | if (queue == IEEE80211_TX_QUEUE_BEACON) | ||
53 | return &rt2x00dev->bcn[0]; | ||
54 | else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
55 | return &rt2x00dev->bcn[1]; | ||
56 | |||
57 | return NULL; | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); | ||
60 | |||
61 | /* | ||
62 | * Link tuning handlers | 34 | * Link tuning handlers |
63 | */ | 35 | */ |
64 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) | 36 | void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -113,46 +85,6 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
113 | } | 85 | } |
114 | 86 | ||
115 | /* | 87 | /* |
116 | * Ring initialization | ||
117 | */ | ||
118 | static void rt2x00lib_init_rxrings(struct rt2x00_dev *rt2x00dev) | ||
119 | { | ||
120 | struct data_ring *ring = rt2x00dev->rx; | ||
121 | unsigned int i; | ||
122 | |||
123 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
124 | return; | ||
125 | |||
126 | if (ring->data_addr) | ||
127 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
128 | |||
129 | for (i = 0; i < ring->stats.limit; i++) | ||
130 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, &ring->entry[i]); | ||
131 | |||
132 | rt2x00_ring_index_clear(ring); | ||
133 | } | ||
134 | |||
135 | static void rt2x00lib_init_txrings(struct rt2x00_dev *rt2x00dev) | ||
136 | { | ||
137 | struct data_ring *ring; | ||
138 | unsigned int i; | ||
139 | |||
140 | if (!rt2x00dev->ops->lib->init_txentry) | ||
141 | return; | ||
142 | |||
143 | txringall_for_each(rt2x00dev, ring) { | ||
144 | if (ring->data_addr) | ||
145 | memset(ring->data_addr, 0, rt2x00_get_ring_size(ring)); | ||
146 | |||
147 | for (i = 0; i < ring->stats.limit; i++) | ||
148 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
149 | &ring->entry[i]); | ||
150 | |||
151 | rt2x00_ring_index_clear(ring); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Radio control handlers. | 88 | * Radio control handlers. |
157 | */ | 89 | */ |
158 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | 90 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) |
@@ -168,10 +100,10 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
168 | return 0; | 100 | return 0; |
169 | 101 | ||
170 | /* | 102 | /* |
171 | * Initialize all data rings. | 103 | * Initialize all data queues. |
172 | */ | 104 | */ |
173 | rt2x00lib_init_rxrings(rt2x00dev); | 105 | rt2x00queue_init_rx(rt2x00dev); |
174 | rt2x00lib_init_txrings(rt2x00dev); | 106 | rt2x00queue_init_tx(rt2x00dev); |
175 | 107 | ||
176 | /* | 108 | /* |
177 | * Enable radio. | 109 | * Enable radio. |
@@ -204,12 +136,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
204 | /* | 136 | /* |
205 | * Stop all scheduled work. | 137 | * Stop all scheduled work. |
206 | */ | 138 | */ |
207 | if (work_pending(&rt2x00dev->beacon_work)) | 139 | if (work_pending(&rt2x00dev->intf_work)) |
208 | cancel_work_sync(&rt2x00dev->beacon_work); | 140 | cancel_work_sync(&rt2x00dev->intf_work); |
209 | if (work_pending(&rt2x00dev->filter_work)) | 141 | if (work_pending(&rt2x00dev->filter_work)) |
210 | cancel_work_sync(&rt2x00dev->filter_work); | 142 | cancel_work_sync(&rt2x00dev->filter_work); |
211 | if (work_pending(&rt2x00dev->config_work)) | ||
212 | cancel_work_sync(&rt2x00dev->config_work); | ||
213 | 143 | ||
214 | /* | 144 | /* |
215 | * Stop the TX queues. | 145 | * Stop the TX queues. |
@@ -241,7 +171,7 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
241 | * When we are enabling the RX, we should also start the link tuner. | 171 | * When we are enabling the RX, we should also start the link tuner. |
242 | */ | 172 | */ |
243 | if (state == STATE_RADIO_RX_ON && | 173 | if (state == STATE_RADIO_RX_ON && |
244 | is_interface_present(&rt2x00dev->interface)) | 174 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) |
245 | rt2x00lib_start_link_tuner(rt2x00dev); | 175 | rt2x00lib_start_link_tuner(rt2x00dev); |
246 | } | 176 | } |
247 | 177 | ||
@@ -449,6 +379,11 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
449 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); | 379 | rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); |
450 | 380 | ||
451 | /* | 381 | /* |
382 | * Send a signal to the led to update the led signal strength. | ||
383 | */ | ||
384 | rt2x00leds_led_quality(rt2x00dev, rt2x00dev->link.qual.avg_rssi); | ||
385 | |||
386 | /* | ||
452 | * Evaluate antenna setup, make this the last step since this could | 387 | * Evaluate antenna setup, make this the last step since this could |
453 | * possibly reset some statistics. | 388 | * possibly reset some statistics. |
454 | */ | 389 | */ |
@@ -469,10 +404,10 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
469 | unsigned int filter = rt2x00dev->packet_filter; | 404 | unsigned int filter = rt2x00dev->packet_filter; |
470 | 405 | ||
471 | /* | 406 | /* |
472 | * Since we had stored the filter inside interface.filter, | 407 | * Since we had stored the filter inside rt2x00dev->packet_filter, |
473 | * we should now clear that field. Otherwise the driver will | 408 | * we should now clear that field. Otherwise the driver will |
474 | * assume nothing has changed (*total_flags will be compared | 409 | * assume nothing has changed (*total_flags will be compared |
475 | * to interface.filter to determine if any action is required). | 410 | * to rt2x00dev->packet_filter to determine if any action is required). |
476 | */ | 411 | */ |
477 | rt2x00dev->packet_filter = 0; | 412 | rt2x00dev->packet_filter = 0; |
478 | 413 | ||
@@ -480,45 +415,72 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
480 | filter, &filter, 0, NULL); | 415 | filter, &filter, 0, NULL); |
481 | } | 416 | } |
482 | 417 | ||
483 | static void rt2x00lib_configuration_scheduled(struct work_struct *work) | 418 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, |
419 | struct ieee80211_vif *vif) | ||
484 | { | 420 | { |
485 | struct rt2x00_dev *rt2x00dev = | 421 | struct rt2x00_dev *rt2x00dev = data; |
486 | container_of(work, struct rt2x00_dev, config_work); | 422 | struct rt2x00_intf *intf = vif_to_intf(vif); |
487 | struct ieee80211_bss_conf bss_conf; | 423 | struct sk_buff *skb; |
424 | struct ieee80211_tx_control control; | ||
425 | struct ieee80211_bss_conf conf; | ||
426 | int delayed_flags; | ||
488 | 427 | ||
489 | bss_conf.use_short_preamble = | 428 | /* |
490 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 429 | * Copy all data we need during this action under the protection |
430 | * of a spinlock. Otherwise race conditions might occur which results | ||
431 | * into an invalid configuration. | ||
432 | */ | ||
433 | spin_lock(&intf->lock); | ||
434 | |||
435 | memcpy(&conf, &intf->conf, sizeof(conf)); | ||
436 | delayed_flags = intf->delayed_flags; | ||
437 | intf->delayed_flags = 0; | ||
438 | |||
439 | spin_unlock(&intf->lock); | ||
440 | |||
441 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | ||
442 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | ||
443 | if (skb) { | ||
444 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
445 | &control); | ||
446 | dev_kfree_skb(skb); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | if (delayed_flags & DELAYED_CONFIG_PREAMBLE) | ||
451 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
452 | intf->conf.use_short_preamble); | ||
453 | } | ||
454 | |||
455 | static void rt2x00lib_intf_scheduled(struct work_struct *work) | ||
456 | { | ||
457 | struct rt2x00_dev *rt2x00dev = | ||
458 | container_of(work, struct rt2x00_dev, intf_work); | ||
491 | 459 | ||
492 | /* | 460 | /* |
493 | * FIXME: shouldn't invoke it this way because all other contents | 461 | * Iterate over each interface and perform the |
494 | * of bss_conf is invalid. | 462 | * requested configurations. |
495 | */ | 463 | */ |
496 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | 464 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
497 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | 465 | rt2x00lib_intf_scheduled_iter, |
466 | rt2x00dev); | ||
498 | } | 467 | } |
499 | 468 | ||
500 | /* | 469 | /* |
501 | * Interrupt context handlers. | 470 | * Interrupt context handlers. |
502 | */ | 471 | */ |
503 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | 472 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
473 | struct ieee80211_vif *vif) | ||
504 | { | 474 | { |
505 | struct rt2x00_dev *rt2x00dev = | 475 | struct rt2x00_intf *intf = vif_to_intf(vif); |
506 | container_of(work, struct rt2x00_dev, beacon_work); | ||
507 | struct data_ring *ring = | ||
508 | rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
509 | struct data_entry *entry = rt2x00_get_data_entry(ring); | ||
510 | struct sk_buff *skb; | ||
511 | 476 | ||
512 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 477 | if (vif->type != IEEE80211_IF_TYPE_AP && |
513 | rt2x00dev->interface.id, | 478 | vif->type != IEEE80211_IF_TYPE_IBSS) |
514 | &entry->tx_status.control); | ||
515 | if (!skb) | ||
516 | return; | 479 | return; |
517 | 480 | ||
518 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | 481 | spin_lock(&intf->lock); |
519 | &entry->tx_status.control); | 482 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; |
520 | 483 | spin_unlock(&intf->lock); | |
521 | dev_kfree_skb(skb); | ||
522 | } | 484 | } |
523 | 485 | ||
524 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 486 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -526,89 +488,107 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
526 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 488 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
527 | return; | 489 | return; |
528 | 490 | ||
529 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | 491 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
492 | rt2x00lib_beacondone_iter, | ||
493 | rt2x00dev); | ||
494 | |||
495 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
530 | } | 496 | } |
531 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 497 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
532 | 498 | ||
533 | void rt2x00lib_txdone(struct data_entry *entry, | 499 | void rt2x00lib_txdone(struct queue_entry *entry, |
534 | const int status, const int retry) | 500 | struct txdone_entry_desc *txdesc) |
535 | { | 501 | { |
536 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 502 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
537 | struct ieee80211_tx_status *tx_status = &entry->tx_status; | 503 | struct skb_frame_desc *skbdesc; |
538 | struct ieee80211_low_level_stats *stats = &rt2x00dev->low_level_stats; | 504 | struct ieee80211_tx_status tx_status; |
539 | int success = !!(status == TX_SUCCESS || status == TX_SUCCESS_RETRY); | 505 | int success = !!(txdesc->status == TX_SUCCESS || |
540 | int fail = !!(status == TX_FAIL_RETRY || status == TX_FAIL_INVALID || | 506 | txdesc->status == TX_SUCCESS_RETRY); |
541 | status == TX_FAIL_OTHER); | 507 | int fail = !!(txdesc->status == TX_FAIL_RETRY || |
508 | txdesc->status == TX_FAIL_INVALID || | ||
509 | txdesc->status == TX_FAIL_OTHER); | ||
542 | 510 | ||
543 | /* | 511 | /* |
544 | * Update TX statistics. | 512 | * Update TX statistics. |
545 | */ | 513 | */ |
546 | tx_status->flags = 0; | ||
547 | tx_status->ack_signal = 0; | ||
548 | tx_status->excessive_retries = (status == TX_FAIL_RETRY); | ||
549 | tx_status->retry_count = retry; | ||
550 | rt2x00dev->link.qual.tx_success += success; | 514 | rt2x00dev->link.qual.tx_success += success; |
551 | rt2x00dev->link.qual.tx_failed += retry + fail; | 515 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; |
516 | |||
517 | /* | ||
518 | * Initialize TX status | ||
519 | */ | ||
520 | tx_status.flags = 0; | ||
521 | tx_status.ack_signal = 0; | ||
522 | tx_status.excessive_retries = (txdesc->status == TX_FAIL_RETRY); | ||
523 | tx_status.retry_count = txdesc->retry; | ||
524 | memcpy(&tx_status.control, txdesc->control, sizeof(txdesc->control)); | ||
552 | 525 | ||
553 | if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { | 526 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { |
554 | if (success) | 527 | if (success) |
555 | tx_status->flags |= IEEE80211_TX_STATUS_ACK; | 528 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; |
556 | else | 529 | else |
557 | stats->dot11ACKFailureCount++; | 530 | rt2x00dev->low_level_stats.dot11ACKFailureCount++; |
558 | } | 531 | } |
559 | 532 | ||
560 | tx_status->queue_length = entry->ring->stats.limit; | 533 | tx_status.queue_length = entry->queue->limit; |
561 | tx_status->queue_number = tx_status->control.queue; | 534 | tx_status.queue_number = tx_status.control.queue; |
562 | 535 | ||
563 | if (tx_status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 536 | if (tx_status.control.flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
564 | if (success) | 537 | if (success) |
565 | stats->dot11RTSSuccessCount++; | 538 | rt2x00dev->low_level_stats.dot11RTSSuccessCount++; |
566 | else | 539 | else |
567 | stats->dot11RTSFailureCount++; | 540 | rt2x00dev->low_level_stats.dot11RTSFailureCount++; |
568 | } | 541 | } |
569 | 542 | ||
570 | /* | 543 | /* |
571 | * Send the tx_status to mac80211 & debugfs. | 544 | * Send the tx_status to debugfs. Only send the status report |
572 | * mac80211 will clean up the skb structure. | 545 | * to mac80211 when the frame originated from there. If this was |
546 | * a extra frame coming through a mac80211 library call (RTS/CTS) | ||
547 | * then we should not send the status report back. | ||
548 | * If send to mac80211, mac80211 will clean up the skb structure, | ||
549 | * otherwise we have to do it ourself. | ||
573 | */ | 550 | */ |
574 | get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; | 551 | skbdesc = get_skb_frame_desc(entry->skb); |
552 | skbdesc->frame_type = DUMP_FRAME_TXDONE; | ||
553 | |||
575 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); | 554 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
576 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); | 555 | |
556 | if (!(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | ||
557 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, | ||
558 | entry->skb, &tx_status); | ||
559 | else | ||
560 | dev_kfree_skb(entry->skb); | ||
577 | entry->skb = NULL; | 561 | entry->skb = NULL; |
578 | } | 562 | } |
579 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 563 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
580 | 564 | ||
581 | void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | 565 | void rt2x00lib_rxdone(struct queue_entry *entry, |
582 | struct rxdata_entry_desc *desc) | 566 | struct rxdone_entry_desc *rxdesc) |
583 | { | 567 | { |
584 | struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; | 568 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
585 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 569 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
586 | struct ieee80211_hw_mode *mode; | 570 | struct ieee80211_supported_band *sband; |
587 | struct ieee80211_rate *rate; | ||
588 | struct ieee80211_hdr *hdr; | 571 | struct ieee80211_hdr *hdr; |
572 | const struct rt2x00_rate *rate; | ||
589 | unsigned int i; | 573 | unsigned int i; |
590 | int val = 0; | 574 | int idx = -1; |
591 | u16 fc; | 575 | u16 fc; |
592 | 576 | ||
593 | /* | 577 | /* |
594 | * Update RX statistics. | 578 | * Update RX statistics. |
595 | */ | 579 | */ |
596 | mode = &rt2x00dev->hwmodes[rt2x00dev->curr_hwmode]; | 580 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
597 | for (i = 0; i < mode->num_rates; i++) { | 581 | for (i = 0; i < sband->n_bitrates; i++) { |
598 | rate = &mode->rates[i]; | 582 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
599 | 583 | ||
600 | /* | 584 | /* |
601 | * When frame was received with an OFDM bitrate, | 585 | * When frame was received with an OFDM bitrate, |
602 | * the signal is the PLCP value. If it was received with | 586 | * the signal is the PLCP value. If it was received with |
603 | * a CCK bitrate the signal is the rate in 0.5kbit/s. | 587 | * a CCK bitrate the signal is the rate in 100kbit/s. |
604 | */ | 588 | */ |
605 | if (!desc->ofdm) | 589 | if ((rxdesc->ofdm && rate->plcp == rxdesc->signal) || |
606 | val = DEVICE_GET_RATE_FIELD(rate->val, RATE); | 590 | (!rxdesc->ofdm && rate->bitrate == rxdesc->signal)) { |
607 | else | 591 | idx = i; |
608 | val = DEVICE_GET_RATE_FIELD(rate->val, PLCP); | ||
609 | |||
610 | if (val == desc->signal) { | ||
611 | val = rate->val; | ||
612 | break; | 592 | break; |
613 | } | 593 | } |
614 | } | 594 | } |
@@ -616,26 +596,28 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, | |||
616 | /* | 596 | /* |
617 | * Only update link status if this is a beacon frame carrying our bssid. | 597 | * Only update link status if this is a beacon frame carrying our bssid. |
618 | */ | 598 | */ |
619 | hdr = (struct ieee80211_hdr*)skb->data; | 599 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
620 | fc = le16_to_cpu(hdr->frame_control); | 600 | fc = le16_to_cpu(hdr->frame_control); |
621 | if (is_beacon(fc) && desc->my_bss) | 601 | if (is_beacon(fc) && rxdesc->my_bss) |
622 | rt2x00lib_update_link_stats(&rt2x00dev->link, desc->rssi); | 602 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); |
623 | 603 | ||
624 | rt2x00dev->link.qual.rx_success++; | 604 | rt2x00dev->link.qual.rx_success++; |
625 | 605 | ||
626 | rx_status->rate = val; | 606 | rx_status->rate_idx = idx; |
627 | rx_status->signal = | 607 | rx_status->signal = |
628 | rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); | 608 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); |
629 | rx_status->ssi = desc->rssi; | 609 | rx_status->ssi = rxdesc->rssi; |
630 | rx_status->flag = desc->flags; | 610 | rx_status->flag = rxdesc->flags; |
631 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 611 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
632 | 612 | ||
633 | /* | 613 | /* |
634 | * Send frame to mac80211 & debugfs | 614 | * Send frame to mac80211 & debugfs. |
615 | * mac80211 will clean up the skb structure. | ||
635 | */ | 616 | */ |
636 | get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; | 617 | get_skb_frame_desc(entry->skb)->frame_type = DUMP_FRAME_RXDONE; |
637 | rt2x00debug_dump_frame(rt2x00dev, skb); | 618 | rt2x00debug_dump_frame(rt2x00dev, entry->skb); |
638 | ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); | 619 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
620 | entry->skb = NULL; | ||
639 | } | 621 | } |
640 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 622 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
641 | 623 | ||
@@ -646,83 +628,69 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
646 | struct sk_buff *skb, | 628 | struct sk_buff *skb, |
647 | struct ieee80211_tx_control *control) | 629 | struct ieee80211_tx_control *control) |
648 | { | 630 | { |
649 | struct txdata_entry_desc desc; | 631 | struct txentry_desc txdesc; |
650 | struct skb_desc *skbdesc = get_skb_desc(skb); | 632 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
651 | struct ieee80211_hdr *ieee80211hdr = skbdesc->data; | 633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
634 | const struct rt2x00_rate *rate; | ||
652 | int tx_rate; | 635 | int tx_rate; |
653 | int bitrate; | ||
654 | int length; | 636 | int length; |
655 | int duration; | 637 | int duration; |
656 | int residual; | 638 | int residual; |
657 | u16 frame_control; | 639 | u16 frame_control; |
658 | u16 seq_ctrl; | 640 | u16 seq_ctrl; |
659 | 641 | ||
660 | memset(&desc, 0, sizeof(desc)); | 642 | memset(&txdesc, 0, sizeof(txdesc)); |
661 | |||
662 | desc.cw_min = skbdesc->ring->tx_params.cw_min; | ||
663 | desc.cw_max = skbdesc->ring->tx_params.cw_max; | ||
664 | desc.aifs = skbdesc->ring->tx_params.aifs; | ||
665 | 643 | ||
666 | /* | 644 | txdesc.queue = skbdesc->entry->queue->qid; |
667 | * Identify queue | 645 | txdesc.cw_min = skbdesc->entry->queue->cw_min; |
668 | */ | 646 | txdesc.cw_max = skbdesc->entry->queue->cw_max; |
669 | if (control->queue < rt2x00dev->hw->queues) | 647 | txdesc.aifs = skbdesc->entry->queue->aifs; |
670 | desc.queue = control->queue; | ||
671 | else if (control->queue == IEEE80211_TX_QUEUE_BEACON || | ||
672 | control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON) | ||
673 | desc.queue = QUEUE_MGMT; | ||
674 | else | ||
675 | desc.queue = QUEUE_OTHER; | ||
676 | 648 | ||
677 | /* | 649 | /* |
678 | * Read required fields from ieee80211 header. | 650 | * Read required fields from ieee80211 header. |
679 | */ | 651 | */ |
680 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 652 | frame_control = le16_to_cpu(hdr->frame_control); |
681 | seq_ctrl = le16_to_cpu(ieee80211hdr->seq_ctrl); | 653 | seq_ctrl = le16_to_cpu(hdr->seq_ctrl); |
682 | 654 | ||
683 | tx_rate = control->tx_rate; | 655 | tx_rate = control->tx_rate->hw_value; |
684 | 656 | ||
685 | /* | 657 | /* |
686 | * Check whether this frame is to be acked | 658 | * Check whether this frame is to be acked |
687 | */ | 659 | */ |
688 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) | 660 | if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) |
689 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 661 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
690 | 662 | ||
691 | /* | 663 | /* |
692 | * Check if this is a RTS/CTS frame | 664 | * Check if this is a RTS/CTS frame |
693 | */ | 665 | */ |
694 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 666 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { |
695 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 667 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
696 | if (is_rts_frame(frame_control)) { | 668 | if (is_rts_frame(frame_control)) { |
697 | __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); | 669 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags); |
698 | __set_bit(ENTRY_TXD_ACK, &desc.flags); | 670 | __set_bit(ENTRY_TXD_ACK, &txdesc.flags); |
699 | } else | 671 | } else |
700 | __clear_bit(ENTRY_TXD_ACK, &desc.flags); | 672 | __clear_bit(ENTRY_TXD_ACK, &txdesc.flags); |
701 | if (control->rts_cts_rate) | 673 | if (control->rts_cts_rate) |
702 | tx_rate = control->rts_cts_rate; | 674 | tx_rate = control->rts_cts_rate->hw_value; |
703 | } | 675 | } |
704 | 676 | ||
705 | /* | 677 | rate = rt2x00_get_rate(tx_rate); |
706 | * Check for OFDM | ||
707 | */ | ||
708 | if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK) | ||
709 | __set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags); | ||
710 | 678 | ||
711 | /* | 679 | /* |
712 | * Check if more fragments are pending | 680 | * Check if more fragments are pending |
713 | */ | 681 | */ |
714 | if (ieee80211_get_morefrag(ieee80211hdr)) { | 682 | if (ieee80211_get_morefrag(hdr)) { |
715 | __set_bit(ENTRY_TXD_BURST, &desc.flags); | 683 | __set_bit(ENTRY_TXD_BURST, &txdesc.flags); |
716 | __set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags); | 684 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc.flags); |
717 | } | 685 | } |
718 | 686 | ||
719 | /* | 687 | /* |
720 | * Beacons and probe responses require the tsf timestamp | 688 | * Beacons and probe responses require the tsf timestamp |
721 | * to be inserted into the frame. | 689 | * to be inserted into the frame. |
722 | */ | 690 | */ |
723 | if (control->queue == IEEE80211_TX_QUEUE_BEACON || | 691 | if (control->queue == RT2X00_BCN_QUEUE_BEACON || |
724 | is_probe_resp(frame_control)) | 692 | is_probe_resp(frame_control)) |
725 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags); | 693 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc.flags); |
726 | 694 | ||
727 | /* | 695 | /* |
728 | * Determine with what IFS priority this frame should be send. | 696 | * Determine with what IFS priority this frame should be send. |
@@ -730,30 +698,30 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
730 | * or this fragment came after RTS/CTS. | 698 | * or this fragment came after RTS/CTS. |
731 | */ | 699 | */ |
732 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || | 700 | if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 || |
733 | test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags)) | 701 | test_bit(ENTRY_TXD_RTS_FRAME, &txdesc.flags)) |
734 | desc.ifs = IFS_SIFS; | 702 | txdesc.ifs = IFS_SIFS; |
735 | else | 703 | else |
736 | desc.ifs = IFS_BACKOFF; | 704 | txdesc.ifs = IFS_BACKOFF; |
737 | 705 | ||
738 | /* | 706 | /* |
739 | * PLCP setup | 707 | * PLCP setup |
740 | * Length calculation depends on OFDM/CCK rate. | 708 | * Length calculation depends on OFDM/CCK rate. |
741 | */ | 709 | */ |
742 | desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); | 710 | txdesc.signal = rate->plcp; |
743 | desc.service = 0x04; | 711 | txdesc.service = 0x04; |
744 | 712 | ||
745 | length = skbdesc->data_len + FCS_LEN; | 713 | length = skb->len + FCS_LEN; |
746 | if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { | 714 | if (rate->flags & DEV_RATE_OFDM) { |
747 | desc.length_high = (length >> 6) & 0x3f; | 715 | __set_bit(ENTRY_TXD_OFDM_RATE, &txdesc.flags); |
748 | desc.length_low = length & 0x3f; | ||
749 | } else { | ||
750 | bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); | ||
751 | 716 | ||
717 | txdesc.length_high = (length >> 6) & 0x3f; | ||
718 | txdesc.length_low = length & 0x3f; | ||
719 | } else { | ||
752 | /* | 720 | /* |
753 | * Convert length to microseconds. | 721 | * Convert length to microseconds. |
754 | */ | 722 | */ |
755 | residual = get_duration_res(length, bitrate); | 723 | residual = get_duration_res(length, rate->bitrate); |
756 | duration = get_duration(length, bitrate); | 724 | duration = get_duration(length, rate->bitrate); |
757 | 725 | ||
758 | if (residual != 0) { | 726 | if (residual != 0) { |
759 | duration++; | 727 | duration++; |
@@ -761,28 +729,27 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
761 | /* | 729 | /* |
762 | * Check if we need to set the Length Extension | 730 | * Check if we need to set the Length Extension |
763 | */ | 731 | */ |
764 | if (bitrate == 110 && residual <= 30) | 732 | if (rate->bitrate == 110 && residual <= 30) |
765 | desc.service |= 0x80; | 733 | txdesc.service |= 0x80; |
766 | } | 734 | } |
767 | 735 | ||
768 | desc.length_high = (duration >> 8) & 0xff; | 736 | txdesc.length_high = (duration >> 8) & 0xff; |
769 | desc.length_low = duration & 0xff; | 737 | txdesc.length_low = duration & 0xff; |
770 | 738 | ||
771 | /* | 739 | /* |
772 | * When preamble is enabled we should set the | 740 | * When preamble is enabled we should set the |
773 | * preamble bit for the signal. | 741 | * preamble bit for the signal. |
774 | */ | 742 | */ |
775 | if (DEVICE_GET_RATE_FIELD(tx_rate, PREAMBLE)) | 743 | if (rt2x00_get_rate_preamble(tx_rate)) |
776 | desc.signal |= 0x08; | 744 | txdesc.signal |= 0x08; |
777 | } | 745 | } |
778 | 746 | ||
779 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &desc, control); | 747 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, skb, &txdesc, control); |
780 | 748 | ||
781 | /* | 749 | /* |
782 | * Update ring entry. | 750 | * Update queue entry. |
783 | */ | 751 | */ |
784 | skbdesc->entry->skb = skb; | 752 | skbdesc->entry->skb = skb; |
785 | memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); | ||
786 | 753 | ||
787 | /* | 754 | /* |
788 | * The frame has been completely initialized and ready | 755 | * The frame has been completely initialized and ready |
@@ -798,133 +765,167 @@ EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); | |||
798 | /* | 765 | /* |
799 | * Driver initialization handlers. | 766 | * Driver initialization handlers. |
800 | */ | 767 | */ |
768 | const struct rt2x00_rate rt2x00_supported_rates[12] = { | ||
769 | { | ||
770 | .flags = DEV_RATE_CCK, | ||
771 | .bitrate = 10, | ||
772 | .ratemask = DEV_RATEMASK_1MB, | ||
773 | .plcp = 0x00, | ||
774 | }, | ||
775 | { | ||
776 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
777 | .bitrate = 20, | ||
778 | .ratemask = DEV_RATEMASK_2MB, | ||
779 | .plcp = 0x01, | ||
780 | }, | ||
781 | { | ||
782 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
783 | .bitrate = 55, | ||
784 | .ratemask = DEV_RATEMASK_5_5MB, | ||
785 | .plcp = 0x02, | ||
786 | }, | ||
787 | { | ||
788 | .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, | ||
789 | .bitrate = 110, | ||
790 | .ratemask = DEV_RATEMASK_11MB, | ||
791 | .plcp = 0x03, | ||
792 | }, | ||
793 | { | ||
794 | .flags = DEV_RATE_OFDM, | ||
795 | .bitrate = 60, | ||
796 | .ratemask = DEV_RATEMASK_6MB, | ||
797 | .plcp = 0x0b, | ||
798 | }, | ||
799 | { | ||
800 | .flags = DEV_RATE_OFDM, | ||
801 | .bitrate = 90, | ||
802 | .ratemask = DEV_RATEMASK_9MB, | ||
803 | .plcp = 0x0f, | ||
804 | }, | ||
805 | { | ||
806 | .flags = DEV_RATE_OFDM, | ||
807 | .bitrate = 120, | ||
808 | .ratemask = DEV_RATEMASK_12MB, | ||
809 | .plcp = 0x0a, | ||
810 | }, | ||
811 | { | ||
812 | .flags = DEV_RATE_OFDM, | ||
813 | .bitrate = 180, | ||
814 | .ratemask = DEV_RATEMASK_18MB, | ||
815 | .plcp = 0x0e, | ||
816 | }, | ||
817 | { | ||
818 | .flags = DEV_RATE_OFDM, | ||
819 | .bitrate = 240, | ||
820 | .ratemask = DEV_RATEMASK_24MB, | ||
821 | .plcp = 0x09, | ||
822 | }, | ||
823 | { | ||
824 | .flags = DEV_RATE_OFDM, | ||
825 | .bitrate = 360, | ||
826 | .ratemask = DEV_RATEMASK_36MB, | ||
827 | .plcp = 0x0d, | ||
828 | }, | ||
829 | { | ||
830 | .flags = DEV_RATE_OFDM, | ||
831 | .bitrate = 480, | ||
832 | .ratemask = DEV_RATEMASK_48MB, | ||
833 | .plcp = 0x08, | ||
834 | }, | ||
835 | { | ||
836 | .flags = DEV_RATE_OFDM, | ||
837 | .bitrate = 540, | ||
838 | .ratemask = DEV_RATEMASK_54MB, | ||
839 | .plcp = 0x0c, | ||
840 | }, | ||
841 | }; | ||
842 | |||
801 | static void rt2x00lib_channel(struct ieee80211_channel *entry, | 843 | static void rt2x00lib_channel(struct ieee80211_channel *entry, |
802 | const int channel, const int tx_power, | 844 | const int channel, const int tx_power, |
803 | const int value) | 845 | const int value) |
804 | { | 846 | { |
805 | entry->chan = channel; | 847 | entry->center_freq = ieee80211_channel_to_frequency(channel); |
806 | if (channel <= 14) | 848 | entry->hw_value = value; |
807 | entry->freq = 2407 + (5 * channel); | 849 | entry->max_power = tx_power; |
808 | else | 850 | entry->max_antenna_gain = 0xff; |
809 | entry->freq = 5000 + (5 * channel); | ||
810 | entry->val = value; | ||
811 | entry->flag = | ||
812 | IEEE80211_CHAN_W_IBSS | | ||
813 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
814 | IEEE80211_CHAN_W_SCAN; | ||
815 | entry->power_level = tx_power; | ||
816 | entry->antenna_max = 0xff; | ||
817 | } | 851 | } |
818 | 852 | ||
819 | static void rt2x00lib_rate(struct ieee80211_rate *entry, | 853 | static void rt2x00lib_rate(struct ieee80211_rate *entry, |
820 | const int rate, const int mask, | 854 | const u16 index, const struct rt2x00_rate *rate) |
821 | const int plcp, const int flags) | ||
822 | { | 855 | { |
823 | entry->rate = rate; | 856 | entry->flags = 0; |
824 | entry->val = | 857 | entry->bitrate = rate->bitrate; |
825 | DEVICE_SET_RATE_FIELD(rate, RATE) | | 858 | entry->hw_value = rt2x00_create_rate_hw_value(index, 0); |
826 | DEVICE_SET_RATE_FIELD(mask, RATEMASK) | | 859 | entry->hw_value_short = entry->hw_value; |
827 | DEVICE_SET_RATE_FIELD(plcp, PLCP); | 860 | |
828 | entry->flags = flags; | 861 | if (rate->flags & DEV_RATE_SHORT_PREAMBLE) { |
829 | entry->val2 = entry->val; | 862 | entry->flags |= IEEE80211_RATE_SHORT_PREAMBLE; |
830 | if (entry->flags & IEEE80211_RATE_PREAMBLE2) | 863 | entry->hw_value_short |= rt2x00_create_rate_hw_value(index, 1); |
831 | entry->val2 |= DEVICE_SET_RATE_FIELD(1, PREAMBLE); | 864 | } |
832 | entry->min_rssi_ack = 0; | ||
833 | entry->min_rssi_ack_delta = 0; | ||
834 | } | 865 | } |
835 | 866 | ||
836 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | 867 | static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, |
837 | struct hw_mode_spec *spec) | 868 | struct hw_mode_spec *spec) |
838 | { | 869 | { |
839 | struct ieee80211_hw *hw = rt2x00dev->hw; | 870 | struct ieee80211_hw *hw = rt2x00dev->hw; |
840 | struct ieee80211_hw_mode *hwmodes; | ||
841 | struct ieee80211_channel *channels; | 871 | struct ieee80211_channel *channels; |
842 | struct ieee80211_rate *rates; | 872 | struct ieee80211_rate *rates; |
873 | unsigned int num_rates; | ||
843 | unsigned int i; | 874 | unsigned int i; |
844 | unsigned char tx_power; | 875 | unsigned char tx_power; |
845 | 876 | ||
846 | hwmodes = kzalloc(sizeof(*hwmodes) * spec->num_modes, GFP_KERNEL); | 877 | num_rates = 0; |
847 | if (!hwmodes) | 878 | if (spec->supported_rates & SUPPORT_RATE_CCK) |
848 | goto exit; | 879 | num_rates += 4; |
880 | if (spec->supported_rates & SUPPORT_RATE_OFDM) | ||
881 | num_rates += 8; | ||
849 | 882 | ||
850 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); | 883 | channels = kzalloc(sizeof(*channels) * spec->num_channels, GFP_KERNEL); |
851 | if (!channels) | 884 | if (!channels) |
852 | goto exit_free_modes; | 885 | return -ENOMEM; |
853 | 886 | ||
854 | rates = kzalloc(sizeof(*rates) * spec->num_rates, GFP_KERNEL); | 887 | rates = kzalloc(sizeof(*rates) * num_rates, GFP_KERNEL); |
855 | if (!rates) | 888 | if (!rates) |
856 | goto exit_free_channels; | 889 | goto exit_free_channels; |
857 | 890 | ||
858 | /* | 891 | /* |
859 | * Initialize Rate list. | 892 | * Initialize Rate list. |
860 | */ | 893 | */ |
861 | rt2x00lib_rate(&rates[0], 10, DEV_RATEMASK_1MB, | 894 | for (i = 0; i < num_rates; i++) |
862 | 0x00, IEEE80211_RATE_CCK); | 895 | rt2x00lib_rate(&rates[i], i, rt2x00_get_rate(i)); |
863 | rt2x00lib_rate(&rates[1], 20, DEV_RATEMASK_2MB, | ||
864 | 0x01, IEEE80211_RATE_CCK_2); | ||
865 | rt2x00lib_rate(&rates[2], 55, DEV_RATEMASK_5_5MB, | ||
866 | 0x02, IEEE80211_RATE_CCK_2); | ||
867 | rt2x00lib_rate(&rates[3], 110, DEV_RATEMASK_11MB, | ||
868 | 0x03, IEEE80211_RATE_CCK_2); | ||
869 | |||
870 | if (spec->num_rates > 4) { | ||
871 | rt2x00lib_rate(&rates[4], 60, DEV_RATEMASK_6MB, | ||
872 | 0x0b, IEEE80211_RATE_OFDM); | ||
873 | rt2x00lib_rate(&rates[5], 90, DEV_RATEMASK_9MB, | ||
874 | 0x0f, IEEE80211_RATE_OFDM); | ||
875 | rt2x00lib_rate(&rates[6], 120, DEV_RATEMASK_12MB, | ||
876 | 0x0a, IEEE80211_RATE_OFDM); | ||
877 | rt2x00lib_rate(&rates[7], 180, DEV_RATEMASK_18MB, | ||
878 | 0x0e, IEEE80211_RATE_OFDM); | ||
879 | rt2x00lib_rate(&rates[8], 240, DEV_RATEMASK_24MB, | ||
880 | 0x09, IEEE80211_RATE_OFDM); | ||
881 | rt2x00lib_rate(&rates[9], 360, DEV_RATEMASK_36MB, | ||
882 | 0x0d, IEEE80211_RATE_OFDM); | ||
883 | rt2x00lib_rate(&rates[10], 480, DEV_RATEMASK_48MB, | ||
884 | 0x08, IEEE80211_RATE_OFDM); | ||
885 | rt2x00lib_rate(&rates[11], 540, DEV_RATEMASK_54MB, | ||
886 | 0x0c, IEEE80211_RATE_OFDM); | ||
887 | } | ||
888 | 896 | ||
889 | /* | 897 | /* |
890 | * Initialize Channel list. | 898 | * Initialize Channel list. |
891 | */ | 899 | */ |
892 | for (i = 0; i < spec->num_channels; i++) { | 900 | for (i = 0; i < spec->num_channels; i++) { |
893 | if (spec->channels[i].channel <= 14) | 901 | if (spec->channels[i].channel <= 14) { |
894 | tx_power = spec->tx_power_bg[i]; | 902 | if (spec->tx_power_bg) |
895 | else if (spec->tx_power_a) | 903 | tx_power = spec->tx_power_bg[i]; |
896 | tx_power = spec->tx_power_a[i]; | 904 | else |
897 | else | 905 | tx_power = spec->tx_power_default; |
898 | tx_power = spec->tx_power_default; | 906 | } else { |
907 | if (spec->tx_power_a) | ||
908 | tx_power = spec->tx_power_a[i]; | ||
909 | else | ||
910 | tx_power = spec->tx_power_default; | ||
911 | } | ||
899 | 912 | ||
900 | rt2x00lib_channel(&channels[i], | 913 | rt2x00lib_channel(&channels[i], |
901 | spec->channels[i].channel, tx_power, i); | 914 | spec->channels[i].channel, tx_power, i); |
902 | } | 915 | } |
903 | 916 | ||
904 | /* | 917 | /* |
905 | * Intitialize 802.11b | 918 | * Intitialize 802.11b, 802.11g |
906 | * Rates: CCK. | ||
907 | * Channels: OFDM. | ||
908 | */ | ||
909 | if (spec->num_modes > HWMODE_B) { | ||
910 | hwmodes[HWMODE_B].mode = MODE_IEEE80211B; | ||
911 | hwmodes[HWMODE_B].num_channels = 14; | ||
912 | hwmodes[HWMODE_B].num_rates = 4; | ||
913 | hwmodes[HWMODE_B].channels = channels; | ||
914 | hwmodes[HWMODE_B].rates = rates; | ||
915 | } | ||
916 | |||
917 | /* | ||
918 | * Intitialize 802.11g | ||
919 | * Rates: CCK, OFDM. | 919 | * Rates: CCK, OFDM. |
920 | * Channels: OFDM. | 920 | * Channels: 2.4 GHz |
921 | */ | 921 | */ |
922 | if (spec->num_modes > HWMODE_G) { | 922 | if (spec->supported_bands & SUPPORT_BAND_2GHZ) { |
923 | hwmodes[HWMODE_G].mode = MODE_IEEE80211G; | 923 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_channels = 14; |
924 | hwmodes[HWMODE_G].num_channels = 14; | 924 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].n_bitrates = num_rates; |
925 | hwmodes[HWMODE_G].num_rates = spec->num_rates; | 925 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].channels = channels; |
926 | hwmodes[HWMODE_G].channels = channels; | 926 | rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; |
927 | hwmodes[HWMODE_G].rates = rates; | 927 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = |
928 | &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; | ||
928 | } | 929 | } |
929 | 930 | ||
930 | /* | 931 | /* |
@@ -932,40 +933,21 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, | |||
932 | * Rates: OFDM. | 933 | * Rates: OFDM. |
933 | * Channels: OFDM, UNII, HiperLAN2. | 934 | * Channels: OFDM, UNII, HiperLAN2. |
934 | */ | 935 | */ |
935 | if (spec->num_modes > HWMODE_A) { | 936 | if (spec->supported_bands & SUPPORT_BAND_5GHZ) { |
936 | hwmodes[HWMODE_A].mode = MODE_IEEE80211A; | 937 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_channels = |
937 | hwmodes[HWMODE_A].num_channels = spec->num_channels - 14; | 938 | spec->num_channels - 14; |
938 | hwmodes[HWMODE_A].num_rates = spec->num_rates - 4; | 939 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].n_bitrates = |
939 | hwmodes[HWMODE_A].channels = &channels[14]; | 940 | num_rates - 4; |
940 | hwmodes[HWMODE_A].rates = &rates[4]; | 941 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].channels = &channels[14]; |
942 | rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; | ||
943 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | ||
944 | &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; | ||
941 | } | 945 | } |
942 | 946 | ||
943 | if (spec->num_modes > HWMODE_G && | ||
944 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_G])) | ||
945 | goto exit_free_rates; | ||
946 | |||
947 | if (spec->num_modes > HWMODE_B && | ||
948 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_B])) | ||
949 | goto exit_free_rates; | ||
950 | |||
951 | if (spec->num_modes > HWMODE_A && | ||
952 | ieee80211_register_hwmode(hw, &hwmodes[HWMODE_A])) | ||
953 | goto exit_free_rates; | ||
954 | |||
955 | rt2x00dev->hwmodes = hwmodes; | ||
956 | |||
957 | return 0; | 947 | return 0; |
958 | 948 | ||
959 | exit_free_rates: | 949 | exit_free_channels: |
960 | kfree(rates); | ||
961 | |||
962 | exit_free_channels: | ||
963 | kfree(channels); | 950 | kfree(channels); |
964 | |||
965 | exit_free_modes: | ||
966 | kfree(hwmodes); | ||
967 | |||
968 | exit: | ||
969 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); | 951 | ERROR(rt2x00dev, "Allocation ieee80211 modes failed.\n"); |
970 | return -ENOMEM; | 952 | return -ENOMEM; |
971 | } | 953 | } |
@@ -975,11 +957,11 @@ static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev) | |||
975 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) | 957 | if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags)) |
976 | ieee80211_unregister_hw(rt2x00dev->hw); | 958 | ieee80211_unregister_hw(rt2x00dev->hw); |
977 | 959 | ||
978 | if (likely(rt2x00dev->hwmodes)) { | 960 | if (likely(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ])) { |
979 | kfree(rt2x00dev->hwmodes->channels); | 961 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels); |
980 | kfree(rt2x00dev->hwmodes->rates); | 962 | kfree(rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->bitrates); |
981 | kfree(rt2x00dev->hwmodes); | 963 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL; |
982 | rt2x00dev->hwmodes = NULL; | 964 | rt2x00dev->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; |
983 | } | 965 | } |
984 | } | 966 | } |
985 | 967 | ||
@@ -1012,86 +994,6 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1012 | /* | 994 | /* |
1013 | * Initialization/uninitialization handlers. | 995 | * Initialization/uninitialization handlers. |
1014 | */ | 996 | */ |
1015 | static int rt2x00lib_alloc_entries(struct data_ring *ring, | ||
1016 | const u16 max_entries, const u16 data_size, | ||
1017 | const u16 desc_size) | ||
1018 | { | ||
1019 | struct data_entry *entry; | ||
1020 | unsigned int i; | ||
1021 | |||
1022 | ring->stats.limit = max_entries; | ||
1023 | ring->data_size = data_size; | ||
1024 | ring->desc_size = desc_size; | ||
1025 | |||
1026 | /* | ||
1027 | * Allocate all ring entries. | ||
1028 | */ | ||
1029 | entry = kzalloc(ring->stats.limit * sizeof(*entry), GFP_KERNEL); | ||
1030 | if (!entry) | ||
1031 | return -ENOMEM; | ||
1032 | |||
1033 | for (i = 0; i < ring->stats.limit; i++) { | ||
1034 | entry[i].flags = 0; | ||
1035 | entry[i].ring = ring; | ||
1036 | entry[i].skb = NULL; | ||
1037 | entry[i].entry_idx = i; | ||
1038 | } | ||
1039 | |||
1040 | ring->entry = entry; | ||
1041 | |||
1042 | return 0; | ||
1043 | } | ||
1044 | |||
1045 | static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1046 | { | ||
1047 | struct data_ring *ring; | ||
1048 | |||
1049 | /* | ||
1050 | * Allocate the RX ring. | ||
1051 | */ | ||
1052 | if (rt2x00lib_alloc_entries(rt2x00dev->rx, RX_ENTRIES, DATA_FRAME_SIZE, | ||
1053 | rt2x00dev->ops->rxd_size)) | ||
1054 | return -ENOMEM; | ||
1055 | |||
1056 | /* | ||
1057 | * First allocate the TX rings. | ||
1058 | */ | ||
1059 | txring_for_each(rt2x00dev, ring) { | ||
1060 | if (rt2x00lib_alloc_entries(ring, TX_ENTRIES, DATA_FRAME_SIZE, | ||
1061 | rt2x00dev->ops->txd_size)) | ||
1062 | return -ENOMEM; | ||
1063 | } | ||
1064 | |||
1065 | if (!test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1066 | return 0; | ||
1067 | |||
1068 | /* | ||
1069 | * Allocate the BEACON ring. | ||
1070 | */ | ||
1071 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[0], BEACON_ENTRIES, | ||
1072 | MGMT_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1073 | return -ENOMEM; | ||
1074 | |||
1075 | /* | ||
1076 | * Allocate the Atim ring. | ||
1077 | */ | ||
1078 | if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES, | ||
1079 | DATA_FRAME_SIZE, rt2x00dev->ops->txd_size)) | ||
1080 | return -ENOMEM; | ||
1081 | |||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev) | ||
1086 | { | ||
1087 | struct data_ring *ring; | ||
1088 | |||
1089 | ring_for_each(rt2x00dev, ring) { | ||
1090 | kfree(ring->entry); | ||
1091 | ring->entry = NULL; | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | 997 | static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) |
1096 | { | 998 | { |
1097 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) | 999 | if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) |
@@ -1108,9 +1010,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); | 1010 | rt2x00dev->ops->lib->uninitialize(rt2x00dev); |
1109 | 1011 | ||
1110 | /* | 1012 | /* |
1111 | * Free allocated ring entries. | 1013 | * Free allocated queue entries. |
1112 | */ | 1014 | */ |
1113 | rt2x00lib_free_ring_entries(rt2x00dev); | 1015 | rt2x00queue_uninitialize(rt2x00dev); |
1114 | } | 1016 | } |
1115 | 1017 | ||
1116 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | 1018 | static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) |
@@ -1121,13 +1023,11 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1121 | return 0; | 1023 | return 0; |
1122 | 1024 | ||
1123 | /* | 1025 | /* |
1124 | * Allocate all ring entries. | 1026 | * Allocate all queue entries. |
1125 | */ | 1027 | */ |
1126 | status = rt2x00lib_alloc_ring_entries(rt2x00dev); | 1028 | status = rt2x00queue_initialize(rt2x00dev); |
1127 | if (status) { | 1029 | if (status) |
1128 | ERROR(rt2x00dev, "Ring entries allocation failed.\n"); | ||
1129 | return status; | 1030 | return status; |
1130 | } | ||
1131 | 1031 | ||
1132 | /* | 1032 | /* |
1133 | * Initialize the device. | 1033 | * Initialize the device. |
@@ -1143,15 +1043,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev) | |||
1143 | */ | 1043 | */ |
1144 | status = rt2x00rfkill_register(rt2x00dev); | 1044 | status = rt2x00rfkill_register(rt2x00dev); |
1145 | if (status) | 1045 | if (status) |
1146 | goto exit_unitialize; | 1046 | goto exit; |
1147 | 1047 | ||
1148 | return 0; | 1048 | return 0; |
1149 | 1049 | ||
1150 | exit_unitialize: | ||
1151 | rt2x00lib_uninitialize(rt2x00dev); | ||
1152 | |||
1153 | exit: | 1050 | exit: |
1154 | rt2x00lib_free_ring_entries(rt2x00dev); | 1051 | rt2x00lib_uninitialize(rt2x00dev); |
1155 | 1052 | ||
1156 | return status; | 1053 | return status; |
1157 | } | 1054 | } |
@@ -1167,11 +1064,9 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1167 | * If this is the first interface which is added, | 1064 | * If this is the first interface which is added, |
1168 | * we should load the firmware now. | 1065 | * we should load the firmware now. |
1169 | */ | 1066 | */ |
1170 | if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) { | 1067 | retval = rt2x00lib_load_firmware(rt2x00dev); |
1171 | retval = rt2x00lib_load_firmware(rt2x00dev); | 1068 | if (retval) |
1172 | if (retval) | 1069 | return retval; |
1173 | return retval; | ||
1174 | } | ||
1175 | 1070 | ||
1176 | /* | 1071 | /* |
1177 | * Initialize the device. | 1072 | * Initialize the device. |
@@ -1189,6 +1084,10 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1189 | return retval; | 1084 | return retval; |
1190 | } | 1085 | } |
1191 | 1086 | ||
1087 | rt2x00dev->intf_ap_count = 0; | ||
1088 | rt2x00dev->intf_sta_count = 0; | ||
1089 | rt2x00dev->intf_associated = 0; | ||
1090 | |||
1192 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1091 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1193 | 1092 | ||
1194 | return 0; | 1093 | return 0; |
@@ -1205,74 +1104,25 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1205 | */ | 1104 | */ |
1206 | rt2x00lib_disable_radio(rt2x00dev); | 1105 | rt2x00lib_disable_radio(rt2x00dev); |
1207 | 1106 | ||
1107 | rt2x00dev->intf_ap_count = 0; | ||
1108 | rt2x00dev->intf_sta_count = 0; | ||
1109 | rt2x00dev->intf_associated = 0; | ||
1110 | |||
1208 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1111 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1209 | } | 1112 | } |
1210 | 1113 | ||
1211 | /* | 1114 | /* |
1212 | * driver allocation handlers. | 1115 | * driver allocation handlers. |
1213 | */ | 1116 | */ |
1214 | static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev) | 1117 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) |
1215 | { | 1118 | { |
1216 | struct data_ring *ring; | 1119 | int retval = -ENOMEM; |
1217 | unsigned int index; | ||
1218 | |||
1219 | /* | ||
1220 | * We need the following rings: | ||
1221 | * RX: 1 | ||
1222 | * TX: hw->queues | ||
1223 | * Beacon: 1 (if required) | ||
1224 | * Atim: 1 (if required) | ||
1225 | */ | ||
1226 | rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues + | ||
1227 | (2 * test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)); | ||
1228 | |||
1229 | ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL); | ||
1230 | if (!ring) { | ||
1231 | ERROR(rt2x00dev, "Ring allocation failed.\n"); | ||
1232 | return -ENOMEM; | ||
1233 | } | ||
1234 | |||
1235 | /* | ||
1236 | * Initialize pointers | ||
1237 | */ | ||
1238 | rt2x00dev->rx = ring; | ||
1239 | rt2x00dev->tx = &rt2x00dev->rx[1]; | ||
1240 | if (test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags)) | ||
1241 | rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues]; | ||
1242 | 1120 | ||
1243 | /* | 1121 | /* |
1244 | * Initialize ring parameters. | 1122 | * Make room for rt2x00_intf inside the per-interface |
1245 | * RX: queue_idx = 0 | 1123 | * structure ieee80211_vif. |
1246 | * TX: queue_idx = IEEE80211_TX_QUEUE_DATA0 + index | ||
1247 | * TX: cw_min: 2^5 = 32. | ||
1248 | * TX: cw_max: 2^10 = 1024. | ||
1249 | */ | 1124 | */ |
1250 | rt2x00dev->rx->rt2x00dev = rt2x00dev; | 1125 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); |
1251 | rt2x00dev->rx->queue_idx = 0; | ||
1252 | |||
1253 | index = IEEE80211_TX_QUEUE_DATA0; | ||
1254 | txring_for_each(rt2x00dev, ring) { | ||
1255 | ring->rt2x00dev = rt2x00dev; | ||
1256 | ring->queue_idx = index++; | ||
1257 | ring->tx_params.aifs = 2; | ||
1258 | ring->tx_params.cw_min = 5; | ||
1259 | ring->tx_params.cw_max = 10; | ||
1260 | } | ||
1261 | |||
1262 | return 0; | ||
1263 | } | ||
1264 | |||
1265 | static void rt2x00lib_free_rings(struct rt2x00_dev *rt2x00dev) | ||
1266 | { | ||
1267 | kfree(rt2x00dev->rx); | ||
1268 | rt2x00dev->rx = NULL; | ||
1269 | rt2x00dev->tx = NULL; | ||
1270 | rt2x00dev->bcn = NULL; | ||
1271 | } | ||
1272 | |||
1273 | int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | ||
1274 | { | ||
1275 | int retval = -ENOMEM; | ||
1276 | 1126 | ||
1277 | /* | 1127 | /* |
1278 | * Let the driver probe the device to detect the capabilities. | 1128 | * Let the driver probe the device to detect the capabilities. |
@@ -1286,20 +1136,14 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1286 | /* | 1136 | /* |
1287 | * Initialize configuration work. | 1137 | * Initialize configuration work. |
1288 | */ | 1138 | */ |
1289 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | 1139 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1290 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1140 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1291 | INIT_WORK(&rt2x00dev->config_work, rt2x00lib_configuration_scheduled); | ||
1292 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1141 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
1293 | 1142 | ||
1294 | /* | 1143 | /* |
1295 | * Reset current working type. | 1144 | * Allocate queue array. |
1296 | */ | ||
1297 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | ||
1298 | |||
1299 | /* | ||
1300 | * Allocate ring array. | ||
1301 | */ | 1145 | */ |
1302 | retval = rt2x00lib_alloc_rings(rt2x00dev); | 1146 | retval = rt2x00queue_allocate(rt2x00dev); |
1303 | if (retval) | 1147 | if (retval) |
1304 | goto exit; | 1148 | goto exit; |
1305 | 1149 | ||
@@ -1313,6 +1157,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1313 | } | 1157 | } |
1314 | 1158 | ||
1315 | /* | 1159 | /* |
1160 | * Register LED. | ||
1161 | */ | ||
1162 | rt2x00leds_register(rt2x00dev); | ||
1163 | |||
1164 | /* | ||
1316 | * Allocatie rfkill. | 1165 | * Allocatie rfkill. |
1317 | */ | 1166 | */ |
1318 | retval = rt2x00rfkill_allocate(rt2x00dev); | 1167 | retval = rt2x00rfkill_allocate(rt2x00dev); |
@@ -1360,6 +1209,11 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1360 | rt2x00rfkill_free(rt2x00dev); | 1209 | rt2x00rfkill_free(rt2x00dev); |
1361 | 1210 | ||
1362 | /* | 1211 | /* |
1212 | * Free LED. | ||
1213 | */ | ||
1214 | rt2x00leds_unregister(rt2x00dev); | ||
1215 | |||
1216 | /* | ||
1363 | * Free ieee80211_hw memory. | 1217 | * Free ieee80211_hw memory. |
1364 | */ | 1218 | */ |
1365 | rt2x00lib_remove_hw(rt2x00dev); | 1219 | rt2x00lib_remove_hw(rt2x00dev); |
@@ -1370,9 +1224,9 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1370 | rt2x00lib_free_firmware(rt2x00dev); | 1224 | rt2x00lib_free_firmware(rt2x00dev); |
1371 | 1225 | ||
1372 | /* | 1226 | /* |
1373 | * Free ring structures. | 1227 | * Free queue structures. |
1374 | */ | 1228 | */ |
1375 | rt2x00lib_free_rings(rt2x00dev); | 1229 | rt2x00queue_free(rt2x00dev); |
1376 | } | 1230 | } |
1377 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); | 1231 | EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); |
1378 | 1232 | ||
@@ -1400,6 +1254,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) | |||
1400 | */ | 1254 | */ |
1401 | rt2x00lib_stop(rt2x00dev); | 1255 | rt2x00lib_stop(rt2x00dev); |
1402 | rt2x00lib_uninitialize(rt2x00dev); | 1256 | rt2x00lib_uninitialize(rt2x00dev); |
1257 | rt2x00leds_suspend(rt2x00dev); | ||
1403 | rt2x00debug_deregister(rt2x00dev); | 1258 | rt2x00debug_deregister(rt2x00dev); |
1404 | 1259 | ||
1405 | exit: | 1260 | exit: |
@@ -1414,17 +1269,39 @@ exit: | |||
1414 | } | 1269 | } |
1415 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 1270 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1416 | 1271 | ||
1272 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1273 | struct ieee80211_vif *vif) | ||
1274 | { | ||
1275 | struct rt2x00_dev *rt2x00dev = data; | ||
1276 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1277 | |||
1278 | spin_lock(&intf->lock); | ||
1279 | |||
1280 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1281 | vif->type, intf->mac, intf->bssid); | ||
1282 | |||
1283 | |||
1284 | /* | ||
1285 | * Master or Ad-hoc mode require a new beacon update. | ||
1286 | */ | ||
1287 | if (vif->type == IEEE80211_IF_TYPE_AP || | ||
1288 | vif->type == IEEE80211_IF_TYPE_IBSS) | ||
1289 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1290 | |||
1291 | spin_unlock(&intf->lock); | ||
1292 | } | ||
1293 | |||
1417 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1294 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1418 | { | 1295 | { |
1419 | struct interface *intf = &rt2x00dev->interface; | ||
1420 | int retval; | 1296 | int retval; |
1421 | 1297 | ||
1422 | NOTICE(rt2x00dev, "Waking up.\n"); | 1298 | NOTICE(rt2x00dev, "Waking up.\n"); |
1423 | 1299 | ||
1424 | /* | 1300 | /* |
1425 | * Open the debugfs entry. | 1301 | * Open the debugfs entry and restore led handling. |
1426 | */ | 1302 | */ |
1427 | rt2x00debug_register(rt2x00dev); | 1303 | rt2x00debug_register(rt2x00dev); |
1304 | rt2x00leds_resume(rt2x00dev); | ||
1428 | 1305 | ||
1429 | /* | 1306 | /* |
1430 | * Only continue if mac80211 had open interfaces. | 1307 | * Only continue if mac80211 had open interfaces. |
@@ -1446,9 +1323,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1446 | if (!rt2x00dev->hw->conf.radio_enabled) | 1323 | if (!rt2x00dev->hw->conf.radio_enabled) |
1447 | rt2x00lib_disable_radio(rt2x00dev); | 1324 | rt2x00lib_disable_radio(rt2x00dev); |
1448 | 1325 | ||
1449 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 1326 | /* |
1450 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 1327 | * Iterator over each active interface to |
1451 | rt2x00lib_config_type(rt2x00dev, intf->type); | 1328 | * reconfigure the hardware. |
1329 | */ | ||
1330 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1331 | rt2x00lib_resume_intf, rt2x00dev); | ||
1452 | 1332 | ||
1453 | /* | 1333 | /* |
1454 | * We are ready again to receive requests from mac80211. | 1334 | * We are ready again to receive requests from mac80211. |
@@ -1464,12 +1344,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1464 | ieee80211_start_queues(rt2x00dev->hw); | 1344 | ieee80211_start_queues(rt2x00dev->hw); |
1465 | 1345 | ||
1466 | /* | 1346 | /* |
1467 | * When in Master or Ad-hoc mode, | 1347 | * During interface iteration we might have changed the |
1468 | * restart Beacon transmitting by faking a beacondone event. | 1348 | * delayed_flags, time to handles the event by calling |
1349 | * the work handler directly. | ||
1469 | */ | 1350 | */ |
1470 | if (intf->type == IEEE80211_IF_TYPE_AP || | 1351 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); |
1471 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
1472 | rt2x00lib_beacondone(rt2x00dev); | ||
1473 | 1352 | ||
1474 | return 0; | 1353 | return 0; |
1475 | 1354 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index 99f3f367adce..7169c222a486 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -93,8 +93,8 @@ enum rt2x00_dump_type { | |||
93 | * @chip_rf: RF chipset | 93 | * @chip_rf: RF chipset |
94 | * @chip_rev: Chipset revision | 94 | * @chip_rev: Chipset revision |
95 | * @type: The frame type (&rt2x00_dump_type) | 95 | * @type: The frame type (&rt2x00_dump_type) |
96 | * @ring_index: The index number of the data ring. | 96 | * @queue_index: The index number of the data queue. |
97 | * @entry_index: The index number of the entry inside the data ring. | 97 | * @entry_index: The index number of the entry inside the data queue. |
98 | * @timestamp_sec: Timestamp - seconds | 98 | * @timestamp_sec: Timestamp - seconds |
99 | * @timestamp_usec: Timestamp - microseconds | 99 | * @timestamp_usec: Timestamp - microseconds |
100 | */ | 100 | */ |
@@ -111,7 +111,7 @@ struct rt2x00dump_hdr { | |||
111 | __le32 chip_rev; | 111 | __le32 chip_rev; |
112 | 112 | ||
113 | __le16 type; | 113 | __le16 type; |
114 | __u8 ring_index; | 114 | __u8 queue_index; |
115 | __u8 entry_index; | 115 | __u8 entry_index; |
116 | 116 | ||
117 | __le32 timestamp_sec; | 117 | __le32 timestamp_sec; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 0a475e4e2442..4f9fe56f4f2e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -23,6 +23,7 @@ | |||
23 | Abstract: rt2x00 firmware loading routines. | 23 | Abstract: rt2x00 firmware loading routines. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/crc-ccitt.h> | ||
26 | #include <linux/crc-itu-t.h> | 27 | #include <linux/crc-itu-t.h> |
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -37,7 +38,6 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
37 | char *fw_name; | 38 | char *fw_name; |
38 | int retval; | 39 | int retval; |
39 | u16 crc; | 40 | u16 crc; |
40 | u16 tmp; | ||
41 | 41 | ||
42 | /* | 42 | /* |
43 | * Read correct firmware from harddisk. | 43 | * Read correct firmware from harddisk. |
@@ -64,17 +64,37 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) | |||
64 | } | 64 | } |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Validate the firmware using 16 bit CRC. | 67 | * Perform crc validation on the firmware. |
68 | * The last 2 bytes of the firmware are the CRC | 68 | * The last 2 bytes in the firmware array are the crc checksum itself, |
69 | * so substract those 2 bytes from the CRC checksum, | 69 | * this means that we should never pass those 2 bytes to the crc |
70 | * and set those 2 bytes to 0 when calculating CRC. | 70 | * algorithm. |
71 | */ | 71 | */ |
72 | tmp = 0; | 72 | if (test_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags)) { |
73 | crc = crc_itu_t(0, fw->data, fw->size - 2); | 73 | /* |
74 | crc = crc_itu_t(crc, (u8 *)&tmp, 2); | 74 | * Use the crc itu-t algorithm. |
75 | * Use 0 for the last 2 bytes to complete the checksum. | ||
76 | */ | ||
77 | crc = crc_itu_t(0, fw->data, fw->size - 2); | ||
78 | crc = crc_itu_t_byte(crc, 0); | ||
79 | crc = crc_itu_t_byte(crc, 0); | ||
80 | } else if (test_bit(DRIVER_REQUIRE_FIRMWARE_CCITT, &rt2x00dev->flags)) { | ||
81 | /* | ||
82 | * Use the crc ccitt algorithm. | ||
83 | * This will return the same value as the legacy driver which | ||
84 | * used bit ordering reversion on the both the firmware bytes | ||
85 | * before input input as well as on the final output. | ||
86 | * Obviously using crc ccitt directly is much more efficient. | ||
87 | */ | ||
88 | crc = crc_ccitt(~0, fw->data, fw->size - 2); | ||
89 | } else { | ||
90 | ERROR(rt2x00dev, "No checksum algorithm selected " | ||
91 | "for firmware validation.\n"); | ||
92 | retval = -ENOENT; | ||
93 | goto exit; | ||
94 | } | ||
75 | 95 | ||
76 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { | 96 | if (crc != (fw->data[fw->size - 2] << 8 | fw->data[fw->size - 1])) { |
77 | ERROR(rt2x00dev, "Firmware CRC error.\n"); | 97 | ERROR(rt2x00dev, "Firmware checksum error.\n"); |
78 | retval = -ENOENT; | 98 | retval = -ENOENT; |
79 | goto exit; | 99 | goto exit; |
80 | } | 100 | } |
@@ -96,6 +116,9 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev) | |||
96 | { | 116 | { |
97 | int retval; | 117 | int retval; |
98 | 118 | ||
119 | if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) | ||
120 | return 0; | ||
121 | |||
99 | if (!rt2x00dev->fw) { | 122 | if (!rt2x00dev->fw) { |
100 | retval = rt2x00lib_request_firmware(rt2x00dev); | 123 | retval = rt2x00lib_request_firmware(rt2x00dev); |
101 | if (retval) | 124 | if (retval) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.c b/drivers/net/wireless/rt2x00/rt2x00leds.c new file mode 100644 index 000000000000..9c29d17e0cc2 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.c | |||
@@ -0,0 +1,217 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi) | ||
33 | { | ||
34 | if (!rt2x00dev->trigger_qual.registered) | ||
35 | return; | ||
36 | |||
37 | /* | ||
38 | * Led handling requires a positive value for the rssi, | ||
39 | * to do that correctly we need to add the correction. | ||
40 | */ | ||
41 | rssi += rt2x00dev->rssi_offset; | ||
42 | |||
43 | /* | ||
44 | * Get the rssi level, this is used to convert the rssi | ||
45 | * to a LED value inside the range LED_OFF - LED_FULL. | ||
46 | */ | ||
47 | if (rssi <= 30) | ||
48 | rssi = 0; | ||
49 | else if (rssi <= 39) | ||
50 | rssi = 1; | ||
51 | else if (rssi <= 49) | ||
52 | rssi = 2; | ||
53 | else if (rssi <= 53) | ||
54 | rssi = 3; | ||
55 | else if (rssi <= 63) | ||
56 | rssi = 4; | ||
57 | else | ||
58 | rssi = 5; | ||
59 | |||
60 | /* | ||
61 | * Note that we must _not_ send LED_OFF since the driver | ||
62 | * is going to calculate the value and might use it in a | ||
63 | * division. | ||
64 | */ | ||
65 | led_trigger_event(&rt2x00dev->trigger_qual.trigger, | ||
66 | ((LED_FULL / 6) * rssi) + 1); | ||
67 | } | ||
68 | |||
69 | static int rt2x00leds_register_trigger(struct rt2x00_dev *rt2x00dev, | ||
70 | struct rt2x00_trigger *trigger, | ||
71 | const char *name) | ||
72 | { | ||
73 | int retval; | ||
74 | |||
75 | trigger->trigger.name = name; | ||
76 | retval = led_trigger_register(&trigger->trigger); | ||
77 | if (retval) { | ||
78 | ERROR(rt2x00dev, "Failed to register led trigger.\n"); | ||
79 | return retval; | ||
80 | } | ||
81 | |||
82 | trigger->registered = 1; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int rt2x00leds_register_led(struct rt2x00_dev *rt2x00dev, | ||
88 | struct rt2x00_led *led, | ||
89 | enum led_type type, | ||
90 | const char *name, char *trigger) | ||
91 | { | ||
92 | struct device *device = wiphy_dev(rt2x00dev->hw->wiphy); | ||
93 | int retval; | ||
94 | |||
95 | led->led_dev.name = name; | ||
96 | led->led_dev.brightness_set = rt2x00dev->ops->lib->led_brightness; | ||
97 | led->led_dev.default_trigger = trigger; | ||
98 | |||
99 | retval = led_classdev_register(device, &led->led_dev); | ||
100 | if (retval) { | ||
101 | ERROR(rt2x00dev, "Failed to register led handler.\n"); | ||
102 | return retval; | ||
103 | } | ||
104 | |||
105 | led->rt2x00dev = rt2x00dev; | ||
106 | led->type = type; | ||
107 | led->registered = 1; | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
113 | { | ||
114 | char *trigger; | ||
115 | char dev_name[16]; | ||
116 | char name[32]; | ||
117 | int retval; | ||
118 | |||
119 | if (!rt2x00dev->ops->lib->led_brightness) | ||
120 | return 0; | ||
121 | |||
122 | snprintf(dev_name, sizeof(dev_name), "%s-%s", | ||
123 | rt2x00dev->ops->name, wiphy_name(rt2x00dev->hw->wiphy)); | ||
124 | |||
125 | if (rt2x00dev->led_flags & LED_SUPPORT_RADIO) { | ||
126 | trigger = ieee80211_get_radio_led_name(rt2x00dev->hw); | ||
127 | snprintf(name, sizeof(name), "%s:radio", dev_name); | ||
128 | |||
129 | retval = rt2x00leds_register_led(rt2x00dev, | ||
130 | &rt2x00dev->led_radio, | ||
131 | LED_TYPE_RADIO, | ||
132 | name, trigger); | ||
133 | if (retval) | ||
134 | goto exit_fail; | ||
135 | } | ||
136 | |||
137 | if (rt2x00dev->led_flags & LED_SUPPORT_ASSOC) { | ||
138 | trigger = ieee80211_get_assoc_led_name(rt2x00dev->hw); | ||
139 | snprintf(name, sizeof(name), "%s:assoc", dev_name); | ||
140 | |||
141 | retval = rt2x00leds_register_led(rt2x00dev, | ||
142 | &rt2x00dev->led_assoc, | ||
143 | LED_TYPE_ASSOC, | ||
144 | name, trigger); | ||
145 | if (retval) | ||
146 | goto exit_fail; | ||
147 | } | ||
148 | |||
149 | if (rt2x00dev->led_flags & LED_SUPPORT_QUALITY) { | ||
150 | snprintf(name, sizeof(name), "%s:quality", dev_name); | ||
151 | |||
152 | retval = rt2x00leds_register_trigger(rt2x00dev, | ||
153 | &rt2x00dev->trigger_qual, | ||
154 | name); | ||
155 | |||
156 | retval = rt2x00leds_register_led(rt2x00dev, | ||
157 | &rt2x00dev->led_qual, | ||
158 | LED_TYPE_QUALITY, | ||
159 | name, name); | ||
160 | if (retval) | ||
161 | goto exit_fail; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | |||
166 | exit_fail: | ||
167 | rt2x00leds_unregister(rt2x00dev); | ||
168 | return retval; | ||
169 | } | ||
170 | |||
171 | static void rt2x00leds_unregister_trigger(struct rt2x00_trigger *trigger) | ||
172 | { | ||
173 | if (!trigger->registered) | ||
174 | return; | ||
175 | |||
176 | led_trigger_unregister(&trigger->trigger); | ||
177 | trigger->registered = 0; | ||
178 | } | ||
179 | |||
180 | static void rt2x00leds_unregister_led(struct rt2x00_led *led) | ||
181 | { | ||
182 | if (!led->registered) | ||
183 | return; | ||
184 | |||
185 | led_classdev_unregister(&led->led_dev); | ||
186 | |||
187 | led->led_dev.brightness_set(&led->led_dev, LED_OFF); | ||
188 | led->registered = 0; | ||
189 | } | ||
190 | |||
191 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
192 | { | ||
193 | rt2x00leds_unregister_trigger(&rt2x00dev->trigger_qual); | ||
194 | rt2x00leds_unregister_led(&rt2x00dev->led_qual); | ||
195 | rt2x00leds_unregister_led(&rt2x00dev->led_assoc); | ||
196 | rt2x00leds_unregister_led(&rt2x00dev->led_radio); | ||
197 | } | ||
198 | |||
199 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
200 | { | ||
201 | if (rt2x00dev->led_qual.registered) | ||
202 | led_classdev_suspend(&rt2x00dev->led_qual.led_dev); | ||
203 | if (rt2x00dev->led_assoc.registered) | ||
204 | led_classdev_suspend(&rt2x00dev->led_assoc.led_dev); | ||
205 | if (rt2x00dev->led_radio.registered) | ||
206 | led_classdev_suspend(&rt2x00dev->led_radio.led_dev); | ||
207 | } | ||
208 | |||
209 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
210 | { | ||
211 | if (rt2x00dev->led_radio.registered) | ||
212 | led_classdev_resume(&rt2x00dev->led_radio.led_dev); | ||
213 | if (rt2x00dev->led_assoc.registered) | ||
214 | led_classdev_resume(&rt2x00dev->led_assoc.led_dev); | ||
215 | if (rt2x00dev->led_qual.registered) | ||
216 | led_classdev_resume(&rt2x00dev->led_qual.led_dev); | ||
217 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00leds.h b/drivers/net/wireless/rt2x00/rt2x00leds.h new file mode 100644 index 000000000000..11e71e9ce853 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00leds.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 led datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00LEDS_H | ||
27 | #define RT2X00LEDS_H | ||
28 | |||
29 | /* | ||
30 | * Flags used by driver to indicate which | ||
31 | * which led types are supported. | ||
32 | */ | ||
33 | #define LED_SUPPORT_RADIO 0x000001 | ||
34 | #define LED_SUPPORT_ASSOC 0x000002 | ||
35 | #define LED_SUPPORT_ACTIVITY 0x000004 | ||
36 | #define LED_SUPPORT_QUALITY 0x000008 | ||
37 | |||
38 | enum led_type { | ||
39 | LED_TYPE_RADIO, | ||
40 | LED_TYPE_ASSOC, | ||
41 | LED_TYPE_QUALITY, | ||
42 | }; | ||
43 | |||
44 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
45 | |||
46 | struct rt2x00_led { | ||
47 | struct rt2x00_dev *rt2x00dev; | ||
48 | struct led_classdev led_dev; | ||
49 | |||
50 | enum led_type type; | ||
51 | unsigned int registered; | ||
52 | }; | ||
53 | |||
54 | struct rt2x00_trigger { | ||
55 | struct led_trigger trigger; | ||
56 | |||
57 | enum led_type type; | ||
58 | unsigned int registered; | ||
59 | }; | ||
60 | |||
61 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
62 | |||
63 | #endif /* RT2X00LEDS_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 1adbd28e0973..34ccb3de687e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -34,6 +34,52 @@ | |||
34 | #define RFKILL_POLL_INTERVAL ( 1000 ) | 34 | #define RFKILL_POLL_INTERVAL ( 1000 ) |
35 | 35 | ||
36 | /* | 36 | /* |
37 | * rt2x00_rate: Per rate device information | ||
38 | */ | ||
39 | struct rt2x00_rate { | ||
40 | unsigned short flags; | ||
41 | #define DEV_RATE_CCK 0x0001 | ||
42 | #define DEV_RATE_OFDM 0x0002 | ||
43 | #define DEV_RATE_SHORT_PREAMBLE 0x0004 | ||
44 | |||
45 | unsigned short bitrate; /* In 100kbit/s */ | ||
46 | |||
47 | unsigned short ratemask; | ||
48 | #define DEV_RATEMASK_1MB ( (1 << 1) - 1 ) | ||
49 | #define DEV_RATEMASK_2MB ( (1 << 2) - 1 ) | ||
50 | #define DEV_RATEMASK_5_5MB ( (1 << 3) - 1 ) | ||
51 | #define DEV_RATEMASK_11MB ( (1 << 4) - 1 ) | ||
52 | #define DEV_RATEMASK_6MB ( (1 << 5) - 1 ) | ||
53 | #define DEV_RATEMASK_9MB ( (1 << 6) - 1 ) | ||
54 | #define DEV_RATEMASK_12MB ( (1 << 7) - 1 ) | ||
55 | #define DEV_RATEMASK_18MB ( (1 << 8) - 1 ) | ||
56 | #define DEV_RATEMASK_24MB ( (1 << 9) - 1 ) | ||
57 | #define DEV_RATEMASK_36MB ( (1 << 10) - 1 ) | ||
58 | #define DEV_RATEMASK_48MB ( (1 << 11) - 1 ) | ||
59 | #define DEV_RATEMASK_54MB ( (1 << 12) - 1 ) | ||
60 | |||
61 | unsigned short plcp; | ||
62 | }; | ||
63 | |||
64 | extern const struct rt2x00_rate rt2x00_supported_rates[12]; | ||
65 | |||
66 | static inline u16 rt2x00_create_rate_hw_value(const u16 index, | ||
67 | const u16 short_preamble) | ||
68 | { | ||
69 | return (short_preamble << 8) | (index & 0xff); | ||
70 | } | ||
71 | |||
72 | static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value) | ||
73 | { | ||
74 | return &rt2x00_supported_rates[hw_value & 0xff]; | ||
75 | } | ||
76 | |||
77 | static inline int rt2x00_get_rate_preamble(const u16 hw_value) | ||
78 | { | ||
79 | return (hw_value & 0xff00); | ||
80 | } | ||
81 | |||
82 | /* | ||
37 | * Radio control handlers. | 83 | * Radio control handlers. |
38 | */ | 84 | */ |
39 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); | 85 | int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev); |
@@ -50,15 +96,29 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev); | |||
50 | /* | 96 | /* |
51 | * Configuration handlers. | 97 | * Configuration handlers. |
52 | */ | 98 | */ |
53 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); | 99 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
54 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); | 100 | struct rt2x00_intf *intf, |
55 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type); | 101 | enum ieee80211_if_types type, |
102 | u8 *mac, u8 *bssid); | ||
103 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
104 | struct rt2x00_intf *intf, | ||
105 | const unsigned int short_preamble); | ||
56 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 106 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
57 | enum antenna rx, enum antenna tx); | 107 | enum antenna rx, enum antenna tx); |
58 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 108 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
59 | struct ieee80211_conf *conf, const int force_config); | 109 | struct ieee80211_conf *conf, const int force_config); |
60 | 110 | ||
61 | /* | 111 | /* |
112 | * Queue handlers. | ||
113 | */ | ||
114 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | ||
115 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | ||
116 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | ||
117 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); | ||
118 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); | ||
119 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev); | ||
120 | |||
121 | /* | ||
62 | * Firmware handlers. | 122 | * Firmware handlers. |
63 | */ | 123 | */ |
64 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE | 124 | #ifdef CONFIG_RT2X00_LIB_FIRMWARE |
@@ -124,4 +184,37 @@ static inline void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) | |||
124 | } | 184 | } |
125 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ | 185 | #endif /* CONFIG_RT2X00_LIB_RFKILL */ |
126 | 186 | ||
187 | /* | ||
188 | * LED handlers | ||
189 | */ | ||
190 | #ifdef CONFIG_RT2X00_LIB_LEDS | ||
191 | void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, int rssi); | ||
192 | int rt2x00leds_register(struct rt2x00_dev *rt2x00dev); | ||
193 | void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev); | ||
194 | void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev); | ||
195 | void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev); | ||
196 | #else | ||
197 | static inline void rt2x00leds_led_quality(struct rt2x00_dev *rt2x00dev, | ||
198 | int rssi) | ||
199 | { | ||
200 | } | ||
201 | |||
202 | static inline int rt2x00leds_register(struct rt2x00_dev *rt2x00dev) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static inline void rt2x00leds_unregister(struct rt2x00_dev *rt2x00dev) | ||
208 | { | ||
209 | } | ||
210 | |||
211 | static inline void rt2x00leds_suspend(struct rt2x00_dev *rt2x00dev) | ||
212 | { | ||
213 | } | ||
214 | |||
215 | static inline void rt2x00leds_resume(struct rt2x00_dev *rt2x00dev) | ||
216 | { | ||
217 | } | ||
218 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | ||
219 | |||
127 | #endif /* RT2X00LIB_H */ | 220 | #endif /* RT2X00LIB_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index e3f15e518c76..a54f6873e9ea 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -30,10 +30,11 @@ | |||
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | 32 | static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, |
33 | struct data_ring *ring, | 33 | struct data_queue *queue, |
34 | struct sk_buff *frag_skb, | 34 | struct sk_buff *frag_skb, |
35 | struct ieee80211_tx_control *control) | 35 | struct ieee80211_tx_control *control) |
36 | { | 36 | { |
37 | struct skb_frame_desc *skbdesc; | ||
37 | struct sk_buff *skb; | 38 | struct sk_buff *skb; |
38 | int size; | 39 | int size; |
39 | 40 | ||
@@ -52,15 +53,22 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
52 | skb_put(skb, size); | 53 | skb_put(skb, size); |
53 | 54 | ||
54 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 55 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
55 | ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id, | 56 | ieee80211_ctstoself_get(rt2x00dev->hw, control->vif, |
56 | frag_skb->data, frag_skb->len, control, | 57 | frag_skb->data, frag_skb->len, control, |
57 | (struct ieee80211_cts *)(skb->data)); | 58 | (struct ieee80211_cts *)(skb->data)); |
58 | else | 59 | else |
59 | ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id, | 60 | ieee80211_rts_get(rt2x00dev->hw, control->vif, |
60 | frag_skb->data, frag_skb->len, control, | 61 | frag_skb->data, frag_skb->len, control, |
61 | (struct ieee80211_rts *)(skb->data)); | 62 | (struct ieee80211_rts *)(skb->data)); |
62 | 63 | ||
63 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 64 | /* |
65 | * Initialize skb descriptor | ||
66 | */ | ||
67 | skbdesc = get_skb_frame_desc(skb); | ||
68 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
69 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
70 | |||
71 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
64 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 72 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
65 | return NETDEV_TX_BUSY; | 73 | return NETDEV_TX_BUSY; |
66 | } | 74 | } |
@@ -73,7 +81,8 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
73 | { | 81 | { |
74 | struct rt2x00_dev *rt2x00dev = hw->priv; | 82 | struct rt2x00_dev *rt2x00dev = hw->priv; |
75 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; | 83 | struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; |
76 | struct data_ring *ring; | 84 | struct data_queue *queue; |
85 | struct skb_frame_desc *skbdesc; | ||
77 | u16 frame_control; | 86 | u16 frame_control; |
78 | 87 | ||
79 | /* | 88 | /* |
@@ -88,10 +97,10 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
88 | } | 97 | } |
89 | 98 | ||
90 | /* | 99 | /* |
91 | * Determine which ring to put packet on. | 100 | * Determine which queue to put packet on. |
92 | */ | 101 | */ |
93 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | 102 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); |
94 | if (unlikely(!ring)) { | 103 | if (unlikely(!queue)) { |
95 | ERROR(rt2x00dev, | 104 | ERROR(rt2x00dev, |
96 | "Attempt to send packet over invalid queue %d.\n" | 105 | "Attempt to send packet over invalid queue %d.\n" |
97 | "Please file bug report to %s.\n", | 106 | "Please file bug report to %s.\n", |
@@ -110,23 +119,29 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
110 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && | 119 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && |
111 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | | 120 | (control->flags & (IEEE80211_TXCTL_USE_RTS_CTS | |
112 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { | 121 | IEEE80211_TXCTL_USE_CTS_PROTECT))) { |
113 | if (rt2x00_ring_free(ring) <= 1) { | 122 | if (rt2x00queue_available(queue) <= 1) { |
114 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 123 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
115 | return NETDEV_TX_BUSY; | 124 | return NETDEV_TX_BUSY; |
116 | } | 125 | } |
117 | 126 | ||
118 | if (rt2x00mac_tx_rts_cts(rt2x00dev, ring, skb, control)) { | 127 | if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb, control)) { |
119 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 128 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
120 | return NETDEV_TX_BUSY; | 129 | return NETDEV_TX_BUSY; |
121 | } | 130 | } |
122 | } | 131 | } |
123 | 132 | ||
124 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) { | 133 | /* |
134 | * Initialize skb descriptor | ||
135 | */ | ||
136 | skbdesc = get_skb_frame_desc(skb); | ||
137 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
138 | |||
139 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb, control)) { | ||
125 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 140 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
126 | return NETDEV_TX_BUSY; | 141 | return NETDEV_TX_BUSY; |
127 | } | 142 | } |
128 | 143 | ||
129 | if (rt2x00_ring_full(ring)) | 144 | if (rt2x00queue_full(queue)) |
130 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); | 145 | ieee80211_stop_queue(rt2x00dev->hw, control->queue); |
131 | 146 | ||
132 | if (rt2x00dev->ops->lib->kick_tx_queue) | 147 | if (rt2x00dev->ops->lib->kick_tx_queue) |
@@ -162,27 +177,67 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
162 | struct ieee80211_if_init_conf *conf) | 177 | struct ieee80211_if_init_conf *conf) |
163 | { | 178 | { |
164 | struct rt2x00_dev *rt2x00dev = hw->priv; | 179 | struct rt2x00_dev *rt2x00dev = hw->priv; |
165 | struct interface *intf = &rt2x00dev->interface; | 180 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
166 | 181 | struct data_queue *queue = | |
167 | /* FIXME: Beaconing is broken in rt2x00. */ | 182 | rt2x00queue_get_queue(rt2x00dev, RT2X00_BCN_QUEUE_BEACON); |
168 | if (conf->type == IEEE80211_IF_TYPE_IBSS || | 183 | struct queue_entry *entry = NULL; |
169 | conf->type == IEEE80211_IF_TYPE_AP) { | 184 | unsigned int i; |
170 | ERROR(rt2x00dev, | ||
171 | "rt2x00 does not support Adhoc or Master mode"); | ||
172 | return -EOPNOTSUPP; | ||
173 | } | ||
174 | 185 | ||
175 | /* | 186 | /* |
176 | * Don't allow interfaces to be added while | 187 | * Don't allow interfaces to be added |
177 | * either the device has disappeared or when | 188 | * the device has disappeared. |
178 | * another interface is already present. | ||
179 | */ | 189 | */ |
180 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 190 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
181 | is_interface_present(intf)) | 191 | !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) |
192 | return -ENODEV; | ||
193 | |||
194 | /* | ||
195 | * When we don't support mixed interfaces (a combination | ||
196 | * of sta and ap virtual interfaces) then we can only | ||
197 | * add this interface when the rival interface count is 0. | ||
198 | */ | ||
199 | if (!test_bit(DRIVER_SUPPORT_MIXED_INTERFACES, &rt2x00dev->flags) && | ||
200 | ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) || | ||
201 | (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count))) | ||
182 | return -ENOBUFS; | 202 | return -ENOBUFS; |
183 | 203 | ||
184 | intf->id = conf->vif; | 204 | /* |
185 | intf->type = conf->type; | 205 | * Check if we exceeded the maximum amount of supported interfaces. |
206 | */ | ||
207 | if ((conf->type == IEEE80211_IF_TYPE_AP && | ||
208 | rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf) || | ||
209 | (conf->type != IEEE80211_IF_TYPE_AP && | ||
210 | rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)) | ||
211 | return -ENOBUFS; | ||
212 | |||
213 | /* | ||
214 | * Loop through all beacon queues to find a free | ||
215 | * entry. Since there are as much beacon entries | ||
216 | * as the maximum interfaces, this search shouldn't | ||
217 | * fail. | ||
218 | */ | ||
219 | for (i = 0; i < queue->limit; i++) { | ||
220 | entry = &queue->entries[i]; | ||
221 | if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) | ||
222 | break; | ||
223 | } | ||
224 | |||
225 | if (unlikely(i == queue->limit)) | ||
226 | return -ENOBUFS; | ||
227 | |||
228 | /* | ||
229 | * We are now absolutely sure the interface can be created, | ||
230 | * increase interface count and start initialization. | ||
231 | */ | ||
232 | |||
233 | if (conf->type == IEEE80211_IF_TYPE_AP) | ||
234 | rt2x00dev->intf_ap_count++; | ||
235 | else | ||
236 | rt2x00dev->intf_sta_count++; | ||
237 | |||
238 | spin_lock_init(&intf->lock); | ||
239 | intf->beacon = entry; | ||
240 | |||
186 | if (conf->type == IEEE80211_IF_TYPE_AP) | 241 | if (conf->type == IEEE80211_IF_TYPE_AP) |
187 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); | 242 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); |
188 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); | 243 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); |
@@ -192,8 +247,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
192 | * has been initialized. Otherwise the device can reset | 247 | * has been initialized. Otherwise the device can reset |
193 | * the MAC registers. | 248 | * the MAC registers. |
194 | */ | 249 | */ |
195 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 250 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL); |
196 | rt2x00lib_config_type(rt2x00dev, conf->type); | ||
197 | 251 | ||
198 | return 0; | 252 | return 0; |
199 | } | 253 | } |
@@ -203,7 +257,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
203 | struct ieee80211_if_init_conf *conf) | 257 | struct ieee80211_if_init_conf *conf) |
204 | { | 258 | { |
205 | struct rt2x00_dev *rt2x00dev = hw->priv; | 259 | struct rt2x00_dev *rt2x00dev = hw->priv; |
206 | struct interface *intf = &rt2x00dev->interface; | 260 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
207 | 261 | ||
208 | /* | 262 | /* |
209 | * Don't allow interfaces to be remove while | 263 | * Don't allow interfaces to be remove while |
@@ -211,21 +265,27 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
211 | * no interface is present. | 265 | * no interface is present. |
212 | */ | 266 | */ |
213 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 267 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
214 | !is_interface_present(intf)) | 268 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
269 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | ||
215 | return; | 270 | return; |
216 | 271 | ||
217 | intf->id = 0; | 272 | if (conf->type == IEEE80211_IF_TYPE_AP) |
218 | intf->type = IEEE80211_IF_TYPE_INVALID; | 273 | rt2x00dev->intf_ap_count--; |
219 | memset(&intf->bssid, 0x00, ETH_ALEN); | 274 | else |
220 | memset(&intf->mac, 0x00, ETH_ALEN); | 275 | rt2x00dev->intf_sta_count--; |
276 | |||
277 | /* | ||
278 | * Release beacon entry so it is available for | ||
279 | * new interfaces again. | ||
280 | */ | ||
281 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | ||
221 | 282 | ||
222 | /* | 283 | /* |
223 | * Make sure the bssid and mac address registers | 284 | * Make sure the bssid and mac address registers |
224 | * are cleared to prevent false ACKing of frames. | 285 | * are cleared to prevent false ACKing of frames. |
225 | */ | 286 | */ |
226 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 287 | rt2x00lib_config_intf(rt2x00dev, intf, |
227 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 288 | IEEE80211_IF_TYPE_INVALID, NULL, NULL); |
228 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
229 | } | 289 | } |
230 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | 290 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); |
231 | 291 | ||
@@ -270,7 +330,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
270 | struct ieee80211_if_conf *conf) | 330 | struct ieee80211_if_conf *conf) |
271 | { | 331 | { |
272 | struct rt2x00_dev *rt2x00dev = hw->priv; | 332 | struct rt2x00_dev *rt2x00dev = hw->priv; |
273 | struct interface *intf = &rt2x00dev->interface; | 333 | struct rt2x00_intf *intf = vif_to_intf(vif); |
274 | int status; | 334 | int status; |
275 | 335 | ||
276 | /* | 336 | /* |
@@ -280,12 +340,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
280 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 340 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) |
281 | return 0; | 341 | return 0; |
282 | 342 | ||
283 | /* | 343 | spin_lock(&intf->lock); |
284 | * If the given type does not match the configured type, | ||
285 | * there has been a problem. | ||
286 | */ | ||
287 | if (conf->type != intf->type) | ||
288 | return -EINVAL; | ||
289 | 344 | ||
290 | /* | 345 | /* |
291 | * If the interface does not work in master mode, | 346 | * If the interface does not work in master mode, |
@@ -294,7 +349,16 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
294 | */ | 349 | */ |
295 | if (conf->type != IEEE80211_IF_TYPE_AP) | 350 | if (conf->type != IEEE80211_IF_TYPE_AP) |
296 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 351 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
297 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 352 | |
353 | spin_unlock(&intf->lock); | ||
354 | |||
355 | /* | ||
356 | * Call rt2x00_config_intf() outside of the spinlock context since | ||
357 | * the call will sleep for USB drivers. By using the ieee80211_if_conf | ||
358 | * values as arguments we make keep access to rt2x00_intf thread safe | ||
359 | * even without the lock. | ||
360 | */ | ||
361 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, conf->bssid); | ||
298 | 362 | ||
299 | /* | 363 | /* |
300 | * We only need to initialize the beacon when master mode is enabled. | 364 | * We only need to initialize the beacon when master mode is enabled. |
@@ -334,9 +398,11 @@ int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, | |||
334 | struct rt2x00_dev *rt2x00dev = hw->priv; | 398 | struct rt2x00_dev *rt2x00dev = hw->priv; |
335 | unsigned int i; | 399 | unsigned int i; |
336 | 400 | ||
337 | for (i = 0; i < hw->queues; i++) | 401 | for (i = 0; i < hw->queues; i++) { |
338 | memcpy(&stats->data[i], &rt2x00dev->tx[i].stats, | 402 | stats->data[i].len = rt2x00dev->tx[i].length; |
339 | sizeof(rt2x00dev->tx[i].stats)); | 403 | stats->data[i].limit = rt2x00dev->tx[i].limit; |
404 | stats->data[i].count = rt2x00dev->tx[i].count; | ||
405 | } | ||
340 | 406 | ||
341 | return 0; | 407 | return 0; |
342 | } | 408 | } |
@@ -348,71 +414,70 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
348 | u32 changes) | 414 | u32 changes) |
349 | { | 415 | { |
350 | struct rt2x00_dev *rt2x00dev = hw->priv; | 416 | struct rt2x00_dev *rt2x00dev = hw->priv; |
351 | int short_preamble; | 417 | struct rt2x00_intf *intf = vif_to_intf(vif); |
352 | int ack_timeout; | ||
353 | int ack_consume_time; | ||
354 | int difs; | ||
355 | int preamble; | ||
356 | 418 | ||
357 | /* | 419 | /* |
358 | * We only support changing preamble mode. | 420 | * When the association status has changed we must reset the link |
421 | * tuner counter. This is because some drivers determine if they | ||
422 | * should perform link tuning based on the number of seconds | ||
423 | * while associated or not associated. | ||
359 | */ | 424 | */ |
360 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) | 425 | if (changes & BSS_CHANGED_ASSOC) { |
361 | return; | 426 | rt2x00dev->link.count = 0; |
362 | |||
363 | short_preamble = bss_conf->use_short_preamble; | ||
364 | preamble = bss_conf->use_short_preamble ? | ||
365 | SHORT_PREAMBLE : PREAMBLE; | ||
366 | |||
367 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | ||
368 | SHORT_DIFS : DIFS; | ||
369 | ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10); | ||
370 | 427 | ||
371 | ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | 428 | if (bss_conf->assoc) |
429 | rt2x00dev->intf_associated++; | ||
430 | else | ||
431 | rt2x00dev->intf_associated--; | ||
432 | } | ||
372 | 433 | ||
373 | if (short_preamble) | 434 | /* |
374 | __set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 435 | * When the preamble mode has changed, we should perform additional |
375 | else | 436 | * configuration steps. For all other changes we are already done. |
376 | __clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 437 | */ |
438 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
439 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
440 | bss_conf->use_short_preamble); | ||
377 | 441 | ||
378 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 442 | spin_lock(&intf->lock); |
379 | ack_timeout, ack_consume_time); | 443 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
444 | spin_unlock(&intf->lock); | ||
445 | } | ||
380 | } | 446 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 447 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
382 | 448 | ||
383 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue, | 449 | int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue_idx, |
384 | const struct ieee80211_tx_queue_params *params) | 450 | const struct ieee80211_tx_queue_params *params) |
385 | { | 451 | { |
386 | struct rt2x00_dev *rt2x00dev = hw->priv; | 452 | struct rt2x00_dev *rt2x00dev = hw->priv; |
387 | struct data_ring *ring; | 453 | struct data_queue *queue; |
388 | 454 | ||
389 | ring = rt2x00lib_get_ring(rt2x00dev, queue); | 455 | queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); |
390 | if (unlikely(!ring)) | 456 | if (unlikely(!queue)) |
391 | return -EINVAL; | 457 | return -EINVAL; |
392 | 458 | ||
393 | /* | 459 | /* |
394 | * The passed variables are stored as real value ((2^n)-1). | 460 | * The passed variables are stored as real value ((2^n)-1). |
395 | * Ralink registers require to know the bit number 'n'. | 461 | * Ralink registers require to know the bit number 'n'. |
396 | */ | 462 | */ |
397 | if (params->cw_min) | 463 | if (params->cw_min > 0) |
398 | ring->tx_params.cw_min = fls(params->cw_min); | 464 | queue->cw_min = fls(params->cw_min); |
399 | else | 465 | else |
400 | ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ | 466 | queue->cw_min = 5; /* cw_min: 2^5 = 32. */ |
401 | 467 | ||
402 | if (params->cw_max) | 468 | if (params->cw_max > 0) |
403 | ring->tx_params.cw_max = fls(params->cw_max); | 469 | queue->cw_max = fls(params->cw_max); |
404 | else | 470 | else |
405 | ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ | 471 | queue->cw_max = 10; /* cw_min: 2^10 = 1024. */ |
406 | 472 | ||
407 | if (params->aifs) | 473 | if (params->aifs >= 0) |
408 | ring->tx_params.aifs = params->aifs; | 474 | queue->aifs = params->aifs; |
409 | else | 475 | else |
410 | ring->tx_params.aifs = 2; | 476 | queue->aifs = 2; |
411 | 477 | ||
412 | INFO(rt2x00dev, | 478 | INFO(rt2x00dev, |
413 | "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", | 479 | "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d.\n", |
414 | queue, ring->tx_params.cw_min, ring->tx_params.cw_max, | 480 | queue_idx, queue->cw_min, queue->cw_max, queue->aifs); |
415 | ring->tx_params.aifs); | ||
416 | 481 | ||
417 | return 0; | 482 | return 0; |
418 | } | 483 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 804a9980055d..1960d938d73b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -32,64 +32,21 @@ | |||
32 | #include "rt2x00pci.h" | 32 | #include "rt2x00pci.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Beacon handlers. | ||
36 | */ | ||
37 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
38 | struct ieee80211_tx_control *control) | ||
39 | { | ||
40 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
41 | struct skb_desc *desc; | ||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | |||
45 | /* | ||
46 | * Just in case mac80211 doesn't set this correctly, | ||
47 | * but we need this queue set for the descriptor | ||
48 | * initialization. | ||
49 | */ | ||
50 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
51 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
52 | entry = rt2x00_get_data_entry(ring); | ||
53 | |||
54 | /* | ||
55 | * Fill in skb descriptor | ||
56 | */ | ||
57 | desc = get_skb_desc(skb); | ||
58 | desc->desc_len = ring->desc_size; | ||
59 | desc->data_len = skb->len; | ||
60 | desc->desc = entry->priv; | ||
61 | desc->data = skb->data; | ||
62 | desc->ring = ring; | ||
63 | desc->entry = entry; | ||
64 | |||
65 | memcpy(entry->data_addr, skb->data, skb->len); | ||
66 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
67 | |||
68 | /* | ||
69 | * Enable beacon generation. | ||
70 | */ | ||
71 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | ||
72 | |||
73 | return 0; | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(rt2x00pci_beacon_update); | ||
76 | |||
77 | /* | ||
78 | * TX data handlers. | 35 | * TX data handlers. |
79 | */ | 36 | */ |
80 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
81 | struct data_ring *ring, struct sk_buff *skb, | 38 | struct data_queue *queue, struct sk_buff *skb, |
82 | struct ieee80211_tx_control *control) | 39 | struct ieee80211_tx_control *control) |
83 | { | 40 | { |
84 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 41 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
85 | __le32 *txd = entry->priv; | 42 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
86 | struct skb_desc *desc; | 43 | struct skb_frame_desc *skbdesc; |
87 | u32 word; | 44 | u32 word; |
88 | 45 | ||
89 | if (rt2x00_ring_full(ring)) | 46 | if (rt2x00queue_full(queue)) |
90 | return -EINVAL; | 47 | return -EINVAL; |
91 | 48 | ||
92 | rt2x00_desc_read(txd, 0, &word); | 49 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
93 | 50 | ||
94 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || |
95 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { |
@@ -103,18 +60,17 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
103 | /* | 60 | /* |
104 | * Fill in skb descriptor | 61 | * Fill in skb descriptor |
105 | */ | 62 | */ |
106 | desc = get_skb_desc(skb); | 63 | skbdesc = get_skb_frame_desc(skb); |
107 | desc->desc_len = ring->desc_size; | 64 | skbdesc->data = skb->data; |
108 | desc->data_len = skb->len; | 65 | skbdesc->data_len = skb->len; |
109 | desc->desc = entry->priv; | 66 | skbdesc->desc = priv_tx->desc; |
110 | desc->data = skb->data; | 67 | skbdesc->desc_len = queue->desc_size; |
111 | desc->ring = ring; | 68 | skbdesc->entry = entry; |
112 | desc->entry = entry; | 69 | |
113 | 70 | memcpy(priv_tx->data, skb->data, skb->len); | |
114 | memcpy(entry->data_addr, skb->data, skb->len); | ||
115 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 71 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
116 | 72 | ||
117 | rt2x00_ring_index_inc(ring); | 73 | rt2x00queue_index_inc(queue, Q_INDEX); |
118 | 74 | ||
119 | return 0; | 75 | return 0; |
120 | } | 76 | } |
@@ -125,29 +81,28 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
125 | */ | 81 | */ |
126 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 82 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
127 | { | 83 | { |
128 | struct data_ring *ring = rt2x00dev->rx; | 84 | struct data_queue *queue = rt2x00dev->rx; |
129 | struct data_entry *entry; | 85 | struct queue_entry *entry; |
130 | struct sk_buff *skb; | 86 | struct queue_entry_priv_pci_rx *priv_rx; |
131 | struct ieee80211_hdr *hdr; | 87 | struct ieee80211_hdr *hdr; |
132 | struct skb_desc *skbdesc; | 88 | struct skb_frame_desc *skbdesc; |
133 | struct rxdata_entry_desc desc; | 89 | struct rxdone_entry_desc rxdesc; |
134 | int header_size; | 90 | int header_size; |
135 | __le32 *rxd; | ||
136 | int align; | 91 | int align; |
137 | u32 word; | 92 | u32 word; |
138 | 93 | ||
139 | while (1) { | 94 | while (1) { |
140 | entry = rt2x00_get_data_entry(ring); | 95 | entry = rt2x00queue_get_entry(queue, Q_INDEX); |
141 | rxd = entry->priv; | 96 | priv_rx = entry->priv_data; |
142 | rt2x00_desc_read(rxd, 0, &word); | 97 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
143 | 98 | ||
144 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 99 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
145 | break; | 100 | break; |
146 | 101 | ||
147 | memset(&desc, 0, sizeof(desc)); | 102 | memset(&rxdesc, 0, sizeof(rxdesc)); |
148 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 103 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
149 | 104 | ||
150 | hdr = (struct ieee80211_hdr *)entry->data_addr; | 105 | hdr = (struct ieee80211_hdr *)priv_rx->data; |
151 | header_size = | 106 | header_size = |
152 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 107 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); |
153 | 108 | ||
@@ -161,66 +116,68 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
161 | * Allocate the sk_buffer, initialize it and copy | 116 | * Allocate the sk_buffer, initialize it and copy |
162 | * all data into it. | 117 | * all data into it. |
163 | */ | 118 | */ |
164 | skb = dev_alloc_skb(desc.size + align); | 119 | entry->skb = dev_alloc_skb(rxdesc.size + align); |
165 | if (!skb) | 120 | if (!entry->skb) |
166 | return; | 121 | return; |
167 | 122 | ||
168 | skb_reserve(skb, align); | 123 | skb_reserve(entry->skb, align); |
169 | memcpy(skb_put(skb, desc.size), entry->data_addr, desc.size); | 124 | memcpy(skb_put(entry->skb, rxdesc.size), |
125 | priv_rx->data, rxdesc.size); | ||
170 | 126 | ||
171 | /* | 127 | /* |
172 | * Fill in skb descriptor | 128 | * Fill in skb descriptor |
173 | */ | 129 | */ |
174 | skbdesc = get_skb_desc(skb); | 130 | skbdesc = get_skb_frame_desc(entry->skb); |
175 | skbdesc->desc_len = entry->ring->desc_size; | 131 | memset(skbdesc, 0, sizeof(*skbdesc)); |
176 | skbdesc->data_len = skb->len; | 132 | skbdesc->data = entry->skb->data; |
177 | skbdesc->desc = entry->priv; | 133 | skbdesc->data_len = entry->skb->len; |
178 | skbdesc->data = skb->data; | 134 | skbdesc->desc = priv_rx->desc; |
179 | skbdesc->ring = ring; | 135 | skbdesc->desc_len = queue->desc_size; |
180 | skbdesc->entry = entry; | 136 | skbdesc->entry = entry; |
181 | 137 | ||
182 | /* | 138 | /* |
183 | * Send the frame to rt2x00lib for further processing. | 139 | * Send the frame to rt2x00lib for further processing. |
184 | */ | 140 | */ |
185 | rt2x00lib_rxdone(entry, skb, &desc); | 141 | rt2x00lib_rxdone(entry, &rxdesc); |
186 | 142 | ||
187 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 143 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { |
188 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | 144 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); |
189 | rt2x00_desc_write(rxd, 0, word); | 145 | rt2x00_desc_write(priv_rx->desc, 0, word); |
190 | } | 146 | } |
191 | 147 | ||
192 | rt2x00_ring_index_inc(ring); | 148 | rt2x00queue_index_inc(queue, Q_INDEX); |
193 | } | 149 | } |
194 | } | 150 | } |
195 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 151 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
196 | 152 | ||
197 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 153 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, |
198 | const int tx_status, const int retry) | 154 | struct txdone_entry_desc *txdesc) |
199 | { | 155 | { |
156 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | ||
200 | u32 word; | 157 | u32 word; |
201 | 158 | ||
202 | rt2x00lib_txdone(entry, tx_status, retry); | 159 | txdesc->control = &priv_tx->control; |
160 | rt2x00lib_txdone(entry, txdesc); | ||
203 | 161 | ||
204 | /* | 162 | /* |
205 | * Make this entry available for reuse. | 163 | * Make this entry available for reuse. |
206 | */ | 164 | */ |
207 | entry->flags = 0; | 165 | entry->flags = 0; |
208 | 166 | ||
209 | rt2x00_desc_read(entry->priv, 0, &word); | 167 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
210 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | 168 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); |
211 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 169 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
212 | rt2x00_desc_write(entry->priv, 0, word); | 170 | rt2x00_desc_write(priv_tx->desc, 0, word); |
213 | 171 | ||
214 | rt2x00_ring_index_done_inc(entry->ring); | 172 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
215 | 173 | ||
216 | /* | 174 | /* |
217 | * If the data ring was full before the txdone handler | 175 | * If the data queue was full before the txdone handler |
218 | * we must make sure the packet queue in the mac80211 stack | 176 | * we must make sure the packet queue in the mac80211 stack |
219 | * is reenabled when the txdone handler has finished. | 177 | * is reenabled when the txdone handler has finished. |
220 | */ | 178 | */ |
221 | if (!rt2x00_ring_full(entry->ring)) | 179 | if (!rt2x00queue_full(entry->queue)) |
222 | ieee80211_wake_queue(rt2x00dev->hw, | 180 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
223 | entry->tx_status.control.queue); | ||
224 | 181 | ||
225 | } | 182 | } |
226 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | 183 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); |
@@ -228,73 +185,122 @@ EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | |||
228 | /* | 185 | /* |
229 | * Device initialization handlers. | 186 | * Device initialization handlers. |
230 | */ | 187 | */ |
231 | #define priv_offset(__ring, __i) \ | 188 | #define desc_size(__queue) \ |
232 | ({ \ | 189 | ({ \ |
233 | ring->data_addr + (i * ring->desc_size); \ | 190 | ((__queue)->limit * (__queue)->desc_size);\ |
191 | }) | ||
192 | |||
193 | #define data_size(__queue) \ | ||
194 | ({ \ | ||
195 | ((__queue)->limit * (__queue)->data_size);\ | ||
234 | }) | 196 | }) |
235 | 197 | ||
236 | #define data_addr_offset(__ring, __i) \ | 198 | #define dma_size(__queue) \ |
237 | ({ \ | 199 | ({ \ |
238 | (__ring)->data_addr + \ | 200 | data_size(__queue) + desc_size(__queue);\ |
239 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | ||
240 | ((__i) * (__ring)->data_size); \ | ||
241 | }) | 201 | }) |
242 | 202 | ||
243 | #define data_dma_offset(__ring, __i) \ | 203 | #define desc_offset(__queue, __base, __i) \ |
244 | ({ \ | 204 | ({ \ |
245 | (__ring)->data_dma + \ | 205 | (__base) + data_size(__queue) + \ |
246 | ((__ring)->stats.limit * (__ring)->desc_size) + \ | 206 | ((__i) * (__queue)->desc_size); \ |
247 | ((__i) * (__ring)->data_size); \ | ||
248 | }) | 207 | }) |
249 | 208 | ||
250 | static int rt2x00pci_alloc_dma(struct rt2x00_dev *rt2x00dev, | 209 | #define data_offset(__queue, __base, __i) \ |
251 | struct data_ring *ring) | 210 | ({ \ |
211 | (__base) + \ | ||
212 | ((__i) * (__queue)->data_size); \ | ||
213 | }) | ||
214 | |||
215 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | ||
216 | struct data_queue *queue) | ||
252 | { | 217 | { |
218 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
219 | struct queue_entry_priv_pci_rx *priv_rx; | ||
220 | struct queue_entry_priv_pci_tx *priv_tx; | ||
221 | void *addr; | ||
222 | dma_addr_t dma; | ||
223 | void *desc_addr; | ||
224 | dma_addr_t desc_dma; | ||
225 | void *data_addr; | ||
226 | dma_addr_t data_dma; | ||
253 | unsigned int i; | 227 | unsigned int i; |
254 | 228 | ||
255 | /* | 229 | /* |
256 | * Allocate DMA memory for descriptor and buffer. | 230 | * Allocate DMA memory for descriptor and buffer. |
257 | */ | 231 | */ |
258 | ring->data_addr = pci_alloc_consistent(rt2x00dev_pci(rt2x00dev), | 232 | addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); |
259 | rt2x00_get_ring_size(ring), | 233 | if (!addr) |
260 | &ring->data_dma); | ||
261 | if (!ring->data_addr) | ||
262 | return -ENOMEM; | 234 | return -ENOMEM; |
263 | 235 | ||
236 | memset(addr, 0, dma_size(queue)); | ||
237 | |||
264 | /* | 238 | /* |
265 | * Initialize all ring entries to contain valid | 239 | * Initialize all queue entries to contain valid addresses. |
266 | * addresses. | ||
267 | */ | 240 | */ |
268 | for (i = 0; i < ring->stats.limit; i++) { | 241 | for (i = 0; i < queue->limit; i++) { |
269 | ring->entry[i].priv = priv_offset(ring, i); | 242 | desc_addr = desc_offset(queue, addr, i); |
270 | ring->entry[i].data_addr = data_addr_offset(ring, i); | 243 | desc_dma = desc_offset(queue, dma, i); |
271 | ring->entry[i].data_dma = data_dma_offset(ring, i); | 244 | data_addr = data_offset(queue, addr, i); |
245 | data_dma = data_offset(queue, dma, i); | ||
246 | |||
247 | if (queue->qid == QID_RX) { | ||
248 | priv_rx = queue->entries[i].priv_data; | ||
249 | priv_rx->desc = desc_addr; | ||
250 | priv_rx->desc_dma = desc_dma; | ||
251 | priv_rx->data = data_addr; | ||
252 | priv_rx->data_dma = data_dma; | ||
253 | } else { | ||
254 | priv_tx = queue->entries[i].priv_data; | ||
255 | priv_tx->desc = desc_addr; | ||
256 | priv_tx->desc_dma = desc_dma; | ||
257 | priv_tx->data = data_addr; | ||
258 | priv_tx->data_dma = data_dma; | ||
259 | } | ||
272 | } | 260 | } |
273 | 261 | ||
274 | return 0; | 262 | return 0; |
275 | } | 263 | } |
276 | 264 | ||
277 | static void rt2x00pci_free_dma(struct rt2x00_dev *rt2x00dev, | 265 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
278 | struct data_ring *ring) | 266 | struct data_queue *queue) |
279 | { | 267 | { |
280 | if (ring->data_addr) | 268 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
281 | pci_free_consistent(rt2x00dev_pci(rt2x00dev), | 269 | struct queue_entry_priv_pci_rx *priv_rx; |
282 | rt2x00_get_ring_size(ring), | 270 | struct queue_entry_priv_pci_tx *priv_tx; |
283 | ring->data_addr, ring->data_dma); | 271 | void *data_addr; |
284 | ring->data_addr = NULL; | 272 | dma_addr_t data_dma; |
273 | |||
274 | if (queue->qid == QID_RX) { | ||
275 | priv_rx = queue->entries[0].priv_data; | ||
276 | data_addr = priv_rx->data; | ||
277 | data_dma = priv_rx->data_dma; | ||
278 | |||
279 | priv_rx->data = NULL; | ||
280 | } else { | ||
281 | priv_tx = queue->entries[0].priv_data; | ||
282 | data_addr = priv_tx->data; | ||
283 | data_dma = priv_tx->data_dma; | ||
284 | |||
285 | priv_tx->data = NULL; | ||
286 | } | ||
287 | |||
288 | if (data_addr) | ||
289 | pci_free_consistent(pci_dev, dma_size(queue), | ||
290 | data_addr, data_dma); | ||
285 | } | 291 | } |
286 | 292 | ||
287 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 293 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
288 | { | 294 | { |
289 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 295 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
290 | struct data_ring *ring; | 296 | struct data_queue *queue; |
291 | int status; | 297 | int status; |
292 | 298 | ||
293 | /* | 299 | /* |
294 | * Allocate DMA | 300 | * Allocate DMA |
295 | */ | 301 | */ |
296 | ring_for_each(rt2x00dev, ring) { | 302 | queue_for_each(rt2x00dev, queue) { |
297 | status = rt2x00pci_alloc_dma(rt2x00dev, ring); | 303 | status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue); |
298 | if (status) | 304 | if (status) |
299 | goto exit; | 305 | goto exit; |
300 | } | 306 | } |
@@ -321,7 +327,7 @@ EXPORT_SYMBOL_GPL(rt2x00pci_initialize); | |||
321 | 327 | ||
322 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | 328 | void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) |
323 | { | 329 | { |
324 | struct data_ring *ring; | 330 | struct data_queue *queue; |
325 | 331 | ||
326 | /* | 332 | /* |
327 | * Free irq line. | 333 | * Free irq line. |
@@ -331,8 +337,8 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
331 | /* | 337 | /* |
332 | * Free DMA | 338 | * Free DMA |
333 | */ | 339 | */ |
334 | ring_for_each(rt2x00dev, ring) | 340 | queue_for_each(rt2x00dev, queue) |
335 | rt2x00pci_free_dma(rt2x00dev, ring); | 341 | rt2x00pci_free_queue_dma(rt2x00dev, queue); |
336 | } | 342 | } |
337 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); | 343 | EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize); |
338 | 344 | ||
@@ -347,9 +353,9 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | |||
347 | kfree(rt2x00dev->eeprom); | 353 | kfree(rt2x00dev->eeprom); |
348 | rt2x00dev->eeprom = NULL; | 354 | rt2x00dev->eeprom = NULL; |
349 | 355 | ||
350 | if (rt2x00dev->csr_addr) { | 356 | if (rt2x00dev->csr.base) { |
351 | iounmap(rt2x00dev->csr_addr); | 357 | iounmap(rt2x00dev->csr.base); |
352 | rt2x00dev->csr_addr = NULL; | 358 | rt2x00dev->csr.base = NULL; |
353 | } | 359 | } |
354 | } | 360 | } |
355 | 361 | ||
@@ -357,9 +363,9 @@ static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | |||
357 | { | 363 | { |
358 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 364 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); |
359 | 365 | ||
360 | rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0), | 366 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), |
361 | pci_resource_len(pci_dev, 0)); | 367 | pci_resource_len(pci_dev, 0)); |
362 | if (!rt2x00dev->csr_addr) | 368 | if (!rt2x00dev->csr.base) |
363 | goto exit; | 369 | goto exit; |
364 | 370 | ||
365 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 371 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -530,5 +536,5 @@ EXPORT_SYMBOL_GPL(rt2x00pci_resume); | |||
530 | */ | 536 | */ |
531 | MODULE_AUTHOR(DRV_PROJECT); | 537 | MODULE_AUTHOR(DRV_PROJECT); |
532 | MODULE_VERSION(DRV_VERSION); | 538 | MODULE_VERSION(DRV_VERSION); |
533 | MODULE_DESCRIPTION("rt2x00 library"); | 539 | MODULE_DESCRIPTION("rt2x00 pci library"); |
534 | MODULE_LICENSE("GPL"); | 540 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 2d1eb8144da4..9d1cdb99431c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -61,7 +61,7 @@ static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, | |||
61 | const unsigned long offset, | 61 | const unsigned long offset, |
62 | u32 *value) | 62 | u32 *value) |
63 | { | 63 | { |
64 | *value = readl(rt2x00dev->csr_addr + offset); | 64 | *value = readl(rt2x00dev->csr.base + offset); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void | 67 | static inline void |
@@ -69,14 +69,14 @@ rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, | |||
69 | const unsigned long offset, | 69 | const unsigned long offset, |
70 | void *value, const u16 length) | 70 | void *value, const u16 length) |
71 | { | 71 | { |
72 | memcpy_fromio(value, rt2x00dev->csr_addr + offset, length); | 72 | memcpy_fromio(value, rt2x00dev->csr.base + offset, length); |
73 | } | 73 | } |
74 | 74 | ||
75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, | 75 | static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, |
76 | const unsigned long offset, | 76 | const unsigned long offset, |
77 | u32 value) | 77 | u32 value) |
78 | { | 78 | { |
79 | writel(value, rt2x00dev->csr_addr + offset); | 79 | writel(value, rt2x00dev->csr.base + offset); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void | 82 | static inline void |
@@ -84,28 +84,63 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
84 | const unsigned long offset, | 84 | const unsigned long offset, |
85 | void *value, const u16 length) | 85 | void *value, const u16 length) |
86 | { | 86 | { |
87 | memcpy_toio(rt2x00dev->csr_addr + offset, value, length); | 87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /* |
91 | * Beacon handlers. | ||
92 | */ | ||
93 | int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
94 | struct ieee80211_tx_control *control); | ||
95 | |||
96 | /* | ||
97 | * TX data handlers. | 91 | * TX data handlers. |
98 | */ | 92 | */ |
99 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 93 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, |
100 | struct data_ring *ring, struct sk_buff *skb, | 94 | struct data_queue *queue, struct sk_buff *skb, |
101 | struct ieee80211_tx_control *control); | 95 | struct ieee80211_tx_control *control); |
102 | 96 | ||
103 | /* | 97 | /** |
104 | * RX/TX data handlers. | 98 | * struct queue_entry_priv_pci_rx: Per RX entry PCI specific information |
99 | * | ||
100 | * @desc: Pointer to device descriptor. | ||
101 | * @data: Pointer to device's entry memory. | ||
102 | * @dma: DMA pointer to &data. | ||
103 | */ | ||
104 | struct queue_entry_priv_pci_rx { | ||
105 | __le32 *desc; | ||
106 | dma_addr_t desc_dma; | ||
107 | |||
108 | void *data; | ||
109 | dma_addr_t data_dma; | ||
110 | }; | ||
111 | |||
112 | /** | ||
113 | * struct queue_entry_priv_pci_tx: Per TX entry PCI specific information | ||
114 | * | ||
115 | * @desc: Pointer to device descriptor | ||
116 | * @data: Pointer to device's entry memory. | ||
117 | * @dma: DMA pointer to &data. | ||
118 | * @control: mac80211 control structure used to transmit data. | ||
119 | */ | ||
120 | struct queue_entry_priv_pci_tx { | ||
121 | __le32 *desc; | ||
122 | dma_addr_t desc_dma; | ||
123 | |||
124 | void *data; | ||
125 | dma_addr_t data_dma; | ||
126 | |||
127 | struct ieee80211_tx_control control; | ||
128 | }; | ||
129 | |||
130 | /** | ||
131 | * rt2x00pci_rxdone - Handle RX done events | ||
132 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
105 | */ | 133 | */ |
106 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 134 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); |
107 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, | 135 | |
108 | const int tx_status, const int retry); | 136 | /** |
137 | * rt2x00pci_txdone - Handle TX done events | ||
138 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
139 | * @entry: Entry which has completed the transmission of a frame. | ||
140 | * @desc: TX done descriptor | ||
141 | */ | ||
142 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
143 | struct txdone_entry_desc *desc); | ||
109 | 144 | ||
110 | /* | 145 | /* |
111 | * Device initialization handlers. | 146 | * Device initialization handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c new file mode 100644 index 000000000000..9188323f067b --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00lib | ||
23 | Abstract: rt2x00 queue specific routines. | ||
24 | */ | ||
25 | |||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include "rt2x00.h" | ||
30 | #include "rt2x00lib.h" | ||
31 | |||
32 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | ||
33 | const unsigned int queue) | ||
34 | { | ||
35 | int atim = test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
36 | |||
37 | if (queue < rt2x00dev->hw->queues && rt2x00dev->tx) | ||
38 | return &rt2x00dev->tx[queue]; | ||
39 | |||
40 | if (!rt2x00dev->bcn) | ||
41 | return NULL; | ||
42 | |||
43 | if (queue == RT2X00_BCN_QUEUE_BEACON) | ||
44 | return &rt2x00dev->bcn[0]; | ||
45 | else if (queue == RT2X00_BCN_QUEUE_ATIM && atim) | ||
46 | return &rt2x00dev->bcn[1]; | ||
47 | |||
48 | return NULL; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(rt2x00queue_get_queue); | ||
51 | |||
52 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | ||
53 | enum queue_index index) | ||
54 | { | ||
55 | struct queue_entry *entry; | ||
56 | |||
57 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
58 | ERROR(queue->rt2x00dev, | ||
59 | "Entry requested from invalid index type (%d)\n", index); | ||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | spin_lock(&queue->lock); | ||
64 | |||
65 | entry = &queue->entries[queue->index[index]]; | ||
66 | |||
67 | spin_unlock(&queue->lock); | ||
68 | |||
69 | return entry; | ||
70 | } | ||
71 | EXPORT_SYMBOL_GPL(rt2x00queue_get_entry); | ||
72 | |||
73 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | ||
74 | { | ||
75 | if (unlikely(index >= Q_INDEX_MAX)) { | ||
76 | ERROR(queue->rt2x00dev, | ||
77 | "Index change on invalid index type (%d)\n", index); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | spin_lock(&queue->lock); | ||
82 | |||
83 | queue->index[index]++; | ||
84 | if (queue->index[index] >= queue->limit) | ||
85 | queue->index[index] = 0; | ||
86 | |||
87 | if (index == Q_INDEX) { | ||
88 | queue->length++; | ||
89 | } else if (index == Q_INDEX_DONE) { | ||
90 | queue->length--; | ||
91 | queue->count ++; | ||
92 | } | ||
93 | |||
94 | spin_unlock(&queue->lock); | ||
95 | } | ||
96 | EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); | ||
97 | |||
98 | static void rt2x00queue_reset(struct data_queue *queue) | ||
99 | { | ||
100 | spin_lock(&queue->lock); | ||
101 | |||
102 | queue->count = 0; | ||
103 | queue->length = 0; | ||
104 | memset(queue->index, 0, sizeof(queue->index)); | ||
105 | |||
106 | spin_unlock(&queue->lock); | ||
107 | } | ||
108 | |||
109 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) | ||
110 | { | ||
111 | struct data_queue *queue = rt2x00dev->rx; | ||
112 | unsigned int i; | ||
113 | |||
114 | rt2x00queue_reset(queue); | ||
115 | |||
116 | if (!rt2x00dev->ops->lib->init_rxentry) | ||
117 | return; | ||
118 | |||
119 | for (i = 0; i < queue->limit; i++) | ||
120 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, | ||
121 | &queue->entries[i]); | ||
122 | } | ||
123 | |||
124 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev) | ||
125 | { | ||
126 | struct data_queue *queue; | ||
127 | unsigned int i; | ||
128 | |||
129 | txall_queue_for_each(rt2x00dev, queue) { | ||
130 | rt2x00queue_reset(queue); | ||
131 | |||
132 | if (!rt2x00dev->ops->lib->init_txentry) | ||
133 | continue; | ||
134 | |||
135 | for (i = 0; i < queue->limit; i++) | ||
136 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, | ||
137 | &queue->entries[i]); | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static int rt2x00queue_alloc_entries(struct data_queue *queue, | ||
142 | const struct data_queue_desc *qdesc) | ||
143 | { | ||
144 | struct queue_entry *entries; | ||
145 | unsigned int entry_size; | ||
146 | unsigned int i; | ||
147 | |||
148 | rt2x00queue_reset(queue); | ||
149 | |||
150 | queue->limit = qdesc->entry_num; | ||
151 | queue->data_size = qdesc->data_size; | ||
152 | queue->desc_size = qdesc->desc_size; | ||
153 | |||
154 | /* | ||
155 | * Allocate all queue entries. | ||
156 | */ | ||
157 | entry_size = sizeof(*entries) + qdesc->priv_size; | ||
158 | entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); | ||
159 | if (!entries) | ||
160 | return -ENOMEM; | ||
161 | |||
162 | #define QUEUE_ENTRY_PRIV_OFFSET(__base, __index, __limit, __esize, __psize) \ | ||
163 | ( ((char *)(__base)) + ((__limit) * (__esize)) + \ | ||
164 | ((__index) * (__psize)) ) | ||
165 | |||
166 | for (i = 0; i < queue->limit; i++) { | ||
167 | entries[i].flags = 0; | ||
168 | entries[i].queue = queue; | ||
169 | entries[i].skb = NULL; | ||
170 | entries[i].entry_idx = i; | ||
171 | entries[i].priv_data = | ||
172 | QUEUE_ENTRY_PRIV_OFFSET(entries, i, queue->limit, | ||
173 | sizeof(*entries), qdesc->priv_size); | ||
174 | } | ||
175 | |||
176 | #undef QUEUE_ENTRY_PRIV_OFFSET | ||
177 | |||
178 | queue->entries = entries; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | ||
184 | { | ||
185 | struct data_queue *queue; | ||
186 | int status; | ||
187 | |||
188 | |||
189 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | ||
190 | if (status) | ||
191 | goto exit; | ||
192 | |||
193 | tx_queue_for_each(rt2x00dev, queue) { | ||
194 | status = rt2x00queue_alloc_entries(queue, rt2x00dev->ops->tx); | ||
195 | if (status) | ||
196 | goto exit; | ||
197 | } | ||
198 | |||
199 | status = rt2x00queue_alloc_entries(rt2x00dev->bcn, rt2x00dev->ops->bcn); | ||
200 | if (status) | ||
201 | goto exit; | ||
202 | |||
203 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
204 | return 0; | ||
205 | |||
206 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | ||
207 | rt2x00dev->ops->atim); | ||
208 | if (status) | ||
209 | goto exit; | ||
210 | |||
211 | return 0; | ||
212 | |||
213 | exit: | ||
214 | ERROR(rt2x00dev, "Queue entries allocation failed.\n"); | ||
215 | |||
216 | rt2x00queue_uninitialize(rt2x00dev); | ||
217 | |||
218 | return status; | ||
219 | } | ||
220 | |||
221 | void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | ||
222 | { | ||
223 | struct data_queue *queue; | ||
224 | |||
225 | queue_for_each(rt2x00dev, queue) { | ||
226 | kfree(queue->entries); | ||
227 | queue->entries = NULL; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | static void rt2x00queue_init(struct rt2x00_dev *rt2x00dev, | ||
232 | struct data_queue *queue, enum data_queue_qid qid) | ||
233 | { | ||
234 | spin_lock_init(&queue->lock); | ||
235 | |||
236 | queue->rt2x00dev = rt2x00dev; | ||
237 | queue->qid = qid; | ||
238 | queue->aifs = 2; | ||
239 | queue->cw_min = 5; | ||
240 | queue->cw_max = 10; | ||
241 | } | ||
242 | |||
243 | int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | ||
244 | { | ||
245 | struct data_queue *queue; | ||
246 | enum data_queue_qid qid; | ||
247 | unsigned int req_atim = | ||
248 | !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | ||
249 | |||
250 | /* | ||
251 | * We need the following queues: | ||
252 | * RX: 1 | ||
253 | * TX: hw->queues | ||
254 | * Beacon: 1 | ||
255 | * Atim: 1 (if required) | ||
256 | */ | ||
257 | rt2x00dev->data_queues = 2 + rt2x00dev->hw->queues + req_atim; | ||
258 | |||
259 | queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); | ||
260 | if (!queue) { | ||
261 | ERROR(rt2x00dev, "Queue allocation failed.\n"); | ||
262 | return -ENOMEM; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * Initialize pointers | ||
267 | */ | ||
268 | rt2x00dev->rx = queue; | ||
269 | rt2x00dev->tx = &queue[1]; | ||
270 | rt2x00dev->bcn = &queue[1 + rt2x00dev->hw->queues]; | ||
271 | |||
272 | /* | ||
273 | * Initialize queue parameters. | ||
274 | * RX: qid = QID_RX | ||
275 | * TX: qid = QID_AC_BE + index | ||
276 | * TX: cw_min: 2^5 = 32. | ||
277 | * TX: cw_max: 2^10 = 1024. | ||
278 | * BCN & Atim: qid = QID_MGMT | ||
279 | */ | ||
280 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); | ||
281 | |||
282 | qid = QID_AC_BE; | ||
283 | tx_queue_for_each(rt2x00dev, queue) | ||
284 | rt2x00queue_init(rt2x00dev, queue, qid++); | ||
285 | |||
286 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); | ||
287 | if (req_atim) | ||
288 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | void rt2x00queue_free(struct rt2x00_dev *rt2x00dev) | ||
294 | { | ||
295 | kfree(rt2x00dev->rx); | ||
296 | rt2x00dev->rx = NULL; | ||
297 | rt2x00dev->tx = NULL; | ||
298 | rt2x00dev->bcn = NULL; | ||
299 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h new file mode 100644 index 000000000000..fbabf389b622 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -0,0 +1,457 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 queue datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00QUEUE_H | ||
27 | #define RT2X00QUEUE_H | ||
28 | |||
29 | #include <linux/prefetch.h> | ||
30 | |||
31 | /** | ||
32 | * DOC: Entrie frame size | ||
33 | * | ||
34 | * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes, | ||
35 | * for USB devices this restriction does not apply, but the value of | ||
36 | * 2432 makes sense since it is big enough to contain the maximum fragment | ||
37 | * size according to the ieee802.11 specs. | ||
38 | */ | ||
39 | #define DATA_FRAME_SIZE 2432 | ||
40 | #define MGMT_FRAME_SIZE 256 | ||
41 | |||
42 | /** | ||
43 | * DOC: Number of entries per queue | ||
44 | * | ||
45 | * After research it was concluded that 12 entries in a RX and TX | ||
46 | * queue would be sufficient. Although this is almost one third of | ||
47 | * the amount the legacy driver allocated, the queues aren't getting | ||
48 | * filled to the maximum even when working with the maximum rate. | ||
49 | */ | ||
50 | #define RX_ENTRIES 12 | ||
51 | #define TX_ENTRIES 12 | ||
52 | #define BEACON_ENTRIES 1 | ||
53 | #define ATIM_ENTRIES 1 | ||
54 | |||
55 | /** | ||
56 | * enum data_queue_qid: Queue identification | ||
57 | */ | ||
58 | enum data_queue_qid { | ||
59 | QID_AC_BE = 0, | ||
60 | QID_AC_BK = 1, | ||
61 | QID_AC_VI = 2, | ||
62 | QID_AC_VO = 3, | ||
63 | QID_HCCA = 4, | ||
64 | QID_MGMT = 13, | ||
65 | QID_RX = 14, | ||
66 | QID_OTHER = 15, | ||
67 | }; | ||
68 | |||
69 | /** | ||
70 | * enum rt2x00_bcn_queue: Beacon queue index | ||
71 | * | ||
72 | * Start counting with a high offset, this because this enumeration | ||
73 | * supplements &enum ieee80211_tx_queue and we should prevent value | ||
74 | * conflicts. | ||
75 | * | ||
76 | * @RT2X00_BCN_QUEUE_BEACON: Beacon queue | ||
77 | * @RT2X00_BCN_QUEUE_ATIM: Atim queue (sends frame after beacon) | ||
78 | */ | ||
79 | enum rt2x00_bcn_queue { | ||
80 | RT2X00_BCN_QUEUE_BEACON = 100, | ||
81 | RT2X00_BCN_QUEUE_ATIM = 101, | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | ||
86 | * | ||
87 | * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver | ||
88 | * and should not be reported back to mac80211 during txdone. | ||
89 | */ | ||
90 | enum skb_frame_desc_flags { | ||
91 | FRAME_DESC_DRIVER_GENERATED = 1 << 0, | ||
92 | }; | ||
93 | |||
94 | /** | ||
95 | * struct skb_frame_desc: Descriptor information for the skb buffer | ||
96 | * | ||
97 | * This structure is placed over the skb->cb array, this means that | ||
98 | * this structure should not exceed the size of that array (48 bytes). | ||
99 | * | ||
100 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | ||
101 | * @frame_type: Frame type, see &enum rt2x00_dump_type. | ||
102 | * @data: Pointer to data part of frame (Start of ieee80211 header). | ||
103 | * @desc: Pointer to descriptor part of the frame. | ||
104 | * Note that this pointer could point to something outside | ||
105 | * of the scope of the skb->data pointer. | ||
106 | * @data_len: Length of the frame data. | ||
107 | * @desc_len: Length of the frame descriptor. | ||
108 | |||
109 | * @entry: The entry to which this sk buffer belongs. | ||
110 | */ | ||
111 | struct skb_frame_desc { | ||
112 | unsigned int flags; | ||
113 | |||
114 | unsigned int frame_type; | ||
115 | |||
116 | void *data; | ||
117 | void *desc; | ||
118 | |||
119 | unsigned int data_len; | ||
120 | unsigned int desc_len; | ||
121 | |||
122 | struct queue_entry *entry; | ||
123 | }; | ||
124 | |||
125 | static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb) | ||
126 | { | ||
127 | BUILD_BUG_ON(sizeof(struct skb_frame_desc) > sizeof(skb->cb)); | ||
128 | return (struct skb_frame_desc *)&skb->cb[0]; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * struct rxdone_entry_desc: RX Entry descriptor | ||
133 | * | ||
134 | * Summary of information that has been read from the RX frame descriptor. | ||
135 | * | ||
136 | * @signal: Signal of the received frame. | ||
137 | * @rssi: RSSI of the received frame. | ||
138 | * @ofdm: Was frame send with an OFDM rate. | ||
139 | * @size: Data size of the received frame. | ||
140 | * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags). | ||
141 | * @my_bss: Does this frame originate from device's BSS. | ||
142 | */ | ||
143 | struct rxdone_entry_desc { | ||
144 | int signal; | ||
145 | int rssi; | ||
146 | int ofdm; | ||
147 | int size; | ||
148 | int flags; | ||
149 | int my_bss; | ||
150 | }; | ||
151 | |||
152 | /** | ||
153 | * struct txdone_entry_desc: TX done entry descriptor | ||
154 | * | ||
155 | * Summary of information that has been read from the TX frame descriptor | ||
156 | * after the device is done with transmission. | ||
157 | * | ||
158 | * @control: Control structure which was used to transmit the frame. | ||
159 | * @status: TX status (See &enum tx_status). | ||
160 | * @retry: Retry count. | ||
161 | */ | ||
162 | struct txdone_entry_desc { | ||
163 | struct ieee80211_tx_control *control; | ||
164 | int status; | ||
165 | int retry; | ||
166 | }; | ||
167 | |||
168 | /** | ||
169 | * enum txentry_desc_flags: Status flags for TX entry descriptor | ||
170 | * | ||
171 | * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame. | ||
172 | * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate. | ||
173 | * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment. | ||
174 | * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted. | ||
175 | * @ENTRY_TXD_BURST: This frame belongs to the same burst event. | ||
176 | * @ENTRY_TXD_ACK: An ACK is required for this frame. | ||
177 | */ | ||
178 | enum txentry_desc_flags { | ||
179 | ENTRY_TXD_RTS_FRAME, | ||
180 | ENTRY_TXD_OFDM_RATE, | ||
181 | ENTRY_TXD_MORE_FRAG, | ||
182 | ENTRY_TXD_REQ_TIMESTAMP, | ||
183 | ENTRY_TXD_BURST, | ||
184 | ENTRY_TXD_ACK, | ||
185 | }; | ||
186 | |||
187 | /** | ||
188 | * struct txentry_desc: TX Entry descriptor | ||
189 | * | ||
190 | * Summary of information for the frame descriptor before sending a TX frame. | ||
191 | * | ||
192 | * @flags: Descriptor flags (See &enum queue_entry_flags). | ||
193 | * @queue: Queue identification (See &enum data_queue_qid). | ||
194 | * @length_high: PLCP length high word. | ||
195 | * @length_low: PLCP length low word. | ||
196 | * @signal: PLCP signal. | ||
197 | * @service: PLCP service. | ||
198 | * @aifs: AIFS value. | ||
199 | * @ifs: IFS value. | ||
200 | * @cw_min: cwmin value. | ||
201 | * @cw_max: cwmax value. | ||
202 | */ | ||
203 | struct txentry_desc { | ||
204 | unsigned long flags; | ||
205 | |||
206 | enum data_queue_qid queue; | ||
207 | |||
208 | u16 length_high; | ||
209 | u16 length_low; | ||
210 | u16 signal; | ||
211 | u16 service; | ||
212 | |||
213 | int aifs; | ||
214 | int ifs; | ||
215 | int cw_min; | ||
216 | int cw_max; | ||
217 | }; | ||
218 | |||
219 | /** | ||
220 | * enum queue_entry_flags: Status flags for queue entry | ||
221 | * | ||
222 | * @ENTRY_BCN_ASSIGNED: This entry has been assigned to an interface. | ||
223 | * As long as this bit is set, this entry may only be touched | ||
224 | * through the interface structure. | ||
225 | * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data | ||
226 | * transfer (either TX or RX depending on the queue). The entry should | ||
227 | * only be touched after the device has signaled it is done with it. | ||
228 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | ||
229 | * encryption or decryption. The entry should only be touched after | ||
230 | * the device has signaled it is done with it. | ||
231 | */ | ||
232 | |||
233 | enum queue_entry_flags { | ||
234 | ENTRY_BCN_ASSIGNED, | ||
235 | ENTRY_OWNER_DEVICE_DATA, | ||
236 | ENTRY_OWNER_DEVICE_CRYPTO, | ||
237 | }; | ||
238 | |||
239 | /** | ||
240 | * struct queue_entry: Entry inside the &struct data_queue | ||
241 | * | ||
242 | * @flags: Entry flags, see &enum queue_entry_flags. | ||
243 | * @queue: The data queue (&struct data_queue) to which this entry belongs. | ||
244 | * @skb: The buffer which is currently being transmitted (for TX queue), | ||
245 | * or used to directly recieve data in (for RX queue). | ||
246 | * @entry_idx: The entry index number. | ||
247 | * @priv_data: Private data belonging to this queue entry. The pointer | ||
248 | * points to data specific to a particular driver and queue type. | ||
249 | */ | ||
250 | struct queue_entry { | ||
251 | unsigned long flags; | ||
252 | |||
253 | struct data_queue *queue; | ||
254 | |||
255 | struct sk_buff *skb; | ||
256 | |||
257 | unsigned int entry_idx; | ||
258 | |||
259 | void *priv_data; | ||
260 | }; | ||
261 | |||
262 | /** | ||
263 | * enum queue_index: Queue index type | ||
264 | * | ||
265 | * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is | ||
266 | * owned by the hardware then the queue is considered to be full. | ||
267 | * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by | ||
268 | * the hardware and for which we need to run the txdone handler. If this | ||
269 | * entry is not owned by the hardware the queue is considered to be empty. | ||
270 | * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription | ||
271 | * will be completed by the hardware next. | ||
272 | * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size | ||
273 | * of the index array. | ||
274 | */ | ||
275 | enum queue_index { | ||
276 | Q_INDEX, | ||
277 | Q_INDEX_DONE, | ||
278 | Q_INDEX_CRYPTO, | ||
279 | Q_INDEX_MAX, | ||
280 | }; | ||
281 | |||
282 | /** | ||
283 | * struct data_queue: Data queue | ||
284 | * | ||
285 | * @rt2x00dev: Pointer to main &struct rt2x00dev where this queue belongs to. | ||
286 | * @entries: Base address of the &struct queue_entry which are | ||
287 | * part of this queue. | ||
288 | * @qid: The queue identification, see &enum data_queue_qid. | ||
289 | * @lock: Spinlock to protect index handling. Whenever @index, @index_done or | ||
290 | * @index_crypt needs to be changed this lock should be grabbed to prevent | ||
291 | * index corruption due to concurrency. | ||
292 | * @count: Number of frames handled in the queue. | ||
293 | * @limit: Maximum number of entries in the queue. | ||
294 | * @length: Number of frames in queue. | ||
295 | * @index: Index pointers to entry positions in the queue, | ||
296 | * use &enum queue_index to get a specific index field. | ||
297 | * @aifs: The aifs value for outgoing frames (field ignored in RX queue). | ||
298 | * @cw_min: The cw min value for outgoing frames (field ignored in RX queue). | ||
299 | * @cw_max: The cw max value for outgoing frames (field ignored in RX queue). | ||
300 | * @data_size: Maximum data size for the frames in this queue. | ||
301 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
302 | */ | ||
303 | struct data_queue { | ||
304 | struct rt2x00_dev *rt2x00dev; | ||
305 | struct queue_entry *entries; | ||
306 | |||
307 | enum data_queue_qid qid; | ||
308 | |||
309 | spinlock_t lock; | ||
310 | unsigned int count; | ||
311 | unsigned short limit; | ||
312 | unsigned short length; | ||
313 | unsigned short index[Q_INDEX_MAX]; | ||
314 | |||
315 | unsigned short aifs; | ||
316 | unsigned short cw_min; | ||
317 | unsigned short cw_max; | ||
318 | |||
319 | unsigned short data_size; | ||
320 | unsigned short desc_size; | ||
321 | }; | ||
322 | |||
323 | /** | ||
324 | * struct data_queue_desc: Data queue description | ||
325 | * | ||
326 | * The information in this structure is used by drivers | ||
327 | * to inform rt2x00lib about the creation of the data queue. | ||
328 | * | ||
329 | * @entry_num: Maximum number of entries for a queue. | ||
330 | * @data_size: Maximum data size for the frames in this queue. | ||
331 | * @desc_size: Hardware descriptor size for the data in this queue. | ||
332 | * @priv_size: Size of per-queue_entry private data. | ||
333 | */ | ||
334 | struct data_queue_desc { | ||
335 | unsigned short entry_num; | ||
336 | unsigned short data_size; | ||
337 | unsigned short desc_size; | ||
338 | unsigned short priv_size; | ||
339 | }; | ||
340 | |||
341 | /** | ||
342 | * queue_end - Return pointer to the last queue (HELPER MACRO). | ||
343 | * @__dev: Pointer to &struct rt2x00_dev | ||
344 | * | ||
345 | * Using the base rx pointer and the maximum number of available queues, | ||
346 | * this macro will return the address of 1 position beyond the end of the | ||
347 | * queues array. | ||
348 | */ | ||
349 | #define queue_end(__dev) \ | ||
350 | &(__dev)->rx[(__dev)->data_queues] | ||
351 | |||
352 | /** | ||
353 | * tx_queue_end - Return pointer to the last TX queue (HELPER MACRO). | ||
354 | * @__dev: Pointer to &struct rt2x00_dev | ||
355 | * | ||
356 | * Using the base tx pointer and the maximum number of available TX | ||
357 | * queues, this macro will return the address of 1 position beyond | ||
358 | * the end of the TX queue array. | ||
359 | */ | ||
360 | #define tx_queue_end(__dev) \ | ||
361 | &(__dev)->tx[(__dev)->hw->queues] | ||
362 | |||
363 | /** | ||
364 | * queue_loop - Loop through the queues within a specific range (HELPER MACRO). | ||
365 | * @__entry: Pointer where the current queue entry will be stored in. | ||
366 | * @__start: Start queue pointer. | ||
367 | * @__end: End queue pointer. | ||
368 | * | ||
369 | * This macro will loop through all queues between &__start and &__end. | ||
370 | */ | ||
371 | #define queue_loop(__entry, __start, __end) \ | ||
372 | for ((__entry) = (__start); \ | ||
373 | prefetch(&(__entry)[1]), (__entry) != (__end); \ | ||
374 | (__entry) = &(__entry)[1]) | ||
375 | |||
376 | /** | ||
377 | * queue_for_each - Loop through all queues | ||
378 | * @__dev: Pointer to &struct rt2x00_dev | ||
379 | * @__entry: Pointer where the current queue entry will be stored in. | ||
380 | * | ||
381 | * This macro will loop through all available queues. | ||
382 | */ | ||
383 | #define queue_for_each(__dev, __entry) \ | ||
384 | queue_loop(__entry, (__dev)->rx, queue_end(__dev)) | ||
385 | |||
386 | /** | ||
387 | * tx_queue_for_each - Loop through the TX queues | ||
388 | * @__dev: Pointer to &struct rt2x00_dev | ||
389 | * @__entry: Pointer where the current queue entry will be stored in. | ||
390 | * | ||
391 | * This macro will loop through all TX related queues excluding | ||
392 | * the Beacon and Atim queues. | ||
393 | */ | ||
394 | #define tx_queue_for_each(__dev, __entry) \ | ||
395 | queue_loop(__entry, (__dev)->tx, tx_queue_end(__dev)) | ||
396 | |||
397 | /** | ||
398 | * txall_queue_for_each - Loop through all TX related queues | ||
399 | * @__dev: Pointer to &struct rt2x00_dev | ||
400 | * @__entry: Pointer where the current queue entry will be stored in. | ||
401 | * | ||
402 | * This macro will loop through all TX related queues including | ||
403 | * the Beacon and Atim queues. | ||
404 | */ | ||
405 | #define txall_queue_for_each(__dev, __entry) \ | ||
406 | queue_loop(__entry, (__dev)->tx, queue_end(__dev)) | ||
407 | |||
408 | /** | ||
409 | * rt2x00queue_empty - Check if the queue is empty. | ||
410 | * @queue: Queue to check if empty. | ||
411 | */ | ||
412 | static inline int rt2x00queue_empty(struct data_queue *queue) | ||
413 | { | ||
414 | return queue->length == 0; | ||
415 | } | ||
416 | |||
417 | /** | ||
418 | * rt2x00queue_full - Check if the queue is full. | ||
419 | * @queue: Queue to check if full. | ||
420 | */ | ||
421 | static inline int rt2x00queue_full(struct data_queue *queue) | ||
422 | { | ||
423 | return queue->length == queue->limit; | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * rt2x00queue_free - Check the number of available entries in queue. | ||
428 | * @queue: Queue to check. | ||
429 | */ | ||
430 | static inline int rt2x00queue_available(struct data_queue *queue) | ||
431 | { | ||
432 | return queue->limit - queue->length; | ||
433 | } | ||
434 | |||
435 | /** | ||
436 | * rt2x00_desc_read - Read a word from the hardware descriptor. | ||
437 | * @desc: Base descriptor address | ||
438 | * @word: Word index from where the descriptor should be read. | ||
439 | * @value: Address where the descriptor value should be written into. | ||
440 | */ | ||
441 | static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) | ||
442 | { | ||
443 | *value = le32_to_cpu(desc[word]); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * rt2x00_desc_write - wrote a word to the hardware descriptor. | ||
448 | * @desc: Base descriptor address | ||
449 | * @word: Word index from where the descriptor should be written. | ||
450 | * @value: Value that should be written into the descriptor. | ||
451 | */ | ||
452 | static inline void rt2x00_desc_write(__le32 *desc, const u8 word, u32 value) | ||
453 | { | ||
454 | desc[word] = cpu_to_le32(value); | ||
455 | } | ||
456 | |||
457 | #endif /* RT2X00QUEUE_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index b1915dc7dda1..0325bed2fbf5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -29,7 +29,7 @@ | |||
29 | /* | 29 | /* |
30 | * TX result flags. | 30 | * TX result flags. |
31 | */ | 31 | */ |
32 | enum TX_STATUS { | 32 | enum tx_status { |
33 | TX_SUCCESS = 0, | 33 | TX_SUCCESS = 0, |
34 | TX_SUCCESS_RETRY = 1, | 34 | TX_SUCCESS_RETRY = 1, |
35 | TX_FAIL_RETRY = 2, | 35 | TX_FAIL_RETRY = 2, |
@@ -220,75 +220,4 @@ static inline u8 rt2x00_get_field8(const u8 reg, | |||
220 | return (reg & field.bit_mask) >> field.bit_offset; | 220 | return (reg & field.bit_mask) >> field.bit_offset; |
221 | } | 221 | } |
222 | 222 | ||
223 | /* | ||
224 | * Device specific rate value. | ||
225 | * We will have to create the device specific rate value | ||
226 | * passed to the ieee80211 kernel. We need to make it a consist of | ||
227 | * multiple fields because we want to store more then 1 device specific | ||
228 | * values inside the value. | ||
229 | * 1 - rate, stored as 100 kbit/s. | ||
230 | * 2 - preamble, short_preamble enabled flag. | ||
231 | * 3 - MASK_RATE, which rates are enabled in this mode, this mask | ||
232 | * corresponds with the TX register format for the current device. | ||
233 | * 4 - plcp, 802.11b rates are device specific, | ||
234 | * 802.11g rates are set according to the ieee802.11a-1999 p.14. | ||
235 | * The bit to enable preamble is set in a seperate define. | ||
236 | */ | ||
237 | #define DEV_RATE FIELD32(0x000007ff) | ||
238 | #define DEV_PREAMBLE FIELD32(0x00000800) | ||
239 | #define DEV_RATEMASK FIELD32(0x00fff000) | ||
240 | #define DEV_PLCP FIELD32(0xff000000) | ||
241 | |||
242 | /* | ||
243 | * Bitfields | ||
244 | */ | ||
245 | #define DEV_RATEBIT_1MB ( 1 << 0 ) | ||
246 | #define DEV_RATEBIT_2MB ( 1 << 1 ) | ||
247 | #define DEV_RATEBIT_5_5MB ( 1 << 2 ) | ||
248 | #define DEV_RATEBIT_11MB ( 1 << 3 ) | ||
249 | #define DEV_RATEBIT_6MB ( 1 << 4 ) | ||
250 | #define DEV_RATEBIT_9MB ( 1 << 5 ) | ||
251 | #define DEV_RATEBIT_12MB ( 1 << 6 ) | ||
252 | #define DEV_RATEBIT_18MB ( 1 << 7 ) | ||
253 | #define DEV_RATEBIT_24MB ( 1 << 8 ) | ||
254 | #define DEV_RATEBIT_36MB ( 1 << 9 ) | ||
255 | #define DEV_RATEBIT_48MB ( 1 << 10 ) | ||
256 | #define DEV_RATEBIT_54MB ( 1 << 11 ) | ||
257 | |||
258 | /* | ||
259 | * Bitmasks for DEV_RATEMASK | ||
260 | */ | ||
261 | #define DEV_RATEMASK_1MB ( (DEV_RATEBIT_1MB << 1) -1 ) | ||
262 | #define DEV_RATEMASK_2MB ( (DEV_RATEBIT_2MB << 1) -1 ) | ||
263 | #define DEV_RATEMASK_5_5MB ( (DEV_RATEBIT_5_5MB << 1) -1 ) | ||
264 | #define DEV_RATEMASK_11MB ( (DEV_RATEBIT_11MB << 1) -1 ) | ||
265 | #define DEV_RATEMASK_6MB ( (DEV_RATEBIT_6MB << 1) -1 ) | ||
266 | #define DEV_RATEMASK_9MB ( (DEV_RATEBIT_9MB << 1) -1 ) | ||
267 | #define DEV_RATEMASK_12MB ( (DEV_RATEBIT_12MB << 1) -1 ) | ||
268 | #define DEV_RATEMASK_18MB ( (DEV_RATEBIT_18MB << 1) -1 ) | ||
269 | #define DEV_RATEMASK_24MB ( (DEV_RATEBIT_24MB << 1) -1 ) | ||
270 | #define DEV_RATEMASK_36MB ( (DEV_RATEBIT_36MB << 1) -1 ) | ||
271 | #define DEV_RATEMASK_48MB ( (DEV_RATEBIT_48MB << 1) -1 ) | ||
272 | #define DEV_RATEMASK_54MB ( (DEV_RATEBIT_54MB << 1) -1 ) | ||
273 | |||
274 | /* | ||
275 | * Bitmask groups of bitrates | ||
276 | */ | ||
277 | #define DEV_BASIC_RATEMASK \ | ||
278 | ( DEV_RATEMASK_11MB | \ | ||
279 | DEV_RATEBIT_6MB | DEV_RATEBIT_12MB | DEV_RATEBIT_24MB ) | ||
280 | |||
281 | #define DEV_CCK_RATEMASK ( DEV_RATEMASK_11MB ) | ||
282 | #define DEV_OFDM_RATEMASK ( DEV_RATEMASK_54MB & ~DEV_CCK_RATEMASK ) | ||
283 | |||
284 | /* | ||
285 | * Macro's to set and get specific fields from the device specific val and val2 | ||
286 | * fields inside the ieee80211_rate entry. | ||
287 | */ | ||
288 | #define DEVICE_SET_RATE_FIELD(__value, __mask) \ | ||
289 | (int)( ((__value) << DEV_##__mask.bit_offset) & DEV_##__mask.bit_mask ) | ||
290 | |||
291 | #define DEVICE_GET_RATE_FIELD(__value, __mask) \ | ||
292 | (int)( ((__value) & DEV_##__mask.bit_mask) >> DEV_##__mask.bit_offset ) | ||
293 | |||
294 | #endif /* RT2X00REG_H */ | 223 | #endif /* RT2X00REG_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index 34a96d44e306..67121427a5bd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h deleted file mode 100644 index 1caa6d688c40..000000000000 --- a/drivers/net/wireless/rt2x00/rt2x00ring.h +++ /dev/null | |||
@@ -1,290 +0,0 @@ | |||
1 | /* | ||
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | ||
3 | <http://rt2x00.serialmonkey.com> | ||
4 | |||
5 | This program is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation; either version 2 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program; if not, write to the | ||
17 | Free Software Foundation, Inc., | ||
18 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /* | ||
22 | Module: rt2x00 | ||
23 | Abstract: rt2x00 ring datastructures and routines | ||
24 | */ | ||
25 | |||
26 | #ifndef RT2X00RING_H | ||
27 | #define RT2X00RING_H | ||
28 | |||
29 | /* | ||
30 | * skb_desc | ||
31 | * Descriptor information for the skb buffer | ||
32 | */ | ||
33 | struct skb_desc { | ||
34 | unsigned int frame_type; | ||
35 | |||
36 | unsigned int desc_len; | ||
37 | unsigned int data_len; | ||
38 | |||
39 | void *desc; | ||
40 | void *data; | ||
41 | |||
42 | struct data_ring *ring; | ||
43 | struct data_entry *entry; | ||
44 | }; | ||
45 | |||
46 | static inline struct skb_desc* get_skb_desc(struct sk_buff *skb) | ||
47 | { | ||
48 | return (struct skb_desc*)&skb->cb[0]; | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * rxdata_entry_desc | ||
53 | * Summary of information that has been read from the | ||
54 | * RX frame descriptor. | ||
55 | */ | ||
56 | struct rxdata_entry_desc { | ||
57 | int signal; | ||
58 | int rssi; | ||
59 | int ofdm; | ||
60 | int size; | ||
61 | int flags; | ||
62 | int my_bss; | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * txdata_entry_desc | ||
67 | * Summary of information that should be written into the | ||
68 | * descriptor for sending a TX frame. | ||
69 | */ | ||
70 | struct txdata_entry_desc { | ||
71 | unsigned long flags; | ||
72 | #define ENTRY_TXDONE 1 | ||
73 | #define ENTRY_TXD_RTS_FRAME 2 | ||
74 | #define ENTRY_TXD_OFDM_RATE 3 | ||
75 | #define ENTRY_TXD_MORE_FRAG 4 | ||
76 | #define ENTRY_TXD_REQ_TIMESTAMP 5 | ||
77 | #define ENTRY_TXD_BURST 6 | ||
78 | #define ENTRY_TXD_ACK 7 | ||
79 | |||
80 | /* | ||
81 | * Queue ID. ID's 0-4 are data TX rings | ||
82 | */ | ||
83 | int queue; | ||
84 | #define QUEUE_MGMT 13 | ||
85 | #define QUEUE_RX 14 | ||
86 | #define QUEUE_OTHER 15 | ||
87 | |||
88 | /* | ||
89 | * PLCP values. | ||
90 | */ | ||
91 | u16 length_high; | ||
92 | u16 length_low; | ||
93 | u16 signal; | ||
94 | u16 service; | ||
95 | |||
96 | /* | ||
97 | * Timing information | ||
98 | */ | ||
99 | int aifs; | ||
100 | int ifs; | ||
101 | int cw_min; | ||
102 | int cw_max; | ||
103 | }; | ||
104 | |||
105 | /* | ||
106 | * data_entry | ||
107 | * The data ring is a list of data entries. | ||
108 | * Each entry holds a reference to the descriptor | ||
109 | * and the data buffer. For TX rings the reference to the | ||
110 | * sk_buff of the packet being transmitted is also stored here. | ||
111 | */ | ||
112 | struct data_entry { | ||
113 | /* | ||
114 | * Status flags | ||
115 | */ | ||
116 | unsigned long flags; | ||
117 | #define ENTRY_OWNER_NIC 1 | ||
118 | |||
119 | /* | ||
120 | * Ring we belong to. | ||
121 | */ | ||
122 | struct data_ring *ring; | ||
123 | |||
124 | /* | ||
125 | * sk_buff for the packet which is being transmitted | ||
126 | * in this entry (Only used with TX related rings). | ||
127 | */ | ||
128 | struct sk_buff *skb; | ||
129 | |||
130 | /* | ||
131 | * Store a ieee80211_tx_status structure in each | ||
132 | * ring entry, this will optimize the txdone | ||
133 | * handler. | ||
134 | */ | ||
135 | struct ieee80211_tx_status tx_status; | ||
136 | |||
137 | /* | ||
138 | * private pointer specific to driver. | ||
139 | */ | ||
140 | void *priv; | ||
141 | |||
142 | /* | ||
143 | * Data address for this entry. | ||
144 | */ | ||
145 | void *data_addr; | ||
146 | dma_addr_t data_dma; | ||
147 | |||
148 | /* | ||
149 | * Entry identification number (index). | ||
150 | */ | ||
151 | unsigned int entry_idx; | ||
152 | }; | ||
153 | |||
154 | /* | ||
155 | * data_ring | ||
156 | * Data rings are used by the device to send and receive packets. | ||
157 | * The data_addr is the base address of the data memory. | ||
158 | * To determine at which point in the ring we are, | ||
159 | * have to use the rt2x00_ring_index_*() functions. | ||
160 | */ | ||
161 | struct data_ring { | ||
162 | /* | ||
163 | * Pointer to main rt2x00dev structure where this | ||
164 | * ring belongs to. | ||
165 | */ | ||
166 | struct rt2x00_dev *rt2x00dev; | ||
167 | |||
168 | /* | ||
169 | * Base address for the device specific data entries. | ||
170 | */ | ||
171 | struct data_entry *entry; | ||
172 | |||
173 | /* | ||
174 | * TX queue statistic info. | ||
175 | */ | ||
176 | struct ieee80211_tx_queue_stats_data stats; | ||
177 | |||
178 | /* | ||
179 | * TX Queue parameters. | ||
180 | */ | ||
181 | struct ieee80211_tx_queue_params tx_params; | ||
182 | |||
183 | /* | ||
184 | * Base address for data ring. | ||
185 | */ | ||
186 | dma_addr_t data_dma; | ||
187 | void *data_addr; | ||
188 | |||
189 | /* | ||
190 | * Queue identification number: | ||
191 | * RX: 0 | ||
192 | * TX: IEEE80211_TX_* | ||
193 | */ | ||
194 | unsigned int queue_idx; | ||
195 | |||
196 | /* | ||
197 | * Index variables. | ||
198 | */ | ||
199 | u16 index; | ||
200 | u16 index_done; | ||
201 | |||
202 | /* | ||
203 | * Size of packet and descriptor in bytes. | ||
204 | */ | ||
205 | u16 data_size; | ||
206 | u16 desc_size; | ||
207 | }; | ||
208 | |||
209 | /* | ||
210 | * Handlers to determine the address of the current device specific | ||
211 | * data entry, where either index or index_done points to. | ||
212 | */ | ||
213 | static inline struct data_entry *rt2x00_get_data_entry(struct data_ring *ring) | ||
214 | { | ||
215 | return &ring->entry[ring->index]; | ||
216 | } | ||
217 | |||
218 | static inline struct data_entry *rt2x00_get_data_entry_done(struct data_ring | ||
219 | *ring) | ||
220 | { | ||
221 | return &ring->entry[ring->index_done]; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Total ring memory | ||
226 | */ | ||
227 | static inline int rt2x00_get_ring_size(struct data_ring *ring) | ||
228 | { | ||
229 | return ring->stats.limit * (ring->desc_size + ring->data_size); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Ring index manipulation functions. | ||
234 | */ | ||
235 | static inline void rt2x00_ring_index_inc(struct data_ring *ring) | ||
236 | { | ||
237 | ring->index++; | ||
238 | if (ring->index >= ring->stats.limit) | ||
239 | ring->index = 0; | ||
240 | ring->stats.len++; | ||
241 | } | ||
242 | |||
243 | static inline void rt2x00_ring_index_done_inc(struct data_ring *ring) | ||
244 | { | ||
245 | ring->index_done++; | ||
246 | if (ring->index_done >= ring->stats.limit) | ||
247 | ring->index_done = 0; | ||
248 | ring->stats.len--; | ||
249 | ring->stats.count++; | ||
250 | } | ||
251 | |||
252 | static inline void rt2x00_ring_index_clear(struct data_ring *ring) | ||
253 | { | ||
254 | ring->index = 0; | ||
255 | ring->index_done = 0; | ||
256 | ring->stats.len = 0; | ||
257 | ring->stats.count = 0; | ||
258 | } | ||
259 | |||
260 | static inline int rt2x00_ring_empty(struct data_ring *ring) | ||
261 | { | ||
262 | return ring->stats.len == 0; | ||
263 | } | ||
264 | |||
265 | static inline int rt2x00_ring_full(struct data_ring *ring) | ||
266 | { | ||
267 | return ring->stats.len == ring->stats.limit; | ||
268 | } | ||
269 | |||
270 | static inline int rt2x00_ring_free(struct data_ring *ring) | ||
271 | { | ||
272 | return ring->stats.limit - ring->stats.len; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * TX/RX Descriptor access functions. | ||
277 | */ | ||
278 | static inline void rt2x00_desc_read(__le32 *desc, | ||
279 | const u8 word, u32 *value) | ||
280 | { | ||
281 | *value = le32_to_cpu(desc[word]); | ||
282 | } | ||
283 | |||
284 | static inline void rt2x00_desc_write(__le32 *desc, | ||
285 | const u8 word, const u32 value) | ||
286 | { | ||
287 | desc[word] = cpu_to_le32(value); | ||
288 | } | ||
289 | |||
290 | #endif /* RT2X00RING_H */ | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 84e9bdb73910..063b167da31e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -40,8 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
40 | void *buffer, const u16 buffer_length, | 40 | void *buffer, const u16 buffer_length, |
41 | const int timeout) | 41 | const int timeout) |
42 | { | 42 | { |
43 | struct usb_device *usb_dev = | 43 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
44 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | ||
45 | int status; | 44 | int status; |
46 | unsigned int i; | 45 | unsigned int i; |
47 | unsigned int pipe = | 46 | unsigned int pipe = |
@@ -85,20 +84,20 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
85 | /* | 84 | /* |
86 | * Check for Cache availability. | 85 | * Check for Cache availability. |
87 | */ | 86 | */ |
88 | if (unlikely(!rt2x00dev->csr_cache || buffer_length > CSR_CACHE_SIZE)) { | 87 | if (unlikely(!rt2x00dev->csr.cache || buffer_length > CSR_CACHE_SIZE)) { |
89 | ERROR(rt2x00dev, "CSR cache not available.\n"); | 88 | ERROR(rt2x00dev, "CSR cache not available.\n"); |
90 | return -ENOMEM; | 89 | return -ENOMEM; |
91 | } | 90 | } |
92 | 91 | ||
93 | if (requesttype == USB_VENDOR_REQUEST_OUT) | 92 | if (requesttype == USB_VENDOR_REQUEST_OUT) |
94 | memcpy(rt2x00dev->csr_cache, buffer, buffer_length); | 93 | memcpy(rt2x00dev->csr.cache, buffer, buffer_length); |
95 | 94 | ||
96 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, | 95 | status = rt2x00usb_vendor_request(rt2x00dev, request, requesttype, |
97 | offset, 0, rt2x00dev->csr_cache, | 96 | offset, 0, rt2x00dev->csr.cache, |
98 | buffer_length, timeout); | 97 | buffer_length, timeout); |
99 | 98 | ||
100 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) | 99 | if (!status && requesttype == USB_VENDOR_REQUEST_IN) |
101 | memcpy(buffer, rt2x00dev->csr_cache, buffer_length); | 100 | memcpy(buffer, rt2x00dev->csr.cache, buffer_length); |
102 | 101 | ||
103 | return status; | 102 | return status; |
104 | } | 103 | } |
@@ -128,15 +127,15 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | |||
128 | */ | 127 | */ |
129 | static void rt2x00usb_interrupt_txdone(struct urb *urb) | 128 | static void rt2x00usb_interrupt_txdone(struct urb *urb) |
130 | { | 129 | { |
131 | struct data_entry *entry = (struct data_entry *)urb->context; | 130 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
132 | struct data_ring *ring = entry->ring; | 131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
133 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | 132 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
133 | struct txdone_entry_desc txdesc; | ||
134 | __le32 *txd = (__le32 *)entry->skb->data; | 134 | __le32 *txd = (__le32 *)entry->skb->data; |
135 | u32 word; | 135 | u32 word; |
136 | int tx_status; | ||
137 | 136 | ||
138 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 137 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
139 | !__test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 138 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
140 | return; | 139 | return; |
141 | 140 | ||
142 | rt2x00_desc_read(txd, 0, &word); | 141 | rt2x00_desc_read(txd, 0, &word); |
@@ -144,45 +143,46 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
144 | /* | 143 | /* |
145 | * Remove the descriptor data from the buffer. | 144 | * Remove the descriptor data from the buffer. |
146 | */ | 145 | */ |
147 | skb_pull(entry->skb, ring->desc_size); | 146 | skb_pull(entry->skb, entry->queue->desc_size); |
148 | 147 | ||
149 | /* | 148 | /* |
150 | * Obtain the status about this packet. | 149 | * Obtain the status about this packet. |
151 | */ | 150 | */ |
152 | tx_status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; | 151 | txdesc.status = !urb->status ? TX_SUCCESS : TX_FAIL_RETRY; |
152 | txdesc.retry = 0; | ||
153 | txdesc.control = &priv_tx->control; | ||
153 | 154 | ||
154 | rt2x00lib_txdone(entry, tx_status, 0); | 155 | rt2x00lib_txdone(entry, &txdesc); |
155 | 156 | ||
156 | /* | 157 | /* |
157 | * Make this entry available for reuse. | 158 | * Make this entry available for reuse. |
158 | */ | 159 | */ |
159 | entry->flags = 0; | 160 | entry->flags = 0; |
160 | rt2x00_ring_index_done_inc(entry->ring); | 161 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
161 | 162 | ||
162 | /* | 163 | /* |
163 | * If the data ring was full before the txdone handler | 164 | * If the data queue was full before the txdone handler |
164 | * we must make sure the packet queue in the mac80211 stack | 165 | * we must make sure the packet queue in the mac80211 stack |
165 | * is reenabled when the txdone handler has finished. | 166 | * is reenabled when the txdone handler has finished. |
166 | */ | 167 | */ |
167 | if (!rt2x00_ring_full(ring)) | 168 | if (!rt2x00queue_full(entry->queue)) |
168 | ieee80211_wake_queue(rt2x00dev->hw, | 169 | ieee80211_wake_queue(rt2x00dev->hw, priv_tx->control.queue); |
169 | entry->tx_status.control.queue); | ||
170 | } | 170 | } |
171 | 171 | ||
172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 172 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
173 | struct data_ring *ring, struct sk_buff *skb, | 173 | struct data_queue *queue, struct sk_buff *skb, |
174 | struct ieee80211_tx_control *control) | 174 | struct ieee80211_tx_control *control) |
175 | { | 175 | { |
176 | struct usb_device *usb_dev = | 176 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
177 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 177 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
178 | struct data_entry *entry = rt2x00_get_data_entry(ring); | 178 | struct queue_entry_priv_usb_tx *priv_tx = entry->priv_data; |
179 | struct skb_desc *desc; | 179 | struct skb_frame_desc *skbdesc; |
180 | u32 length; | 180 | u32 length; |
181 | 181 | ||
182 | if (rt2x00_ring_full(ring)) | 182 | if (rt2x00queue_full(queue)) |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | 184 | ||
185 | if (test_bit(ENTRY_OWNER_NIC, &entry->flags)) { | 185 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { |
186 | ERROR(rt2x00dev, | 186 | ERROR(rt2x00dev, |
187 | "Arrived at non-free entry in the non-full queue %d.\n" | 187 | "Arrived at non-free entry in the non-full queue %d.\n" |
188 | "Please file bug report to %s.\n", | 188 | "Please file bug report to %s.\n", |
@@ -193,19 +193,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
193 | /* | 193 | /* |
194 | * Add the descriptor in front of the skb. | 194 | * Add the descriptor in front of the skb. |
195 | */ | 195 | */ |
196 | skb_push(skb, ring->desc_size); | 196 | skb_push(skb, queue->desc_size); |
197 | memset(skb->data, 0, ring->desc_size); | 197 | memset(skb->data, 0, queue->desc_size); |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * Fill in skb descriptor | 200 | * Fill in skb descriptor |
201 | */ | 201 | */ |
202 | desc = get_skb_desc(skb); | 202 | skbdesc = get_skb_frame_desc(skb); |
203 | desc->desc_len = ring->desc_size; | 203 | skbdesc->data = skb->data + queue->desc_size; |
204 | desc->data_len = skb->len - ring->desc_size; | 204 | skbdesc->data_len = skb->len - queue->desc_size; |
205 | desc->desc = skb->data; | 205 | skbdesc->desc = skb->data; |
206 | desc->data = skb->data + ring->desc_size; | 206 | skbdesc->desc_len = queue->desc_size; |
207 | desc->ring = ring; | 207 | skbdesc->entry = entry; |
208 | desc->entry = entry; | ||
209 | 208 | ||
210 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 209 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
211 | 210 | ||
@@ -219,12 +218,12 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | |||
219 | /* | 218 | /* |
220 | * Initialize URB and send the frame to the device. | 219 | * Initialize URB and send the frame to the device. |
221 | */ | 220 | */ |
222 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 221 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
223 | usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1), | 222 | usb_fill_bulk_urb(priv_tx->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), |
224 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | 223 | skb->data, length, rt2x00usb_interrupt_txdone, entry); |
225 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 224 | usb_submit_urb(priv_tx->urb, GFP_ATOMIC); |
226 | 225 | ||
227 | rt2x00_ring_index_inc(ring); | 226 | rt2x00queue_index_inc(queue, Q_INDEX); |
228 | 227 | ||
229 | return 0; | 228 | return 0; |
230 | } | 229 | } |
@@ -233,20 +232,41 @@ EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); | |||
233 | /* | 232 | /* |
234 | * RX data handlers. | 233 | * RX data handlers. |
235 | */ | 234 | */ |
235 | static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue) | ||
236 | { | ||
237 | struct sk_buff *skb; | ||
238 | unsigned int frame_size; | ||
239 | |||
240 | /* | ||
241 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
242 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
243 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
244 | * alignment later, we assume that the chance that | ||
245 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
246 | * and thus optimize alignment by reserving the 2 bytes in | ||
247 | * advance. | ||
248 | */ | ||
249 | frame_size = queue->data_size + queue->desc_size; | ||
250 | skb = dev_alloc_skb(frame_size + 2); | ||
251 | if (!skb) | ||
252 | return NULL; | ||
253 | |||
254 | skb_reserve(skb, 2); | ||
255 | skb_put(skb, frame_size); | ||
256 | |||
257 | return skb; | ||
258 | } | ||
259 | |||
236 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 260 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
237 | { | 261 | { |
238 | struct data_entry *entry = (struct data_entry *)urb->context; | 262 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
239 | struct data_ring *ring = entry->ring; | 263 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
240 | struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; | ||
241 | struct sk_buff *skb; | 264 | struct sk_buff *skb; |
242 | struct ieee80211_hdr *hdr; | 265 | struct skb_frame_desc *skbdesc; |
243 | struct skb_desc *skbdesc; | 266 | struct rxdone_entry_desc rxdesc; |
244 | struct rxdata_entry_desc desc; | ||
245 | int header_size; | ||
246 | int frame_size; | ||
247 | 267 | ||
248 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 268 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
249 | !test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags)) | 269 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
250 | return; | 270 | return; |
251 | 271 | ||
252 | /* | 272 | /* |
@@ -254,67 +274,32 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
254 | * to be actually valid, or if the urb is signaling | 274 | * to be actually valid, or if the urb is signaling |
255 | * a problem. | 275 | * a problem. |
256 | */ | 276 | */ |
257 | if (urb->actual_length < entry->ring->desc_size || urb->status) | 277 | if (urb->actual_length < entry->queue->desc_size || urb->status) |
258 | goto skip_entry; | 278 | goto skip_entry; |
259 | 279 | ||
260 | /* | 280 | /* |
261 | * Fill in skb descriptor | 281 | * Fill in skb descriptor |
262 | */ | 282 | */ |
263 | skbdesc = get_skb_desc(entry->skb); | 283 | skbdesc = get_skb_frame_desc(entry->skb); |
264 | skbdesc->ring = ring; | 284 | memset(skbdesc, 0, sizeof(*skbdesc)); |
265 | skbdesc->entry = entry; | 285 | skbdesc->entry = entry; |
266 | 286 | ||
267 | memset(&desc, 0, sizeof(desc)); | 287 | memset(&rxdesc, 0, sizeof(rxdesc)); |
268 | rt2x00dev->ops->lib->fill_rxdone(entry, &desc); | 288 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
269 | 289 | ||
270 | /* | 290 | /* |
271 | * Allocate a new sk buffer to replace the current one. | 291 | * Allocate a new sk buffer to replace the current one. |
272 | * If allocation fails, we should drop the current frame | 292 | * If allocation fails, we should drop the current frame |
273 | * so we can recycle the existing sk buffer for the new frame. | 293 | * so we can recycle the existing sk buffer for the new frame. |
274 | * As alignment we use 2 and not NET_IP_ALIGN because we need | ||
275 | * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN | ||
276 | * can be 0 on some hardware). We use these 2 bytes for frame | ||
277 | * alignment later, we assume that the chance that | ||
278 | * header_size % 4 == 2 is bigger then header_size % 2 == 0 | ||
279 | * and thus optimize alignment by reserving the 2 bytes in | ||
280 | * advance. | ||
281 | */ | 294 | */ |
282 | frame_size = entry->ring->data_size + entry->ring->desc_size; | 295 | skb = rt2x00usb_alloc_rxskb(entry->queue); |
283 | skb = dev_alloc_skb(frame_size + 2); | ||
284 | if (!skb) | 296 | if (!skb) |
285 | goto skip_entry; | 297 | goto skip_entry; |
286 | 298 | ||
287 | skb_reserve(skb, 2); | ||
288 | skb_put(skb, frame_size); | ||
289 | |||
290 | /* | ||
291 | * The data behind the ieee80211 header must be | ||
292 | * aligned on a 4 byte boundary. | ||
293 | */ | ||
294 | hdr = (struct ieee80211_hdr *)entry->skb->data; | ||
295 | header_size = | ||
296 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
297 | |||
298 | if (header_size % 4 == 0) { | ||
299 | skb_push(entry->skb, 2); | ||
300 | memmove(entry->skb->data, entry->skb->data + 2, skb->len - 2); | ||
301 | } | ||
302 | |||
303 | /* | ||
304 | * Trim the entire buffer down to only contain the valid frame data | ||
305 | * excluding the device descriptor. The position of the descriptor | ||
306 | * varies. This means that we should check where the descriptor is | ||
307 | * and decide if we need to pull the data pointer to exclude the | ||
308 | * device descriptor. | ||
309 | */ | ||
310 | if (skbdesc->data > skbdesc->desc) | ||
311 | skb_pull(entry->skb, skbdesc->desc_len); | ||
312 | skb_trim(entry->skb, desc.size); | ||
313 | |||
314 | /* | 299 | /* |
315 | * Send the frame to rt2x00lib for further processing. | 300 | * Send the frame to rt2x00lib for further processing. |
316 | */ | 301 | */ |
317 | rt2x00lib_rxdone(entry, entry->skb, &desc); | 302 | rt2x00lib_rxdone(entry, &rxdesc); |
318 | 303 | ||
319 | /* | 304 | /* |
320 | * Replace current entry's skb with the newly allocated one, | 305 | * Replace current entry's skb with the newly allocated one, |
@@ -325,12 +310,12 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
325 | urb->transfer_buffer_length = entry->skb->len; | 310 | urb->transfer_buffer_length = entry->skb->len; |
326 | 311 | ||
327 | skip_entry: | 312 | skip_entry: |
328 | if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) { | 313 | if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { |
329 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 314 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
330 | usb_submit_urb(urb, GFP_ATOMIC); | 315 | usb_submit_urb(urb, GFP_ATOMIC); |
331 | } | 316 | } |
332 | 317 | ||
333 | rt2x00_ring_index_inc(ring); | 318 | rt2x00queue_index_inc(entry->queue, Q_INDEX); |
334 | } | 319 | } |
335 | 320 | ||
336 | /* | 321 | /* |
@@ -338,18 +323,44 @@ skip_entry: | |||
338 | */ | 323 | */ |
339 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 324 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
340 | { | 325 | { |
341 | struct data_ring *ring; | 326 | struct queue_entry_priv_usb_rx *priv_rx; |
327 | struct queue_entry_priv_usb_tx *priv_tx; | ||
328 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
329 | struct data_queue *queue; | ||
342 | unsigned int i; | 330 | unsigned int i; |
343 | 331 | ||
344 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, | 332 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0x0000, 0x0000, |
345 | REGISTER_TIMEOUT); | 333 | REGISTER_TIMEOUT); |
346 | 334 | ||
347 | /* | 335 | /* |
348 | * Cancel all rings. | 336 | * Cancel all queues. |
349 | */ | 337 | */ |
350 | ring_for_each(rt2x00dev, ring) { | 338 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
351 | for (i = 0; i < ring->stats.limit; i++) | 339 | priv_rx = rt2x00dev->rx->entries[i].priv_data; |
352 | usb_kill_urb(ring->entry[i].priv); | 340 | usb_kill_urb(priv_rx->urb); |
341 | } | ||
342 | |||
343 | tx_queue_for_each(rt2x00dev, queue) { | ||
344 | for (i = 0; i < queue->limit; i++) { | ||
345 | priv_tx = queue->entries[i].priv_data; | ||
346 | usb_kill_urb(priv_tx->urb); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | ||
351 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; | ||
352 | usb_kill_urb(priv_bcn->urb); | ||
353 | |||
354 | if (priv_bcn->guardian_urb) | ||
355 | usb_kill_urb(priv_bcn->guardian_urb); | ||
356 | } | ||
357 | |||
358 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | ||
359 | return; | ||
360 | |||
361 | for (i = 0; i < rt2x00dev->bcn[1].limit; i++) { | ||
362 | priv_tx = rt2x00dev->bcn[1].entries[i].priv_data; | ||
363 | usb_kill_urb(priv_tx->urb); | ||
353 | } | 364 | } |
354 | } | 365 | } |
355 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | 366 | EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); |
@@ -358,64 +369,108 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
358 | * Device initialization handlers. | 369 | * Device initialization handlers. |
359 | */ | 370 | */ |
360 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 371 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
361 | struct data_entry *entry) | 372 | struct queue_entry *entry) |
362 | { | 373 | { |
363 | struct usb_device *usb_dev = | 374 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
364 | interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); | 375 | struct queue_entry_priv_usb_rx *priv_rx = entry->priv_data; |
365 | 376 | ||
366 | usb_fill_bulk_urb(entry->priv, usb_dev, | 377 | usb_fill_bulk_urb(priv_rx->urb, usb_dev, |
367 | usb_rcvbulkpipe(usb_dev, 1), | 378 | usb_rcvbulkpipe(usb_dev, 1), |
368 | entry->skb->data, entry->skb->len, | 379 | entry->skb->data, entry->skb->len, |
369 | rt2x00usb_interrupt_rxdone, entry); | 380 | rt2x00usb_interrupt_rxdone, entry); |
370 | 381 | ||
371 | __set_bit(ENTRY_OWNER_NIC, &entry->flags); | 382 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
372 | usb_submit_urb(entry->priv, GFP_ATOMIC); | 383 | usb_submit_urb(priv_rx->urb, GFP_ATOMIC); |
373 | } | 384 | } |
374 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); | 385 | EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); |
375 | 386 | ||
376 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 387 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
377 | struct data_entry *entry) | 388 | struct queue_entry *entry) |
378 | { | 389 | { |
379 | entry->flags = 0; | 390 | entry->flags = 0; |
380 | } | 391 | } |
381 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); | 392 | EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); |
382 | 393 | ||
383 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, | 394 | static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, |
384 | struct data_ring *ring) | 395 | struct data_queue *queue) |
385 | { | 396 | { |
397 | struct queue_entry_priv_usb_rx *priv_rx; | ||
398 | struct queue_entry_priv_usb_tx *priv_tx; | ||
399 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
400 | struct urb *urb; | ||
401 | unsigned int guardian = | ||
402 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
386 | unsigned int i; | 403 | unsigned int i; |
387 | 404 | ||
388 | /* | 405 | /* |
389 | * Allocate the URB's | 406 | * Allocate the URB's |
390 | */ | 407 | */ |
391 | for (i = 0; i < ring->stats.limit; i++) { | 408 | for (i = 0; i < queue->limit; i++) { |
392 | ring->entry[i].priv = usb_alloc_urb(0, GFP_KERNEL); | 409 | urb = usb_alloc_urb(0, GFP_KERNEL); |
393 | if (!ring->entry[i].priv) | 410 | if (!urb) |
394 | return -ENOMEM; | 411 | return -ENOMEM; |
412 | |||
413 | if (queue->qid == QID_RX) { | ||
414 | priv_rx = queue->entries[i].priv_data; | ||
415 | priv_rx->urb = urb; | ||
416 | } else if (queue->qid == QID_MGMT && guardian) { | ||
417 | priv_bcn = queue->entries[i].priv_data; | ||
418 | priv_bcn->urb = urb; | ||
419 | |||
420 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
421 | if (!urb) | ||
422 | return -ENOMEM; | ||
423 | |||
424 | priv_bcn->guardian_urb = urb; | ||
425 | } else { | ||
426 | priv_tx = queue->entries[i].priv_data; | ||
427 | priv_tx->urb = urb; | ||
428 | } | ||
395 | } | 429 | } |
396 | 430 | ||
397 | return 0; | 431 | return 0; |
398 | } | 432 | } |
399 | 433 | ||
400 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | 434 | static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, |
401 | struct data_ring *ring) | 435 | struct data_queue *queue) |
402 | { | 436 | { |
437 | struct queue_entry_priv_usb_rx *priv_rx; | ||
438 | struct queue_entry_priv_usb_tx *priv_tx; | ||
439 | struct queue_entry_priv_usb_bcn *priv_bcn; | ||
440 | struct urb *urb; | ||
441 | unsigned int guardian = | ||
442 | test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | ||
403 | unsigned int i; | 443 | unsigned int i; |
404 | 444 | ||
405 | if (!ring->entry) | 445 | if (!queue->entries) |
406 | return; | 446 | return; |
407 | 447 | ||
408 | for (i = 0; i < ring->stats.limit; i++) { | 448 | for (i = 0; i < queue->limit; i++) { |
409 | usb_kill_urb(ring->entry[i].priv); | 449 | if (queue->qid == QID_RX) { |
410 | usb_free_urb(ring->entry[i].priv); | 450 | priv_rx = queue->entries[i].priv_data; |
411 | if (ring->entry[i].skb) | 451 | urb = priv_rx->urb; |
412 | kfree_skb(ring->entry[i].skb); | 452 | } else if (queue->qid == QID_MGMT && guardian) { |
453 | priv_bcn = queue->entries[i].priv_data; | ||
454 | |||
455 | usb_kill_urb(priv_bcn->guardian_urb); | ||
456 | usb_free_urb(priv_bcn->guardian_urb); | ||
457 | |||
458 | urb = priv_bcn->urb; | ||
459 | } else { | ||
460 | priv_tx = queue->entries[i].priv_data; | ||
461 | urb = priv_tx->urb; | ||
462 | } | ||
463 | |||
464 | usb_kill_urb(urb); | ||
465 | usb_free_urb(urb); | ||
466 | if (queue->entries[i].skb) | ||
467 | kfree_skb(queue->entries[i].skb); | ||
413 | } | 468 | } |
414 | } | 469 | } |
415 | 470 | ||
416 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | 471 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) |
417 | { | 472 | { |
418 | struct data_ring *ring; | 473 | struct data_queue *queue; |
419 | struct sk_buff *skb; | 474 | struct sk_buff *skb; |
420 | unsigned int entry_size; | 475 | unsigned int entry_size; |
421 | unsigned int i; | 476 | unsigned int i; |
@@ -424,25 +479,22 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
424 | /* | 479 | /* |
425 | * Allocate DMA | 480 | * Allocate DMA |
426 | */ | 481 | */ |
427 | ring_for_each(rt2x00dev, ring) { | 482 | queue_for_each(rt2x00dev, queue) { |
428 | status = rt2x00usb_alloc_urb(rt2x00dev, ring); | 483 | status = rt2x00usb_alloc_urb(rt2x00dev, queue); |
429 | if (status) | 484 | if (status) |
430 | goto exit; | 485 | goto exit; |
431 | } | 486 | } |
432 | 487 | ||
433 | /* | 488 | /* |
434 | * For the RX ring, skb's should be allocated. | 489 | * For the RX queue, skb's should be allocated. |
435 | */ | 490 | */ |
436 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | 491 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; |
437 | for (i = 0; i < rt2x00dev->rx->stats.limit; i++) { | 492 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
438 | skb = dev_alloc_skb(NET_IP_ALIGN + entry_size); | 493 | skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); |
439 | if (!skb) | 494 | if (!skb) |
440 | goto exit; | 495 | goto exit; |
441 | 496 | ||
442 | skb_reserve(skb, NET_IP_ALIGN); | 497 | rt2x00dev->rx->entries[i].skb = skb; |
443 | skb_put(skb, entry_size); | ||
444 | |||
445 | rt2x00dev->rx->entry[i].skb = skb; | ||
446 | } | 498 | } |
447 | 499 | ||
448 | return 0; | 500 | return 0; |
@@ -456,10 +508,10 @@ EXPORT_SYMBOL_GPL(rt2x00usb_initialize); | |||
456 | 508 | ||
457 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) | 509 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) |
458 | { | 510 | { |
459 | struct data_ring *ring; | 511 | struct data_queue *queue; |
460 | 512 | ||
461 | ring_for_each(rt2x00dev, ring) | 513 | queue_for_each(rt2x00dev, queue) |
462 | rt2x00usb_free_urb(rt2x00dev, ring); | 514 | rt2x00usb_free_urb(rt2x00dev, queue); |
463 | } | 515 | } |
464 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); | 516 | EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); |
465 | 517 | ||
@@ -474,14 +526,14 @@ static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev) | |||
474 | kfree(rt2x00dev->eeprom); | 526 | kfree(rt2x00dev->eeprom); |
475 | rt2x00dev->eeprom = NULL; | 527 | rt2x00dev->eeprom = NULL; |
476 | 528 | ||
477 | kfree(rt2x00dev->csr_cache); | 529 | kfree(rt2x00dev->csr.cache); |
478 | rt2x00dev->csr_cache = NULL; | 530 | rt2x00dev->csr.cache = NULL; |
479 | } | 531 | } |
480 | 532 | ||
481 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) | 533 | static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev) |
482 | { | 534 | { |
483 | rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); | 535 | rt2x00dev->csr.cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL); |
484 | if (!rt2x00dev->csr_cache) | 536 | if (!rt2x00dev->csr.cache) |
485 | goto exit; | 537 | goto exit; |
486 | 538 | ||
487 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); | 539 | rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL); |
@@ -627,9 +679,9 @@ EXPORT_SYMBOL_GPL(rt2x00usb_resume); | |||
627 | #endif /* CONFIG_PM */ | 679 | #endif /* CONFIG_PM */ |
628 | 680 | ||
629 | /* | 681 | /* |
630 | * rt2x00pci module information. | 682 | * rt2x00usb module information. |
631 | */ | 683 | */ |
632 | MODULE_AUTHOR(DRV_PROJECT); | 684 | MODULE_AUTHOR(DRV_PROJECT); |
633 | MODULE_VERSION(DRV_VERSION); | 685 | MODULE_VERSION(DRV_VERSION); |
634 | MODULE_DESCRIPTION("rt2x00 library"); | 686 | MODULE_DESCRIPTION("rt2x00 usb library"); |
635 | MODULE_LICENSE("GPL"); | 687 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index e40df4050cd0..11e55180cbaf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -60,34 +60,47 @@ | |||
60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) | 60 | #define USB_VENDOR_REQUEST_IN ( USB_DIR_IN | USB_VENDOR_REQUEST ) |
61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) | 61 | #define USB_VENDOR_REQUEST_OUT ( USB_DIR_OUT | USB_VENDOR_REQUEST ) |
62 | 62 | ||
63 | /* | 63 | /** |
64 | * USB vendor commands. | 64 | * enum rt2x00usb_vendor_request: USB vendor commands. |
65 | */ | 65 | */ |
66 | #define USB_DEVICE_MODE 0x01 | 66 | enum rt2x00usb_vendor_request { |
67 | #define USB_SINGLE_WRITE 0x02 | 67 | USB_DEVICE_MODE = 1, |
68 | #define USB_SINGLE_READ 0x03 | 68 | USB_SINGLE_WRITE = 2, |
69 | #define USB_MULTI_WRITE 0x06 | 69 | USB_SINGLE_READ = 3, |
70 | #define USB_MULTI_READ 0x07 | 70 | USB_MULTI_WRITE = 6, |
71 | #define USB_EEPROM_WRITE 0x08 | 71 | USB_MULTI_READ = 7, |
72 | #define USB_EEPROM_READ 0x09 | 72 | USB_EEPROM_WRITE = 8, |
73 | #define USB_LED_CONTROL 0x0a /* RT73USB */ | 73 | USB_EEPROM_READ = 9, |
74 | #define USB_RX_CONTROL 0x0c | 74 | USB_LED_CONTROL = 10, /* RT73USB */ |
75 | USB_RX_CONTROL = 12, | ||
76 | }; | ||
75 | 77 | ||
76 | /* | 78 | /** |
77 | * Device modes offset | 79 | * enum rt2x00usb_mode_offset: Device modes offset. |
78 | */ | 80 | */ |
79 | #define USB_MODE_RESET 0x01 | 81 | enum rt2x00usb_mode_offset { |
80 | #define USB_MODE_UNPLUG 0x02 | 82 | USB_MODE_RESET = 1, |
81 | #define USB_MODE_FUNCTION 0x03 | 83 | USB_MODE_UNPLUG = 2, |
82 | #define USB_MODE_TEST 0x04 | 84 | USB_MODE_FUNCTION = 3, |
83 | #define USB_MODE_SLEEP 0x07 /* RT73USB */ | 85 | USB_MODE_TEST = 4, |
84 | #define USB_MODE_FIRMWARE 0x08 /* RT73USB */ | 86 | USB_MODE_SLEEP = 7, /* RT73USB */ |
85 | #define USB_MODE_WAKEUP 0x09 /* RT73USB */ | 87 | USB_MODE_FIRMWARE = 8, /* RT73USB */ |
88 | USB_MODE_WAKEUP = 9, /* RT73USB */ | ||
89 | }; | ||
86 | 90 | ||
87 | /* | 91 | /** |
88 | * Used to read/write from/to the device. | 92 | * rt2x00usb_vendor_request - Send register command to device |
93 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
94 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
95 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
96 | * @offset: Register offset to perform action on | ||
97 | * @value: Value to write to device | ||
98 | * @buffer: Buffer where information will be read/written to by device | ||
99 | * @buffer_length: Size of &buffer | ||
100 | * @timeout: Operation timeout | ||
101 | * | ||
89 | * This is the main function to communicate with the device, | 102 | * This is the main function to communicate with the device, |
90 | * the buffer argument _must_ either be NULL or point to | 103 | * the &buffer argument _must_ either be NULL or point to |
91 | * a buffer allocated by kmalloc. Failure to do so can lead | 104 | * a buffer allocated by kmalloc. Failure to do so can lead |
92 | * to unexpected behavior depending on the architecture. | 105 | * to unexpected behavior depending on the architecture. |
93 | */ | 106 | */ |
@@ -97,13 +110,21 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
97 | void *buffer, const u16 buffer_length, | 110 | void *buffer, const u16 buffer_length, |
98 | const int timeout); | 111 | const int timeout); |
99 | 112 | ||
100 | /* | 113 | /** |
101 | * Used to read/write from/to the device. | 114 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
115 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
116 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
117 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
118 | * @offset: Register offset to perform action on | ||
119 | * @buffer: Buffer where information will be read/written to by device | ||
120 | * @buffer_length: Size of &buffer | ||
121 | * @timeout: Operation timeout | ||
122 | * | ||
102 | * This function will use a previously with kmalloc allocated cache | 123 | * This function will use a previously with kmalloc allocated cache |
103 | * to communicate with the device. The contents of the buffer pointer | 124 | * to communicate with the device. The contents of the buffer pointer |
104 | * will be copied to this cache when writing, or read from the cache | 125 | * will be copied to this cache when writing, or read from the cache |
105 | * when reading. | 126 | * when reading. |
106 | * Buffers send to rt2x00usb_vendor_request _must_ be allocated with | 127 | * Buffers send to &rt2x00usb_vendor_request _must_ be allocated with |
107 | * kmalloc. Hence the reason for using a previously allocated cache | 128 | * kmalloc. Hence the reason for using a previously allocated cache |
108 | * which has been allocated properly. | 129 | * which has been allocated properly. |
109 | */ | 130 | */ |
@@ -112,15 +133,32 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
112 | const u16 offset, void *buffer, | 133 | const u16 offset, void *buffer, |
113 | const u16 buffer_length, const int timeout); | 134 | const u16 buffer_length, const int timeout); |
114 | 135 | ||
115 | /* | 136 | /** |
116 | * A version of rt2x00usb_vendor_request_buff which must be called | 137 | * rt2x00usb_vendor_request_buff - Send register command to device (buffered) |
117 | * if the usb_cache_mutex is already held. */ | 138 | * @rt2x00dev: Pointer to &struct rt2x00_dev |
139 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
140 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
141 | * @offset: Register offset to perform action on | ||
142 | * @buffer: Buffer where information will be read/written to by device | ||
143 | * @buffer_length: Size of &buffer | ||
144 | * @timeout: Operation timeout | ||
145 | * | ||
146 | * A version of &rt2x00usb_vendor_request_buff which must be called | ||
147 | * if the usb_cache_mutex is already held. | ||
148 | */ | ||
118 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | 149 | int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, |
119 | const u8 request, const u8 requesttype, | 150 | const u8 request, const u8 requesttype, |
120 | const u16 offset, void *buffer, | 151 | const u16 offset, void *buffer, |
121 | const u16 buffer_length, const int timeout); | 152 | const u16 buffer_length, const int timeout); |
122 | 153 | ||
123 | /* | 154 | /** |
155 | * rt2x00usb_vendor_request_sw - Send single register command to device | ||
156 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
157 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
158 | * @offset: Register offset to perform action on | ||
159 | * @value: Value to write to device | ||
160 | * @timeout: Operation timeout | ||
161 | * | ||
124 | * Simple wrapper around rt2x00usb_vendor_request to write a single | 162 | * Simple wrapper around rt2x00usb_vendor_request to write a single |
125 | * command to the device. Since we don't use the buffer argument we | 163 | * command to the device. Since we don't use the buffer argument we |
126 | * don't have to worry about kmalloc here. | 164 | * don't have to worry about kmalloc here. |
@@ -136,7 +174,12 @@ static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev, | |||
136 | value, NULL, 0, timeout); | 174 | value, NULL, 0, timeout); |
137 | } | 175 | } |
138 | 176 | ||
139 | /* | 177 | /** |
178 | * rt2x00usb_eeprom_read - Read eeprom from device | ||
179 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
180 | * @eeprom: Pointer to eeprom array to store the information in | ||
181 | * @length: Number of bytes to read from the eeprom | ||
182 | * | ||
140 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom | 183 | * Simple wrapper around rt2x00usb_vendor_request to read the eeprom |
141 | * from the device. Note that the eeprom argument _must_ be allocated using | 184 | * from the device. Note that the eeprom argument _must_ be allocated using |
142 | * kmalloc for correct handling inside the kernel USB layer. | 185 | * kmalloc for correct handling inside the kernel USB layer. |
@@ -147,8 +190,8 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, | |||
147 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); | 190 | int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); |
148 | 191 | ||
149 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, | 192 | return rt2x00usb_vendor_request(rt2x00dev, USB_EEPROM_READ, |
150 | USB_VENDOR_REQUEST_IN, 0x0000, | 193 | USB_VENDOR_REQUEST_IN, 0, 0, |
151 | 0x0000, eeprom, lenght, timeout); | 194 | eeprom, lenght, timeout); |
152 | } | 195 | } |
153 | 196 | ||
154 | /* | 197 | /* |
@@ -160,16 +203,58 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | |||
160 | * TX data handlers. | 203 | * TX data handlers. |
161 | */ | 204 | */ |
162 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 205 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, |
163 | struct data_ring *ring, struct sk_buff *skb, | 206 | struct data_queue *queue, struct sk_buff *skb, |
164 | struct ieee80211_tx_control *control); | 207 | struct ieee80211_tx_control *control); |
165 | 208 | ||
209 | /** | ||
210 | * struct queue_entry_priv_usb_rx: Per RX entry USB specific information | ||
211 | * | ||
212 | * @urb: Urb structure used for device communication. | ||
213 | */ | ||
214 | struct queue_entry_priv_usb_rx { | ||
215 | struct urb *urb; | ||
216 | }; | ||
217 | |||
218 | /** | ||
219 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
220 | * | ||
221 | * @urb: Urb structure used for device communication. | ||
222 | * @control: mac80211 control structure used to transmit data. | ||
223 | */ | ||
224 | struct queue_entry_priv_usb_tx { | ||
225 | struct urb *urb; | ||
226 | |||
227 | struct ieee80211_tx_control control; | ||
228 | }; | ||
229 | |||
230 | /** | ||
231 | * struct queue_entry_priv_usb_tx: Per TX entry USB specific information | ||
232 | * | ||
233 | * The first section should match &struct queue_entry_priv_usb_tx exactly. | ||
234 | * rt2500usb can use this structure to send a guardian byte when working | ||
235 | * with beacons. | ||
236 | * | ||
237 | * @urb: Urb structure used for device communication. | ||
238 | * @control: mac80211 control structure used to transmit data. | ||
239 | * @guardian_data: Set to 0, used for sending the guardian data. | ||
240 | * @guardian_urb: Urb structure used to send the guardian data. | ||
241 | */ | ||
242 | struct queue_entry_priv_usb_bcn { | ||
243 | struct urb *urb; | ||
244 | |||
245 | struct ieee80211_tx_control control; | ||
246 | |||
247 | unsigned int guardian_data; | ||
248 | struct urb *guardian_urb; | ||
249 | }; | ||
250 | |||
166 | /* | 251 | /* |
167 | * Device initialization handlers. | 252 | * Device initialization handlers. |
168 | */ | 253 | */ |
169 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 254 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
170 | struct data_entry *entry); | 255 | struct queue_entry *entry); |
171 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, | 256 | void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev, |
172 | struct data_entry *entry); | 257 | struct queue_entry *entry); |
173 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); | 258 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); |
174 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); | 259 | void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); |
175 | 260 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e808db98f2f5..091fe398676d 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -155,6 +155,12 @@ rf_write: | |||
155 | rt2x00_rf_write(rt2x00dev, word, value); | 155 | rt2x00_rf_write(rt2x00dev, word, value); |
156 | } | 156 | } |
157 | 157 | ||
158 | #ifdef CONFIG_RT61PCI_LEDS | ||
159 | /* | ||
160 | * This function is only called from rt61pci_led_brightness() | ||
161 | * make gcc happy by placing this function inside the | ||
162 | * same ifdef statement as the caller. | ||
163 | */ | ||
158 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | 164 | static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, |
159 | const u8 command, const u8 token, | 165 | const u8 command, const u8 token, |
160 | const u8 arg0, const u8 arg1) | 166 | const u8 arg0, const u8 arg1) |
@@ -181,6 +187,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
181 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | 187 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); |
182 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | 188 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); |
183 | } | 189 | } |
190 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
184 | 191 | ||
185 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 192 | static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
186 | { | 193 | { |
@@ -262,72 +269,111 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
262 | u32 reg; | 269 | u32 reg; |
263 | 270 | ||
264 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | 271 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); |
265 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5);; | 272 | return rt2x00_get_field32(reg, MAC_CSR13_BIT5); |
266 | } | 273 | } |
267 | #else | 274 | #else |
268 | #define rt61pci_rfkill_poll NULL | 275 | #define rt61pci_rfkill_poll NULL |
269 | #endif /* CONFIG_RT61PCI_RFKILL */ | 276 | #endif /* CONFIG_RT61PCI_RFKILL */ |
270 | 277 | ||
278 | #ifdef CONFIG_RT61PCI_LEDS | ||
279 | static void rt61pci_led_brightness(struct led_classdev *led_cdev, | ||
280 | enum led_brightness brightness) | ||
281 | { | ||
282 | struct rt2x00_led *led = | ||
283 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
284 | unsigned int enabled = brightness != LED_OFF; | ||
285 | unsigned int a_mode = | ||
286 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
287 | unsigned int bg_mode = | ||
288 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
289 | |||
290 | if (led->type == LED_TYPE_RADIO) { | ||
291 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
292 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
293 | |||
294 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
295 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
296 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
297 | } else if (led->type == LED_TYPE_ASSOC) { | ||
298 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
299 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
300 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
301 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
302 | |||
303 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, | ||
304 | (led->rt2x00dev->led_mcu_reg & 0xff), | ||
305 | ((led->rt2x00dev->led_mcu_reg >> 8))); | ||
306 | } else if (led->type == LED_TYPE_QUALITY) { | ||
307 | /* | ||
308 | * The brightness is divided into 6 levels (0 - 5), | ||
309 | * this means we need to convert the brightness | ||
310 | * argument into the matching level within that range. | ||
311 | */ | ||
312 | rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, | ||
313 | brightness / (LED_FULL / 6), 0); | ||
314 | } | ||
315 | } | ||
316 | #else | ||
317 | #define rt61pci_led_brightness NULL | ||
318 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
319 | |||
271 | /* | 320 | /* |
272 | * Configuration handlers. | 321 | * Configuration handlers. |
273 | */ | 322 | */ |
274 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 323 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
324 | struct rt2x00_intf *intf, | ||
325 | struct rt2x00intf_conf *conf, | ||
326 | const unsigned int flags) | ||
275 | { | 327 | { |
276 | u32 tmp; | 328 | unsigned int beacon_base; |
277 | 329 | u32 reg; | |
278 | tmp = le32_to_cpu(mac[1]); | ||
279 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
280 | mac[1] = cpu_to_le32(tmp); | ||
281 | 330 | ||
282 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 331 | if (flags & CONFIG_UPDATE_TYPE) { |
283 | (2 * sizeof(__le32))); | 332 | /* |
284 | } | 333 | * Clear current synchronisation setup. |
334 | * For the Beacon base registers we only need to clear | ||
335 | * the first byte since that byte contains the VALID and OWNER | ||
336 | * bits which (when set to 0) will invalidate the entire beacon. | ||
337 | */ | ||
338 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
339 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
340 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | ||
285 | 341 | ||
286 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 342 | /* |
287 | { | 343 | * Enable synchronisation. |
288 | u32 tmp; | 344 | */ |
345 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
346 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
347 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
348 | (conf->sync == TSF_SYNC_BEACON)); | ||
349 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
350 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
351 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
352 | } | ||
289 | 353 | ||
290 | tmp = le32_to_cpu(bssid[1]); | 354 | if (flags & CONFIG_UPDATE_MAC) { |
291 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 355 | reg = le32_to_cpu(conf->mac[1]); |
292 | bssid[1] = cpu_to_le32(tmp); | 356 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
357 | conf->mac[1] = cpu_to_le32(reg); | ||
293 | 358 | ||
294 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 359 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, |
295 | (2 * sizeof(__le32))); | 360 | conf->mac, sizeof(conf->mac)); |
296 | } | 361 | } |
297 | 362 | ||
298 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 363 | if (flags & CONFIG_UPDATE_BSSID) { |
299 | const int tsf_sync) | 364 | reg = le32_to_cpu(conf->bssid[1]); |
300 | { | 365 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
301 | u32 reg; | 366 | conf->bssid[1] = cpu_to_le32(reg); |
302 | 367 | ||
303 | /* | 368 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, |
304 | * Clear current synchronisation setup. | 369 | conf->bssid, sizeof(conf->bssid)); |
305 | * For the Beacon base registers we only need to clear | 370 | } |
306 | * the first byte since that byte contains the VALID and OWNER | ||
307 | * bits which (when set to 0) will invalidate the entire beacon. | ||
308 | */ | ||
309 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
310 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
311 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
312 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
313 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
314 | |||
315 | /* | ||
316 | * Enable synchronisation. | ||
317 | */ | ||
318 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
319 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
320 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
321 | (tsf_sync == TSF_SYNC_BEACON)); | ||
322 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
323 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
324 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
325 | } | 371 | } |
326 | 372 | ||
327 | static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 373 | static int rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
328 | const int short_preamble, | 374 | const int short_preamble, |
329 | const int ack_timeout, | 375 | const int ack_timeout, |
330 | const int ack_consume_time) | 376 | const int ack_consume_time) |
331 | { | 377 | { |
332 | u32 reg; | 378 | u32 reg; |
333 | 379 | ||
@@ -339,6 +385,8 @@ static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
339 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 385 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
340 | !!short_preamble); | 386 | !!short_preamble); |
341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 387 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
388 | |||
389 | return 0; | ||
342 | } | 390 | } |
343 | 391 | ||
344 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 392 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -427,12 +475,12 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
427 | case ANTENNA_HW_DIVERSITY: | 475 | case ANTENNA_HW_DIVERSITY: |
428 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 476 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
429 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, | 477 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, |
430 | (rt2x00dev->curr_hwmode != HWMODE_A)); | 478 | (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ)); |
431 | break; | 479 | break; |
432 | case ANTENNA_A: | 480 | case ANTENNA_A: |
433 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 481 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
434 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 482 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
435 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 483 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
436 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 484 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
437 | else | 485 | else |
438 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 486 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
@@ -447,7 +495,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
447 | case ANTENNA_B: | 495 | case ANTENNA_B: |
448 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 496 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 497 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
450 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 498 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
451 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 499 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
452 | else | 500 | else |
453 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -603,7 +651,7 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
603 | unsigned int i; | 651 | unsigned int i; |
604 | u32 reg; | 652 | u32 reg; |
605 | 653 | ||
606 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 654 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
607 | sel = antenna_sel_a; | 655 | sel = antenna_sel_a; |
608 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 656 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
609 | } else { | 657 | } else { |
@@ -617,10 +665,9 @@ static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
617 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); | 665 | rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); |
618 | 666 | ||
619 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 667 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
620 | (rt2x00dev->curr_hwmode == HWMODE_B || | 668 | rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); |
621 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
622 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 669 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
623 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 670 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); |
624 | 671 | ||
625 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); | 672 | rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); |
626 | 673 | ||
@@ -667,8 +714,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
667 | } | 714 | } |
668 | 715 | ||
669 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 716 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
670 | const unsigned int flags, | 717 | struct rt2x00lib_conf *libconf, |
671 | struct rt2x00lib_conf *libconf) | 718 | const unsigned int flags) |
672 | { | 719 | { |
673 | if (flags & CONFIG_UPDATE_PHYMODE) | 720 | if (flags & CONFIG_UPDATE_PHYMODE) |
674 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 721 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -684,78 +731,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | |||
684 | } | 731 | } |
685 | 732 | ||
686 | /* | 733 | /* |
687 | * LED functions. | ||
688 | */ | ||
689 | static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) | ||
690 | { | ||
691 | u32 reg; | ||
692 | u8 arg0; | ||
693 | u8 arg1; | ||
694 | |||
695 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
696 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
697 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
698 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
699 | |||
700 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
701 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
702 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
703 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
704 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
705 | |||
706 | arg0 = rt2x00dev->led_reg & 0xff; | ||
707 | arg1 = (rt2x00dev->led_reg >> 8) & 0xff; | ||
708 | |||
709 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
710 | } | ||
711 | |||
712 | static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) | ||
713 | { | ||
714 | u16 led_reg; | ||
715 | u8 arg0; | ||
716 | u8 arg1; | ||
717 | |||
718 | led_reg = rt2x00dev->led_reg; | ||
719 | rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
720 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
721 | rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
722 | |||
723 | arg0 = led_reg & 0xff; | ||
724 | arg1 = (led_reg >> 8) & 0xff; | ||
725 | |||
726 | rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); | ||
727 | } | ||
728 | |||
729 | static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
730 | { | ||
731 | u8 led; | ||
732 | |||
733 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
734 | return; | ||
735 | |||
736 | /* | ||
737 | * Led handling requires a positive value for the rssi, | ||
738 | * to do that correctly we need to add the correction. | ||
739 | */ | ||
740 | rssi += rt2x00dev->rssi_offset; | ||
741 | |||
742 | if (rssi <= 30) | ||
743 | led = 0; | ||
744 | else if (rssi <= 39) | ||
745 | led = 1; | ||
746 | else if (rssi <= 49) | ||
747 | led = 2; | ||
748 | else if (rssi <= 53) | ||
749 | led = 3; | ||
750 | else if (rssi <= 63) | ||
751 | led = 4; | ||
752 | else | ||
753 | led = 5; | ||
754 | |||
755 | rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); | ||
756 | } | ||
757 | |||
758 | /* | ||
759 | * Link tuning | 734 | * Link tuning |
760 | */ | 735 | */ |
761 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | 736 | static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -789,17 +764,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
789 | u8 up_bound; | 764 | u8 up_bound; |
790 | u8 low_bound; | 765 | u8 low_bound; |
791 | 766 | ||
792 | /* | ||
793 | * Update Led strength | ||
794 | */ | ||
795 | rt61pci_activity_led(rt2x00dev, rssi); | ||
796 | |||
797 | rt61pci_bbp_read(rt2x00dev, 17, &r17); | 767 | rt61pci_bbp_read(rt2x00dev, 17, &r17); |
798 | 768 | ||
799 | /* | 769 | /* |
800 | * Determine r17 bounds. | 770 | * Determine r17 bounds. |
801 | */ | 771 | */ |
802 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 772 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
803 | low_bound = 0x28; | 773 | low_bound = 0x28; |
804 | up_bound = 0x48; | 774 | up_bound = 0x48; |
805 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 775 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
@@ -816,6 +786,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
816 | } | 786 | } |
817 | 787 | ||
818 | /* | 788 | /* |
789 | * If we are not associated, we should go straight to the | ||
790 | * dynamic CCA tuning. | ||
791 | */ | ||
792 | if (!rt2x00dev->intf_associated) | ||
793 | goto dynamic_cca_tune; | ||
794 | |||
795 | /* | ||
819 | * Special big-R17 for very short distance | 796 | * Special big-R17 for very short distance |
820 | */ | 797 | */ |
821 | if (rssi >= -35) { | 798 | if (rssi >= -35) { |
@@ -866,6 +843,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
866 | return; | 843 | return; |
867 | } | 844 | } |
868 | 845 | ||
846 | dynamic_cca_tune: | ||
847 | |||
869 | /* | 848 | /* |
870 | * r17 does not yet exceed upper limit, continue and base | 849 | * r17 does not yet exceed upper limit, continue and base |
871 | * the r17 tuning on the false CCA count. | 850 | * the r17 tuning on the false CCA count. |
@@ -990,49 +969,51 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
990 | } | 969 | } |
991 | 970 | ||
992 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 971 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
993 | struct data_entry *entry) | 972 | struct queue_entry *entry) |
994 | { | 973 | { |
995 | __le32 *rxd = entry->priv; | 974 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
996 | u32 word; | 975 | u32 word; |
997 | 976 | ||
998 | rt2x00_desc_read(rxd, 5, &word); | 977 | rt2x00_desc_read(priv_rx->desc, 5, &word); |
999 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 978 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1000 | entry->data_dma); | 979 | priv_rx->data_dma); |
1001 | rt2x00_desc_write(rxd, 5, word); | 980 | rt2x00_desc_write(priv_rx->desc, 5, word); |
1002 | 981 | ||
1003 | rt2x00_desc_read(rxd, 0, &word); | 982 | rt2x00_desc_read(priv_rx->desc, 0, &word); |
1004 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 983 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
1005 | rt2x00_desc_write(rxd, 0, word); | 984 | rt2x00_desc_write(priv_rx->desc, 0, word); |
1006 | } | 985 | } |
1007 | 986 | ||
1008 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 987 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
1009 | struct data_entry *entry) | 988 | struct queue_entry *entry) |
1010 | { | 989 | { |
1011 | __le32 *txd = entry->priv; | 990 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; |
1012 | u32 word; | 991 | u32 word; |
1013 | 992 | ||
1014 | rt2x00_desc_read(txd, 1, &word); | 993 | rt2x00_desc_read(priv_tx->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | 994 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); |
1016 | rt2x00_desc_write(txd, 1, word); | 995 | rt2x00_desc_write(priv_tx->desc, 1, word); |
1017 | 996 | ||
1018 | rt2x00_desc_read(txd, 5, &word); | 997 | rt2x00_desc_read(priv_tx->desc, 5, &word); |
1019 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->ring->queue_idx); | 998 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); |
1020 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); | 999 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); |
1021 | rt2x00_desc_write(txd, 5, word); | 1000 | rt2x00_desc_write(priv_tx->desc, 5, word); |
1022 | 1001 | ||
1023 | rt2x00_desc_read(txd, 6, &word); | 1002 | rt2x00_desc_read(priv_tx->desc, 6, &word); |
1024 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1003 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1025 | entry->data_dma); | 1004 | priv_tx->data_dma); |
1026 | rt2x00_desc_write(txd, 6, word); | 1005 | rt2x00_desc_write(priv_tx->desc, 6, word); |
1027 | 1006 | ||
1028 | rt2x00_desc_read(txd, 0, &word); | 1007 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1029 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 1008 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
1030 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 1009 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
1031 | rt2x00_desc_write(txd, 0, word); | 1010 | rt2x00_desc_write(priv_tx->desc, 0, word); |
1032 | } | 1011 | } |
1033 | 1012 | ||
1034 | static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | 1013 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
1035 | { | 1014 | { |
1015 | struct queue_entry_priv_pci_rx *priv_rx; | ||
1016 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1036 | u32 reg; | 1017 | u32 reg; |
1037 | 1018 | ||
1038 | /* | 1019 | /* |
@@ -1040,59 +1021,55 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1040 | */ | 1021 | */ |
1041 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); | 1022 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR0, ®); |
1042 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, | 1023 | rt2x00_set_field32(®, TX_RING_CSR0_AC0_RING_SIZE, |
1043 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].stats.limit); | 1024 | rt2x00dev->tx[0].limit); |
1044 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, | 1025 | rt2x00_set_field32(®, TX_RING_CSR0_AC1_RING_SIZE, |
1045 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].stats.limit); | 1026 | rt2x00dev->tx[1].limit); |
1046 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, | 1027 | rt2x00_set_field32(®, TX_RING_CSR0_AC2_RING_SIZE, |
1047 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].stats.limit); | 1028 | rt2x00dev->tx[2].limit); |
1048 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, | 1029 | rt2x00_set_field32(®, TX_RING_CSR0_AC3_RING_SIZE, |
1049 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].stats.limit); | 1030 | rt2x00dev->tx[3].limit); |
1050 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); | 1031 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR0, reg); |
1051 | 1032 | ||
1052 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); | 1033 | rt2x00pci_register_read(rt2x00dev, TX_RING_CSR1, ®); |
1053 | rt2x00_set_field32(®, TX_RING_CSR1_MGMT_RING_SIZE, | ||
1054 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].stats.limit); | ||
1055 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, | 1034 | rt2x00_set_field32(®, TX_RING_CSR1_TXD_SIZE, |
1056 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].desc_size / | 1035 | rt2x00dev->tx[0].desc_size / 4); |
1057 | 4); | ||
1058 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1036 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); |
1059 | 1037 | ||
1038 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | ||
1060 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1039 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
1061 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1040 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
1062 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA0].data_dma); | 1041 | priv_tx->desc_dma); |
1063 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1042 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
1064 | 1043 | ||
1044 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | ||
1065 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1045 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
1066 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1046 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
1067 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA1].data_dma); | 1047 | priv_tx->desc_dma); |
1068 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1048 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
1069 | 1049 | ||
1050 | priv_tx = rt2x00dev->tx[2].entries[0].priv_data; | ||
1070 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1051 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
1071 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1052 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
1072 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA2].data_dma); | 1053 | priv_tx->desc_dma); |
1073 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1054 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
1074 | 1055 | ||
1056 | priv_tx = rt2x00dev->tx[3].entries[0].priv_data; | ||
1075 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1057 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
1076 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1058 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
1077 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA3].data_dma); | 1059 | priv_tx->desc_dma); |
1078 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1060 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
1079 | 1061 | ||
1080 | rt2x00pci_register_read(rt2x00dev, MGMT_BASE_CSR, ®); | ||
1081 | rt2x00_set_field32(®, MGMT_BASE_CSR_RING_REGISTER, | ||
1082 | rt2x00dev->tx[IEEE80211_TX_QUEUE_DATA4].data_dma); | ||
1083 | rt2x00pci_register_write(rt2x00dev, MGMT_BASE_CSR, reg); | ||
1084 | |||
1085 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | 1062 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); |
1086 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, | 1063 | rt2x00_set_field32(®, RX_RING_CSR_RING_SIZE, rt2x00dev->rx->limit); |
1087 | rt2x00dev->rx->stats.limit); | ||
1088 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, | 1064 | rt2x00_set_field32(®, RX_RING_CSR_RXD_SIZE, |
1089 | rt2x00dev->rx->desc_size / 4); | 1065 | rt2x00dev->rx->desc_size / 4); |
1090 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1066 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
1091 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1067 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); |
1092 | 1068 | ||
1069 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | ||
1093 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1070 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); |
1094 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1071 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
1095 | rt2x00dev->rx->data_dma); | 1072 | priv_rx->desc_dma); |
1096 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1073 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); |
1097 | 1074 | ||
1098 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1075 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
@@ -1100,7 +1077,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1100 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); | 1077 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC1, 2); |
1101 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); | 1078 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC2, 2); |
1102 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); | 1079 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_AC3, 2); |
1103 | rt2x00_set_field32(®, TX_DMA_DST_CSR_DEST_MGMT, 0); | ||
1104 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); | 1080 | rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg); |
1105 | 1081 | ||
1106 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); | 1082 | rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, ®); |
@@ -1108,7 +1084,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev) | |||
1108 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); | 1084 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1); |
1109 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); | 1085 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1); |
1110 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); | 1086 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1); |
1111 | rt2x00_set_field32(®, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1); | ||
1112 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); | 1087 | rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg); |
1113 | 1088 | ||
1114 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); | 1089 | rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, ®); |
@@ -1194,6 +1169,11 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1194 | 1169 | ||
1195 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); | 1170 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); |
1196 | 1171 | ||
1172 | rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); | ||
1173 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
1174 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
1175 | rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); | ||
1176 | |||
1197 | /* | 1177 | /* |
1198 | * Invalidate all Shared Keys (SEC_CSR0), | 1178 | * Invalidate all Shared Keys (SEC_CSR0), |
1199 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 1179 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1224,6 +1204,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1224 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | 1204 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); |
1225 | 1205 | ||
1226 | /* | 1206 | /* |
1207 | * Clear all beacons | ||
1208 | * For the Beacon base registers we only need to clear | ||
1209 | * the first byte since that byte contains the VALID and OWNER | ||
1210 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1211 | */ | ||
1212 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1213 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1214 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1215 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1216 | |||
1217 | /* | ||
1227 | * We must clear the error counters. | 1218 | * We must clear the error counters. |
1228 | * These registers are cleared on read, | 1219 | * These registers are cleared on read, |
1229 | * so we may pass a useless variable to store the value. | 1220 | * so we may pass a useless variable to store the value. |
@@ -1296,19 +1287,15 @@ continue_csr_init: | |||
1296 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); | 1287 | rt61pci_bbp_write(rt2x00dev, 102, 0x16); |
1297 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); | 1288 | rt61pci_bbp_write(rt2x00dev, 107, 0x04); |
1298 | 1289 | ||
1299 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1300 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1290 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1301 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1291 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1302 | 1292 | ||
1303 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1293 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1304 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1294 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1305 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1295 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1306 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1307 | reg_id, value); | ||
1308 | rt61pci_bbp_write(rt2x00dev, reg_id, value); | 1296 | rt61pci_bbp_write(rt2x00dev, reg_id, value); |
1309 | } | 1297 | } |
1310 | } | 1298 | } |
1311 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1312 | 1299 | ||
1313 | return 0; | 1300 | return 0; |
1314 | } | 1301 | } |
@@ -1375,7 +1362,7 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1375 | /* | 1362 | /* |
1376 | * Initialize all registers. | 1363 | * Initialize all registers. |
1377 | */ | 1364 | */ |
1378 | if (rt61pci_init_rings(rt2x00dev) || | 1365 | if (rt61pci_init_queues(rt2x00dev) || |
1379 | rt61pci_init_registers(rt2x00dev) || | 1366 | rt61pci_init_registers(rt2x00dev) || |
1380 | rt61pci_init_bbp(rt2x00dev)) { | 1367 | rt61pci_init_bbp(rt2x00dev)) { |
1381 | ERROR(rt2x00dev, "Register initialization failed.\n"); | 1368 | ERROR(rt2x00dev, "Register initialization failed.\n"); |
@@ -1394,11 +1381,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1394 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); | 1381 | rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); |
1395 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); | 1382 | rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); |
1396 | 1383 | ||
1397 | /* | ||
1398 | * Enable LED | ||
1399 | */ | ||
1400 | rt61pci_enable_led(rt2x00dev); | ||
1401 | |||
1402 | return 0; | 1384 | return 0; |
1403 | } | 1385 | } |
1404 | 1386 | ||
@@ -1406,11 +1388,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1406 | { | 1388 | { |
1407 | u32 reg; | 1389 | u32 reg; |
1408 | 1390 | ||
1409 | /* | ||
1410 | * Disable LED | ||
1411 | */ | ||
1412 | rt61pci_disable_led(rt2x00dev); | ||
1413 | |||
1414 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1391 | rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1415 | 1392 | ||
1416 | /* | 1393 | /* |
@@ -1426,7 +1403,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1426 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); | 1403 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, 1); |
1427 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1404 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1428 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1405 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
1429 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_MGMT, 1); | ||
1430 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1406 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1431 | 1407 | ||
1432 | /* | 1408 | /* |
@@ -1508,10 +1484,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1508 | */ | 1484 | */ |
1509 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1485 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1510 | struct sk_buff *skb, | 1486 | struct sk_buff *skb, |
1511 | struct txdata_entry_desc *desc, | 1487 | struct txentry_desc *txdesc, |
1512 | struct ieee80211_tx_control *control) | 1488 | struct ieee80211_tx_control *control) |
1513 | { | 1489 | { |
1514 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1490 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1515 | __le32 *txd = skbdesc->desc; | 1491 | __le32 *txd = skbdesc->desc; |
1516 | u32 word; | 1492 | u32 word; |
1517 | 1493 | ||
@@ -1519,50 +1495,52 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1519 | * Start writing the descriptor words. | 1495 | * Start writing the descriptor words. |
1520 | */ | 1496 | */ |
1521 | rt2x00_desc_read(txd, 1, &word); | 1497 | rt2x00_desc_read(txd, 1, &word); |
1522 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1498 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1523 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1499 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1524 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1500 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1525 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1501 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1526 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1502 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1527 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1503 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1528 | rt2x00_desc_write(txd, 1, word); | 1504 | rt2x00_desc_write(txd, 1, word); |
1529 | 1505 | ||
1530 | rt2x00_desc_read(txd, 2, &word); | 1506 | rt2x00_desc_read(txd, 2, &word); |
1531 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1507 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1532 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1508 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1533 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1509 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1534 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1510 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1535 | rt2x00_desc_write(txd, 2, word); | 1511 | rt2x00_desc_write(txd, 2, word); |
1536 | 1512 | ||
1537 | rt2x00_desc_read(txd, 5, &word); | 1513 | rt2x00_desc_read(txd, 5, &word); |
1538 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1514 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1539 | TXPOWER_TO_DEV(control->power_level)); | 1515 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1540 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1516 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1541 | rt2x00_desc_write(txd, 5, word); | 1517 | rt2x00_desc_write(txd, 5, word); |
1542 | 1518 | ||
1543 | rt2x00_desc_read(txd, 11, &word); | 1519 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1544 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1520 | rt2x00_desc_read(txd, 11, &word); |
1545 | rt2x00_desc_write(txd, 11, word); | 1521 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); |
1522 | rt2x00_desc_write(txd, 11, word); | ||
1523 | } | ||
1546 | 1524 | ||
1547 | rt2x00_desc_read(txd, 0, &word); | 1525 | rt2x00_desc_read(txd, 0, &word); |
1548 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); | 1526 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1); |
1549 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1527 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1550 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1528 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1551 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1529 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1552 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1530 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1553 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1531 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1554 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1532 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1555 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1533 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1556 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1534 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1557 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1535 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1558 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1536 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1559 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1537 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1560 | !!(control->flags & | 1538 | !!(control->flags & |
1561 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1539 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1562 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1540 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1563 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1541 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1564 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1542 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1565 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1543 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1566 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1544 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1567 | rt2x00_desc_write(txd, 0, word); | 1545 | rt2x00_desc_write(txd, 0, word); |
1568 | } | 1546 | } |
@@ -1571,11 +1549,11 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1571 | * TX data initialization | 1549 | * TX data initialization |
1572 | */ | 1550 | */ |
1573 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1551 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1574 | unsigned int queue) | 1552 | const unsigned int queue) |
1575 | { | 1553 | { |
1576 | u32 reg; | 1554 | u32 reg; |
1577 | 1555 | ||
1578 | if (queue == IEEE80211_TX_QUEUE_BEACON) { | 1556 | if (queue == RT2X00_BCN_QUEUE_BEACON) { |
1579 | /* | 1557 | /* |
1580 | * For Wi-Fi faily generated beacons between participating | 1558 | * For Wi-Fi faily generated beacons between participating |
1581 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 1559 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
@@ -1599,8 +1577,6 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1599 | (queue == IEEE80211_TX_QUEUE_DATA2)); | 1577 | (queue == IEEE80211_TX_QUEUE_DATA2)); |
1600 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, | 1578 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, |
1601 | (queue == IEEE80211_TX_QUEUE_DATA3)); | 1579 | (queue == IEEE80211_TX_QUEUE_DATA3)); |
1602 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, | ||
1603 | (queue == IEEE80211_TX_QUEUE_DATA4)); | ||
1604 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1580 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1605 | } | 1581 | } |
1606 | 1582 | ||
@@ -1628,7 +1604,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1628 | return 0; | 1604 | return 0; |
1629 | } | 1605 | } |
1630 | 1606 | ||
1631 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1607 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1632 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) | 1608 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) |
1633 | offset += 14; | 1609 | offset += 14; |
1634 | 1610 | ||
@@ -1648,28 +1624,28 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1648 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1624 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1649 | } | 1625 | } |
1650 | 1626 | ||
1651 | static void rt61pci_fill_rxdone(struct data_entry *entry, | 1627 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1652 | struct rxdata_entry_desc *desc) | 1628 | struct rxdone_entry_desc *rxdesc) |
1653 | { | 1629 | { |
1654 | __le32 *rxd = entry->priv; | 1630 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; |
1655 | u32 word0; | 1631 | u32 word0; |
1656 | u32 word1; | 1632 | u32 word1; |
1657 | 1633 | ||
1658 | rt2x00_desc_read(rxd, 0, &word0); | 1634 | rt2x00_desc_read(priv_rx->desc, 0, &word0); |
1659 | rt2x00_desc_read(rxd, 1, &word1); | 1635 | rt2x00_desc_read(priv_rx->desc, 1, &word1); |
1660 | 1636 | ||
1661 | desc->flags = 0; | 1637 | rxdesc->flags = 0; |
1662 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1638 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1663 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1639 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1664 | 1640 | ||
1665 | /* | 1641 | /* |
1666 | * Obtain the status about this packet. | 1642 | * Obtain the status about this packet. |
1667 | */ | 1643 | */ |
1668 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1644 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1669 | desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1645 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1670 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1646 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1671 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1647 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1672 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1648 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1673 | } | 1649 | } |
1674 | 1650 | ||
1675 | /* | 1651 | /* |
@@ -1677,17 +1653,16 @@ static void rt61pci_fill_rxdone(struct data_entry *entry, | |||
1677 | */ | 1653 | */ |
1678 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | 1654 | static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) |
1679 | { | 1655 | { |
1680 | struct data_ring *ring; | 1656 | struct data_queue *queue; |
1681 | struct data_entry *entry; | 1657 | struct queue_entry *entry; |
1682 | struct data_entry *entry_done; | 1658 | struct queue_entry *entry_done; |
1683 | __le32 *txd; | 1659 | struct queue_entry_priv_pci_tx *priv_tx; |
1660 | struct txdone_entry_desc txdesc; | ||
1684 | u32 word; | 1661 | u32 word; |
1685 | u32 reg; | 1662 | u32 reg; |
1686 | u32 old_reg; | 1663 | u32 old_reg; |
1687 | int type; | 1664 | int type; |
1688 | int index; | 1665 | int index; |
1689 | int tx_status; | ||
1690 | int retry; | ||
1691 | 1666 | ||
1692 | /* | 1667 | /* |
1693 | * During each loop we will compare the freshly read | 1668 | * During each loop we will compare the freshly read |
@@ -1710,11 +1685,11 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1710 | 1685 | ||
1711 | /* | 1686 | /* |
1712 | * Skip this entry when it contains an invalid | 1687 | * Skip this entry when it contains an invalid |
1713 | * ring identication number. | 1688 | * queue identication number. |
1714 | */ | 1689 | */ |
1715 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); | 1690 | type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE); |
1716 | ring = rt2x00lib_get_ring(rt2x00dev, type); | 1691 | queue = rt2x00queue_get_queue(rt2x00dev, type); |
1717 | if (unlikely(!ring)) | 1692 | if (unlikely(!queue)) |
1718 | continue; | 1693 | continue; |
1719 | 1694 | ||
1720 | /* | 1695 | /* |
@@ -1722,36 +1697,40 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1722 | * index number. | 1697 | * index number. |
1723 | */ | 1698 | */ |
1724 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); | 1699 | index = rt2x00_get_field32(reg, STA_CSR4_PID_SUBTYPE); |
1725 | if (unlikely(index >= ring->stats.limit)) | 1700 | if (unlikely(index >= queue->limit)) |
1726 | continue; | 1701 | continue; |
1727 | 1702 | ||
1728 | entry = &ring->entry[index]; | 1703 | entry = &queue->entries[index]; |
1729 | txd = entry->priv; | 1704 | priv_tx = entry->priv_data; |
1730 | rt2x00_desc_read(txd, 0, &word); | 1705 | rt2x00_desc_read(priv_tx->desc, 0, &word); |
1731 | 1706 | ||
1732 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1707 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1733 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1708 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
1734 | return; | 1709 | return; |
1735 | 1710 | ||
1736 | entry_done = rt2x00_get_data_entry_done(ring); | 1711 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1737 | while (entry != entry_done) { | 1712 | while (entry != entry_done) { |
1738 | /* Catch up. Just report any entries we missed as | 1713 | /* Catch up. |
1739 | * failed. */ | 1714 | * Just report any entries we missed as failed. |
1715 | */ | ||
1740 | WARNING(rt2x00dev, | 1716 | WARNING(rt2x00dev, |
1741 | "TX status report missed for entry %p\n", | 1717 | "TX status report missed for entry %d\n", |
1742 | entry_done); | 1718 | entry_done->entry_idx); |
1743 | rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER, | 1719 | |
1744 | 0); | 1720 | txdesc.status = TX_FAIL_OTHER; |
1745 | entry_done = rt2x00_get_data_entry_done(ring); | 1721 | txdesc.retry = 0; |
1722 | |||
1723 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | ||
1724 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
1746 | } | 1725 | } |
1747 | 1726 | ||
1748 | /* | 1727 | /* |
1749 | * Obtain the status about this packet. | 1728 | * Obtain the status about this packet. |
1750 | */ | 1729 | */ |
1751 | tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | 1730 | txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); |
1752 | retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1731 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1753 | 1732 | ||
1754 | rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); | 1733 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); |
1755 | } | 1734 | } |
1756 | } | 1735 | } |
1757 | 1736 | ||
@@ -1906,7 +1885,7 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1906 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1885 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1907 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1886 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1908 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1887 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1909 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1888 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1910 | } else { | 1889 | } else { |
1911 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1890 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1912 | if (value < -10 || value > 10) | 1891 | if (value < -10 || value > 10) |
@@ -2035,35 +2014,51 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2035 | * If the eeprom value is invalid, | 2014 | * If the eeprom value is invalid, |
2036 | * switch to default led mode. | 2015 | * switch to default led mode. |
2037 | */ | 2016 | */ |
2017 | #ifdef CONFIG_RT61PCI_LEDS | ||
2038 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2018 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2039 | 2019 | ||
2040 | rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2020 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2021 | |||
2022 | switch (value) { | ||
2023 | case LED_MODE_TXRX_ACTIVITY: | ||
2024 | case LED_MODE_ASUS: | ||
2025 | case LED_MODE_ALPHA: | ||
2026 | case LED_MODE_DEFAULT: | ||
2027 | rt2x00dev->led_flags = | ||
2028 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
2029 | break; | ||
2030 | case LED_MODE_SIGNAL_STRENGTH: | ||
2031 | rt2x00dev->led_flags = | ||
2032 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
2033 | LED_SUPPORT_QUALITY; | ||
2034 | break; | ||
2035 | } | ||
2041 | 2036 | ||
2042 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 2037 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2043 | rt2x00dev->led_mode); | 2038 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
2044 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
2045 | rt2x00_get_field16(eeprom, | 2039 | rt2x00_get_field16(eeprom, |
2046 | EEPROM_LED_POLARITY_GPIO_0)); | 2040 | EEPROM_LED_POLARITY_GPIO_0)); |
2047 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 2041 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
2048 | rt2x00_get_field16(eeprom, | 2042 | rt2x00_get_field16(eeprom, |
2049 | EEPROM_LED_POLARITY_GPIO_1)); | 2043 | EEPROM_LED_POLARITY_GPIO_1)); |
2050 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 2044 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
2051 | rt2x00_get_field16(eeprom, | 2045 | rt2x00_get_field16(eeprom, |
2052 | EEPROM_LED_POLARITY_GPIO_2)); | 2046 | EEPROM_LED_POLARITY_GPIO_2)); |
2053 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 2047 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
2054 | rt2x00_get_field16(eeprom, | 2048 | rt2x00_get_field16(eeprom, |
2055 | EEPROM_LED_POLARITY_GPIO_3)); | 2049 | EEPROM_LED_POLARITY_GPIO_3)); |
2056 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 2050 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
2057 | rt2x00_get_field16(eeprom, | 2051 | rt2x00_get_field16(eeprom, |
2058 | EEPROM_LED_POLARITY_GPIO_4)); | 2052 | EEPROM_LED_POLARITY_GPIO_4)); |
2059 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 2053 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
2060 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 2054 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
2061 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 2055 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
2062 | rt2x00_get_field16(eeprom, | 2056 | rt2x00_get_field16(eeprom, |
2063 | EEPROM_LED_POLARITY_RDY_G)); | 2057 | EEPROM_LED_POLARITY_RDY_G)); |
2064 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 2058 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
2065 | rt2x00_get_field16(eeprom, | 2059 | rt2x00_get_field16(eeprom, |
2066 | EEPROM_LED_POLARITY_RDY_A)); | 2060 | EEPROM_LED_POLARITY_RDY_A)); |
2061 | #endif /* CONFIG_RT61PCI_LEDS */ | ||
2067 | 2062 | ||
2068 | return 0; | 2063 | return 0; |
2069 | } | 2064 | } |
@@ -2197,7 +2192,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2197 | rt2x00dev->hw->extra_tx_headroom = 0; | 2192 | rt2x00dev->hw->extra_tx_headroom = 0; |
2198 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 2193 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
2199 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 2194 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
2200 | rt2x00dev->hw->queues = 5; | 2195 | rt2x00dev->hw->queues = 4; |
2201 | 2196 | ||
2202 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2197 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); |
2203 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2198 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -2214,8 +2209,8 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2214 | /* | 2209 | /* |
2215 | * Initialize hw_mode information. | 2210 | * Initialize hw_mode information. |
2216 | */ | 2211 | */ |
2217 | spec->num_modes = 2; | 2212 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
2218 | spec->num_rates = 12; | 2213 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
2219 | spec->tx_power_a = NULL; | 2214 | spec->tx_power_a = NULL; |
2220 | spec->tx_power_bg = txpower; | 2215 | spec->tx_power_bg = txpower; |
2221 | spec->tx_power_default = DEFAULT_TXPOWER; | 2216 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -2230,7 +2225,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2230 | 2225 | ||
2231 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 2226 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
2232 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { | 2227 | rt2x00_rf(&rt2x00dev->chip, RF5325)) { |
2233 | spec->num_modes = 3; | 2228 | spec->supported_bands |= SUPPORT_BAND_5GHZ; |
2234 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); | 2229 | spec->num_channels = ARRAY_SIZE(rf_vals_seq); |
2235 | 2230 | ||
2236 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 2231 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
@@ -2262,9 +2257,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2262 | rt61pci_probe_hw_mode(rt2x00dev); | 2257 | rt61pci_probe_hw_mode(rt2x00dev); |
2263 | 2258 | ||
2264 | /* | 2259 | /* |
2265 | * This device requires firmware | 2260 | * This device requires firmware. |
2266 | */ | 2261 | */ |
2267 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2262 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2263 | __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags); | ||
2268 | 2264 | ||
2269 | /* | 2265 | /* |
2270 | * Set the rssi offset. | 2266 | * Set the rssi offset. |
@@ -2336,8 +2332,9 @@ static void rt61pci_configure_filter(struct ieee80211_hw *hw, | |||
2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | 2332 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); |
2337 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 2333 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
2338 | !(*total_flags & FIF_ALLMULTI)); | 2334 | !(*total_flags & FIF_ALLMULTI)); |
2339 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, 0); | 2335 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
2340 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 2336 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
2337 | !(*total_flags & FIF_CONTROL)); | ||
2341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 2338 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
2342 | } | 2339 | } |
2343 | 2340 | ||
@@ -2369,37 +2366,24 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2369 | return tsf; | 2366 | return tsf; |
2370 | } | 2367 | } |
2371 | 2368 | ||
2372 | static void rt61pci_reset_tsf(struct ieee80211_hw *hw) | ||
2373 | { | ||
2374 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2375 | |||
2376 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
2377 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
2378 | } | ||
2379 | |||
2380 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 2369 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
2381 | struct ieee80211_tx_control *control) | 2370 | struct ieee80211_tx_control *control) |
2382 | { | 2371 | { |
2383 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2372 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2384 | struct skb_desc *desc; | 2373 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
2385 | struct data_ring *ring; | 2374 | struct skb_frame_desc *skbdesc; |
2386 | struct data_entry *entry; | 2375 | unsigned int beacon_base; |
2387 | 2376 | ||
2388 | /* | 2377 | if (unlikely(!intf->beacon)) |
2389 | * Just in case the ieee80211 doesn't set this, | 2378 | return -ENOBUFS; |
2390 | * but we need this queue set for the descriptor | ||
2391 | * initialization. | ||
2392 | */ | ||
2393 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2394 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
2395 | entry = rt2x00_get_data_entry(ring); | ||
2396 | 2379 | ||
2397 | /* | 2380 | /* |
2398 | * We need to append the descriptor in front of the | 2381 | * We need to append the descriptor in front of the |
2399 | * beacon frame. | 2382 | * beacon frame. |
2400 | */ | 2383 | */ |
2401 | if (skb_headroom(skb) < TXD_DESC_SIZE) { | 2384 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { |
2402 | if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) { | 2385 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, |
2386 | 0, GFP_ATOMIC)) { | ||
2403 | dev_kfree_skb(skb); | 2387 | dev_kfree_skb(skb); |
2404 | return -ENOMEM; | 2388 | return -ENOMEM; |
2405 | } | 2389 | } |
@@ -2408,29 +2392,37 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2408 | /* | 2392 | /* |
2409 | * Add the descriptor in front of the skb. | 2393 | * Add the descriptor in front of the skb. |
2410 | */ | 2394 | */ |
2411 | skb_push(skb, ring->desc_size); | 2395 | skb_push(skb, intf->beacon->queue->desc_size); |
2412 | memset(skb->data, 0, ring->desc_size); | 2396 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2413 | 2397 | ||
2414 | /* | 2398 | /* |
2415 | * Fill in skb descriptor | 2399 | * Fill in skb descriptor |
2416 | */ | 2400 | */ |
2417 | desc = get_skb_desc(skb); | 2401 | skbdesc = get_skb_frame_desc(skb); |
2418 | desc->desc_len = ring->desc_size; | 2402 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2419 | desc->data_len = skb->len - ring->desc_size; | 2403 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
2420 | desc->desc = skb->data; | 2404 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2421 | desc->data = skb->data + ring->desc_size; | 2405 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2422 | desc->ring = ring; | 2406 | skbdesc->desc = skb->data; |
2423 | desc->entry = entry; | 2407 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2408 | skbdesc->entry = intf->beacon; | ||
2424 | 2409 | ||
2410 | /* | ||
2411 | * mac80211 doesn't provide the control->queue variable | ||
2412 | * for beacons. Set our own queue identification so | ||
2413 | * it can be used during descriptor initialization. | ||
2414 | */ | ||
2415 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2425 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2416 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2426 | 2417 | ||
2427 | /* | 2418 | /* |
2428 | * Write entire beacon with descriptor to register, | 2419 | * Write entire beacon with descriptor to register, |
2429 | * and kick the beacon generator. | 2420 | * and kick the beacon generator. |
2430 | */ | 2421 | */ |
2431 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, | 2422 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2423 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2432 | skb->data, skb->len); | 2424 | skb->data, skb->len); |
2433 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2425 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2434 | 2426 | ||
2435 | return 0; | 2427 | return 0; |
2436 | } | 2428 | } |
@@ -2450,7 +2442,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2450 | .conf_tx = rt2x00mac_conf_tx, | 2442 | .conf_tx = rt2x00mac_conf_tx, |
2451 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2443 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2452 | .get_tsf = rt61pci_get_tsf, | 2444 | .get_tsf = rt61pci_get_tsf, |
2453 | .reset_tsf = rt61pci_reset_tsf, | ||
2454 | .beacon_update = rt61pci_beacon_update, | 2445 | .beacon_update = rt61pci_beacon_update, |
2455 | }; | 2446 | }; |
2456 | 2447 | ||
@@ -2468,23 +2459,46 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2468 | .link_stats = rt61pci_link_stats, | 2459 | .link_stats = rt61pci_link_stats, |
2469 | .reset_tuner = rt61pci_reset_tuner, | 2460 | .reset_tuner = rt61pci_reset_tuner, |
2470 | .link_tuner = rt61pci_link_tuner, | 2461 | .link_tuner = rt61pci_link_tuner, |
2462 | .led_brightness = rt61pci_led_brightness, | ||
2471 | .write_tx_desc = rt61pci_write_tx_desc, | 2463 | .write_tx_desc = rt61pci_write_tx_desc, |
2472 | .write_tx_data = rt2x00pci_write_tx_data, | 2464 | .write_tx_data = rt2x00pci_write_tx_data, |
2473 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2465 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2474 | .fill_rxdone = rt61pci_fill_rxdone, | 2466 | .fill_rxdone = rt61pci_fill_rxdone, |
2475 | .config_mac_addr = rt61pci_config_mac_addr, | 2467 | .config_intf = rt61pci_config_intf, |
2476 | .config_bssid = rt61pci_config_bssid, | ||
2477 | .config_type = rt61pci_config_type, | ||
2478 | .config_preamble = rt61pci_config_preamble, | 2468 | .config_preamble = rt61pci_config_preamble, |
2479 | .config = rt61pci_config, | 2469 | .config = rt61pci_config, |
2480 | }; | 2470 | }; |
2481 | 2471 | ||
2472 | static const struct data_queue_desc rt61pci_queue_rx = { | ||
2473 | .entry_num = RX_ENTRIES, | ||
2474 | .data_size = DATA_FRAME_SIZE, | ||
2475 | .desc_size = RXD_DESC_SIZE, | ||
2476 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | ||
2477 | }; | ||
2478 | |||
2479 | static const struct data_queue_desc rt61pci_queue_tx = { | ||
2480 | .entry_num = TX_ENTRIES, | ||
2481 | .data_size = DATA_FRAME_SIZE, | ||
2482 | .desc_size = TXD_DESC_SIZE, | ||
2483 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2484 | }; | ||
2485 | |||
2486 | static const struct data_queue_desc rt61pci_queue_bcn = { | ||
2487 | .entry_num = 4 * BEACON_ENTRIES, | ||
2488 | .data_size = MGMT_FRAME_SIZE, | ||
2489 | .desc_size = TXINFO_SIZE, | ||
2490 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | ||
2491 | }; | ||
2492 | |||
2482 | static const struct rt2x00_ops rt61pci_ops = { | 2493 | static const struct rt2x00_ops rt61pci_ops = { |
2483 | .name = KBUILD_MODNAME, | 2494 | .name = KBUILD_MODNAME, |
2484 | .rxd_size = RXD_DESC_SIZE, | 2495 | .max_sta_intf = 1, |
2485 | .txd_size = TXD_DESC_SIZE, | 2496 | .max_ap_intf = 4, |
2486 | .eeprom_size = EEPROM_SIZE, | 2497 | .eeprom_size = EEPROM_SIZE, |
2487 | .rf_size = RF_SIZE, | 2498 | .rf_size = RF_SIZE, |
2499 | .rx = &rt61pci_queue_rx, | ||
2500 | .tx = &rt61pci_queue_tx, | ||
2501 | .bcn = &rt61pci_queue_bcn, | ||
2488 | .lib = &rt61pci_rt2x00_ops, | 2502 | .lib = &rt61pci_rt2x00_ops, |
2489 | .hw = &rt61pci_mac80211_ops, | 2503 | .hw = &rt61pci_mac80211_ops, |
2490 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2504 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 4c6524eedad0..3511bba7ff65 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -161,7 +161,9 @@ struct hw_pairwise_ta_entry { | |||
161 | #define HW_BEACON_BASE1 0x2d00 | 161 | #define HW_BEACON_BASE1 0x2d00 |
162 | #define HW_BEACON_BASE2 0x2e00 | 162 | #define HW_BEACON_BASE2 0x2e00 |
163 | #define HW_BEACON_BASE3 0x2f00 | 163 | #define HW_BEACON_BASE3 0x2f00 |
164 | #define HW_BEACON_OFFSET 0x0100 | 164 | |
165 | #define HW_BEACON_OFFSET(__index) \ | ||
166 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
165 | 167 | ||
166 | /* | 168 | /* |
167 | * HOST-MCU shared memory. | 169 | * HOST-MCU shared memory. |
@@ -234,6 +236,11 @@ struct hw_pairwise_ta_entry { | |||
234 | 236 | ||
235 | /* | 237 | /* |
236 | * MAC_CSR3: STA MAC register 1. | 238 | * MAC_CSR3: STA MAC register 1. |
239 | * UNICAST_TO_ME_MASK: | ||
240 | * Used to mask off bits from byte 5 of the MAC address | ||
241 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
242 | * The full mask is complemented by BSS_ID_MASK: | ||
243 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
237 | */ | 244 | */ |
238 | #define MAC_CSR3 0x300c | 245 | #define MAC_CSR3 0x300c |
239 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 246 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -251,7 +258,14 @@ struct hw_pairwise_ta_entry { | |||
251 | 258 | ||
252 | /* | 259 | /* |
253 | * MAC_CSR5: BSSID register 1. | 260 | * MAC_CSR5: BSSID register 1. |
254 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 261 | * BSS_ID_MASK: |
262 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
263 | * BSSID. This will make sure that those bits will be ignored | ||
264 | * when determining the MY_BSS of RX frames. | ||
265 | * 0: 1-BSSID mode (BSS index = 0) | ||
266 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
267 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
268 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
255 | */ | 269 | */ |
256 | #define MAC_CSR5 0x3014 | 270 | #define MAC_CSR5 0x3014 |
257 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 271 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -391,7 +405,7 @@ struct hw_pairwise_ta_entry { | |||
391 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) | 405 | #define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000) |
392 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) | 406 | #define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000) |
393 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) | 407 | #define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000) |
394 | #define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000) | 408 | #define TXRX_CSR0_DROP_BROADCAST FIELD32(0x01000000) |
395 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) | 409 | #define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000) |
396 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) | 410 | #define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000) |
397 | 411 | ||
@@ -866,7 +880,7 @@ struct hw_pairwise_ta_entry { | |||
866 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) | 880 | #define TX_CNTL_CSR_ABORT_TX_MGMT FIELD32(0x00100000) |
867 | 881 | ||
868 | /* | 882 | /* |
869 | * LOAD_TX_RING_CSR: Load RX de | 883 | * LOAD_TX_RING_CSR: Load RX desriptor |
870 | */ | 884 | */ |
871 | #define LOAD_TX_RING_CSR 0x3434 | 885 | #define LOAD_TX_RING_CSR 0x3434 |
872 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) | 886 | #define LOAD_TX_RING_CSR_LOAD_TXD_AC0 FIELD32(0x00000001) |
@@ -1116,10 +1130,10 @@ struct hw_pairwise_ta_entry { | |||
1116 | #define EEPROM_MAC_ADDR_0 0x0002 | 1130 | #define EEPROM_MAC_ADDR_0 0x0002 |
1117 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) | 1131 | #define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) |
1118 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) | 1132 | #define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) |
1119 | #define EEPROM_MAC_ADDR1 0x0004 | 1133 | #define EEPROM_MAC_ADDR1 0x0003 |
1120 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) | 1134 | #define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) |
1121 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) | 1135 | #define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) |
1122 | #define EEPROM_MAC_ADDR_2 0x0006 | 1136 | #define EEPROM_MAC_ADDR_2 0x0004 |
1123 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) | 1137 | #define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) |
1124 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) | 1138 | #define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) |
1125 | 1139 | ||
@@ -1247,6 +1261,7 @@ struct hw_pairwise_ta_entry { | |||
1247 | * DMA descriptor defines. | 1261 | * DMA descriptor defines. |
1248 | */ | 1262 | */ |
1249 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1263 | #define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1264 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
1250 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) | 1265 | #define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) |
1251 | 1266 | ||
1252 | /* | 1267 | /* |
@@ -1440,8 +1455,8 @@ struct hw_pairwise_ta_entry { | |||
1440 | #define RXD_W15_RESERVED FIELD32(0xffffffff) | 1455 | #define RXD_W15_RESERVED FIELD32(0xffffffff) |
1441 | 1456 | ||
1442 | /* | 1457 | /* |
1443 | * Macro's for converting txpower from EEPROM to dscape value | 1458 | * Macro's for converting txpower from EEPROM to mac80211 value |
1444 | * and from dscape value to register value. | 1459 | * and from mac80211 value to register value. |
1445 | */ | 1460 | */ |
1446 | #define MIN_TXPOWER 0 | 1461 | #define MIN_TXPOWER 0 |
1447 | #define MAX_TXPOWER 31 | 1462 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 4fac2d414d84..6546b0d607b9 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -278,77 +278,122 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
278 | }; | 278 | }; |
279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | 279 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ |
280 | 280 | ||
281 | /* | 281 | #ifdef CONFIG_RT73USB_LEDS |
282 | * Configuration handlers. | 282 | static void rt73usb_led_brightness(struct led_classdev *led_cdev, |
283 | */ | 283 | enum led_brightness brightness) |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | ||
285 | { | 284 | { |
286 | u32 tmp; | 285 | struct rt2x00_led *led = |
286 | container_of(led_cdev, struct rt2x00_led, led_dev); | ||
287 | unsigned int enabled = brightness != LED_OFF; | ||
288 | unsigned int a_mode = | ||
289 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
290 | unsigned int bg_mode = | ||
291 | (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); | ||
287 | 292 | ||
288 | tmp = le32_to_cpu(mac[1]); | 293 | if (in_atomic()) { |
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | 294 | NOTICE(led->rt2x00dev, |
290 | mac[1] = cpu_to_le32(tmp); | 295 | "Ignoring LED brightness command for led %d", led->type); |
296 | return; | ||
297 | } | ||
291 | 298 | ||
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 299 | if (led->type == LED_TYPE_RADIO) { |
293 | (2 * sizeof(__le32))); | 300 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, |
301 | MCU_LEDCS_RADIO_STATUS, enabled); | ||
302 | |||
303 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
304 | 0, led->rt2x00dev->led_mcu_reg, | ||
305 | REGISTER_TIMEOUT); | ||
306 | } else if (led->type == LED_TYPE_ASSOC) { | ||
307 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
308 | MCU_LEDCS_LINK_BG_STATUS, bg_mode); | ||
309 | rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, | ||
310 | MCU_LEDCS_LINK_A_STATUS, a_mode); | ||
311 | |||
312 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
313 | 0, led->rt2x00dev->led_mcu_reg, | ||
314 | REGISTER_TIMEOUT); | ||
315 | } else if (led->type == LED_TYPE_QUALITY) { | ||
316 | /* | ||
317 | * The brightness is divided into 6 levels (0 - 5), | ||
318 | * this means we need to convert the brightness | ||
319 | * argument into the matching level within that range. | ||
320 | */ | ||
321 | rt2x00usb_vendor_request_sw(led->rt2x00dev, USB_LED_CONTROL, | ||
322 | brightness / (LED_FULL / 6), | ||
323 | led->rt2x00dev->led_mcu_reg, | ||
324 | REGISTER_TIMEOUT); | ||
325 | } | ||
294 | } | 326 | } |
327 | #else | ||
328 | #define rt73usb_led_brightness NULL | ||
329 | #endif /* CONFIG_RT73USB_LEDS */ | ||
295 | 330 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 331 | /* |
332 | * Configuration handlers. | ||
333 | */ | ||
334 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | ||
335 | struct rt2x00_intf *intf, | ||
336 | struct rt2x00intf_conf *conf, | ||
337 | const unsigned int flags) | ||
297 | { | 338 | { |
298 | u32 tmp; | 339 | unsigned int beacon_base; |
340 | u32 reg; | ||
299 | 341 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 342 | if (flags & CONFIG_UPDATE_TYPE) { |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 343 | /* |
302 | bssid[1] = cpu_to_le32(tmp); | 344 | * Clear current synchronisation setup. |
345 | * For the Beacon base registers we only need to clear | ||
346 | * the first byte since that byte contains the VALID and OWNER | ||
347 | * bits which (when set to 0) will invalidate the entire beacon. | ||
348 | */ | ||
349 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
350 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
351 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
303 | 352 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 353 | /* |
305 | (2 * sizeof(__le32))); | 354 | * Enable synchronisation. |
306 | } | 355 | */ |
356 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
357 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
358 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
359 | (conf->sync == TSF_SYNC_BEACON)); | ||
360 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
361 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
362 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
363 | } | ||
307 | 364 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 365 | if (flags & CONFIG_UPDATE_MAC) { |
309 | const int tsf_sync) | 366 | reg = le32_to_cpu(conf->mac[1]); |
310 | { | 367 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
311 | u32 reg; | 368 | conf->mac[1] = cpu_to_le32(reg); |
312 | 369 | ||
313 | /* | 370 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, |
314 | * Clear current synchronisation setup. | 371 | conf->mac, sizeof(conf->mac)); |
315 | * For the Beacon base registers we only need to clear | 372 | } |
316 | * the first byte since that byte contains the VALID and OWNER | ||
317 | * bits which (when set to 0) will invalidate the entire beacon. | ||
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | 373 | ||
325 | /* | 374 | if (flags & CONFIG_UPDATE_BSSID) { |
326 | * Enable synchronisation. | 375 | reg = le32_to_cpu(conf->bssid[1]); |
327 | */ | 376 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 377 | conf->bssid[1] = cpu_to_le32(reg); |
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | 378 | |
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | 379 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 380 | conf->bssid, sizeof(conf->bssid)); |
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 381 | } |
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
335 | } | 382 | } |
336 | 383 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 384 | static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 385 | const int short_preamble, |
339 | const int ack_timeout, | 386 | const int ack_timeout, |
340 | const int ack_consume_time) | 387 | const int ack_consume_time) |
341 | { | 388 | { |
342 | u32 reg; | 389 | u32 reg; |
343 | 390 | ||
344 | /* | 391 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 392 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 393 | * try this configuration again later. |
347 | */ | 394 | */ |
348 | if (in_atomic()) { | 395 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 396 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 397 | ||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 398 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 399 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); |
@@ -358,6 +403,8 @@ static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 403 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 404 | !!short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 405 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
406 | |||
407 | return 0; | ||
361 | } | 408 | } |
362 | 409 | ||
363 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 410 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -442,13 +489,13 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
442 | case ANTENNA_HW_DIVERSITY: | 489 | case ANTENNA_HW_DIVERSITY: |
443 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); | 490 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); |
444 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) | 491 | temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) |
445 | && (rt2x00dev->curr_hwmode != HWMODE_A); | 492 | && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); |
446 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); | 493 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); |
447 | break; | 494 | break; |
448 | case ANTENNA_A: | 495 | case ANTENNA_A: |
449 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 496 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
450 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 497 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
451 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 498 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
452 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 499 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
453 | else | 500 | else |
454 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 501 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
@@ -463,7 +510,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, | |||
463 | case ANTENNA_B: | 510 | case ANTENNA_B: |
464 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); | 511 | rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); |
465 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); | 512 | rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); |
466 | if (rt2x00dev->curr_hwmode == HWMODE_A) | 513 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) |
467 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); | 514 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); |
468 | else | 515 | else |
469 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); | 516 | rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); |
@@ -558,7 +605,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
558 | unsigned int i; | 605 | unsigned int i; |
559 | u32 reg; | 606 | u32 reg; |
560 | 607 | ||
561 | if (rt2x00dev->curr_hwmode == HWMODE_A) { | 608 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { |
562 | sel = antenna_sel_a; | 609 | sel = antenna_sel_a; |
563 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); | 610 | lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); |
564 | } else { | 611 | } else { |
@@ -572,10 +619,9 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
572 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); | 619 | rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); |
573 | 620 | ||
574 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, | 621 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, |
575 | (rt2x00dev->curr_hwmode == HWMODE_B || | 622 | (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ)); |
576 | rt2x00dev->curr_hwmode == HWMODE_G)); | ||
577 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, | 623 | rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, |
578 | (rt2x00dev->curr_hwmode == HWMODE_A)); | 624 | (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ)); |
579 | 625 | ||
580 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); | 626 | rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); |
581 | 627 | ||
@@ -617,8 +663,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 663 | } |
618 | 664 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 665 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 666 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 667 | const unsigned int flags) |
622 | { | 668 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 669 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 670 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -634,68 +680,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | |||
634 | } | 680 | } |
635 | 681 | ||
636 | /* | 682 | /* |
637 | * LED functions. | ||
638 | */ | ||
639 | static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) | ||
640 | { | ||
641 | u32 reg; | ||
642 | |||
643 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
644 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
645 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
646 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
647 | |||
648 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); | ||
649 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, | ||
650 | (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); | ||
651 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, | ||
652 | (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); | ||
653 | |||
654 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
655 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
656 | } | ||
657 | |||
658 | static void rt73usb_disable_led(struct rt2x00_dev *rt2x00dev) | ||
659 | { | ||
660 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 0); | ||
661 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); | ||
662 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, 0); | ||
663 | |||
664 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, | ||
665 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
666 | } | ||
667 | |||
668 | static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) | ||
669 | { | ||
670 | u32 led; | ||
671 | |||
672 | if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) | ||
673 | return; | ||
674 | |||
675 | /* | ||
676 | * Led handling requires a positive value for the rssi, | ||
677 | * to do that correctly we need to add the correction. | ||
678 | */ | ||
679 | rssi += rt2x00dev->rssi_offset; | ||
680 | |||
681 | if (rssi <= 30) | ||
682 | led = 0; | ||
683 | else if (rssi <= 39) | ||
684 | led = 1; | ||
685 | else if (rssi <= 49) | ||
686 | led = 2; | ||
687 | else if (rssi <= 53) | ||
688 | led = 3; | ||
689 | else if (rssi <= 63) | ||
690 | led = 4; | ||
691 | else | ||
692 | led = 5; | ||
693 | |||
694 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, led, | ||
695 | rt2x00dev->led_reg, REGISTER_TIMEOUT); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Link tuning | 683 | * Link tuning |
700 | */ | 684 | */ |
701 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | 685 | static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, |
@@ -729,17 +713,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
729 | u8 up_bound; | 713 | u8 up_bound; |
730 | u8 low_bound; | 714 | u8 low_bound; |
731 | 715 | ||
732 | /* | ||
733 | * Update Led strength | ||
734 | */ | ||
735 | rt73usb_activity_led(rt2x00dev, rssi); | ||
736 | |||
737 | rt73usb_bbp_read(rt2x00dev, 17, &r17); | 716 | rt73usb_bbp_read(rt2x00dev, 17, &r17); |
738 | 717 | ||
739 | /* | 718 | /* |
740 | * Determine r17 bounds. | 719 | * Determine r17 bounds. |
741 | */ | 720 | */ |
742 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 721 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
743 | low_bound = 0x28; | 722 | low_bound = 0x28; |
744 | up_bound = 0x48; | 723 | up_bound = 0x48; |
745 | 724 | ||
@@ -766,6 +745,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 745 | } |
767 | 746 | ||
768 | /* | 747 | /* |
748 | * If we are not associated, we should go straight to the | ||
749 | * dynamic CCA tuning. | ||
750 | */ | ||
751 | if (!rt2x00dev->intf_associated) | ||
752 | goto dynamic_cca_tune; | ||
753 | |||
754 | /* | ||
769 | * Special big-R17 for very short distance | 755 | * Special big-R17 for very short distance |
770 | */ | 756 | */ |
771 | if (rssi > -35) { | 757 | if (rssi > -35) { |
@@ -815,6 +801,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 801 | return; |
816 | } | 802 | } |
817 | 803 | ||
804 | dynamic_cca_tune: | ||
805 | |||
818 | /* | 806 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 807 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 808 | * the r17 tuning on the false CCA count. |
@@ -889,7 +877,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
889 | 877 | ||
890 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 878 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
891 | USB_VENDOR_REQUEST_OUT, | 879 | USB_VENDOR_REQUEST_OUT, |
892 | FIRMWARE_IMAGE_BASE + i, 0x0000, | 880 | FIRMWARE_IMAGE_BASE + i, 0, |
893 | cache, buflen, timeout); | 881 | cache, buflen, timeout); |
894 | 882 | ||
895 | ptr += buflen; | 883 | ptr += buflen; |
@@ -902,15 +890,13 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, | |||
902 | * we need to specify a long timeout time. | 890 | * we need to specify a long timeout time. |
903 | */ | 891 | */ |
904 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, | 892 | status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, |
905 | 0x0000, USB_MODE_FIRMWARE, | 893 | 0, USB_MODE_FIRMWARE, |
906 | REGISTER_TIMEOUT_FIRMWARE); | 894 | REGISTER_TIMEOUT_FIRMWARE); |
907 | if (status < 0) { | 895 | if (status < 0) { |
908 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); | 896 | ERROR(rt2x00dev, "Failed to write Firmware to device.\n"); |
909 | return status; | 897 | return status; |
910 | } | 898 | } |
911 | 899 | ||
912 | rt73usb_disable_led(rt2x00dev); | ||
913 | |||
914 | return 0; | 900 | return 0; |
915 | } | 901 | } |
916 | 902 | ||
@@ -988,6 +974,11 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
988 | 974 | ||
989 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); | 975 | rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00); |
990 | 976 | ||
977 | rt73usb_register_read(rt2x00dev, MAC_CSR14, ®); | ||
978 | rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); | ||
979 | rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); | ||
980 | rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); | ||
981 | |||
991 | /* | 982 | /* |
992 | * Invalidate all Shared Keys (SEC_CSR0), | 983 | * Invalidate all Shared Keys (SEC_CSR0), |
993 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) | 984 | * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) |
@@ -1021,6 +1012,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1012 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1013 | ||
1023 | /* | 1014 | /* |
1015 | * Clear all beacons | ||
1016 | * For the Beacon base registers we only need to clear | ||
1017 | * the first byte since that byte contains the VALID and OWNER | ||
1018 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1019 | */ | ||
1020 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1021 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1022 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1023 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1024 | |||
1025 | /* | ||
1024 | * We must clear the error counters. | 1026 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1027 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1028 | * so we may pass a useless variable to store the value. |
@@ -1094,19 +1096,15 @@ continue_csr_init: | |||
1094 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); | 1096 | rt73usb_bbp_write(rt2x00dev, 102, 0x16); |
1095 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); | 1097 | rt73usb_bbp_write(rt2x00dev, 107, 0x04); |
1096 | 1098 | ||
1097 | DEBUG(rt2x00dev, "Start initialization from EEPROM...\n"); | ||
1098 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 1099 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
1099 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 1100 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
1100 | 1101 | ||
1101 | if (eeprom != 0xffff && eeprom != 0x0000) { | 1102 | if (eeprom != 0xffff && eeprom != 0x0000) { |
1102 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); | 1103 | reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID); |
1103 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); | 1104 | value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE); |
1104 | DEBUG(rt2x00dev, "BBP: 0x%02x, value: 0x%02x.\n", | ||
1105 | reg_id, value); | ||
1106 | rt73usb_bbp_write(rt2x00dev, reg_id, value); | 1105 | rt73usb_bbp_write(rt2x00dev, reg_id, value); |
1107 | } | 1106 | } |
1108 | } | 1107 | } |
1109 | DEBUG(rt2x00dev, "...End initialization from EEPROM.\n"); | ||
1110 | 1108 | ||
1111 | return 0; | 1109 | return 0; |
1112 | } | 1110 | } |
@@ -1136,21 +1134,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1136 | return -EIO; | 1134 | return -EIO; |
1137 | } | 1135 | } |
1138 | 1136 | ||
1139 | /* | ||
1140 | * Enable LED | ||
1141 | */ | ||
1142 | rt73usb_enable_led(rt2x00dev); | ||
1143 | |||
1144 | return 0; | 1137 | return 0; |
1145 | } | 1138 | } |
1146 | 1139 | ||
1147 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) | 1140 | static void rt73usb_disable_radio(struct rt2x00_dev *rt2x00dev) |
1148 | { | 1141 | { |
1149 | /* | ||
1150 | * Disable LED | ||
1151 | */ | ||
1152 | rt73usb_disable_led(rt2x00dev); | ||
1153 | |||
1154 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); | 1142 | rt73usb_register_write(rt2x00dev, MAC_CSR10, 0x00001818); |
1155 | 1143 | ||
1156 | /* | 1144 | /* |
@@ -1234,10 +1222,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1234 | */ | 1222 | */ |
1235 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1223 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1236 | struct sk_buff *skb, | 1224 | struct sk_buff *skb, |
1237 | struct txdata_entry_desc *desc, | 1225 | struct txentry_desc *txdesc, |
1238 | struct ieee80211_tx_control *control) | 1226 | struct ieee80211_tx_control *control) |
1239 | { | 1227 | { |
1240 | struct skb_desc *skbdesc = get_skb_desc(skb); | 1228 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1241 | __le32 *txd = skbdesc->desc; | 1229 | __le32 *txd = skbdesc->desc; |
1242 | u32 word; | 1230 | u32 word; |
1243 | 1231 | ||
@@ -1245,47 +1233,47 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1245 | * Start writing the descriptor words. | 1233 | * Start writing the descriptor words. |
1246 | */ | 1234 | */ |
1247 | rt2x00_desc_read(txd, 1, &word); | 1235 | rt2x00_desc_read(txd, 1, &word); |
1248 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue); | 1236 | rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); |
1249 | rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs); | 1237 | rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); |
1250 | rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min); | 1238 | rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); |
1251 | rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max); | 1239 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1252 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1240 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1253 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1241 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1254 | rt2x00_desc_write(txd, 1, word); | 1242 | rt2x00_desc_write(txd, 1, word); |
1255 | 1243 | ||
1256 | rt2x00_desc_read(txd, 2, &word); | 1244 | rt2x00_desc_read(txd, 2, &word); |
1257 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, desc->signal); | 1245 | rt2x00_set_field32(&word, TXD_W2_PLCP_SIGNAL, txdesc->signal); |
1258 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, desc->service); | 1246 | rt2x00_set_field32(&word, TXD_W2_PLCP_SERVICE, txdesc->service); |
1259 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, desc->length_low); | 1247 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_LOW, txdesc->length_low); |
1260 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, desc->length_high); | 1248 | rt2x00_set_field32(&word, TXD_W2_PLCP_LENGTH_HIGH, txdesc->length_high); |
1261 | rt2x00_desc_write(txd, 2, word); | 1249 | rt2x00_desc_write(txd, 2, word); |
1262 | 1250 | ||
1263 | rt2x00_desc_read(txd, 5, &word); | 1251 | rt2x00_desc_read(txd, 5, &word); |
1264 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1252 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1265 | TXPOWER_TO_DEV(control->power_level)); | 1253 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1266 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1254 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1267 | rt2x00_desc_write(txd, 5, word); | 1255 | rt2x00_desc_write(txd, 5, word); |
1268 | 1256 | ||
1269 | rt2x00_desc_read(txd, 0, &word); | 1257 | rt2x00_desc_read(txd, 0, &word); |
1270 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1258 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1271 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1259 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1272 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); | 1260 | rt2x00_set_field32(&word, TXD_W0_VALID, 1); |
1273 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, | 1261 | rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, |
1274 | test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); | 1262 | test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); |
1275 | rt2x00_set_field32(&word, TXD_W0_ACK, | 1263 | rt2x00_set_field32(&word, TXD_W0_ACK, |
1276 | test_bit(ENTRY_TXD_ACK, &desc->flags)); | 1264 | test_bit(ENTRY_TXD_ACK, &txdesc->flags)); |
1277 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, | 1265 | rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, |
1278 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); | 1266 | test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); |
1279 | rt2x00_set_field32(&word, TXD_W0_OFDM, | 1267 | rt2x00_set_field32(&word, TXD_W0_OFDM, |
1280 | test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags)); | 1268 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1281 | rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs); | 1269 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1282 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1270 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1283 | !!(control->flags & | 1271 | !!(control->flags & |
1284 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | 1272 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); |
1285 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1273 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1286 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1274 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); |
1287 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1275 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1288 | test_bit(ENTRY_TXD_BURST, &desc->flags)); | 1276 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1289 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1277 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1290 | rt2x00_desc_write(txd, 0, word); | 1278 | rt2x00_desc_write(txd, 0, word); |
1291 | } | 1279 | } |
@@ -1309,11 +1297,11 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1309 | * TX data initialization | 1297 | * TX data initialization |
1310 | */ | 1298 | */ |
1311 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1299 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1312 | unsigned int queue) | 1300 | const unsigned int queue) |
1313 | { | 1301 | { |
1314 | u32 reg; | 1302 | u32 reg; |
1315 | 1303 | ||
1316 | if (queue != IEEE80211_TX_QUEUE_BEACON) | 1304 | if (queue != RT2X00_BCN_QUEUE_BEACON) |
1317 | return; | 1305 | return; |
1318 | 1306 | ||
1319 | /* | 1307 | /* |
@@ -1353,7 +1341,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1353 | return 0; | 1341 | return 0; |
1354 | } | 1342 | } |
1355 | 1343 | ||
1356 | if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) { | 1344 | if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { |
1357 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { | 1345 | if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { |
1358 | if (lna == 3 || lna == 2) | 1346 | if (lna == 3 || lna == 2) |
1359 | offset += 10; | 1347 | offset += 10; |
@@ -1377,37 +1365,57 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1377 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; | 1365 | return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset; |
1378 | } | 1366 | } |
1379 | 1367 | ||
1380 | static void rt73usb_fill_rxdone(struct data_entry *entry, | 1368 | static void rt73usb_fill_rxdone(struct queue_entry *entry, |
1381 | struct rxdata_entry_desc *desc) | 1369 | struct rxdone_entry_desc *rxdesc) |
1382 | { | 1370 | { |
1383 | struct skb_desc *skbdesc = get_skb_desc(entry->skb); | 1371 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1384 | __le32 *rxd = (__le32 *)entry->skb->data; | 1372 | __le32 *rxd = (__le32 *)entry->skb->data; |
1373 | struct ieee80211_hdr *hdr = | ||
1374 | (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size; | ||
1375 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1385 | u32 word0; | 1376 | u32 word0; |
1386 | u32 word1; | 1377 | u32 word1; |
1387 | 1378 | ||
1388 | rt2x00_desc_read(rxd, 0, &word0); | 1379 | rt2x00_desc_read(rxd, 0, &word0); |
1389 | rt2x00_desc_read(rxd, 1, &word1); | 1380 | rt2x00_desc_read(rxd, 1, &word1); |
1390 | 1381 | ||
1391 | desc->flags = 0; | 1382 | rxdesc->flags = 0; |
1392 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1383 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1393 | desc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1384 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1394 | 1385 | ||
1395 | /* | 1386 | /* |
1396 | * Obtain the status about this packet. | 1387 | * Obtain the status about this packet. |
1397 | */ | 1388 | */ |
1398 | desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); | 1389 | rxdesc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL); |
1399 | desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1); | 1390 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1400 | desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); | 1391 | rxdesc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM); |
1401 | desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1392 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1402 | desc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1393 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1394 | |||
1395 | /* | ||
1396 | * The data behind the ieee80211 header must be | ||
1397 | * aligned on a 4 byte boundary. | ||
1398 | */ | ||
1399 | if (header_size % 4 == 0) { | ||
1400 | skb_push(entry->skb, 2); | ||
1401 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1402 | entry->skb->len - 2); | ||
1403 | } | ||
1403 | 1404 | ||
1404 | /* | 1405 | /* |
1405 | * Set descriptor and data pointer. | 1406 | * Set descriptor and data pointer. |
1406 | */ | 1407 | */ |
1408 | skbdesc->data = entry->skb->data + entry->queue->desc_size; | ||
1409 | skbdesc->data_len = rxdesc->size; | ||
1407 | skbdesc->desc = entry->skb->data; | 1410 | skbdesc->desc = entry->skb->data; |
1408 | skbdesc->desc_len = entry->ring->desc_size; | 1411 | skbdesc->desc_len = entry->queue->desc_size; |
1409 | skbdesc->data = entry->skb->data + entry->ring->desc_size; | 1412 | |
1410 | skbdesc->data_len = desc->size; | 1413 | /* |
1414 | * Remove descriptor from skb buffer and trim the whole thing | ||
1415 | * down to only contain data. | ||
1416 | */ | ||
1417 | skb_pull(entry->skb, skbdesc->desc_len); | ||
1418 | skb_trim(entry->skb, rxdesc->size); | ||
1411 | } | 1419 | } |
1412 | 1420 | ||
1413 | /* | 1421 | /* |
@@ -1499,7 +1507,7 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1499 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); | 1507 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_1, 0); |
1500 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); | 1508 | rt2x00_set_field16(&word, EEPROM_RSSI_OFFSET_A_2, 0); |
1501 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); | 1509 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_OFFSET_A, word); |
1502 | EEPROM(rt2x00dev, "RSSI OFFSET BG: 0x%04x\n", word); | 1510 | EEPROM(rt2x00dev, "RSSI OFFSET A: 0x%04x\n", word); |
1503 | } else { | 1511 | } else { |
1504 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); | 1512 | value = rt2x00_get_field16(word, EEPROM_RSSI_OFFSET_A_1); |
1505 | if (value < -10 || value > 10) | 1513 | if (value < -10 || value > 10) |
@@ -1577,33 +1585,49 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1577 | /* | 1585 | /* |
1578 | * Store led settings, for correct led behaviour. | 1586 | * Store led settings, for correct led behaviour. |
1579 | */ | 1587 | */ |
1588 | #ifdef CONFIG_RT73USB_LEDS | ||
1580 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1589 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1581 | 1590 | ||
1582 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, | 1591 | switch (value) { |
1583 | rt2x00dev->led_mode); | 1592 | case LED_MODE_TXRX_ACTIVITY: |
1584 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1593 | case LED_MODE_ASUS: |
1594 | case LED_MODE_ALPHA: | ||
1595 | case LED_MODE_DEFAULT: | ||
1596 | rt2x00dev->led_flags = | ||
1597 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; | ||
1598 | break; | ||
1599 | case LED_MODE_SIGNAL_STRENGTH: | ||
1600 | rt2x00dev->led_flags = | ||
1601 | LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | | ||
1602 | LED_SUPPORT_QUALITY; | ||
1603 | break; | ||
1604 | } | ||
1605 | |||
1606 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | ||
1607 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | ||
1585 | rt2x00_get_field16(eeprom, | 1608 | rt2x00_get_field16(eeprom, |
1586 | EEPROM_LED_POLARITY_GPIO_0)); | 1609 | EEPROM_LED_POLARITY_GPIO_0)); |
1587 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, | 1610 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, |
1588 | rt2x00_get_field16(eeprom, | 1611 | rt2x00_get_field16(eeprom, |
1589 | EEPROM_LED_POLARITY_GPIO_1)); | 1612 | EEPROM_LED_POLARITY_GPIO_1)); |
1590 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, | 1613 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, |
1591 | rt2x00_get_field16(eeprom, | 1614 | rt2x00_get_field16(eeprom, |
1592 | EEPROM_LED_POLARITY_GPIO_2)); | 1615 | EEPROM_LED_POLARITY_GPIO_2)); |
1593 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, | 1616 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, |
1594 | rt2x00_get_field16(eeprom, | 1617 | rt2x00_get_field16(eeprom, |
1595 | EEPROM_LED_POLARITY_GPIO_3)); | 1618 | EEPROM_LED_POLARITY_GPIO_3)); |
1596 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, | 1619 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, |
1597 | rt2x00_get_field16(eeprom, | 1620 | rt2x00_get_field16(eeprom, |
1598 | EEPROM_LED_POLARITY_GPIO_4)); | 1621 | EEPROM_LED_POLARITY_GPIO_4)); |
1599 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, | 1622 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, |
1600 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); | 1623 | rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); |
1601 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, | 1624 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, |
1602 | rt2x00_get_field16(eeprom, | 1625 | rt2x00_get_field16(eeprom, |
1603 | EEPROM_LED_POLARITY_RDY_G)); | 1626 | EEPROM_LED_POLARITY_RDY_G)); |
1604 | rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, | 1627 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, |
1605 | rt2x00_get_field16(eeprom, | 1628 | rt2x00_get_field16(eeprom, |
1606 | EEPROM_LED_POLARITY_RDY_A)); | 1629 | EEPROM_LED_POLARITY_RDY_A)); |
1630 | #endif /* CONFIG_RT73USB_LEDS */ | ||
1607 | 1631 | ||
1608 | return 0; | 1632 | return 0; |
1609 | } | 1633 | } |
@@ -1759,7 +1783,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1759 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1783 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1760 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | 1784 | rt2x00dev->hw->max_signal = MAX_SIGNAL; |
1761 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | 1785 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; |
1762 | rt2x00dev->hw->queues = 5; | 1786 | rt2x00dev->hw->queues = 4; |
1763 | 1787 | ||
1764 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1788 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); |
1765 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1789 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
@@ -1776,8 +1800,8 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1776 | /* | 1800 | /* |
1777 | * Initialize hw_mode information. | 1801 | * Initialize hw_mode information. |
1778 | */ | 1802 | */ |
1779 | spec->num_modes = 2; | 1803 | spec->supported_bands = SUPPORT_BAND_2GHZ; |
1780 | spec->num_rates = 12; | 1804 | spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; |
1781 | spec->tx_power_a = NULL; | 1805 | spec->tx_power_a = NULL; |
1782 | spec->tx_power_bg = txpower; | 1806 | spec->tx_power_bg = txpower; |
1783 | spec->tx_power_default = DEFAULT_TXPOWER; | 1807 | spec->tx_power_default = DEFAULT_TXPOWER; |
@@ -1786,20 +1810,20 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1786 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); | 1810 | spec->num_channels = ARRAY_SIZE(rf_vals_bg_2528); |
1787 | spec->channels = rf_vals_bg_2528; | 1811 | spec->channels = rf_vals_bg_2528; |
1788 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1812 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1813 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1789 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); | 1814 | spec->num_channels = ARRAY_SIZE(rf_vals_5226); |
1790 | spec->channels = rf_vals_5226; | 1815 | spec->channels = rf_vals_5226; |
1791 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { | 1816 | } else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) { |
1792 | spec->num_channels = 14; | 1817 | spec->num_channels = 14; |
1793 | spec->channels = rf_vals_5225_2527; | 1818 | spec->channels = rf_vals_5225_2527; |
1794 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { | 1819 | } else if (rt2x00_rf(&rt2x00dev->chip, RF5225)) { |
1820 | spec->supported_bands |= SUPPORT_BAND_5GHZ; | ||
1795 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); | 1821 | spec->num_channels = ARRAY_SIZE(rf_vals_5225_2527); |
1796 | spec->channels = rf_vals_5225_2527; | 1822 | spec->channels = rf_vals_5225_2527; |
1797 | } | 1823 | } |
1798 | 1824 | ||
1799 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 1825 | if (rt2x00_rf(&rt2x00dev->chip, RF5225) || |
1800 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { | 1826 | rt2x00_rf(&rt2x00dev->chip, RF5226)) { |
1801 | spec->num_modes = 3; | ||
1802 | |||
1803 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); | 1827 | txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); |
1804 | for (i = 0; i < 14; i++) | 1828 | for (i = 0; i < 14; i++) |
1805 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); | 1829 | txpower[i] = TXPOWER_FROM_DEV(txpower[i]); |
@@ -1829,9 +1853,10 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1829 | rt73usb_probe_hw_mode(rt2x00dev); | 1853 | rt73usb_probe_hw_mode(rt2x00dev); |
1830 | 1854 | ||
1831 | /* | 1855 | /* |
1832 | * This device requires firmware | 1856 | * This device requires firmware. |
1833 | */ | 1857 | */ |
1834 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1858 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1859 | __set_bit(DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, &rt2x00dev->flags); | ||
1835 | 1860 | ||
1836 | /* | 1861 | /* |
1837 | * Set the rssi offset. | 1862 | * Set the rssi offset. |
@@ -1913,7 +1938,8 @@ static void rt73usb_configure_filter(struct ieee80211_hw *hw, | |||
1913 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | 1938 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, |
1914 | !(*total_flags & FIF_ALLMULTI)); | 1939 | !(*total_flags & FIF_ALLMULTI)); |
1915 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | 1940 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); |
1916 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1); | 1941 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, |
1942 | !(*total_flags & FIF_CONTROL)); | ||
1917 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 1943 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
1918 | } | 1944 | } |
1919 | 1945 | ||
@@ -1955,61 +1981,54 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1955 | #define rt73usb_get_tsf NULL | 1981 | #define rt73usb_get_tsf NULL |
1956 | #endif | 1982 | #endif |
1957 | 1983 | ||
1958 | static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | ||
1959 | { | ||
1960 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1961 | |||
1962 | rt73usb_register_write(rt2x00dev, TXRX_CSR12, 0); | ||
1963 | rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0); | ||
1964 | } | ||
1965 | |||
1966 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 1984 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1967 | struct ieee80211_tx_control *control) | 1985 | struct ieee80211_tx_control *control) |
1968 | { | 1986 | { |
1969 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1987 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1970 | struct skb_desc *desc; | 1988 | struct rt2x00_intf *intf = vif_to_intf(control->vif); |
1971 | struct data_ring *ring; | 1989 | struct skb_frame_desc *skbdesc; |
1972 | struct data_entry *entry; | 1990 | unsigned int beacon_base; |
1973 | int timeout; | 1991 | unsigned int timeout; |
1974 | 1992 | ||
1975 | /* | 1993 | if (unlikely(!intf->beacon)) |
1976 | * Just in case the ieee80211 doesn't set this, | 1994 | return -ENOBUFS; |
1977 | * but we need this queue set for the descriptor | ||
1978 | * initialization. | ||
1979 | */ | ||
1980 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1981 | ring = rt2x00lib_get_ring(rt2x00dev, control->queue); | ||
1982 | entry = rt2x00_get_data_entry(ring); | ||
1983 | 1995 | ||
1984 | /* | 1996 | /* |
1985 | * Add the descriptor in front of the skb. | 1997 | * Add the descriptor in front of the skb. |
1986 | */ | 1998 | */ |
1987 | skb_push(skb, ring->desc_size); | 1999 | skb_push(skb, intf->beacon->queue->desc_size); |
1988 | memset(skb->data, 0, ring->desc_size); | 2000 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1989 | 2001 | ||
1990 | /* | 2002 | /* |
1991 | * Fill in skb descriptor | 2003 | * Fill in skb descriptor |
1992 | */ | 2004 | */ |
1993 | desc = get_skb_desc(skb); | 2005 | skbdesc = get_skb_frame_desc(skb); |
1994 | desc->desc_len = ring->desc_size; | 2006 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1995 | desc->data_len = skb->len - ring->desc_size; | 2007 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; |
1996 | desc->desc = skb->data; | 2008 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1997 | desc->data = skb->data + ring->desc_size; | 2009 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1998 | desc->ring = ring; | 2010 | skbdesc->desc = skb->data; |
1999 | desc->entry = entry; | 2011 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2012 | skbdesc->entry = intf->beacon; | ||
2000 | 2013 | ||
2014 | /* | ||
2015 | * mac80211 doesn't provide the control->queue variable | ||
2016 | * for beacons. Set our own queue identification so | ||
2017 | * it can be used during descriptor initialization. | ||
2018 | */ | ||
2019 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2001 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2020 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2002 | 2021 | ||
2003 | /* | 2022 | /* |
2004 | * Write entire beacon with descriptor to register, | 2023 | * Write entire beacon with descriptor to register, |
2005 | * and kick the beacon generator. | 2024 | * and kick the beacon generator. |
2006 | */ | 2025 | */ |
2026 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2007 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2027 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2008 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2028 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2009 | USB_VENDOR_REQUEST_OUT, | 2029 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2010 | HW_BEACON_BASE0, 0x0000, | ||
2011 | skb->data, skb->len, timeout); | 2030 | skb->data, skb->len, timeout); |
2012 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2031 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2013 | 2032 | ||
2014 | return 0; | 2033 | return 0; |
2015 | } | 2034 | } |
@@ -2029,7 +2048,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2029 | .conf_tx = rt2x00mac_conf_tx, | 2048 | .conf_tx = rt2x00mac_conf_tx, |
2030 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2049 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2031 | .get_tsf = rt73usb_get_tsf, | 2050 | .get_tsf = rt73usb_get_tsf, |
2032 | .reset_tsf = rt73usb_reset_tsf, | ||
2033 | .beacon_update = rt73usb_beacon_update, | 2051 | .beacon_update = rt73usb_beacon_update, |
2034 | }; | 2052 | }; |
2035 | 2053 | ||
@@ -2045,24 +2063,47 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2045 | .link_stats = rt73usb_link_stats, | 2063 | .link_stats = rt73usb_link_stats, |
2046 | .reset_tuner = rt73usb_reset_tuner, | 2064 | .reset_tuner = rt73usb_reset_tuner, |
2047 | .link_tuner = rt73usb_link_tuner, | 2065 | .link_tuner = rt73usb_link_tuner, |
2066 | .led_brightness = rt73usb_led_brightness, | ||
2048 | .write_tx_desc = rt73usb_write_tx_desc, | 2067 | .write_tx_desc = rt73usb_write_tx_desc, |
2049 | .write_tx_data = rt2x00usb_write_tx_data, | 2068 | .write_tx_data = rt2x00usb_write_tx_data, |
2050 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2069 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2051 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2070 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2052 | .fill_rxdone = rt73usb_fill_rxdone, | 2071 | .fill_rxdone = rt73usb_fill_rxdone, |
2053 | .config_mac_addr = rt73usb_config_mac_addr, | 2072 | .config_intf = rt73usb_config_intf, |
2054 | .config_bssid = rt73usb_config_bssid, | ||
2055 | .config_type = rt73usb_config_type, | ||
2056 | .config_preamble = rt73usb_config_preamble, | 2073 | .config_preamble = rt73usb_config_preamble, |
2057 | .config = rt73usb_config, | 2074 | .config = rt73usb_config, |
2058 | }; | 2075 | }; |
2059 | 2076 | ||
2077 | static const struct data_queue_desc rt73usb_queue_rx = { | ||
2078 | .entry_num = RX_ENTRIES, | ||
2079 | .data_size = DATA_FRAME_SIZE, | ||
2080 | .desc_size = RXD_DESC_SIZE, | ||
2081 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | ||
2082 | }; | ||
2083 | |||
2084 | static const struct data_queue_desc rt73usb_queue_tx = { | ||
2085 | .entry_num = TX_ENTRIES, | ||
2086 | .data_size = DATA_FRAME_SIZE, | ||
2087 | .desc_size = TXD_DESC_SIZE, | ||
2088 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2089 | }; | ||
2090 | |||
2091 | static const struct data_queue_desc rt73usb_queue_bcn = { | ||
2092 | .entry_num = 4 * BEACON_ENTRIES, | ||
2093 | .data_size = MGMT_FRAME_SIZE, | ||
2094 | .desc_size = TXINFO_SIZE, | ||
2095 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | ||
2096 | }; | ||
2097 | |||
2060 | static const struct rt2x00_ops rt73usb_ops = { | 2098 | static const struct rt2x00_ops rt73usb_ops = { |
2061 | .name = KBUILD_MODNAME, | 2099 | .name = KBUILD_MODNAME, |
2062 | .rxd_size = RXD_DESC_SIZE, | 2100 | .max_sta_intf = 1, |
2063 | .txd_size = TXD_DESC_SIZE, | 2101 | .max_ap_intf = 4, |
2064 | .eeprom_size = EEPROM_SIZE, | 2102 | .eeprom_size = EEPROM_SIZE, |
2065 | .rf_size = RF_SIZE, | 2103 | .rf_size = RF_SIZE, |
2104 | .rx = &rt73usb_queue_rx, | ||
2105 | .tx = &rt73usb_queue_tx, | ||
2106 | .bcn = &rt73usb_queue_bcn, | ||
2066 | .lib = &rt73usb_rt2x00_ops, | 2107 | .lib = &rt73usb_rt2x00_ops, |
2067 | .hw = &rt73usb_mac80211_ops, | 2108 | .hw = &rt73usb_mac80211_ops, |
2068 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 2109 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index d49dcaacecee..06d687425fef 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | Copyright (C) 2004 - 2007 rt2x00 SourceForge Project | 2 | Copyright (C) 2004 - 2008 rt2x00 SourceForge Project |
3 | <http://rt2x00.serialmonkey.com> | 3 | <http://rt2x00.serialmonkey.com> |
4 | 4 | ||
5 | This program is free software; you can redistribute it and/or modify | 5 | This program is free software; you can redistribute it and/or modify |
@@ -114,6 +114,9 @@ struct hw_pairwise_ta_entry { | |||
114 | #define HW_BEACON_BASE2 0x2600 | 114 | #define HW_BEACON_BASE2 0x2600 |
115 | #define HW_BEACON_BASE3 0x2700 | 115 | #define HW_BEACON_BASE3 0x2700 |
116 | 116 | ||
117 | #define HW_BEACON_OFFSET(__index) \ | ||
118 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
119 | |||
117 | /* | 120 | /* |
118 | * MAC Control/Status Registers(CSR). | 121 | * MAC Control/Status Registers(CSR). |
119 | * Some values are set in TU, whereas 1 TU == 1024 us. | 122 | * Some values are set in TU, whereas 1 TU == 1024 us. |
@@ -146,6 +149,11 @@ struct hw_pairwise_ta_entry { | |||
146 | 149 | ||
147 | /* | 150 | /* |
148 | * MAC_CSR3: STA MAC register 1. | 151 | * MAC_CSR3: STA MAC register 1. |
152 | * UNICAST_TO_ME_MASK: | ||
153 | * Used to mask off bits from byte 5 of the MAC address | ||
154 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
155 | * The full mask is complemented by BSS_ID_MASK: | ||
156 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
149 | */ | 157 | */ |
150 | #define MAC_CSR3 0x300c | 158 | #define MAC_CSR3 0x300c |
151 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 159 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -163,7 +171,14 @@ struct hw_pairwise_ta_entry { | |||
163 | 171 | ||
164 | /* | 172 | /* |
165 | * MAC_CSR5: BSSID register 1. | 173 | * MAC_CSR5: BSSID register 1. |
166 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 174 | * BSS_ID_MASK: |
175 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
176 | * BSSID. This will make sure that those bits will be ignored | ||
177 | * when determining the MY_BSS of RX frames. | ||
178 | * 0: 1-BSSID mode (BSS index = 0) | ||
179 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
180 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
181 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
167 | */ | 182 | */ |
168 | #define MAC_CSR5 0x3014 | 183 | #define MAC_CSR5 0x3014 |
169 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 184 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
@@ -867,6 +882,7 @@ struct hw_pairwise_ta_entry { | |||
867 | * DMA descriptor defines. | 882 | * DMA descriptor defines. |
868 | */ | 883 | */ |
869 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 884 | #define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
885 | #define TXINFO_SIZE ( 6 * sizeof(__le32) ) | ||
870 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) | 886 | #define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) |
871 | 887 | ||
872 | /* | 888 | /* |
@@ -1007,8 +1023,8 @@ struct hw_pairwise_ta_entry { | |||
1007 | #define RXD_W5_RESERVED FIELD32(0xffffffff) | 1023 | #define RXD_W5_RESERVED FIELD32(0xffffffff) |
1008 | 1024 | ||
1009 | /* | 1025 | /* |
1010 | * Macro's for converting txpower from EEPROM to dscape value | 1026 | * Macro's for converting txpower from EEPROM to mac80211 value |
1011 | * and from dscape value to register value. | 1027 | * and from mac80211 value to register value. |
1012 | */ | 1028 | */ |
1013 | #define MIN_TXPOWER 0 | 1029 | #define MIN_TXPOWER 0 |
1014 | #define MAX_TXPOWER 31 | 1030 | #define MAX_TXPOWER 31 |
diff --git a/drivers/net/wireless/rtl8180.h b/drivers/net/wireless/rtl8180.h index 2cbfe3c8081f..082a11f93beb 100644 --- a/drivers/net/wireless/rtl8180.h +++ b/drivers/net/wireless/rtl8180.h | |||
@@ -102,7 +102,7 @@ struct rtl8180_priv { | |||
102 | struct rtl8180_tx_ring tx_ring[4]; | 102 | struct rtl8180_tx_ring tx_ring[4]; |
103 | struct ieee80211_channel channels[14]; | 103 | struct ieee80211_channel channels[14]; |
104 | struct ieee80211_rate rates[12]; | 104 | struct ieee80211_rate rates[12]; |
105 | struct ieee80211_hw_mode modes[2]; | 105 | struct ieee80211_supported_band band; |
106 | struct pci_dev *pdev; | 106 | struct pci_dev *pdev; |
107 | u32 rx_conf; | 107 | u32 rx_conf; |
108 | 108 | ||
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 5e9a8ace0d81..b1b3a478335b 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c | |||
@@ -49,6 +49,41 @@ static struct pci_device_id rtl8180_table[] __devinitdata = { | |||
49 | 49 | ||
50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); | 50 | MODULE_DEVICE_TABLE(pci, rtl8180_table); |
51 | 51 | ||
52 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
53 | { .bitrate = 10, .hw_value = 0, }, | ||
54 | { .bitrate = 20, .hw_value = 1, }, | ||
55 | { .bitrate = 55, .hw_value = 2, }, | ||
56 | { .bitrate = 110, .hw_value = 3, }, | ||
57 | { .bitrate = 60, .hw_value = 4, }, | ||
58 | { .bitrate = 90, .hw_value = 5, }, | ||
59 | { .bitrate = 120, .hw_value = 6, }, | ||
60 | { .bitrate = 180, .hw_value = 7, }, | ||
61 | { .bitrate = 240, .hw_value = 8, }, | ||
62 | { .bitrate = 360, .hw_value = 9, }, | ||
63 | { .bitrate = 480, .hw_value = 10, }, | ||
64 | { .bitrate = 540, .hw_value = 11, }, | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
68 | { .center_freq = 2412 }, | ||
69 | { .center_freq = 2417 }, | ||
70 | { .center_freq = 2422 }, | ||
71 | { .center_freq = 2427 }, | ||
72 | { .center_freq = 2432 }, | ||
73 | { .center_freq = 2437 }, | ||
74 | { .center_freq = 2442 }, | ||
75 | { .center_freq = 2447 }, | ||
76 | { .center_freq = 2452 }, | ||
77 | { .center_freq = 2457 }, | ||
78 | { .center_freq = 2462 }, | ||
79 | { .center_freq = 2467 }, | ||
80 | { .center_freq = 2472 }, | ||
81 | { .center_freq = 2484 }, | ||
82 | }; | ||
83 | |||
84 | |||
85 | |||
86 | |||
52 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) | 87 | void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) |
53 | { | 88 | { |
54 | struct rtl8180_priv *priv = dev->priv; | 89 | struct rtl8180_priv *priv = dev->priv; |
@@ -99,10 +134,10 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
99 | /* TODO: improve signal/rssi reporting */ | 134 | /* TODO: improve signal/rssi reporting */ |
100 | rx_status.signal = flags2 & 0xFF; | 135 | rx_status.signal = flags2 & 0xFF; |
101 | rx_status.ssi = (flags2 >> 8) & 0x7F; | 136 | rx_status.ssi = (flags2 >> 8) & 0x7F; |
102 | rx_status.rate = (flags >> 20) & 0xF; | 137 | /* XXX: is this correct? */ |
103 | rx_status.freq = dev->conf.freq; | 138 | rx_status.rate_idx = (flags >> 20) & 0xF; |
104 | rx_status.channel = dev->conf.channel; | 139 | rx_status.freq = dev->conf.channel->center_freq; |
105 | rx_status.phymode = dev->conf.phymode; | 140 | rx_status.band = dev->conf.channel->band; |
106 | rx_status.mactime = le64_to_cpu(entry->tsft); | 141 | rx_status.mactime = le64_to_cpu(entry->tsft); |
107 | rx_status.flag |= RX_FLAG_TSFT; | 142 | rx_status.flag |= RX_FLAG_TSFT; |
108 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) | 143 | if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) |
@@ -222,18 +257,25 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
222 | mapping = pci_map_single(priv->pdev, skb->data, | 257 | mapping = pci_map_single(priv->pdev, skb->data, |
223 | skb->len, PCI_DMA_TODEVICE); | 258 | skb->len, PCI_DMA_TODEVICE); |
224 | 259 | ||
260 | BUG_ON(!control->tx_rate); | ||
261 | |||
225 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | | 262 | tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | |
226 | RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) | | 263 | RTL8180_TX_DESC_FLAG_LS | |
227 | (control->rts_cts_rate << 19) | skb->len; | 264 | (control->tx_rate->hw_value << 24) | skb->len; |
228 | 265 | ||
229 | if (priv->r8185) | 266 | if (priv->r8185) |
230 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | | 267 | tx_flags |= RTL8180_TX_DESC_FLAG_DMA | |
231 | RTL8180_TX_DESC_FLAG_NO_ENC; | 268 | RTL8180_TX_DESC_FLAG_NO_ENC; |
232 | 269 | ||
233 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 270 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
271 | BUG_ON(!control->rts_cts_rate); | ||
234 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; | 272 | tx_flags |= RTL8180_TX_DESC_FLAG_RTS; |
235 | else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 273 | tx_flags |= control->rts_cts_rate->hw_value << 19; |
274 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | ||
275 | BUG_ON(!control->rts_cts_rate); | ||
236 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; | 276 | tx_flags |= RTL8180_TX_DESC_FLAG_CTS; |
277 | tx_flags |= control->rts_cts_rate->hw_value << 19; | ||
278 | } | ||
237 | 279 | ||
238 | *((struct ieee80211_tx_control **) skb->cb) = | 280 | *((struct ieee80211_tx_control **) skb->cb) = |
239 | kmemdup(control, sizeof(*control), GFP_ATOMIC); | 281 | kmemdup(control, sizeof(*control), GFP_ATOMIC); |
@@ -246,9 +288,9 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
246 | unsigned int remainder; | 288 | unsigned int remainder; |
247 | 289 | ||
248 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), | 290 | plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), |
249 | (control->rate->rate * 2) / 10); | 291 | (control->tx_rate->bitrate * 2) / 10); |
250 | remainder = (16 * (skb->len + 4)) % | 292 | remainder = (16 * (skb->len + 4)) % |
251 | ((control->rate->rate * 2) / 10); | 293 | ((control->tx_rate->bitrate * 2) / 10); |
252 | if (remainder > 0 && remainder <= 6) | 294 | if (remainder > 0 && remainder <= 6) |
253 | plcp_len |= 1 << 15; | 295 | plcp_len |= 1 << 15; |
254 | } | 296 | } |
@@ -261,8 +303,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
261 | entry->plcp_len = cpu_to_le16(plcp_len); | 303 | entry->plcp_len = cpu_to_le16(plcp_len); |
262 | entry->tx_buf = cpu_to_le32(mapping); | 304 | entry->tx_buf = cpu_to_le32(mapping); |
263 | entry->frame_len = cpu_to_le32(skb->len); | 305 | entry->frame_len = cpu_to_le32(skb->len); |
264 | entry->flags2 = control->alt_retry_rate != -1 ? | 306 | entry->flags2 = control->alt_retry_rate != NULL ? |
265 | control->alt_retry_rate << 4 : 0; | 307 | control->alt_retry_rate->bitrate << 4 : 0; |
266 | entry->retry_limit = control->retry_limit; | 308 | entry->retry_limit = control->retry_limit; |
267 | entry->flags = cpu_to_le32(tx_flags); | 309 | entry->flags = cpu_to_le32(tx_flags); |
268 | __skb_queue_tail(&ring->queue, skb); | 310 | __skb_queue_tail(&ring->queue, skb); |
@@ -838,19 +880,19 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
838 | goto err_free_dev; | 880 | goto err_free_dev; |
839 | } | 881 | } |
840 | 882 | ||
883 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); | ||
884 | BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); | ||
885 | |||
841 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); | 886 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); |
842 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); | 887 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); |
843 | priv->modes[0].mode = MODE_IEEE80211G; | 888 | |
844 | priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); | 889 | priv->band.band = IEEE80211_BAND_2GHZ; |
845 | priv->modes[0].rates = priv->rates; | 890 | priv->band.channels = priv->channels; |
846 | priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); | 891 | priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); |
847 | priv->modes[0].channels = priv->channels; | 892 | priv->band.bitrates = priv->rates; |
848 | priv->modes[1].mode = MODE_IEEE80211B; | 893 | priv->band.n_bitrates = 4; |
849 | priv->modes[1].num_rates = 4; | 894 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
850 | priv->modes[1].rates = priv->rates; | 895 | |
851 | priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); | ||
852 | priv->modes[1].channels = priv->channels; | ||
853 | priv->mode = IEEE80211_IF_TYPE_INVALID; | ||
854 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 896 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
855 | IEEE80211_HW_RX_INCLUDES_FCS; | 897 | IEEE80211_HW_RX_INCLUDES_FCS; |
856 | dev->queues = 1; | 898 | dev->queues = 1; |
@@ -879,15 +921,10 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
879 | 921 | ||
880 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; | 922 | priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; |
881 | if (priv->r8185) { | 923 | if (priv->r8185) { |
882 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[0]))) | 924 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
883 | goto err_iounmap; | ||
884 | |||
885 | pci_try_set_mwi(pdev); | 925 | pci_try_set_mwi(pdev); |
886 | } | 926 | } |
887 | 927 | ||
888 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[1]))) | ||
889 | goto err_iounmap; | ||
890 | |||
891 | eeprom.data = dev; | 928 | eeprom.data = dev; |
892 | eeprom.register_read = rtl8180_eeprom_register_read; | 929 | eeprom.register_read = rtl8180_eeprom_register_read; |
893 | eeprom.register_write = rtl8180_eeprom_register_write; | 930 | eeprom.register_write = rtl8180_eeprom_register_write; |
@@ -950,8 +987,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
950 | for (i = 0; i < 14; i += 2) { | 987 | for (i = 0; i < 14; i += 2) { |
951 | u16 txpwr; | 988 | u16 txpwr; |
952 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); | 989 | eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); |
953 | priv->channels[i].val = txpwr & 0xFF; | 990 | priv->channels[i].hw_value = txpwr & 0xFF; |
954 | priv->channels[i + 1].val = txpwr >> 8; | 991 | priv->channels[i + 1].hw_value = txpwr >> 8; |
955 | } | 992 | } |
956 | 993 | ||
957 | /* OFDM TX power */ | 994 | /* OFDM TX power */ |
@@ -959,8 +996,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev, | |||
959 | for (i = 0; i < 14; i += 2) { | 996 | for (i = 0; i < 14; i += 2) { |
960 | u16 txpwr; | 997 | u16 txpwr; |
961 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); | 998 | eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); |
962 | priv->channels[i].val |= (txpwr & 0xFF) << 8; | 999 | priv->channels[i].hw_value |= (txpwr & 0xFF) << 8; |
963 | priv->channels[i + 1].val |= txpwr & 0xFF00; | 1000 | priv->channels[i + 1].hw_value |= txpwr & 0xFF00; |
964 | } | 1001 | } |
965 | } | 1002 | } |
966 | 1003 | ||
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 8293e19c4c59..5d47935dbac3 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
@@ -73,8 +73,9 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
73 | struct ieee80211_conf *conf) | 73 | struct ieee80211_conf *conf) |
74 | { | 74 | { |
75 | struct rtl8180_priv *priv = dev->priv; | 75 | struct rtl8180_priv *priv = dev->priv; |
76 | u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; | 76 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
77 | u32 chan = conf->channel - 1; | 77 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
78 | u32 chan = channel - 1; | ||
78 | 79 | ||
79 | /* set TX power */ | 80 | /* set TX power */ |
80 | write_grf5101(dev, 0x15, 0x0); | 81 | write_grf5101(dev, 0x15, 0x0); |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index 98fe9fd64968..a34dfd382b6d 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
@@ -78,8 +78,9 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
79 | { | 79 | { |
80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
81 | unsigned int chan_idx = conf ? conf->channel - 1 : 0; | 81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
82 | u32 txpw = priv->channels[chan_idx].val & 0xFF; | 82 | unsigned int chan_idx = channel - 1; |
83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | ||
83 | u32 chan = max2820_chan[chan_idx]; | 84 | u32 chan = max2820_chan[chan_idx]; |
84 | 85 | ||
85 | /* While philips SA2400 drive the PA bias from | 86 | /* While philips SA2400 drive the PA bias from |
diff --git a/drivers/net/wireless/rtl8180_rtl8225.c b/drivers/net/wireless/rtl8180_rtl8225.c index ef3832bee85c..cd22781728a9 100644 --- a/drivers/net/wireless/rtl8180_rtl8225.c +++ b/drivers/net/wireless/rtl8180_rtl8225.c | |||
@@ -261,8 +261,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
261 | u32 reg; | 261 | u32 reg; |
262 | int i; | 262 | int i; |
263 | 263 | ||
264 | cck_power = priv->channels[channel - 1].val & 0xFF; | 264 | cck_power = priv->channels[channel - 1].hw_value & 0xFF; |
265 | ofdm_power = priv->channels[channel - 1].val >> 8; | 265 | ofdm_power = priv->channels[channel - 1].hw_value >> 8; |
266 | 266 | ||
267 | cck_power = min(cck_power, (u8)35); | 267 | cck_power = min(cck_power, (u8)35); |
268 | ofdm_power = min(ofdm_power, (u8)35); | 268 | 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 | const u8 *tmp; | 476 | const u8 *tmp; |
477 | int i; | 477 | int i; |
478 | 478 | ||
479 | cck_power = priv->channels[channel - 1].val & 0xFF; | 479 | cck_power = priv->channels[channel - 1].hw_value & 0xFF; |
480 | ofdm_power = priv->channels[channel - 1].val >> 8; | 480 | ofdm_power = priv->channels[channel - 1].hw_value >> 8; |
481 | 481 | ||
482 | if (channel == 14) | 482 | if (channel == 14) |
483 | tmp = rtl8225z2_tx_power_cck_ch14; | 483 | tmp = rtl8225z2_tx_power_cck_ch14; |
@@ -716,13 +716,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
716 | struct ieee80211_conf *conf) | 716 | struct ieee80211_conf *conf) |
717 | { | 717 | { |
718 | struct rtl8180_priv *priv = dev->priv; | 718 | struct rtl8180_priv *priv = dev->priv; |
719 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
719 | 720 | ||
720 | if (priv->rf->init == rtl8225_rf_init) | 721 | if (priv->rf->init == rtl8225_rf_init) |
721 | rtl8225_rf_set_tx_power(dev, conf->channel); | 722 | rtl8225_rf_set_tx_power(dev, chan); |
722 | else | 723 | else |
723 | rtl8225z2_rf_set_tx_power(dev, conf->channel); | 724 | rtl8225z2_rf_set_tx_power(dev, chan); |
724 | 725 | ||
725 | rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); | 726 | rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); |
726 | msleep(10); | 727 | msleep(10); |
727 | 728 | ||
728 | if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { | 729 | if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { |
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index e08ace7b1cb7..0311b4ea124c 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
@@ -80,8 +80,9 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
80 | struct ieee80211_conf *conf) | 80 | struct ieee80211_conf *conf) |
81 | { | 81 | { |
82 | struct rtl8180_priv *priv = dev->priv; | 82 | struct rtl8180_priv *priv = dev->priv; |
83 | u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; | 83 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); |
84 | u32 chan = sa2400_chan[conf->channel - 1]; | 84 | u32 txpw = priv->channels[channel - 1].hw_value & 0xFF; |
85 | u32 chan = sa2400_chan[channel - 1]; | ||
85 | 86 | ||
86 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
87 | 88 | ||
diff --git a/drivers/net/wireless/rtl8187.h b/drivers/net/wireless/rtl8187.h index 8680a0b6433c..076d88b6db0e 100644 --- a/drivers/net/wireless/rtl8187.h +++ b/drivers/net/wireless/rtl8187.h | |||
@@ -71,7 +71,7 @@ struct rtl8187_priv { | |||
71 | /* rtl8187 specific */ | 71 | /* rtl8187 specific */ |
72 | struct ieee80211_channel channels[14]; | 72 | struct ieee80211_channel channels[14]; |
73 | struct ieee80211_rate rates[12]; | 73 | struct ieee80211_rate rates[12]; |
74 | struct ieee80211_hw_mode modes[2]; | 74 | struct ieee80211_supported_band band; |
75 | struct usb_device *udev; | 75 | struct usb_device *udev; |
76 | u32 rx_conf; | 76 | u32 rx_conf; |
77 | u16 txpwr_base; | 77 | u16 txpwr_base; |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index f44505994a0e..c03834d5cb0b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -45,6 +45,38 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
45 | 45 | ||
46 | MODULE_DEVICE_TABLE(usb, rtl8187_table); | 46 | MODULE_DEVICE_TABLE(usb, rtl8187_table); |
47 | 47 | ||
48 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
49 | { .bitrate = 10, .hw_value = 0, }, | ||
50 | { .bitrate = 20, .hw_value = 1, }, | ||
51 | { .bitrate = 55, .hw_value = 2, }, | ||
52 | { .bitrate = 110, .hw_value = 3, }, | ||
53 | { .bitrate = 60, .hw_value = 4, }, | ||
54 | { .bitrate = 90, .hw_value = 5, }, | ||
55 | { .bitrate = 120, .hw_value = 6, }, | ||
56 | { .bitrate = 180, .hw_value = 7, }, | ||
57 | { .bitrate = 240, .hw_value = 8, }, | ||
58 | { .bitrate = 360, .hw_value = 9, }, | ||
59 | { .bitrate = 480, .hw_value = 10, }, | ||
60 | { .bitrate = 540, .hw_value = 11, }, | ||
61 | }; | ||
62 | |||
63 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
64 | { .center_freq = 2412 }, | ||
65 | { .center_freq = 2417 }, | ||
66 | { .center_freq = 2422 }, | ||
67 | { .center_freq = 2427 }, | ||
68 | { .center_freq = 2432 }, | ||
69 | { .center_freq = 2437 }, | ||
70 | { .center_freq = 2442 }, | ||
71 | { .center_freq = 2447 }, | ||
72 | { .center_freq = 2452 }, | ||
73 | { .center_freq = 2457 }, | ||
74 | { .center_freq = 2462 }, | ||
75 | { .center_freq = 2467 }, | ||
76 | { .center_freq = 2472 }, | ||
77 | { .center_freq = 2484 }, | ||
78 | }; | ||
79 | |||
48 | static void rtl8187_iowrite_async_cb(struct urb *urb) | 80 | static void rtl8187_iowrite_async_cb(struct urb *urb) |
49 | { | 81 | { |
50 | kfree(urb->context); | 82 | kfree(urb->context); |
@@ -146,17 +178,23 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
146 | 178 | ||
147 | flags = skb->len; | 179 | flags = skb->len; |
148 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; | 180 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; |
149 | flags |= control->rts_cts_rate << 19; | 181 | |
150 | flags |= control->tx_rate << 24; | 182 | BUG_ON(!control->tx_rate); |
183 | |||
184 | flags |= control->tx_rate->hw_value << 24; | ||
151 | if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) | 185 | if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) |
152 | flags |= RTL8187_TX_FLAG_MORE_FRAG; | 186 | flags |= RTL8187_TX_FLAG_MORE_FRAG; |
153 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 187 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { |
188 | BUG_ON(!control->rts_cts_rate); | ||
154 | flags |= RTL8187_TX_FLAG_RTS; | 189 | flags |= RTL8187_TX_FLAG_RTS; |
190 | flags |= control->rts_cts_rate->hw_value << 19; | ||
155 | rts_dur = ieee80211_rts_duration(dev, priv->vif, | 191 | rts_dur = ieee80211_rts_duration(dev, priv->vif, |
156 | skb->len, control); | 192 | skb->len, control); |
157 | } | 193 | } else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { |
158 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 194 | BUG_ON(!control->rts_cts_rate); |
159 | flags |= RTL8187_TX_FLAG_CTS; | 195 | flags |= RTL8187_TX_FLAG_CTS; |
196 | flags |= control->rts_cts_rate->hw_value << 19; | ||
197 | } | ||
160 | 198 | ||
161 | hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); | 199 | hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
162 | hdr->flags = cpu_to_le32(flags); | 200 | hdr->flags = cpu_to_le32(flags); |
@@ -225,10 +263,9 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
225 | rx_status.antenna = (hdr->signal >> 7) & 1; | 263 | rx_status.antenna = (hdr->signal >> 7) & 1; |
226 | rx_status.signal = 64 - min(hdr->noise, (u8)64); | 264 | rx_status.signal = 64 - min(hdr->noise, (u8)64); |
227 | rx_status.ssi = signal; | 265 | rx_status.ssi = signal; |
228 | rx_status.rate = rate; | 266 | rx_status.rate_idx = rate; |
229 | rx_status.freq = dev->conf.freq; | 267 | rx_status.freq = dev->conf.channel->center_freq; |
230 | rx_status.channel = dev->conf.channel; | 268 | rx_status.band = dev->conf.channel->band; |
231 | rx_status.phymode = dev->conf.phymode; | ||
232 | rx_status.mactime = le64_to_cpu(hdr->mac_time); | 269 | rx_status.mactime = le64_to_cpu(hdr->mac_time); |
233 | rx_status.flag |= RX_FLAG_TSFT; | 270 | rx_status.flag |= RX_FLAG_TSFT; |
234 | if (flags & (1 << 13)) | 271 | if (flags & (1 << 13)) |
@@ -682,19 +719,22 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
682 | usb_get_dev(udev); | 719 | usb_get_dev(udev); |
683 | 720 | ||
684 | skb_queue_head_init(&priv->rx_queue); | 721 | skb_queue_head_init(&priv->rx_queue); |
722 | |||
723 | BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels)); | ||
724 | BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates)); | ||
725 | |||
685 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); | 726 | memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); |
686 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); | 727 | memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); |
687 | priv->map = (struct rtl818x_csr *)0xFF00; | 728 | priv->map = (struct rtl818x_csr *)0xFF00; |
688 | priv->modes[0].mode = MODE_IEEE80211G; | 729 | |
689 | priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); | 730 | priv->band.band = IEEE80211_BAND_2GHZ; |
690 | priv->modes[0].rates = priv->rates; | 731 | priv->band.channels = priv->channels; |
691 | priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); | 732 | priv->band.n_channels = ARRAY_SIZE(rtl818x_channels); |
692 | priv->modes[0].channels = priv->channels; | 733 | priv->band.bitrates = priv->rates; |
693 | priv->modes[1].mode = MODE_IEEE80211B; | 734 | priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates); |
694 | priv->modes[1].num_rates = 4; | 735 | dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; |
695 | priv->modes[1].rates = priv->rates; | 736 | |
696 | priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); | 737 | |
697 | priv->modes[1].channels = priv->channels; | ||
698 | priv->mode = IEEE80211_IF_TYPE_MNTR; | 738 | priv->mode = IEEE80211_IF_TYPE_MNTR; |
699 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 739 | dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
700 | IEEE80211_HW_RX_INCLUDES_FCS; | 740 | IEEE80211_HW_RX_INCLUDES_FCS; |
@@ -703,10 +743,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
703 | dev->max_rssi = 65; | 743 | dev->max_rssi = 65; |
704 | dev->max_signal = 64; | 744 | dev->max_signal = 64; |
705 | 745 | ||
706 | for (i = 0; i < 2; i++) | ||
707 | if ((err = ieee80211_register_hwmode(dev, &priv->modes[i]))) | ||
708 | goto err_free_dev; | ||
709 | |||
710 | eeprom.data = dev; | 746 | eeprom.data = dev; |
711 | eeprom.register_read = rtl8187_eeprom_register_read; | 747 | eeprom.register_read = rtl8187_eeprom_register_read; |
712 | eeprom.register_write = rtl8187_eeprom_register_write; | 748 | eeprom.register_write = rtl8187_eeprom_register_write; |
@@ -730,20 +766,20 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
730 | for (i = 0; i < 3; i++) { | 766 | for (i = 0; i < 3; i++) { |
731 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, | 767 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i, |
732 | &txpwr); | 768 | &txpwr); |
733 | (*channel++).val = txpwr & 0xFF; | 769 | (*channel++).hw_value = txpwr & 0xFF; |
734 | (*channel++).val = txpwr >> 8; | 770 | (*channel++).hw_value = txpwr >> 8; |
735 | } | 771 | } |
736 | for (i = 0; i < 2; i++) { | 772 | for (i = 0; i < 2; i++) { |
737 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, | 773 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i, |
738 | &txpwr); | 774 | &txpwr); |
739 | (*channel++).val = txpwr & 0xFF; | 775 | (*channel++).hw_value = txpwr & 0xFF; |
740 | (*channel++).val = txpwr >> 8; | 776 | (*channel++).hw_value = txpwr >> 8; |
741 | } | 777 | } |
742 | for (i = 0; i < 2; i++) { | 778 | for (i = 0; i < 2; i++) { |
743 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, | 779 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6 + i, |
744 | &txpwr); | 780 | &txpwr); |
745 | (*channel++).val = txpwr & 0xFF; | 781 | (*channel++).hw_value = txpwr & 0xFF; |
746 | (*channel++).val = txpwr >> 8; | 782 | (*channel++).hw_value = txpwr >> 8; |
747 | } | 783 | } |
748 | 784 | ||
749 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, | 785 | eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, |
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index b713de17ba0a..9146387b4c5e 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c | |||
@@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) | |||
283 | u32 reg; | 283 | u32 reg; |
284 | int i; | 284 | int i; |
285 | 285 | ||
286 | cck_power = priv->channels[channel - 1].val & 0xF; | 286 | cck_power = priv->channels[channel - 1].hw_value & 0xF; |
287 | ofdm_power = priv->channels[channel - 1].val >> 4; | 287 | ofdm_power = priv->channels[channel - 1].hw_value >> 4; |
288 | 288 | ||
289 | cck_power = min(cck_power, (u8)11); | 289 | cck_power = min(cck_power, (u8)11); |
290 | ofdm_power = min(ofdm_power, (u8)35); | 290 | 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 | u32 reg; | 500 | u32 reg; |
501 | int i; | 501 | int i; |
502 | 502 | ||
503 | cck_power = priv->channels[channel - 1].val & 0xF; | 503 | cck_power = priv->channels[channel - 1].hw_value & 0xF; |
504 | ofdm_power = priv->channels[channel - 1].val >> 4; | 504 | ofdm_power = priv->channels[channel - 1].hw_value >> 4; |
505 | 505 | ||
506 | cck_power = min(cck_power, (u8)15); | 506 | cck_power = min(cck_power, (u8)15); |
507 | cck_power += priv->txpwr_base & 0xF; | 507 | cck_power += priv->txpwr_base & 0xF; |
@@ -735,13 +735,14 @@ static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, | |||
735 | struct ieee80211_conf *conf) | 735 | struct ieee80211_conf *conf) |
736 | { | 736 | { |
737 | struct rtl8187_priv *priv = dev->priv; | 737 | struct rtl8187_priv *priv = dev->priv; |
738 | int chan = ieee80211_frequency_to_channel(conf->channel->center_freq); | ||
738 | 739 | ||
739 | if (priv->rf->init == rtl8225_rf_init) | 740 | if (priv->rf->init == rtl8225_rf_init) |
740 | rtl8225_rf_set_tx_power(dev, conf->channel); | 741 | rtl8225_rf_set_tx_power(dev, chan); |
741 | else | 742 | else |
742 | rtl8225z2_rf_set_tx_power(dev, conf->channel); | 743 | rtl8225z2_rf_set_tx_power(dev, chan); |
743 | 744 | ||
744 | rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); | 745 | rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); |
745 | msleep(10); | 746 | msleep(10); |
746 | } | 747 | } |
747 | 748 | ||
diff --git a/drivers/net/wireless/rtl818x.h b/drivers/net/wireless/rtl818x.h index 1e7d6f8278d7..4f7d38f506eb 100644 --- a/drivers/net/wireless/rtl818x.h +++ b/drivers/net/wireless/rtl818x.h | |||
@@ -175,74 +175,4 @@ struct rtl818x_rf_ops { | |||
175 | void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); | 175 | void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static const struct ieee80211_rate rtl818x_rates[] = { | ||
179 | { .rate = 10, | ||
180 | .val = 0, | ||
181 | .flags = IEEE80211_RATE_CCK }, | ||
182 | { .rate = 20, | ||
183 | .val = 1, | ||
184 | .flags = IEEE80211_RATE_CCK }, | ||
185 | { .rate = 55, | ||
186 | .val = 2, | ||
187 | .flags = IEEE80211_RATE_CCK }, | ||
188 | { .rate = 110, | ||
189 | .val = 3, | ||
190 | .flags = IEEE80211_RATE_CCK }, | ||
191 | { .rate = 60, | ||
192 | .val = 4, | ||
193 | .flags = IEEE80211_RATE_OFDM }, | ||
194 | { .rate = 90, | ||
195 | .val = 5, | ||
196 | .flags = IEEE80211_RATE_OFDM }, | ||
197 | { .rate = 120, | ||
198 | .val = 6, | ||
199 | .flags = IEEE80211_RATE_OFDM }, | ||
200 | { .rate = 180, | ||
201 | .val = 7, | ||
202 | .flags = IEEE80211_RATE_OFDM }, | ||
203 | { .rate = 240, | ||
204 | .val = 8, | ||
205 | .flags = IEEE80211_RATE_OFDM }, | ||
206 | { .rate = 360, | ||
207 | .val = 9, | ||
208 | .flags = IEEE80211_RATE_OFDM }, | ||
209 | { .rate = 480, | ||
210 | .val = 10, | ||
211 | .flags = IEEE80211_RATE_OFDM }, | ||
212 | { .rate = 540, | ||
213 | .val = 11, | ||
214 | .flags = IEEE80211_RATE_OFDM }, | ||
215 | }; | ||
216 | |||
217 | static const struct ieee80211_channel rtl818x_channels[] = { | ||
218 | { .chan = 1, | ||
219 | .freq = 2412}, | ||
220 | { .chan = 2, | ||
221 | .freq = 2417}, | ||
222 | { .chan = 3, | ||
223 | .freq = 2422}, | ||
224 | { .chan = 4, | ||
225 | .freq = 2427}, | ||
226 | { .chan = 5, | ||
227 | .freq = 2432}, | ||
228 | { .chan = 6, | ||
229 | .freq = 2437}, | ||
230 | { .chan = 7, | ||
231 | .freq = 2442}, | ||
232 | { .chan = 8, | ||
233 | .freq = 2447}, | ||
234 | { .chan = 9, | ||
235 | .freq = 2452}, | ||
236 | { .chan = 10, | ||
237 | .freq = 2457}, | ||
238 | { .chan = 11, | ||
239 | .freq = 2462}, | ||
240 | { .chan = 12, | ||
241 | .freq = 2467}, | ||
242 | { .chan = 13, | ||
243 | .freq = 2472}, | ||
244 | { .chan = 14, | ||
245 | .freq = 2484} | ||
246 | }; | ||
247 | |||
248 | #endif /* RTL818X_H */ | 178 | #endif /* RTL818X_H */ |
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 88efe1bae58f..bced3fe1cf8a 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c | |||
@@ -962,12 +962,12 @@ static char *time_delta(char buffer[], long time) | |||
962 | /* get Nth element of the linked list */ | 962 | /* get Nth element of the linked list */ |
963 | static struct strip *strip_get_idx(loff_t pos) | 963 | static struct strip *strip_get_idx(loff_t pos) |
964 | { | 964 | { |
965 | struct list_head *l; | 965 | struct strip *str; |
966 | int i = 0; | 966 | int i = 0; |
967 | 967 | ||
968 | list_for_each_rcu(l, &strip_list) { | 968 | list_for_each_entry_rcu(str, &strip_list, list) { |
969 | if (pos == i) | 969 | if (pos == i) |
970 | return list_entry(l, struct strip, list); | 970 | return str; |
971 | ++i; | 971 | ++i; |
972 | } | 972 | } |
973 | return NULL; | 973 | return NULL; |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 99e5b03b3f51..db96adf90ae2 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -771,10 +771,10 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip) | |||
771 | { | 771 | { |
772 | static const struct zd_ioreq32 ioreqs[] = { | 772 | static const struct zd_ioreq32 ioreqs[] = { |
773 | { CR_ZD1211B_RETRY_MAX, 0x02020202 }, | 773 | { CR_ZD1211B_RETRY_MAX, 0x02020202 }, |
774 | { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f }, | 774 | { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f }, |
775 | { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f }, | 775 | { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f }, |
776 | { CR_ZD1211B_TX_PWR_CTL2, 0x003f001f }, | 776 | { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f }, |
777 | { CR_ZD1211B_TX_PWR_CTL1, 0x001f000f }, | 777 | { CR_ZD1211B_CWIN_MAX_MIN_AC3, 0x001f000f }, |
778 | { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, | 778 | { CR_ZD1211B_AIFS_CTL1, 0x00280028 }, |
779 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, | 779 | { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, |
780 | { CR_ZD1211B_TXOP, 0x01800824 }, | 780 | { CR_ZD1211B_TXOP, 0x01800824 }, |
@@ -986,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip) | |||
986 | return 0; | 986 | return 0; |
987 | } | 987 | } |
988 | 988 | ||
989 | static int set_mandatory_rates(struct zd_chip *chip, int mode) | 989 | static int set_mandatory_rates(struct zd_chip *chip, int gmode) |
990 | { | 990 | { |
991 | u32 rates; | 991 | u32 rates; |
992 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 992 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
@@ -994,17 +994,12 @@ static int set_mandatory_rates(struct zd_chip *chip, int mode) | |||
994 | * that the device is supporting. Until further notice we should try | 994 | * that the device is supporting. Until further notice we should try |
995 | * to support 802.11g also for full speed USB. | 995 | * to support 802.11g also for full speed USB. |
996 | */ | 996 | */ |
997 | switch (mode) { | 997 | if (!gmode) |
998 | case MODE_IEEE80211B: | ||
999 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; | 998 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; |
1000 | break; | 999 | else |
1001 | case MODE_IEEE80211G: | ||
1002 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| | 1000 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| |
1003 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; | 1001 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; |
1004 | break; | 1002 | |
1005 | default: | ||
1006 | return -EINVAL; | ||
1007 | } | ||
1008 | return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); | 1003 | return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL); |
1009 | } | 1004 | } |
1010 | 1005 | ||
@@ -1108,7 +1103,7 @@ int zd_chip_init_hw(struct zd_chip *chip) | |||
1108 | * It might be discussed, whether we should suppport pure b mode for | 1103 | * It might be discussed, whether we should suppport pure b mode for |
1109 | * full speed USB. | 1104 | * full speed USB. |
1110 | */ | 1105 | */ |
1111 | r = set_mandatory_rates(chip, MODE_IEEE80211G); | 1106 | r = set_mandatory_rates(chip, 1); |
1112 | if (r) | 1107 | if (r) |
1113 | goto out; | 1108 | goto out; |
1114 | /* Disabling interrupts is certainly a smart thing here. | 1109 | /* Disabling interrupts is certainly a smart thing here. |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 009c03777a35..5b6e3a3751ba 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -625,11 +625,10 @@ enum { | |||
625 | #define CR_S_MD CTL_REG(0x0830) | 625 | #define CR_S_MD CTL_REG(0x0830) |
626 | 626 | ||
627 | #define CR_USB_DEBUG_PORT CTL_REG(0x0888) | 627 | #define CR_USB_DEBUG_PORT CTL_REG(0x0888) |
628 | 628 | #define CR_ZD1211B_CWIN_MAX_MIN_AC0 CTL_REG(0x0b00) | |
629 | #define CR_ZD1211B_TX_PWR_CTL1 CTL_REG(0x0b00) | 629 | #define CR_ZD1211B_CWIN_MAX_MIN_AC1 CTL_REG(0x0b04) |
630 | #define CR_ZD1211B_TX_PWR_CTL2 CTL_REG(0x0b04) | 630 | #define CR_ZD1211B_CWIN_MAX_MIN_AC2 CTL_REG(0x0b08) |
631 | #define CR_ZD1211B_TX_PWR_CTL3 CTL_REG(0x0b08) | 631 | #define CR_ZD1211B_CWIN_MAX_MIN_AC3 CTL_REG(0x0b0c) |
632 | #define CR_ZD1211B_TX_PWR_CTL4 CTL_REG(0x0b0c) | ||
633 | #define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10) | 632 | #define CR_ZD1211B_AIFS_CTL1 CTL_REG(0x0b10) |
634 | #define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14) | 633 | #define CR_ZD1211B_AIFS_CTL2 CTL_REG(0x0b14) |
635 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) | 634 | #define CR_ZD1211B_TXOP CTL_REG(0x0b20) |
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c index 7c277ec43f79..d8dc41ec0e5d 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.c +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c | |||
@@ -65,16 +65,14 @@ static const struct channel_range *zd_channel_range(u8 regdomain) | |||
65 | 65 | ||
66 | static void unmask_bg_channels(struct ieee80211_hw *hw, | 66 | static void unmask_bg_channels(struct ieee80211_hw *hw, |
67 | const struct channel_range *range, | 67 | const struct channel_range *range, |
68 | struct ieee80211_hw_mode *mode) | 68 | struct ieee80211_supported_band *sband) |
69 | { | 69 | { |
70 | u8 channel; | 70 | u8 channel; |
71 | 71 | ||
72 | for (channel = range->start; channel < range->end; channel++) { | 72 | for (channel = range->start; channel < range->end; channel++) { |
73 | struct ieee80211_channel *chan = | 73 | struct ieee80211_channel *chan = |
74 | &mode->channels[CHAN_TO_IDX(channel)]; | 74 | &sband->channels[CHAN_TO_IDX(channel)]; |
75 | chan->flag |= IEEE80211_CHAN_W_SCAN | | 75 | chan->flags = 0; |
76 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
77 | IEEE80211_CHAN_W_IBSS; | ||
78 | } | 76 | } |
79 | } | 77 | } |
80 | 78 | ||
@@ -97,7 +95,6 @@ void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain) | |||
97 | range = zd_channel_range(ZD_REGDOMAIN_FCC); | 95 | range = zd_channel_range(ZD_REGDOMAIN_FCC); |
98 | } | 96 | } |
99 | 97 | ||
100 | unmask_bg_channels(hw, range, &mac->modes[0]); | 98 | unmask_bg_channels(hw, range, &mac->band); |
101 | unmask_bg_channels(hw, range, &mac->modes[1]); | ||
102 | } | 99 | } |
103 | 100 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 76ef2d83919d..f90f03f676de 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -34,76 +34,61 @@ | |||
34 | 34 | ||
35 | /* This table contains the hardware specific values for the modulation rates. */ | 35 | /* This table contains the hardware specific values for the modulation rates. */ |
36 | static const struct ieee80211_rate zd_rates[] = { | 36 | static const struct ieee80211_rate zd_rates[] = { |
37 | { .rate = 10, | 37 | { .bitrate = 10, |
38 | .val = ZD_CCK_RATE_1M, | 38 | .hw_value = ZD_CCK_RATE_1M, }, |
39 | .flags = IEEE80211_RATE_CCK }, | 39 | { .bitrate = 20, |
40 | { .rate = 20, | 40 | .hw_value = ZD_CCK_RATE_2M, |
41 | .val = ZD_CCK_RATE_2M, | 41 | .hw_value_short = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, |
42 | .val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, | 42 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
43 | .flags = IEEE80211_RATE_CCK_2 }, | 43 | { .bitrate = 55, |
44 | { .rate = 55, | 44 | .hw_value = ZD_CCK_RATE_5_5M, |
45 | .val = ZD_CCK_RATE_5_5M, | 45 | .hw_value_short = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, |
46 | .val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, | 46 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
47 | .flags = IEEE80211_RATE_CCK_2 }, | 47 | { .bitrate = 110, |
48 | { .rate = 110, | 48 | .hw_value = ZD_CCK_RATE_11M, |
49 | .val = ZD_CCK_RATE_11M, | 49 | .hw_value_short = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, |
50 | .val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, | 50 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, |
51 | .flags = IEEE80211_RATE_CCK_2 }, | 51 | { .bitrate = 60, |
52 | { .rate = 60, | 52 | .hw_value = ZD_OFDM_RATE_6M, |
53 | .val = ZD_OFDM_RATE_6M, | 53 | .flags = 0 }, |
54 | .flags = IEEE80211_RATE_OFDM }, | 54 | { .bitrate = 90, |
55 | { .rate = 90, | 55 | .hw_value = ZD_OFDM_RATE_9M, |
56 | .val = ZD_OFDM_RATE_9M, | 56 | .flags = 0 }, |
57 | .flags = IEEE80211_RATE_OFDM }, | 57 | { .bitrate = 120, |
58 | { .rate = 120, | 58 | .hw_value = ZD_OFDM_RATE_12M, |
59 | .val = ZD_OFDM_RATE_12M, | 59 | .flags = 0 }, |
60 | .flags = IEEE80211_RATE_OFDM }, | 60 | { .bitrate = 180, |
61 | { .rate = 180, | 61 | .hw_value = ZD_OFDM_RATE_18M, |
62 | .val = ZD_OFDM_RATE_18M, | 62 | .flags = 0 }, |
63 | .flags = IEEE80211_RATE_OFDM }, | 63 | { .bitrate = 240, |
64 | { .rate = 240, | 64 | .hw_value = ZD_OFDM_RATE_24M, |
65 | .val = ZD_OFDM_RATE_24M, | 65 | .flags = 0 }, |
66 | .flags = IEEE80211_RATE_OFDM }, | 66 | { .bitrate = 360, |
67 | { .rate = 360, | 67 | .hw_value = ZD_OFDM_RATE_36M, |
68 | .val = ZD_OFDM_RATE_36M, | 68 | .flags = 0 }, |
69 | .flags = IEEE80211_RATE_OFDM }, | 69 | { .bitrate = 480, |
70 | { .rate = 480, | 70 | .hw_value = ZD_OFDM_RATE_48M, |
71 | .val = ZD_OFDM_RATE_48M, | 71 | .flags = 0 }, |
72 | .flags = IEEE80211_RATE_OFDM }, | 72 | { .bitrate = 540, |
73 | { .rate = 540, | 73 | .hw_value = ZD_OFDM_RATE_54M, |
74 | .val = ZD_OFDM_RATE_54M, | 74 | .flags = 0 }, |
75 | .flags = IEEE80211_RATE_OFDM }, | ||
76 | }; | 75 | }; |
77 | 76 | ||
78 | static const struct ieee80211_channel zd_channels[] = { | 77 | static const struct ieee80211_channel zd_channels[] = { |
79 | { .chan = 1, | 78 | { .center_freq = 2412, .hw_value = 1 }, |
80 | .freq = 2412}, | 79 | { .center_freq = 2417, .hw_value = 2 }, |
81 | { .chan = 2, | 80 | { .center_freq = 2422, .hw_value = 3 }, |
82 | .freq = 2417}, | 81 | { .center_freq = 2427, .hw_value = 4 }, |
83 | { .chan = 3, | 82 | { .center_freq = 2432, .hw_value = 5 }, |
84 | .freq = 2422}, | 83 | { .center_freq = 2437, .hw_value = 6 }, |
85 | { .chan = 4, | 84 | { .center_freq = 2442, .hw_value = 7 }, |
86 | .freq = 2427}, | 85 | { .center_freq = 2447, .hw_value = 8 }, |
87 | { .chan = 5, | 86 | { .center_freq = 2452, .hw_value = 9 }, |
88 | .freq = 2432}, | 87 | { .center_freq = 2457, .hw_value = 10 }, |
89 | { .chan = 6, | 88 | { .center_freq = 2462, .hw_value = 11 }, |
90 | .freq = 2437}, | 89 | { .center_freq = 2467, .hw_value = 12 }, |
91 | { .chan = 7, | 90 | { .center_freq = 2472, .hw_value = 13 }, |
92 | .freq = 2442}, | 91 | { .center_freq = 2484, .hw_value = 14 }, |
93 | { .chan = 8, | ||
94 | .freq = 2447}, | ||
95 | { .chan = 9, | ||
96 | .freq = 2452}, | ||
97 | { .chan = 10, | ||
98 | .freq = 2457}, | ||
99 | { .chan = 11, | ||
100 | .freq = 2462}, | ||
101 | { .chan = 12, | ||
102 | .freq = 2467}, | ||
103 | { .chan = 13, | ||
104 | .freq = 2472}, | ||
105 | { .chan = 14, | ||
106 | .freq = 2484} | ||
107 | }; | 92 | }; |
108 | 93 | ||
109 | static void housekeeping_init(struct zd_mac *mac); | 94 | static void housekeeping_init(struct zd_mac *mac); |
@@ -503,7 +488,9 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
503 | 488 | ||
504 | ZD_ASSERT(frag_len <= 0xffff); | 489 | ZD_ASSERT(frag_len <= 0xffff); |
505 | 490 | ||
506 | cs->modulation = control->tx_rate; | 491 | cs->modulation = control->tx_rate->hw_value; |
492 | if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) | ||
493 | cs->modulation = control->tx_rate->hw_value_short; | ||
507 | 494 | ||
508 | cs->tx_length = cpu_to_le16(frag_len); | 495 | cs->tx_length = cpu_to_le16(frag_len); |
509 | 496 | ||
@@ -631,6 +618,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
631 | int bad_frame = 0; | 618 | int bad_frame = 0; |
632 | u16 fc; | 619 | u16 fc; |
633 | bool is_qos, is_4addr, need_padding; | 620 | bool is_qos, is_4addr, need_padding; |
621 | int i; | ||
622 | u8 rate; | ||
634 | 623 | ||
635 | if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + | 624 | if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + |
636 | FCS_LEN + sizeof(struct rx_status)) | 625 | FCS_LEN + sizeof(struct rx_status)) |
@@ -660,14 +649,19 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
660 | } | 649 | } |
661 | } | 650 | } |
662 | 651 | ||
663 | stats.channel = _zd_chip_get_channel(&mac->chip); | 652 | stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq; |
664 | stats.freq = zd_channels[stats.channel - 1].freq; | 653 | stats.band = IEEE80211_BAND_2GHZ; |
665 | stats.phymode = MODE_IEEE80211G; | ||
666 | stats.ssi = status->signal_strength; | 654 | stats.ssi = status->signal_strength; |
667 | stats.signal = zd_rx_qual_percent(buffer, | 655 | stats.signal = zd_rx_qual_percent(buffer, |
668 | length - sizeof(struct rx_status), | 656 | length - sizeof(struct rx_status), |
669 | status); | 657 | status); |
670 | stats.rate = zd_rx_rate(buffer, status); | 658 | |
659 | rate = zd_rx_rate(buffer, status); | ||
660 | |||
661 | /* todo: return index in the big switches in zd_rx_rate instead */ | ||
662 | for (i = 0; i < mac->band.n_bitrates; i++) | ||
663 | if (rate == mac->band.bitrates[i].hw_value) | ||
664 | stats.rate_idx = i; | ||
671 | 665 | ||
672 | length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); | 666 | length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); |
673 | buffer += ZD_PLCP_HEADER_SIZE; | 667 | buffer += ZD_PLCP_HEADER_SIZE; |
@@ -736,7 +730,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
736 | static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) | 730 | static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) |
737 | { | 731 | { |
738 | struct zd_mac *mac = zd_hw_mac(hw); | 732 | struct zd_mac *mac = zd_hw_mac(hw); |
739 | return zd_chip_set_channel(&mac->chip, conf->channel); | 733 | return zd_chip_set_channel(&mac->chip, conf->channel->hw_value); |
740 | } | 734 | } |
741 | 735 | ||
742 | static int zd_op_config_interface(struct ieee80211_hw *hw, | 736 | static int zd_op_config_interface(struct ieee80211_hw *hw, |
@@ -780,7 +774,7 @@ static void set_rx_filter_handler(struct work_struct *work) | |||
780 | 774 | ||
781 | #define SUPPORTED_FIF_FLAGS \ | 775 | #define SUPPORTED_FIF_FLAGS \ |
782 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ | 776 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ |
783 | FIF_OTHER_BSS) | 777 | FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) |
784 | static void zd_op_configure_filter(struct ieee80211_hw *hw, | 778 | static void zd_op_configure_filter(struct ieee80211_hw *hw, |
785 | unsigned int changed_flags, | 779 | unsigned int changed_flags, |
786 | unsigned int *new_flags, | 780 | unsigned int *new_flags, |
@@ -894,7 +888,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
894 | { | 888 | { |
895 | struct zd_mac *mac; | 889 | struct zd_mac *mac; |
896 | struct ieee80211_hw *hw; | 890 | struct ieee80211_hw *hw; |
897 | int i; | ||
898 | 891 | ||
899 | hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); | 892 | hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); |
900 | if (!hw) { | 893 | if (!hw) { |
@@ -912,19 +905,14 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
912 | 905 | ||
913 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); | 906 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); |
914 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); | 907 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); |
915 | mac->modes[0].mode = MODE_IEEE80211G; | 908 | mac->band.n_bitrates = ARRAY_SIZE(zd_rates); |
916 | mac->modes[0].num_rates = ARRAY_SIZE(zd_rates); | 909 | mac->band.bitrates = mac->rates; |
917 | mac->modes[0].rates = mac->rates; | 910 | mac->band.n_channels = ARRAY_SIZE(zd_channels); |
918 | mac->modes[0].num_channels = ARRAY_SIZE(zd_channels); | 911 | mac->band.channels = mac->channels; |
919 | mac->modes[0].channels = mac->channels; | 912 | |
920 | mac->modes[1].mode = MODE_IEEE80211B; | 913 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; |
921 | mac->modes[1].num_rates = 4; | 914 | |
922 | mac->modes[1].rates = mac->rates; | 915 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; |
923 | mac->modes[1].num_channels = ARRAY_SIZE(zd_channels); | ||
924 | mac->modes[1].channels = mac->channels; | ||
925 | |||
926 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
927 | IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; | ||
928 | hw->max_rssi = 100; | 916 | hw->max_rssi = 100; |
929 | hw->max_signal = 100; | 917 | hw->max_signal = 100; |
930 | 918 | ||
@@ -933,14 +921,6 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
933 | 921 | ||
934 | skb_queue_head_init(&mac->ack_wait_queue); | 922 | skb_queue_head_init(&mac->ack_wait_queue); |
935 | 923 | ||
936 | for (i = 0; i < 2; i++) { | ||
937 | if (ieee80211_register_hwmode(hw, &mac->modes[i])) { | ||
938 | dev_dbg_f(&intf->dev, "cannot register hwmode\n"); | ||
939 | ieee80211_free_hw(hw); | ||
940 | return NULL; | ||
941 | } | ||
942 | } | ||
943 | |||
944 | zd_chip_init(&mac->chip, hw, intf); | 924 | zd_chip_init(&mac->chip, hw, intf); |
945 | housekeeping_init(mac); | 925 | housekeeping_init(mac); |
946 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); | 926 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 2dde108df767..67dea9739c8f 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -185,7 +185,7 @@ struct zd_mac { | |||
185 | struct sk_buff_head ack_wait_queue; | 185 | struct sk_buff_head ack_wait_queue; |
186 | struct ieee80211_channel channels[14]; | 186 | struct ieee80211_channel channels[14]; |
187 | struct ieee80211_rate rates[12]; | 187 | struct ieee80211_rate rates[12]; |
188 | struct ieee80211_hw_mode modes[2]; | 188 | struct ieee80211_supported_band band; |
189 | 189 | ||
190 | /* Short preamble (used for RTS/CTS) */ | 190 | /* Short preamble (used for RTS/CTS) */ |
191 | unsigned int short_preamble:1; | 191 | unsigned int short_preamble:1; |
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index e586321a473a..45b672a69003 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -353,6 +353,16 @@ void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) | |||
353 | chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); | 353 | chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); |
354 | } | 354 | } |
355 | 355 | ||
356 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) | ||
357 | { | ||
358 | chipco_write32_masked(cc, SSB_CHIPCO_IRQMASK, mask, value); | ||
359 | } | ||
360 | |||
361 | u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask) | ||
362 | { | ||
363 | return chipco_read32(cc, SSB_CHIPCO_IRQSTAT) & mask; | ||
364 | } | ||
365 | |||
356 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) | 366 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) |
357 | { | 367 | { |
358 | return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; | 368 | return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index bedb2b4ee9d2..8db40c4b86e9 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -505,6 +505,14 @@ error: | |||
505 | return err; | 505 | return err; |
506 | } | 506 | } |
507 | 507 | ||
508 | static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset) | ||
509 | { | ||
510 | struct ssb_bus *bus = dev->bus; | ||
511 | |||
512 | offset += dev->core_index * SSB_CORE_SIZE; | ||
513 | return readb(bus->mmio + offset); | ||
514 | } | ||
515 | |||
508 | static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) | 516 | static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset) |
509 | { | 517 | { |
510 | struct ssb_bus *bus = dev->bus; | 518 | struct ssb_bus *bus = dev->bus; |
@@ -521,6 +529,14 @@ static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset) | |||
521 | return readl(bus->mmio + offset); | 529 | return readl(bus->mmio + offset); |
522 | } | 530 | } |
523 | 531 | ||
532 | static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
533 | { | ||
534 | struct ssb_bus *bus = dev->bus; | ||
535 | |||
536 | offset += dev->core_index * SSB_CORE_SIZE; | ||
537 | writeb(value, bus->mmio + offset); | ||
538 | } | ||
539 | |||
524 | static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) | 540 | static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value) |
525 | { | 541 | { |
526 | struct ssb_bus *bus = dev->bus; | 542 | struct ssb_bus *bus = dev->bus; |
@@ -539,8 +555,10 @@ static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
539 | 555 | ||
540 | /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ | 556 | /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */ |
541 | static const struct ssb_bus_ops ssb_ssb_ops = { | 557 | static const struct ssb_bus_ops ssb_ssb_ops = { |
558 | .read8 = ssb_ssb_read8, | ||
542 | .read16 = ssb_ssb_read16, | 559 | .read16 = ssb_ssb_read16, |
543 | .read32 = ssb_ssb_read32, | 560 | .read32 = ssb_ssb_read32, |
561 | .write8 = ssb_ssb_write8, | ||
544 | .write16 = ssb_ssb_write16, | 562 | .write16 = ssb_ssb_write16, |
545 | .write32 = ssb_ssb_write32, | 563 | .write32 = ssb_ssb_write32, |
546 | }; | 564 | }; |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index b434df75047f..1facc7620fc8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -572,6 +572,19 @@ static inline int ssb_pci_assert_buspower(struct ssb_bus *bus) | |||
572 | } | 572 | } |
573 | #endif /* DEBUG */ | 573 | #endif /* DEBUG */ |
574 | 574 | ||
575 | static u8 ssb_pci_read8(struct ssb_device *dev, u16 offset) | ||
576 | { | ||
577 | struct ssb_bus *bus = dev->bus; | ||
578 | |||
579 | if (unlikely(ssb_pci_assert_buspower(bus))) | ||
580 | return 0xFF; | ||
581 | if (unlikely(bus->mapped_device != dev)) { | ||
582 | if (unlikely(ssb_pci_switch_core(bus, dev))) | ||
583 | return 0xFF; | ||
584 | } | ||
585 | return ioread8(bus->mmio + offset); | ||
586 | } | ||
587 | |||
575 | static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) | 588 | static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset) |
576 | { | 589 | { |
577 | struct ssb_bus *bus = dev->bus; | 590 | struct ssb_bus *bus = dev->bus; |
@@ -598,6 +611,19 @@ static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset) | |||
598 | return ioread32(bus->mmio + offset); | 611 | return ioread32(bus->mmio + offset); |
599 | } | 612 | } |
600 | 613 | ||
614 | static void ssb_pci_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
615 | { | ||
616 | struct ssb_bus *bus = dev->bus; | ||
617 | |||
618 | if (unlikely(ssb_pci_assert_buspower(bus))) | ||
619 | return; | ||
620 | if (unlikely(bus->mapped_device != dev)) { | ||
621 | if (unlikely(ssb_pci_switch_core(bus, dev))) | ||
622 | return; | ||
623 | } | ||
624 | iowrite8(value, bus->mmio + offset); | ||
625 | } | ||
626 | |||
601 | static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) | 627 | static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value) |
602 | { | 628 | { |
603 | struct ssb_bus *bus = dev->bus; | 629 | struct ssb_bus *bus = dev->bus; |
@@ -626,8 +652,10 @@ static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
626 | 652 | ||
627 | /* Not "static", as it's used in main.c */ | 653 | /* Not "static", as it's used in main.c */ |
628 | const struct ssb_bus_ops ssb_pci_ops = { | 654 | const struct ssb_bus_ops ssb_pci_ops = { |
655 | .read8 = ssb_pci_read8, | ||
629 | .read16 = ssb_pci_read16, | 656 | .read16 = ssb_pci_read16, |
630 | .read32 = ssb_pci_read32, | 657 | .read32 = ssb_pci_read32, |
658 | .write8 = ssb_pci_write8, | ||
631 | .write16 = ssb_pci_write16, | 659 | .write16 = ssb_pci_write16, |
632 | .write32 = ssb_pci_write32, | 660 | .write32 = ssb_pci_write32, |
633 | }; | 661 | }; |
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c index 46816cda8b98..84b3a845a8a8 100644 --- a/drivers/ssb/pcmcia.c +++ b/drivers/ssb/pcmcia.c | |||
@@ -172,6 +172,22 @@ static int select_core_and_segment(struct ssb_device *dev, | |||
172 | return 0; | 172 | return 0; |
173 | } | 173 | } |
174 | 174 | ||
175 | static u8 ssb_pcmcia_read8(struct ssb_device *dev, u16 offset) | ||
176 | { | ||
177 | struct ssb_bus *bus = dev->bus; | ||
178 | unsigned long flags; | ||
179 | int err; | ||
180 | u8 value = 0xFF; | ||
181 | |||
182 | spin_lock_irqsave(&bus->bar_lock, flags); | ||
183 | err = select_core_and_segment(dev, &offset); | ||
184 | if (likely(!err)) | ||
185 | value = readb(bus->mmio + offset); | ||
186 | spin_unlock_irqrestore(&bus->bar_lock, flags); | ||
187 | |||
188 | return value; | ||
189 | } | ||
190 | |||
175 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) | 191 | static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset) |
176 | { | 192 | { |
177 | struct ssb_bus *bus = dev->bus; | 193 | struct ssb_bus *bus = dev->bus; |
@@ -206,6 +222,20 @@ static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset) | |||
206 | return (lo | (hi << 16)); | 222 | return (lo | (hi << 16)); |
207 | } | 223 | } |
208 | 224 | ||
225 | static void ssb_pcmcia_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
226 | { | ||
227 | struct ssb_bus *bus = dev->bus; | ||
228 | unsigned long flags; | ||
229 | int err; | ||
230 | |||
231 | spin_lock_irqsave(&bus->bar_lock, flags); | ||
232 | err = select_core_and_segment(dev, &offset); | ||
233 | if (likely(!err)) | ||
234 | writeb(value, bus->mmio + offset); | ||
235 | mmiowb(); | ||
236 | spin_unlock_irqrestore(&bus->bar_lock, flags); | ||
237 | } | ||
238 | |||
209 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) | 239 | static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value) |
210 | { | 240 | { |
211 | struct ssb_bus *bus = dev->bus; | 241 | struct ssb_bus *bus = dev->bus; |
@@ -238,8 +268,10 @@ static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value) | |||
238 | 268 | ||
239 | /* Not "static", as it's used in main.c */ | 269 | /* Not "static", as it's used in main.c */ |
240 | const struct ssb_bus_ops ssb_pcmcia_ops = { | 270 | const struct ssb_bus_ops ssb_pcmcia_ops = { |
271 | .read8 = ssb_pcmcia_read8, | ||
241 | .read16 = ssb_pcmcia_read16, | 272 | .read16 = ssb_pcmcia_read16, |
242 | .read32 = ssb_pcmcia_read32, | 273 | .read32 = ssb_pcmcia_read32, |
274 | .write8 = ssb_pcmcia_write8, | ||
243 | .write16 = ssb_pcmcia_write16, | 275 | .write16 = ssb_pcmcia_write16, |
244 | .write32 = ssb_pcmcia_write32, | 276 | .write32 = ssb_pcmcia_write32, |
245 | }; | 277 | }; |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 9fecf902419c..a9f0b93324a2 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -161,6 +161,12 @@ enum nl80211_commands { | |||
161 | * given for %NL80211_CMD_GET_STATION, nested attribute containing | 161 | * given for %NL80211_CMD_GET_STATION, nested attribute containing |
162 | * info as possible, see &enum nl80211_sta_stats. | 162 | * info as possible, see &enum nl80211_sta_stats. |
163 | * | 163 | * |
164 | * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands, | ||
165 | * consisting of a nested array. | ||
166 | * | ||
167 | * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of | ||
168 | * &enum nl80211_mntr_flags. | ||
169 | * | ||
164 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 170 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
165 | * @__NL80211_ATTR_AFTER_LAST: internal use | 171 | * @__NL80211_ATTR_AFTER_LAST: internal use |
166 | */ | 172 | */ |
@@ -195,6 +201,10 @@ enum nl80211_attrs { | |||
195 | NL80211_ATTR_STA_VLAN, | 201 | NL80211_ATTR_STA_VLAN, |
196 | NL80211_ATTR_STA_STATS, | 202 | NL80211_ATTR_STA_STATS, |
197 | 203 | ||
204 | NL80211_ATTR_WIPHY_BANDS, | ||
205 | |||
206 | NL80211_ATTR_MNTR_FLAGS, | ||
207 | |||
198 | /* add attributes here, update the policy in nl80211.c */ | 208 | /* add attributes here, update the policy in nl80211.c */ |
199 | 209 | ||
200 | __NL80211_ATTR_AFTER_LAST, | 210 | __NL80211_ATTR_AFTER_LAST, |
@@ -280,4 +290,93 @@ enum nl80211_sta_stats { | |||
280 | NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1 | 290 | NL80211_STA_STAT_MAX = __NL80211_STA_STAT_AFTER_LAST - 1 |
281 | }; | 291 | }; |
282 | 292 | ||
293 | /** | ||
294 | * enum nl80211_band_attr - band attributes | ||
295 | * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved | ||
296 | * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band, | ||
297 | * an array of nested frequency attributes | ||
298 | * @NL80211_BAND_ATTR_RATES: supported bitrates in this band, | ||
299 | * an array of nested bitrate attributes | ||
300 | */ | ||
301 | enum nl80211_band_attr { | ||
302 | __NL80211_BAND_ATTR_INVALID, | ||
303 | NL80211_BAND_ATTR_FREQS, | ||
304 | NL80211_BAND_ATTR_RATES, | ||
305 | |||
306 | /* keep last */ | ||
307 | __NL80211_BAND_ATTR_AFTER_LAST, | ||
308 | NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 | ||
309 | }; | ||
310 | |||
311 | /** | ||
312 | * enum nl80211_frequency_attr - frequency attributes | ||
313 | * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz | ||
314 | * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current | ||
315 | * regulatory domain. | ||
316 | * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is | ||
317 | * permitted on this channel in current regulatory domain. | ||
318 | * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted | ||
319 | * on this channel in current regulatory domain. | ||
320 | * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory | ||
321 | * on this channel in current regulatory domain. | ||
322 | */ | ||
323 | enum nl80211_frequency_attr { | ||
324 | __NL80211_FREQUENCY_ATTR_INVALID, | ||
325 | NL80211_FREQUENCY_ATTR_FREQ, | ||
326 | NL80211_FREQUENCY_ATTR_DISABLED, | ||
327 | NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, | ||
328 | NL80211_FREQUENCY_ATTR_NO_IBSS, | ||
329 | NL80211_FREQUENCY_ATTR_RADAR, | ||
330 | |||
331 | /* keep last */ | ||
332 | __NL80211_FREQUENCY_ATTR_AFTER_LAST, | ||
333 | NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 | ||
334 | }; | ||
335 | |||
336 | /** | ||
337 | * enum nl80211_bitrate_attr - bitrate attributes | ||
338 | * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps | ||
339 | * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported | ||
340 | * in 2.4 GHz band. | ||
341 | */ | ||
342 | enum nl80211_bitrate_attr { | ||
343 | __NL80211_BITRATE_ATTR_INVALID, | ||
344 | NL80211_BITRATE_ATTR_RATE, | ||
345 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, | ||
346 | |||
347 | /* keep last */ | ||
348 | __NL80211_BITRATE_ATTR_AFTER_LAST, | ||
349 | NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 | ||
350 | }; | ||
351 | |||
352 | /** | ||
353 | * enum nl80211_mntr_flags - monitor configuration flags | ||
354 | * | ||
355 | * Monitor configuration flags. | ||
356 | * | ||
357 | * @__NL80211_MNTR_FLAG_INVALID: reserved | ||
358 | * | ||
359 | * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS | ||
360 | * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP | ||
361 | * @NL80211_MNTR_FLAG_CONTROL: pass control frames | ||
362 | * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering | ||
363 | * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. | ||
364 | * overrides all other flags. | ||
365 | * | ||
366 | * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use | ||
367 | * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag | ||
368 | */ | ||
369 | enum nl80211_mntr_flags { | ||
370 | __NL80211_MNTR_FLAG_INVALID, | ||
371 | NL80211_MNTR_FLAG_FCSFAIL, | ||
372 | NL80211_MNTR_FLAG_PLCPFAIL, | ||
373 | NL80211_MNTR_FLAG_CONTROL, | ||
374 | NL80211_MNTR_FLAG_OTHER_BSS, | ||
375 | NL80211_MNTR_FLAG_COOK_FRAMES, | ||
376 | |||
377 | /* keep last */ | ||
378 | __NL80211_MNTR_FLAG_AFTER_LAST, | ||
379 | NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 | ||
380 | }; | ||
381 | |||
283 | #endif /* __LINUX_NL80211_H */ | 382 | #endif /* __LINUX_NL80211_H */ |
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 20add65215af..860d28c6d149 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h | |||
@@ -72,8 +72,10 @@ struct ssb_device; | |||
72 | /* Lowlevel read/write operations on the device MMIO. | 72 | /* Lowlevel read/write operations on the device MMIO. |
73 | * Internal, don't use that outside of ssb. */ | 73 | * Internal, don't use that outside of ssb. */ |
74 | struct ssb_bus_ops { | 74 | struct ssb_bus_ops { |
75 | u8 (*read8)(struct ssb_device *dev, u16 offset); | ||
75 | u16 (*read16)(struct ssb_device *dev, u16 offset); | 76 | u16 (*read16)(struct ssb_device *dev, u16 offset); |
76 | u32 (*read32)(struct ssb_device *dev, u16 offset); | 77 | u32 (*read32)(struct ssb_device *dev, u16 offset); |
78 | void (*write8)(struct ssb_device *dev, u16 offset, u8 value); | ||
77 | void (*write16)(struct ssb_device *dev, u16 offset, u16 value); | 79 | void (*write16)(struct ssb_device *dev, u16 offset, u16 value); |
78 | void (*write32)(struct ssb_device *dev, u16 offset, u32 value); | 80 | void (*write32)(struct ssb_device *dev, u16 offset, u32 value); |
79 | }; | 81 | }; |
@@ -344,6 +346,10 @@ void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags); | |||
344 | 346 | ||
345 | 347 | ||
346 | /* Device MMIO register read/write functions. */ | 348 | /* Device MMIO register read/write functions. */ |
349 | static inline u8 ssb_read8(struct ssb_device *dev, u16 offset) | ||
350 | { | ||
351 | return dev->ops->read8(dev, offset); | ||
352 | } | ||
347 | static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) | 353 | static inline u16 ssb_read16(struct ssb_device *dev, u16 offset) |
348 | { | 354 | { |
349 | return dev->ops->read16(dev, offset); | 355 | return dev->ops->read16(dev, offset); |
@@ -352,6 +358,10 @@ static inline u32 ssb_read32(struct ssb_device *dev, u16 offset) | |||
352 | { | 358 | { |
353 | return dev->ops->read32(dev, offset); | 359 | return dev->ops->read32(dev, offset); |
354 | } | 360 | } |
361 | static inline void ssb_write8(struct ssb_device *dev, u16 offset, u8 value) | ||
362 | { | ||
363 | dev->ops->write8(dev, offset, value); | ||
364 | } | ||
355 | static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) | 365 | static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value) |
356 | { | 366 | { |
357 | dev->ops->write16(dev, offset, value); | 367 | dev->ops->write16(dev, offset, value); |
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index 536851b946f6..b548a54ff1f5 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
@@ -390,6 +390,10 @@ extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, | |||
390 | extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, | 390 | extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, |
391 | u32 ticks); | 391 | u32 ticks); |
392 | 392 | ||
393 | void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); | ||
394 | |||
395 | u32 ssb_chipco_irq_status(struct ssb_chipcommon *cc, u32 mask); | ||
396 | |||
393 | /* Chipcommon GPIO pin access. */ | 397 | /* Chipcommon GPIO pin access. */ |
394 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); | 398 | u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask); |
395 | u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); | 399 | u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value); |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index bcc480b8892a..ab4caf63954f 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -163,6 +163,26 @@ struct station_stats { | |||
163 | u32 tx_bytes; | 163 | u32 tx_bytes; |
164 | }; | 164 | }; |
165 | 165 | ||
166 | /** | ||
167 | * enum monitor_flags - monitor flags | ||
168 | * | ||
169 | * Monitor interface configuration flags. Note that these must be the bits | ||
170 | * according to the nl80211 flags. | ||
171 | * | ||
172 | * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS | ||
173 | * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP | ||
174 | * @MONITOR_FLAG_CONTROL: pass control frames | ||
175 | * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering | ||
176 | * @MONITOR_FLAG_COOK_FRAMES: report frames after processing | ||
177 | */ | ||
178 | enum monitor_flags { | ||
179 | MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL, | ||
180 | MONITOR_FLAG_PLCPFAIL = 1<<NL80211_MNTR_FLAG_PLCPFAIL, | ||
181 | MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL, | ||
182 | MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS, | ||
183 | MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES, | ||
184 | }; | ||
185 | |||
166 | /* from net/wireless.h */ | 186 | /* from net/wireless.h */ |
167 | struct wiphy; | 187 | struct wiphy; |
168 | 188 | ||
@@ -213,10 +233,10 @@ struct wiphy; | |||
213 | */ | 233 | */ |
214 | struct cfg80211_ops { | 234 | struct cfg80211_ops { |
215 | int (*add_virtual_intf)(struct wiphy *wiphy, char *name, | 235 | int (*add_virtual_intf)(struct wiphy *wiphy, char *name, |
216 | enum nl80211_iftype type); | 236 | enum nl80211_iftype type, u32 *flags); |
217 | int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex); | 237 | int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex); |
218 | int (*change_virtual_intf)(struct wiphy *wiphy, int ifindex, | 238 | int (*change_virtual_intf)(struct wiphy *wiphy, int ifindex, |
219 | enum nl80211_iftype type); | 239 | enum nl80211_iftype type, u32 *flags); |
220 | 240 | ||
221 | int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, | 241 | int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, |
222 | u8 key_index, u8 *mac_addr, | 242 | u8 key_index, u8 *mac_addr, |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9083bafb63ca..7a80c3981237 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -38,7 +38,11 @@ | |||
38 | * called in hardware interrupt context. The low-level driver must not call any | 38 | * called in hardware interrupt context. The low-level driver must not call any |
39 | * other functions in hardware interrupt context. If there is a need for such | 39 | * other functions in hardware interrupt context. If there is a need for such |
40 | * call, the low-level driver should first ACK the interrupt and perform the | 40 | * call, the low-level driver should first ACK the interrupt and perform the |
41 | * IEEE 802.11 code call after this, e.g. from a scheduled workqueue function. | 41 | * IEEE 802.11 code call after this, e.g. from a scheduled workqueue or even |
42 | * tasklet function. | ||
43 | * | ||
44 | * NOTE: If the driver opts to use the _irqsafe() functions, it may not also | ||
45 | * use the non-irqsafe functions! | ||
42 | */ | 46 | */ |
43 | 47 | ||
44 | /** | 48 | /** |
@@ -69,95 +73,6 @@ | |||
69 | * not do so then mac80211 may add this under certain circumstances. | 73 | * not do so then mac80211 may add this under certain circumstances. |
70 | */ | 74 | */ |
71 | 75 | ||
72 | #define IEEE80211_CHAN_W_SCAN 0x00000001 | ||
73 | #define IEEE80211_CHAN_W_ACTIVE_SCAN 0x00000002 | ||
74 | #define IEEE80211_CHAN_W_IBSS 0x00000004 | ||
75 | |||
76 | /* Channel information structure. Low-level driver is expected to fill in chan, | ||
77 | * freq, and val fields. Other fields will be filled in by 80211.o based on | ||
78 | * hostapd information and low-level driver does not need to use them. The | ||
79 | * limits for each channel will be provided in 'struct ieee80211_conf' when | ||
80 | * configuring the low-level driver with hw->config callback. If a device has | ||
81 | * a default regulatory domain, IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED | ||
82 | * can be set to let the driver configure all fields */ | ||
83 | struct ieee80211_channel { | ||
84 | short chan; /* channel number (IEEE 802.11) */ | ||
85 | short freq; /* frequency in MHz */ | ||
86 | int val; /* hw specific value for the channel */ | ||
87 | int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */ | ||
88 | unsigned char power_level; | ||
89 | unsigned char antenna_max; | ||
90 | }; | ||
91 | |||
92 | #define IEEE80211_RATE_ERP 0x00000001 | ||
93 | #define IEEE80211_RATE_BASIC 0x00000002 | ||
94 | #define IEEE80211_RATE_PREAMBLE2 0x00000004 | ||
95 | #define IEEE80211_RATE_SUPPORTED 0x00000010 | ||
96 | #define IEEE80211_RATE_OFDM 0x00000020 | ||
97 | #define IEEE80211_RATE_CCK 0x00000040 | ||
98 | #define IEEE80211_RATE_MANDATORY 0x00000100 | ||
99 | |||
100 | #define IEEE80211_RATE_CCK_2 (IEEE80211_RATE_CCK | IEEE80211_RATE_PREAMBLE2) | ||
101 | #define IEEE80211_RATE_MODULATION(f) \ | ||
102 | (f & (IEEE80211_RATE_CCK | IEEE80211_RATE_OFDM)) | ||
103 | |||
104 | /* Low-level driver should set PREAMBLE2, OFDM and CCK flags. | ||
105 | * BASIC, SUPPORTED, ERP, and MANDATORY flags are set in 80211.o based on the | ||
106 | * configuration. */ | ||
107 | struct ieee80211_rate { | ||
108 | int rate; /* rate in 100 kbps */ | ||
109 | int val; /* hw specific value for the rate */ | ||
110 | int flags; /* IEEE80211_RATE_ flags */ | ||
111 | int val2; /* hw specific value for the rate when using short preamble | ||
112 | * (only when IEEE80211_RATE_PREAMBLE2 flag is set, i.e., for | ||
113 | * 2, 5.5, and 11 Mbps) */ | ||
114 | signed char min_rssi_ack; | ||
115 | unsigned char min_rssi_ack_delta; | ||
116 | |||
117 | /* following fields are set by 80211.o and need not be filled by the | ||
118 | * low-level driver */ | ||
119 | int rate_inv; /* inverse of the rate (LCM(all rates) / rate) for | ||
120 | * optimizing channel utilization estimates */ | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * enum ieee80211_phymode - PHY modes | ||
125 | * | ||
126 | * @MODE_IEEE80211A: 5GHz as defined by 802.11a/802.11h | ||
127 | * @MODE_IEEE80211B: 2.4 GHz as defined by 802.11b | ||
128 | * @MODE_IEEE80211G: 2.4 GHz as defined by 802.11g (with OFDM), | ||
129 | * backwards compatible with 11b mode | ||
130 | * @NUM_IEEE80211_MODES: internal | ||
131 | */ | ||
132 | enum ieee80211_phymode { | ||
133 | MODE_IEEE80211A, | ||
134 | MODE_IEEE80211B, | ||
135 | MODE_IEEE80211G, | ||
136 | |||
137 | /* keep last */ | ||
138 | NUM_IEEE80211_MODES | ||
139 | }; | ||
140 | |||
141 | /** | ||
142 | * struct ieee80211_ht_info - describing STA's HT capabilities | ||
143 | * | ||
144 | * This structure describes most essential parameters needed | ||
145 | * to describe 802.11n HT capabilities for an STA. | ||
146 | * | ||
147 | * @ht_supported: is HT supported by STA, 0: no, 1: yes | ||
148 | * @cap: HT capabilities map as described in 802.11n spec | ||
149 | * @ampdu_factor: Maximum A-MPDU length factor | ||
150 | * @ampdu_density: Minimum A-MPDU spacing | ||
151 | * @supp_mcs_set: Supported MCS set as described in 802.11n spec | ||
152 | */ | ||
153 | struct ieee80211_ht_info { | ||
154 | u8 ht_supported; | ||
155 | u16 cap; /* use IEEE80211_HT_CAP_ */ | ||
156 | u8 ampdu_factor; | ||
157 | u8 ampdu_density; | ||
158 | u8 supp_mcs_set[16]; | ||
159 | }; | ||
160 | |||
161 | /** | 76 | /** |
162 | * struct ieee80211_ht_bss_info - describing BSS's HT characteristics | 77 | * struct ieee80211_ht_bss_info - describing BSS's HT characteristics |
163 | * | 78 | * |
@@ -175,46 +90,22 @@ struct ieee80211_ht_bss_info { | |||
175 | }; | 90 | }; |
176 | 91 | ||
177 | /** | 92 | /** |
178 | * struct ieee80211_hw_mode - PHY mode definition | ||
179 | * | ||
180 | * This structure describes the capabilities supported by the device | ||
181 | * in a single PHY mode. | ||
182 | * | ||
183 | * @list: internal | ||
184 | * @channels: pointer to array of supported channels | ||
185 | * @rates: pointer to array of supported bitrates | ||
186 | * @mode: the PHY mode for this definition | ||
187 | * @num_channels: number of supported channels | ||
188 | * @num_rates: number of supported bitrates | ||
189 | * @ht_info: PHY's 802.11n HT abilities for this mode | ||
190 | */ | ||
191 | struct ieee80211_hw_mode { | ||
192 | struct list_head list; | ||
193 | struct ieee80211_channel *channels; | ||
194 | struct ieee80211_rate *rates; | ||
195 | enum ieee80211_phymode mode; | ||
196 | int num_channels; | ||
197 | int num_rates; | ||
198 | struct ieee80211_ht_info ht_info; | ||
199 | }; | ||
200 | |||
201 | /** | ||
202 | * struct ieee80211_tx_queue_params - transmit queue configuration | 93 | * struct ieee80211_tx_queue_params - transmit queue configuration |
203 | * | 94 | * |
204 | * The information provided in this structure is required for QoS | 95 | * The information provided in this structure is required for QoS |
205 | * transmit queue configuration. | 96 | * transmit queue configuration. Cf. IEEE 802.11 7.3.2.29. |
206 | * | 97 | * |
207 | * @aifs: arbitration interface space [0..255, -1: use default] | 98 | * @aifs: arbitration interface space [0..255, -1: use default] |
208 | * @cw_min: minimum contention window [will be a value of the form | 99 | * @cw_min: minimum contention window [will be a value of the form |
209 | * 2^n-1 in the range 1..1023; 0: use default] | 100 | * 2^n-1 in the range 1..1023; 0: use default] |
210 | * @cw_max: maximum contention window [like @cw_min] | 101 | * @cw_max: maximum contention window [like @cw_min] |
211 | * @burst_time: maximum burst time in units of 0.1ms, 0 meaning disabled | 102 | * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled |
212 | */ | 103 | */ |
213 | struct ieee80211_tx_queue_params { | 104 | struct ieee80211_tx_queue_params { |
214 | int aifs; | 105 | s16 aifs; |
215 | int cw_min; | 106 | u16 cw_min; |
216 | int cw_max; | 107 | u16 cw_max; |
217 | int burst_time; | 108 | u16 txop; |
218 | }; | 109 | }; |
219 | 110 | ||
220 | /** | 111 | /** |
@@ -246,6 +137,7 @@ struct ieee80211_tx_queue_stats_data { | |||
246 | * @IEEE80211_TX_QUEUE_AFTER_BEACON: transmit queue for frames to be | 137 | * @IEEE80211_TX_QUEUE_AFTER_BEACON: transmit queue for frames to be |
247 | * sent after a beacon | 138 | * sent after a beacon |
248 | * @IEEE80211_TX_QUEUE_BEACON: transmit queue for beacon frames | 139 | * @IEEE80211_TX_QUEUE_BEACON: transmit queue for beacon frames |
140 | * @NUM_TX_DATA_QUEUES_AMPDU: adding more queues for A-MPDU | ||
249 | */ | 141 | */ |
250 | enum ieee80211_tx_queue { | 142 | enum ieee80211_tx_queue { |
251 | IEEE80211_TX_QUEUE_DATA0, | 143 | IEEE80211_TX_QUEUE_DATA0, |
@@ -261,11 +153,12 @@ enum ieee80211_tx_queue { | |||
261 | * this struct need to have fixed values. As soon as it is removed, we can | 153 | * this struct need to have fixed values. As soon as it is removed, we can |
262 | * fix these entries. */ | 154 | * fix these entries. */ |
263 | IEEE80211_TX_QUEUE_AFTER_BEACON = 6, | 155 | IEEE80211_TX_QUEUE_AFTER_BEACON = 6, |
264 | IEEE80211_TX_QUEUE_BEACON = 7 | 156 | IEEE80211_TX_QUEUE_BEACON = 7, |
157 | NUM_TX_DATA_QUEUES_AMPDU = 16 | ||
265 | }; | 158 | }; |
266 | 159 | ||
267 | struct ieee80211_tx_queue_stats { | 160 | struct ieee80211_tx_queue_stats { |
268 | struct ieee80211_tx_queue_stats_data data[NUM_TX_DATA_QUEUES]; | 161 | struct ieee80211_tx_queue_stats_data data[NUM_TX_DATA_QUEUES_AMPDU]; |
269 | }; | 162 | }; |
270 | 163 | ||
271 | struct ieee80211_low_level_stats { | 164 | struct ieee80211_low_level_stats { |
@@ -318,11 +211,13 @@ struct ieee80211_bss_conf { | |||
318 | 211 | ||
319 | struct ieee80211_tx_control { | 212 | struct ieee80211_tx_control { |
320 | struct ieee80211_vif *vif; | 213 | struct ieee80211_vif *vif; |
321 | int tx_rate; /* Transmit rate, given as the hw specific value for the | 214 | struct ieee80211_rate *tx_rate; |
322 | * rate (from struct ieee80211_rate) */ | 215 | |
323 | int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw | 216 | /* Transmit rate for RTS/CTS frame */ |
324 | * specific value for the rate (from | 217 | struct ieee80211_rate *rts_cts_rate; |
325 | * struct ieee80211_rate) */ | 218 | |
219 | /* retry rate for the last retries */ | ||
220 | struct ieee80211_rate *alt_retry_rate; | ||
326 | 221 | ||
327 | #define IEEE80211_TXCTL_REQ_TX_STATUS (1<<0)/* request TX status callback for | 222 | #define IEEE80211_TXCTL_REQ_TX_STATUS (1<<0)/* request TX status callback for |
328 | * this frame */ | 223 | * this frame */ |
@@ -337,10 +232,12 @@ struct ieee80211_tx_control { | |||
337 | #define IEEE80211_TXCTL_NO_ACK (1<<4) /* tell the low level not to | 232 | #define IEEE80211_TXCTL_NO_ACK (1<<4) /* tell the low level not to |
338 | * wait for an ack */ | 233 | * wait for an ack */ |
339 | #define IEEE80211_TXCTL_RATE_CTRL_PROBE (1<<5) | 234 | #define IEEE80211_TXCTL_RATE_CTRL_PROBE (1<<5) |
340 | #define IEEE80211_TXCTL_CLEAR_DST_MASK (1<<6) | 235 | #define IEEE80211_TXCTL_CLEAR_PS_FILT (1<<6) /* clear powersave filter |
236 | * for destination station */ | ||
341 | #define IEEE80211_TXCTL_REQUEUE (1<<7) | 237 | #define IEEE80211_TXCTL_REQUEUE (1<<7) |
342 | #define IEEE80211_TXCTL_FIRST_FRAGMENT (1<<8) /* this is a first fragment of | 238 | #define IEEE80211_TXCTL_FIRST_FRAGMENT (1<<8) /* this is a first fragment of |
343 | * the frame */ | 239 | * the frame */ |
240 | #define IEEE80211_TXCTL_SHORT_PREAMBLE (1<<9) | ||
344 | #define IEEE80211_TXCTL_LONG_RETRY_LIMIT (1<<10) /* this frame should be send | 241 | #define IEEE80211_TXCTL_LONG_RETRY_LIMIT (1<<10) /* this frame should be send |
345 | * using the through | 242 | * using the through |
346 | * set_retry_limit configured | 243 | * set_retry_limit configured |
@@ -348,6 +245,8 @@ struct ieee80211_tx_control { | |||
348 | #define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */ | 245 | #define IEEE80211_TXCTL_EAPOL_FRAME (1<<11) /* internal to mac80211 */ |
349 | #define IEEE80211_TXCTL_SEND_AFTER_DTIM (1<<12) /* send this frame after DTIM | 246 | #define IEEE80211_TXCTL_SEND_AFTER_DTIM (1<<12) /* send this frame after DTIM |
350 | * beacon */ | 247 | * beacon */ |
248 | #define IEEE80211_TXCTL_AMPDU (1<<13) /* this frame should be sent | ||
249 | * as part of an A-MPDU */ | ||
351 | u32 flags; /* tx control flags defined | 250 | u32 flags; /* tx control flags defined |
352 | * above */ | 251 | * above */ |
353 | u8 key_idx; /* keyidx from hw->set_key(), undefined if | 252 | u8 key_idx; /* keyidx from hw->set_key(), undefined if |
@@ -355,20 +254,11 @@ struct ieee80211_tx_control { | |||
355 | u8 retry_limit; /* 1 = only first attempt, 2 = one retry, .. | 254 | u8 retry_limit; /* 1 = only first attempt, 2 = one retry, .. |
356 | * This could be used when set_retry_limit | 255 | * This could be used when set_retry_limit |
357 | * is not implemented by the driver */ | 256 | * is not implemented by the driver */ |
358 | u8 power_level; /* per-packet transmit power level, in dBm */ | ||
359 | u8 antenna_sel_tx; /* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */ | 257 | u8 antenna_sel_tx; /* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */ |
360 | u8 icv_len; /* length of the ICV/MIC field in octets */ | 258 | u8 icv_len; /* length of the ICV/MIC field in octets */ |
361 | u8 iv_len; /* length of the IV field in octets */ | 259 | u8 iv_len; /* length of the IV field in octets */ |
362 | u8 queue; /* hardware queue to use for this frame; | 260 | u8 queue; /* hardware queue to use for this frame; |
363 | * 0 = highest, hw->queues-1 = lowest */ | 261 | * 0 = highest, hw->queues-1 = lowest */ |
364 | struct ieee80211_rate *rate; /* internal 80211.o rate */ | ||
365 | struct ieee80211_rate *rts_rate; /* internal 80211.o rate | ||
366 | * for RTS/CTS */ | ||
367 | int alt_retry_rate; /* retry rate for the last retries, given as the | ||
368 | * hw specific value for the rate (from | ||
369 | * struct ieee80211_rate). To be used to limit | ||
370 | * packet dropping when probing higher rates, if hw | ||
371 | * supports multiple retry rates. -1 = not used */ | ||
372 | int type; /* internal */ | 262 | int type; /* internal */ |
373 | }; | 263 | }; |
374 | 264 | ||
@@ -391,7 +281,8 @@ struct ieee80211_tx_control { | |||
391 | * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on | 281 | * @RX_FLAG_FAILED_PLCP_CRC: Set this flag if the PCLP check failed on |
392 | * the frame. | 282 | * the frame. |
393 | * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field) | 283 | * @RX_FLAG_TSFT: The timestamp passed in the RX status (@mactime field) |
394 | * is valid. | 284 | * is valid. This is useful in monitor mode and necessary for beacon frames |
285 | * to enable IBSS merging. | ||
395 | */ | 286 | */ |
396 | enum mac80211_rx_flags { | 287 | enum mac80211_rx_flags { |
397 | RX_FLAG_MMIC_ERROR = 1<<0, | 288 | RX_FLAG_MMIC_ERROR = 1<<0, |
@@ -410,27 +301,26 @@ enum mac80211_rx_flags { | |||
410 | * The low-level driver should provide this information (the subset | 301 | * The low-level driver should provide this information (the subset |
411 | * supported by hardware) to the 802.11 code with each received | 302 | * supported by hardware) to the 802.11 code with each received |
412 | * frame. | 303 | * frame. |
413 | * @mactime: MAC timestamp as defined by 802.11 | 304 | * @mactime: value in microseconds of the 64-bit Time Synchronization Function |
305 | * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. | ||
306 | * @band: the active band when this frame was received | ||
414 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz | 307 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz |
415 | * @channel: channel the radio was tuned to | ||
416 | * @phymode: active PHY mode | ||
417 | * @ssi: signal strength when receiving this frame | 308 | * @ssi: signal strength when receiving this frame |
418 | * @signal: used as 'qual' in statistics reporting | 309 | * @signal: used as 'qual' in statistics reporting |
419 | * @noise: PHY noise when receiving this frame | 310 | * @noise: PHY noise when receiving this frame |
420 | * @antenna: antenna used | 311 | * @antenna: antenna used |
421 | * @rate: data rate | 312 | * @rate_idx: index of data rate into band's supported rates |
422 | * @flag: %RX_FLAG_* | 313 | * @flag: %RX_FLAG_* |
423 | */ | 314 | */ |
424 | struct ieee80211_rx_status { | 315 | struct ieee80211_rx_status { |
425 | u64 mactime; | 316 | u64 mactime; |
317 | enum ieee80211_band band; | ||
426 | int freq; | 318 | int freq; |
427 | int channel; | ||
428 | enum ieee80211_phymode phymode; | ||
429 | int ssi; | 319 | int ssi; |
430 | int signal; | 320 | int signal; |
431 | int noise; | 321 | int noise; |
432 | int antenna; | 322 | int antenna; |
433 | int rate; | 323 | int rate_idx; |
434 | int flag; | 324 | int flag; |
435 | }; | 325 | }; |
436 | 326 | ||
@@ -441,12 +331,14 @@ struct ieee80211_rx_status { | |||
441 | * | 331 | * |
442 | * @IEEE80211_TX_STATUS_TX_FILTERED: The frame was not transmitted | 332 | * @IEEE80211_TX_STATUS_TX_FILTERED: The frame was not transmitted |
443 | * because the destination STA was in powersave mode. | 333 | * because the destination STA was in powersave mode. |
444 | * | ||
445 | * @IEEE80211_TX_STATUS_ACK: Frame was acknowledged | 334 | * @IEEE80211_TX_STATUS_ACK: Frame was acknowledged |
335 | * @IEEE80211_TX_STATUS_AMPDU: The frame was aggregated, so status | ||
336 | * is for the whole aggregation. | ||
446 | */ | 337 | */ |
447 | enum ieee80211_tx_status_flags { | 338 | enum ieee80211_tx_status_flags { |
448 | IEEE80211_TX_STATUS_TX_FILTERED = 1<<0, | 339 | IEEE80211_TX_STATUS_TX_FILTERED = 1<<0, |
449 | IEEE80211_TX_STATUS_ACK = 1<<1, | 340 | IEEE80211_TX_STATUS_ACK = 1<<1, |
341 | IEEE80211_TX_STATUS_AMPDU = 1<<2, | ||
450 | }; | 342 | }; |
451 | 343 | ||
452 | /** | 344 | /** |
@@ -457,24 +349,25 @@ enum ieee80211_tx_status_flags { | |||
457 | * | 349 | * |
458 | * @control: a copy of the &struct ieee80211_tx_control passed to the driver | 350 | * @control: a copy of the &struct ieee80211_tx_control passed to the driver |
459 | * in the tx() callback. | 351 | * in the tx() callback. |
460 | * | ||
461 | * @flags: transmit status flags, defined above | 352 | * @flags: transmit status flags, defined above |
462 | * | 353 | * @retry_count: number of retries |
463 | * @ack_signal: signal strength of the ACK frame | ||
464 | * | ||
465 | * @excessive_retries: set to 1 if the frame was retried many times | 354 | * @excessive_retries: set to 1 if the frame was retried many times |
466 | * but not acknowledged | 355 | * but not acknowledged |
467 | * | 356 | * @ampdu_ack_len: number of aggregated frames. |
468 | * @retry_count: number of retries | 357 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. |
469 | * | 358 | * @ampdu_ack_map: block ack bit map for the aggregation. |
359 | * relevant only if IEEE80211_TX_STATUS_AMPDU was set. | ||
360 | * @ack_signal: signal strength of the ACK frame | ||
470 | * @queue_length: ?? REMOVE | 361 | * @queue_length: ?? REMOVE |
471 | * @queue_number: ?? REMOVE | 362 | * @queue_number: ?? REMOVE |
472 | */ | 363 | */ |
473 | struct ieee80211_tx_status { | 364 | struct ieee80211_tx_status { |
474 | struct ieee80211_tx_control control; | 365 | struct ieee80211_tx_control control; |
475 | u8 flags; | 366 | u8 flags; |
476 | bool excessive_retries; | ||
477 | u8 retry_count; | 367 | u8 retry_count; |
368 | bool excessive_retries; | ||
369 | u8 ampdu_ack_len; | ||
370 | u64 ampdu_ack_map; | ||
478 | int ack_signal; | 371 | int ack_signal; |
479 | int queue_length; | 372 | int queue_length; |
480 | int queue_number; | 373 | int queue_number; |
@@ -502,41 +395,30 @@ enum ieee80211_conf_flags { | |||
502 | * | 395 | * |
503 | * @radio_enabled: when zero, driver is required to switch off the radio. | 396 | * @radio_enabled: when zero, driver is required to switch off the radio. |
504 | * TODO make a flag | 397 | * TODO make a flag |
505 | * @channel: IEEE 802.11 channel number | ||
506 | * @freq: frequency in MHz | ||
507 | * @channel_val: hardware specific channel value for the channel | ||
508 | * @phymode: PHY mode to activate (REMOVE) | ||
509 | * @chan: channel to switch to, pointer to the channel information | ||
510 | * @mode: pointer to mode definition | ||
511 | * @regulatory_domain: ?? | ||
512 | * @beacon_int: beacon interval (TODO make interface config) | 398 | * @beacon_int: beacon interval (TODO make interface config) |
513 | * @flags: configuration flags defined above | 399 | * @flags: configuration flags defined above |
514 | * @power_level: transmit power limit for current regulatory domain in dBm | 400 | * @power_level: requested transmit power (in dBm) |
515 | * @antenna_max: maximum antenna gain | 401 | * @max_antenna_gain: maximum antenna gain (in dBi) |
516 | * @antenna_sel_tx: transmit antenna selection, 0: default/diversity, | 402 | * @antenna_sel_tx: transmit antenna selection, 0: default/diversity, |
517 | * 1/2: antenna 0/1 | 403 | * 1/2: antenna 0/1 |
518 | * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx | 404 | * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx |
519 | * @ht_conf: describes current self configuration of 802.11n HT capabilies | 405 | * @ht_conf: describes current self configuration of 802.11n HT capabilies |
520 | * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters | 406 | * @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters |
407 | * @channel: the channel to tune to | ||
521 | */ | 408 | */ |
522 | struct ieee80211_conf { | 409 | struct ieee80211_conf { |
523 | int channel; /* IEEE 802.11 channel number */ | ||
524 | int freq; /* MHz */ | ||
525 | int channel_val; /* hw specific value for the channel */ | ||
526 | |||
527 | enum ieee80211_phymode phymode; | ||
528 | struct ieee80211_channel *chan; | ||
529 | struct ieee80211_hw_mode *mode; | ||
530 | unsigned int regulatory_domain; | 410 | unsigned int regulatory_domain; |
531 | int radio_enabled; | 411 | int radio_enabled; |
532 | 412 | ||
533 | int beacon_int; | 413 | int beacon_int; |
534 | u32 flags; | 414 | u32 flags; |
535 | u8 power_level; | 415 | int power_level; |
536 | u8 antenna_max; | 416 | int max_antenna_gain; |
537 | u8 antenna_sel_tx; | 417 | u8 antenna_sel_tx; |
538 | u8 antenna_sel_rx; | 418 | u8 antenna_sel_rx; |
539 | 419 | ||
420 | struct ieee80211_channel *channel; | ||
421 | |||
540 | struct ieee80211_ht_info ht_conf; | 422 | struct ieee80211_ht_info ht_conf; |
541 | struct ieee80211_ht_bss_info ht_bss_conf; | 423 | struct ieee80211_ht_bss_info ht_bss_conf; |
542 | }; | 424 | }; |
@@ -757,15 +639,19 @@ enum sta_notify_cmd { | |||
757 | * %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is also not set because | 639 | * %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is also not set because |
758 | * otherwise the stack will not know when the DTIM beacon was sent. | 640 | * otherwise the stack will not know when the DTIM beacon was sent. |
759 | * | 641 | * |
760 | * @IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED: | 642 | * @IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE: |
761 | * Channels are already configured to the default regulatory domain | 643 | * Hardware is not capable of short slot operation on the 2.4 GHz band. |
762 | * specified in the device's EEPROM | 644 | * |
645 | * @IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE: | ||
646 | * Hardware is not capable of receiving frames with short preamble on | ||
647 | * the 2.4 GHz band. | ||
763 | */ | 648 | */ |
764 | enum ieee80211_hw_flags { | 649 | enum ieee80211_hw_flags { |
765 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, | 650 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0, |
766 | IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, | 651 | IEEE80211_HW_RX_INCLUDES_FCS = 1<<1, |
767 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, | 652 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2, |
768 | IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED = 1<<3, | 653 | IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3, |
654 | IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE = 1<<4, | ||
769 | }; | 655 | }; |
770 | 656 | ||
771 | /** | 657 | /** |
@@ -777,7 +663,8 @@ enum ieee80211_hw_flags { | |||
777 | * @wiphy: This points to the &struct wiphy allocated for this | 663 | * @wiphy: This points to the &struct wiphy allocated for this |
778 | * 802.11 PHY. You must fill in the @perm_addr and @dev | 664 | * 802.11 PHY. You must fill in the @perm_addr and @dev |
779 | * members of this structure using SET_IEEE80211_DEV() | 665 | * members of this structure using SET_IEEE80211_DEV() |
780 | * and SET_IEEE80211_PERM_ADDR(). | 666 | * and SET_IEEE80211_PERM_ADDR(). Additionally, all supported |
667 | * bands (with channels, bitrates) are registered here. | ||
781 | * | 668 | * |
782 | * @conf: &struct ieee80211_conf, device configuration, don't use. | 669 | * @conf: &struct ieee80211_conf, device configuration, don't use. |
783 | * | 670 | * |
@@ -913,8 +800,18 @@ static inline void SET_IEEE80211_PERM_ADDR(struct ieee80211_hw *hw, u8 *addr) | |||
913 | * parameter to see whether multicast frames should be accepted | 800 | * parameter to see whether multicast frames should be accepted |
914 | * or dropped. | 801 | * or dropped. |
915 | * | 802 | * |
916 | * All unsupported flags in @total_flags must be cleared, i.e. you | 803 | * All unsupported flags in @total_flags must be cleared. |
917 | * should clear all bits except those you honoured. | 804 | * Hardware does not support a flag if it is incapable of _passing_ |
805 | * the frame to the stack. Otherwise the driver must ignore | ||
806 | * the flag, but not clear it. | ||
807 | * You must _only_ clear the flag (announce no support for the | ||
808 | * flag to mac80211) if you are not able to pass the packet type | ||
809 | * to the stack (so the hardware always filters it). | ||
810 | * So for example, you should clear @FIF_CONTROL, if your hardware | ||
811 | * always filters control frames. If your hardware always passes | ||
812 | * control frames to the kernel and is incapable of filtering them, | ||
813 | * you do _not_ clear the @FIF_CONTROL flag. | ||
814 | * This rule applies to all other FIF flags as well. | ||
918 | */ | 815 | */ |
919 | 816 | ||
920 | /** | 817 | /** |
@@ -967,10 +864,14 @@ enum ieee80211_filter_flags { | |||
967 | * &struct ieee80211_ops to indicate which action is needed. | 864 | * &struct ieee80211_ops to indicate which action is needed. |
968 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation | 865 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation |
969 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation | 866 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation |
867 | * @IEEE80211_AMPDU_TX_START: start Tx aggregation | ||
868 | * @IEEE80211_AMPDU_TX_STOP: stop Tx aggregation | ||
970 | */ | 869 | */ |
971 | enum ieee80211_ampdu_mlme_action { | 870 | enum ieee80211_ampdu_mlme_action { |
972 | IEEE80211_AMPDU_RX_START, | 871 | IEEE80211_AMPDU_RX_START, |
973 | IEEE80211_AMPDU_RX_STOP, | 872 | IEEE80211_AMPDU_RX_STOP, |
873 | IEEE80211_AMPDU_TX_START, | ||
874 | IEEE80211_AMPDU_TX_STOP, | ||
974 | }; | 875 | }; |
975 | 876 | ||
976 | /** | 877 | /** |
@@ -1051,7 +952,9 @@ enum ieee80211_ampdu_mlme_action { | |||
1051 | * given local_address is enabled. | 952 | * given local_address is enabled. |
1052 | * | 953 | * |
1053 | * @hw_scan: Ask the hardware to service the scan request, no need to start | 954 | * @hw_scan: Ask the hardware to service the scan request, no need to start |
1054 | * the scan state machine in stack. | 955 | * the scan state machine in stack. The scan must honour the channel |
956 | * configuration done by the regulatory agent in the wiphy's registered | ||
957 | * bands. | ||
1055 | * | 958 | * |
1056 | * @get_stats: return low-level statistics | 959 | * @get_stats: return low-level statistics |
1057 | * | 960 | * |
@@ -1111,7 +1014,8 @@ enum ieee80211_ampdu_mlme_action { | |||
1111 | * The RA/TID combination determines the destination and TID we want | 1014 | * The RA/TID combination determines the destination and TID we want |
1112 | * the ampdu action to be performed for. The action is defined through | 1015 | * the ampdu action to be performed for. The action is defined through |
1113 | * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn) | 1016 | * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn) |
1114 | * is the first frame we expect to perform the action on. | 1017 | * is the first frame we expect to perform the action on. notice |
1018 | * that TX/RX_STOP can pass NULL for this parameter. | ||
1115 | */ | 1019 | */ |
1116 | struct ieee80211_ops { | 1020 | struct ieee80211_ops { |
1117 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb, | 1021 | int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb, |
@@ -1162,7 +1066,7 @@ struct ieee80211_ops { | |||
1162 | int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | 1066 | int (*conf_ht)(struct ieee80211_hw *hw, struct ieee80211_conf *conf); |
1163 | int (*ampdu_action)(struct ieee80211_hw *hw, | 1067 | int (*ampdu_action)(struct ieee80211_hw *hw, |
1164 | enum ieee80211_ampdu_mlme_action action, | 1068 | enum ieee80211_ampdu_mlme_action action, |
1165 | const u8 *ra, u16 tid, u16 ssn); | 1069 | const u8 *addr, u16 tid, u16 *ssn); |
1166 | }; | 1070 | }; |
1167 | 1071 | ||
1168 | /** | 1072 | /** |
@@ -1272,10 +1176,6 @@ static inline char *ieee80211_get_radio_led_name(struct ieee80211_hw *hw) | |||
1272 | #endif | 1176 | #endif |
1273 | } | 1177 | } |
1274 | 1178 | ||
1275 | /* Register a new hardware PHYMODE capability to the stack. */ | ||
1276 | int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||
1277 | struct ieee80211_hw_mode *mode); | ||
1278 | |||
1279 | /** | 1179 | /** |
1280 | * ieee80211_unregister_hw - Unregister a hardware device | 1180 | * ieee80211_unregister_hw - Unregister a hardware device |
1281 | * | 1181 | * |
@@ -1308,7 +1208,10 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1308 | * buffer in @skb must start with an IEEE 802.11 header or a radiotap | 1208 | * buffer in @skb must start with an IEEE 802.11 header or a radiotap |
1309 | * header if %RX_FLAG_RADIOTAP is set in the @status flags. | 1209 | * header if %RX_FLAG_RADIOTAP is set in the @status flags. |
1310 | * | 1210 | * |
1311 | * This function may not be called in IRQ context. | 1211 | * This function may not be called in IRQ context. Calls to this function |
1212 | * for a single hardware must be synchronized against each other. Calls | ||
1213 | * to this function and ieee80211_rx_irqsafe() may not be mixed for a | ||
1214 | * single hardware. | ||
1312 | * | 1215 | * |
1313 | * @hw: the hardware this frame came in on | 1216 | * @hw: the hardware this frame came in on |
1314 | * @skb: the buffer to receive, owned by mac80211 after this call | 1217 | * @skb: the buffer to receive, owned by mac80211 after this call |
@@ -1325,7 +1228,10 @@ static inline void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1325 | * ieee80211_rx_irqsafe - receive frame | 1228 | * ieee80211_rx_irqsafe - receive frame |
1326 | * | 1229 | * |
1327 | * Like ieee80211_rx() but can be called in IRQ context | 1230 | * Like ieee80211_rx() but can be called in IRQ context |
1328 | * (internally defers to a workqueue.) | 1231 | * (internally defers to a tasklet.) |
1232 | * | ||
1233 | * Calls to this function and ieee80211_rx() may not be mixed for a | ||
1234 | * single hardware. | ||
1329 | * | 1235 | * |
1330 | * @hw: the hardware this frame came in on | 1236 | * @hw: the hardware this frame came in on |
1331 | * @skb: the buffer to receive, owned by mac80211 after this call | 1237 | * @skb: the buffer to receive, owned by mac80211 after this call |
@@ -1344,6 +1250,11 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, | |||
1344 | * transmitted. It is permissible to not call this function for | 1250 | * transmitted. It is permissible to not call this function for |
1345 | * multicast frames but this can affect statistics. | 1251 | * multicast frames but this can affect statistics. |
1346 | * | 1252 | * |
1253 | * This function may not be called in IRQ context. Calls to this function | ||
1254 | * for a single hardware must be synchronized against each other. Calls | ||
1255 | * to this function and ieee80211_tx_status_irqsafe() may not be mixed | ||
1256 | * for a single hardware. | ||
1257 | * | ||
1347 | * @hw: the hardware the frame was transmitted by | 1258 | * @hw: the hardware the frame was transmitted by |
1348 | * @skb: the frame that was transmitted, owned by mac80211 after this call | 1259 | * @skb: the frame that was transmitted, owned by mac80211 after this call |
1349 | * @status: status information for this frame; the status pointer need not | 1260 | * @status: status information for this frame; the status pointer need not |
@@ -1353,6 +1264,22 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, | |||
1353 | void ieee80211_tx_status(struct ieee80211_hw *hw, | 1264 | void ieee80211_tx_status(struct ieee80211_hw *hw, |
1354 | struct sk_buff *skb, | 1265 | struct sk_buff *skb, |
1355 | struct ieee80211_tx_status *status); | 1266 | struct ieee80211_tx_status *status); |
1267 | |||
1268 | /** | ||
1269 | * ieee80211_tx_status_irqsafe - irq-safe transmit status callback | ||
1270 | * | ||
1271 | * Like ieee80211_tx_status() but can be called in IRQ context | ||
1272 | * (internally defers to a tasklet.) | ||
1273 | * | ||
1274 | * Calls to this function and ieee80211_tx_status() may not be mixed for a | ||
1275 | * single hardware. | ||
1276 | * | ||
1277 | * @hw: the hardware the frame was transmitted by | ||
1278 | * @skb: the frame that was transmitted, owned by mac80211 after this call | ||
1279 | * @status: status information for this frame; the status pointer need not | ||
1280 | * be valid after this function returns and is not freed by mac80211, | ||
1281 | * it is recommended that it points to a stack area | ||
1282 | */ | ||
1356 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1283 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
1357 | struct sk_buff *skb, | 1284 | struct sk_buff *skb, |
1358 | struct ieee80211_tx_status *status); | 1285 | struct ieee80211_tx_status *status); |
@@ -1449,7 +1376,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
1449 | * @hw: pointer obtained from ieee80211_alloc_hw(). | 1376 | * @hw: pointer obtained from ieee80211_alloc_hw(). |
1450 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. | 1377 | * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. |
1451 | * @frame_len: the length of the frame. | 1378 | * @frame_len: the length of the frame. |
1452 | * @rate: the rate (in 100kbps) at which the frame is going to be transmitted. | 1379 | * @rate: the rate at which the frame is going to be transmitted. |
1453 | * | 1380 | * |
1454 | * Calculate the duration field of some generic frame, given its | 1381 | * Calculate the duration field of some generic frame, given its |
1455 | * length and transmission rate (in 100kbps). | 1382 | * length and transmission rate (in 100kbps). |
@@ -1457,7 +1384,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
1457 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | 1384 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, |
1458 | struct ieee80211_vif *vif, | 1385 | struct ieee80211_vif *vif, |
1459 | size_t frame_len, | 1386 | size_t frame_len, |
1460 | int rate); | 1387 | struct ieee80211_rate *rate); |
1461 | 1388 | ||
1462 | /** | 1389 | /** |
1463 | * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames | 1390 | * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames |
@@ -1574,4 +1501,81 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, | |||
1574 | struct ieee80211_vif *vif), | 1501 | struct ieee80211_vif *vif), |
1575 | void *data); | 1502 | void *data); |
1576 | 1503 | ||
1504 | /** | ||
1505 | * ieee80211_start_tx_ba_session - Start a tx Block Ack session. | ||
1506 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1507 | * @ra: receiver address of the BA session recipient | ||
1508 | * @tid: the TID to BA on. | ||
1509 | * @return: success if addBA request was sent, failure otherwise | ||
1510 | * | ||
1511 | * Although mac80211/low level driver/user space application can estimate | ||
1512 | * the need to start aggregation on a certain RA/TID, the session level | ||
1513 | * will be managed by the mac80211. | ||
1514 | */ | ||
1515 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid); | ||
1516 | |||
1517 | /** | ||
1518 | * ieee80211_start_tx_ba_cb - low level driver ready to aggregate. | ||
1519 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1520 | * @ra: receiver address of the BA session recipient. | ||
1521 | * @tid: the TID to BA on. | ||
1522 | * | ||
1523 | * This function must be called by low level driver once it has | ||
1524 | * finished with preparations for the BA session. | ||
1525 | */ | ||
1526 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid); | ||
1527 | |||
1528 | /** | ||
1529 | * ieee80211_start_tx_ba_cb_irqsafe - low level driver ready to aggregate. | ||
1530 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1531 | * @ra: receiver address of the BA session recipient. | ||
1532 | * @tid: the TID to BA on. | ||
1533 | * | ||
1534 | * This function must be called by low level driver once it has | ||
1535 | * finished with preparations for the BA session. | ||
1536 | * This version of the function is irq safe. | ||
1537 | */ | ||
1538 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | ||
1539 | u16 tid); | ||
1540 | |||
1541 | /** | ||
1542 | * ieee80211_stop_tx_ba_session - Stop a Block Ack session. | ||
1543 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1544 | * @ra: receiver address of the BA session recipient | ||
1545 | * @tid: the TID to stop BA. | ||
1546 | * @initiator: if indicates initiator DELBA frame will be sent. | ||
1547 | * @return: error if no sta with matching da found, success otherwise | ||
1548 | * | ||
1549 | * Although mac80211/low level driver/user space application can estimate | ||
1550 | * the need to stop aggregation on a certain RA/TID, the session level | ||
1551 | * will be managed by the mac80211. | ||
1552 | */ | ||
1553 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | ||
1554 | u8 *ra, u16 tid, | ||
1555 | enum ieee80211_back_parties initiator); | ||
1556 | |||
1557 | /** | ||
1558 | * ieee80211_stop_tx_ba_cb - low level driver ready to stop aggregate. | ||
1559 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1560 | * @ra: receiver address of the BA session recipient. | ||
1561 | * @tid: the desired TID to BA on. | ||
1562 | * | ||
1563 | * This function must be called by low level driver once it has | ||
1564 | * finished with preparations for the BA session tear down. | ||
1565 | */ | ||
1566 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid); | ||
1567 | |||
1568 | /** | ||
1569 | * ieee80211_stop_tx_ba_cb_irqsafe - low level driver ready to stop aggregate. | ||
1570 | * @hw: pointer as obtained from ieee80211_alloc_hw(). | ||
1571 | * @ra: receiver address of the BA session recipient. | ||
1572 | * @tid: the desired TID to BA on. | ||
1573 | * | ||
1574 | * This function must be called by low level driver once it has | ||
1575 | * finished with preparations for the BA session tear down. | ||
1576 | * This version of the function is irq safe. | ||
1577 | */ | ||
1578 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, | ||
1579 | u16 tid); | ||
1580 | |||
1577 | #endif /* MAC80211_H */ | 1581 | #endif /* MAC80211_H */ |
diff --git a/include/net/wireless.h b/include/net/wireless.h index d30c4ba8fd99..c7f805ee5545 100644 --- a/include/net/wireless.h +++ b/include/net/wireless.h | |||
@@ -13,6 +13,162 @@ | |||
13 | #include <net/cfg80211.h> | 13 | #include <net/cfg80211.h> |
14 | 14 | ||
15 | /** | 15 | /** |
16 | * enum ieee80211_band - supported frequency bands | ||
17 | * | ||
18 | * The bands are assigned this way because the supported | ||
19 | * bitrates differ in these bands. | ||
20 | * | ||
21 | * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band | ||
22 | * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) | ||
23 | */ | ||
24 | enum ieee80211_band { | ||
25 | IEEE80211_BAND_2GHZ, | ||
26 | IEEE80211_BAND_5GHZ, | ||
27 | |||
28 | /* keep last */ | ||
29 | IEEE80211_NUM_BANDS | ||
30 | }; | ||
31 | |||
32 | /** | ||
33 | * enum ieee80211_channel_flags - channel flags | ||
34 | * | ||
35 | * Channel flags set by the regulatory control code. | ||
36 | * | ||
37 | * @IEEE80211_CHAN_DISABLED: This channel is disabled. | ||
38 | * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted | ||
39 | * on this channel. | ||
40 | * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. | ||
41 | * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. | ||
42 | */ | ||
43 | enum ieee80211_channel_flags { | ||
44 | IEEE80211_CHAN_DISABLED = 1<<0, | ||
45 | IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, | ||
46 | IEEE80211_CHAN_NO_IBSS = 1<<2, | ||
47 | IEEE80211_CHAN_RADAR = 1<<3, | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * struct ieee80211_channel - channel definition | ||
52 | * | ||
53 | * This structure describes a single channel for use | ||
54 | * with cfg80211. | ||
55 | * | ||
56 | * @center_freq: center frequency in MHz | ||
57 | * @hw_value: hardware-specific value for the channel | ||
58 | * @flags: channel flags from &enum ieee80211_channel_flags. | ||
59 | * @orig_flags: channel flags at registration time, used by regulatory | ||
60 | * code to support devices with additional restrictions | ||
61 | * @band: band this channel belongs to. | ||
62 | * @max_antenna_gain: maximum antenna gain in dBi | ||
63 | * @max_power: maximum transmission power (in dBm) | ||
64 | * @orig_mag: internal use | ||
65 | * @orig_mpwr: internal use | ||
66 | */ | ||
67 | struct ieee80211_channel { | ||
68 | enum ieee80211_band band; | ||
69 | u16 center_freq; | ||
70 | u16 hw_value; | ||
71 | u32 flags; | ||
72 | int max_antenna_gain; | ||
73 | int max_power; | ||
74 | u32 orig_flags; | ||
75 | int orig_mag, orig_mpwr; | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * enum ieee80211_rate_flags - rate flags | ||
80 | * | ||
81 | * Hardware/specification flags for rates. These are structured | ||
82 | * in a way that allows using the same bitrate structure for | ||
83 | * different bands/PHY modes. | ||
84 | * | ||
85 | * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short | ||
86 | * preamble on this bitrate; only relevant in 2.4GHz band and | ||
87 | * with CCK rates. | ||
88 | * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate | ||
89 | * when used with 802.11a (on the 5 GHz band); filled by the | ||
90 | * core code when registering the wiphy. | ||
91 | * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate | ||
92 | * when used with 802.11b (on the 2.4 GHz band); filled by the | ||
93 | * core code when registering the wiphy. | ||
94 | * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate | ||
95 | * when used with 802.11g (on the 2.4 GHz band); filled by the | ||
96 | * core code when registering the wiphy. | ||
97 | * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. | ||
98 | */ | ||
99 | enum ieee80211_rate_flags { | ||
100 | IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, | ||
101 | IEEE80211_RATE_MANDATORY_A = 1<<1, | ||
102 | IEEE80211_RATE_MANDATORY_B = 1<<2, | ||
103 | IEEE80211_RATE_MANDATORY_G = 1<<3, | ||
104 | IEEE80211_RATE_ERP_G = 1<<4, | ||
105 | }; | ||
106 | |||
107 | /** | ||
108 | * struct ieee80211_rate - bitrate definition | ||
109 | * | ||
110 | * This structure describes a bitrate that an 802.11 PHY can | ||
111 | * operate with. The two values @hw_value and @hw_value_short | ||
112 | * are only for driver use when pointers to this structure are | ||
113 | * passed around. | ||
114 | * | ||
115 | * @flags: rate-specific flags | ||
116 | * @bitrate: bitrate in units of 100 Kbps | ||
117 | * @hw_value: driver/hardware value for this rate | ||
118 | * @hw_value_short: driver/hardware value for this rate when | ||
119 | * short preamble is used | ||
120 | */ | ||
121 | struct ieee80211_rate { | ||
122 | u32 flags; | ||
123 | u16 bitrate; | ||
124 | u16 hw_value, hw_value_short; | ||
125 | }; | ||
126 | |||
127 | /** | ||
128 | * struct ieee80211_ht_info - describing STA's HT capabilities | ||
129 | * | ||
130 | * This structure describes most essential parameters needed | ||
131 | * to describe 802.11n HT capabilities for an STA. | ||
132 | * | ||
133 | * @ht_supported: is HT supported by STA, 0: no, 1: yes | ||
134 | * @cap: HT capabilities map as described in 802.11n spec | ||
135 | * @ampdu_factor: Maximum A-MPDU length factor | ||
136 | * @ampdu_density: Minimum A-MPDU spacing | ||
137 | * @supp_mcs_set: Supported MCS set as described in 802.11n spec | ||
138 | */ | ||
139 | struct ieee80211_ht_info { | ||
140 | u16 cap; /* use IEEE80211_HT_CAP_ */ | ||
141 | u8 ht_supported; | ||
142 | u8 ampdu_factor; | ||
143 | u8 ampdu_density; | ||
144 | u8 supp_mcs_set[16]; | ||
145 | }; | ||
146 | |||
147 | /** | ||
148 | * struct ieee80211_supported_band - frequency band definition | ||
149 | * | ||
150 | * This structure describes a frequency band a wiphy | ||
151 | * is able to operate in. | ||
152 | * | ||
153 | * @channels: Array of channels the hardware can operate in | ||
154 | * in this band. | ||
155 | * @band: the band this structure represents | ||
156 | * @n_channels: Number of channels in @channels | ||
157 | * @bitrates: Array of bitrates the hardware can operate with | ||
158 | * in this band. Must be sorted to give a valid "supported | ||
159 | * rates" IE, i.e. CCK rates first, then OFDM. | ||
160 | * @n_bitrates: Number of bitrates in @bitrates | ||
161 | */ | ||
162 | struct ieee80211_supported_band { | ||
163 | struct ieee80211_channel *channels; | ||
164 | struct ieee80211_rate *bitrates; | ||
165 | enum ieee80211_band band; | ||
166 | int n_channels; | ||
167 | int n_bitrates; | ||
168 | struct ieee80211_ht_info ht_info; | ||
169 | }; | ||
170 | |||
171 | /** | ||
16 | * struct wiphy - wireless hardware description | 172 | * struct wiphy - wireless hardware description |
17 | * @idx: the wiphy index assigned to this item | 173 | * @idx: the wiphy index assigned to this item |
18 | * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> | 174 | * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name> |
@@ -30,6 +186,8 @@ struct wiphy { | |||
30 | * help determine whether you own this wiphy or not. */ | 186 | * help determine whether you own this wiphy or not. */ |
31 | void *privid; | 187 | void *privid; |
32 | 188 | ||
189 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; | ||
190 | |||
33 | /* fields below are read-only, assigned by cfg80211 */ | 191 | /* fields below are read-only, assigned by cfg80211 */ |
34 | 192 | ||
35 | /* the item in /sys/class/ieee80211/ points to this, | 193 | /* the item in /sys/class/ieee80211/ points to this, |
@@ -136,4 +294,14 @@ extern void wiphy_unregister(struct wiphy *wiphy); | |||
136 | */ | 294 | */ |
137 | extern void wiphy_free(struct wiphy *wiphy); | 295 | extern void wiphy_free(struct wiphy *wiphy); |
138 | 296 | ||
297 | /** | ||
298 | * ieee80211_channel_to_frequency - convert channel number to frequency | ||
299 | */ | ||
300 | extern int ieee80211_channel_to_frequency(int chan); | ||
301 | |||
302 | /** | ||
303 | * ieee80211_frequency_to_channel - convert frequency to channel number | ||
304 | */ | ||
305 | extern int ieee80211_frequency_to_channel(int freq); | ||
306 | |||
139 | #endif /* __NET_WIRELESS_H */ | 307 | #endif /* __NET_WIRELESS_H */ |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 54f46bc80cfe..9d7a19581a29 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -19,7 +19,6 @@ mac80211-y := \ | |||
19 | ieee80211_iface.o \ | 19 | ieee80211_iface.o \ |
20 | ieee80211_rate.o \ | 20 | ieee80211_rate.o \ |
21 | michael.o \ | 21 | michael.o \ |
22 | regdomain.o \ | ||
23 | tkip.o \ | 22 | tkip.o \ |
24 | aes_ccm.o \ | 23 | aes_ccm.o \ |
25 | cfg.o \ | 24 | cfg.o \ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 22c9619ba776..e7535ffc8e1c 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -34,10 +34,13 @@ nl80211_type_to_mac80211_type(enum nl80211_iftype type) | |||
34 | } | 34 | } |
35 | 35 | ||
36 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | 36 | static int ieee80211_add_iface(struct wiphy *wiphy, char *name, |
37 | enum nl80211_iftype type) | 37 | enum nl80211_iftype type, u32 *flags) |
38 | { | 38 | { |
39 | struct ieee80211_local *local = wiphy_priv(wiphy); | 39 | struct ieee80211_local *local = wiphy_priv(wiphy); |
40 | enum ieee80211_if_types itype; | 40 | enum ieee80211_if_types itype; |
41 | struct net_device *dev; | ||
42 | struct ieee80211_sub_if_data *sdata; | ||
43 | int err; | ||
41 | 44 | ||
42 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) | 45 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) |
43 | return -ENODEV; | 46 | return -ENODEV; |
@@ -46,7 +49,13 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
46 | if (itype == IEEE80211_IF_TYPE_INVALID) | 49 | if (itype == IEEE80211_IF_TYPE_INVALID) |
47 | return -EINVAL; | 50 | return -EINVAL; |
48 | 51 | ||
49 | return ieee80211_if_add(local->mdev, name, NULL, itype); | 52 | err = ieee80211_if_add(local->mdev, name, &dev, itype); |
53 | if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) | ||
54 | return err; | ||
55 | |||
56 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
57 | sdata->u.mntr_flags = *flags; | ||
58 | return 0; | ||
50 | } | 59 | } |
51 | 60 | ||
52 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | 61 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) |
@@ -69,7 +78,7 @@ static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | |||
69 | } | 78 | } |
70 | 79 | ||
71 | static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | 80 | static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, |
72 | enum nl80211_iftype type) | 81 | enum nl80211_iftype type, u32 *flags) |
73 | { | 82 | { |
74 | struct ieee80211_local *local = wiphy_priv(wiphy); | 83 | struct ieee80211_local *local = wiphy_priv(wiphy); |
75 | struct net_device *dev; | 84 | struct net_device *dev; |
@@ -99,6 +108,10 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | |||
99 | ieee80211_if_reinit(dev); | 108 | ieee80211_if_reinit(dev); |
100 | ieee80211_if_set_type(dev, itype); | 109 | ieee80211_if_set_type(dev, itype); |
101 | 110 | ||
111 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) | ||
112 | return 0; | ||
113 | |||
114 | sdata->u.mntr_flags = *flags; | ||
102 | return 0; | 115 | return 0; |
103 | } | 116 | } |
104 | 117 | ||
@@ -110,6 +123,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
110 | struct sta_info *sta = NULL; | 123 | struct sta_info *sta = NULL; |
111 | enum ieee80211_key_alg alg; | 124 | enum ieee80211_key_alg alg; |
112 | int ret; | 125 | int ret; |
126 | struct ieee80211_key *key; | ||
113 | 127 | ||
114 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 128 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
115 | 129 | ||
@@ -128,16 +142,21 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
128 | return -EINVAL; | 142 | return -EINVAL; |
129 | } | 143 | } |
130 | 144 | ||
145 | key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); | ||
146 | if (!key) | ||
147 | return -ENOMEM; | ||
148 | |||
131 | if (mac_addr) { | 149 | if (mac_addr) { |
132 | sta = sta_info_get(sdata->local, mac_addr); | 150 | sta = sta_info_get(sdata->local, mac_addr); |
133 | if (!sta) | 151 | if (!sta) { |
152 | ieee80211_key_free(key); | ||
134 | return -ENOENT; | 153 | return -ENOENT; |
154 | } | ||
135 | } | 155 | } |
136 | 156 | ||
157 | ieee80211_key_link(key, sdata, sta); | ||
158 | |||
137 | ret = 0; | 159 | ret = 0; |
138 | if (!ieee80211_key_alloc(sdata, sta, alg, key_idx, | ||
139 | params->key_len, params->key)) | ||
140 | ret = -ENOMEM; | ||
141 | 160 | ||
142 | if (sta) | 161 | if (sta) |
143 | sta_info_put(sta); | 162 | sta_info_put(sta); |
@@ -151,6 +170,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
151 | struct ieee80211_sub_if_data *sdata; | 170 | struct ieee80211_sub_if_data *sdata; |
152 | struct sta_info *sta; | 171 | struct sta_info *sta; |
153 | int ret; | 172 | int ret; |
173 | struct ieee80211_key *key; | ||
154 | 174 | ||
155 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 175 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
156 | 176 | ||
@@ -160,9 +180,11 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
160 | return -ENOENT; | 180 | return -ENOENT; |
161 | 181 | ||
162 | ret = 0; | 182 | ret = 0; |
163 | if (sta->key) | 183 | if (sta->key) { |
164 | ieee80211_key_free(sta->key); | 184 | key = sta->key; |
165 | else | 185 | ieee80211_key_free(key); |
186 | WARN_ON(sta->key); | ||
187 | } else | ||
166 | ret = -ENOENT; | 188 | ret = -ENOENT; |
167 | 189 | ||
168 | sta_info_put(sta); | 190 | sta_info_put(sta); |
@@ -172,7 +194,9 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
172 | if (!sdata->keys[key_idx]) | 194 | if (!sdata->keys[key_idx]) |
173 | return -ENOENT; | 195 | return -ENOENT; |
174 | 196 | ||
175 | ieee80211_key_free(sdata->keys[key_idx]); | 197 | key = sdata->keys[key_idx]; |
198 | ieee80211_key_free(key); | ||
199 | WARN_ON(sdata->keys[key_idx]); | ||
176 | 200 | ||
177 | return 0; | 201 | return 0; |
178 | } | 202 | } |
@@ -498,7 +522,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
498 | { | 522 | { |
499 | u32 rates; | 523 | u32 rates; |
500 | int i, j; | 524 | int i, j; |
501 | struct ieee80211_hw_mode *mode; | 525 | struct ieee80211_supported_band *sband; |
502 | 526 | ||
503 | if (params->station_flags & STATION_FLAG_CHANGED) { | 527 | if (params->station_flags & STATION_FLAG_CHANGED) { |
504 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 528 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
@@ -525,15 +549,16 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
525 | 549 | ||
526 | if (params->supported_rates) { | 550 | if (params->supported_rates) { |
527 | rates = 0; | 551 | rates = 0; |
528 | mode = local->oper_hw_mode; | 552 | sband = local->hw.wiphy->bands[local->oper_channel->band]; |
553 | |||
529 | for (i = 0; i < params->supported_rates_len; i++) { | 554 | for (i = 0; i < params->supported_rates_len; i++) { |
530 | int rate = (params->supported_rates[i] & 0x7f) * 5; | 555 | int rate = (params->supported_rates[i] & 0x7f) * 5; |
531 | for (j = 0; j < mode->num_rates; j++) { | 556 | for (j = 0; j < sband->n_bitrates; j++) { |
532 | if (mode->rates[j].rate == rate) | 557 | if (sband->bitrates[j].bitrate == rate) |
533 | rates |= BIT(j); | 558 | rates |= BIT(j); |
534 | } | 559 | } |
535 | } | 560 | } |
536 | sta->supp_rates = rates; | 561 | sta->supp_rates[local->oper_channel->band] = rates; |
537 | } | 562 | } |
538 | } | 563 | } |
539 | 564 | ||
@@ -548,13 +573,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
548 | if (!netif_running(dev)) | 573 | if (!netif_running(dev)) |
549 | return -ENETDOWN; | 574 | return -ENETDOWN; |
550 | 575 | ||
551 | /* XXX: get sta belonging to dev */ | ||
552 | sta = sta_info_get(local, mac); | ||
553 | if (sta) { | ||
554 | sta_info_put(sta); | ||
555 | return -EEXIST; | ||
556 | } | ||
557 | |||
558 | if (params->vlan) { | 576 | if (params->vlan) { |
559 | sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); | 577 | sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); |
560 | 578 | ||
@@ -565,8 +583,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
565 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 583 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
566 | 584 | ||
567 | sta = sta_info_add(local, dev, mac, GFP_KERNEL); | 585 | sta = sta_info_add(local, dev, mac, GFP_KERNEL); |
568 | if (!sta) | 586 | if (IS_ERR(sta)) |
569 | return -ENOMEM; | 587 | return PTR_ERR(sta); |
570 | 588 | ||
571 | sta->dev = sdata->dev; | 589 | sta->dev = sdata->dev; |
572 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || | 590 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 60514b2c97b9..4736c64937b4 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -19,41 +19,6 @@ int mac80211_open_file_generic(struct inode *inode, struct file *file) | |||
19 | return 0; | 19 | return 0; |
20 | } | 20 | } |
21 | 21 | ||
22 | static const char *ieee80211_mode_str(int mode) | ||
23 | { | ||
24 | switch (mode) { | ||
25 | case MODE_IEEE80211A: | ||
26 | return "IEEE 802.11a"; | ||
27 | case MODE_IEEE80211B: | ||
28 | return "IEEE 802.11b"; | ||
29 | case MODE_IEEE80211G: | ||
30 | return "IEEE 802.11g"; | ||
31 | default: | ||
32 | return "UNKNOWN"; | ||
33 | } | ||
34 | } | ||
35 | |||
36 | static ssize_t modes_read(struct file *file, char __user *userbuf, | ||
37 | size_t count, loff_t *ppos) | ||
38 | { | ||
39 | struct ieee80211_local *local = file->private_data; | ||
40 | struct ieee80211_hw_mode *mode; | ||
41 | char buf[150], *p = buf; | ||
42 | |||
43 | /* FIXME: locking! */ | ||
44 | list_for_each_entry(mode, &local->modes_list, list) { | ||
45 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
46 | "%s\n", ieee80211_mode_str(mode->mode)); | ||
47 | } | ||
48 | |||
49 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
50 | } | ||
51 | |||
52 | static const struct file_operations modes_ops = { | ||
53 | .read = modes_read, | ||
54 | .open = mac80211_open_file_generic, | ||
55 | }; | ||
56 | |||
57 | #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ | 22 | #define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...) \ |
58 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ | 23 | static ssize_t name## _read(struct file *file, char __user *userbuf, \ |
59 | size_t count, loff_t *ppos) \ | 24 | size_t count, loff_t *ppos) \ |
@@ -80,10 +45,8 @@ static const struct file_operations name## _ops = { \ | |||
80 | local->debugfs.name = NULL; | 45 | local->debugfs.name = NULL; |
81 | 46 | ||
82 | 47 | ||
83 | DEBUGFS_READONLY_FILE(channel, 20, "%d", | ||
84 | local->hw.conf.channel); | ||
85 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", | 48 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", |
86 | local->hw.conf.freq); | 49 | local->hw.conf.channel->center_freq); |
87 | DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", | 50 | DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d", |
88 | local->hw.conf.antenna_sel_tx); | 51 | local->hw.conf.antenna_sel_tx); |
89 | DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", | 52 | DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", |
@@ -100,8 +63,6 @@ DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d", | |||
100 | local->long_retry_limit); | 63 | local->long_retry_limit); |
101 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", | 64 | DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d", |
102 | local->total_ps_buffered); | 65 | local->total_ps_buffered); |
103 | DEBUGFS_READONLY_FILE(mode, 20, "%s", | ||
104 | ieee80211_mode_str(local->hw.conf.phymode)); | ||
105 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", | 66 | DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x", |
106 | local->wep_iv & 0xffffff); | 67 | local->wep_iv & 0xffffff); |
107 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", | 68 | DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", |
@@ -294,7 +255,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
294 | local->debugfs.stations = debugfs_create_dir("stations", phyd); | 255 | local->debugfs.stations = debugfs_create_dir("stations", phyd); |
295 | local->debugfs.keys = debugfs_create_dir("keys", phyd); | 256 | local->debugfs.keys = debugfs_create_dir("keys", phyd); |
296 | 257 | ||
297 | DEBUGFS_ADD(channel); | ||
298 | DEBUGFS_ADD(frequency); | 258 | DEBUGFS_ADD(frequency); |
299 | DEBUGFS_ADD(antenna_sel_tx); | 259 | DEBUGFS_ADD(antenna_sel_tx); |
300 | DEBUGFS_ADD(antenna_sel_rx); | 260 | DEBUGFS_ADD(antenna_sel_rx); |
@@ -304,9 +264,7 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
304 | DEBUGFS_ADD(short_retry_limit); | 264 | DEBUGFS_ADD(short_retry_limit); |
305 | DEBUGFS_ADD(long_retry_limit); | 265 | DEBUGFS_ADD(long_retry_limit); |
306 | DEBUGFS_ADD(total_ps_buffered); | 266 | DEBUGFS_ADD(total_ps_buffered); |
307 | DEBUGFS_ADD(mode); | ||
308 | DEBUGFS_ADD(wep_iv); | 267 | DEBUGFS_ADD(wep_iv); |
309 | DEBUGFS_ADD(modes); | ||
310 | 268 | ||
311 | statsd = debugfs_create_dir("statistics", phyd); | 269 | statsd = debugfs_create_dir("statistics", phyd); |
312 | local->debugfs.statistics = statsd; | 270 | local->debugfs.statistics = statsd; |
@@ -356,7 +314,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
356 | 314 | ||
357 | void debugfs_hw_del(struct ieee80211_local *local) | 315 | void debugfs_hw_del(struct ieee80211_local *local) |
358 | { | 316 | { |
359 | DEBUGFS_DEL(channel); | ||
360 | DEBUGFS_DEL(frequency); | 317 | DEBUGFS_DEL(frequency); |
361 | DEBUGFS_DEL(antenna_sel_tx); | 318 | DEBUGFS_DEL(antenna_sel_tx); |
362 | DEBUGFS_DEL(antenna_sel_rx); | 319 | DEBUGFS_DEL(antenna_sel_rx); |
@@ -366,9 +323,7 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
366 | DEBUGFS_DEL(short_retry_limit); | 323 | DEBUGFS_DEL(short_retry_limit); |
367 | DEBUGFS_DEL(long_retry_limit); | 324 | DEBUGFS_DEL(long_retry_limit); |
368 | DEBUGFS_DEL(total_ps_buffered); | 325 | DEBUGFS_DEL(total_ps_buffered); |
369 | DEBUGFS_DEL(mode); | ||
370 | DEBUGFS_DEL(wep_iv); | 326 | DEBUGFS_DEL(wep_iv); |
371 | DEBUGFS_DEL(modes); | ||
372 | 327 | ||
373 | DEBUGFS_STATS_DEL(transmitted_fragment_count); | 328 | DEBUGFS_STATS_DEL(transmitted_fragment_count); |
374 | DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); | 329 | DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 829872a3ae81..29f7b98ba1fb 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -91,7 +91,6 @@ static const struct file_operations name##_ops = { \ | |||
91 | /* common attributes */ | 91 | /* common attributes */ |
92 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); | 92 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); |
93 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 93 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
94 | IEEE80211_IF_FILE(ieee802_1x_pac, ieee802_1x_pac, DEC); | ||
95 | 94 | ||
96 | /* STA/IBSS attributes */ | 95 | /* STA/IBSS attributes */ |
97 | IEEE80211_IF_FILE(state, u.sta.state, DEC); | 96 | IEEE80211_IF_FILE(state, u.sta.state, DEC); |
@@ -148,7 +147,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
148 | { | 147 | { |
149 | DEBUGFS_ADD(channel_use, sta); | 148 | DEBUGFS_ADD(channel_use, sta); |
150 | DEBUGFS_ADD(drop_unencrypted, sta); | 149 | DEBUGFS_ADD(drop_unencrypted, sta); |
151 | DEBUGFS_ADD(ieee802_1x_pac, sta); | ||
152 | DEBUGFS_ADD(state, sta); | 150 | DEBUGFS_ADD(state, sta); |
153 | DEBUGFS_ADD(bssid, sta); | 151 | DEBUGFS_ADD(bssid, sta); |
154 | DEBUGFS_ADD(prev_bssid, sta); | 152 | DEBUGFS_ADD(prev_bssid, sta); |
@@ -169,7 +167,6 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata) | |||
169 | { | 167 | { |
170 | DEBUGFS_ADD(channel_use, ap); | 168 | DEBUGFS_ADD(channel_use, ap); |
171 | DEBUGFS_ADD(drop_unencrypted, ap); | 169 | DEBUGFS_ADD(drop_unencrypted, ap); |
172 | DEBUGFS_ADD(ieee802_1x_pac, ap); | ||
173 | DEBUGFS_ADD(num_sta_ps, ap); | 170 | DEBUGFS_ADD(num_sta_ps, ap); |
174 | DEBUGFS_ADD(dtim_count, ap); | 171 | DEBUGFS_ADD(dtim_count, ap); |
175 | DEBUGFS_ADD(num_beacons, ap); | 172 | DEBUGFS_ADD(num_beacons, ap); |
@@ -182,7 +179,6 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata) | |||
182 | { | 179 | { |
183 | DEBUGFS_ADD(channel_use, wds); | 180 | DEBUGFS_ADD(channel_use, wds); |
184 | DEBUGFS_ADD(drop_unencrypted, wds); | 181 | DEBUGFS_ADD(drop_unencrypted, wds); |
185 | DEBUGFS_ADD(ieee802_1x_pac, wds); | ||
186 | DEBUGFS_ADD(peer, wds); | 182 | DEBUGFS_ADD(peer, wds); |
187 | } | 183 | } |
188 | 184 | ||
@@ -190,7 +186,6 @@ static void add_vlan_files(struct ieee80211_sub_if_data *sdata) | |||
190 | { | 186 | { |
191 | DEBUGFS_ADD(channel_use, vlan); | 187 | DEBUGFS_ADD(channel_use, vlan); |
192 | DEBUGFS_ADD(drop_unencrypted, vlan); | 188 | DEBUGFS_ADD(drop_unencrypted, vlan); |
193 | DEBUGFS_ADD(ieee802_1x_pac, vlan); | ||
194 | } | 189 | } |
195 | 190 | ||
196 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | 191 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) |
@@ -234,7 +229,6 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata) | |||
234 | { | 229 | { |
235 | DEBUGFS_DEL(channel_use, sta); | 230 | DEBUGFS_DEL(channel_use, sta); |
236 | DEBUGFS_DEL(drop_unencrypted, sta); | 231 | DEBUGFS_DEL(drop_unencrypted, sta); |
237 | DEBUGFS_DEL(ieee802_1x_pac, sta); | ||
238 | DEBUGFS_DEL(state, sta); | 232 | DEBUGFS_DEL(state, sta); |
239 | DEBUGFS_DEL(bssid, sta); | 233 | DEBUGFS_DEL(bssid, sta); |
240 | DEBUGFS_DEL(prev_bssid, sta); | 234 | DEBUGFS_DEL(prev_bssid, sta); |
@@ -255,7 +249,6 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata) | |||
255 | { | 249 | { |
256 | DEBUGFS_DEL(channel_use, ap); | 250 | DEBUGFS_DEL(channel_use, ap); |
257 | DEBUGFS_DEL(drop_unencrypted, ap); | 251 | DEBUGFS_DEL(drop_unencrypted, ap); |
258 | DEBUGFS_DEL(ieee802_1x_pac, ap); | ||
259 | DEBUGFS_DEL(num_sta_ps, ap); | 252 | DEBUGFS_DEL(num_sta_ps, ap); |
260 | DEBUGFS_DEL(dtim_count, ap); | 253 | DEBUGFS_DEL(dtim_count, ap); |
261 | DEBUGFS_DEL(num_beacons, ap); | 254 | DEBUGFS_DEL(num_beacons, ap); |
@@ -268,7 +261,6 @@ static void del_wds_files(struct ieee80211_sub_if_data *sdata) | |||
268 | { | 261 | { |
269 | DEBUGFS_DEL(channel_use, wds); | 262 | DEBUGFS_DEL(channel_use, wds); |
270 | DEBUGFS_DEL(drop_unencrypted, wds); | 263 | DEBUGFS_DEL(drop_unencrypted, wds); |
271 | DEBUGFS_DEL(ieee802_1x_pac, wds); | ||
272 | DEBUGFS_DEL(peer, wds); | 264 | DEBUGFS_DEL(peer, wds); |
273 | } | 265 | } |
274 | 266 | ||
@@ -276,7 +268,6 @@ static void del_vlan_files(struct ieee80211_sub_if_data *sdata) | |||
276 | { | 268 | { |
277 | DEBUGFS_DEL(channel_use, vlan); | 269 | DEBUGFS_DEL(channel_use, vlan); |
278 | DEBUGFS_DEL(drop_unencrypted, vlan); | 270 | DEBUGFS_DEL(drop_unencrypted, vlan); |
279 | DEBUGFS_DEL(ieee802_1x_pac, vlan); | ||
280 | } | 271 | } |
281 | 272 | ||
282 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) | 273 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 8f5944c53d4e..ed7c9f3b4602 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -33,25 +33,16 @@ static ssize_t sta_ ##name## _read(struct file *file, \ | |||
33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") | 33 | #define STA_READ_LU(name, field) STA_READ(name, 20, field, "%lu\n") |
34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") | 34 | #define STA_READ_S(name, field) STA_READ(name, 20, field, "%s\n") |
35 | 35 | ||
36 | #define STA_READ_RATE(name, field) \ | 36 | #define STA_OPS(name) \ |
37 | static ssize_t sta_##name##_read(struct file *file, \ | 37 | static const struct file_operations sta_ ##name## _ops = { \ |
38 | char __user *userbuf, \ | 38 | .read = sta_##name##_read, \ |
39 | size_t count, loff_t *ppos) \ | 39 | .open = mac80211_open_file_generic, \ |
40 | { \ | ||
41 | struct sta_info *sta = file->private_data; \ | ||
42 | struct ieee80211_local *local = wdev_priv(sta->dev->ieee80211_ptr);\ | ||
43 | struct ieee80211_hw_mode *mode = local->oper_hw_mode; \ | ||
44 | char buf[20]; \ | ||
45 | int res = scnprintf(buf, sizeof(buf), "%d\n", \ | ||
46 | (sta->field >= 0 && \ | ||
47 | sta->field < mode->num_rates) ? \ | ||
48 | mode->rates[sta->field].rate : -1); \ | ||
49 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); \ | ||
50 | } | 40 | } |
51 | 41 | ||
52 | #define STA_OPS(name) \ | 42 | #define STA_OPS_WR(name) \ |
53 | static const struct file_operations sta_ ##name## _ops = { \ | 43 | static const struct file_operations sta_ ##name## _ops = { \ |
54 | .read = sta_##name##_read, \ | 44 | .read = sta_##name##_read, \ |
45 | .write = sta_##name##_write, \ | ||
55 | .open = mac80211_open_file_generic, \ | 46 | .open = mac80211_open_file_generic, \ |
56 | } | 47 | } |
57 | 48 | ||
@@ -70,8 +61,6 @@ STA_FILE(rx_fragments, rx_fragments, LU); | |||
70 | STA_FILE(rx_dropped, rx_dropped, LU); | 61 | STA_FILE(rx_dropped, rx_dropped, LU); |
71 | STA_FILE(tx_fragments, tx_fragments, LU); | 62 | STA_FILE(tx_fragments, tx_fragments, LU); |
72 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
73 | STA_FILE(txrate, txrate, RATE); | ||
74 | STA_FILE(last_txrate, last_txrate, RATE); | ||
75 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
76 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
77 | STA_FILE(last_rssi, last_rssi, D); | 66 | STA_FILE(last_rssi, last_rssi, D); |
@@ -85,12 +74,10 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
85 | { | 74 | { |
86 | char buf[100]; | 75 | char buf[100]; |
87 | struct sta_info *sta = file->private_data; | 76 | struct sta_info *sta = file->private_data; |
88 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", | 77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
89 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", |
90 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
91 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", |
92 | sta->flags & WLAN_STA_TIM ? "TIM\n" : "", | ||
93 | sta->flags & WLAN_STA_PERM ? "PERM\n" : "", | ||
94 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
95 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
96 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", |
@@ -111,31 +98,6 @@ static ssize_t sta_num_ps_buf_frames_read(struct file *file, | |||
111 | } | 98 | } |
112 | STA_OPS(num_ps_buf_frames); | 99 | STA_OPS(num_ps_buf_frames); |
113 | 100 | ||
114 | static ssize_t sta_last_ack_rssi_read(struct file *file, char __user *userbuf, | ||
115 | size_t count, loff_t *ppos) | ||
116 | { | ||
117 | char buf[100]; | ||
118 | struct sta_info *sta = file->private_data; | ||
119 | int res = scnprintf(buf, sizeof(buf), "%d %d %d\n", | ||
120 | sta->last_ack_rssi[0], | ||
121 | sta->last_ack_rssi[1], | ||
122 | sta->last_ack_rssi[2]); | ||
123 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
124 | } | ||
125 | STA_OPS(last_ack_rssi); | ||
126 | |||
127 | static ssize_t sta_last_ack_ms_read(struct file *file, char __user *userbuf, | ||
128 | size_t count, loff_t *ppos) | ||
129 | { | ||
130 | char buf[20]; | ||
131 | struct sta_info *sta = file->private_data; | ||
132 | int res = scnprintf(buf, sizeof(buf), "%d\n", | ||
133 | sta->last_ack ? | ||
134 | jiffies_to_msecs(jiffies - sta->last_ack) : -1); | ||
135 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | ||
136 | } | ||
137 | STA_OPS(last_ack_ms); | ||
138 | |||
139 | static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, | 101 | static ssize_t sta_inactive_ms_read(struct file *file, char __user *userbuf, |
140 | size_t count, loff_t *ppos) | 102 | size_t count, loff_t *ppos) |
141 | { | 103 | { |
@@ -191,6 +153,113 @@ static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf, | |||
191 | STA_OPS(wme_tx_queue); | 153 | STA_OPS(wme_tx_queue); |
192 | #endif | 154 | #endif |
193 | 155 | ||
156 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | ||
157 | size_t count, loff_t *ppos) | ||
158 | { | ||
159 | char buf[768], *p = buf; | ||
160 | int i; | ||
161 | struct sta_info *sta = file->private_data; | ||
162 | p += scnprintf(p, sizeof(buf)+buf-p, "Agg state for STA is:\n"); | ||
163 | p += scnprintf(p, sizeof(buf)+buf-p, " STA next dialog_token is %d \n " | ||
164 | "TIDs info is: \n TID :", | ||
165 | (sta->ampdu_mlme.dialog_token_allocator + 1)); | ||
166 | for (i = 0; i < STA_TID_NUM; i++) | ||
167 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", i); | ||
168 | |||
169 | p += scnprintf(p, sizeof(buf)+buf-p, "\n RX :"); | ||
170 | for (i = 0; i < STA_TID_NUM; i++) | ||
171 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
172 | sta->ampdu_mlme.tid_rx[i].state); | ||
173 | |||
174 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
175 | for (i = 0; i < STA_TID_NUM; i++) | ||
176 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
177 | sta->ampdu_mlme.tid_rx[i].dialog_token); | ||
178 | |||
179 | p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :"); | ||
180 | for (i = 0; i < STA_TID_NUM; i++) | ||
181 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
182 | sta->ampdu_mlme.tid_tx[i].state); | ||
183 | |||
184 | p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:"); | ||
185 | for (i = 0; i < STA_TID_NUM; i++) | ||
186 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
187 | sta->ampdu_mlme.tid_tx[i].dialog_token); | ||
188 | |||
189 | p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :"); | ||
190 | for (i = 0; i < STA_TID_NUM; i++) | ||
191 | p += scnprintf(p, sizeof(buf)+buf-p, "%5d", | ||
192 | sta->ampdu_mlme.tid_tx[i].ssn); | ||
193 | |||
194 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
195 | |||
196 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
197 | } | ||
198 | |||
199 | static ssize_t sta_agg_status_write(struct file *file, | ||
200 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
201 | { | ||
202 | struct sta_info *sta = file->private_data; | ||
203 | struct net_device *dev = sta->dev; | ||
204 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
205 | struct ieee80211_hw *hw = &local->hw; | ||
206 | u8 *da = sta->addr; | ||
207 | static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0, | ||
208 | 0, 0, 0, 0, 0, 0, 0, 0}; | ||
209 | static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1, | ||
210 | 1, 1, 1, 1, 1, 1, 1, 1}; | ||
211 | char *endp; | ||
212 | char buf[32]; | ||
213 | int buf_size, rs; | ||
214 | unsigned int tid_num; | ||
215 | char state[4]; | ||
216 | |||
217 | memset(buf, 0x00, sizeof(buf)); | ||
218 | buf_size = min(count, (sizeof(buf)-1)); | ||
219 | if (copy_from_user(buf, user_buf, buf_size)) | ||
220 | return -EFAULT; | ||
221 | |||
222 | tid_num = simple_strtoul(buf, &endp, 0); | ||
223 | if (endp == buf) | ||
224 | return -EINVAL; | ||
225 | |||
226 | if ((tid_num >= 100) && (tid_num <= 115)) { | ||
227 | /* toggle Rx aggregation command */ | ||
228 | tid_num = tid_num - 100; | ||
229 | if (tid_static_rx[tid_num] == 1) { | ||
230 | strcpy(state, "off "); | ||
231 | ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0, | ||
232 | WLAN_REASON_QSTA_REQUIRE_SETUP); | ||
233 | sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0xFF; | ||
234 | tid_static_rx[tid_num] = 0; | ||
235 | } else { | ||
236 | strcpy(state, "on "); | ||
237 | sta->ampdu_mlme.tid_rx[tid_num].buf_size = 0x00; | ||
238 | tid_static_rx[tid_num] = 1; | ||
239 | } | ||
240 | printk(KERN_DEBUG "debugfs - try switching tid %u %s\n", | ||
241 | tid_num, state); | ||
242 | } else if ((tid_num >= 0) && (tid_num <= 15)) { | ||
243 | /* toggle Tx aggregation command */ | ||
244 | if (tid_static_tx[tid_num] == 0) { | ||
245 | strcpy(state, "on "); | ||
246 | rs = ieee80211_start_tx_ba_session(hw, da, tid_num); | ||
247 | if (rs == 0) | ||
248 | tid_static_tx[tid_num] = 1; | ||
249 | } else { | ||
250 | strcpy(state, "off"); | ||
251 | rs = ieee80211_stop_tx_ba_session(hw, da, tid_num, 1); | ||
252 | if (rs == 0) | ||
253 | tid_static_tx[tid_num] = 0; | ||
254 | } | ||
255 | printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n", | ||
256 | tid_num, state, rs); | ||
257 | } | ||
258 | |||
259 | return count; | ||
260 | } | ||
261 | STA_OPS_WR(agg_status); | ||
262 | |||
194 | #define DEBUGFS_ADD(name) \ | 263 | #define DEBUGFS_ADD(name) \ |
195 | sta->debugfs.name = debugfs_create_file(#name, 0444, \ | 264 | sta->debugfs.name = debugfs_create_file(#name, 0444, \ |
196 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 265 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
@@ -203,12 +272,13 @@ STA_OPS(wme_tx_queue); | |||
203 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 272 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
204 | { | 273 | { |
205 | struct dentry *stations_dir = sta->local->debugfs.stations; | 274 | struct dentry *stations_dir = sta->local->debugfs.stations; |
206 | DECLARE_MAC_BUF(mac); | 275 | DECLARE_MAC_BUF(mbuf); |
276 | u8 *mac; | ||
207 | 277 | ||
208 | if (!stations_dir) | 278 | if (!stations_dir) |
209 | return; | 279 | return; |
210 | 280 | ||
211 | print_mac(mac, sta->addr); | 281 | mac = print_mac(mbuf, sta->addr); |
212 | 282 | ||
213 | sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); | 283 | sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); |
214 | if (!sta->debugfs.dir) | 284 | if (!sta->debugfs.dir) |
@@ -216,28 +286,26 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
216 | 286 | ||
217 | DEBUGFS_ADD(flags); | 287 | DEBUGFS_ADD(flags); |
218 | DEBUGFS_ADD(num_ps_buf_frames); | 288 | DEBUGFS_ADD(num_ps_buf_frames); |
219 | DEBUGFS_ADD(last_ack_rssi); | ||
220 | DEBUGFS_ADD(last_ack_ms); | ||
221 | DEBUGFS_ADD(inactive_ms); | 289 | DEBUGFS_ADD(inactive_ms); |
222 | DEBUGFS_ADD(last_seq_ctrl); | 290 | DEBUGFS_ADD(last_seq_ctrl); |
223 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 291 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
224 | DEBUGFS_ADD(wme_rx_queue); | 292 | DEBUGFS_ADD(wme_rx_queue); |
225 | DEBUGFS_ADD(wme_tx_queue); | 293 | DEBUGFS_ADD(wme_tx_queue); |
226 | #endif | 294 | #endif |
295 | DEBUGFS_ADD(agg_status); | ||
227 | } | 296 | } |
228 | 297 | ||
229 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) | 298 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) |
230 | { | 299 | { |
231 | DEBUGFS_DEL(flags); | 300 | DEBUGFS_DEL(flags); |
232 | DEBUGFS_DEL(num_ps_buf_frames); | 301 | DEBUGFS_DEL(num_ps_buf_frames); |
233 | DEBUGFS_DEL(last_ack_rssi); | ||
234 | DEBUGFS_DEL(last_ack_ms); | ||
235 | DEBUGFS_DEL(inactive_ms); | 302 | DEBUGFS_DEL(inactive_ms); |
236 | DEBUGFS_DEL(last_seq_ctrl); | 303 | DEBUGFS_DEL(last_seq_ctrl); |
237 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 304 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
238 | DEBUGFS_DEL(wme_rx_queue); | 305 | DEBUGFS_DEL(wme_rx_queue); |
239 | DEBUGFS_DEL(wme_tx_queue); | 306 | DEBUGFS_DEL(wme_tx_queue); |
240 | #endif | 307 | #endif |
308 | DEBUGFS_DEL(agg_status); | ||
241 | 309 | ||
242 | debugfs_remove(sta->debugfs.dir); | 310 | debugfs_remove(sta->debugfs.dir); |
243 | sta->debugfs.dir = NULL; | 311 | sta->debugfs.dir = NULL; |
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 28bcdf9fc3df..2133c9fd27a4 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c | |||
@@ -67,9 +67,19 @@ static void ieee80211_configure_filter(struct ieee80211_local *local) | |||
67 | new_flags |= FIF_ALLMULTI; | 67 | new_flags |= FIF_ALLMULTI; |
68 | 68 | ||
69 | if (local->monitors) | 69 | if (local->monitors) |
70 | new_flags |= FIF_CONTROL | | 70 | new_flags |= FIF_BCN_PRBRESP_PROMISC; |
71 | FIF_OTHER_BSS | | 71 | |
72 | FIF_BCN_PRBRESP_PROMISC; | 72 | if (local->fif_fcsfail) |
73 | new_flags |= FIF_FCSFAIL; | ||
74 | |||
75 | if (local->fif_plcpfail) | ||
76 | new_flags |= FIF_PLCPFAIL; | ||
77 | |||
78 | if (local->fif_control) | ||
79 | new_flags |= FIF_CONTROL; | ||
80 | |||
81 | if (local->fif_other_bss) | ||
82 | new_flags |= FIF_OTHER_BSS; | ||
73 | 83 | ||
74 | changed_flags = local->filter_flags ^ new_flags; | 84 | changed_flags = local->filter_flags ^ new_flags; |
75 | 85 | ||
@@ -173,8 +183,52 @@ static int ieee80211_open(struct net_device *dev) | |||
173 | list_for_each_entry(nsdata, &local->interfaces, list) { | 183 | list_for_each_entry(nsdata, &local->interfaces, list) { |
174 | struct net_device *ndev = nsdata->dev; | 184 | struct net_device *ndev = nsdata->dev; |
175 | 185 | ||
176 | if (ndev != dev && ndev != local->mdev && netif_running(ndev) && | 186 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { |
177 | compare_ether_addr(dev->dev_addr, ndev->dev_addr) == 0) { | 187 | /* |
188 | * Allow only a single IBSS interface to be up at any | ||
189 | * time. This is restricted because beacon distribution | ||
190 | * cannot work properly if both are in the same IBSS. | ||
191 | * | ||
192 | * To remove this restriction we'd have to disallow them | ||
193 | * from setting the same SSID on different IBSS interfaces | ||
194 | * belonging to the same hardware. Then, however, we're | ||
195 | * faced with having to adopt two different TSF timers... | ||
196 | */ | ||
197 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | ||
198 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS) | ||
199 | return -EBUSY; | ||
200 | |||
201 | /* | ||
202 | * Disallow multiple IBSS/STA mode interfaces. | ||
203 | * | ||
204 | * This is a technical restriction, it is possible although | ||
205 | * most likely not IEEE 802.11 compliant to have multiple | ||
206 | * STAs with just a single hardware (the TSF timer will not | ||
207 | * be adjusted properly.) | ||
208 | * | ||
209 | * However, because mac80211 uses the master device's BSS | ||
210 | * information for each STA/IBSS interface, doing this will | ||
211 | * currently corrupt that BSS information completely, unless, | ||
212 | * a not very useful case, both STAs are associated to the | ||
213 | * same BSS. | ||
214 | * | ||
215 | * To remove this restriction, the BSS information needs to | ||
216 | * be embedded in the STA/IBSS mode sdata instead of using | ||
217 | * the master device's BSS structure. | ||
218 | */ | ||
219 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
220 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && | ||
221 | (nsdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
222 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)) | ||
223 | return -EBUSY; | ||
224 | |||
225 | /* | ||
226 | * The remaining checks are only performed for interfaces | ||
227 | * with the same MAC address. | ||
228 | */ | ||
229 | if (compare_ether_addr(dev->dev_addr, ndev->dev_addr)) | ||
230 | continue; | ||
231 | |||
178 | /* | 232 | /* |
179 | * check whether it may have the same address | 233 | * check whether it may have the same address |
180 | */ | 234 | */ |
@@ -186,8 +240,7 @@ static int ieee80211_open(struct net_device *dev) | |||
186 | * can only add VLANs to enabled APs | 240 | * can only add VLANs to enabled APs |
187 | */ | 241 | */ |
188 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 242 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
189 | nsdata->vif.type == IEEE80211_IF_TYPE_AP && | 243 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
190 | netif_running(nsdata->dev)) | ||
191 | sdata->u.vlan.ap = nsdata; | 244 | sdata->u.vlan.ap = nsdata; |
192 | } | 245 | } |
193 | } | 246 | } |
@@ -229,15 +282,28 @@ static int ieee80211_open(struct net_device *dev) | |||
229 | /* no need to tell driver */ | 282 | /* no need to tell driver */ |
230 | break; | 283 | break; |
231 | case IEEE80211_IF_TYPE_MNTR: | 284 | case IEEE80211_IF_TYPE_MNTR: |
285 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { | ||
286 | local->cooked_mntrs++; | ||
287 | break; | ||
288 | } | ||
289 | |||
232 | /* must be before the call to ieee80211_configure_filter */ | 290 | /* must be before the call to ieee80211_configure_filter */ |
233 | local->monitors++; | 291 | local->monitors++; |
234 | if (local->monitors == 1) { | 292 | if (local->monitors == 1) |
235 | netif_tx_lock_bh(local->mdev); | ||
236 | ieee80211_configure_filter(local); | ||
237 | netif_tx_unlock_bh(local->mdev); | ||
238 | |||
239 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 293 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; |
240 | } | 294 | |
295 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
296 | local->fif_fcsfail++; | ||
297 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
298 | local->fif_plcpfail++; | ||
299 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
300 | local->fif_control++; | ||
301 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
302 | local->fif_other_bss++; | ||
303 | |||
304 | netif_tx_lock_bh(local->mdev); | ||
305 | ieee80211_configure_filter(local); | ||
306 | netif_tx_unlock_bh(local->mdev); | ||
241 | break; | 307 | break; |
242 | case IEEE80211_IF_TYPE_STA: | 308 | case IEEE80211_IF_TYPE_STA: |
243 | case IEEE80211_IF_TYPE_IBSS: | 309 | case IEEE80211_IF_TYPE_IBSS: |
@@ -352,14 +418,27 @@ static int ieee80211_stop(struct net_device *dev) | |||
352 | /* no need to tell driver */ | 418 | /* no need to tell driver */ |
353 | break; | 419 | break; |
354 | case IEEE80211_IF_TYPE_MNTR: | 420 | case IEEE80211_IF_TYPE_MNTR: |
355 | local->monitors--; | 421 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { |
356 | if (local->monitors == 0) { | 422 | local->cooked_mntrs--; |
357 | netif_tx_lock_bh(local->mdev); | 423 | break; |
358 | ieee80211_configure_filter(local); | 424 | } |
359 | netif_tx_unlock_bh(local->mdev); | ||
360 | 425 | ||
426 | local->monitors--; | ||
427 | if (local->monitors == 0) | ||
361 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 428 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; |
362 | } | 429 | |
430 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | ||
431 | local->fif_fcsfail--; | ||
432 | if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) | ||
433 | local->fif_plcpfail--; | ||
434 | if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) | ||
435 | local->fif_control--; | ||
436 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | ||
437 | local->fif_other_bss--; | ||
438 | |||
439 | netif_tx_lock_bh(local->mdev); | ||
440 | ieee80211_configure_filter(local); | ||
441 | netif_tx_unlock_bh(local->mdev); | ||
363 | break; | 442 | break; |
364 | case IEEE80211_IF_TYPE_STA: | 443 | case IEEE80211_IF_TYPE_STA: |
365 | case IEEE80211_IF_TYPE_IBSS: | 444 | case IEEE80211_IF_TYPE_IBSS: |
@@ -414,6 +493,329 @@ static int ieee80211_stop(struct net_device *dev) | |||
414 | return 0; | 493 | return 0; |
415 | } | 494 | } |
416 | 495 | ||
496 | int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
497 | { | ||
498 | struct ieee80211_local *local = hw_to_local(hw); | ||
499 | struct sta_info *sta; | ||
500 | struct ieee80211_sub_if_data *sdata; | ||
501 | u16 start_seq_num = 0; | ||
502 | u8 *state; | ||
503 | int ret; | ||
504 | DECLARE_MAC_BUF(mac); | ||
505 | |||
506 | if (tid >= STA_TID_NUM) | ||
507 | return -EINVAL; | ||
508 | |||
509 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
510 | printk(KERN_DEBUG "Open BA session requested for %s tid %u\n", | ||
511 | print_mac(mac, ra), tid); | ||
512 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
513 | |||
514 | sta = sta_info_get(local, ra); | ||
515 | if (!sta) { | ||
516 | printk(KERN_DEBUG "Could not find the station\n"); | ||
517 | return -ENOENT; | ||
518 | } | ||
519 | |||
520 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
521 | |||
522 | /* we have tried too many times, receiver does not want A-MPDU */ | ||
523 | if (sta->ampdu_mlme.tid_tx[tid].addba_req_num > HT_AGG_MAX_RETRIES) { | ||
524 | ret = -EBUSY; | ||
525 | goto start_ba_exit; | ||
526 | } | ||
527 | |||
528 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
529 | /* check if the TID is not in aggregation flow already */ | ||
530 | if (*state != HT_AGG_STATE_IDLE) { | ||
531 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
532 | printk(KERN_DEBUG "BA request denied - session is not " | ||
533 | "idle on tid %u\n", tid); | ||
534 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
535 | ret = -EAGAIN; | ||
536 | goto start_ba_exit; | ||
537 | } | ||
538 | |||
539 | /* ensure that TX flow won't interrupt us | ||
540 | * until the end of the call to requeue function */ | ||
541 | spin_lock_bh(&local->mdev->queue_lock); | ||
542 | |||
543 | /* create a new queue for this aggregation */ | ||
544 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | ||
545 | |||
546 | /* case no queue is available to aggregation | ||
547 | * don't switch to aggregation */ | ||
548 | if (ret) { | ||
549 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
550 | printk(KERN_DEBUG "BA request denied - no queue available for" | ||
551 | " tid %d\n", tid); | ||
552 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
553 | spin_unlock_bh(&local->mdev->queue_lock); | ||
554 | goto start_ba_exit; | ||
555 | } | ||
556 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
557 | |||
558 | /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the | ||
559 | * call back right away, it must see that the flow has begun */ | ||
560 | *state |= HT_ADDBA_REQUESTED_MSK; | ||
561 | |||
562 | if (local->ops->ampdu_action) | ||
563 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, | ||
564 | ra, tid, &start_seq_num); | ||
565 | |||
566 | if (ret) { | ||
567 | /* No need to requeue the packets in the agg queue, since we | ||
568 | * held the tx lock: no packet could be enqueued to the newly | ||
569 | * allocated queue */ | ||
570 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | ||
571 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
572 | printk(KERN_DEBUG "BA request denied - HW or queue unavailable" | ||
573 | " for tid %d\n", tid); | ||
574 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
575 | spin_unlock_bh(&local->mdev->queue_lock); | ||
576 | *state = HT_AGG_STATE_IDLE; | ||
577 | goto start_ba_exit; | ||
578 | } | ||
579 | |||
580 | /* Will put all the packets in the new SW queue */ | ||
581 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | ||
582 | spin_unlock_bh(&local->mdev->queue_lock); | ||
583 | |||
584 | /* We have most probably almost emptied the legacy queue */ | ||
585 | /* ieee80211_wake_queue(local_to_hw(local), ieee802_1d_to_ac[tid]); */ | ||
586 | |||
587 | /* send an addBA request */ | ||
588 | sta->ampdu_mlme.dialog_token_allocator++; | ||
589 | sta->ampdu_mlme.tid_tx[tid].dialog_token = | ||
590 | sta->ampdu_mlme.dialog_token_allocator; | ||
591 | sta->ampdu_mlme.tid_tx[tid].ssn = start_seq_num; | ||
592 | |||
593 | ieee80211_send_addba_request(sta->dev, ra, tid, | ||
594 | sta->ampdu_mlme.tid_tx[tid].dialog_token, | ||
595 | sta->ampdu_mlme.tid_tx[tid].ssn, | ||
596 | 0x40, 5000); | ||
597 | |||
598 | /* activate the timer for the recipient's addBA response */ | ||
599 | sta->ampdu_mlme.tid_tx[tid].addba_resp_timer.expires = | ||
600 | jiffies + ADDBA_RESP_INTERVAL; | ||
601 | add_timer(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); | ||
602 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | ||
603 | |||
604 | start_ba_exit: | ||
605 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
606 | sta_info_put(sta); | ||
607 | return ret; | ||
608 | } | ||
609 | EXPORT_SYMBOL(ieee80211_start_tx_ba_session); | ||
610 | |||
611 | int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | ||
612 | u8 *ra, u16 tid, | ||
613 | enum ieee80211_back_parties initiator) | ||
614 | { | ||
615 | struct ieee80211_local *local = hw_to_local(hw); | ||
616 | struct sta_info *sta; | ||
617 | u8 *state; | ||
618 | int ret = 0; | ||
619 | DECLARE_MAC_BUF(mac); | ||
620 | |||
621 | if (tid >= STA_TID_NUM) | ||
622 | return -EINVAL; | ||
623 | |||
624 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
625 | printk(KERN_DEBUG "Stop a BA session requested for %s tid %u\n", | ||
626 | print_mac(mac, ra), tid); | ||
627 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
628 | |||
629 | sta = sta_info_get(local, ra); | ||
630 | if (!sta) | ||
631 | return -ENOENT; | ||
632 | |||
633 | /* check if the TID is in aggregation */ | ||
634 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
635 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
636 | |||
637 | if (*state != HT_AGG_STATE_OPERATIONAL) { | ||
638 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
639 | printk(KERN_DEBUG "Try to stop Tx aggregation on" | ||
640 | " non active TID\n"); | ||
641 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
642 | ret = -ENOENT; | ||
643 | goto stop_BA_exit; | ||
644 | } | ||
645 | |||
646 | ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]); | ||
647 | |||
648 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | ||
649 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | ||
650 | |||
651 | if (local->ops->ampdu_action) | ||
652 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP, | ||
653 | ra, tid, NULL); | ||
654 | |||
655 | /* case HW denied going back to legacy */ | ||
656 | if (ret) { | ||
657 | WARN_ON(ret != -EBUSY); | ||
658 | *state = HT_AGG_STATE_OPERATIONAL; | ||
659 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
660 | goto stop_BA_exit; | ||
661 | } | ||
662 | |||
663 | stop_BA_exit: | ||
664 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
665 | sta_info_put(sta); | ||
666 | return ret; | ||
667 | } | ||
668 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | ||
669 | |||
670 | void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | ||
671 | { | ||
672 | struct ieee80211_local *local = hw_to_local(hw); | ||
673 | struct sta_info *sta; | ||
674 | u8 *state; | ||
675 | DECLARE_MAC_BUF(mac); | ||
676 | |||
677 | if (tid >= STA_TID_NUM) { | ||
678 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
679 | tid, STA_TID_NUM); | ||
680 | return; | ||
681 | } | ||
682 | |||
683 | sta = sta_info_get(local, ra); | ||
684 | if (!sta) { | ||
685 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
686 | print_mac(mac, ra)); | ||
687 | return; | ||
688 | } | ||
689 | |||
690 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
691 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
692 | |||
693 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | ||
694 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | ||
695 | *state); | ||
696 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
697 | sta_info_put(sta); | ||
698 | return; | ||
699 | } | ||
700 | |||
701 | WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK); | ||
702 | |||
703 | *state |= HT_ADDBA_DRV_READY_MSK; | ||
704 | |||
705 | if (*state == HT_AGG_STATE_OPERATIONAL) { | ||
706 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | ||
707 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
708 | } | ||
709 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
710 | sta_info_put(sta); | ||
711 | } | ||
712 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | ||
713 | |||
714 | void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | ||
715 | { | ||
716 | struct ieee80211_local *local = hw_to_local(hw); | ||
717 | struct sta_info *sta; | ||
718 | u8 *state; | ||
719 | int agg_queue; | ||
720 | DECLARE_MAC_BUF(mac); | ||
721 | |||
722 | if (tid >= STA_TID_NUM) { | ||
723 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | ||
724 | tid, STA_TID_NUM); | ||
725 | return; | ||
726 | } | ||
727 | |||
728 | printk(KERN_DEBUG "Stop a BA session requested on DA %s tid %d\n", | ||
729 | print_mac(mac, ra), tid); | ||
730 | |||
731 | sta = sta_info_get(local, ra); | ||
732 | if (!sta) { | ||
733 | printk(KERN_DEBUG "Could not find station: %s\n", | ||
734 | print_mac(mac, ra)); | ||
735 | return; | ||
736 | } | ||
737 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
738 | |||
739 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
740 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | ||
741 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | ||
742 | sta_info_put(sta); | ||
743 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
744 | return; | ||
745 | } | ||
746 | |||
747 | if (*state & HT_AGG_STATE_INITIATOR_MSK) | ||
748 | ieee80211_send_delba(sta->dev, ra, tid, | ||
749 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | ||
750 | |||
751 | agg_queue = sta->tid_to_tx_q[tid]; | ||
752 | |||
753 | /* avoid ordering issues: we are the only one that can modify | ||
754 | * the content of the qdiscs */ | ||
755 | spin_lock_bh(&local->mdev->queue_lock); | ||
756 | /* remove the queue for this aggregation */ | ||
757 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | ||
758 | spin_unlock_bh(&local->mdev->queue_lock); | ||
759 | |||
760 | /* we just requeued the all the frames that were in the removed | ||
761 | * queue, and since we might miss a softirq we do netif_schedule. | ||
762 | * ieee80211_wake_queue is not used here as this queue is not | ||
763 | * necessarily stopped */ | ||
764 | netif_schedule(local->mdev); | ||
765 | *state = HT_AGG_STATE_IDLE; | ||
766 | sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; | ||
767 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
768 | |||
769 | sta_info_put(sta); | ||
770 | } | ||
771 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb); | ||
772 | |||
773 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
774 | const u8 *ra, u16 tid) | ||
775 | { | ||
776 | struct ieee80211_local *local = hw_to_local(hw); | ||
777 | struct ieee80211_ra_tid *ra_tid; | ||
778 | struct sk_buff *skb = dev_alloc_skb(0); | ||
779 | |||
780 | if (unlikely(!skb)) { | ||
781 | if (net_ratelimit()) | ||
782 | printk(KERN_WARNING "%s: Not enough memory, " | ||
783 | "dropping start BA session", skb->dev->name); | ||
784 | return; | ||
785 | } | ||
786 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
787 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
788 | ra_tid->tid = tid; | ||
789 | |||
790 | skb->pkt_type = IEEE80211_ADDBA_MSG; | ||
791 | skb_queue_tail(&local->skb_queue, skb); | ||
792 | tasklet_schedule(&local->tasklet); | ||
793 | } | ||
794 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | ||
795 | |||
796 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | ||
797 | const u8 *ra, u16 tid) | ||
798 | { | ||
799 | struct ieee80211_local *local = hw_to_local(hw); | ||
800 | struct ieee80211_ra_tid *ra_tid; | ||
801 | struct sk_buff *skb = dev_alloc_skb(0); | ||
802 | |||
803 | if (unlikely(!skb)) { | ||
804 | if (net_ratelimit()) | ||
805 | printk(KERN_WARNING "%s: Not enough memory, " | ||
806 | "dropping stop BA session", skb->dev->name); | ||
807 | return; | ||
808 | } | ||
809 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
810 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | ||
811 | ra_tid->tid = tid; | ||
812 | |||
813 | skb->pkt_type = IEEE80211_DELBA_MSG; | ||
814 | skb_queue_tail(&local->skb_queue, skb); | ||
815 | tasklet_schedule(&local->tasklet); | ||
816 | } | ||
817 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); | ||
818 | |||
417 | static void ieee80211_set_multicast_list(struct net_device *dev) | 819 | static void ieee80211_set_multicast_list(struct net_device *dev) |
418 | { | 820 | { |
419 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 821 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -479,8 +881,11 @@ int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr) | |||
479 | 881 | ||
480 | /* Create STA entry for the new peer */ | 882 | /* Create STA entry for the new peer */ |
481 | sta = sta_info_add(local, dev, remote_addr, GFP_KERNEL); | 883 | sta = sta_info_add(local, dev, remote_addr, GFP_KERNEL); |
482 | if (!sta) | 884 | if (IS_ERR(sta)) |
483 | return -ENOMEM; | 885 | return PTR_ERR(sta); |
886 | |||
887 | sta->flags |= WLAN_STA_AUTHORIZED; | ||
888 | |||
484 | sta_info_put(sta); | 889 | sta_info_put(sta); |
485 | 890 | ||
486 | /* Remove STA entry for the old peer */ | 891 | /* Remove STA entry for the old peer */ |
@@ -553,37 +958,28 @@ int ieee80211_if_config_beacon(struct net_device *dev) | |||
553 | 958 | ||
554 | int ieee80211_hw_config(struct ieee80211_local *local) | 959 | int ieee80211_hw_config(struct ieee80211_local *local) |
555 | { | 960 | { |
556 | struct ieee80211_hw_mode *mode; | ||
557 | struct ieee80211_channel *chan; | 961 | struct ieee80211_channel *chan; |
558 | int ret = 0; | 962 | int ret = 0; |
559 | 963 | ||
560 | if (local->sta_sw_scanning) { | 964 | if (local->sta_sw_scanning) |
561 | chan = local->scan_channel; | 965 | chan = local->scan_channel; |
562 | mode = local->scan_hw_mode; | 966 | else |
563 | } else { | ||
564 | chan = local->oper_channel; | 967 | chan = local->oper_channel; |
565 | mode = local->oper_hw_mode; | ||
566 | } | ||
567 | 968 | ||
568 | local->hw.conf.channel = chan->chan; | 969 | local->hw.conf.channel = chan; |
569 | local->hw.conf.channel_val = chan->val; | 970 | |
570 | if (!local->hw.conf.power_level) { | 971 | if (!local->hw.conf.power_level) |
571 | local->hw.conf.power_level = chan->power_level; | 972 | local->hw.conf.power_level = chan->max_power; |
572 | } else { | 973 | else |
573 | local->hw.conf.power_level = min(chan->power_level, | 974 | local->hw.conf.power_level = min(chan->max_power, |
574 | local->hw.conf.power_level); | 975 | local->hw.conf.power_level); |
575 | } | 976 | |
576 | local->hw.conf.freq = chan->freq; | 977 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; |
577 | local->hw.conf.phymode = mode->mode; | ||
578 | local->hw.conf.antenna_max = chan->antenna_max; | ||
579 | local->hw.conf.chan = chan; | ||
580 | local->hw.conf.mode = mode; | ||
581 | 978 | ||
582 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 979 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
583 | printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d " | 980 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", |
584 | "phymode=%d\n", local->hw.conf.channel, local->hw.conf.freq, | 981 | wiphy_name(local->hw.wiphy), chan->center_freq); |
585 | local->hw.conf.phymode); | 982 | #endif |
586 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
587 | 983 | ||
588 | if (local->open_count) | 984 | if (local->open_count) |
589 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | 985 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); |
@@ -601,11 +997,13 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
601 | struct ieee80211_ht_bss_info *req_bss_cap) | 997 | struct ieee80211_ht_bss_info *req_bss_cap) |
602 | { | 998 | { |
603 | struct ieee80211_conf *conf = &local->hw.conf; | 999 | struct ieee80211_conf *conf = &local->hw.conf; |
604 | struct ieee80211_hw_mode *mode = conf->mode; | 1000 | struct ieee80211_supported_band *sband; |
605 | int i; | 1001 | int i; |
606 | 1002 | ||
1003 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
1004 | |||
607 | /* HT is not supported */ | 1005 | /* HT is not supported */ |
608 | if (!mode->ht_info.ht_supported) { | 1006 | if (!sband->ht_info.ht_supported) { |
609 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1007 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
610 | return -EOPNOTSUPP; | 1008 | return -EOPNOTSUPP; |
611 | } | 1009 | } |
@@ -615,17 +1013,17 @@ int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | |||
615 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1013 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
616 | } else { | 1014 | } else { |
617 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | 1015 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
618 | conf->ht_conf.cap = req_ht_cap->cap & mode->ht_info.cap; | 1016 | conf->ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
619 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1017 | conf->ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
620 | conf->ht_conf.cap |= | 1018 | conf->ht_conf.cap |= |
621 | mode->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | 1019 | sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
622 | conf->ht_bss_conf.primary_channel = | 1020 | conf->ht_bss_conf.primary_channel = |
623 | req_bss_cap->primary_channel; | 1021 | req_bss_cap->primary_channel; |
624 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1022 | conf->ht_bss_conf.bss_cap = req_bss_cap->bss_cap; |
625 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1023 | conf->ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; |
626 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1024 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) |
627 | conf->ht_conf.supp_mcs_set[i] = | 1025 | conf->ht_conf.supp_mcs_set[i] = |
628 | mode->ht_info.supp_mcs_set[i] & | 1026 | sband->ht_info.supp_mcs_set[i] & |
629 | req_ht_cap->supp_mcs_set[i]; | 1027 | req_ht_cap->supp_mcs_set[i]; |
630 | 1028 | ||
631 | /* In STA mode, this gives us indication | 1029 | /* In STA mode, this gives us indication |
@@ -713,6 +1111,7 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
713 | struct sk_buff *skb; | 1111 | struct sk_buff *skb; |
714 | struct ieee80211_rx_status rx_status; | 1112 | struct ieee80211_rx_status rx_status; |
715 | struct ieee80211_tx_status *tx_status; | 1113 | struct ieee80211_tx_status *tx_status; |
1114 | struct ieee80211_ra_tid *ra_tid; | ||
716 | 1115 | ||
717 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1116 | while ((skb = skb_dequeue(&local->skb_queue)) || |
718 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1117 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
@@ -733,6 +1132,18 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
733 | skb, tx_status); | 1132 | skb, tx_status); |
734 | kfree(tx_status); | 1133 | kfree(tx_status); |
735 | break; | 1134 | break; |
1135 | case IEEE80211_DELBA_MSG: | ||
1136 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
1137 | ieee80211_stop_tx_ba_cb(local_to_hw(local), | ||
1138 | ra_tid->ra, ra_tid->tid); | ||
1139 | dev_kfree_skb(skb); | ||
1140 | break; | ||
1141 | case IEEE80211_ADDBA_MSG: | ||
1142 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | ||
1143 | ieee80211_start_tx_ba_cb(local_to_hw(local), | ||
1144 | ra_tid->ra, ra_tid->tid); | ||
1145 | dev_kfree_skb(skb); | ||
1146 | break ; | ||
736 | default: /* should never get here! */ | 1147 | default: /* should never get here! */ |
737 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1148 | printk(KERN_ERR "%s: Unknown message type (%d)\n", |
738 | wiphy_name(local->hw.wiphy), skb->pkt_type); | 1149 | wiphy_name(local->hw.wiphy), skb->pkt_type); |
@@ -810,6 +1221,77 @@ no_key: | |||
810 | } | 1221 | } |
811 | } | 1222 | } |
812 | 1223 | ||
1224 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | ||
1225 | struct sta_info *sta, | ||
1226 | struct sk_buff *skb, | ||
1227 | struct ieee80211_tx_status *status) | ||
1228 | { | ||
1229 | sta->tx_filtered_count++; | ||
1230 | |||
1231 | /* | ||
1232 | * Clear the TX filter mask for this STA when sending the next | ||
1233 | * packet. If the STA went to power save mode, this will happen | ||
1234 | * happen when it wakes up for the next time. | ||
1235 | */ | ||
1236 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | ||
1237 | |||
1238 | /* | ||
1239 | * This code races in the following way: | ||
1240 | * | ||
1241 | * (1) STA sends frame indicating it will go to sleep and does so | ||
1242 | * (2) hardware/firmware adds STA to filter list, passes frame up | ||
1243 | * (3) hardware/firmware processes TX fifo and suppresses a frame | ||
1244 | * (4) we get TX status before having processed the frame and | ||
1245 | * knowing that the STA has gone to sleep. | ||
1246 | * | ||
1247 | * This is actually quite unlikely even when both those events are | ||
1248 | * processed from interrupts coming in quickly after one another or | ||
1249 | * even at the same time because we queue both TX status events and | ||
1250 | * RX frames to be processed by a tasklet and process them in the | ||
1251 | * same order that they were received or TX status last. Hence, there | ||
1252 | * is no race as long as the frame RX is processed before the next TX | ||
1253 | * status, which drivers can ensure, see below. | ||
1254 | * | ||
1255 | * Note that this can only happen if the hardware or firmware can | ||
1256 | * actually add STAs to the filter list, if this is done by the | ||
1257 | * driver in response to set_tim() (which will only reduce the race | ||
1258 | * this whole filtering tries to solve, not completely solve it) | ||
1259 | * this situation cannot happen. | ||
1260 | * | ||
1261 | * To completely solve this race drivers need to make sure that they | ||
1262 | * (a) don't mix the irq-safe/not irq-safe TX status/RX processing | ||
1263 | * functions and | ||
1264 | * (b) always process RX events before TX status events if ordering | ||
1265 | * can be unknown, for example with different interrupt status | ||
1266 | * bits. | ||
1267 | */ | ||
1268 | if (sta->flags & WLAN_STA_PS && | ||
1269 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | ||
1270 | ieee80211_remove_tx_extra(local, sta->key, skb, | ||
1271 | &status->control); | ||
1272 | skb_queue_tail(&sta->tx_filtered, skb); | ||
1273 | return; | ||
1274 | } | ||
1275 | |||
1276 | if (!(sta->flags & WLAN_STA_PS) && | ||
1277 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | ||
1278 | /* Software retry the packet once */ | ||
1279 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
1280 | ieee80211_remove_tx_extra(local, sta->key, skb, | ||
1281 | &status->control); | ||
1282 | dev_queue_xmit(skb); | ||
1283 | return; | ||
1284 | } | ||
1285 | |||
1286 | if (net_ratelimit()) | ||
1287 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | ||
1288 | "queue_len=%d PS=%d @%lu\n", | ||
1289 | wiphy_name(local->hw.wiphy), | ||
1290 | skb_queue_len(&sta->tx_filtered), | ||
1291 | !!(sta->flags & WLAN_STA_PS), jiffies); | ||
1292 | dev_kfree_skb(skb); | ||
1293 | } | ||
1294 | |||
813 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1295 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
814 | struct ieee80211_tx_status *status) | 1296 | struct ieee80211_tx_status *status) |
815 | { | 1297 | { |
@@ -819,7 +1301,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
819 | u16 frag, type; | 1301 | u16 frag, type; |
820 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1302 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
821 | struct ieee80211_sub_if_data *sdata; | 1303 | struct ieee80211_sub_if_data *sdata; |
822 | int monitors; | 1304 | struct net_device *prev_dev = NULL; |
823 | 1305 | ||
824 | if (!status) { | 1306 | if (!status) { |
825 | printk(KERN_ERR | 1307 | printk(KERN_ERR |
@@ -834,11 +1316,16 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
834 | sta = sta_info_get(local, hdr->addr1); | 1316 | sta = sta_info_get(local, hdr->addr1); |
835 | if (sta) { | 1317 | if (sta) { |
836 | if (sta->flags & WLAN_STA_PS) { | 1318 | if (sta->flags & WLAN_STA_PS) { |
837 | /* The STA is in power save mode, so assume | 1319 | /* |
1320 | * The STA is in power save mode, so assume | ||
838 | * that this TX packet failed because of that. | 1321 | * that this TX packet failed because of that. |
839 | */ | 1322 | */ |
840 | status->excessive_retries = 0; | 1323 | status->excessive_retries = 0; |
841 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | 1324 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; |
1325 | ieee80211_handle_filtered_frame(local, sta, | ||
1326 | skb, status); | ||
1327 | sta_info_put(sta); | ||
1328 | return; | ||
842 | } | 1329 | } |
843 | sta_info_put(sta); | 1330 | sta_info_put(sta); |
844 | } | 1331 | } |
@@ -848,47 +1335,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
848 | struct sta_info *sta; | 1335 | struct sta_info *sta; |
849 | sta = sta_info_get(local, hdr->addr1); | 1336 | sta = sta_info_get(local, hdr->addr1); |
850 | if (sta) { | 1337 | if (sta) { |
851 | sta->tx_filtered_count++; | 1338 | ieee80211_handle_filtered_frame(local, sta, skb, |
852 | 1339 | status); | |
853 | /* Clear the TX filter mask for this STA when sending | ||
854 | * the next packet. If the STA went to power save mode, | ||
855 | * this will happen when it is waking up for the next | ||
856 | * time. */ | ||
857 | sta->clear_dst_mask = 1; | ||
858 | |||
859 | /* TODO: Is the WLAN_STA_PS flag always set here or is | ||
860 | * the race between RX and TX status causing some | ||
861 | * packets to be filtered out before 80211.o gets an | ||
862 | * update for PS status? This seems to be the case, so | ||
863 | * no changes are likely to be needed. */ | ||
864 | if (sta->flags & WLAN_STA_PS && | ||
865 | skb_queue_len(&sta->tx_filtered) < | ||
866 | STA_MAX_TX_BUFFER) { | ||
867 | ieee80211_remove_tx_extra(local, sta->key, | ||
868 | skb, | ||
869 | &status->control); | ||
870 | skb_queue_tail(&sta->tx_filtered, skb); | ||
871 | } else if (!(sta->flags & WLAN_STA_PS) && | ||
872 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | ||
873 | /* Software retry the packet once */ | ||
874 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
875 | ieee80211_remove_tx_extra(local, sta->key, | ||
876 | skb, | ||
877 | &status->control); | ||
878 | dev_queue_xmit(skb); | ||
879 | } else { | ||
880 | if (net_ratelimit()) { | ||
881 | printk(KERN_DEBUG "%s: dropped TX " | ||
882 | "filtered frame queue_len=%d " | ||
883 | "PS=%d @%lu\n", | ||
884 | wiphy_name(local->hw.wiphy), | ||
885 | skb_queue_len( | ||
886 | &sta->tx_filtered), | ||
887 | !!(sta->flags & WLAN_STA_PS), | ||
888 | jiffies); | ||
889 | } | ||
890 | dev_kfree_skb(skb); | ||
891 | } | ||
892 | sta_info_put(sta); | 1340 | sta_info_put(sta); |
893 | return; | 1341 | return; |
894 | } | 1342 | } |
@@ -932,7 +1380,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
932 | /* this was a transmitted frame, but now we want to reuse it */ | 1380 | /* this was a transmitted frame, but now we want to reuse it */ |
933 | skb_orphan(skb); | 1381 | skb_orphan(skb); |
934 | 1382 | ||
935 | if (!local->monitors) { | 1383 | /* |
1384 | * This is a bit racy but we can avoid a lot of work | ||
1385 | * with this test... | ||
1386 | */ | ||
1387 | if (!local->monitors && !local->cooked_mntrs) { | ||
936 | dev_kfree_skb(skb); | 1388 | dev_kfree_skb(skb); |
937 | return; | 1389 | return; |
938 | } | 1390 | } |
@@ -966,51 +1418,44 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
966 | 1418 | ||
967 | rthdr->data_retries = status->retry_count; | 1419 | rthdr->data_retries = status->retry_count; |
968 | 1420 | ||
1421 | /* XXX: is this sufficient for BPF? */ | ||
1422 | skb_set_mac_header(skb, 0); | ||
1423 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1424 | skb->pkt_type = PACKET_OTHERHOST; | ||
1425 | skb->protocol = htons(ETH_P_802_2); | ||
1426 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
1427 | |||
969 | rcu_read_lock(); | 1428 | rcu_read_lock(); |
970 | monitors = local->monitors; | ||
971 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 1429 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
972 | /* | ||
973 | * Using the monitors counter is possibly racy, but | ||
974 | * if the value is wrong we simply either clone the skb | ||
975 | * once too much or forget sending it to one monitor iface | ||
976 | * The latter case isn't nice but fixing the race is much | ||
977 | * more complicated. | ||
978 | */ | ||
979 | if (!monitors || !skb) | ||
980 | goto out; | ||
981 | |||
982 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { | 1430 | if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { |
983 | if (!netif_running(sdata->dev)) | 1431 | if (!netif_running(sdata->dev)) |
984 | continue; | 1432 | continue; |
985 | monitors--; | 1433 | |
986 | if (monitors) | 1434 | if (prev_dev) { |
987 | skb2 = skb_clone(skb, GFP_ATOMIC); | 1435 | skb2 = skb_clone(skb, GFP_ATOMIC); |
988 | else | 1436 | if (skb2) { |
989 | skb2 = NULL; | 1437 | skb2->dev = prev_dev; |
990 | skb->dev = sdata->dev; | 1438 | netif_rx(skb2); |
991 | /* XXX: is this sufficient for BPF? */ | 1439 | } |
992 | skb_set_mac_header(skb, 0); | 1440 | } |
993 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1441 | |
994 | skb->pkt_type = PACKET_OTHERHOST; | 1442 | prev_dev = sdata->dev; |
995 | skb->protocol = htons(ETH_P_802_2); | ||
996 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
997 | netif_rx(skb); | ||
998 | skb = skb2; | ||
999 | } | 1443 | } |
1000 | } | 1444 | } |
1001 | out: | 1445 | if (prev_dev) { |
1446 | skb->dev = prev_dev; | ||
1447 | netif_rx(skb); | ||
1448 | skb = NULL; | ||
1449 | } | ||
1002 | rcu_read_unlock(); | 1450 | rcu_read_unlock(); |
1003 | if (skb) | 1451 | dev_kfree_skb(skb); |
1004 | dev_kfree_skb(skb); | ||
1005 | } | 1452 | } |
1006 | EXPORT_SYMBOL(ieee80211_tx_status); | 1453 | EXPORT_SYMBOL(ieee80211_tx_status); |
1007 | 1454 | ||
1008 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 1455 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
1009 | const struct ieee80211_ops *ops) | 1456 | const struct ieee80211_ops *ops) |
1010 | { | 1457 | { |
1011 | struct net_device *mdev; | ||
1012 | struct ieee80211_local *local; | 1458 | struct ieee80211_local *local; |
1013 | struct ieee80211_sub_if_data *sdata; | ||
1014 | int priv_size; | 1459 | int priv_size; |
1015 | struct wiphy *wiphy; | 1460 | struct wiphy *wiphy; |
1016 | 1461 | ||
@@ -1056,25 +1501,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1056 | BUG_ON(!ops->configure_filter); | 1501 | BUG_ON(!ops->configure_filter); |
1057 | local->ops = ops; | 1502 | local->ops = ops; |
1058 | 1503 | ||
1059 | /* for now, mdev needs sub_if_data :/ */ | ||
1060 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | ||
1061 | "wmaster%d", ether_setup); | ||
1062 | if (!mdev) { | ||
1063 | wiphy_free(wiphy); | ||
1064 | return NULL; | ||
1065 | } | ||
1066 | |||
1067 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | ||
1068 | mdev->ieee80211_ptr = &sdata->wdev; | ||
1069 | sdata->wdev.wiphy = wiphy; | ||
1070 | |||
1071 | local->hw.queues = 1; /* default */ | 1504 | local->hw.queues = 1; /* default */ |
1072 | 1505 | ||
1073 | local->mdev = mdev; | ||
1074 | local->rx_pre_handlers = ieee80211_rx_pre_handlers; | ||
1075 | local->rx_handlers = ieee80211_rx_handlers; | ||
1076 | local->tx_handlers = ieee80211_tx_handlers; | ||
1077 | |||
1078 | local->bridge_packets = 1; | 1506 | local->bridge_packets = 1; |
1079 | 1507 | ||
1080 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 1508 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
@@ -1083,33 +1511,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
1083 | local->long_retry_limit = 4; | 1511 | local->long_retry_limit = 4; |
1084 | local->hw.conf.radio_enabled = 1; | 1512 | local->hw.conf.radio_enabled = 1; |
1085 | 1513 | ||
1086 | local->enabled_modes = ~0; | ||
1087 | |||
1088 | INIT_LIST_HEAD(&local->modes_list); | ||
1089 | |||
1090 | INIT_LIST_HEAD(&local->interfaces); | 1514 | INIT_LIST_HEAD(&local->interfaces); |
1091 | 1515 | ||
1092 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); | 1516 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); |
1093 | ieee80211_rx_bss_list_init(mdev); | ||
1094 | 1517 | ||
1095 | sta_info_init(local); | 1518 | sta_info_init(local); |
1096 | 1519 | ||
1097 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | ||
1098 | mdev->open = ieee80211_master_open; | ||
1099 | mdev->stop = ieee80211_master_stop; | ||
1100 | mdev->type = ARPHRD_IEEE80211; | ||
1101 | mdev->header_ops = &ieee80211_header_ops; | ||
1102 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | ||
1103 | |||
1104 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1105 | sdata->dev = mdev; | ||
1106 | sdata->local = local; | ||
1107 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1108 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1109 | ieee80211_if_sdata_init(sdata); | ||
1110 | /* no RCU needed since we're still during init phase */ | ||
1111 | list_add_tail(&sdata->list, &local->interfaces); | ||
1112 | |||
1113 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, | 1520 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, |
1114 | (unsigned long)local); | 1521 | (unsigned long)local); |
1115 | tasklet_disable(&local->tx_pending_tasklet); | 1522 | tasklet_disable(&local->tx_pending_tasklet); |
@@ -1131,11 +1538,63 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1131 | struct ieee80211_local *local = hw_to_local(hw); | 1538 | struct ieee80211_local *local = hw_to_local(hw); |
1132 | const char *name; | 1539 | const char *name; |
1133 | int result; | 1540 | int result; |
1541 | enum ieee80211_band band; | ||
1542 | struct net_device *mdev; | ||
1543 | struct ieee80211_sub_if_data *sdata; | ||
1544 | |||
1545 | /* | ||
1546 | * generic code guarantees at least one band, | ||
1547 | * set this very early because much code assumes | ||
1548 | * that hw.conf.channel is assigned | ||
1549 | */ | ||
1550 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
1551 | struct ieee80211_supported_band *sband; | ||
1552 | |||
1553 | sband = local->hw.wiphy->bands[band]; | ||
1554 | if (sband) { | ||
1555 | /* init channel we're on */ | ||
1556 | local->hw.conf.channel = | ||
1557 | local->oper_channel = | ||
1558 | local->scan_channel = &sband->channels[0]; | ||
1559 | break; | ||
1560 | } | ||
1561 | } | ||
1134 | 1562 | ||
1135 | result = wiphy_register(local->hw.wiphy); | 1563 | result = wiphy_register(local->hw.wiphy); |
1136 | if (result < 0) | 1564 | if (result < 0) |
1137 | return result; | 1565 | return result; |
1138 | 1566 | ||
1567 | /* for now, mdev needs sub_if_data :/ */ | ||
1568 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | ||
1569 | "wmaster%d", ether_setup); | ||
1570 | if (!mdev) | ||
1571 | goto fail_mdev_alloc; | ||
1572 | |||
1573 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | ||
1574 | mdev->ieee80211_ptr = &sdata->wdev; | ||
1575 | sdata->wdev.wiphy = local->hw.wiphy; | ||
1576 | |||
1577 | local->mdev = mdev; | ||
1578 | |||
1579 | ieee80211_rx_bss_list_init(mdev); | ||
1580 | |||
1581 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | ||
1582 | mdev->open = ieee80211_master_open; | ||
1583 | mdev->stop = ieee80211_master_stop; | ||
1584 | mdev->type = ARPHRD_IEEE80211; | ||
1585 | mdev->header_ops = &ieee80211_header_ops; | ||
1586 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | ||
1587 | |||
1588 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
1589 | sdata->dev = mdev; | ||
1590 | sdata->local = local; | ||
1591 | sdata->u.ap.force_unicast_rateidx = -1; | ||
1592 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
1593 | ieee80211_if_sdata_init(sdata); | ||
1594 | |||
1595 | /* no RCU needed since we're still during init phase */ | ||
1596 | list_add_tail(&sdata->list, &local->interfaces); | ||
1597 | |||
1139 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1598 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
1140 | local->hw.workqueue = create_singlethread_workqueue(name); | 1599 | local->hw.workqueue = create_singlethread_workqueue(name); |
1141 | if (!local->hw.workqueue) { | 1600 | if (!local->hw.workqueue) { |
@@ -1227,49 +1686,18 @@ fail_sta_info: | |||
1227 | debugfs_hw_del(local); | 1686 | debugfs_hw_del(local); |
1228 | destroy_workqueue(local->hw.workqueue); | 1687 | destroy_workqueue(local->hw.workqueue); |
1229 | fail_workqueue: | 1688 | fail_workqueue: |
1689 | ieee80211_if_free(local->mdev); | ||
1690 | local->mdev = NULL; | ||
1691 | fail_mdev_alloc: | ||
1230 | wiphy_unregister(local->hw.wiphy); | 1692 | wiphy_unregister(local->hw.wiphy); |
1231 | return result; | 1693 | return result; |
1232 | } | 1694 | } |
1233 | EXPORT_SYMBOL(ieee80211_register_hw); | 1695 | EXPORT_SYMBOL(ieee80211_register_hw); |
1234 | 1696 | ||
1235 | int ieee80211_register_hwmode(struct ieee80211_hw *hw, | ||
1236 | struct ieee80211_hw_mode *mode) | ||
1237 | { | ||
1238 | struct ieee80211_local *local = hw_to_local(hw); | ||
1239 | struct ieee80211_rate *rate; | ||
1240 | int i; | ||
1241 | |||
1242 | INIT_LIST_HEAD(&mode->list); | ||
1243 | list_add_tail(&mode->list, &local->modes_list); | ||
1244 | |||
1245 | local->hw_modes |= (1 << mode->mode); | ||
1246 | for (i = 0; i < mode->num_rates; i++) { | ||
1247 | rate = &(mode->rates[i]); | ||
1248 | rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; | ||
1249 | } | ||
1250 | ieee80211_prepare_rates(local, mode); | ||
1251 | |||
1252 | if (!local->oper_hw_mode) { | ||
1253 | /* Default to this mode */ | ||
1254 | local->hw.conf.phymode = mode->mode; | ||
1255 | local->oper_hw_mode = local->scan_hw_mode = mode; | ||
1256 | local->oper_channel = local->scan_channel = &mode->channels[0]; | ||
1257 | local->hw.conf.mode = local->oper_hw_mode; | ||
1258 | local->hw.conf.chan = local->oper_channel; | ||
1259 | } | ||
1260 | |||
1261 | if (!(hw->flags & IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED)) | ||
1262 | ieee80211_set_default_regdomain(mode); | ||
1263 | |||
1264 | return 0; | ||
1265 | } | ||
1266 | EXPORT_SYMBOL(ieee80211_register_hwmode); | ||
1267 | |||
1268 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1697 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
1269 | { | 1698 | { |
1270 | struct ieee80211_local *local = hw_to_local(hw); | 1699 | struct ieee80211_local *local = hw_to_local(hw); |
1271 | struct ieee80211_sub_if_data *sdata, *tmp; | 1700 | struct ieee80211_sub_if_data *sdata, *tmp; |
1272 | int i; | ||
1273 | 1701 | ||
1274 | tasklet_kill(&local->tx_pending_tasklet); | 1702 | tasklet_kill(&local->tx_pending_tasklet); |
1275 | tasklet_kill(&local->tasklet); | 1703 | tasklet_kill(&local->tasklet); |
@@ -1310,11 +1738,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1310 | rate_control_deinitialize(local); | 1738 | rate_control_deinitialize(local); |
1311 | debugfs_hw_del(local); | 1739 | debugfs_hw_del(local); |
1312 | 1740 | ||
1313 | for (i = 0; i < NUM_IEEE80211_MODES; i++) { | ||
1314 | kfree(local->supp_rates[i]); | ||
1315 | kfree(local->basic_rates[i]); | ||
1316 | } | ||
1317 | |||
1318 | if (skb_queue_len(&local->skb_queue) | 1741 | if (skb_queue_len(&local->skb_queue) |
1319 | || skb_queue_len(&local->skb_queue_unreliable)) | 1742 | || skb_queue_len(&local->skb_queue_unreliable)) |
1320 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 1743 | printk(KERN_WARNING "%s: skb_queue not empty\n", |
@@ -1326,6 +1749,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1326 | wiphy_unregister(local->hw.wiphy); | 1749 | wiphy_unregister(local->hw.wiphy); |
1327 | ieee80211_wep_free(local); | 1750 | ieee80211_wep_free(local); |
1328 | ieee80211_led_exit(local); | 1751 | ieee80211_led_exit(local); |
1752 | ieee80211_if_free(local->mdev); | ||
1753 | local->mdev = NULL; | ||
1329 | } | 1754 | } |
1330 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1755 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
1331 | 1756 | ||
@@ -1333,7 +1758,6 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1333 | { | 1758 | { |
1334 | struct ieee80211_local *local = hw_to_local(hw); | 1759 | struct ieee80211_local *local = hw_to_local(hw); |
1335 | 1760 | ||
1336 | ieee80211_if_free(local->mdev); | ||
1337 | wiphy_free(local->hw.wiphy); | 1761 | wiphy_free(local->hw.wiphy); |
1338 | } | 1762 | } |
1339 | EXPORT_SYMBOL(ieee80211_free_hw); | 1763 | EXPORT_SYMBOL(ieee80211_free_hw); |
@@ -1361,7 +1785,6 @@ static int __init ieee80211_init(void) | |||
1361 | } | 1785 | } |
1362 | 1786 | ||
1363 | ieee80211_debugfs_netdev_init(); | 1787 | ieee80211_debugfs_netdev_init(); |
1364 | ieee80211_regdomain_init(); | ||
1365 | 1788 | ||
1366 | return 0; | 1789 | return 0; |
1367 | 1790 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 72ecbf7bf962..b07b3cbfd039 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -79,8 +79,7 @@ struct ieee80211_sta_bss { | |||
79 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 79 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
80 | size_t ssid_len; | 80 | size_t ssid_len; |
81 | u16 capability; /* host byte order */ | 81 | u16 capability; /* host byte order */ |
82 | int hw_mode; | 82 | enum ieee80211_band band; |
83 | int channel; | ||
84 | int freq; | 83 | int freq; |
85 | int rssi, signal, noise; | 84 | int rssi, signal, noise; |
86 | u8 *wpa_ie; | 85 | u8 *wpa_ie; |
@@ -109,9 +108,17 @@ struct ieee80211_sta_bss { | |||
109 | }; | 108 | }; |
110 | 109 | ||
111 | 110 | ||
112 | typedef enum { | 111 | typedef unsigned __bitwise__ ieee80211_tx_result; |
113 | TXRX_CONTINUE, TXRX_DROP, TXRX_QUEUED | 112 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) |
114 | } ieee80211_txrx_result; | 113 | #define TX_DROP ((__force ieee80211_tx_result) 1u) |
114 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) | ||
115 | |||
116 | typedef unsigned __bitwise__ ieee80211_rx_result; | ||
117 | #define RX_CONTINUE ((__force ieee80211_rx_result) 0u) | ||
118 | #define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u) | ||
119 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | ||
120 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | ||
121 | |||
115 | 122 | ||
116 | /* flags used in struct ieee80211_txrx_data.flags */ | 123 | /* flags used in struct ieee80211_txrx_data.flags */ |
117 | /* whether the MSDU was fragmented */ | 124 | /* whether the MSDU was fragmented */ |
@@ -124,6 +131,7 @@ typedef enum { | |||
124 | #define IEEE80211_TXRXD_RXRA_MATCH BIT(5) | 131 | #define IEEE80211_TXRXD_RXRA_MATCH BIT(5) |
125 | #define IEEE80211_TXRXD_TX_INJECTED BIT(6) | 132 | #define IEEE80211_TXRXD_TX_INJECTED BIT(6) |
126 | #define IEEE80211_TXRXD_RX_AMSDU BIT(7) | 133 | #define IEEE80211_TXRXD_RX_AMSDU BIT(7) |
134 | #define IEEE80211_TXRXD_RX_CMNTR_REPORTED BIT(8) | ||
127 | struct ieee80211_txrx_data { | 135 | struct ieee80211_txrx_data { |
128 | struct sk_buff *skb; | 136 | struct sk_buff *skb; |
129 | struct net_device *dev; | 137 | struct net_device *dev; |
@@ -136,13 +144,12 @@ struct ieee80211_txrx_data { | |||
136 | union { | 144 | union { |
137 | struct { | 145 | struct { |
138 | struct ieee80211_tx_control *control; | 146 | struct ieee80211_tx_control *control; |
139 | struct ieee80211_hw_mode *mode; | 147 | struct ieee80211_channel *channel; |
140 | struct ieee80211_rate *rate; | 148 | struct ieee80211_rate *rate; |
141 | /* use this rate (if set) for last fragment; rate can | 149 | /* use this rate (if set) for last fragment; rate can |
142 | * be set to lower rate for the first fragments, e.g., | 150 | * be set to lower rate for the first fragments, e.g., |
143 | * when using CTS protection with IEEE 802.11g. */ | 151 | * when using CTS protection with IEEE 802.11g. */ |
144 | struct ieee80211_rate *last_frag_rate; | 152 | struct ieee80211_rate *last_frag_rate; |
145 | int last_frag_hwrate; | ||
146 | 153 | ||
147 | /* Extra fragments (in addition to the first fragment | 154 | /* Extra fragments (in addition to the first fragment |
148 | * in skb) */ | 155 | * in skb) */ |
@@ -151,6 +158,7 @@ struct ieee80211_txrx_data { | |||
151 | } tx; | 158 | } tx; |
152 | struct { | 159 | struct { |
153 | struct ieee80211_rx_status *status; | 160 | struct ieee80211_rx_status *status; |
161 | struct ieee80211_rate *rate; | ||
154 | int sent_ps_buffered; | 162 | int sent_ps_buffered; |
155 | int queue; | 163 | int queue; |
156 | int load; | 164 | int load; |
@@ -165,6 +173,7 @@ struct ieee80211_txrx_data { | |||
165 | #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) | 173 | #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) |
166 | #define IEEE80211_TXPD_REQUEUE BIT(2) | 174 | #define IEEE80211_TXPD_REQUEUE BIT(2) |
167 | #define IEEE80211_TXPD_EAPOL_FRAME BIT(3) | 175 | #define IEEE80211_TXPD_EAPOL_FRAME BIT(3) |
176 | #define IEEE80211_TXPD_AMPDU BIT(4) | ||
168 | /* Stored in sk_buff->cb */ | 177 | /* Stored in sk_buff->cb */ |
169 | struct ieee80211_tx_packet_data { | 178 | struct ieee80211_tx_packet_data { |
170 | int ifindex; | 179 | int ifindex; |
@@ -178,18 +187,10 @@ struct ieee80211_tx_stored_packet { | |||
178 | struct sk_buff *skb; | 187 | struct sk_buff *skb; |
179 | int num_extra_frag; | 188 | int num_extra_frag; |
180 | struct sk_buff **extra_frag; | 189 | struct sk_buff **extra_frag; |
181 | int last_frag_rateidx; | ||
182 | int last_frag_hwrate; | ||
183 | struct ieee80211_rate *last_frag_rate; | 190 | struct ieee80211_rate *last_frag_rate; |
184 | unsigned int last_frag_rate_ctrl_probe; | 191 | unsigned int last_frag_rate_ctrl_probe; |
185 | }; | 192 | }; |
186 | 193 | ||
187 | typedef ieee80211_txrx_result (*ieee80211_tx_handler) | ||
188 | (struct ieee80211_txrx_data *tx); | ||
189 | |||
190 | typedef ieee80211_txrx_result (*ieee80211_rx_handler) | ||
191 | (struct ieee80211_txrx_data *rx); | ||
192 | |||
193 | struct beacon_data { | 194 | struct beacon_data { |
194 | u8 *head, *tail; | 195 | u8 *head, *tail; |
195 | int head_len, tail_len; | 196 | int head_len, tail_len; |
@@ -206,7 +207,7 @@ struct ieee80211_if_ap { | |||
206 | 207 | ||
207 | /* yes, this looks ugly, but guarantees that we can later use | 208 | /* yes, this looks ugly, but guarantees that we can later use |
208 | * bitmap_empty :) | 209 | * bitmap_empty :) |
209 | * NB: don't ever use set_bit, use bss_tim_set/bss_tim_clear! */ | 210 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
210 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 211 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; |
211 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 212 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
212 | struct sk_buff_head ps_bc_buf; | 213 | struct sk_buff_head ps_bc_buf; |
@@ -282,7 +283,7 @@ struct ieee80211_if_sta { | |||
282 | 283 | ||
283 | unsigned long ibss_join_req; | 284 | unsigned long ibss_join_req; |
284 | struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ | 285 | struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ |
285 | u32 supp_rates_bits; | 286 | u32 supp_rates_bits[IEEE80211_NUM_BANDS]; |
286 | 287 | ||
287 | int wmm_last_param_set; | 288 | int wmm_last_param_set; |
288 | }; | 289 | }; |
@@ -292,6 +293,7 @@ struct ieee80211_if_sta { | |||
292 | #define IEEE80211_SDATA_ALLMULTI BIT(0) | 293 | #define IEEE80211_SDATA_ALLMULTI BIT(0) |
293 | #define IEEE80211_SDATA_PROMISC BIT(1) | 294 | #define IEEE80211_SDATA_PROMISC BIT(1) |
294 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(2) | 295 | #define IEEE80211_SDATA_USERSPACE_MLME BIT(2) |
296 | #define IEEE80211_SDATA_OPERATING_GMODE BIT(3) | ||
295 | struct ieee80211_sub_if_data { | 297 | struct ieee80211_sub_if_data { |
296 | struct list_head list; | 298 | struct list_head list; |
297 | 299 | ||
@@ -306,11 +308,11 @@ struct ieee80211_sub_if_data { | |||
306 | unsigned int flags; | 308 | unsigned int flags; |
307 | 309 | ||
308 | int drop_unencrypted; | 310 | int drop_unencrypted; |
311 | |||
309 | /* | 312 | /* |
310 | * IEEE 802.1X Port access control in effect, | 313 | * basic rates of this AP or the AP we're associated to |
311 | * drop packets to/from unauthorized port | ||
312 | */ | 314 | */ |
313 | int ieee802_1x_pac; | 315 | u64 basic_rates; |
314 | 316 | ||
315 | u16 sequence; | 317 | u16 sequence; |
316 | 318 | ||
@@ -338,6 +340,7 @@ struct ieee80211_sub_if_data { | |||
338 | struct ieee80211_if_wds wds; | 340 | struct ieee80211_if_wds wds; |
339 | struct ieee80211_if_vlan vlan; | 341 | struct ieee80211_if_vlan vlan; |
340 | struct ieee80211_if_sta sta; | 342 | struct ieee80211_if_sta sta; |
343 | u32 mntr_flags; | ||
341 | } u; | 344 | } u; |
342 | int channel_use; | 345 | int channel_use; |
343 | int channel_use_raw; | 346 | int channel_use_raw; |
@@ -348,7 +351,6 @@ struct ieee80211_sub_if_data { | |||
348 | struct { | 351 | struct { |
349 | struct dentry *channel_use; | 352 | struct dentry *channel_use; |
350 | struct dentry *drop_unencrypted; | 353 | struct dentry *drop_unencrypted; |
351 | struct dentry *ieee802_1x_pac; | ||
352 | struct dentry *state; | 354 | struct dentry *state; |
353 | struct dentry *bssid; | 355 | struct dentry *bssid; |
354 | struct dentry *prev_bssid; | 356 | struct dentry *prev_bssid; |
@@ -367,7 +369,6 @@ struct ieee80211_sub_if_data { | |||
367 | struct { | 369 | struct { |
368 | struct dentry *channel_use; | 370 | struct dentry *channel_use; |
369 | struct dentry *drop_unencrypted; | 371 | struct dentry *drop_unencrypted; |
370 | struct dentry *ieee802_1x_pac; | ||
371 | struct dentry *num_sta_ps; | 372 | struct dentry *num_sta_ps; |
372 | struct dentry *dtim_count; | 373 | struct dentry *dtim_count; |
373 | struct dentry *num_beacons; | 374 | struct dentry *num_beacons; |
@@ -378,13 +379,11 @@ struct ieee80211_sub_if_data { | |||
378 | struct { | 379 | struct { |
379 | struct dentry *channel_use; | 380 | struct dentry *channel_use; |
380 | struct dentry *drop_unencrypted; | 381 | struct dentry *drop_unencrypted; |
381 | struct dentry *ieee802_1x_pac; | ||
382 | struct dentry *peer; | 382 | struct dentry *peer; |
383 | } wds; | 383 | } wds; |
384 | struct { | 384 | struct { |
385 | struct dentry *channel_use; | 385 | struct dentry *channel_use; |
386 | struct dentry *drop_unencrypted; | 386 | struct dentry *drop_unencrypted; |
387 | struct dentry *ieee802_1x_pac; | ||
388 | } vlan; | 387 | } vlan; |
389 | struct { | 388 | struct { |
390 | struct dentry *mode; | 389 | struct dentry *mode; |
@@ -407,6 +406,8 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | |||
407 | enum { | 406 | enum { |
408 | IEEE80211_RX_MSG = 1, | 407 | IEEE80211_RX_MSG = 1, |
409 | IEEE80211_TX_STATUS_MSG = 2, | 408 | IEEE80211_TX_STATUS_MSG = 2, |
409 | IEEE80211_DELBA_MSG = 3, | ||
410 | IEEE80211_ADDBA_MSG = 4, | ||
410 | }; | 411 | }; |
411 | 412 | ||
412 | struct ieee80211_local { | 413 | struct ieee80211_local { |
@@ -417,12 +418,11 @@ struct ieee80211_local { | |||
417 | 418 | ||
418 | const struct ieee80211_ops *ops; | 419 | const struct ieee80211_ops *ops; |
419 | 420 | ||
420 | /* List of registered struct ieee80211_hw_mode */ | ||
421 | struct list_head modes_list; | ||
422 | |||
423 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ | 421 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ |
424 | int open_count; | 422 | int open_count; |
425 | int monitors; | 423 | int monitors, cooked_mntrs; |
424 | /* number of interfaces with corresponding FIF_ flags */ | ||
425 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; | ||
426 | unsigned int filter_flags; /* FIF_* */ | 426 | unsigned int filter_flags; /* FIF_* */ |
427 | struct iw_statistics wstats; | 427 | struct iw_statistics wstats; |
428 | u8 wstats_flags; | 428 | u8 wstats_flags; |
@@ -450,8 +450,8 @@ struct ieee80211_local { | |||
450 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 450 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
451 | struct timer_list sta_cleanup; | 451 | struct timer_list sta_cleanup; |
452 | 452 | ||
453 | unsigned long state[NUM_TX_DATA_QUEUES]; | 453 | unsigned long state[NUM_TX_DATA_QUEUES_AMPDU]; |
454 | struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES]; | 454 | struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU]; |
455 | struct tasklet_struct tx_pending_tasklet; | 455 | struct tasklet_struct tx_pending_tasklet; |
456 | 456 | ||
457 | /* number of interfaces with corresponding IFF_ flags */ | 457 | /* number of interfaces with corresponding IFF_ flags */ |
@@ -459,11 +459,6 @@ struct ieee80211_local { | |||
459 | 459 | ||
460 | struct rate_control_ref *rate_ctrl; | 460 | struct rate_control_ref *rate_ctrl; |
461 | 461 | ||
462 | /* Supported and basic rate filters for different modes. These are | ||
463 | * pointers to -1 terminated lists and rates in 100 kbps units. */ | ||
464 | int *supp_rates[NUM_IEEE80211_MODES]; | ||
465 | int *basic_rates[NUM_IEEE80211_MODES]; | ||
466 | |||
467 | int rts_threshold; | 462 | int rts_threshold; |
468 | int fragmentation_threshold; | 463 | int fragmentation_threshold; |
469 | int short_retry_limit; /* dot11ShortRetryLimit */ | 464 | int short_retry_limit; /* dot11ShortRetryLimit */ |
@@ -477,21 +472,18 @@ struct ieee80211_local { | |||
477 | * deliver multicast frames both back to wireless | 472 | * deliver multicast frames both back to wireless |
478 | * media and to the local net stack */ | 473 | * media and to the local net stack */ |
479 | 474 | ||
480 | ieee80211_rx_handler *rx_pre_handlers; | ||
481 | ieee80211_rx_handler *rx_handlers; | ||
482 | ieee80211_tx_handler *tx_handlers; | ||
483 | |||
484 | struct list_head interfaces; | 475 | struct list_head interfaces; |
485 | 476 | ||
486 | bool sta_sw_scanning; | 477 | bool sta_sw_scanning; |
487 | bool sta_hw_scanning; | 478 | bool sta_hw_scanning; |
488 | int scan_channel_idx; | 479 | int scan_channel_idx; |
480 | enum ieee80211_band scan_band; | ||
481 | |||
489 | enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; | 482 | enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; |
490 | unsigned long last_scan_completed; | 483 | unsigned long last_scan_completed; |
491 | struct delayed_work scan_work; | 484 | struct delayed_work scan_work; |
492 | struct net_device *scan_dev; | 485 | struct net_device *scan_dev; |
493 | struct ieee80211_channel *oper_channel, *scan_channel; | 486 | struct ieee80211_channel *oper_channel, *scan_channel; |
494 | struct ieee80211_hw_mode *oper_hw_mode, *scan_hw_mode; | ||
495 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; | 487 | u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; |
496 | size_t scan_ssid_len; | 488 | size_t scan_ssid_len; |
497 | struct list_head sta_bss_list; | 489 | struct list_head sta_bss_list; |
@@ -560,14 +552,8 @@ struct ieee80211_local { | |||
560 | int wifi_wme_noack_test; | 552 | int wifi_wme_noack_test; |
561 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 553 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
562 | 554 | ||
563 | unsigned int enabled_modes; /* bitfield of allowed modes; | ||
564 | * (1 << MODE_*) */ | ||
565 | unsigned int hw_modes; /* bitfield of supported hardware modes; | ||
566 | * (1 << MODE_*) */ | ||
567 | |||
568 | #ifdef CONFIG_MAC80211_DEBUGFS | 555 | #ifdef CONFIG_MAC80211_DEBUGFS |
569 | struct local_debugfsdentries { | 556 | struct local_debugfsdentries { |
570 | struct dentry *channel; | ||
571 | struct dentry *frequency; | 557 | struct dentry *frequency; |
572 | struct dentry *antenna_sel_tx; | 558 | struct dentry *antenna_sel_tx; |
573 | struct dentry *antenna_sel_rx; | 559 | struct dentry *antenna_sel_rx; |
@@ -577,9 +563,7 @@ struct ieee80211_local { | |||
577 | struct dentry *short_retry_limit; | 563 | struct dentry *short_retry_limit; |
578 | struct dentry *long_retry_limit; | 564 | struct dentry *long_retry_limit; |
579 | struct dentry *total_ps_buffered; | 565 | struct dentry *total_ps_buffered; |
580 | struct dentry *mode; | ||
581 | struct dentry *wep_iv; | 566 | struct dentry *wep_iv; |
582 | struct dentry *modes; | ||
583 | struct dentry *statistics; | 567 | struct dentry *statistics; |
584 | struct local_debugfsdentries_statsdentries { | 568 | struct local_debugfsdentries_statsdentries { |
585 | struct dentry *transmitted_fragment_count; | 569 | struct dentry *transmitted_fragment_count; |
@@ -627,6 +611,12 @@ struct ieee80211_local { | |||
627 | #endif | 611 | #endif |
628 | }; | 612 | }; |
629 | 613 | ||
614 | /* this struct represents 802.11n's RA/TID combination */ | ||
615 | struct ieee80211_ra_tid { | ||
616 | u8 ra[ETH_ALEN]; | ||
617 | u16 tid; | ||
618 | }; | ||
619 | |||
630 | static inline struct ieee80211_local *hw_to_local( | 620 | static inline struct ieee80211_local *hw_to_local( |
631 | struct ieee80211_hw *hw) | 621 | struct ieee80211_hw *hw) |
632 | { | 622 | { |
@@ -650,57 +640,6 @@ struct sta_attribute { | |||
650 | ssize_t (*store)(struct sta_info *, const char *buf, size_t count); | 640 | ssize_t (*store)(struct sta_info *, const char *buf, size_t count); |
651 | }; | 641 | }; |
652 | 642 | ||
653 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | ||
654 | { | ||
655 | /* | ||
656 | * This format has been mandated by the IEEE specifications, | ||
657 | * so this line may not be changed to use the __set_bit() format. | ||
658 | */ | ||
659 | bss->tim[aid / 8] |= (1 << (aid % 8)); | ||
660 | } | ||
661 | |||
662 | static inline void bss_tim_set(struct ieee80211_local *local, | ||
663 | struct ieee80211_if_ap *bss, u16 aid) | ||
664 | { | ||
665 | read_lock_bh(&local->sta_lock); | ||
666 | __bss_tim_set(bss, aid); | ||
667 | read_unlock_bh(&local->sta_lock); | ||
668 | } | ||
669 | |||
670 | static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | ||
671 | { | ||
672 | /* | ||
673 | * This format has been mandated by the IEEE specifications, | ||
674 | * so this line may not be changed to use the __clear_bit() format. | ||
675 | */ | ||
676 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | ||
677 | } | ||
678 | |||
679 | static inline void bss_tim_clear(struct ieee80211_local *local, | ||
680 | struct ieee80211_if_ap *bss, u16 aid) | ||
681 | { | ||
682 | read_lock_bh(&local->sta_lock); | ||
683 | __bss_tim_clear(bss, aid); | ||
684 | read_unlock_bh(&local->sta_lock); | ||
685 | } | ||
686 | |||
687 | /** | ||
688 | * ieee80211_is_erp_rate - Check if a rate is an ERP rate | ||
689 | * @phymode: The PHY-mode for this rate (MODE_IEEE80211...) | ||
690 | * @rate: Transmission rate to check, in 100 kbps | ||
691 | * | ||
692 | * Check if a given rate is an Extended Rate PHY (ERP) rate. | ||
693 | */ | ||
694 | static inline int ieee80211_is_erp_rate(int phymode, int rate) | ||
695 | { | ||
696 | if (phymode == MODE_IEEE80211G) { | ||
697 | if (rate != 10 && rate != 20 && | ||
698 | rate != 55 && rate != 110) | ||
699 | return 1; | ||
700 | } | ||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 643 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
705 | { | 644 | { |
706 | return compare_ether_addr(raddr, addr) == 0 || | 645 | return compare_ether_addr(raddr, addr) == 0 || |
@@ -712,13 +651,9 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
712 | int ieee80211_hw_config(struct ieee80211_local *local); | 651 | int ieee80211_hw_config(struct ieee80211_local *local); |
713 | int ieee80211_if_config(struct net_device *dev); | 652 | int ieee80211_if_config(struct net_device *dev); |
714 | int ieee80211_if_config_beacon(struct net_device *dev); | 653 | int ieee80211_if_config_beacon(struct net_device *dev); |
715 | void ieee80211_prepare_rates(struct ieee80211_local *local, | ||
716 | struct ieee80211_hw_mode *mode); | ||
717 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); | 654 | void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); |
718 | int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); | 655 | int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); |
719 | void ieee80211_if_setup(struct net_device *dev); | 656 | void ieee80211_if_setup(struct net_device *dev); |
720 | struct ieee80211_rate *ieee80211_get_rate(struct ieee80211_local *local, | ||
721 | int phymode, int hwrate); | ||
722 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, | 657 | int ieee80211_hw_config_ht(struct ieee80211_local *local, int enable_ht, |
723 | struct ieee80211_ht_info *req_ht_cap, | 658 | struct ieee80211_ht_info *req_ht_cap, |
724 | struct ieee80211_ht_bss_info *req_bss_cap); | 659 | struct ieee80211_ht_bss_info *req_bss_cap); |
@@ -749,7 +684,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def; | |||
749 | /* ieee80211_ioctl.c */ | 684 | /* ieee80211_ioctl.c */ |
750 | int ieee80211_set_compression(struct ieee80211_local *local, | 685 | int ieee80211_set_compression(struct ieee80211_local *local, |
751 | struct net_device *dev, struct sta_info *sta); | 686 | struct net_device *dev, struct sta_info *sta); |
752 | int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq); | 687 | int ieee80211_set_freq(struct ieee80211_local *local, int freq); |
753 | /* ieee80211_sta.c */ | 688 | /* ieee80211_sta.c */ |
754 | void ieee80211_sta_timer(unsigned long data); | 689 | void ieee80211_sta_timer(unsigned long data); |
755 | void ieee80211_sta_work(struct work_struct *work); | 690 | void ieee80211_sta_work(struct work_struct *work); |
@@ -763,9 +698,9 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); | |||
763 | void ieee80211_sta_req_auth(struct net_device *dev, | 698 | void ieee80211_sta_req_auth(struct net_device *dev, |
764 | struct ieee80211_if_sta *ifsta); | 699 | struct ieee80211_if_sta *ifsta); |
765 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); | 700 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); |
766 | ieee80211_txrx_result ieee80211_sta_rx_scan(struct net_device *dev, | 701 | ieee80211_rx_result ieee80211_sta_rx_scan( |
767 | struct sk_buff *skb, | 702 | struct net_device *dev, struct sk_buff *skb, |
768 | struct ieee80211_rx_status *rx_status); | 703 | struct ieee80211_rx_status *rx_status); |
769 | void ieee80211_rx_bss_list_init(struct net_device *dev); | 704 | void ieee80211_rx_bss_list_init(struct net_device *dev); |
770 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); | 705 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); |
771 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); | 706 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); |
@@ -782,9 +717,15 @@ int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | |||
782 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 717 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( |
783 | struct ieee80211_ht_addt_info *ht_add_info_ie, | 718 | struct ieee80211_ht_addt_info *ht_add_info_ie, |
784 | struct ieee80211_ht_bss_info *bss_info); | 719 | struct ieee80211_ht_bss_info *bss_info); |
720 | void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, | ||
721 | u16 tid, u8 dialog_token, u16 start_seq_num, | ||
722 | u16 agg_size, u16 timeout); | ||
723 | void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | ||
724 | u16 initiator, u16 reason_code); | ||
785 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, | 725 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, |
786 | u16 tid, u16 initiator, u16 reason); | 726 | u16 tid, u16 initiator, u16 reason); |
787 | void sta_rx_agg_session_timer_expired(unsigned long data); | 727 | void sta_rx_agg_session_timer_expired(unsigned long data); |
728 | void sta_addba_resp_timer_expired(unsigned long data); | ||
788 | /* ieee80211_iface.c */ | 729 | /* ieee80211_iface.c */ |
789 | int ieee80211_if_add(struct net_device *dev, const char *name, | 730 | int ieee80211_if_add(struct net_device *dev, const char *name, |
790 | struct net_device **new_dev, int type); | 731 | struct net_device **new_dev, int type); |
@@ -796,16 +737,7 @@ int ieee80211_if_remove(struct net_device *dev, const char *name, int id); | |||
796 | void ieee80211_if_free(struct net_device *dev); | 737 | void ieee80211_if_free(struct net_device *dev); |
797 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); | 738 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); |
798 | 739 | ||
799 | /* regdomain.c */ | ||
800 | void ieee80211_regdomain_init(void); | ||
801 | void ieee80211_set_default_regdomain(struct ieee80211_hw_mode *mode); | ||
802 | |||
803 | /* rx handling */ | ||
804 | extern ieee80211_rx_handler ieee80211_rx_pre_handlers[]; | ||
805 | extern ieee80211_rx_handler ieee80211_rx_handlers[]; | ||
806 | |||
807 | /* tx handling */ | 740 | /* tx handling */ |
808 | extern ieee80211_tx_handler ieee80211_tx_handlers[]; | ||
809 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); | 741 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); |
810 | void ieee80211_tx_pending(unsigned long data); | 742 | void ieee80211_tx_pending(unsigned long data); |
811 | int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev); | 743 | int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev); |
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c index 92f1eb2da311..0d6824bca92b 100644 --- a/net/mac80211/ieee80211_iface.c +++ b/net/mac80211/ieee80211_iface.c | |||
@@ -118,6 +118,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
118 | sdata->bss = NULL; | 118 | sdata->bss = NULL; |
119 | sdata->vif.type = type; | 119 | sdata->vif.type = type; |
120 | 120 | ||
121 | sdata->basic_rates = 0; | ||
122 | |||
121 | switch (type) { | 123 | switch (type) { |
122 | case IEEE80211_IF_TYPE_WDS: | 124 | case IEEE80211_IF_TYPE_WDS: |
123 | /* nothing special */ | 125 | /* nothing special */ |
@@ -158,6 +160,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
158 | case IEEE80211_IF_TYPE_MNTR: | 160 | case IEEE80211_IF_TYPE_MNTR: |
159 | dev->type = ARPHRD_IEEE80211_RADIOTAP; | 161 | dev->type = ARPHRD_IEEE80211_RADIOTAP; |
160 | dev->hard_start_xmit = ieee80211_monitor_start_xmit; | 162 | dev->hard_start_xmit = ieee80211_monitor_start_xmit; |
163 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | | ||
164 | MONITOR_FLAG_OTHER_BSS; | ||
161 | break; | 165 | break; |
162 | default: | 166 | default: |
163 | printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", | 167 | printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", |
@@ -189,6 +193,7 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
189 | /* Remove all virtual interfaces that use this BSS | 193 | /* Remove all virtual interfaces that use this BSS |
190 | * as their sdata->bss */ | 194 | * as their sdata->bss */ |
191 | struct ieee80211_sub_if_data *tsdata, *n; | 195 | struct ieee80211_sub_if_data *tsdata, *n; |
196 | struct beacon_data *beacon; | ||
192 | 197 | ||
193 | list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { | 198 | list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { |
194 | if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { | 199 | if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { |
@@ -206,7 +211,10 @@ void ieee80211_if_reinit(struct net_device *dev) | |||
206 | } | 211 | } |
207 | } | 212 | } |
208 | 213 | ||
209 | kfree(sdata->u.ap.beacon); | 214 | beacon = sdata->u.ap.beacon; |
215 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
216 | synchronize_rcu(); | ||
217 | kfree(beacon); | ||
210 | 218 | ||
211 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { | 219 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { |
212 | local->total_ps_buffered--; | 220 | local->total_ps_buffered--; |
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c index 5024d3733834..7551db3f3abc 100644 --- a/net/mac80211/ieee80211_ioctl.c +++ b/net/mac80211/ieee80211_ioctl.c | |||
@@ -33,8 +33,8 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
33 | size_t key_len) | 33 | size_t key_len) |
34 | { | 34 | { |
35 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 35 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
36 | int ret = 0; | 36 | int ret; |
37 | struct sta_info *sta; | 37 | struct sta_info *sta = NULL; |
38 | struct ieee80211_key *key; | 38 | struct ieee80211_key *key; |
39 | struct ieee80211_sub_if_data *sdata; | 39 | struct ieee80211_sub_if_data *sdata; |
40 | 40 | ||
@@ -46,58 +46,64 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
46 | return -EINVAL; | 46 | return -EINVAL; |
47 | } | 47 | } |
48 | 48 | ||
49 | if (is_broadcast_ether_addr(sta_addr)) { | 49 | if (remove) { |
50 | sta = NULL; | 50 | if (is_broadcast_ether_addr(sta_addr)) { |
51 | key = sdata->keys[idx]; | 51 | key = sdata->keys[idx]; |
52 | } else { | 52 | } else { |
53 | set_tx_key = 0; | 53 | sta = sta_info_get(local, sta_addr); |
54 | /* | 54 | if (!sta) { |
55 | * According to the standard, the key index of a pairwise | 55 | ret = -ENOENT; |
56 | * key must be zero. However, some AP are broken when it | 56 | key = NULL; |
57 | * comes to WEP key indices, so we work around this. | 57 | goto err_out; |
58 | */ | 58 | } |
59 | if (idx != 0 && alg != ALG_WEP) { | 59 | |
60 | printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for " | 60 | key = sta->key; |
61 | "individual key\n", dev->name); | ||
62 | return -EINVAL; | ||
63 | } | 61 | } |
64 | 62 | ||
65 | sta = sta_info_get(local, sta_addr); | 63 | if (!key) |
66 | if (!sta) { | 64 | ret = -ENOENT; |
67 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 65 | else |
68 | DECLARE_MAC_BUF(mac); | 66 | ret = 0; |
69 | printk(KERN_DEBUG "%s: set_encrypt - unknown addr " | 67 | } else { |
70 | "%s\n", | 68 | key = ieee80211_key_alloc(alg, idx, key_len, _key); |
71 | dev->name, print_mac(mac, sta_addr)); | 69 | if (!key) |
72 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 70 | return -ENOMEM; |
73 | 71 | ||
74 | return -ENOENT; | 72 | if (!is_broadcast_ether_addr(sta_addr)) { |
73 | set_tx_key = 0; | ||
74 | /* | ||
75 | * According to the standard, the key index of a | ||
76 | * pairwise key must be zero. However, some AP are | ||
77 | * broken when it comes to WEP key indices, so we | ||
78 | * work around this. | ||
79 | */ | ||
80 | if (idx != 0 && alg != ALG_WEP) { | ||
81 | ret = -EINVAL; | ||
82 | goto err_out; | ||
83 | } | ||
84 | |||
85 | sta = sta_info_get(local, sta_addr); | ||
86 | if (!sta) { | ||
87 | ret = -ENOENT; | ||
88 | goto err_out; | ||
89 | } | ||
75 | } | 90 | } |
76 | 91 | ||
77 | key = sta->key; | 92 | ieee80211_key_link(key, sdata, sta); |
78 | } | ||
79 | 93 | ||
80 | if (remove) { | 94 | if (set_tx_key || (!sta && !sdata->default_key && key)) |
81 | ieee80211_key_free(key); | 95 | ieee80211_set_default_key(sdata, idx); |
96 | |||
97 | /* don't free key later */ | ||
82 | key = NULL; | 98 | key = NULL; |
83 | } else { | ||
84 | /* | ||
85 | * Automatically frees any old key if present. | ||
86 | */ | ||
87 | key = ieee80211_key_alloc(sdata, sta, alg, idx, key_len, _key); | ||
88 | if (!key) { | ||
89 | ret = -ENOMEM; | ||
90 | goto err_out; | ||
91 | } | ||
92 | } | ||
93 | 99 | ||
94 | if (set_tx_key || (!sta && !sdata->default_key && key)) | 100 | ret = 0; |
95 | ieee80211_set_default_key(sdata, idx); | 101 | } |
96 | 102 | ||
97 | ret = 0; | ||
98 | err_out: | 103 | err_out: |
99 | if (sta) | 104 | if (sta) |
100 | sta_info_put(sta); | 105 | sta_info_put(sta); |
106 | ieee80211_key_free(key); | ||
101 | return ret; | 107 | return ret; |
102 | } | 108 | } |
103 | 109 | ||
@@ -129,22 +135,7 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
129 | struct iw_request_info *info, | 135 | struct iw_request_info *info, |
130 | char *name, char *extra) | 136 | char *name, char *extra) |
131 | { | 137 | { |
132 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 138 | strcpy(name, "IEEE 802.11"); |
133 | |||
134 | switch (local->hw.conf.phymode) { | ||
135 | case MODE_IEEE80211A: | ||
136 | strcpy(name, "IEEE 802.11a"); | ||
137 | break; | ||
138 | case MODE_IEEE80211B: | ||
139 | strcpy(name, "IEEE 802.11b"); | ||
140 | break; | ||
141 | case MODE_IEEE80211G: | ||
142 | strcpy(name, "IEEE 802.11g"); | ||
143 | break; | ||
144 | default: | ||
145 | strcpy(name, "IEEE 802.11"); | ||
146 | break; | ||
147 | } | ||
148 | 139 | ||
149 | return 0; | 140 | return 0; |
150 | } | 141 | } |
@@ -156,7 +147,7 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
156 | { | 147 | { |
157 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 148 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
158 | struct iw_range *range = (struct iw_range *) extra; | 149 | struct iw_range *range = (struct iw_range *) extra; |
159 | struct ieee80211_hw_mode *mode = NULL; | 150 | enum ieee80211_band band; |
160 | int c = 0; | 151 | int c = 0; |
161 | 152 | ||
162 | data->length = sizeof(struct iw_range); | 153 | data->length = sizeof(struct iw_range); |
@@ -191,24 +182,27 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
191 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 182 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
192 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; | 183 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; |
193 | 184 | ||
194 | list_for_each_entry(mode, &local->modes_list, list) { | ||
195 | int i = 0; | ||
196 | 185 | ||
197 | if (!(local->enabled_modes & (1 << mode->mode)) || | 186 | for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { |
198 | (local->hw_modes & local->enabled_modes & | 187 | int i; |
199 | (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) | 188 | struct ieee80211_supported_band *sband; |
189 | |||
190 | sband = local->hw.wiphy->bands[band]; | ||
191 | |||
192 | if (!sband) | ||
200 | continue; | 193 | continue; |
201 | 194 | ||
202 | while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) { | 195 | for (i = 0; i < sband->n_channels && c < IW_MAX_FREQUENCIES; i++) { |
203 | struct ieee80211_channel *chan = &mode->channels[i]; | 196 | struct ieee80211_channel *chan = &sband->channels[i]; |
204 | 197 | ||
205 | if (chan->flag & IEEE80211_CHAN_W_SCAN) { | 198 | if (!(chan->flags & IEEE80211_CHAN_DISABLED)) { |
206 | range->freq[c].i = chan->chan; | 199 | range->freq[c].i = |
207 | range->freq[c].m = chan->freq * 100000; | 200 | ieee80211_frequency_to_channel( |
208 | range->freq[c].e = 1; | 201 | chan->center_freq); |
202 | range->freq[c].m = chan->center_freq; | ||
203 | range->freq[c].e = 6; | ||
209 | c++; | 204 | c++; |
210 | } | 205 | } |
211 | i++; | ||
212 | } | 206 | } |
213 | } | 207 | } |
214 | range->num_channels = c; | 208 | range->num_channels = c; |
@@ -294,22 +288,29 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev, | |||
294 | return 0; | 288 | return 0; |
295 | } | 289 | } |
296 | 290 | ||
297 | int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq) | 291 | int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz) |
298 | { | 292 | { |
299 | struct ieee80211_hw_mode *mode; | 293 | int set = 0; |
300 | int c, set = 0; | ||
301 | int ret = -EINVAL; | 294 | int ret = -EINVAL; |
295 | enum ieee80211_band band; | ||
296 | struct ieee80211_supported_band *sband; | ||
297 | int i; | ||
298 | |||
299 | for (band = 0; band < IEEE80211_NUM_BANDS; band ++) { | ||
300 | sband = local->hw.wiphy->bands[band]; | ||
302 | 301 | ||
303 | list_for_each_entry(mode, &local->modes_list, list) { | 302 | if (!sband) |
304 | if (!(local->enabled_modes & (1 << mode->mode))) | ||
305 | continue; | 303 | continue; |
306 | for (c = 0; c < mode->num_channels; c++) { | 304 | |
307 | struct ieee80211_channel *chan = &mode->channels[c]; | 305 | for (i = 0; i < sband->n_channels; i++) { |
308 | if (chan->flag & IEEE80211_CHAN_W_SCAN && | 306 | struct ieee80211_channel *chan = &sband->channels[i]; |
309 | ((chan->chan == channel) || (chan->freq == freq))) { | 307 | |
310 | local->oper_channel = chan; | 308 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
311 | local->oper_hw_mode = mode; | 309 | continue; |
310 | |||
311 | if (chan->center_freq == freqMHz) { | ||
312 | set = 1; | 312 | set = 1; |
313 | local->oper_channel = chan; | ||
313 | break; | 314 | break; |
314 | } | 315 | } |
315 | } | 316 | } |
@@ -347,13 +348,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, | |||
347 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 348 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
348 | return 0; | 349 | return 0; |
349 | } else | 350 | } else |
350 | return ieee80211_set_channel(local, freq->m, -1); | 351 | return ieee80211_set_freq(local, |
352 | ieee80211_channel_to_frequency(freq->m)); | ||
351 | } else { | 353 | } else { |
352 | int i, div = 1000000; | 354 | int i, div = 1000000; |
353 | for (i = 0; i < freq->e; i++) | 355 | for (i = 0; i < freq->e; i++) |
354 | div /= 10; | 356 | div /= 10; |
355 | if (div > 0) | 357 | if (div > 0) |
356 | return ieee80211_set_channel(local, -1, freq->m / div); | 358 | return ieee80211_set_freq(local, freq->m / div); |
357 | else | 359 | else |
358 | return -EINVAL; | 360 | return -EINVAL; |
359 | } | 361 | } |
@@ -366,10 +368,7 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev, | |||
366 | { | 368 | { |
367 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 369 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
368 | 370 | ||
369 | /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level | 371 | freq->m = local->hw.conf.channel->center_freq; |
370 | * driver for the current channel with firmware-based management */ | ||
371 | |||
372 | freq->m = local->hw.conf.freq; | ||
373 | freq->e = 6; | 372 | freq->e = 6; |
374 | 373 | ||
375 | return 0; | 374 | return 0; |
@@ -566,15 +565,17 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
566 | struct iw_param *rate, char *extra) | 565 | struct iw_param *rate, char *extra) |
567 | { | 566 | { |
568 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 567 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
569 | struct ieee80211_hw_mode *mode; | 568 | int i, err = -EINVAL; |
570 | int i; | ||
571 | u32 target_rate = rate->value / 100000; | 569 | u32 target_rate = rate->value / 100000; |
572 | struct ieee80211_sub_if_data *sdata; | 570 | struct ieee80211_sub_if_data *sdata; |
571 | struct ieee80211_supported_band *sband; | ||
573 | 572 | ||
574 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 573 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
575 | if (!sdata->bss) | 574 | if (!sdata->bss) |
576 | return -ENODEV; | 575 | return -ENODEV; |
577 | mode = local->oper_hw_mode; | 576 | |
577 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
578 | |||
578 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates | 579 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates |
579 | * target_rate = X, rate->fixed = 1 means only rate X | 580 | * target_rate = X, rate->fixed = 1 means only rate X |
580 | * target_rate = X, rate->fixed = 0 means all rates <= X */ | 581 | * target_rate = X, rate->fixed = 0 means all rates <= X */ |
@@ -582,18 +583,20 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
582 | sdata->bss->force_unicast_rateidx = -1; | 583 | sdata->bss->force_unicast_rateidx = -1; |
583 | if (rate->value < 0) | 584 | if (rate->value < 0) |
584 | return 0; | 585 | return 0; |
585 | for (i=0; i < mode->num_rates; i++) { | 586 | |
586 | struct ieee80211_rate *rates = &mode->rates[i]; | 587 | for (i=0; i< sband->n_bitrates; i++) { |
587 | int this_rate = rates->rate; | 588 | struct ieee80211_rate *brate = &sband->bitrates[i]; |
589 | int this_rate = brate->bitrate; | ||
588 | 590 | ||
589 | if (target_rate == this_rate) { | 591 | if (target_rate == this_rate) { |
590 | sdata->bss->max_ratectrl_rateidx = i; | 592 | sdata->bss->max_ratectrl_rateidx = i; |
591 | if (rate->fixed) | 593 | if (rate->fixed) |
592 | sdata->bss->force_unicast_rateidx = i; | 594 | sdata->bss->force_unicast_rateidx = i; |
593 | return 0; | 595 | err = 0; |
596 | break; | ||
594 | } | 597 | } |
595 | } | 598 | } |
596 | return -EINVAL; | 599 | return err; |
597 | } | 600 | } |
598 | 601 | ||
599 | static int ieee80211_ioctl_giwrate(struct net_device *dev, | 602 | static int ieee80211_ioctl_giwrate(struct net_device *dev, |
@@ -603,18 +606,24 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, | |||
603 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 606 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
604 | struct sta_info *sta; | 607 | struct sta_info *sta; |
605 | struct ieee80211_sub_if_data *sdata; | 608 | struct ieee80211_sub_if_data *sdata; |
609 | struct ieee80211_supported_band *sband; | ||
606 | 610 | ||
607 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 611 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
612 | |||
608 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) | 613 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) |
609 | sta = sta_info_get(local, sdata->u.sta.bssid); | 614 | sta = sta_info_get(local, sdata->u.sta.bssid); |
610 | else | 615 | else |
611 | return -EOPNOTSUPP; | 616 | return -EOPNOTSUPP; |
612 | if (!sta) | 617 | if (!sta) |
613 | return -ENODEV; | 618 | return -ENODEV; |
614 | if (sta->txrate < local->oper_hw_mode->num_rates) | 619 | |
615 | rate->value = local->oper_hw_mode->rates[sta->txrate].rate * 100000; | 620 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
621 | |||
622 | if (sta->txrate_idx < sband->n_bitrates) | ||
623 | rate->value = sband->bitrates[sta->txrate_idx].bitrate; | ||
616 | else | 624 | else |
617 | rate->value = 0; | 625 | rate->value = 0; |
626 | rate->value *= 100000; | ||
618 | sta_info_put(sta); | 627 | sta_info_put(sta); |
619 | return 0; | 628 | return 0; |
620 | } | 629 | } |
@@ -625,7 +634,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
625 | { | 634 | { |
626 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 635 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
627 | bool need_reconfig = 0; | 636 | bool need_reconfig = 0; |
628 | u8 new_power_level; | 637 | int new_power_level; |
629 | 638 | ||
630 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) | 639 | if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) |
631 | return -EINVAL; | 640 | return -EINVAL; |
@@ -635,13 +644,15 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
635 | if (data->txpower.fixed) { | 644 | if (data->txpower.fixed) { |
636 | new_power_level = data->txpower.value; | 645 | new_power_level = data->txpower.value; |
637 | } else { | 646 | } else { |
638 | /* Automatic power level. Get the px power from the current | 647 | /* |
639 | * channel. */ | 648 | * Automatic power level. Use maximum power for the current |
640 | struct ieee80211_channel* chan = local->oper_channel; | 649 | * channel. Should be part of rate control. |
650 | */ | ||
651 | struct ieee80211_channel* chan = local->hw.conf.channel; | ||
641 | if (!chan) | 652 | if (!chan) |
642 | return -EINVAL; | 653 | return -EINVAL; |
643 | 654 | ||
644 | new_power_level = chan->power_level; | 655 | new_power_level = chan->max_power; |
645 | } | 656 | } |
646 | 657 | ||
647 | if (local->hw.conf.power_level != new_power_level) { | 658 | if (local->hw.conf.power_level != new_power_level) { |
diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h index fc770e98d47b..d670e6dbfa39 100644 --- a/net/mac80211/ieee80211_key.h +++ b/net/mac80211/ieee80211_key.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/crypto.h> | 15 | #include <linux/crypto.h> |
16 | #include <linux/rcupdate.h> | ||
16 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
17 | 18 | ||
18 | /* ALG_TKIP | 19 | /* ALG_TKIP |
@@ -45,7 +46,19 @@ struct ieee80211_local; | |||
45 | struct ieee80211_sub_if_data; | 46 | struct ieee80211_sub_if_data; |
46 | struct sta_info; | 47 | struct sta_info; |
47 | 48 | ||
48 | #define KEY_FLAG_UPLOADED_TO_HARDWARE (1<<0) | 49 | /** |
50 | * enum ieee80211_internal_key_flags - internal key flags | ||
51 | * | ||
52 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present | ||
53 | * in the hardware for TX crypto hardware acceleration. | ||
54 | * @KEY_FLAG_REMOVE_FROM_HARDWARE: Indicates to the key code that this | ||
55 | * key is present in the hardware (but it cannot be used for | ||
56 | * hardware acceleration any more!) | ||
57 | */ | ||
58 | enum ieee80211_internal_key_flags { | ||
59 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), | ||
60 | KEY_FLAG_REMOVE_FROM_HARDWARE = BIT(1), | ||
61 | }; | ||
49 | 62 | ||
50 | struct ieee80211_key { | 63 | struct ieee80211_key { |
51 | struct ieee80211_local *local; | 64 | struct ieee80211_local *local; |
@@ -112,12 +125,17 @@ struct ieee80211_key { | |||
112 | struct ieee80211_key_conf conf; | 125 | struct ieee80211_key_conf conf; |
113 | }; | 126 | }; |
114 | 127 | ||
115 | struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | 128 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, |
116 | struct sta_info *sta, | ||
117 | enum ieee80211_key_alg alg, | ||
118 | int idx, | 129 | int idx, |
119 | size_t key_len, | 130 | size_t key_len, |
120 | const u8 *key_data); | 131 | const u8 *key_data); |
132 | /* | ||
133 | * Insert a key into data structures (sdata, sta if necessary) | ||
134 | * to make it used, free old key. | ||
135 | */ | ||
136 | void ieee80211_key_link(struct ieee80211_key *key, | ||
137 | struct ieee80211_sub_if_data *sdata, | ||
138 | struct sta_info *sta); | ||
121 | void ieee80211_key_free(struct ieee80211_key *key); | 139 | void ieee80211_key_free(struct ieee80211_key *key); |
122 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); |
123 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); | 141 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/ieee80211_rate.c b/net/mac80211/ieee80211_rate.c index b957e67c5fba..ebe29b716b27 100644 --- a/net/mac80211/ieee80211_rate.c +++ b/net/mac80211/ieee80211_rate.c | |||
@@ -163,7 +163,8 @@ static void rate_control_release(struct kref *kref) | |||
163 | } | 163 | } |
164 | 164 | ||
165 | void rate_control_get_rate(struct net_device *dev, | 165 | void rate_control_get_rate(struct net_device *dev, |
166 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 166 | struct ieee80211_supported_band *sband, |
167 | struct sk_buff *skb, | ||
167 | struct rate_selection *sel) | 168 | struct rate_selection *sel) |
168 | { | 169 | { |
169 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 170 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -174,17 +175,17 @@ void rate_control_get_rate(struct net_device *dev, | |||
174 | 175 | ||
175 | memset(sel, 0, sizeof(struct rate_selection)); | 176 | memset(sel, 0, sizeof(struct rate_selection)); |
176 | 177 | ||
177 | ref->ops->get_rate(ref->priv, dev, mode, skb, sel); | 178 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); |
178 | 179 | ||
179 | /* Select a non-ERP backup rate. */ | 180 | /* Select a non-ERP backup rate. */ |
180 | if (!sel->nonerp) { | 181 | if (!sel->nonerp) { |
181 | for (i = 0; i < mode->num_rates - 1; i++) { | 182 | for (i = 0; i < sband->n_bitrates; i++) { |
182 | struct ieee80211_rate *rate = &mode->rates[i]; | 183 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
183 | if (sel->rate->rate < rate->rate) | 184 | if (sel->rate->bitrate < rate->bitrate) |
184 | break; | 185 | break; |
185 | 186 | ||
186 | if (rate_supported(sta, mode, i) && | 187 | if (rate_supported(sta, sband->band, i) && |
187 | !(rate->flags & IEEE80211_RATE_ERP)) | 188 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
188 | sel->nonerp = rate; | 189 | sel->nonerp = rate; |
189 | } | 190 | } |
190 | } | 191 | } |
diff --git a/net/mac80211/ieee80211_rate.h b/net/mac80211/ieee80211_rate.h index 73f19e8aa51c..5f9a2ca49a57 100644 --- a/net/mac80211/ieee80211_rate.h +++ b/net/mac80211/ieee80211_rate.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
19 | #include "sta_info.h" | 19 | #include "sta_info.h" |
20 | 20 | ||
21 | /* TODO: kdoc */ | ||
21 | struct rate_selection { | 22 | struct rate_selection { |
22 | /* Selected transmission rate */ | 23 | /* Selected transmission rate */ |
23 | struct ieee80211_rate *rate; | 24 | struct ieee80211_rate *rate; |
@@ -34,7 +35,8 @@ struct rate_control_ops { | |||
34 | struct sk_buff *skb, | 35 | struct sk_buff *skb, |
35 | struct ieee80211_tx_status *status); | 36 | struct ieee80211_tx_status *status); |
36 | void (*get_rate)(void *priv, struct net_device *dev, | 37 | void (*get_rate)(void *priv, struct net_device *dev, |
37 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 38 | struct ieee80211_supported_band *band, |
39 | struct sk_buff *skb, | ||
38 | struct rate_selection *sel); | 40 | struct rate_selection *sel); |
39 | void (*rate_init)(void *priv, void *priv_sta, | 41 | void (*rate_init)(void *priv, void *priv_sta, |
40 | struct ieee80211_local *local, struct sta_info *sta); | 42 | struct ieee80211_local *local, struct sta_info *sta); |
@@ -66,7 +68,8 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops); | |||
66 | struct rate_control_ref *rate_control_alloc(const char *name, | 68 | struct rate_control_ref *rate_control_alloc(const char *name, |
67 | struct ieee80211_local *local); | 69 | struct ieee80211_local *local); |
68 | void rate_control_get_rate(struct net_device *dev, | 70 | void rate_control_get_rate(struct net_device *dev, |
69 | struct ieee80211_hw_mode *mode, struct sk_buff *skb, | 71 | struct ieee80211_supported_band *sband, |
72 | struct sk_buff *skb, | ||
70 | struct rate_selection *sel); | 73 | struct rate_selection *sel); |
71 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | 74 | struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); |
72 | void rate_control_put(struct rate_control_ref *ref); | 75 | void rate_control_put(struct rate_control_ref *ref); |
@@ -127,23 +130,23 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta) | |||
127 | #endif | 130 | #endif |
128 | } | 131 | } |
129 | 132 | ||
130 | static inline int | 133 | static inline int rate_supported(struct sta_info *sta, |
131 | rate_supported(struct sta_info *sta, struct ieee80211_hw_mode *mode, int index) | 134 | enum ieee80211_band band, |
135 | int index) | ||
132 | { | 136 | { |
133 | return (sta == NULL || sta->supp_rates & BIT(index)) && | 137 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); |
134 | (mode->rates[index].flags & IEEE80211_RATE_SUPPORTED); | ||
135 | } | 138 | } |
136 | 139 | ||
137 | static inline int | 140 | static inline int |
138 | rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | 141 | rate_lowest_index(struct ieee80211_local *local, |
142 | struct ieee80211_supported_band *sband, | ||
139 | struct sta_info *sta) | 143 | struct sta_info *sta) |
140 | { | 144 | { |
141 | int i; | 145 | int i; |
142 | 146 | ||
143 | for (i = 0; i < mode->num_rates; i++) { | 147 | for (i = 0; i < sband->n_bitrates; i++) |
144 | if (rate_supported(sta, mode, i)) | 148 | if (rate_supported(sta, sband->band, i)) |
145 | return i; | 149 | return i; |
146 | } | ||
147 | 150 | ||
148 | /* warn when we cannot find a rate. */ | 151 | /* warn when we cannot find a rate. */ |
149 | WARN_ON(1); | 152 | WARN_ON(1); |
@@ -152,10 +155,11 @@ rate_lowest_index(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | |||
152 | } | 155 | } |
153 | 156 | ||
154 | static inline struct ieee80211_rate * | 157 | static inline struct ieee80211_rate * |
155 | rate_lowest(struct ieee80211_local *local, struct ieee80211_hw_mode *mode, | 158 | rate_lowest(struct ieee80211_local *local, |
159 | struct ieee80211_supported_band *sband, | ||
156 | struct sta_info *sta) | 160 | struct sta_info *sta) |
157 | { | 161 | { |
158 | return &mode->rates[rate_lowest_index(local, mode, sta)]; | 162 | return &sband->bitrates[rate_lowest_index(local, sband, sta)]; |
159 | } | 163 | } |
160 | 164 | ||
161 | 165 | ||
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 9aeed5320228..ddb5832f37cb 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c | |||
@@ -74,7 +74,7 @@ | |||
74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | 74 | static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, |
75 | u8 *ssid, size_t ssid_len); | 75 | u8 *ssid, size_t ssid_len); |
76 | static struct ieee80211_sta_bss * | 76 | static struct ieee80211_sta_bss * |
77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 77 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
78 | u8 *ssid, u8 ssid_len); | 78 | u8 *ssid, u8 ssid_len); |
79 | static void ieee80211_rx_bss_put(struct net_device *dev, | 79 | static void ieee80211_rx_bss_put(struct net_device *dev, |
80 | struct ieee80211_sta_bss *bss); | 80 | struct ieee80211_sta_bss *bss); |
@@ -227,12 +227,7 @@ static void ieee802_11_parse_elems(u8 *start, size_t len, | |||
227 | 227 | ||
228 | static int ecw2cw(int ecw) | 228 | static int ecw2cw(int ecw) |
229 | { | 229 | { |
230 | int cw = 1; | 230 | return (1 << ecw) - 1; |
231 | while (ecw > 0) { | ||
232 | cw <<= 1; | ||
233 | ecw--; | ||
234 | } | ||
235 | return cw - 1; | ||
236 | } | 231 | } |
237 | 232 | ||
238 | static void ieee80211_sta_wmm_params(struct net_device *dev, | 233 | static void ieee80211_sta_wmm_params(struct net_device *dev, |
@@ -297,12 +292,13 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
297 | params.aifs = pos[0] & 0x0f; | 292 | params.aifs = pos[0] & 0x0f; |
298 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 293 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
299 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 294 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
300 | /* TXOP is in units of 32 usec; burst_time in 0.1 ms */ | 295 | params.txop = pos[2] | (pos[3] << 8); |
301 | params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; | 296 | #ifdef CONFIG_MAC80211_DEBUG |
302 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 297 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
303 | "cWmin=%d cWmax=%d burst=%d\n", | 298 | "cWmin=%d cWmax=%d txop=%d\n", |
304 | dev->name, queue, aci, acm, params.aifs, params.cw_min, | 299 | dev->name, queue, aci, acm, params.aifs, params.cw_min, |
305 | params.cw_max, params.burst_time); | 300 | params.cw_max, params.txop); |
301 | #endif | ||
306 | /* TODO: handle ACM (block TX, fallback to next lowest allowed | 302 | /* TODO: handle ACM (block TX, fallback to next lowest allowed |
307 | * AC for now) */ | 303 | * AC for now) */ |
308 | if (local->ops->conf_tx(local_to_hw(local), queue, ¶ms)) { | 304 | if (local->ops->conf_tx(local_to_hw(local), queue, ¶ms)) { |
@@ -466,7 +462,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
466 | return; | 462 | return; |
467 | 463 | ||
468 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 464 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
469 | local->hw.conf.channel, | 465 | local->hw.conf.channel->center_freq, |
470 | ifsta->ssid, ifsta->ssid_len); | 466 | ifsta->ssid, ifsta->ssid_len); |
471 | if (bss) { | 467 | if (bss) { |
472 | if (bss->has_erp_value) | 468 | if (bss->has_erp_value) |
@@ -492,6 +488,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
492 | ifsta->last_probe = jiffies; | 488 | ifsta->last_probe = jiffies; |
493 | ieee80211_led_assoc(local, assoc); | 489 | ieee80211_led_assoc(local, assoc); |
494 | 490 | ||
491 | sdata->bss_conf.assoc = assoc; | ||
495 | ieee80211_bss_info_change_notify(sdata, changed); | 492 | ieee80211_bss_info_change_notify(sdata, changed); |
496 | } | 493 | } |
497 | 494 | ||
@@ -592,7 +589,6 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
592 | struct ieee80211_if_sta *ifsta) | 589 | struct ieee80211_if_sta *ifsta) |
593 | { | 590 | { |
594 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 591 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
595 | struct ieee80211_hw_mode *mode; | ||
596 | struct sk_buff *skb; | 592 | struct sk_buff *skb; |
597 | struct ieee80211_mgmt *mgmt; | 593 | struct ieee80211_mgmt *mgmt; |
598 | u8 *pos, *ies; | 594 | u8 *pos, *ies; |
@@ -600,6 +596,7 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
600 | u16 capab; | 596 | u16 capab; |
601 | struct ieee80211_sta_bss *bss; | 597 | struct ieee80211_sta_bss *bss; |
602 | int wmm = 0; | 598 | int wmm = 0; |
599 | struct ieee80211_supported_band *sband; | ||
603 | 600 | ||
604 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 601 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
605 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + | 602 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + |
@@ -611,13 +608,19 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
611 | } | 608 | } |
612 | skb_reserve(skb, local->hw.extra_tx_headroom); | 609 | skb_reserve(skb, local->hw.extra_tx_headroom); |
613 | 610 | ||
614 | mode = local->oper_hw_mode; | 611 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
612 | |||
615 | capab = ifsta->capab; | 613 | capab = ifsta->capab; |
616 | if (mode->mode == MODE_IEEE80211G) { | 614 | |
617 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | | 615 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) { |
618 | WLAN_CAPABILITY_SHORT_PREAMBLE; | 616 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE)) |
617 | capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME; | ||
618 | if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE)) | ||
619 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; | ||
619 | } | 620 | } |
620 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 621 | |
622 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | ||
623 | local->hw.conf.channel->center_freq, | ||
621 | ifsta->ssid, ifsta->ssid_len); | 624 | ifsta->ssid, ifsta->ssid_len); |
622 | if (bss) { | 625 | if (bss) { |
623 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 626 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) |
@@ -656,23 +659,23 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
656 | *pos++ = ifsta->ssid_len; | 659 | *pos++ = ifsta->ssid_len; |
657 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 660 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
658 | 661 | ||
659 | len = mode->num_rates; | 662 | len = sband->n_bitrates; |
660 | if (len > 8) | 663 | if (len > 8) |
661 | len = 8; | 664 | len = 8; |
662 | pos = skb_put(skb, len + 2); | 665 | pos = skb_put(skb, len + 2); |
663 | *pos++ = WLAN_EID_SUPP_RATES; | 666 | *pos++ = WLAN_EID_SUPP_RATES; |
664 | *pos++ = len; | 667 | *pos++ = len; |
665 | for (i = 0; i < len; i++) { | 668 | for (i = 0; i < len; i++) { |
666 | int rate = mode->rates[i].rate; | 669 | int rate = sband->bitrates[i].bitrate; |
667 | *pos++ = (u8) (rate / 5); | 670 | *pos++ = (u8) (rate / 5); |
668 | } | 671 | } |
669 | 672 | ||
670 | if (mode->num_rates > len) { | 673 | if (sband->n_bitrates > len) { |
671 | pos = skb_put(skb, mode->num_rates - len + 2); | 674 | pos = skb_put(skb, sband->n_bitrates - len + 2); |
672 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 675 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
673 | *pos++ = mode->num_rates - len; | 676 | *pos++ = sband->n_bitrates - len; |
674 | for (i = len; i < mode->num_rates; i++) { | 677 | for (i = len; i < sband->n_bitrates; i++) { |
675 | int rate = mode->rates[i].rate; | 678 | int rate = sband->bitrates[i].bitrate; |
676 | *pos++ = (u8) (rate / 5); | 679 | *pos++ = (u8) (rate / 5); |
677 | } | 680 | } |
678 | } | 681 | } |
@@ -695,17 +698,18 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
695 | *pos++ = 0; | 698 | *pos++ = 0; |
696 | } | 699 | } |
697 | /* wmm support is a must to HT */ | 700 | /* wmm support is a must to HT */ |
698 | if (wmm && mode->ht_info.ht_supported) { | 701 | if (wmm && sband->ht_info.ht_supported) { |
699 | __le16 tmp = cpu_to_le16(mode->ht_info.cap); | 702 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); |
700 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 703 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
701 | *pos++ = WLAN_EID_HT_CAPABILITY; | 704 | *pos++ = WLAN_EID_HT_CAPABILITY; |
702 | *pos++ = sizeof(struct ieee80211_ht_cap); | 705 | *pos++ = sizeof(struct ieee80211_ht_cap); |
703 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | 706 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); |
704 | memcpy(pos, &tmp, sizeof(u16)); | 707 | memcpy(pos, &tmp, sizeof(u16)); |
705 | pos += sizeof(u16); | 708 | pos += sizeof(u16); |
706 | *pos++ = (mode->ht_info.ampdu_factor | | 709 | /* TODO: needs a define here for << 2 */ |
707 | (mode->ht_info.ampdu_density << 2)); | 710 | *pos++ = sband->ht_info.ampdu_factor | |
708 | memcpy(pos, mode->ht_info.supp_mcs_set, 16); | 711 | (sband->ht_info.ampdu_density << 2); |
712 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | ||
709 | } | 713 | } |
710 | 714 | ||
711 | kfree(ifsta->assocreq_ies); | 715 | kfree(ifsta->assocreq_ies); |
@@ -788,7 +792,8 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
788 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) | 792 | if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) |
789 | return 0; | 793 | return 0; |
790 | 794 | ||
791 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, | 795 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
796 | local->hw.conf.channel->center_freq, | ||
792 | ifsta->ssid, ifsta->ssid_len); | 797 | ifsta->ssid, ifsta->ssid_len); |
793 | if (!bss) | 798 | if (!bss) |
794 | return 0; | 799 | return 0; |
@@ -898,7 +903,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
898 | u8 *ssid, size_t ssid_len) | 903 | u8 *ssid, size_t ssid_len) |
899 | { | 904 | { |
900 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 905 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
901 | struct ieee80211_hw_mode *mode; | 906 | struct ieee80211_supported_band *sband; |
902 | struct sk_buff *skb; | 907 | struct sk_buff *skb; |
903 | struct ieee80211_mgmt *mgmt; | 908 | struct ieee80211_mgmt *mgmt; |
904 | u8 *pos, *supp_rates, *esupp_rates = NULL; | 909 | u8 *pos, *supp_rates, *esupp_rates = NULL; |
@@ -932,11 +937,10 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
932 | supp_rates = skb_put(skb, 2); | 937 | supp_rates = skb_put(skb, 2); |
933 | supp_rates[0] = WLAN_EID_SUPP_RATES; | 938 | supp_rates[0] = WLAN_EID_SUPP_RATES; |
934 | supp_rates[1] = 0; | 939 | supp_rates[1] = 0; |
935 | mode = local->oper_hw_mode; | 940 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
936 | for (i = 0; i < mode->num_rates; i++) { | 941 | |
937 | struct ieee80211_rate *rate = &mode->rates[i]; | 942 | for (i = 0; i < sband->n_bitrates; i++) { |
938 | if (!(rate->flags & IEEE80211_RATE_SUPPORTED)) | 943 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
939 | continue; | ||
940 | if (esupp_rates) { | 944 | if (esupp_rates) { |
941 | pos = skb_put(skb, 1); | 945 | pos = skb_put(skb, 1); |
942 | esupp_rates[1]++; | 946 | esupp_rates[1]++; |
@@ -949,7 +953,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
949 | pos = skb_put(skb, 1); | 953 | pos = skb_put(skb, 1); |
950 | supp_rates[1]++; | 954 | supp_rates[1]++; |
951 | } | 955 | } |
952 | *pos = rate->rate / 5; | 956 | *pos = rate->bitrate / 5; |
953 | } | 957 | } |
954 | 958 | ||
955 | ieee80211_sta_tx(dev, skb, 0); | 959 | ieee80211_sta_tx(dev, skb, 0); |
@@ -1044,6 +1048,58 @@ static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid, | |||
1044 | return; | 1048 | return; |
1045 | } | 1049 | } |
1046 | 1050 | ||
1051 | void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, | ||
1052 | u16 tid, u8 dialog_token, u16 start_seq_num, | ||
1053 | u16 agg_size, u16 timeout) | ||
1054 | { | ||
1055 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1056 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1057 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
1058 | struct sk_buff *skb; | ||
1059 | struct ieee80211_mgmt *mgmt; | ||
1060 | u16 capab; | ||
1061 | |||
1062 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | ||
1063 | sizeof(mgmt->u.action.u.addba_req)); | ||
1064 | |||
1065 | |||
1066 | if (!skb) { | ||
1067 | printk(KERN_ERR "%s: failed to allocate buffer " | ||
1068 | "for addba request frame\n", dev->name); | ||
1069 | return; | ||
1070 | } | ||
1071 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1072 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | ||
1073 | memset(mgmt, 0, 24); | ||
1074 | memcpy(mgmt->da, da, ETH_ALEN); | ||
1075 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | ||
1076 | if (sdata->vif.type == IEEE80211_IF_TYPE_AP) | ||
1077 | memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN); | ||
1078 | else | ||
1079 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1080 | |||
1081 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1082 | IEEE80211_STYPE_ACTION); | ||
1083 | |||
1084 | skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); | ||
1085 | |||
1086 | mgmt->u.action.category = WLAN_CATEGORY_BACK; | ||
1087 | mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; | ||
1088 | |||
1089 | mgmt->u.action.u.addba_req.dialog_token = dialog_token; | ||
1090 | capab = (u16)(1 << 1); /* bit 1 aggregation policy */ | ||
1091 | capab |= (u16)(tid << 2); /* bit 5:2 TID number */ | ||
1092 | capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */ | ||
1093 | |||
1094 | mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); | ||
1095 | |||
1096 | mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); | ||
1097 | mgmt->u.action.u.addba_req.start_seq_num = | ||
1098 | cpu_to_le16(start_seq_num << 4); | ||
1099 | |||
1100 | ieee80211_sta_tx(dev, skb, 0); | ||
1101 | } | ||
1102 | |||
1047 | static void ieee80211_sta_process_addba_request(struct net_device *dev, | 1103 | static void ieee80211_sta_process_addba_request(struct net_device *dev, |
1048 | struct ieee80211_mgmt *mgmt, | 1104 | struct ieee80211_mgmt *mgmt, |
1049 | size_t len) | 1105 | size_t len) |
@@ -1093,9 +1149,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1093 | } | 1149 | } |
1094 | /* determine default buffer size */ | 1150 | /* determine default buffer size */ |
1095 | if (buf_size == 0) { | 1151 | if (buf_size == 0) { |
1096 | struct ieee80211_hw_mode *mode = conf->mode; | 1152 | struct ieee80211_supported_band *sband; |
1153 | |||
1154 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
1097 | buf_size = IEEE80211_MIN_AMPDU_BUF; | 1155 | buf_size = IEEE80211_MIN_AMPDU_BUF; |
1098 | buf_size = buf_size << mode->ht_info.ampdu_factor; | 1156 | buf_size = buf_size << sband->ht_info.ampdu_factor; |
1099 | } | 1157 | } |
1100 | 1158 | ||
1101 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; | 1159 | tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid]; |
@@ -1127,7 +1185,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1127 | 1185 | ||
1128 | if (local->ops->ampdu_action) | 1186 | if (local->ops->ampdu_action) |
1129 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, | 1187 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, |
1130 | sta->addr, tid, start_seq_num); | 1188 | sta->addr, tid, &start_seq_num); |
1131 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1189 | #ifdef CONFIG_MAC80211_HT_DEBUG |
1132 | printk(KERN_DEBUG "Rx A-MPDU on tid %d result %d", tid, ret); | 1190 | printk(KERN_DEBUG "Rx A-MPDU on tid %d result %d", tid, ret); |
1133 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1191 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -1155,8 +1213,80 @@ end_no_lock: | |||
1155 | sta_info_put(sta); | 1213 | sta_info_put(sta); |
1156 | } | 1214 | } |
1157 | 1215 | ||
1158 | static void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | 1216 | static void ieee80211_sta_process_addba_resp(struct net_device *dev, |
1159 | u16 initiator, u16 reason_code) | 1217 | struct ieee80211_mgmt *mgmt, |
1218 | size_t len) | ||
1219 | { | ||
1220 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1221 | struct ieee80211_hw *hw = &local->hw; | ||
1222 | struct sta_info *sta; | ||
1223 | u16 capab; | ||
1224 | u16 tid; | ||
1225 | u8 *state; | ||
1226 | |||
1227 | sta = sta_info_get(local, mgmt->sa); | ||
1228 | if (!sta) | ||
1229 | return; | ||
1230 | |||
1231 | capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); | ||
1232 | tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; | ||
1233 | |||
1234 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
1235 | |||
1236 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1237 | |||
1238 | if (mgmt->u.action.u.addba_resp.dialog_token != | ||
1239 | sta->ampdu_mlme.tid_tx[tid].dialog_token) { | ||
1240 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1241 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1242 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | ||
1243 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
1244 | sta_info_put(sta); | ||
1245 | return; | ||
1246 | } | ||
1247 | |||
1248 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer); | ||
1249 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1250 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | ||
1251 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
1252 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | ||
1253 | == WLAN_STATUS_SUCCESS) { | ||
1254 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | ||
1255 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1256 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | ||
1257 | "%d\n", *state); | ||
1258 | sta_info_put(sta); | ||
1259 | return; | ||
1260 | } | ||
1261 | |||
1262 | if (*state & HT_ADDBA_RECEIVED_MSK) | ||
1263 | printk(KERN_DEBUG "double addBA response\n"); | ||
1264 | |||
1265 | *state |= HT_ADDBA_RECEIVED_MSK; | ||
1266 | sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0; | ||
1267 | |||
1268 | if (*state == HT_AGG_STATE_OPERATIONAL) { | ||
1269 | printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); | ||
1270 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | ||
1271 | } | ||
1272 | |||
1273 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1274 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | ||
1275 | } else { | ||
1276 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | ||
1277 | |||
1278 | sta->ampdu_mlme.tid_tx[tid].addba_req_num++; | ||
1279 | /* this will allow the state check in stop_BA_session */ | ||
1280 | *state = HT_AGG_STATE_OPERATIONAL; | ||
1281 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1282 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, | ||
1283 | WLAN_BACK_INITIATOR); | ||
1284 | } | ||
1285 | sta_info_put(sta); | ||
1286 | } | ||
1287 | |||
1288 | void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | ||
1289 | u16 initiator, u16 reason_code) | ||
1160 | { | 1290 | { |
1161 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1291 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1162 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1292 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -1229,7 +1359,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1229 | BUG_ON(!local->ops->ampdu_action); | 1359 | BUG_ON(!local->ops->ampdu_action); |
1230 | 1360 | ||
1231 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, | 1361 | ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP, |
1232 | ra, tid, EINVAL); | 1362 | ra, tid, NULL); |
1233 | if (ret) | 1363 | if (ret) |
1234 | printk(KERN_DEBUG "HW problem - can not stop rx " | 1364 | printk(KERN_DEBUG "HW problem - can not stop rx " |
1235 | "aggergation for tid %d\n", tid); | 1365 | "aggergation for tid %d\n", tid); |
@@ -1258,6 +1388,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1258 | sta_info_put(sta); | 1388 | sta_info_put(sta); |
1259 | } | 1389 | } |
1260 | 1390 | ||
1391 | |||
1261 | static void ieee80211_sta_process_delba(struct net_device *dev, | 1392 | static void ieee80211_sta_process_delba(struct net_device *dev, |
1262 | struct ieee80211_mgmt *mgmt, size_t len) | 1393 | struct ieee80211_mgmt *mgmt, size_t len) |
1263 | { | 1394 | { |
@@ -1277,14 +1408,70 @@ static void ieee80211_sta_process_delba(struct net_device *dev, | |||
1277 | 1408 | ||
1278 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1409 | #ifdef CONFIG_MAC80211_HT_DEBUG |
1279 | if (net_ratelimit()) | 1410 | if (net_ratelimit()) |
1280 | printk(KERN_DEBUG "delba from %s on tid %d reason code %d\n", | 1411 | printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n", |
1281 | print_mac(mac, mgmt->sa), tid, | 1412 | print_mac(mac, mgmt->sa), |
1413 | initiator ? "recipient" : "initiator", tid, | ||
1282 | mgmt->u.action.u.delba.reason_code); | 1414 | mgmt->u.action.u.delba.reason_code); |
1283 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1415 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
1284 | 1416 | ||
1285 | if (initiator == WLAN_BACK_INITIATOR) | 1417 | if (initiator == WLAN_BACK_INITIATOR) |
1286 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, | 1418 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, |
1287 | WLAN_BACK_INITIATOR, 0); | 1419 | WLAN_BACK_INITIATOR, 0); |
1420 | else { /* WLAN_BACK_RECIPIENT */ | ||
1421 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1422 | sta->ampdu_mlme.tid_tx[tid].state = | ||
1423 | HT_AGG_STATE_OPERATIONAL; | ||
1424 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1425 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, | ||
1426 | WLAN_BACK_RECIPIENT); | ||
1427 | } | ||
1428 | sta_info_put(sta); | ||
1429 | } | ||
1430 | |||
1431 | /* | ||
1432 | * After sending add Block Ack request we activated a timer until | ||
1433 | * add Block Ack response will arrive from the recipient. | ||
1434 | * If this timer expires sta_addba_resp_timer_expired will be executed. | ||
1435 | */ | ||
1436 | void sta_addba_resp_timer_expired(unsigned long data) | ||
1437 | { | ||
1438 | /* not an elegant detour, but there is no choice as the timer passes | ||
1439 | * only one argument, and both sta_info and TID are needed, so init | ||
1440 | * flow in sta_info_add gives the TID as data, while the timer_to_id | ||
1441 | * array gives the sta through container_of */ | ||
1442 | u16 tid = *(int *)data; | ||
1443 | struct sta_info *temp_sta = container_of((void *)data, | ||
1444 | struct sta_info, timer_to_tid[tid]); | ||
1445 | |||
1446 | struct ieee80211_local *local = temp_sta->local; | ||
1447 | struct ieee80211_hw *hw = &local->hw; | ||
1448 | struct sta_info *sta; | ||
1449 | u8 *state; | ||
1450 | |||
1451 | sta = sta_info_get(local, temp_sta->addr); | ||
1452 | if (!sta) | ||
1453 | return; | ||
1454 | |||
1455 | state = &sta->ampdu_mlme.tid_tx[tid].state; | ||
1456 | /* check if the TID waits for addBA response */ | ||
1457 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1458 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | ||
1459 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1460 | *state = HT_AGG_STATE_IDLE; | ||
1461 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | ||
1462 | "expecting addBA response there", tid); | ||
1463 | goto timer_expired_exit; | ||
1464 | } | ||
1465 | |||
1466 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | ||
1467 | |||
1468 | /* go through the state check in stop_BA_session */ | ||
1469 | *state = HT_AGG_STATE_OPERATIONAL; | ||
1470 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
1471 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, | ||
1472 | WLAN_BACK_INITIATOR); | ||
1473 | |||
1474 | timer_expired_exit: | ||
1288 | sta_info_put(sta); | 1475 | sta_info_put(sta); |
1289 | } | 1476 | } |
1290 | 1477 | ||
@@ -1536,15 +1723,16 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1536 | { | 1723 | { |
1537 | struct ieee80211_local *local = sdata->local; | 1724 | struct ieee80211_local *local = sdata->local; |
1538 | struct net_device *dev = sdata->dev; | 1725 | struct net_device *dev = sdata->dev; |
1539 | struct ieee80211_hw_mode *mode; | 1726 | struct ieee80211_supported_band *sband; |
1540 | struct sta_info *sta; | 1727 | struct sta_info *sta; |
1541 | u32 rates; | 1728 | u64 rates, basic_rates; |
1542 | u16 capab_info, status_code, aid; | 1729 | u16 capab_info, status_code, aid; |
1543 | struct ieee802_11_elems elems; | 1730 | struct ieee802_11_elems elems; |
1544 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1731 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; |
1545 | u8 *pos; | 1732 | u8 *pos; |
1546 | int i, j; | 1733 | int i, j; |
1547 | DECLARE_MAC_BUF(mac); | 1734 | DECLARE_MAC_BUF(mac); |
1735 | bool have_higher_than_11mbit = false; | ||
1548 | 1736 | ||
1549 | /* AssocResp and ReassocResp have identical structure, so process both | 1737 | /* AssocResp and ReassocResp have identical structure, so process both |
1550 | * of them in this function. */ | 1738 | * of them in this function. */ |
@@ -1614,22 +1802,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1614 | if (ifsta->assocresp_ies) | 1802 | if (ifsta->assocresp_ies) |
1615 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); | 1803 | memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); |
1616 | 1804 | ||
1617 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1618 | bss_conf->aid = aid; | ||
1619 | ieee80211_set_associated(dev, ifsta, 1); | ||
1620 | |||
1621 | /* Add STA entry for the AP */ | 1805 | /* Add STA entry for the AP */ |
1622 | sta = sta_info_get(local, ifsta->bssid); | 1806 | sta = sta_info_get(local, ifsta->bssid); |
1623 | if (!sta) { | 1807 | if (!sta) { |
1624 | struct ieee80211_sta_bss *bss; | 1808 | struct ieee80211_sta_bss *bss; |
1625 | sta = sta_info_add(local, dev, ifsta->bssid, GFP_KERNEL); | 1809 | sta = sta_info_add(local, dev, ifsta->bssid, GFP_KERNEL); |
1626 | if (!sta) { | 1810 | if (IS_ERR(sta)) { |
1627 | printk(KERN_DEBUG "%s: failed to add STA entry for the" | 1811 | printk(KERN_DEBUG "%s: failed to add STA entry for the" |
1628 | " AP\n", dev->name); | 1812 | " AP (error %ld)\n", dev->name, PTR_ERR(sta)); |
1629 | return; | 1813 | return; |
1630 | } | 1814 | } |
1631 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, | 1815 | bss = ieee80211_rx_bss_get(dev, ifsta->bssid, |
1632 | local->hw.conf.channel, | 1816 | local->hw.conf.channel->center_freq, |
1633 | ifsta->ssid, ifsta->ssid_len); | 1817 | ifsta->ssid, ifsta->ssid_len); |
1634 | if (bss) { | 1818 | if (bss) { |
1635 | sta->last_rssi = bss->rssi; | 1819 | sta->last_rssi = bss->rssi; |
@@ -1640,23 +1824,50 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1640 | } | 1824 | } |
1641 | 1825 | ||
1642 | sta->dev = dev; | 1826 | sta->dev = dev; |
1643 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP; | 1827 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
1828 | WLAN_STA_AUTHORIZED; | ||
1644 | 1829 | ||
1645 | rates = 0; | 1830 | rates = 0; |
1646 | mode = local->oper_hw_mode; | 1831 | basic_rates = 0; |
1832 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1833 | |||
1647 | for (i = 0; i < elems.supp_rates_len; i++) { | 1834 | for (i = 0; i < elems.supp_rates_len; i++) { |
1648 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1835 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1649 | for (j = 0; j < mode->num_rates; j++) | 1836 | |
1650 | if (mode->rates[j].rate == rate) | 1837 | if (rate > 110) |
1838 | have_higher_than_11mbit = true; | ||
1839 | |||
1840 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1841 | if (sband->bitrates[j].bitrate == rate) | ||
1651 | rates |= BIT(j); | 1842 | rates |= BIT(j); |
1843 | if (elems.supp_rates[i] & 0x80) | ||
1844 | basic_rates |= BIT(j); | ||
1845 | } | ||
1652 | } | 1846 | } |
1847 | |||
1653 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1848 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1654 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1849 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1655 | for (j = 0; j < mode->num_rates; j++) | 1850 | |
1656 | if (mode->rates[j].rate == rate) | 1851 | if (rate > 110) |
1852 | have_higher_than_11mbit = true; | ||
1853 | |||
1854 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1855 | if (sband->bitrates[j].bitrate == rate) | ||
1657 | rates |= BIT(j); | 1856 | rates |= BIT(j); |
1857 | if (elems.ext_supp_rates[i] & 0x80) | ||
1858 | basic_rates |= BIT(j); | ||
1859 | } | ||
1658 | } | 1860 | } |
1659 | sta->supp_rates = rates; | 1861 | |
1862 | sta->supp_rates[local->hw.conf.channel->band] = rates; | ||
1863 | sdata->basic_rates = basic_rates; | ||
1864 | |||
1865 | /* cf. IEEE 802.11 9.2.12 */ | ||
1866 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | ||
1867 | have_higher_than_11mbit) | ||
1868 | sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; | ||
1869 | else | ||
1870 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | ||
1660 | 1871 | ||
1661 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1872 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
1662 | local->ops->conf_ht) { | 1873 | local->ops->conf_ht) { |
@@ -1679,6 +1890,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1679 | elems.wmm_param_len); | 1890 | elems.wmm_param_len); |
1680 | } | 1891 | } |
1681 | 1892 | ||
1893 | /* set AID, ieee80211_set_associated() will tell the driver */ | ||
1894 | bss_conf->aid = aid; | ||
1895 | ieee80211_set_associated(dev, ifsta, 1); | ||
1682 | 1896 | ||
1683 | sta_info_put(sta); | 1897 | sta_info_put(sta); |
1684 | 1898 | ||
@@ -1719,7 +1933,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | |||
1719 | 1933 | ||
1720 | 1934 | ||
1721 | static struct ieee80211_sta_bss * | 1935 | static struct ieee80211_sta_bss * |
1722 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | 1936 | ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int freq, |
1723 | u8 *ssid, u8 ssid_len) | 1937 | u8 *ssid, u8 ssid_len) |
1724 | { | 1938 | { |
1725 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1939 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1731,7 +1945,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1731 | atomic_inc(&bss->users); | 1945 | atomic_inc(&bss->users); |
1732 | atomic_inc(&bss->users); | 1946 | atomic_inc(&bss->users); |
1733 | memcpy(bss->bssid, bssid, ETH_ALEN); | 1947 | memcpy(bss->bssid, bssid, ETH_ALEN); |
1734 | bss->channel = channel; | 1948 | bss->freq = freq; |
1735 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { | 1949 | if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { |
1736 | memcpy(bss->ssid, ssid, ssid_len); | 1950 | memcpy(bss->ssid, ssid, ssid_len); |
1737 | bss->ssid_len = ssid_len; | 1951 | bss->ssid_len = ssid_len; |
@@ -1747,7 +1961,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, | |||
1747 | 1961 | ||
1748 | 1962 | ||
1749 | static struct ieee80211_sta_bss * | 1963 | static struct ieee80211_sta_bss * |
1750 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | 1964 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
1751 | u8 *ssid, u8 ssid_len) | 1965 | u8 *ssid, u8 ssid_len) |
1752 | { | 1966 | { |
1753 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1967 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -1757,7 +1971,7 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, | |||
1757 | bss = local->sta_bss_hash[STA_HASH(bssid)]; | 1971 | bss = local->sta_bss_hash[STA_HASH(bssid)]; |
1758 | while (bss) { | 1972 | while (bss) { |
1759 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && | 1973 | if (!memcmp(bss->bssid, bssid, ETH_ALEN) && |
1760 | bss->channel == channel && | 1974 | bss->freq == freq && |
1761 | bss->ssid_len == ssid_len && | 1975 | bss->ssid_len == ssid_len && |
1762 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { | 1976 | (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { |
1763 | atomic_inc(&bss->users); | 1977 | atomic_inc(&bss->users); |
@@ -1813,6 +2027,165 @@ void ieee80211_rx_bss_list_deinit(struct net_device *dev) | |||
1813 | } | 2027 | } |
1814 | 2028 | ||
1815 | 2029 | ||
2030 | static int ieee80211_sta_join_ibss(struct net_device *dev, | ||
2031 | struct ieee80211_if_sta *ifsta, | ||
2032 | struct ieee80211_sta_bss *bss) | ||
2033 | { | ||
2034 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2035 | int res, rates, i, j; | ||
2036 | struct sk_buff *skb; | ||
2037 | struct ieee80211_mgmt *mgmt; | ||
2038 | struct ieee80211_tx_control control; | ||
2039 | struct rate_selection ratesel; | ||
2040 | u8 *pos; | ||
2041 | struct ieee80211_sub_if_data *sdata; | ||
2042 | struct ieee80211_supported_band *sband; | ||
2043 | |||
2044 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2045 | |||
2046 | /* Remove possible STA entries from other IBSS networks. */ | ||
2047 | sta_info_flush(local, NULL); | ||
2048 | |||
2049 | if (local->ops->reset_tsf) { | ||
2050 | /* Reset own TSF to allow time synchronization work. */ | ||
2051 | local->ops->reset_tsf(local_to_hw(local)); | ||
2052 | } | ||
2053 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); | ||
2054 | res = ieee80211_if_config(dev); | ||
2055 | if (res) | ||
2056 | return res; | ||
2057 | |||
2058 | local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; | ||
2059 | |||
2060 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2061 | sdata->drop_unencrypted = bss->capability & | ||
2062 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
2063 | |||
2064 | res = ieee80211_set_freq(local, bss->freq); | ||
2065 | |||
2066 | if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { | ||
2067 | printk(KERN_DEBUG "%s: IBSS not allowed on frequency " | ||
2068 | "%d MHz\n", dev->name, local->oper_channel->center_freq); | ||
2069 | return -1; | ||
2070 | } | ||
2071 | |||
2072 | /* Set beacon template */ | ||
2073 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
2074 | do { | ||
2075 | if (!skb) | ||
2076 | break; | ||
2077 | |||
2078 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2079 | |||
2080 | mgmt = (struct ieee80211_mgmt *) | ||
2081 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
2082 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
2083 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2084 | IEEE80211_STYPE_BEACON); | ||
2085 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
2086 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | ||
2087 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
2088 | mgmt->u.beacon.beacon_int = | ||
2089 | cpu_to_le16(local->hw.conf.beacon_int); | ||
2090 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
2091 | |||
2092 | pos = skb_put(skb, 2 + ifsta->ssid_len); | ||
2093 | *pos++ = WLAN_EID_SSID; | ||
2094 | *pos++ = ifsta->ssid_len; | ||
2095 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | ||
2096 | |||
2097 | rates = bss->supp_rates_len; | ||
2098 | if (rates > 8) | ||
2099 | rates = 8; | ||
2100 | pos = skb_put(skb, 2 + rates); | ||
2101 | *pos++ = WLAN_EID_SUPP_RATES; | ||
2102 | *pos++ = rates; | ||
2103 | memcpy(pos, bss->supp_rates, rates); | ||
2104 | |||
2105 | if (bss->band == IEEE80211_BAND_2GHZ) { | ||
2106 | pos = skb_put(skb, 2 + 1); | ||
2107 | *pos++ = WLAN_EID_DS_PARAMS; | ||
2108 | *pos++ = 1; | ||
2109 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
2110 | } | ||
2111 | |||
2112 | pos = skb_put(skb, 2 + 2); | ||
2113 | *pos++ = WLAN_EID_IBSS_PARAMS; | ||
2114 | *pos++ = 2; | ||
2115 | /* FIX: set ATIM window based on scan results */ | ||
2116 | *pos++ = 0; | ||
2117 | *pos++ = 0; | ||
2118 | |||
2119 | if (bss->supp_rates_len > 8) { | ||
2120 | rates = bss->supp_rates_len - 8; | ||
2121 | pos = skb_put(skb, 2 + rates); | ||
2122 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
2123 | *pos++ = rates; | ||
2124 | memcpy(pos, &bss->supp_rates[8], rates); | ||
2125 | } | ||
2126 | |||
2127 | memset(&control, 0, sizeof(control)); | ||
2128 | rate_control_get_rate(dev, sband, skb, &ratesel); | ||
2129 | if (!ratesel.rate) { | ||
2130 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | ||
2131 | "for IBSS beacon\n", dev->name); | ||
2132 | break; | ||
2133 | } | ||
2134 | control.vif = &sdata->vif; | ||
2135 | control.tx_rate = ratesel.rate; | ||
2136 | if (sdata->bss_conf.use_short_preamble && | ||
2137 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
2138 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | ||
2139 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
2140 | control.flags |= IEEE80211_TXCTL_NO_ACK; | ||
2141 | control.retry_limit = 1; | ||
2142 | |||
2143 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | ||
2144 | if (ifsta->probe_resp) { | ||
2145 | mgmt = (struct ieee80211_mgmt *) | ||
2146 | ifsta->probe_resp->data; | ||
2147 | mgmt->frame_control = | ||
2148 | IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2149 | IEEE80211_STYPE_PROBE_RESP); | ||
2150 | } else { | ||
2151 | printk(KERN_DEBUG "%s: Could not allocate ProbeResp " | ||
2152 | "template for IBSS\n", dev->name); | ||
2153 | } | ||
2154 | |||
2155 | if (local->ops->beacon_update && | ||
2156 | local->ops->beacon_update(local_to_hw(local), | ||
2157 | skb, &control) == 0) { | ||
2158 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | ||
2159 | "template\n", dev->name); | ||
2160 | skb = NULL; | ||
2161 | } | ||
2162 | |||
2163 | rates = 0; | ||
2164 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
2165 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
2166 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | ||
2167 | for (j = 0; j < sband->n_bitrates; j++) | ||
2168 | if (sband->bitrates[j].bitrate == bitrate) | ||
2169 | rates |= BIT(j); | ||
2170 | } | ||
2171 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
2172 | } while (0); | ||
2173 | |||
2174 | if (skb) { | ||
2175 | printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " | ||
2176 | "template\n", dev->name); | ||
2177 | dev_kfree_skb(skb); | ||
2178 | } | ||
2179 | |||
2180 | ifsta->state = IEEE80211_IBSS_JOINED; | ||
2181 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | ||
2182 | |||
2183 | ieee80211_rx_bss_put(dev, bss); | ||
2184 | |||
2185 | return res; | ||
2186 | } | ||
2187 | |||
2188 | |||
1816 | static void ieee80211_rx_bss_info(struct net_device *dev, | 2189 | static void ieee80211_rx_bss_info(struct net_device *dev, |
1817 | struct ieee80211_mgmt *mgmt, | 2190 | struct ieee80211_mgmt *mgmt, |
1818 | size_t len, | 2191 | size_t len, |
@@ -1822,11 +2195,11 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1822 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2195 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1823 | struct ieee802_11_elems elems; | 2196 | struct ieee802_11_elems elems; |
1824 | size_t baselen; | 2197 | size_t baselen; |
1825 | int channel, clen; | 2198 | int freq, clen; |
1826 | struct ieee80211_sta_bss *bss; | 2199 | struct ieee80211_sta_bss *bss; |
1827 | struct sta_info *sta; | 2200 | struct sta_info *sta; |
1828 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2201 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1829 | u64 timestamp; | 2202 | u64 beacon_timestamp, rx_timestamp; |
1830 | DECLARE_MAC_BUF(mac); | 2203 | DECLARE_MAC_BUF(mac); |
1831 | DECLARE_MAC_BUF(mac2); | 2204 | DECLARE_MAC_BUF(mac2); |
1832 | 2205 | ||
@@ -1843,56 +2216,28 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1843 | if (baselen > len) | 2216 | if (baselen > len) |
1844 | return; | 2217 | return; |
1845 | 2218 | ||
1846 | timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2219 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
1847 | |||
1848 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && | ||
1849 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) { | ||
1850 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
1851 | static unsigned long last_tsf_debug = 0; | ||
1852 | u64 tsf; | ||
1853 | if (local->ops->get_tsf) | ||
1854 | tsf = local->ops->get_tsf(local_to_hw(local)); | ||
1855 | else | ||
1856 | tsf = -1LLU; | ||
1857 | if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { | ||
1858 | printk(KERN_DEBUG "RX beacon SA=%s BSSID=" | ||
1859 | "%s TSF=0x%llx BCN=0x%llx diff=%lld " | ||
1860 | "@%lu\n", | ||
1861 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->bssid), | ||
1862 | (unsigned long long)tsf, | ||
1863 | (unsigned long long)timestamp, | ||
1864 | (unsigned long long)(tsf - timestamp), | ||
1865 | jiffies); | ||
1866 | last_tsf_debug = jiffies; | ||
1867 | } | ||
1868 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
1869 | } | ||
1870 | |||
1871 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | 2220 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); |
1872 | 2221 | ||
1873 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2222 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && |
1874 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2223 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
1875 | (sta = sta_info_get(local, mgmt->sa))) { | 2224 | (sta = sta_info_get(local, mgmt->sa))) { |
1876 | struct ieee80211_hw_mode *mode; | 2225 | struct ieee80211_supported_band *sband; |
1877 | struct ieee80211_rate *rates; | 2226 | struct ieee80211_rate *bitrates; |
1878 | size_t num_rates; | 2227 | size_t num_rates; |
1879 | u32 supp_rates, prev_rates; | 2228 | u64 supp_rates, prev_rates; |
1880 | int i, j; | 2229 | int i, j; |
1881 | 2230 | ||
1882 | mode = local->sta_sw_scanning ? | 2231 | sband = local->hw.wiphy->bands[rx_status->band]; |
1883 | local->scan_hw_mode : local->oper_hw_mode; | ||
1884 | 2232 | ||
1885 | if (local->sta_hw_scanning) { | 2233 | if (!sband) { |
1886 | /* search for the correct mode matches the beacon */ | 2234 | WARN_ON(1); |
1887 | list_for_each_entry(mode, &local->modes_list, list) | 2235 | sband = local->hw.wiphy->bands[ |
1888 | if (mode->mode == rx_status->phymode) | 2236 | local->hw.conf.channel->band]; |
1889 | break; | ||
1890 | |||
1891 | if (mode == NULL) | ||
1892 | mode = local->oper_hw_mode; | ||
1893 | } | 2237 | } |
1894 | rates = mode->rates; | 2238 | |
1895 | num_rates = mode->num_rates; | 2239 | bitrates = sband->bitrates; |
2240 | num_rates = sband->n_bitrates; | ||
1896 | 2241 | ||
1897 | supp_rates = 0; | 2242 | supp_rates = 0; |
1898 | for (i = 0; i < elems.supp_rates_len + | 2243 | for (i = 0; i < elems.supp_rates_len + |
@@ -1906,24 +2251,27 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1906 | [i - elems.supp_rates_len]; | 2251 | [i - elems.supp_rates_len]; |
1907 | own_rate = 5 * (rate & 0x7f); | 2252 | own_rate = 5 * (rate & 0x7f); |
1908 | for (j = 0; j < num_rates; j++) | 2253 | for (j = 0; j < num_rates; j++) |
1909 | if (rates[j].rate == own_rate) | 2254 | if (bitrates[j].bitrate == own_rate) |
1910 | supp_rates |= BIT(j); | 2255 | supp_rates |= BIT(j); |
1911 | } | 2256 | } |
1912 | 2257 | ||
1913 | prev_rates = sta->supp_rates; | 2258 | prev_rates = sta->supp_rates[rx_status->band]; |
1914 | sta->supp_rates &= supp_rates; | 2259 | sta->supp_rates[rx_status->band] &= supp_rates; |
1915 | if (sta->supp_rates == 0) { | 2260 | if (sta->supp_rates[rx_status->band] == 0) { |
1916 | /* No matching rates - this should not really happen. | 2261 | /* No matching rates - this should not really happen. |
1917 | * Make sure that at least one rate is marked | 2262 | * Make sure that at least one rate is marked |
1918 | * supported to avoid issues with TX rate ctrl. */ | 2263 | * supported to avoid issues with TX rate ctrl. */ |
1919 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 2264 | sta->supp_rates[rx_status->band] = |
2265 | sdata->u.sta.supp_rates_bits[rx_status->band]; | ||
1920 | } | 2266 | } |
1921 | if (sta->supp_rates != prev_rates) { | 2267 | if (sta->supp_rates[rx_status->band] != prev_rates) { |
1922 | printk(KERN_DEBUG "%s: updated supp_rates set for " | 2268 | printk(KERN_DEBUG "%s: updated supp_rates set for " |
1923 | "%s based on beacon info (0x%x & 0x%x -> " | 2269 | "%s based on beacon info (0x%llx & 0x%llx -> " |
1924 | "0x%x)\n", | 2270 | "0x%llx)\n", |
1925 | dev->name, print_mac(mac, sta->addr), prev_rates, | 2271 | dev->name, print_mac(mac, sta->addr), |
1926 | supp_rates, sta->supp_rates); | 2272 | (unsigned long long) prev_rates, |
2273 | (unsigned long long) supp_rates, | ||
2274 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
1927 | } | 2275 | } |
1928 | sta_info_put(sta); | 2276 | sta_info_put(sta); |
1929 | } | 2277 | } |
@@ -1932,14 +2280,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1932 | return; | 2280 | return; |
1933 | 2281 | ||
1934 | if (elems.ds_params && elems.ds_params_len == 1) | 2282 | if (elems.ds_params && elems.ds_params_len == 1) |
1935 | channel = elems.ds_params[0]; | 2283 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); |
1936 | else | 2284 | else |
1937 | channel = rx_status->channel; | 2285 | freq = rx_status->freq; |
1938 | 2286 | ||
1939 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, | 2287 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
1940 | elems.ssid, elems.ssid_len); | 2288 | elems.ssid, elems.ssid_len); |
1941 | if (!bss) { | 2289 | if (!bss) { |
1942 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, | 2290 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
1943 | elems.ssid, elems.ssid_len); | 2291 | elems.ssid, elems.ssid_len); |
1944 | if (!bss) | 2292 | if (!bss) |
1945 | return; | 2293 | return; |
@@ -1952,8 +2300,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
1952 | #endif | 2300 | #endif |
1953 | } | 2301 | } |
1954 | 2302 | ||
1955 | if (bss->probe_resp && beacon) { | 2303 | bss->band = rx_status->band; |
1956 | /* Do not allow beacon to override data from Probe Response. */ | 2304 | |
2305 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | ||
2306 | bss->probe_resp && beacon) { | ||
2307 | /* STA mode: | ||
2308 | * Do not allow beacon to override data from Probe Response. */ | ||
1957 | ieee80211_rx_bss_put(dev, bss); | 2309 | ieee80211_rx_bss_put(dev, bss); |
1958 | return; | 2310 | return; |
1959 | } | 2311 | } |
@@ -2050,27 +2402,69 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2050 | bss->ht_ie_len = 0; | 2402 | bss->ht_ie_len = 0; |
2051 | } | 2403 | } |
2052 | 2404 | ||
2053 | bss->hw_mode = rx_status->phymode; | 2405 | bss->timestamp = beacon_timestamp; |
2054 | bss->freq = rx_status->freq; | ||
2055 | if (channel != rx_status->channel && | ||
2056 | (bss->hw_mode == MODE_IEEE80211G || | ||
2057 | bss->hw_mode == MODE_IEEE80211B) && | ||
2058 | channel >= 1 && channel <= 14) { | ||
2059 | static const int freq_list[] = { | ||
2060 | 2412, 2417, 2422, 2427, 2432, 2437, 2442, | ||
2061 | 2447, 2452, 2457, 2462, 2467, 2472, 2484 | ||
2062 | }; | ||
2063 | /* IEEE 802.11g/b mode can receive packets from neighboring | ||
2064 | * channels, so map the channel into frequency. */ | ||
2065 | bss->freq = freq_list[channel - 1]; | ||
2066 | } | ||
2067 | bss->timestamp = timestamp; | ||
2068 | bss->last_update = jiffies; | 2406 | bss->last_update = jiffies; |
2069 | bss->rssi = rx_status->ssi; | 2407 | bss->rssi = rx_status->ssi; |
2070 | bss->signal = rx_status->signal; | 2408 | bss->signal = rx_status->signal; |
2071 | bss->noise = rx_status->noise; | 2409 | bss->noise = rx_status->noise; |
2072 | if (!beacon) | 2410 | if (!beacon) |
2073 | bss->probe_resp++; | 2411 | bss->probe_resp++; |
2412 | |||
2413 | /* check if we need to merge IBSS */ | ||
2414 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && | ||
2415 | !local->sta_sw_scanning && !local->sta_hw_scanning && | ||
2416 | bss->capability & WLAN_CAPABILITY_IBSS && | ||
2417 | bss->freq == local->oper_channel->center_freq && | ||
2418 | elems.ssid_len == sdata->u.sta.ssid_len && | ||
2419 | memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { | ||
2420 | if (rx_status->flag & RX_FLAG_TSFT) { | ||
2421 | /* in order for correct IBSS merging we need mactime | ||
2422 | * | ||
2423 | * since mactime is defined as the time the first data | ||
2424 | * symbol of the frame hits the PHY, and the timestamp | ||
2425 | * of the beacon is defined as "the time that the data | ||
2426 | * symbol containing the first bit of the timestamp is | ||
2427 | * transmitted to the PHY plus the transmitting STA’s | ||
2428 | * delays through its local PHY from the MAC-PHY | ||
2429 | * interface to its interface with the WM" | ||
2430 | * (802.11 11.1.2) - equals the time this bit arrives at | ||
2431 | * the receiver - we have to take into account the | ||
2432 | * offset between the two. | ||
2433 | * e.g: at 1 MBit that means mactime is 192 usec earlier | ||
2434 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. | ||
2435 | */ | ||
2436 | int rate = local->hw.wiphy->bands[rx_status->band]-> | ||
2437 | bitrates[rx_status->rate_idx].bitrate; | ||
2438 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); | ||
2439 | } else if (local && local->ops && local->ops->get_tsf) | ||
2440 | /* second best option: get current TSF */ | ||
2441 | rx_timestamp = local->ops->get_tsf(local_to_hw(local)); | ||
2442 | else | ||
2443 | /* can't merge without knowing the TSF */ | ||
2444 | rx_timestamp = -1LLU; | ||
2445 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
2446 | printk(KERN_DEBUG "RX beacon SA=%s BSSID=" | ||
2447 | "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | ||
2448 | print_mac(mac, mgmt->sa), | ||
2449 | print_mac(mac2, mgmt->bssid), | ||
2450 | (unsigned long long)rx_timestamp, | ||
2451 | (unsigned long long)beacon_timestamp, | ||
2452 | (unsigned long long)(rx_timestamp - beacon_timestamp), | ||
2453 | jiffies); | ||
2454 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
2455 | if (beacon_timestamp > rx_timestamp) { | ||
2456 | #ifndef CONFIG_MAC80211_IBSS_DEBUG | ||
2457 | if (net_ratelimit()) | ||
2458 | #endif | ||
2459 | printk(KERN_DEBUG "%s: beacon TSF higher than " | ||
2460 | "local TSF - IBSS merge with BSSID %s\n", | ||
2461 | dev->name, print_mac(mac, mgmt->bssid)); | ||
2462 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | ||
2463 | ieee80211_ibss_add_sta(dev, NULL, | ||
2464 | mgmt->bssid, mgmt->sa); | ||
2465 | } | ||
2466 | } | ||
2467 | |||
2074 | ieee80211_rx_bss_put(dev, bss); | 2468 | ieee80211_rx_bss_put(dev, bss); |
2075 | } | 2469 | } |
2076 | 2470 | ||
@@ -2235,6 +2629,12 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
2235 | break; | 2629 | break; |
2236 | ieee80211_sta_process_addba_request(dev, mgmt, len); | 2630 | ieee80211_sta_process_addba_request(dev, mgmt, len); |
2237 | break; | 2631 | break; |
2632 | case WLAN_ACTION_ADDBA_RESP: | ||
2633 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
2634 | sizeof(mgmt->u.action.u.addba_resp))) | ||
2635 | break; | ||
2636 | ieee80211_sta_process_addba_resp(dev, mgmt, len); | ||
2637 | break; | ||
2238 | case WLAN_ACTION_DELBA: | 2638 | case WLAN_ACTION_DELBA: |
2239 | if (len < (IEEE80211_MIN_ACTION_SIZE + | 2639 | if (len < (IEEE80211_MIN_ACTION_SIZE + |
2240 | sizeof(mgmt->u.action.u.delba))) | 2640 | sizeof(mgmt->u.action.u.delba))) |
@@ -2348,7 +2748,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev, | |||
2348 | } | 2748 | } |
2349 | 2749 | ||
2350 | 2750 | ||
2351 | ieee80211_txrx_result | 2751 | ieee80211_rx_result |
2352 | ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, | 2752 | ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, |
2353 | struct ieee80211_rx_status *rx_status) | 2753 | struct ieee80211_rx_status *rx_status) |
2354 | { | 2754 | { |
@@ -2356,31 +2756,31 @@ ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, | |||
2356 | u16 fc; | 2756 | u16 fc; |
2357 | 2757 | ||
2358 | if (skb->len < 2) | 2758 | if (skb->len < 2) |
2359 | return TXRX_DROP; | 2759 | return RX_DROP_UNUSABLE; |
2360 | 2760 | ||
2361 | mgmt = (struct ieee80211_mgmt *) skb->data; | 2761 | mgmt = (struct ieee80211_mgmt *) skb->data; |
2362 | fc = le16_to_cpu(mgmt->frame_control); | 2762 | fc = le16_to_cpu(mgmt->frame_control); |
2363 | 2763 | ||
2364 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) | 2764 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) |
2365 | return TXRX_CONTINUE; | 2765 | return RX_CONTINUE; |
2366 | 2766 | ||
2367 | if (skb->len < 24) | 2767 | if (skb->len < 24) |
2368 | return TXRX_DROP; | 2768 | return RX_DROP_MONITOR; |
2369 | 2769 | ||
2370 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 2770 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { |
2371 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { | 2771 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { |
2372 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, | 2772 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, |
2373 | skb->len, rx_status); | 2773 | skb->len, rx_status); |
2374 | dev_kfree_skb(skb); | 2774 | dev_kfree_skb(skb); |
2375 | return TXRX_QUEUED; | 2775 | return RX_QUEUED; |
2376 | } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { | 2776 | } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { |
2377 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, | 2777 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, |
2378 | rx_status); | 2778 | rx_status); |
2379 | dev_kfree_skb(skb); | 2779 | dev_kfree_skb(skb); |
2380 | return TXRX_QUEUED; | 2780 | return RX_QUEUED; |
2381 | } | 2781 | } |
2382 | } | 2782 | } |
2383 | return TXRX_CONTINUE; | 2783 | return RX_CONTINUE; |
2384 | } | 2784 | } |
2385 | 2785 | ||
2386 | 2786 | ||
@@ -2629,7 +3029,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2629 | } | 3029 | } |
2630 | 3030 | ||
2631 | spin_lock_bh(&local->sta_bss_lock); | 3031 | spin_lock_bh(&local->sta_bss_lock); |
2632 | freq = local->oper_channel->freq; | 3032 | freq = local->oper_channel->center_freq; |
2633 | list_for_each_entry(bss, &local->sta_bss_list, list) { | 3033 | list_for_each_entry(bss, &local->sta_bss_list, list) { |
2634 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) | 3034 | if (!(bss->capability & WLAN_CAPABILITY_ESS)) |
2635 | continue; | 3035 | continue; |
@@ -2660,7 +3060,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2660 | spin_unlock_bh(&local->sta_bss_lock); | 3060 | spin_unlock_bh(&local->sta_bss_lock); |
2661 | 3061 | ||
2662 | if (selected) { | 3062 | if (selected) { |
2663 | ieee80211_set_channel(local, -1, selected->freq); | 3063 | ieee80211_set_freq(local, selected->freq); |
2664 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) | 3064 | if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) |
2665 | ieee80211_sta_set_ssid(dev, selected->ssid, | 3065 | ieee80211_sta_set_ssid(dev, selected->ssid, |
2666 | selected->ssid_len); | 3066 | selected->ssid_len); |
@@ -2684,162 +3084,6 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
2684 | return -1; | 3084 | return -1; |
2685 | } | 3085 | } |
2686 | 3086 | ||
2687 | static int ieee80211_sta_join_ibss(struct net_device *dev, | ||
2688 | struct ieee80211_if_sta *ifsta, | ||
2689 | struct ieee80211_sta_bss *bss) | ||
2690 | { | ||
2691 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2692 | int res, rates, i, j; | ||
2693 | struct sk_buff *skb; | ||
2694 | struct ieee80211_mgmt *mgmt; | ||
2695 | struct ieee80211_tx_control control; | ||
2696 | struct ieee80211_hw_mode *mode; | ||
2697 | struct rate_selection ratesel; | ||
2698 | u8 *pos; | ||
2699 | struct ieee80211_sub_if_data *sdata; | ||
2700 | |||
2701 | /* Remove possible STA entries from other IBSS networks. */ | ||
2702 | sta_info_flush(local, NULL); | ||
2703 | |||
2704 | if (local->ops->reset_tsf) { | ||
2705 | /* Reset own TSF to allow time synchronization work. */ | ||
2706 | local->ops->reset_tsf(local_to_hw(local)); | ||
2707 | } | ||
2708 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); | ||
2709 | res = ieee80211_if_config(dev); | ||
2710 | if (res) | ||
2711 | return res; | ||
2712 | |||
2713 | local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; | ||
2714 | |||
2715 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
2716 | sdata->drop_unencrypted = bss->capability & | ||
2717 | WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
2718 | |||
2719 | res = ieee80211_set_channel(local, -1, bss->freq); | ||
2720 | |||
2721 | if (!(local->oper_channel->flag & IEEE80211_CHAN_W_IBSS)) { | ||
2722 | printk(KERN_DEBUG "%s: IBSS not allowed on channel %d " | ||
2723 | "(%d MHz)\n", dev->name, local->hw.conf.channel, | ||
2724 | local->hw.conf.freq); | ||
2725 | return -1; | ||
2726 | } | ||
2727 | |||
2728 | /* Set beacon template based on scan results */ | ||
2729 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
2730 | do { | ||
2731 | if (!skb) | ||
2732 | break; | ||
2733 | |||
2734 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
2735 | |||
2736 | mgmt = (struct ieee80211_mgmt *) | ||
2737 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
2738 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
2739 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2740 | IEEE80211_STYPE_BEACON); | ||
2741 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
2742 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | ||
2743 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
2744 | mgmt->u.beacon.beacon_int = | ||
2745 | cpu_to_le16(local->hw.conf.beacon_int); | ||
2746 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
2747 | |||
2748 | pos = skb_put(skb, 2 + ifsta->ssid_len); | ||
2749 | *pos++ = WLAN_EID_SSID; | ||
2750 | *pos++ = ifsta->ssid_len; | ||
2751 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | ||
2752 | |||
2753 | rates = bss->supp_rates_len; | ||
2754 | if (rates > 8) | ||
2755 | rates = 8; | ||
2756 | pos = skb_put(skb, 2 + rates); | ||
2757 | *pos++ = WLAN_EID_SUPP_RATES; | ||
2758 | *pos++ = rates; | ||
2759 | memcpy(pos, bss->supp_rates, rates); | ||
2760 | |||
2761 | pos = skb_put(skb, 2 + 1); | ||
2762 | *pos++ = WLAN_EID_DS_PARAMS; | ||
2763 | *pos++ = 1; | ||
2764 | *pos++ = bss->channel; | ||
2765 | |||
2766 | pos = skb_put(skb, 2 + 2); | ||
2767 | *pos++ = WLAN_EID_IBSS_PARAMS; | ||
2768 | *pos++ = 2; | ||
2769 | /* FIX: set ATIM window based on scan results */ | ||
2770 | *pos++ = 0; | ||
2771 | *pos++ = 0; | ||
2772 | |||
2773 | if (bss->supp_rates_len > 8) { | ||
2774 | rates = bss->supp_rates_len - 8; | ||
2775 | pos = skb_put(skb, 2 + rates); | ||
2776 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
2777 | *pos++ = rates; | ||
2778 | memcpy(pos, &bss->supp_rates[8], rates); | ||
2779 | } | ||
2780 | |||
2781 | memset(&control, 0, sizeof(control)); | ||
2782 | rate_control_get_rate(dev, local->oper_hw_mode, skb, &ratesel); | ||
2783 | if (!ratesel.rate) { | ||
2784 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | ||
2785 | "for IBSS beacon\n", dev->name); | ||
2786 | break; | ||
2787 | } | ||
2788 | control.vif = &sdata->vif; | ||
2789 | control.tx_rate = | ||
2790 | (sdata->bss_conf.use_short_preamble && | ||
2791 | (ratesel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | ||
2792 | ratesel.rate->val2 : ratesel.rate->val; | ||
2793 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
2794 | control.power_level = local->hw.conf.power_level; | ||
2795 | control.flags |= IEEE80211_TXCTL_NO_ACK; | ||
2796 | control.retry_limit = 1; | ||
2797 | |||
2798 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | ||
2799 | if (ifsta->probe_resp) { | ||
2800 | mgmt = (struct ieee80211_mgmt *) | ||
2801 | ifsta->probe_resp->data; | ||
2802 | mgmt->frame_control = | ||
2803 | IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
2804 | IEEE80211_STYPE_PROBE_RESP); | ||
2805 | } else { | ||
2806 | printk(KERN_DEBUG "%s: Could not allocate ProbeResp " | ||
2807 | "template for IBSS\n", dev->name); | ||
2808 | } | ||
2809 | |||
2810 | if (local->ops->beacon_update && | ||
2811 | local->ops->beacon_update(local_to_hw(local), | ||
2812 | skb, &control) == 0) { | ||
2813 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | ||
2814 | "template based on scan results\n", dev->name); | ||
2815 | skb = NULL; | ||
2816 | } | ||
2817 | |||
2818 | rates = 0; | ||
2819 | mode = local->oper_hw_mode; | ||
2820 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
2821 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | ||
2822 | for (j = 0; j < mode->num_rates; j++) | ||
2823 | if (mode->rates[j].rate == bitrate) | ||
2824 | rates |= BIT(j); | ||
2825 | } | ||
2826 | ifsta->supp_rates_bits = rates; | ||
2827 | } while (0); | ||
2828 | |||
2829 | if (skb) { | ||
2830 | printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " | ||
2831 | "template\n", dev->name); | ||
2832 | dev_kfree_skb(skb); | ||
2833 | } | ||
2834 | |||
2835 | ifsta->state = IEEE80211_IBSS_JOINED; | ||
2836 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | ||
2837 | |||
2838 | ieee80211_rx_bss_put(dev, bss); | ||
2839 | |||
2840 | return res; | ||
2841 | } | ||
2842 | |||
2843 | 3087 | ||
2844 | static int ieee80211_sta_create_ibss(struct net_device *dev, | 3088 | static int ieee80211_sta_create_ibss(struct net_device *dev, |
2845 | struct ieee80211_if_sta *ifsta) | 3089 | struct ieee80211_if_sta *ifsta) |
@@ -2847,7 +3091,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
2847 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3091 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2848 | struct ieee80211_sta_bss *bss; | 3092 | struct ieee80211_sta_bss *bss; |
2849 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3093 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2850 | struct ieee80211_hw_mode *mode; | 3094 | struct ieee80211_supported_band *sband; |
2851 | u8 bssid[ETH_ALEN], *pos; | 3095 | u8 bssid[ETH_ALEN], *pos; |
2852 | int i; | 3096 | int i; |
2853 | DECLARE_MAC_BUF(mac); | 3097 | DECLARE_MAC_BUF(mac); |
@@ -2869,28 +3113,28 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
2869 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 3113 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", |
2870 | dev->name, print_mac(mac, bssid)); | 3114 | dev->name, print_mac(mac, bssid)); |
2871 | 3115 | ||
2872 | bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, | 3116 | bss = ieee80211_rx_bss_add(dev, bssid, |
3117 | local->hw.conf.channel->center_freq, | ||
2873 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); | 3118 | sdata->u.sta.ssid, sdata->u.sta.ssid_len); |
2874 | if (!bss) | 3119 | if (!bss) |
2875 | return -ENOMEM; | 3120 | return -ENOMEM; |
2876 | 3121 | ||
2877 | mode = local->oper_hw_mode; | 3122 | bss->band = local->hw.conf.channel->band; |
3123 | sband = local->hw.wiphy->bands[bss->band]; | ||
2878 | 3124 | ||
2879 | if (local->hw.conf.beacon_int == 0) | 3125 | if (local->hw.conf.beacon_int == 0) |
2880 | local->hw.conf.beacon_int = 100; | 3126 | local->hw.conf.beacon_int = 100; |
2881 | bss->beacon_int = local->hw.conf.beacon_int; | 3127 | bss->beacon_int = local->hw.conf.beacon_int; |
2882 | bss->hw_mode = local->hw.conf.phymode; | ||
2883 | bss->freq = local->hw.conf.freq; | ||
2884 | bss->last_update = jiffies; | 3128 | bss->last_update = jiffies; |
2885 | bss->capability = WLAN_CAPABILITY_IBSS; | 3129 | bss->capability = WLAN_CAPABILITY_IBSS; |
2886 | if (sdata->default_key) { | 3130 | if (sdata->default_key) { |
2887 | bss->capability |= WLAN_CAPABILITY_PRIVACY; | 3131 | bss->capability |= WLAN_CAPABILITY_PRIVACY; |
2888 | } else | 3132 | } else |
2889 | sdata->drop_unencrypted = 0; | 3133 | sdata->drop_unencrypted = 0; |
2890 | bss->supp_rates_len = mode->num_rates; | 3134 | bss->supp_rates_len = sband->n_bitrates; |
2891 | pos = bss->supp_rates; | 3135 | pos = bss->supp_rates; |
2892 | for (i = 0; i < mode->num_rates; i++) { | 3136 | for (i = 0; i < sband->n_bitrates; i++) { |
2893 | int rate = mode->rates[i].rate; | 3137 | int rate = sband->bitrates[i].bitrate; |
2894 | *pos++ = (u8) (rate / 5); | 3138 | *pos++ = (u8) (rate / 5); |
2895 | } | 3139 | } |
2896 | 3140 | ||
@@ -2939,7 +3183,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
2939 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3183 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); |
2940 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3184 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2941 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3185 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
2942 | (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, | 3186 | (bss = ieee80211_rx_bss_get(dev, bssid, |
3187 | local->hw.conf.channel->center_freq, | ||
2943 | ifsta->ssid, ifsta->ssid_len))) { | 3188 | ifsta->ssid, ifsta->ssid_len))) { |
2944 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 3189 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" |
2945 | " based on configured SSID\n", | 3190 | " based on configured SSID\n", |
@@ -2967,13 +3212,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
2967 | if (time_after(jiffies, ifsta->ibss_join_req + | 3212 | if (time_after(jiffies, ifsta->ibss_join_req + |
2968 | IEEE80211_IBSS_JOIN_TIMEOUT)) { | 3213 | IEEE80211_IBSS_JOIN_TIMEOUT)) { |
2969 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && | 3214 | if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && |
2970 | local->oper_channel->flag & IEEE80211_CHAN_W_IBSS) | 3215 | (!(local->oper_channel->flags & |
3216 | IEEE80211_CHAN_NO_IBSS))) | ||
2971 | return ieee80211_sta_create_ibss(dev, ifsta); | 3217 | return ieee80211_sta_create_ibss(dev, ifsta); |
2972 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { | 3218 | if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { |
2973 | printk(KERN_DEBUG "%s: IBSS not allowed on the" | 3219 | printk(KERN_DEBUG "%s: IBSS not allowed on" |
2974 | " configured channel %d (%d MHz)\n", | 3220 | " %d MHz\n", dev->name, |
2975 | dev->name, local->hw.conf.channel, | 3221 | local->hw.conf.channel->center_freq); |
2976 | local->hw.conf.freq); | ||
2977 | } | 3222 | } |
2978 | 3223 | ||
2979 | /* No IBSS found - decrease scan interval and continue | 3224 | /* No IBSS found - decrease scan interval and continue |
@@ -2992,7 +3237,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
2992 | 3237 | ||
2993 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | 3238 | int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) |
2994 | { | 3239 | { |
2995 | struct ieee80211_sub_if_data *sdata; | 3240 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2996 | struct ieee80211_if_sta *ifsta; | 3241 | struct ieee80211_if_sta *ifsta; |
2997 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 3242 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2998 | 3243 | ||
@@ -3006,18 +3251,23 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3006 | int i; | 3251 | int i; |
3007 | 3252 | ||
3008 | memset(&qparam, 0, sizeof(qparam)); | 3253 | memset(&qparam, 0, sizeof(qparam)); |
3009 | /* TODO: are these ok defaults for all hw_modes? */ | 3254 | |
3010 | qparam.aifs = 2; | 3255 | qparam.aifs = 2; |
3011 | qparam.cw_min = | 3256 | |
3012 | local->hw.conf.phymode == MODE_IEEE80211B ? 31 : 15; | 3257 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
3258 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)) | ||
3259 | qparam.cw_min = 31; | ||
3260 | else | ||
3261 | qparam.cw_min = 15; | ||
3262 | |||
3013 | qparam.cw_max = 1023; | 3263 | qparam.cw_max = 1023; |
3014 | qparam.burst_time = 0; | 3264 | qparam.txop = 0; |
3265 | |||
3015 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) | 3266 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) |
3016 | { | ||
3017 | local->ops->conf_tx(local_to_hw(local), | 3267 | local->ops->conf_tx(local_to_hw(local), |
3018 | i + IEEE80211_TX_QUEUE_DATA0, | 3268 | i + IEEE80211_TX_QUEUE_DATA0, |
3019 | &qparam); | 3269 | &qparam); |
3020 | } | 3270 | |
3021 | /* IBSS uses different parameters for Beacon sending */ | 3271 | /* IBSS uses different parameters for Beacon sending */ |
3022 | qparam.cw_min++; | 3272 | qparam.cw_min++; |
3023 | qparam.cw_min *= 2; | 3273 | qparam.cw_min *= 2; |
@@ -3026,7 +3276,6 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
3026 | IEEE80211_TX_QUEUE_BEACON, &qparam); | 3276 | IEEE80211_TX_QUEUE_BEACON, &qparam); |
3027 | } | 3277 | } |
3028 | 3278 | ||
3029 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
3030 | ifsta = &sdata->u.sta; | 3279 | ifsta = &sdata->u.sta; |
3031 | 3280 | ||
3032 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3281 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) |
@@ -3185,7 +3434,7 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3185 | container_of(work, struct ieee80211_local, scan_work.work); | 3434 | container_of(work, struct ieee80211_local, scan_work.work); |
3186 | struct net_device *dev = local->scan_dev; | 3435 | struct net_device *dev = local->scan_dev; |
3187 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3436 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3188 | struct ieee80211_hw_mode *mode; | 3437 | struct ieee80211_supported_band *sband; |
3189 | struct ieee80211_channel *chan; | 3438 | struct ieee80211_channel *chan; |
3190 | int skip; | 3439 | int skip; |
3191 | unsigned long next_delay = 0; | 3440 | unsigned long next_delay = 0; |
@@ -3195,44 +3444,59 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3195 | 3444 | ||
3196 | switch (local->scan_state) { | 3445 | switch (local->scan_state) { |
3197 | case SCAN_SET_CHANNEL: | 3446 | case SCAN_SET_CHANNEL: |
3198 | mode = local->scan_hw_mode; | 3447 | /* |
3199 | if (local->scan_hw_mode->list.next == &local->modes_list && | 3448 | * Get current scan band. scan_band may be IEEE80211_NUM_BANDS |
3200 | local->scan_channel_idx >= mode->num_channels) { | 3449 | * after we successfully scanned the last channel of the last |
3450 | * band (and the last band is supported by the hw) | ||
3451 | */ | ||
3452 | if (local->scan_band < IEEE80211_NUM_BANDS) | ||
3453 | sband = local->hw.wiphy->bands[local->scan_band]; | ||
3454 | else | ||
3455 | sband = NULL; | ||
3456 | |||
3457 | /* | ||
3458 | * If we are at an unsupported band and have more bands | ||
3459 | * left to scan, advance to the next supported one. | ||
3460 | */ | ||
3461 | while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) { | ||
3462 | local->scan_band++; | ||
3463 | sband = local->hw.wiphy->bands[local->scan_band]; | ||
3464 | local->scan_channel_idx = 0; | ||
3465 | } | ||
3466 | |||
3467 | /* if no more bands/channels left, complete scan */ | ||
3468 | if (!sband || local->scan_channel_idx >= sband->n_channels) { | ||
3201 | ieee80211_scan_completed(local_to_hw(local)); | 3469 | ieee80211_scan_completed(local_to_hw(local)); |
3202 | return; | 3470 | return; |
3203 | } | 3471 | } |
3204 | skip = !(local->enabled_modes & (1 << mode->mode)); | 3472 | skip = 0; |
3205 | chan = &mode->channels[local->scan_channel_idx]; | 3473 | chan = &sband->channels[local->scan_channel_idx]; |
3206 | if (!(chan->flag & IEEE80211_CHAN_W_SCAN) || | 3474 | |
3475 | if (chan->flags & IEEE80211_CHAN_DISABLED || | ||
3207 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3476 | (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
3208 | !(chan->flag & IEEE80211_CHAN_W_IBSS)) || | 3477 | chan->flags & IEEE80211_CHAN_NO_IBSS)) |
3209 | (local->hw_modes & local->enabled_modes & | ||
3210 | (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B)) | ||
3211 | skip = 1; | 3478 | skip = 1; |
3212 | 3479 | ||
3213 | if (!skip) { | 3480 | if (!skip) { |
3214 | #if 0 | ||
3215 | printk(KERN_DEBUG "%s: scan channel %d (%d MHz)\n", | ||
3216 | dev->name, chan->chan, chan->freq); | ||
3217 | #endif | ||
3218 | |||
3219 | local->scan_channel = chan; | 3481 | local->scan_channel = chan; |
3220 | if (ieee80211_hw_config(local)) { | 3482 | if (ieee80211_hw_config(local)) { |
3221 | printk(KERN_DEBUG "%s: failed to set channel " | 3483 | printk(KERN_DEBUG "%s: failed to set freq to " |
3222 | "%d (%d MHz) for scan\n", dev->name, | 3484 | "%d MHz for scan\n", dev->name, |
3223 | chan->chan, chan->freq); | 3485 | chan->center_freq); |
3224 | skip = 1; | 3486 | skip = 1; |
3225 | } | 3487 | } |
3226 | } | 3488 | } |
3227 | 3489 | ||
3490 | /* advance state machine to next channel/band */ | ||
3228 | local->scan_channel_idx++; | 3491 | local->scan_channel_idx++; |
3229 | if (local->scan_channel_idx >= local->scan_hw_mode->num_channels) { | 3492 | if (local->scan_channel_idx >= sband->n_channels) { |
3230 | if (local->scan_hw_mode->list.next != &local->modes_list) { | 3493 | /* |
3231 | local->scan_hw_mode = list_entry(local->scan_hw_mode->list.next, | 3494 | * scan_band may end up == IEEE80211_NUM_BANDS, but |
3232 | struct ieee80211_hw_mode, | 3495 | * we'll catch that case above and complete the scan |
3233 | list); | 3496 | * if that is the case. |
3234 | local->scan_channel_idx = 0; | 3497 | */ |
3235 | } | 3498 | local->scan_band++; |
3499 | local->scan_channel_idx = 0; | ||
3236 | } | 3500 | } |
3237 | 3501 | ||
3238 | if (skip) | 3502 | if (skip) |
@@ -3243,13 +3507,14 @@ void ieee80211_sta_scan_work(struct work_struct *work) | |||
3243 | local->scan_state = SCAN_SEND_PROBE; | 3507 | local->scan_state = SCAN_SEND_PROBE; |
3244 | break; | 3508 | break; |
3245 | case SCAN_SEND_PROBE: | 3509 | case SCAN_SEND_PROBE: |
3246 | if (local->scan_channel->flag & IEEE80211_CHAN_W_ACTIVE_SCAN) { | 3510 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; |
3247 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3248 | local->scan_ssid_len); | ||
3249 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3250 | } else | ||
3251 | next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; | ||
3252 | local->scan_state = SCAN_SET_CHANNEL; | 3511 | local->scan_state = SCAN_SET_CHANNEL; |
3512 | |||
3513 | if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
3514 | break; | ||
3515 | ieee80211_send_probe_req(dev, NULL, local->scan_ssid, | ||
3516 | local->scan_ssid_len); | ||
3517 | next_delay = IEEE80211_CHANNEL_TIME; | ||
3253 | break; | 3518 | break; |
3254 | } | 3519 | } |
3255 | 3520 | ||
@@ -3324,10 +3589,8 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
3324 | } else | 3589 | } else |
3325 | local->scan_ssid_len = 0; | 3590 | local->scan_ssid_len = 0; |
3326 | local->scan_state = SCAN_SET_CHANNEL; | 3591 | local->scan_state = SCAN_SET_CHANNEL; |
3327 | local->scan_hw_mode = list_entry(local->modes_list.next, | ||
3328 | struct ieee80211_hw_mode, | ||
3329 | list); | ||
3330 | local->scan_channel_idx = 0; | 3592 | local->scan_channel_idx = 0; |
3593 | local->scan_band = IEEE80211_BAND_2GHZ; | ||
3331 | local->scan_dev = dev; | 3594 | local->scan_dev = dev; |
3332 | 3595 | ||
3333 | netif_tx_lock_bh(local->mdev); | 3596 | netif_tx_lock_bh(local->mdev); |
@@ -3382,9 +3645,6 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3382 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) | 3645 | bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) |
3383 | return current_ev; | 3646 | return current_ev; |
3384 | 3647 | ||
3385 | if (!(local->enabled_modes & (1 << bss->hw_mode))) | ||
3386 | return current_ev; | ||
3387 | |||
3388 | memset(&iwe, 0, sizeof(iwe)); | 3648 | memset(&iwe, 0, sizeof(iwe)); |
3389 | iwe.cmd = SIOCGIWAP; | 3649 | iwe.cmd = SIOCGIWAP; |
3390 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 3650 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
@@ -3412,12 +3672,15 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
3412 | 3672 | ||
3413 | memset(&iwe, 0, sizeof(iwe)); | 3673 | memset(&iwe, 0, sizeof(iwe)); |
3414 | iwe.cmd = SIOCGIWFREQ; | 3674 | iwe.cmd = SIOCGIWFREQ; |
3415 | iwe.u.freq.m = bss->channel; | 3675 | iwe.u.freq.m = bss->freq; |
3416 | iwe.u.freq.e = 0; | 3676 | iwe.u.freq.e = 6; |
3417 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3677 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3418 | IW_EV_FREQ_LEN); | 3678 | IW_EV_FREQ_LEN); |
3419 | iwe.u.freq.m = bss->freq * 100000; | 3679 | |
3420 | iwe.u.freq.e = 1; | 3680 | memset(&iwe, 0, sizeof(iwe)); |
3681 | iwe.cmd = SIOCGIWFREQ; | ||
3682 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | ||
3683 | iwe.u.freq.e = 0; | ||
3421 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 3684 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
3422 | IW_EV_FREQ_LEN); | 3685 | IW_EV_FREQ_LEN); |
3423 | 3686 | ||
@@ -3557,10 +3820,13 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
3557 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 3820 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
3558 | 3821 | ||
3559 | sta = sta_info_add(local, dev, addr, GFP_ATOMIC); | 3822 | sta = sta_info_add(local, dev, addr, GFP_ATOMIC); |
3560 | if (!sta) | 3823 | if (IS_ERR(sta)) |
3561 | return NULL; | 3824 | return NULL; |
3562 | 3825 | ||
3563 | sta->supp_rates = sdata->u.sta.supp_rates_bits; | 3826 | sta->flags |= WLAN_STA_AUTHORIZED; |
3827 | |||
3828 | sta->supp_rates[local->hw.conf.channel->band] = | ||
3829 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | ||
3564 | 3830 | ||
3565 | rate_control_rate_init(sta, local); | 3831 | rate_control_rate_init(sta, local); |
3566 | 3832 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index ed57fb8e82fc..eac9c59dbc4d 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/etherdevice.h> | 13 | #include <linux/etherdevice.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/rcupdate.h> | 15 | #include <linux/rcupdate.h> |
16 | #include <linux/rtnetlink.h> | ||
16 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
17 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
18 | #include "debugfs_key.h" | 19 | #include "debugfs_key.h" |
@@ -34,6 +35,10 @@ | |||
34 | * | 35 | * |
35 | * All operations here are called under RTNL so no extra locking is | 36 | * All operations here are called under RTNL so no extra locking is |
36 | * required. | 37 | * required. |
38 | * | ||
39 | * NOTE: This code requires that sta info *destruction* is done under | ||
40 | * RTNL, otherwise it can try to access already freed STA structs | ||
41 | * when a STA key is being freed. | ||
37 | */ | 42 | */ |
38 | 43 | ||
39 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 44 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
@@ -84,16 +89,25 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
84 | key->conf.keyidx, print_mac(mac, addr), ret); | 89 | key->conf.keyidx, print_mac(mac, addr), ret); |
85 | } | 90 | } |
86 | 91 | ||
92 | static void ieee80211_key_mark_hw_accel_off(struct ieee80211_key *key) | ||
93 | { | ||
94 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | ||
95 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
96 | key->flags |= KEY_FLAG_REMOVE_FROM_HARDWARE; | ||
97 | } | ||
98 | } | ||
99 | |||
87 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | 100 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) |
88 | { | 101 | { |
89 | const u8 *addr; | 102 | const u8 *addr; |
90 | int ret; | 103 | int ret; |
91 | DECLARE_MAC_BUF(mac); | 104 | DECLARE_MAC_BUF(mac); |
92 | 105 | ||
93 | if (!key->local->ops->set_key) | 106 | if (!key || !key->local->ops->set_key) |
94 | return; | 107 | return; |
95 | 108 | ||
96 | if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 109 | if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
110 | !(key->flags & KEY_FLAG_REMOVE_FROM_HARDWARE)) | ||
97 | return; | 111 | return; |
98 | 112 | ||
99 | addr = get_mac_for_key(key); | 113 | addr = get_mac_for_key(key); |
@@ -108,12 +122,11 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
108 | wiphy_name(key->local->hw.wiphy), | 122 | wiphy_name(key->local->hw.wiphy), |
109 | key->conf.keyidx, print_mac(mac, addr), ret); | 123 | key->conf.keyidx, print_mac(mac, addr), ret); |
110 | 124 | ||
111 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 125 | key->flags &= ~(KEY_FLAG_UPLOADED_TO_HARDWARE | |
126 | KEY_FLAG_REMOVE_FROM_HARDWARE); | ||
112 | } | 127 | } |
113 | 128 | ||
114 | struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | 129 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, |
115 | struct sta_info *sta, | ||
116 | enum ieee80211_key_alg alg, | ||
117 | int idx, | 130 | int idx, |
118 | size_t key_len, | 131 | size_t key_len, |
119 | const u8 *key_data) | 132 | const u8 *key_data) |
@@ -137,10 +150,7 @@ struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | |||
137 | key->conf.keyidx = idx; | 150 | key->conf.keyidx = idx; |
138 | key->conf.keylen = key_len; | 151 | key->conf.keylen = key_len; |
139 | memcpy(key->conf.key, key_data, key_len); | 152 | memcpy(key->conf.key, key_data, key_len); |
140 | 153 | INIT_LIST_HEAD(&key->list); | |
141 | key->local = sdata->local; | ||
142 | key->sdata = sdata; | ||
143 | key->sta = sta; | ||
144 | 154 | ||
145 | if (alg == ALG_CCMP) { | 155 | if (alg == ALG_CCMP) { |
146 | /* | 156 | /* |
@@ -154,13 +164,68 @@ struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | |||
154 | } | 164 | } |
155 | } | 165 | } |
156 | 166 | ||
157 | ieee80211_debugfs_key_add(key->local, key); | 167 | return key; |
168 | } | ||
158 | 169 | ||
159 | /* remove key first */ | 170 | static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, |
160 | if (sta) | 171 | struct sta_info *sta, |
161 | ieee80211_key_free(sta->key); | 172 | struct ieee80211_key *key, |
162 | else | 173 | struct ieee80211_key *new) |
163 | ieee80211_key_free(sdata->keys[idx]); | 174 | { |
175 | int idx, defkey; | ||
176 | |||
177 | if (sta) { | ||
178 | rcu_assign_pointer(sta->key, new); | ||
179 | } else { | ||
180 | WARN_ON(new && key && new->conf.keyidx != key->conf.keyidx); | ||
181 | |||
182 | if (key) | ||
183 | idx = key->conf.keyidx; | ||
184 | else | ||
185 | idx = new->conf.keyidx; | ||
186 | |||
187 | defkey = key && sdata->default_key == key; | ||
188 | |||
189 | if (defkey && !new) | ||
190 | ieee80211_set_default_key(sdata, -1); | ||
191 | |||
192 | rcu_assign_pointer(sdata->keys[idx], new); | ||
193 | if (new) | ||
194 | list_add(&new->list, &sdata->key_list); | ||
195 | |||
196 | if (defkey && new) | ||
197 | ieee80211_set_default_key(sdata, new->conf.keyidx); | ||
198 | } | ||
199 | |||
200 | if (key) { | ||
201 | ieee80211_key_mark_hw_accel_off(key); | ||
202 | /* | ||
203 | * We'll use an empty list to indicate that the key | ||
204 | * has already been removed. | ||
205 | */ | ||
206 | list_del_init(&key->list); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | void ieee80211_key_link(struct ieee80211_key *key, | ||
211 | struct ieee80211_sub_if_data *sdata, | ||
212 | struct sta_info *sta) | ||
213 | { | ||
214 | struct ieee80211_key *old_key; | ||
215 | int idx; | ||
216 | |||
217 | ASSERT_RTNL(); | ||
218 | might_sleep(); | ||
219 | |||
220 | BUG_ON(!sdata); | ||
221 | BUG_ON(!key); | ||
222 | |||
223 | idx = key->conf.keyidx; | ||
224 | key->local = sdata->local; | ||
225 | key->sdata = sdata; | ||
226 | key->sta = sta; | ||
227 | |||
228 | ieee80211_debugfs_key_add(key->local, key); | ||
164 | 229 | ||
165 | if (sta) { | 230 | if (sta) { |
166 | ieee80211_debugfs_key_sta_link(key, sta); | 231 | ieee80211_debugfs_key_sta_link(key, sta); |
@@ -186,50 +251,59 @@ struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | |||
186 | } | 251 | } |
187 | } | 252 | } |
188 | 253 | ||
189 | /* enable hwaccel if appropriate */ | ||
190 | if (netif_running(key->sdata->dev)) | ||
191 | ieee80211_key_enable_hw_accel(key); | ||
192 | |||
193 | if (sta) | 254 | if (sta) |
194 | rcu_assign_pointer(sta->key, key); | 255 | old_key = sta->key; |
195 | else | 256 | else |
196 | rcu_assign_pointer(sdata->keys[idx], key); | 257 | old_key = sdata->keys[idx]; |
197 | 258 | ||
198 | list_add(&key->list, &sdata->key_list); | 259 | __ieee80211_key_replace(sdata, sta, old_key, key); |
199 | 260 | ||
200 | return key; | 261 | if (old_key) { |
262 | synchronize_rcu(); | ||
263 | ieee80211_key_free(old_key); | ||
264 | } | ||
265 | |||
266 | if (netif_running(sdata->dev)) | ||
267 | ieee80211_key_enable_hw_accel(key); | ||
201 | } | 268 | } |
202 | 269 | ||
203 | void ieee80211_key_free(struct ieee80211_key *key) | 270 | void ieee80211_key_free(struct ieee80211_key *key) |
204 | { | 271 | { |
272 | ASSERT_RTNL(); | ||
273 | might_sleep(); | ||
274 | |||
205 | if (!key) | 275 | if (!key) |
206 | return; | 276 | return; |
207 | 277 | ||
208 | if (key->sta) { | 278 | if (key->sdata) { |
209 | rcu_assign_pointer(key->sta->key, NULL); | 279 | /* |
210 | } else { | 280 | * Replace key with nothingness. |
211 | if (key->sdata->default_key == key) | 281 | * |
212 | ieee80211_set_default_key(key->sdata, -1); | 282 | * Because other code may have key reference (RCU protected) |
213 | if (key->conf.keyidx >= 0 && | 283 | * right now, we then wait for a grace period before freeing |
214 | key->conf.keyidx < NUM_DEFAULT_KEYS) | 284 | * it. |
215 | rcu_assign_pointer(key->sdata->keys[key->conf.keyidx], | 285 | * An empty list indicates it was never added to the key list |
216 | NULL); | 286 | * or has been removed already. It may, however, still be in |
217 | else | 287 | * hardware for acceleration. |
218 | WARN_ON(1); | 288 | */ |
219 | } | 289 | if (!list_empty(&key->list)) |
290 | __ieee80211_key_replace(key->sdata, key->sta, | ||
291 | key, NULL); | ||
220 | 292 | ||
221 | /* wait for all key users to complete */ | 293 | synchronize_rcu(); |
222 | synchronize_rcu(); | ||
223 | 294 | ||
224 | /* remove from hwaccel if appropriate */ | 295 | /* |
225 | ieee80211_key_disable_hw_accel(key); | 296 | * Remove from hwaccel if appropriate, this will |
297 | * only happen when the key is actually unlinked, | ||
298 | * it will already be done when the key was replaced. | ||
299 | */ | ||
300 | ieee80211_key_disable_hw_accel(key); | ||
301 | } | ||
226 | 302 | ||
227 | if (key->conf.alg == ALG_CCMP) | 303 | if (key->conf.alg == ALG_CCMP) |
228 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 304 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
229 | ieee80211_debugfs_key_remove(key); | 305 | ieee80211_debugfs_key_remove(key); |
230 | 306 | ||
231 | list_del(&key->list); | ||
232 | |||
233 | kfree(key); | 307 | kfree(key); |
234 | } | 308 | } |
235 | 309 | ||
@@ -253,6 +327,10 @@ void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) | |||
253 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) | 327 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata) |
254 | { | 328 | { |
255 | struct ieee80211_key *key, *tmp; | 329 | struct ieee80211_key *key, *tmp; |
330 | LIST_HEAD(tmp_list); | ||
331 | |||
332 | ASSERT_RTNL(); | ||
333 | might_sleep(); | ||
256 | 334 | ||
257 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) | 335 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) |
258 | ieee80211_key_free(key); | 336 | ieee80211_key_free(key); |
@@ -262,8 +340,10 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
262 | { | 340 | { |
263 | struct ieee80211_key *key; | 341 | struct ieee80211_key *key; |
264 | 342 | ||
265 | WARN_ON(!netif_running(sdata->dev)); | 343 | ASSERT_RTNL(); |
266 | if (!netif_running(sdata->dev)) | 344 | might_sleep(); |
345 | |||
346 | if (WARN_ON(!netif_running(sdata->dev))) | ||
267 | return; | 347 | return; |
268 | 348 | ||
269 | list_for_each_entry(key, &sdata->key_list, list) | 349 | list_for_each_entry(key, &sdata->key_list, list) |
@@ -274,6 +354,9 @@ void ieee80211_disable_keys(struct ieee80211_sub_if_data *sdata) | |||
274 | { | 354 | { |
275 | struct ieee80211_key *key; | 355 | struct ieee80211_key *key; |
276 | 356 | ||
357 | ASSERT_RTNL(); | ||
358 | might_sleep(); | ||
359 | |||
277 | list_for_each_entry(key, &sdata->key_list, list) | 360 | list_for_each_entry(key, &sdata->key_list, list) |
278 | ieee80211_key_disable_hw_accel(key); | 361 | ieee80211_key_disable_hw_accel(key); |
279 | } | 362 | } |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index c339571632b2..9762803e4876 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
4 | * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de> | 4 | * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de> |
5 | * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it> | 5 | * Copyright 2007-2008, Stefano Brivio <stefano.brivio@polimi.it> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -64,71 +64,66 @@ | |||
64 | */ | 64 | */ |
65 | 65 | ||
66 | 66 | ||
67 | /* Shift the adjustment so that we won't switch to a lower rate if it exhibited | 67 | /* Adjust the rate while ensuring that we won't switch to a lower rate if it |
68 | * a worse failed frames behaviour and we'll choose the highest rate whose | 68 | * exhibited a worse failed frames behaviour and we'll choose the highest rate |
69 | * failed frames behaviour is not worse than the one of the original rate | 69 | * whose failed frames behaviour is not worse than the one of the original rate |
70 | * target. While at it, check that the adjustment is within the ranges. Then, | 70 | * target. While at it, check that the new rate is valid. */ |
71 | * provide the new rate index. */ | ||
72 | static int rate_control_pid_shift_adjust(struct rc_pid_rateinfo *r, | ||
73 | int adj, int cur, int l) | ||
74 | { | ||
75 | int i, j, k, tmp; | ||
76 | |||
77 | j = r[cur].rev_index; | ||
78 | i = j + adj; | ||
79 | |||
80 | if (i < 0) | ||
81 | return r[0].index; | ||
82 | if (i >= l - 1) | ||
83 | return r[l - 1].index; | ||
84 | |||
85 | tmp = i; | ||
86 | |||
87 | if (adj < 0) { | ||
88 | for (k = j; k >= i; k--) | ||
89 | if (r[k].diff <= r[j].diff) | ||
90 | tmp = k; | ||
91 | } else { | ||
92 | for (k = i + 1; k + i < l; k++) | ||
93 | if (r[k].diff <= r[i].diff) | ||
94 | tmp = k; | ||
95 | } | ||
96 | |||
97 | return r[tmp].index; | ||
98 | } | ||
99 | |||
100 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, | 71 | static void rate_control_pid_adjust_rate(struct ieee80211_local *local, |
101 | struct sta_info *sta, int adj, | 72 | struct sta_info *sta, int adj, |
102 | struct rc_pid_rateinfo *rinfo) | 73 | struct rc_pid_rateinfo *rinfo) |
103 | { | 74 | { |
104 | struct ieee80211_sub_if_data *sdata; | 75 | struct ieee80211_sub_if_data *sdata; |
105 | struct ieee80211_hw_mode *mode; | 76 | struct ieee80211_supported_band *sband; |
106 | int newidx; | 77 | int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; |
107 | int maxrate; | 78 | int cur = sta->txrate_idx; |
108 | int back = (adj > 0) ? 1 : -1; | ||
109 | 79 | ||
110 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 80 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
81 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
82 | band = sband->band; | ||
83 | n_bitrates = sband->n_bitrates; | ||
111 | 84 | ||
112 | mode = local->oper_hw_mode; | 85 | /* Map passed arguments to sorted values. */ |
113 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 86 | cur_sorted = rinfo[cur].rev_index; |
87 | new_sorted = cur_sorted + adj; | ||
114 | 88 | ||
115 | newidx = rate_control_pid_shift_adjust(rinfo, adj, sta->txrate, | 89 | /* Check limits. */ |
116 | mode->num_rates); | 90 | if (new_sorted < 0) |
91 | new_sorted = rinfo[0].rev_index; | ||
92 | else if (new_sorted >= n_bitrates) | ||
93 | new_sorted = rinfo[n_bitrates - 1].rev_index; | ||
117 | 94 | ||
118 | while (newidx != sta->txrate) { | 95 | tmp = new_sorted; |
119 | if (rate_supported(sta, mode, newidx) && | ||
120 | (maxrate < 0 || newidx <= maxrate)) { | ||
121 | sta->txrate = newidx; | ||
122 | break; | ||
123 | } | ||
124 | 96 | ||
125 | newidx += back; | 97 | if (adj < 0) { |
98 | /* Ensure that the rate decrease isn't disadvantageous. */ | ||
99 | for (probe = cur_sorted; probe >= new_sorted; probe--) | ||
100 | if (rinfo[probe].diff <= rinfo[cur_sorted].diff && | ||
101 | rate_supported(sta, band, rinfo[probe].index)) | ||
102 | tmp = probe; | ||
103 | } else { | ||
104 | /* Look for rate increase with zero (or below) cost. */ | ||
105 | for (probe = new_sorted + 1; probe < n_bitrates; probe++) | ||
106 | if (rinfo[probe].diff <= rinfo[new_sorted].diff && | ||
107 | rate_supported(sta, band, rinfo[probe].index)) | ||
108 | tmp = probe; | ||
126 | } | 109 | } |
127 | 110 | ||
111 | /* Fit the rate found to the nearest supported rate. */ | ||
112 | do { | ||
113 | if (rate_supported(sta, band, rinfo[tmp].index)) { | ||
114 | sta->txrate_idx = rinfo[tmp].index; | ||
115 | break; | ||
116 | } | ||
117 | if (adj < 0) | ||
118 | tmp--; | ||
119 | else | ||
120 | tmp++; | ||
121 | } while (tmp < n_bitrates && tmp >= 0); | ||
122 | |||
128 | #ifdef CONFIG_MAC80211_DEBUGFS | 123 | #ifdef CONFIG_MAC80211_DEBUGFS |
129 | rate_control_pid_event_rate_change( | 124 | rate_control_pid_event_rate_change( |
130 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, | 125 | &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, |
131 | newidx, mode->rates[newidx].rate); | 126 | sta->txrate_idx, sband->bitrates[sta->txrate_idx].bitrate); |
132 | #endif | 127 | #endif |
133 | } | 128 | } |
134 | 129 | ||
@@ -155,7 +150,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
155 | { | 150 | { |
156 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; | 151 | struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv; |
157 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; | 152 | struct rc_pid_rateinfo *rinfo = pinfo->rinfo; |
158 | struct ieee80211_hw_mode *mode; | 153 | struct ieee80211_supported_band *sband; |
159 | u32 pf; | 154 | u32 pf; |
160 | s32 err_avg; | 155 | s32 err_avg; |
161 | u32 err_prop; | 156 | u32 err_prop; |
@@ -164,7 +159,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
164 | int adj, i, j, tmp; | 159 | int adj, i, j, tmp; |
165 | unsigned long period; | 160 | unsigned long period; |
166 | 161 | ||
167 | mode = local->oper_hw_mode; | 162 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
168 | spinfo = sta->rate_ctrl_priv; | 163 | spinfo = sta->rate_ctrl_priv; |
169 | 164 | ||
170 | /* In case nothing happened during the previous control interval, turn | 165 | /* In case nothing happened during the previous control interval, turn |
@@ -190,18 +185,18 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
190 | spinfo->tx_num_failed = 0; | 185 | spinfo->tx_num_failed = 0; |
191 | 186 | ||
192 | /* If we just switched rate, update the rate behaviour info. */ | 187 | /* If we just switched rate, update the rate behaviour info. */ |
193 | if (pinfo->oldrate != sta->txrate) { | 188 | if (pinfo->oldrate != sta->txrate_idx) { |
194 | 189 | ||
195 | i = rinfo[pinfo->oldrate].rev_index; | 190 | i = rinfo[pinfo->oldrate].rev_index; |
196 | j = rinfo[sta->txrate].rev_index; | 191 | j = rinfo[sta->txrate_idx].rev_index; |
197 | 192 | ||
198 | tmp = (pf - spinfo->last_pf); | 193 | tmp = (pf - spinfo->last_pf); |
199 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); | 194 | tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); |
200 | 195 | ||
201 | rinfo[j].diff = rinfo[i].diff + tmp; | 196 | rinfo[j].diff = rinfo[i].diff + tmp; |
202 | pinfo->oldrate = sta->txrate; | 197 | pinfo->oldrate = sta->txrate_idx; |
203 | } | 198 | } |
204 | rate_control_pid_normalize(pinfo, mode->num_rates); | 199 | rate_control_pid_normalize(pinfo, sband->n_bitrates); |
205 | 200 | ||
206 | /* Compute the proportional, integral and derivative errors. */ | 201 | /* Compute the proportional, integral and derivative errors. */ |
207 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; | 202 | err_prop = (pinfo->target << RC_PID_ARITH_SHIFT) - pf; |
@@ -242,8 +237,10 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
242 | struct sta_info *sta; | 237 | struct sta_info *sta; |
243 | struct rc_pid_sta_info *spinfo; | 238 | struct rc_pid_sta_info *spinfo; |
244 | unsigned long period; | 239 | unsigned long period; |
240 | struct ieee80211_supported_band *sband; | ||
245 | 241 | ||
246 | sta = sta_info_get(local, hdr->addr1); | 242 | sta = sta_info_get(local, hdr->addr1); |
243 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
247 | 244 | ||
248 | if (!sta) | 245 | if (!sta) |
249 | return; | 246 | return; |
@@ -251,13 +248,13 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
251 | /* Don't update the state if we're not controlling the rate. */ | 248 | /* Don't update the state if we're not controlling the rate. */ |
252 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 249 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
253 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 250 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { |
254 | sta->txrate = sdata->bss->max_ratectrl_rateidx; | 251 | sta->txrate_idx = sdata->bss->max_ratectrl_rateidx; |
255 | return; | 252 | return; |
256 | } | 253 | } |
257 | 254 | ||
258 | /* Ignore all frames that were sent with a different rate than the rate | 255 | /* Ignore all frames that were sent with a different rate than the rate |
259 | * we currently advise mac80211 to use. */ | 256 | * we currently advise mac80211 to use. */ |
260 | if (status->control.rate != &local->oper_hw_mode->rates[sta->txrate]) | 257 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) |
261 | goto ignore; | 258 | goto ignore; |
262 | 259 | ||
263 | spinfo = sta->rate_ctrl_priv; | 260 | spinfo = sta->rate_ctrl_priv; |
@@ -283,9 +280,6 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
283 | sta->tx_num_consecutive_failures++; | 280 | sta->tx_num_consecutive_failures++; |
284 | sta->tx_num_mpdu_fail++; | 281 | sta->tx_num_mpdu_fail++; |
285 | } else { | 282 | } else { |
286 | sta->last_ack_rssi[0] = sta->last_ack_rssi[1]; | ||
287 | sta->last_ack_rssi[1] = sta->last_ack_rssi[2]; | ||
288 | sta->last_ack_rssi[2] = status->ack_signal; | ||
289 | sta->tx_num_consecutive_failures = 0; | 283 | sta->tx_num_consecutive_failures = 0; |
290 | sta->tx_num_mpdu_ok++; | 284 | sta->tx_num_mpdu_ok++; |
291 | } | 285 | } |
@@ -304,7 +298,7 @@ ignore: | |||
304 | } | 298 | } |
305 | 299 | ||
306 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | 300 | static void rate_control_pid_get_rate(void *priv, struct net_device *dev, |
307 | struct ieee80211_hw_mode *mode, | 301 | struct ieee80211_supported_band *sband, |
308 | struct sk_buff *skb, | 302 | struct sk_buff *skb, |
309 | struct rate_selection *sel) | 303 | struct rate_selection *sel) |
310 | { | 304 | { |
@@ -322,7 +316,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
322 | fc = le16_to_cpu(hdr->frame_control); | 316 | fc = le16_to_cpu(hdr->frame_control); |
323 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 317 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
324 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 318 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
325 | sel->rate = rate_lowest(local, mode, sta); | 319 | sel->rate = rate_lowest(local, sband, sta); |
326 | if (sta) | 320 | if (sta) |
327 | sta_info_put(sta); | 321 | sta_info_put(sta); |
328 | return; | 322 | return; |
@@ -331,23 +325,23 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
331 | /* If a forced rate is in effect, select it. */ | 325 | /* If a forced rate is in effect, select it. */ |
332 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 326 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
333 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 327 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) |
334 | sta->txrate = sdata->bss->force_unicast_rateidx; | 328 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; |
335 | 329 | ||
336 | rateidx = sta->txrate; | 330 | rateidx = sta->txrate_idx; |
337 | 331 | ||
338 | if (rateidx >= mode->num_rates) | 332 | if (rateidx >= sband->n_bitrates) |
339 | rateidx = mode->num_rates - 1; | 333 | rateidx = sband->n_bitrates - 1; |
340 | 334 | ||
341 | sta->last_txrate = rateidx; | 335 | sta->last_txrate_idx = rateidx; |
342 | 336 | ||
343 | sta_info_put(sta); | 337 | sta_info_put(sta); |
344 | 338 | ||
345 | sel->rate = &mode->rates[rateidx]; | 339 | sel->rate = &sband->bitrates[rateidx]; |
346 | 340 | ||
347 | #ifdef CONFIG_MAC80211_DEBUGFS | 341 | #ifdef CONFIG_MAC80211_DEBUGFS |
348 | rate_control_pid_event_tx_rate( | 342 | rate_control_pid_event_tx_rate( |
349 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, | 343 | &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events, |
350 | rateidx, mode->rates[rateidx].rate); | 344 | rateidx, sband->bitrates[rateidx].bitrate); |
351 | #endif | 345 | #endif |
352 | } | 346 | } |
353 | 347 | ||
@@ -359,28 +353,32 @@ static void rate_control_pid_rate_init(void *priv, void *priv_sta, | |||
359 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 353 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
360 | * Until that method is implemented, we will use the lowest supported | 354 | * Until that method is implemented, we will use the lowest supported |
361 | * rate as a workaround. */ | 355 | * rate as a workaround. */ |
362 | sta->txrate = rate_lowest_index(local, local->oper_hw_mode, sta); | 356 | struct ieee80211_supported_band *sband; |
357 | |||
358 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
359 | sta->txrate_idx = rate_lowest_index(local, sband, sta); | ||
363 | } | 360 | } |
364 | 361 | ||
365 | static void *rate_control_pid_alloc(struct ieee80211_local *local) | 362 | static void *rate_control_pid_alloc(struct ieee80211_local *local) |
366 | { | 363 | { |
367 | struct rc_pid_info *pinfo; | 364 | struct rc_pid_info *pinfo; |
368 | struct rc_pid_rateinfo *rinfo; | 365 | struct rc_pid_rateinfo *rinfo; |
369 | struct ieee80211_hw_mode *mode; | 366 | struct ieee80211_supported_band *sband; |
370 | int i, j, tmp; | 367 | int i, j, tmp; |
371 | bool s; | 368 | bool s; |
372 | #ifdef CONFIG_MAC80211_DEBUGFS | 369 | #ifdef CONFIG_MAC80211_DEBUGFS |
373 | struct rc_pid_debugfs_entries *de; | 370 | struct rc_pid_debugfs_entries *de; |
374 | #endif | 371 | #endif |
375 | 372 | ||
373 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
374 | |||
376 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); | 375 | pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); |
377 | if (!pinfo) | 376 | if (!pinfo) |
378 | return NULL; | 377 | return NULL; |
379 | 378 | ||
380 | /* We can safely assume that oper_hw_mode won't change unless we get | 379 | /* We can safely assume that sband won't change unless we get |
381 | * reinitialized. */ | 380 | * reinitialized. */ |
382 | mode = local->oper_hw_mode; | 381 | rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC); |
383 | rinfo = kmalloc(sizeof(*rinfo) * mode->num_rates, GFP_ATOMIC); | ||
384 | if (!rinfo) { | 382 | if (!rinfo) { |
385 | kfree(pinfo); | 383 | kfree(pinfo); |
386 | return NULL; | 384 | return NULL; |
@@ -389,7 +387,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
389 | /* Sort the rates. This is optimized for the most common case (i.e. | 387 | /* Sort the rates. This is optimized for the most common case (i.e. |
390 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | 388 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed |
391 | * mapping too. */ | 389 | * mapping too. */ |
392 | for (i = 0; i < mode->num_rates; i++) { | 390 | for (i = 0; i < sband->n_bitrates; i++) { |
393 | rinfo[i].index = i; | 391 | rinfo[i].index = i; |
394 | rinfo[i].rev_index = i; | 392 | rinfo[i].rev_index = i; |
395 | if (pinfo->fast_start) | 393 | if (pinfo->fast_start) |
@@ -397,11 +395,11 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
397 | else | 395 | else |
398 | rinfo[i].diff = i * pinfo->norm_offset; | 396 | rinfo[i].diff = i * pinfo->norm_offset; |
399 | } | 397 | } |
400 | for (i = 1; i < mode->num_rates; i++) { | 398 | for (i = 1; i < sband->n_bitrates; i++) { |
401 | s = 0; | 399 | s = 0; |
402 | for (j = 0; j < mode->num_rates - i; j++) | 400 | for (j = 0; j < sband->n_bitrates - i; j++) |
403 | if (unlikely(mode->rates[rinfo[j].index].rate > | 401 | if (unlikely(sband->bitrates[rinfo[j].index].bitrate > |
404 | mode->rates[rinfo[j + 1].index].rate)) { | 402 | sband->bitrates[rinfo[j + 1].index].bitrate)) { |
405 | tmp = rinfo[j].index; | 403 | tmp = rinfo[j].index; |
406 | rinfo[j].index = rinfo[j + 1].index; | 404 | rinfo[j].index = rinfo[j + 1].index; |
407 | rinfo[j + 1].index = tmp; | 405 | rinfo[j + 1].index = tmp; |
diff --git a/net/mac80211/rc80211_simple.c b/net/mac80211/rc80211_simple.c index 9a78b116acff..bcc541d4b95c 100644 --- a/net/mac80211/rc80211_simple.c +++ b/net/mac80211/rc80211_simple.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/jiffies.h> | ||
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
12 | #include <linux/types.h> | 13 | #include <linux/types.h> |
@@ -35,8 +36,8 @@ static void rate_control_rate_inc(struct ieee80211_local *local, | |||
35 | struct sta_info *sta) | 36 | struct sta_info *sta) |
36 | { | 37 | { |
37 | struct ieee80211_sub_if_data *sdata; | 38 | struct ieee80211_sub_if_data *sdata; |
38 | struct ieee80211_hw_mode *mode; | 39 | struct ieee80211_supported_band *sband; |
39 | int i = sta->txrate; | 40 | int i = sta->txrate_idx; |
40 | int maxrate; | 41 | int maxrate; |
41 | 42 | ||
42 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 43 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
@@ -45,18 +46,17 @@ static void rate_control_rate_inc(struct ieee80211_local *local, | |||
45 | return; | 46 | return; |
46 | } | 47 | } |
47 | 48 | ||
48 | mode = local->oper_hw_mode; | 49 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
49 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; | 50 | maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; |
50 | 51 | ||
51 | if (i > mode->num_rates) | 52 | if (i > sband->n_bitrates) |
52 | i = mode->num_rates - 2; | 53 | i = sband->n_bitrates - 2; |
53 | 54 | ||
54 | while (i + 1 < mode->num_rates) { | 55 | while (i + 1 < sband->n_bitrates) { |
55 | i++; | 56 | i++; |
56 | if (sta->supp_rates & BIT(i) && | 57 | if (rate_supported(sta, sband->band, i) && |
57 | mode->rates[i].flags & IEEE80211_RATE_SUPPORTED && | ||
58 | (maxrate < 0 || i <= maxrate)) { | 58 | (maxrate < 0 || i <= maxrate)) { |
59 | sta->txrate = i; | 59 | sta->txrate_idx = i; |
60 | break; | 60 | break; |
61 | } | 61 | } |
62 | } | 62 | } |
@@ -67,8 +67,8 @@ static void rate_control_rate_dec(struct ieee80211_local *local, | |||
67 | struct sta_info *sta) | 67 | struct sta_info *sta) |
68 | { | 68 | { |
69 | struct ieee80211_sub_if_data *sdata; | 69 | struct ieee80211_sub_if_data *sdata; |
70 | struct ieee80211_hw_mode *mode; | 70 | struct ieee80211_supported_band *sband; |
71 | int i = sta->txrate; | 71 | int i = sta->txrate_idx; |
72 | 72 | ||
73 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 73 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
74 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 74 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { |
@@ -76,15 +76,14 @@ static void rate_control_rate_dec(struct ieee80211_local *local, | |||
76 | return; | 76 | return; |
77 | } | 77 | } |
78 | 78 | ||
79 | mode = local->oper_hw_mode; | 79 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
80 | if (i > mode->num_rates) | 80 | if (i > sband->n_bitrates) |
81 | i = mode->num_rates; | 81 | i = sband->n_bitrates; |
82 | 82 | ||
83 | while (i > 0) { | 83 | while (i > 0) { |
84 | i--; | 84 | i--; |
85 | if (sta->supp_rates & BIT(i) && | 85 | if (rate_supported(sta, sband->band, i)) { |
86 | mode->rates[i].flags & IEEE80211_RATE_SUPPORTED) { | 86 | sta->txrate_idx = i; |
87 | sta->txrate = i; | ||
88 | break; | 87 | break; |
89 | } | 88 | } |
90 | } | 89 | } |
@@ -132,9 +131,6 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
132 | sta->tx_num_consecutive_failures++; | 131 | sta->tx_num_consecutive_failures++; |
133 | sta->tx_num_mpdu_fail++; | 132 | sta->tx_num_mpdu_fail++; |
134 | } else { | 133 | } else { |
135 | sta->last_ack_rssi[0] = sta->last_ack_rssi[1]; | ||
136 | sta->last_ack_rssi[1] = sta->last_ack_rssi[2]; | ||
137 | sta->last_ack_rssi[2] = status->ack_signal; | ||
138 | sta->tx_num_consecutive_failures = 0; | 134 | sta->tx_num_consecutive_failures = 0; |
139 | sta->tx_num_mpdu_ok++; | 135 | sta->tx_num_mpdu_ok++; |
140 | } | 136 | } |
@@ -168,7 +164,7 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
168 | } else if (per_failed < RATE_CONTROL_NUM_UP) { | 164 | } else if (per_failed < RATE_CONTROL_NUM_UP) { |
169 | rate_control_rate_inc(local, sta); | 165 | rate_control_rate_inc(local, sta); |
170 | } | 166 | } |
171 | srctrl->tx_avg_rate_sum += status->control.rate->rate; | 167 | srctrl->tx_avg_rate_sum += status->control.tx_rate->bitrate; |
172 | srctrl->tx_avg_rate_num++; | 168 | srctrl->tx_avg_rate_num++; |
173 | srctrl->tx_num_failures = 0; | 169 | srctrl->tx_num_failures = 0; |
174 | srctrl->tx_num_xmit = 0; | 170 | srctrl->tx_num_xmit = 0; |
@@ -177,7 +173,7 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
177 | rate_control_rate_dec(local, sta); | 173 | rate_control_rate_dec(local, sta); |
178 | } | 174 | } |
179 | 175 | ||
180 | if (srctrl->avg_rate_update + 60 * HZ < jiffies) { | 176 | if (time_after(jiffies, srctrl->avg_rate_update + 60 * HZ)) { |
181 | srctrl->avg_rate_update = jiffies; | 177 | srctrl->avg_rate_update = jiffies; |
182 | if (srctrl->tx_avg_rate_num > 0) { | 178 | if (srctrl->tx_avg_rate_num > 0) { |
183 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 179 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -201,7 +197,7 @@ static void rate_control_simple_tx_status(void *priv, struct net_device *dev, | |||
201 | 197 | ||
202 | static void | 198 | static void |
203 | rate_control_simple_get_rate(void *priv, struct net_device *dev, | 199 | rate_control_simple_get_rate(void *priv, struct net_device *dev, |
204 | struct ieee80211_hw_mode *mode, | 200 | struct ieee80211_supported_band *sband, |
205 | struct sk_buff *skb, | 201 | struct sk_buff *skb, |
206 | struct rate_selection *sel) | 202 | struct rate_selection *sel) |
207 | { | 203 | { |
@@ -219,7 +215,7 @@ rate_control_simple_get_rate(void *priv, struct net_device *dev, | |||
219 | fc = le16_to_cpu(hdr->frame_control); | 215 | fc = le16_to_cpu(hdr->frame_control); |
220 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 216 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
221 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 217 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
222 | sel->rate = rate_lowest(local, mode, sta); | 218 | sel->rate = rate_lowest(local, sband, sta); |
223 | if (sta) | 219 | if (sta) |
224 | sta_info_put(sta); | 220 | sta_info_put(sta); |
225 | return; | 221 | return; |
@@ -228,18 +224,18 @@ rate_control_simple_get_rate(void *priv, struct net_device *dev, | |||
228 | /* If a forced rate is in effect, select it. */ | 224 | /* If a forced rate is in effect, select it. */ |
229 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 225 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
230 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 226 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) |
231 | sta->txrate = sdata->bss->force_unicast_rateidx; | 227 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; |
232 | 228 | ||
233 | rateidx = sta->txrate; | 229 | rateidx = sta->txrate_idx; |
234 | 230 | ||
235 | if (rateidx >= mode->num_rates) | 231 | if (rateidx >= sband->n_bitrates) |
236 | rateidx = mode->num_rates - 1; | 232 | rateidx = sband->n_bitrates - 1; |
237 | 233 | ||
238 | sta->last_txrate = rateidx; | 234 | sta->last_txrate_idx = rateidx; |
239 | 235 | ||
240 | sta_info_put(sta); | 236 | sta_info_put(sta); |
241 | 237 | ||
242 | sel->rate = &mode->rates[rateidx]; | 238 | sel->rate = &sband->bitrates[rateidx]; |
243 | } | 239 | } |
244 | 240 | ||
245 | 241 | ||
@@ -247,21 +243,15 @@ static void rate_control_simple_rate_init(void *priv, void *priv_sta, | |||
247 | struct ieee80211_local *local, | 243 | struct ieee80211_local *local, |
248 | struct sta_info *sta) | 244 | struct sta_info *sta) |
249 | { | 245 | { |
250 | struct ieee80211_hw_mode *mode; | 246 | struct ieee80211_supported_band *sband; |
251 | int i; | 247 | |
252 | sta->txrate = 0; | 248 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
253 | mode = local->oper_hw_mode; | 249 | |
254 | /* TODO: This routine should consider using RSSI from previous packets | 250 | /* TODO: This routine should consider using RSSI from previous packets |
255 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. | 251 | * as we need to have IEEE 802.1X auth succeed immediately after assoc.. |
256 | * Until that method is implemented, we will use the lowest supported rate | 252 | * Until that method is implemented, we will use the lowest supported rate |
257 | * as a workaround, */ | 253 | * as a workaround, */ |
258 | for (i = 0; i < mode->num_rates; i++) { | 254 | sta->txrate_idx = rate_lowest_index(local, sband, sta); |
259 | if ((sta->supp_rates & BIT(i)) && | ||
260 | (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) { | ||
261 | sta->txrate = i; | ||
262 | break; | ||
263 | } | ||
264 | } | ||
265 | } | 255 | } |
266 | 256 | ||
267 | 257 | ||
diff --git a/net/mac80211/regdomain.c b/net/mac80211/regdomain.c deleted file mode 100644 index f42678fa62d1..000000000000 --- a/net/mac80211/regdomain.c +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This regulatory domain control implementation is known to be incomplete | ||
12 | * and confusing. mac80211 regulatory domain control will be significantly | ||
13 | * reworked in the not-too-distant future. | ||
14 | * | ||
15 | * For now, drivers wishing to control which channels are and aren't available | ||
16 | * are advised as follows: | ||
17 | * - set the IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED flag | ||
18 | * - continue to include *ALL* possible channels in the modes registered | ||
19 | * through ieee80211_register_hwmode() | ||
20 | * - for each allowable ieee80211_channel structure registered in the above | ||
21 | * call, set the flag member to some meaningful value such as | ||
22 | * IEEE80211_CHAN_W_SCAN | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
23 | * IEEE80211_CHAN_W_IBSS. | ||
24 | * - leave flag as 0 for non-allowable channels | ||
25 | * | ||
26 | * The usual implementation is for a driver to read a device EEPROM to | ||
27 | * determine which regulatory domain it should be operating under, then | ||
28 | * looking up the allowable channels in a driver-local table, then performing | ||
29 | * the above. | ||
30 | */ | ||
31 | |||
32 | #include <linux/module.h> | ||
33 | #include <linux/netdevice.h> | ||
34 | #include <net/mac80211.h> | ||
35 | #include "ieee80211_i.h" | ||
36 | |||
37 | static int ieee80211_regdom = 0x10; /* FCC */ | ||
38 | module_param(ieee80211_regdom, int, 0444); | ||
39 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain; 64=MKK"); | ||
40 | |||
41 | /* | ||
42 | * If firmware is upgraded by the vendor, additional channels can be used based | ||
43 | * on the new Japanese regulatory rules. This is indicated by setting | ||
44 | * ieee80211_japan_5ghz module parameter to one when loading the 80211 kernel | ||
45 | * module. | ||
46 | */ | ||
47 | static int ieee80211_japan_5ghz /* = 0 */; | ||
48 | module_param(ieee80211_japan_5ghz, int, 0444); | ||
49 | MODULE_PARM_DESC(ieee80211_japan_5ghz, "Vendor-updated firmware for 5 GHz"); | ||
50 | |||
51 | |||
52 | struct ieee80211_channel_range { | ||
53 | short start_freq; | ||
54 | short end_freq; | ||
55 | unsigned char power_level; | ||
56 | unsigned char antenna_max; | ||
57 | }; | ||
58 | |||
59 | static const struct ieee80211_channel_range ieee80211_fcc_channels[] = { | ||
60 | { 2412, 2462, 27, 6 } /* IEEE 802.11b/g, channels 1..11 */, | ||
61 | { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, | ||
62 | { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, | ||
63 | { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, | ||
64 | { 0 } | ||
65 | }; | ||
66 | |||
67 | static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { | ||
68 | { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, | ||
69 | { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, | ||
70 | { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, | ||
71 | { 0 } | ||
72 | }; | ||
73 | |||
74 | |||
75 | static const struct ieee80211_channel_range *channel_range = | ||
76 | ieee80211_fcc_channels; | ||
77 | |||
78 | |||
79 | static void ieee80211_unmask_channel(int mode, struct ieee80211_channel *chan) | ||
80 | { | ||
81 | int i; | ||
82 | |||
83 | chan->flag = 0; | ||
84 | |||
85 | for (i = 0; channel_range[i].start_freq; i++) { | ||
86 | const struct ieee80211_channel_range *r = &channel_range[i]; | ||
87 | if (r->start_freq <= chan->freq && r->end_freq >= chan->freq) { | ||
88 | if (ieee80211_regdom == 64 && !ieee80211_japan_5ghz && | ||
89 | chan->freq >= 5260 && chan->freq <= 5320) { | ||
90 | /* | ||
91 | * Skip new channels in Japan since the | ||
92 | * firmware was not marked having been upgraded | ||
93 | * by the vendor. | ||
94 | */ | ||
95 | continue; | ||
96 | } | ||
97 | |||
98 | if (ieee80211_regdom == 0x10 && | ||
99 | (chan->freq == 5190 || chan->freq == 5210 || | ||
100 | chan->freq == 5230)) { | ||
101 | /* Skip MKK channels when in FCC domain. */ | ||
102 | continue; | ||
103 | } | ||
104 | |||
105 | chan->flag |= IEEE80211_CHAN_W_SCAN | | ||
106 | IEEE80211_CHAN_W_ACTIVE_SCAN | | ||
107 | IEEE80211_CHAN_W_IBSS; | ||
108 | chan->power_level = r->power_level; | ||
109 | chan->antenna_max = r->antenna_max; | ||
110 | |||
111 | if (ieee80211_regdom == 64 && | ||
112 | (chan->freq == 5170 || chan->freq == 5190 || | ||
113 | chan->freq == 5210 || chan->freq == 5230)) { | ||
114 | /* | ||
115 | * New regulatory rules in Japan have backwards | ||
116 | * compatibility with old channels in 5.15-5.25 | ||
117 | * GHz band, but the station is not allowed to | ||
118 | * use active scan on these old channels. | ||
119 | */ | ||
120 | chan->flag &= ~IEEE80211_CHAN_W_ACTIVE_SCAN; | ||
121 | } | ||
122 | |||
123 | if (ieee80211_regdom == 64 && | ||
124 | (chan->freq == 5260 || chan->freq == 5280 || | ||
125 | chan->freq == 5300 || chan->freq == 5320)) { | ||
126 | /* | ||
127 | * IBSS is not allowed on 5.25-5.35 GHz band | ||
128 | * due to radar detection requirements. | ||
129 | */ | ||
130 | chan->flag &= ~IEEE80211_CHAN_W_IBSS; | ||
131 | } | ||
132 | |||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | |||
138 | |||
139 | void ieee80211_set_default_regdomain(struct ieee80211_hw_mode *mode) | ||
140 | { | ||
141 | int c; | ||
142 | for (c = 0; c < mode->num_channels; c++) | ||
143 | ieee80211_unmask_channel(mode->mode, &mode->channels[c]); | ||
144 | } | ||
145 | |||
146 | |||
147 | void ieee80211_regdomain_init(void) | ||
148 | { | ||
149 | if (ieee80211_regdom == 0x40) | ||
150 | channel_range = ieee80211_mkk_channels; | ||
151 | } | ||
152 | |||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 535407d07fa4..48574f6c0e74 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/jiffies.h> | ||
12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
13 | #include <linux/skbuff.h> | 14 | #include <linux/skbuff.h> |
14 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
@@ -82,10 +83,10 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
82 | */ | 83 | */ |
83 | static struct sk_buff * | 84 | static struct sk_buff * |
84 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | 85 | ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, |
85 | struct ieee80211_rx_status *status) | 86 | struct ieee80211_rx_status *status, |
87 | struct ieee80211_rate *rate) | ||
86 | { | 88 | { |
87 | struct ieee80211_sub_if_data *sdata; | 89 | struct ieee80211_sub_if_data *sdata; |
88 | struct ieee80211_rate *rate; | ||
89 | int needed_headroom = 0; | 90 | int needed_headroom = 0; |
90 | struct ieee80211_radiotap_header *rthdr; | 91 | struct ieee80211_radiotap_header *rthdr; |
91 | __le64 *rttsft = NULL; | 92 | __le64 *rttsft = NULL; |
@@ -194,14 +195,11 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
194 | rtfixed->rx_flags |= | 195 | rtfixed->rx_flags |= |
195 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | 196 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); |
196 | 197 | ||
197 | rate = ieee80211_get_rate(local, status->phymode, | 198 | rtfixed->rate = rate->bitrate / 5; |
198 | status->rate); | ||
199 | if (rate) | ||
200 | rtfixed->rate = rate->rate / 5; | ||
201 | 199 | ||
202 | rtfixed->chan_freq = cpu_to_le16(status->freq); | 200 | rtfixed->chan_freq = cpu_to_le16(status->freq); |
203 | 201 | ||
204 | if (status->phymode == MODE_IEEE80211A) | 202 | if (status->band == IEEE80211_BAND_5GHZ) |
205 | rtfixed->chan_flags = | 203 | rtfixed->chan_flags = |
206 | cpu_to_le16(IEEE80211_CHAN_OFDM | | 204 | cpu_to_le16(IEEE80211_CHAN_OFDM | |
207 | IEEE80211_CHAN_5GHZ); | 205 | IEEE80211_CHAN_5GHZ); |
@@ -226,6 +224,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
226 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR) | 224 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR) |
227 | continue; | 225 | continue; |
228 | 226 | ||
227 | if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) | ||
228 | continue; | ||
229 | |||
229 | if (prev_dev) { | 230 | if (prev_dev) { |
230 | skb2 = skb_clone(skb, GFP_ATOMIC); | 231 | skb2 = skb_clone(skb, GFP_ATOMIC); |
231 | if (skb2) { | 232 | if (skb2) { |
@@ -249,15 +250,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
249 | } | 250 | } |
250 | 251 | ||
251 | 252 | ||
252 | /* pre-rx handlers | 253 | static void ieee80211_parse_qos(struct ieee80211_txrx_data *rx) |
253 | * | ||
254 | * these don't have dev/sdata fields in the rx data | ||
255 | * The sta value should also not be used because it may | ||
256 | * be NULL even though a STA (in IBSS mode) will be added. | ||
257 | */ | ||
258 | |||
259 | static ieee80211_txrx_result | ||
260 | ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx) | ||
261 | { | 254 | { |
262 | u8 *data = rx->skb->data; | 255 | u8 *data = rx->skb->data; |
263 | int tid; | 256 | int tid; |
@@ -290,64 +283,15 @@ ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx) | |||
290 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. | 283 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. |
291 | * For now, set skb->priority to 0 for other cases. */ | 284 | * For now, set skb->priority to 0 for other cases. */ |
292 | rx->skb->priority = (tid > 7) ? 0 : tid; | 285 | rx->skb->priority = (tid > 7) ? 0 : tid; |
293 | |||
294 | return TXRX_CONTINUE; | ||
295 | } | 286 | } |
296 | 287 | ||
297 | 288 | static void ieee80211_verify_ip_alignment(struct ieee80211_txrx_data *rx) | |
298 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | ||
299 | struct sk_buff *skb, | ||
300 | struct ieee80211_rx_status *status) | ||
301 | { | 289 | { |
302 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
303 | u32 load = 0, hdrtime; | ||
304 | struct ieee80211_rate *rate; | ||
305 | struct ieee80211_hw_mode *mode = local->hw.conf.mode; | ||
306 | int i; | ||
307 | |||
308 | /* Estimate total channel use caused by this frame */ | ||
309 | |||
310 | if (unlikely(mode->num_rates < 0)) | ||
311 | return TXRX_CONTINUE; | ||
312 | |||
313 | rate = &mode->rates[0]; | ||
314 | for (i = 0; i < mode->num_rates; i++) { | ||
315 | if (mode->rates[i].val == status->rate) { | ||
316 | rate = &mode->rates[i]; | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | ||
322 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
323 | |||
324 | if (mode->mode == MODE_IEEE80211A || | ||
325 | (mode->mode == MODE_IEEE80211G && | ||
326 | rate->flags & IEEE80211_RATE_ERP)) | ||
327 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
328 | else | ||
329 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
330 | |||
331 | load = hdrtime; | ||
332 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
333 | load += hdrtime; | ||
334 | |||
335 | load += skb->len * rate->rate_inv; | ||
336 | |||
337 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
338 | load >>= CHAN_UTIL_SHIFT; | ||
339 | |||
340 | return load; | ||
341 | } | ||
342 | |||
343 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT | 290 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT |
344 | static ieee80211_txrx_result | ||
345 | ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx) | ||
346 | { | ||
347 | int hdrlen; | 291 | int hdrlen; |
348 | 292 | ||
349 | if (!WLAN_FC_DATA_PRESENT(rx->fc)) | 293 | if (!WLAN_FC_DATA_PRESENT(rx->fc)) |
350 | return TXRX_CONTINUE; | 294 | return; |
351 | 295 | ||
352 | /* | 296 | /* |
353 | * Drivers are required to align the payload data in a way that | 297 | * Drivers are required to align the payload data in a way that |
@@ -372,32 +316,55 @@ ieee80211_rx_h_verify_ip_alignment(struct ieee80211_txrx_data *rx) | |||
372 | if (rx->flags & IEEE80211_TXRXD_RX_AMSDU) | 316 | if (rx->flags & IEEE80211_TXRXD_RX_AMSDU) |
373 | hdrlen += ETH_HLEN; | 317 | hdrlen += ETH_HLEN; |
374 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); | 318 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); |
375 | |||
376 | return TXRX_CONTINUE; | ||
377 | } | ||
378 | #endif | 319 | #endif |
320 | } | ||
379 | 321 | ||
380 | ieee80211_rx_handler ieee80211_rx_pre_handlers[] = | 322 | |
323 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | ||
324 | struct sk_buff *skb, | ||
325 | struct ieee80211_rx_status *status, | ||
326 | struct ieee80211_rate *rate) | ||
381 | { | 327 | { |
382 | ieee80211_rx_h_parse_qos, | 328 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
383 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT | 329 | u32 load = 0, hdrtime; |
384 | ieee80211_rx_h_verify_ip_alignment, | 330 | |
385 | #endif | 331 | /* Estimate total channel use caused by this frame */ |
386 | NULL | 332 | |
387 | }; | 333 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, |
334 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
335 | |||
336 | if (status->band == IEEE80211_BAND_5GHZ || | ||
337 | (status->band == IEEE80211_BAND_5GHZ && | ||
338 | rate->flags & IEEE80211_RATE_ERP_G)) | ||
339 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
340 | else | ||
341 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
342 | |||
343 | load = hdrtime; | ||
344 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
345 | load += hdrtime; | ||
346 | |||
347 | /* TODO: optimise again */ | ||
348 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
349 | |||
350 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
351 | load >>= CHAN_UTIL_SHIFT; | ||
352 | |||
353 | return load; | ||
354 | } | ||
388 | 355 | ||
389 | /* rx handlers */ | 356 | /* rx handlers */ |
390 | 357 | ||
391 | static ieee80211_txrx_result | 358 | static ieee80211_rx_result |
392 | ieee80211_rx_h_if_stats(struct ieee80211_txrx_data *rx) | 359 | ieee80211_rx_h_if_stats(struct ieee80211_txrx_data *rx) |
393 | { | 360 | { |
394 | if (rx->sta) | 361 | if (rx->sta) |
395 | rx->sta->channel_use_raw += rx->u.rx.load; | 362 | rx->sta->channel_use_raw += rx->u.rx.load; |
396 | rx->sdata->channel_use_raw += rx->u.rx.load; | 363 | rx->sdata->channel_use_raw += rx->u.rx.load; |
397 | return TXRX_CONTINUE; | 364 | return RX_CONTINUE; |
398 | } | 365 | } |
399 | 366 | ||
400 | static ieee80211_txrx_result | 367 | static ieee80211_rx_result |
401 | ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx) | 368 | ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx) |
402 | { | 369 | { |
403 | struct ieee80211_local *local = rx->local; | 370 | struct ieee80211_local *local = rx->local; |
@@ -409,21 +376,21 @@ ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx) | |||
409 | if (unlikely(local->sta_sw_scanning)) { | 376 | if (unlikely(local->sta_sw_scanning)) { |
410 | /* drop all the other packets during a software scan anyway */ | 377 | /* drop all the other packets during a software scan anyway */ |
411 | if (ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status) | 378 | if (ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status) |
412 | != TXRX_QUEUED) | 379 | != RX_QUEUED) |
413 | dev_kfree_skb(skb); | 380 | dev_kfree_skb(skb); |
414 | return TXRX_QUEUED; | 381 | return RX_QUEUED; |
415 | } | 382 | } |
416 | 383 | ||
417 | if (unlikely(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) { | 384 | if (unlikely(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) { |
418 | /* scanning finished during invoking of handlers */ | 385 | /* scanning finished during invoking of handlers */ |
419 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | 386 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); |
420 | return TXRX_DROP; | 387 | return RX_DROP_UNUSABLE; |
421 | } | 388 | } |
422 | 389 | ||
423 | return TXRX_CONTINUE; | 390 | return RX_CONTINUE; |
424 | } | 391 | } |
425 | 392 | ||
426 | static ieee80211_txrx_result | 393 | static ieee80211_rx_result |
427 | ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) | 394 | ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) |
428 | { | 395 | { |
429 | struct ieee80211_hdr *hdr; | 396 | struct ieee80211_hdr *hdr; |
@@ -438,14 +405,14 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) | |||
438 | rx->local->dot11FrameDuplicateCount++; | 405 | rx->local->dot11FrameDuplicateCount++; |
439 | rx->sta->num_duplicates++; | 406 | rx->sta->num_duplicates++; |
440 | } | 407 | } |
441 | return TXRX_DROP; | 408 | return RX_DROP_MONITOR; |
442 | } else | 409 | } else |
443 | rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl; | 410 | rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl; |
444 | } | 411 | } |
445 | 412 | ||
446 | if (unlikely(rx->skb->len < 16)) { | 413 | if (unlikely(rx->skb->len < 16)) { |
447 | I802_DEBUG_INC(rx->local->rx_handlers_drop_short); | 414 | I802_DEBUG_INC(rx->local->rx_handlers_drop_short); |
448 | return TXRX_DROP; | 415 | return RX_DROP_MONITOR; |
449 | } | 416 | } |
450 | 417 | ||
451 | /* Drop disallowed frame classes based on STA auth/assoc state; | 418 | /* Drop disallowed frame classes based on STA auth/assoc state; |
@@ -467,23 +434,23 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) | |||
467 | || !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) { | 434 | || !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) { |
468 | /* Drop IBSS frames and frames for other hosts | 435 | /* Drop IBSS frames and frames for other hosts |
469 | * silently. */ | 436 | * silently. */ |
470 | return TXRX_DROP; | 437 | return RX_DROP_MONITOR; |
471 | } | 438 | } |
472 | 439 | ||
473 | return TXRX_DROP; | 440 | return RX_DROP_MONITOR; |
474 | } | 441 | } |
475 | 442 | ||
476 | return TXRX_CONTINUE; | 443 | return RX_CONTINUE; |
477 | } | 444 | } |
478 | 445 | ||
479 | 446 | ||
480 | static ieee80211_txrx_result | 447 | static ieee80211_rx_result |
481 | ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) | 448 | ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) |
482 | { | 449 | { |
483 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 450 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
484 | int keyidx; | 451 | int keyidx; |
485 | int hdrlen; | 452 | int hdrlen; |
486 | ieee80211_txrx_result result = TXRX_DROP; | 453 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
487 | struct ieee80211_key *stakey = NULL; | 454 | struct ieee80211_key *stakey = NULL; |
488 | 455 | ||
489 | /* | 456 | /* |
@@ -513,14 +480,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) | |||
513 | */ | 480 | */ |
514 | 481 | ||
515 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | 482 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) |
516 | return TXRX_CONTINUE; | 483 | return RX_CONTINUE; |
517 | 484 | ||
518 | /* | 485 | /* |
519 | * No point in finding a key and decrypting if the frame is neither | 486 | * No point in finding a key and decrypting if the frame is neither |
520 | * addressed to us nor a multicast frame. | 487 | * addressed to us nor a multicast frame. |
521 | */ | 488 | */ |
522 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) | 489 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) |
523 | return TXRX_CONTINUE; | 490 | return RX_CONTINUE; |
524 | 491 | ||
525 | if (rx->sta) | 492 | if (rx->sta) |
526 | stakey = rcu_dereference(rx->sta->key); | 493 | stakey = rcu_dereference(rx->sta->key); |
@@ -539,12 +506,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) | |||
539 | */ | 506 | */ |
540 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | 507 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && |
541 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) | 508 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) |
542 | return TXRX_CONTINUE; | 509 | return RX_CONTINUE; |
543 | 510 | ||
544 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 511 | hdrlen = ieee80211_get_hdrlen(rx->fc); |
545 | 512 | ||
546 | if (rx->skb->len < 8 + hdrlen) | 513 | if (rx->skb->len < 8 + hdrlen) |
547 | return TXRX_DROP; /* TODO: count this? */ | 514 | return RX_DROP_UNUSABLE; /* TODO: count this? */ |
548 | 515 | ||
549 | /* | 516 | /* |
550 | * no need to call ieee80211_wep_get_keyidx, | 517 | * no need to call ieee80211_wep_get_keyidx, |
@@ -573,7 +540,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_txrx_data *rx) | |||
573 | printk(KERN_DEBUG "%s: RX protected frame," | 540 | printk(KERN_DEBUG "%s: RX protected frame," |
574 | " but have no key\n", rx->dev->name); | 541 | " but have no key\n", rx->dev->name); |
575 | #endif /* CONFIG_MAC80211_DEBUG */ | 542 | #endif /* CONFIG_MAC80211_DEBUG */ |
576 | return TXRX_DROP; | 543 | return RX_DROP_MONITOR; |
577 | } | 544 | } |
578 | 545 | ||
579 | /* Check for weak IVs if possible */ | 546 | /* Check for weak IVs if possible */ |
@@ -612,7 +579,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
612 | if (sdata->bss) | 579 | if (sdata->bss) |
613 | atomic_inc(&sdata->bss->num_sta_ps); | 580 | atomic_inc(&sdata->bss->num_sta_ps); |
614 | sta->flags |= WLAN_STA_PS; | 581 | sta->flags |= WLAN_STA_PS; |
615 | sta->pspoll = 0; | 582 | sta->flags &= ~WLAN_STA_PSPOLL; |
616 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 583 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
617 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 584 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
618 | dev->name, print_mac(mac, sta->addr), sta->aid); | 585 | dev->name, print_mac(mac, sta->addr), sta->aid); |
@@ -629,20 +596,20 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
629 | DECLARE_MAC_BUF(mac); | 596 | DECLARE_MAC_BUF(mac); |
630 | 597 | ||
631 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | 598 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); |
599 | |||
632 | if (sdata->bss) | 600 | if (sdata->bss) |
633 | atomic_dec(&sdata->bss->num_sta_ps); | 601 | atomic_dec(&sdata->bss->num_sta_ps); |
634 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_TIM); | 602 | |
635 | sta->pspoll = 0; | 603 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); |
636 | if (!skb_queue_empty(&sta->ps_tx_buf)) { | 604 | |
637 | if (local->ops->set_tim) | 605 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
638 | local->ops->set_tim(local_to_hw(local), sta->aid, 0); | 606 | sta_info_clear_tim_bit(sta); |
639 | if (sdata->bss) | 607 | |
640 | bss_tim_clear(local, sdata->bss, sta->aid); | ||
641 | } | ||
642 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 608 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
643 | printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", | 609 | printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", |
644 | dev->name, print_mac(mac, sta->addr), sta->aid); | 610 | dev->name, print_mac(mac, sta->addr), sta->aid); |
645 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 611 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
612 | |||
646 | /* Send all buffered frames to the station */ | 613 | /* Send all buffered frames to the station */ |
647 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 614 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
648 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 615 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; |
@@ -666,7 +633,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
666 | return sent; | 633 | return sent; |
667 | } | 634 | } |
668 | 635 | ||
669 | static ieee80211_txrx_result | 636 | static ieee80211_rx_result |
670 | ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) | 637 | ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) |
671 | { | 638 | { |
672 | struct sta_info *sta = rx->sta; | 639 | struct sta_info *sta = rx->sta; |
@@ -674,7 +641,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) | |||
674 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 641 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
675 | 642 | ||
676 | if (!sta) | 643 | if (!sta) |
677 | return TXRX_CONTINUE; | 644 | return RX_CONTINUE; |
678 | 645 | ||
679 | /* Update last_rx only for IBSS packets which are for the current | 646 | /* Update last_rx only for IBSS packets which are for the current |
680 | * BSSID to avoid keeping the current IBSS network alive in cases where | 647 | * BSSID to avoid keeping the current IBSS network alive in cases where |
@@ -695,7 +662,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) | |||
695 | } | 662 | } |
696 | 663 | ||
697 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) | 664 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) |
698 | return TXRX_CONTINUE; | 665 | return RX_CONTINUE; |
699 | 666 | ||
700 | sta->rx_fragments++; | 667 | sta->rx_fragments++; |
701 | sta->rx_bytes += rx->skb->len; | 668 | sta->rx_bytes += rx->skb->len; |
@@ -722,10 +689,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) | |||
722 | * as a dropped packed. */ | 689 | * as a dropped packed. */ |
723 | sta->rx_packets++; | 690 | sta->rx_packets++; |
724 | dev_kfree_skb(rx->skb); | 691 | dev_kfree_skb(rx->skb); |
725 | return TXRX_QUEUED; | 692 | return RX_QUEUED; |
726 | } | 693 | } |
727 | 694 | ||
728 | return TXRX_CONTINUE; | 695 | return RX_CONTINUE; |
729 | } /* ieee80211_rx_h_sta_process */ | 696 | } /* ieee80211_rx_h_sta_process */ |
730 | 697 | ||
731 | static inline struct ieee80211_fragment_entry * | 698 | static inline struct ieee80211_fragment_entry * |
@@ -801,7 +768,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
801 | compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) | 768 | compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) |
802 | continue; | 769 | continue; |
803 | 770 | ||
804 | if (entry->first_frag_time + 2 * HZ < jiffies) { | 771 | if (time_after(jiffies, entry->first_frag_time + 2 * HZ)) { |
805 | __skb_queue_purge(&entry->skb_list); | 772 | __skb_queue_purge(&entry->skb_list); |
806 | continue; | 773 | continue; |
807 | } | 774 | } |
@@ -811,7 +778,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
811 | return NULL; | 778 | return NULL; |
812 | } | 779 | } |
813 | 780 | ||
814 | static ieee80211_txrx_result | 781 | static ieee80211_rx_result |
815 | ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | 782 | ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) |
816 | { | 783 | { |
817 | struct ieee80211_hdr *hdr; | 784 | struct ieee80211_hdr *hdr; |
@@ -848,7 +815,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
848 | rx->key->u.ccmp.rx_pn[rx->u.rx.queue], | 815 | rx->key->u.ccmp.rx_pn[rx->u.rx.queue], |
849 | CCMP_PN_LEN); | 816 | CCMP_PN_LEN); |
850 | } | 817 | } |
851 | return TXRX_QUEUED; | 818 | return RX_QUEUED; |
852 | } | 819 | } |
853 | 820 | ||
854 | /* This is a fragment for a frame that should already be pending in | 821 | /* This is a fragment for a frame that should already be pending in |
@@ -858,7 +825,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
858 | rx->u.rx.queue, hdr); | 825 | rx->u.rx.queue, hdr); |
859 | if (!entry) { | 826 | if (!entry) { |
860 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 827 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
861 | return TXRX_DROP; | 828 | return RX_DROP_MONITOR; |
862 | } | 829 | } |
863 | 830 | ||
864 | /* Verify that MPDUs within one MSDU have sequential PN values. | 831 | /* Verify that MPDUs within one MSDU have sequential PN values. |
@@ -867,7 +834,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
867 | int i; | 834 | int i; |
868 | u8 pn[CCMP_PN_LEN], *rpn; | 835 | u8 pn[CCMP_PN_LEN], *rpn; |
869 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) | 836 | if (!rx->key || rx->key->conf.alg != ALG_CCMP) |
870 | return TXRX_DROP; | 837 | return RX_DROP_UNUSABLE; |
871 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 838 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); |
872 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 839 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { |
873 | pn[i]++; | 840 | pn[i]++; |
@@ -885,7 +852,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
885 | rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], | 852 | rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], |
886 | rpn[5], pn[0], pn[1], pn[2], pn[3], | 853 | rpn[5], pn[0], pn[1], pn[2], pn[3], |
887 | pn[4], pn[5]); | 854 | pn[4], pn[5]); |
888 | return TXRX_DROP; | 855 | return RX_DROP_UNUSABLE; |
889 | } | 856 | } |
890 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 857 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
891 | } | 858 | } |
@@ -896,7 +863,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
896 | entry->extra_len += rx->skb->len; | 863 | entry->extra_len += rx->skb->len; |
897 | if (rx->fc & IEEE80211_FCTL_MOREFRAGS) { | 864 | if (rx->fc & IEEE80211_FCTL_MOREFRAGS) { |
898 | rx->skb = NULL; | 865 | rx->skb = NULL; |
899 | return TXRX_QUEUED; | 866 | return RX_QUEUED; |
900 | } | 867 | } |
901 | 868 | ||
902 | rx->skb = __skb_dequeue(&entry->skb_list); | 869 | rx->skb = __skb_dequeue(&entry->skb_list); |
@@ -906,7 +873,7 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
906 | GFP_ATOMIC))) { | 873 | GFP_ATOMIC))) { |
907 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); | 874 | I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); |
908 | __skb_queue_purge(&entry->skb_list); | 875 | __skb_queue_purge(&entry->skb_list); |
909 | return TXRX_DROP; | 876 | return RX_DROP_UNUSABLE; |
910 | } | 877 | } |
911 | } | 878 | } |
912 | while ((skb = __skb_dequeue(&entry->skb_list))) { | 879 | while ((skb = __skb_dequeue(&entry->skb_list))) { |
@@ -924,10 +891,10 @@ ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) | |||
924 | rx->local->dot11MulticastReceivedFrameCount++; | 891 | rx->local->dot11MulticastReceivedFrameCount++; |
925 | else | 892 | else |
926 | ieee80211_led_rx(rx->local); | 893 | ieee80211_led_rx(rx->local); |
927 | return TXRX_CONTINUE; | 894 | return RX_CONTINUE; |
928 | } | 895 | } |
929 | 896 | ||
930 | static ieee80211_txrx_result | 897 | static ieee80211_rx_result |
931 | ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) | 898 | ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) |
932 | { | 899 | { |
933 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 900 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
@@ -939,11 +906,11 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) | |||
939 | (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL || | 906 | (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL || |
940 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PSPOLL || | 907 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PSPOLL || |
941 | !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))) | 908 | !(rx->flags & IEEE80211_TXRXD_RXRA_MATCH))) |
942 | return TXRX_CONTINUE; | 909 | return RX_CONTINUE; |
943 | 910 | ||
944 | if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) && | 911 | if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) && |
945 | (sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) | 912 | (sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) |
946 | return TXRX_DROP; | 913 | return RX_DROP_UNUSABLE; |
947 | 914 | ||
948 | skb = skb_dequeue(&rx->sta->tx_filtered); | 915 | skb = skb_dequeue(&rx->sta->tx_filtered); |
949 | if (!skb) { | 916 | if (!skb) { |
@@ -958,9 +925,11 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) | |||
958 | struct ieee80211_hdr *hdr = | 925 | struct ieee80211_hdr *hdr = |
959 | (struct ieee80211_hdr *) skb->data; | 926 | (struct ieee80211_hdr *) skb->data; |
960 | 927 | ||
961 | /* tell TX path to send one frame even though the STA may | 928 | /* |
962 | * still remain is PS mode after this frame exchange */ | 929 | * Tell TX path to send one frame even though the STA may |
963 | rx->sta->pspoll = 1; | 930 | * still remain is PS mode after this frame exchange. |
931 | */ | ||
932 | rx->sta->flags |= WLAN_STA_PSPOLL; | ||
964 | 933 | ||
965 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 934 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
966 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 935 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", |
@@ -970,38 +939,37 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) | |||
970 | 939 | ||
971 | /* Use MoreData flag to indicate whether there are more | 940 | /* Use MoreData flag to indicate whether there are more |
972 | * buffered frames for this STA */ | 941 | * buffered frames for this STA */ |
973 | if (no_pending_pkts) { | 942 | if (no_pending_pkts) |
974 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | 943 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); |
975 | rx->sta->flags &= ~WLAN_STA_TIM; | 944 | else |
976 | } else | ||
977 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 945 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
978 | 946 | ||
979 | dev_queue_xmit(skb); | 947 | dev_queue_xmit(skb); |
980 | 948 | ||
981 | if (no_pending_pkts) { | 949 | if (no_pending_pkts) |
982 | if (rx->local->ops->set_tim) | 950 | sta_info_clear_tim_bit(rx->sta); |
983 | rx->local->ops->set_tim(local_to_hw(rx->local), | ||
984 | rx->sta->aid, 0); | ||
985 | if (rx->sdata->bss) | ||
986 | bss_tim_clear(rx->local, rx->sdata->bss, rx->sta->aid); | ||
987 | } | ||
988 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 951 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
989 | } else if (!rx->u.rx.sent_ps_buffered) { | 952 | } else if (!rx->u.rx.sent_ps_buffered) { |
953 | /* | ||
954 | * FIXME: This can be the result of a race condition between | ||
955 | * us expiring a frame and the station polling for it. | ||
956 | * Should we send it a null-func frame indicating we | ||
957 | * have nothing buffered for it? | ||
958 | */ | ||
990 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 959 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " |
991 | "though there is no buffered frames for it\n", | 960 | "though there is no buffered frames for it\n", |
992 | rx->dev->name, print_mac(mac, rx->sta->addr)); | 961 | rx->dev->name, print_mac(mac, rx->sta->addr)); |
993 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 962 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
994 | |||
995 | } | 963 | } |
996 | 964 | ||
997 | /* Free PS Poll skb here instead of returning TXRX_DROP that would | 965 | /* Free PS Poll skb here instead of returning RX_DROP that would |
998 | * count as an dropped frame. */ | 966 | * count as an dropped frame. */ |
999 | dev_kfree_skb(rx->skb); | 967 | dev_kfree_skb(rx->skb); |
1000 | 968 | ||
1001 | return TXRX_QUEUED; | 969 | return RX_QUEUED; |
1002 | } | 970 | } |
1003 | 971 | ||
1004 | static ieee80211_txrx_result | 972 | static ieee80211_rx_result |
1005 | ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx) | 973 | ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx) |
1006 | { | 974 | { |
1007 | u16 fc = rx->fc; | 975 | u16 fc = rx->fc; |
@@ -1009,7 +977,7 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx) | |||
1009 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data; | 977 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data; |
1010 | 978 | ||
1011 | if (!WLAN_FC_IS_QOS_DATA(fc)) | 979 | if (!WLAN_FC_IS_QOS_DATA(fc)) |
1012 | return TXRX_CONTINUE; | 980 | return RX_CONTINUE; |
1013 | 981 | ||
1014 | /* remove the qos control field, update frame type and meta-data */ | 982 | /* remove the qos control field, update frame type and meta-data */ |
1015 | memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2); | 983 | memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2); |
@@ -1018,17 +986,17 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx) | |||
1018 | rx->fc = fc &= ~IEEE80211_STYPE_QOS_DATA; | 986 | rx->fc = fc &= ~IEEE80211_STYPE_QOS_DATA; |
1019 | hdr->frame_control = cpu_to_le16(fc); | 987 | hdr->frame_control = cpu_to_le16(fc); |
1020 | 988 | ||
1021 | return TXRX_CONTINUE; | 989 | return RX_CONTINUE; |
1022 | } | 990 | } |
1023 | 991 | ||
1024 | static int | 992 | static int |
1025 | ieee80211_802_1x_port_control(struct ieee80211_txrx_data *rx) | 993 | ieee80211_802_1x_port_control(struct ieee80211_txrx_data *rx) |
1026 | { | 994 | { |
1027 | if (unlikely(rx->sdata->ieee802_1x_pac && | 995 | if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { |
1028 | (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)))) { | ||
1029 | #ifdef CONFIG_MAC80211_DEBUG | 996 | #ifdef CONFIG_MAC80211_DEBUG |
1030 | printk(KERN_DEBUG "%s: dropped frame " | 997 | if (net_ratelimit()) |
1031 | "(unauthorized port)\n", rx->dev->name); | 998 | printk(KERN_DEBUG "%s: dropped frame " |
999 | "(unauthorized port)\n", rx->dev->name); | ||
1032 | #endif /* CONFIG_MAC80211_DEBUG */ | 1000 | #endif /* CONFIG_MAC80211_DEBUG */ |
1033 | return -EACCES; | 1001 | return -EACCES; |
1034 | } | 1002 | } |
@@ -1275,7 +1243,7 @@ ieee80211_deliver_skb(struct ieee80211_txrx_data *rx) | |||
1275 | } | 1243 | } |
1276 | } | 1244 | } |
1277 | 1245 | ||
1278 | static ieee80211_txrx_result | 1246 | static ieee80211_rx_result |
1279 | ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | 1247 | ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) |
1280 | { | 1248 | { |
1281 | struct net_device *dev = rx->dev; | 1249 | struct net_device *dev = rx->dev; |
@@ -1291,17 +1259,17 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1291 | 1259 | ||
1292 | fc = rx->fc; | 1260 | fc = rx->fc; |
1293 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) | 1261 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) |
1294 | return TXRX_CONTINUE; | 1262 | return RX_CONTINUE; |
1295 | 1263 | ||
1296 | if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) | 1264 | if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) |
1297 | return TXRX_DROP; | 1265 | return RX_DROP_MONITOR; |
1298 | 1266 | ||
1299 | if (!(rx->flags & IEEE80211_TXRXD_RX_AMSDU)) | 1267 | if (!(rx->flags & IEEE80211_TXRXD_RX_AMSDU)) |
1300 | return TXRX_CONTINUE; | 1268 | return RX_CONTINUE; |
1301 | 1269 | ||
1302 | err = ieee80211_data_to_8023(rx); | 1270 | err = ieee80211_data_to_8023(rx); |
1303 | if (unlikely(err)) | 1271 | if (unlikely(err)) |
1304 | return TXRX_DROP; | 1272 | return RX_DROP_UNUSABLE; |
1305 | 1273 | ||
1306 | skb->dev = dev; | 1274 | skb->dev = dev; |
1307 | 1275 | ||
@@ -1311,7 +1279,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1311 | /* skip the wrapping header */ | 1279 | /* skip the wrapping header */ |
1312 | eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); | 1280 | eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); |
1313 | if (!eth) | 1281 | if (!eth) |
1314 | return TXRX_DROP; | 1282 | return RX_DROP_UNUSABLE; |
1315 | 1283 | ||
1316 | while (skb != frame) { | 1284 | while (skb != frame) { |
1317 | u8 padding; | 1285 | u8 padding; |
@@ -1326,7 +1294,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1326 | /* the last MSDU has no padding */ | 1294 | /* the last MSDU has no padding */ |
1327 | if (subframe_len > remaining) { | 1295 | if (subframe_len > remaining) { |
1328 | printk(KERN_DEBUG "%s: wrong buffer size", dev->name); | 1296 | printk(KERN_DEBUG "%s: wrong buffer size", dev->name); |
1329 | return TXRX_DROP; | 1297 | return RX_DROP_UNUSABLE; |
1330 | } | 1298 | } |
1331 | 1299 | ||
1332 | skb_pull(skb, sizeof(struct ethhdr)); | 1300 | skb_pull(skb, sizeof(struct ethhdr)); |
@@ -1338,7 +1306,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1338 | subframe_len); | 1306 | subframe_len); |
1339 | 1307 | ||
1340 | if (frame == NULL) | 1308 | if (frame == NULL) |
1341 | return TXRX_DROP; | 1309 | return RX_DROP_UNUSABLE; |
1342 | 1310 | ||
1343 | skb_reserve(frame, local->hw.extra_tx_headroom + | 1311 | skb_reserve(frame, local->hw.extra_tx_headroom + |
1344 | sizeof(struct ethhdr)); | 1312 | sizeof(struct ethhdr)); |
@@ -1351,7 +1319,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1351 | printk(KERN_DEBUG "%s: wrong buffer size ", | 1319 | printk(KERN_DEBUG "%s: wrong buffer size ", |
1352 | dev->name); | 1320 | dev->name); |
1353 | dev_kfree_skb(frame); | 1321 | dev_kfree_skb(frame); |
1354 | return TXRX_DROP; | 1322 | return RX_DROP_UNUSABLE; |
1355 | } | 1323 | } |
1356 | } | 1324 | } |
1357 | 1325 | ||
@@ -1381,7 +1349,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1381 | 1349 | ||
1382 | if (!ieee80211_frame_allowed(rx)) { | 1350 | if (!ieee80211_frame_allowed(rx)) { |
1383 | if (skb == frame) /* last frame */ | 1351 | if (skb == frame) /* last frame */ |
1384 | return TXRX_DROP; | 1352 | return RX_DROP_UNUSABLE; |
1385 | dev_kfree_skb(frame); | 1353 | dev_kfree_skb(frame); |
1386 | continue; | 1354 | continue; |
1387 | } | 1355 | } |
@@ -1389,10 +1357,10 @@ ieee80211_rx_h_amsdu(struct ieee80211_txrx_data *rx) | |||
1389 | ieee80211_deliver_skb(rx); | 1357 | ieee80211_deliver_skb(rx); |
1390 | } | 1358 | } |
1391 | 1359 | ||
1392 | return TXRX_QUEUED; | 1360 | return RX_QUEUED; |
1393 | } | 1361 | } |
1394 | 1362 | ||
1395 | static ieee80211_txrx_result | 1363 | static ieee80211_rx_result |
1396 | ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) | 1364 | ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) |
1397 | { | 1365 | { |
1398 | struct net_device *dev = rx->dev; | 1366 | struct net_device *dev = rx->dev; |
@@ -1401,17 +1369,17 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) | |||
1401 | 1369 | ||
1402 | fc = rx->fc; | 1370 | fc = rx->fc; |
1403 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) | 1371 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) |
1404 | return TXRX_CONTINUE; | 1372 | return RX_CONTINUE; |
1405 | 1373 | ||
1406 | if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) | 1374 | if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) |
1407 | return TXRX_DROP; | 1375 | return RX_DROP_MONITOR; |
1408 | 1376 | ||
1409 | err = ieee80211_data_to_8023(rx); | 1377 | err = ieee80211_data_to_8023(rx); |
1410 | if (unlikely(err)) | 1378 | if (unlikely(err)) |
1411 | return TXRX_DROP; | 1379 | return RX_DROP_UNUSABLE; |
1412 | 1380 | ||
1413 | if (!ieee80211_frame_allowed(rx)) | 1381 | if (!ieee80211_frame_allowed(rx)) |
1414 | return TXRX_DROP; | 1382 | return RX_DROP_MONITOR; |
1415 | 1383 | ||
1416 | rx->skb->dev = dev; | 1384 | rx->skb->dev = dev; |
1417 | 1385 | ||
@@ -1420,10 +1388,10 @@ ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) | |||
1420 | 1388 | ||
1421 | ieee80211_deliver_skb(rx); | 1389 | ieee80211_deliver_skb(rx); |
1422 | 1390 | ||
1423 | return TXRX_QUEUED; | 1391 | return RX_QUEUED; |
1424 | } | 1392 | } |
1425 | 1393 | ||
1426 | static ieee80211_txrx_result | 1394 | static ieee80211_rx_result |
1427 | ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx) | 1395 | ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx) |
1428 | { | 1396 | { |
1429 | struct ieee80211_local *local = rx->local; | 1397 | struct ieee80211_local *local = rx->local; |
@@ -1435,15 +1403,15 @@ ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx) | |||
1435 | u16 tid; | 1403 | u16 tid; |
1436 | 1404 | ||
1437 | if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL)) | 1405 | if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL)) |
1438 | return TXRX_CONTINUE; | 1406 | return RX_CONTINUE; |
1439 | 1407 | ||
1440 | if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) { | 1408 | if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) { |
1441 | if (!rx->sta) | 1409 | if (!rx->sta) |
1442 | return TXRX_CONTINUE; | 1410 | return RX_CONTINUE; |
1443 | tid = le16_to_cpu(bar->control) >> 12; | 1411 | tid = le16_to_cpu(bar->control) >> 12; |
1444 | tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]); | 1412 | tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]); |
1445 | if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL) | 1413 | if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL) |
1446 | return TXRX_CONTINUE; | 1414 | return RX_CONTINUE; |
1447 | 1415 | ||
1448 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; | 1416 | start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4; |
1449 | 1417 | ||
@@ -1460,19 +1428,19 @@ ieee80211_rx_h_ctrl(struct ieee80211_txrx_data *rx) | |||
1460 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, | 1428 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, |
1461 | start_seq_num, 1); | 1429 | start_seq_num, 1); |
1462 | rcu_read_unlock(); | 1430 | rcu_read_unlock(); |
1463 | return TXRX_DROP; | 1431 | return RX_DROP_UNUSABLE; |
1464 | } | 1432 | } |
1465 | 1433 | ||
1466 | return TXRX_CONTINUE; | 1434 | return RX_CONTINUE; |
1467 | } | 1435 | } |
1468 | 1436 | ||
1469 | static ieee80211_txrx_result | 1437 | static ieee80211_rx_result |
1470 | ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx) | 1438 | ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx) |
1471 | { | 1439 | { |
1472 | struct ieee80211_sub_if_data *sdata; | 1440 | struct ieee80211_sub_if_data *sdata; |
1473 | 1441 | ||
1474 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) | 1442 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) |
1475 | return TXRX_DROP; | 1443 | return RX_DROP_MONITOR; |
1476 | 1444 | ||
1477 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1445 | sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
1478 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | 1446 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || |
@@ -1480,56 +1448,13 @@ ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx) | |||
1480 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) | 1448 | !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) |
1481 | ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status); | 1449 | ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status); |
1482 | else | 1450 | else |
1483 | return TXRX_DROP; | 1451 | return RX_DROP_MONITOR; |
1484 | 1452 | ||
1485 | return TXRX_QUEUED; | 1453 | return RX_QUEUED; |
1486 | } | ||
1487 | |||
1488 | static inline ieee80211_txrx_result __ieee80211_invoke_rx_handlers( | ||
1489 | struct ieee80211_local *local, | ||
1490 | ieee80211_rx_handler *handlers, | ||
1491 | struct ieee80211_txrx_data *rx, | ||
1492 | struct sta_info *sta) | ||
1493 | { | ||
1494 | ieee80211_rx_handler *handler; | ||
1495 | ieee80211_txrx_result res = TXRX_DROP; | ||
1496 | |||
1497 | for (handler = handlers; *handler != NULL; handler++) { | ||
1498 | res = (*handler)(rx); | ||
1499 | |||
1500 | switch (res) { | ||
1501 | case TXRX_CONTINUE: | ||
1502 | continue; | ||
1503 | case TXRX_DROP: | ||
1504 | I802_DEBUG_INC(local->rx_handlers_drop); | ||
1505 | if (sta) | ||
1506 | sta->rx_dropped++; | ||
1507 | break; | ||
1508 | case TXRX_QUEUED: | ||
1509 | I802_DEBUG_INC(local->rx_handlers_queued); | ||
1510 | break; | ||
1511 | } | ||
1512 | break; | ||
1513 | } | ||
1514 | |||
1515 | if (res == TXRX_DROP) | ||
1516 | dev_kfree_skb(rx->skb); | ||
1517 | return res; | ||
1518 | } | ||
1519 | |||
1520 | static inline void ieee80211_invoke_rx_handlers(struct ieee80211_local *local, | ||
1521 | ieee80211_rx_handler *handlers, | ||
1522 | struct ieee80211_txrx_data *rx, | ||
1523 | struct sta_info *sta) | ||
1524 | { | ||
1525 | if (__ieee80211_invoke_rx_handlers(local, handlers, rx, sta) == | ||
1526 | TXRX_CONTINUE) | ||
1527 | dev_kfree_skb(rx->skb); | ||
1528 | } | 1454 | } |
1529 | 1455 | ||
1530 | static void ieee80211_rx_michael_mic_report(struct net_device *dev, | 1456 | static void ieee80211_rx_michael_mic_report(struct net_device *dev, |
1531 | struct ieee80211_hdr *hdr, | 1457 | struct ieee80211_hdr *hdr, |
1532 | struct sta_info *sta, | ||
1533 | struct ieee80211_txrx_data *rx) | 1458 | struct ieee80211_txrx_data *rx) |
1534 | { | 1459 | { |
1535 | int keyidx, hdrlen; | 1460 | int keyidx, hdrlen; |
@@ -1548,7 +1473,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1548 | dev->name, print_mac(mac, hdr->addr2), | 1473 | dev->name, print_mac(mac, hdr->addr2), |
1549 | print_mac(mac2, hdr->addr1), keyidx); | 1474 | print_mac(mac2, hdr->addr1), keyidx); |
1550 | 1475 | ||
1551 | if (!sta) { | 1476 | if (!rx->sta) { |
1552 | /* | 1477 | /* |
1553 | * Some hardware seem to generate incorrect Michael MIC | 1478 | * Some hardware seem to generate incorrect Michael MIC |
1554 | * reports; ignore them to avoid triggering countermeasures. | 1479 | * reports; ignore them to avoid triggering countermeasures. |
@@ -1600,7 +1525,88 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1600 | rx->skb = NULL; | 1525 | rx->skb = NULL; |
1601 | } | 1526 | } |
1602 | 1527 | ||
1603 | ieee80211_rx_handler ieee80211_rx_handlers[] = | 1528 | static void ieee80211_rx_cooked_monitor(struct ieee80211_txrx_data *rx) |
1529 | { | ||
1530 | struct ieee80211_sub_if_data *sdata; | ||
1531 | struct ieee80211_local *local = rx->local; | ||
1532 | struct ieee80211_rtap_hdr { | ||
1533 | struct ieee80211_radiotap_header hdr; | ||
1534 | u8 flags; | ||
1535 | u8 rate; | ||
1536 | __le16 chan_freq; | ||
1537 | __le16 chan_flags; | ||
1538 | } __attribute__ ((packed)) *rthdr; | ||
1539 | struct sk_buff *skb = rx->skb, *skb2; | ||
1540 | struct net_device *prev_dev = NULL; | ||
1541 | struct ieee80211_rx_status *status = rx->u.rx.status; | ||
1542 | |||
1543 | if (rx->flags & IEEE80211_TXRXD_RX_CMNTR_REPORTED) | ||
1544 | goto out_free_skb; | ||
1545 | |||
1546 | if (skb_headroom(skb) < sizeof(*rthdr) && | ||
1547 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | ||
1548 | goto out_free_skb; | ||
1549 | |||
1550 | rthdr = (void *)skb_push(skb, sizeof(*rthdr)); | ||
1551 | memset(rthdr, 0, sizeof(*rthdr)); | ||
1552 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
1553 | rthdr->hdr.it_present = | ||
1554 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
1555 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
1556 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | ||
1557 | |||
1558 | rthdr->rate = rx->u.rx.rate->bitrate / 5; | ||
1559 | rthdr->chan_freq = cpu_to_le16(status->freq); | ||
1560 | |||
1561 | if (status->band == IEEE80211_BAND_5GHZ) | ||
1562 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
1563 | IEEE80211_CHAN_5GHZ); | ||
1564 | else | ||
1565 | rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
1566 | IEEE80211_CHAN_2GHZ); | ||
1567 | |||
1568 | skb_set_mac_header(skb, 0); | ||
1569 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1570 | skb->pkt_type = PACKET_OTHERHOST; | ||
1571 | skb->protocol = htons(ETH_P_802_2); | ||
1572 | |||
1573 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
1574 | if (!netif_running(sdata->dev)) | ||
1575 | continue; | ||
1576 | |||
1577 | if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || | ||
1578 | !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) | ||
1579 | continue; | ||
1580 | |||
1581 | if (prev_dev) { | ||
1582 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
1583 | if (skb2) { | ||
1584 | skb2->dev = prev_dev; | ||
1585 | netif_rx(skb2); | ||
1586 | } | ||
1587 | } | ||
1588 | |||
1589 | prev_dev = sdata->dev; | ||
1590 | sdata->dev->stats.rx_packets++; | ||
1591 | sdata->dev->stats.rx_bytes += skb->len; | ||
1592 | } | ||
1593 | |||
1594 | if (prev_dev) { | ||
1595 | skb->dev = prev_dev; | ||
1596 | netif_rx(skb); | ||
1597 | skb = NULL; | ||
1598 | } else | ||
1599 | goto out_free_skb; | ||
1600 | |||
1601 | rx->flags |= IEEE80211_TXRXD_RX_CMNTR_REPORTED; | ||
1602 | return; | ||
1603 | |||
1604 | out_free_skb: | ||
1605 | dev_kfree_skb(skb); | ||
1606 | } | ||
1607 | |||
1608 | typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_txrx_data *); | ||
1609 | static ieee80211_rx_handler ieee80211_rx_handlers[] = | ||
1604 | { | 1610 | { |
1605 | ieee80211_rx_h_if_stats, | 1611 | ieee80211_rx_h_if_stats, |
1606 | ieee80211_rx_h_passive_scan, | 1612 | ieee80211_rx_h_passive_scan, |
@@ -1622,6 +1628,47 @@ ieee80211_rx_handler ieee80211_rx_handlers[] = | |||
1622 | NULL | 1628 | NULL |
1623 | }; | 1629 | }; |
1624 | 1630 | ||
1631 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | ||
1632 | struct ieee80211_txrx_data *rx, | ||
1633 | struct sk_buff *skb) | ||
1634 | { | ||
1635 | ieee80211_rx_handler *handler; | ||
1636 | ieee80211_rx_result res = RX_DROP_MONITOR; | ||
1637 | |||
1638 | rx->skb = skb; | ||
1639 | rx->sdata = sdata; | ||
1640 | rx->dev = sdata->dev; | ||
1641 | |||
1642 | for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { | ||
1643 | res = (*handler)(rx); | ||
1644 | |||
1645 | switch (res) { | ||
1646 | case RX_CONTINUE: | ||
1647 | continue; | ||
1648 | case RX_DROP_UNUSABLE: | ||
1649 | case RX_DROP_MONITOR: | ||
1650 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1651 | if (rx->sta) | ||
1652 | rx->sta->rx_dropped++; | ||
1653 | break; | ||
1654 | case RX_QUEUED: | ||
1655 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | ||
1656 | break; | ||
1657 | } | ||
1658 | break; | ||
1659 | } | ||
1660 | |||
1661 | switch (res) { | ||
1662 | case RX_CONTINUE: | ||
1663 | case RX_DROP_MONITOR: | ||
1664 | ieee80211_rx_cooked_monitor(rx); | ||
1665 | break; | ||
1666 | case RX_DROP_UNUSABLE: | ||
1667 | dev_kfree_skb(rx->skb); | ||
1668 | break; | ||
1669 | } | ||
1670 | } | ||
1671 | |||
1625 | /* main receive path */ | 1672 | /* main receive path */ |
1626 | 1673 | ||
1627 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | 1674 | static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, |
@@ -1649,7 +1696,10 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1649 | case IEEE80211_IF_TYPE_IBSS: | 1696 | case IEEE80211_IF_TYPE_IBSS: |
1650 | if (!bssid) | 1697 | if (!bssid) |
1651 | return 0; | 1698 | return 0; |
1652 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | 1699 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && |
1700 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) | ||
1701 | return 1; | ||
1702 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | ||
1653 | if (!(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) | 1703 | if (!(rx->flags & IEEE80211_TXRXD_RXIN_SCAN)) |
1654 | return 0; | 1704 | return 0; |
1655 | rx->flags &= ~IEEE80211_TXRXD_RXRA_MATCH; | 1705 | rx->flags &= ~IEEE80211_TXRXD_RXRA_MATCH; |
@@ -1707,11 +1757,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1707 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 1757 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
1708 | struct sk_buff *skb, | 1758 | struct sk_buff *skb, |
1709 | struct ieee80211_rx_status *status, | 1759 | struct ieee80211_rx_status *status, |
1710 | u32 load) | 1760 | u32 load, |
1761 | struct ieee80211_rate *rate) | ||
1711 | { | 1762 | { |
1712 | struct ieee80211_local *local = hw_to_local(hw); | 1763 | struct ieee80211_local *local = hw_to_local(hw); |
1713 | struct ieee80211_sub_if_data *sdata; | 1764 | struct ieee80211_sub_if_data *sdata; |
1714 | struct sta_info *sta; | ||
1715 | struct ieee80211_hdr *hdr; | 1765 | struct ieee80211_hdr *hdr; |
1716 | struct ieee80211_txrx_data rx; | 1766 | struct ieee80211_txrx_data rx; |
1717 | u16 type; | 1767 | u16 type; |
@@ -1727,40 +1777,31 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1727 | 1777 | ||
1728 | rx.u.rx.status = status; | 1778 | rx.u.rx.status = status; |
1729 | rx.u.rx.load = load; | 1779 | rx.u.rx.load = load; |
1780 | rx.u.rx.rate = rate; | ||
1730 | rx.fc = le16_to_cpu(hdr->frame_control); | 1781 | rx.fc = le16_to_cpu(hdr->frame_control); |
1731 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1782 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
1732 | 1783 | ||
1733 | if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) | 1784 | if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) |
1734 | local->dot11ReceivedFragmentCount++; | 1785 | local->dot11ReceivedFragmentCount++; |
1735 | 1786 | ||
1736 | sta = rx.sta = sta_info_get(local, hdr->addr2); | 1787 | rx.sta = sta_info_get(local, hdr->addr2); |
1737 | if (sta) { | 1788 | if (rx.sta) { |
1738 | rx.dev = rx.sta->dev; | 1789 | rx.dev = rx.sta->dev; |
1739 | rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev); | 1790 | rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev); |
1740 | } | 1791 | } |
1741 | 1792 | ||
1742 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { | 1793 | if ((status->flag & RX_FLAG_MMIC_ERROR)) { |
1743 | ieee80211_rx_michael_mic_report(local->mdev, hdr, sta, &rx); | 1794 | ieee80211_rx_michael_mic_report(local->mdev, hdr, &rx); |
1744 | goto end; | 1795 | goto end; |
1745 | } | 1796 | } |
1746 | 1797 | ||
1747 | if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning)) | 1798 | if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning)) |
1748 | rx.flags |= IEEE80211_TXRXD_RXIN_SCAN; | 1799 | rx.flags |= IEEE80211_TXRXD_RXIN_SCAN; |
1749 | 1800 | ||
1750 | if (__ieee80211_invoke_rx_handlers(local, local->rx_pre_handlers, &rx, | 1801 | ieee80211_parse_qos(&rx); |
1751 | sta) != TXRX_CONTINUE) | 1802 | ieee80211_verify_ip_alignment(&rx); |
1752 | goto end; | ||
1753 | skb = rx.skb; | ||
1754 | 1803 | ||
1755 | if (sta && !(sta->flags & (WLAN_STA_WDS | WLAN_STA_ASSOC_AP)) && | 1804 | skb = rx.skb; |
1756 | !atomic_read(&local->iff_promiscs) && | ||
1757 | !is_multicast_ether_addr(hdr->addr1)) { | ||
1758 | rx.flags |= IEEE80211_TXRXD_RXRA_MATCH; | ||
1759 | ieee80211_invoke_rx_handlers(local, local->rx_handlers, &rx, | ||
1760 | rx.sta); | ||
1761 | sta_info_put(sta); | ||
1762 | return; | ||
1763 | } | ||
1764 | 1805 | ||
1765 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 1806 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
1766 | if (!netif_running(sdata->dev)) | 1807 | if (!netif_running(sdata->dev)) |
@@ -1772,8 +1813,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1772 | bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); | 1813 | bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); |
1773 | rx.flags |= IEEE80211_TXRXD_RXRA_MATCH; | 1814 | rx.flags |= IEEE80211_TXRXD_RXRA_MATCH; |
1774 | prepares = prepare_for_handlers(sdata, bssid, &rx, hdr); | 1815 | prepares = prepare_for_handlers(sdata, bssid, &rx, hdr); |
1775 | /* prepare_for_handlers can change sta */ | ||
1776 | sta = rx.sta; | ||
1777 | 1816 | ||
1778 | if (!prepares) | 1817 | if (!prepares) |
1779 | continue; | 1818 | continue; |
@@ -1804,26 +1843,18 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1804 | continue; | 1843 | continue; |
1805 | } | 1844 | } |
1806 | rx.fc = le16_to_cpu(hdr->frame_control); | 1845 | rx.fc = le16_to_cpu(hdr->frame_control); |
1807 | rx.skb = skb_new; | 1846 | ieee80211_invoke_rx_handlers(prev, &rx, skb_new); |
1808 | rx.dev = prev->dev; | ||
1809 | rx.sdata = prev; | ||
1810 | ieee80211_invoke_rx_handlers(local, local->rx_handlers, | ||
1811 | &rx, sta); | ||
1812 | prev = sdata; | 1847 | prev = sdata; |
1813 | } | 1848 | } |
1814 | if (prev) { | 1849 | if (prev) { |
1815 | rx.fc = le16_to_cpu(hdr->frame_control); | 1850 | rx.fc = le16_to_cpu(hdr->frame_control); |
1816 | rx.skb = skb; | 1851 | ieee80211_invoke_rx_handlers(prev, &rx, skb); |
1817 | rx.dev = prev->dev; | ||
1818 | rx.sdata = prev; | ||
1819 | ieee80211_invoke_rx_handlers(local, local->rx_handlers, | ||
1820 | &rx, sta); | ||
1821 | } else | 1852 | } else |
1822 | dev_kfree_skb(skb); | 1853 | dev_kfree_skb(skb); |
1823 | 1854 | ||
1824 | end: | 1855 | end: |
1825 | if (sta) | 1856 | if (rx.sta) |
1826 | sta_info_put(sta); | 1857 | sta_info_put(rx.sta); |
1827 | } | 1858 | } |
1828 | 1859 | ||
1829 | #define SEQ_MODULO 0x1000 | 1860 | #define SEQ_MODULO 0x1000 |
@@ -1859,6 +1890,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1859 | u16 head_seq_num, buf_size; | 1890 | u16 head_seq_num, buf_size; |
1860 | int index; | 1891 | int index; |
1861 | u32 pkt_load; | 1892 | u32 pkt_load; |
1893 | struct ieee80211_supported_band *sband; | ||
1894 | struct ieee80211_rate *rate; | ||
1862 | 1895 | ||
1863 | buf_size = tid_agg_rx->buf_size; | 1896 | buf_size = tid_agg_rx->buf_size; |
1864 | head_seq_num = tid_agg_rx->head_seq_num; | 1897 | head_seq_num = tid_agg_rx->head_seq_num; |
@@ -1889,12 +1922,14 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1889 | memcpy(&status, | 1922 | memcpy(&status, |
1890 | tid_agg_rx->reorder_buf[index]->cb, | 1923 | tid_agg_rx->reorder_buf[index]->cb, |
1891 | sizeof(status)); | 1924 | sizeof(status)); |
1925 | sband = local->hw.wiphy->bands[status.band]; | ||
1926 | rate = &sband->bitrates[status.rate_idx]; | ||
1892 | pkt_load = ieee80211_rx_load_stats(local, | 1927 | pkt_load = ieee80211_rx_load_stats(local, |
1893 | tid_agg_rx->reorder_buf[index], | 1928 | tid_agg_rx->reorder_buf[index], |
1894 | &status); | 1929 | &status, rate); |
1895 | __ieee80211_rx_handle_packet(hw, | 1930 | __ieee80211_rx_handle_packet(hw, |
1896 | tid_agg_rx->reorder_buf[index], | 1931 | tid_agg_rx->reorder_buf[index], |
1897 | &status, pkt_load); | 1932 | &status, pkt_load, rate); |
1898 | tid_agg_rx->stored_mpdu_num--; | 1933 | tid_agg_rx->stored_mpdu_num--; |
1899 | tid_agg_rx->reorder_buf[index] = NULL; | 1934 | tid_agg_rx->reorder_buf[index] = NULL; |
1900 | } | 1935 | } |
@@ -1934,11 +1969,13 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
1934 | /* release the reordered frame back to stack */ | 1969 | /* release the reordered frame back to stack */ |
1935 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, | 1970 | memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, |
1936 | sizeof(status)); | 1971 | sizeof(status)); |
1972 | sband = local->hw.wiphy->bands[status.band]; | ||
1973 | rate = &sband->bitrates[status.rate_idx]; | ||
1937 | pkt_load = ieee80211_rx_load_stats(local, | 1974 | pkt_load = ieee80211_rx_load_stats(local, |
1938 | tid_agg_rx->reorder_buf[index], | 1975 | tid_agg_rx->reorder_buf[index], |
1939 | &status); | 1976 | &status, rate); |
1940 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 1977 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
1941 | &status, pkt_load); | 1978 | &status, pkt_load, rate); |
1942 | tid_agg_rx->stored_mpdu_num--; | 1979 | tid_agg_rx->stored_mpdu_num--; |
1943 | tid_agg_rx->reorder_buf[index] = NULL; | 1980 | tid_agg_rx->reorder_buf[index] = NULL; |
1944 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 1981 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
@@ -2019,6 +2056,25 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2019 | { | 2056 | { |
2020 | struct ieee80211_local *local = hw_to_local(hw); | 2057 | struct ieee80211_local *local = hw_to_local(hw); |
2021 | u32 pkt_load; | 2058 | u32 pkt_load; |
2059 | struct ieee80211_rate *rate = NULL; | ||
2060 | struct ieee80211_supported_band *sband; | ||
2061 | |||
2062 | if (status->band < 0 || | ||
2063 | status->band > IEEE80211_NUM_BANDS) { | ||
2064 | WARN_ON(1); | ||
2065 | return; | ||
2066 | } | ||
2067 | |||
2068 | sband = local->hw.wiphy->bands[status->band]; | ||
2069 | |||
2070 | if (!sband || | ||
2071 | status->rate_idx < 0 || | ||
2072 | status->rate_idx >= sband->n_bitrates) { | ||
2073 | WARN_ON(1); | ||
2074 | return; | ||
2075 | } | ||
2076 | |||
2077 | rate = &sband->bitrates[status->rate_idx]; | ||
2022 | 2078 | ||
2023 | /* | 2079 | /* |
2024 | * key references and virtual interfaces are protected using RCU | 2080 | * key references and virtual interfaces are protected using RCU |
@@ -2033,17 +2089,17 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2033 | * if it was previously present. | 2089 | * if it was previously present. |
2034 | * Also, frames with less than 16 bytes are dropped. | 2090 | * Also, frames with less than 16 bytes are dropped. |
2035 | */ | 2091 | */ |
2036 | skb = ieee80211_rx_monitor(local, skb, status); | 2092 | skb = ieee80211_rx_monitor(local, skb, status, rate); |
2037 | if (!skb) { | 2093 | if (!skb) { |
2038 | rcu_read_unlock(); | 2094 | rcu_read_unlock(); |
2039 | return; | 2095 | return; |
2040 | } | 2096 | } |
2041 | 2097 | ||
2042 | pkt_load = ieee80211_rx_load_stats(local, skb, status); | 2098 | pkt_load = ieee80211_rx_load_stats(local, skb, status, rate); |
2043 | local->channel_use_raw += pkt_load; | 2099 | local->channel_use_raw += pkt_load; |
2044 | 2100 | ||
2045 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2101 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
2046 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load); | 2102 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); |
2047 | 2103 | ||
2048 | rcu_read_unlock(); | 2104 | rcu_read_unlock(); |
2049 | } | 2105 | } |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 1f74bd296357..e384e6632d97 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -55,48 +55,34 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
55 | return -ENOENT; | 55 | return -ENOENT; |
56 | } | 56 | } |
57 | 57 | ||
58 | struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) | 58 | /* must hold local->sta_lock */ |
59 | static struct sta_info *__sta_info_find(struct ieee80211_local *local, | ||
60 | u8 *addr) | ||
59 | { | 61 | { |
60 | struct sta_info *sta; | 62 | struct sta_info *sta; |
61 | 63 | ||
62 | read_lock_bh(&local->sta_lock); | ||
63 | sta = local->sta_hash[STA_HASH(addr)]; | 64 | sta = local->sta_hash[STA_HASH(addr)]; |
64 | while (sta) { | 65 | while (sta) { |
65 | if (memcmp(sta->addr, addr, ETH_ALEN) == 0) { | 66 | if (compare_ether_addr(sta->addr, addr) == 0) |
66 | __sta_info_get(sta); | ||
67 | break; | 67 | break; |
68 | } | ||
69 | sta = sta->hnext; | 68 | sta = sta->hnext; |
70 | } | 69 | } |
71 | read_unlock_bh(&local->sta_lock); | ||
72 | |||
73 | return sta; | 70 | return sta; |
74 | } | 71 | } |
75 | EXPORT_SYMBOL(sta_info_get); | ||
76 | 72 | ||
77 | int sta_info_min_txrate_get(struct ieee80211_local *local) | 73 | struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) |
78 | { | 74 | { |
79 | struct sta_info *sta; | 75 | struct sta_info *sta; |
80 | struct ieee80211_hw_mode *mode; | ||
81 | int min_txrate = 9999999; | ||
82 | int i; | ||
83 | 76 | ||
84 | read_lock_bh(&local->sta_lock); | 77 | read_lock_bh(&local->sta_lock); |
85 | mode = local->oper_hw_mode; | 78 | sta = __sta_info_find(local, addr); |
86 | for (i = 0; i < STA_HASH_SIZE; i++) { | 79 | if (sta) |
87 | sta = local->sta_hash[i]; | 80 | __sta_info_get(sta); |
88 | while (sta) { | ||
89 | if (sta->txrate < min_txrate) | ||
90 | min_txrate = sta->txrate; | ||
91 | sta = sta->hnext; | ||
92 | } | ||
93 | } | ||
94 | read_unlock_bh(&local->sta_lock); | 81 | read_unlock_bh(&local->sta_lock); |
95 | if (min_txrate == 9999999) | ||
96 | min_txrate = 0; | ||
97 | 82 | ||
98 | return mode->rates[min_txrate].rate; | 83 | return sta; |
99 | } | 84 | } |
85 | EXPORT_SYMBOL(sta_info_get); | ||
100 | 86 | ||
101 | 87 | ||
102 | static void sta_info_release(struct kref *kref) | 88 | static void sta_info_release(struct kref *kref) |
@@ -117,8 +103,10 @@ static void sta_info_release(struct kref *kref) | |||
117 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 103 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
118 | dev_kfree_skb_any(skb); | 104 | dev_kfree_skb_any(skb); |
119 | } | 105 | } |
120 | for (i = 0; i < STA_TID_NUM; i++) | 106 | for (i = 0; i < STA_TID_NUM; i++) { |
121 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); | 107 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer); |
108 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); | ||
109 | } | ||
122 | rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); | 110 | rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); |
123 | rate_control_put(sta->rate_ctrl); | 111 | rate_control_put(sta->rate_ctrl); |
124 | kfree(sta); | 112 | kfree(sta); |
@@ -132,8 +120,8 @@ void sta_info_put(struct sta_info *sta) | |||
132 | EXPORT_SYMBOL(sta_info_put); | 120 | EXPORT_SYMBOL(sta_info_put); |
133 | 121 | ||
134 | 122 | ||
135 | struct sta_info * sta_info_add(struct ieee80211_local *local, | 123 | struct sta_info *sta_info_add(struct ieee80211_local *local, |
136 | struct net_device *dev, u8 *addr, gfp_t gfp) | 124 | struct net_device *dev, u8 *addr, gfp_t gfp) |
137 | { | 125 | { |
138 | struct sta_info *sta; | 126 | struct sta_info *sta; |
139 | int i; | 127 | int i; |
@@ -141,7 +129,7 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, | |||
141 | 129 | ||
142 | sta = kzalloc(sizeof(*sta), gfp); | 130 | sta = kzalloc(sizeof(*sta), gfp); |
143 | if (!sta) | 131 | if (!sta) |
144 | return NULL; | 132 | return ERR_PTR(-ENOMEM); |
145 | 133 | ||
146 | kref_init(&sta->kref); | 134 | kref_init(&sta->kref); |
147 | 135 | ||
@@ -150,30 +138,45 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, | |||
150 | if (!sta->rate_ctrl_priv) { | 138 | if (!sta->rate_ctrl_priv) { |
151 | rate_control_put(sta->rate_ctrl); | 139 | rate_control_put(sta->rate_ctrl); |
152 | kfree(sta); | 140 | kfree(sta); |
153 | return NULL; | 141 | return ERR_PTR(-ENOMEM); |
154 | } | 142 | } |
155 | 143 | ||
156 | memcpy(sta->addr, addr, ETH_ALEN); | 144 | memcpy(sta->addr, addr, ETH_ALEN); |
157 | sta->local = local; | 145 | sta->local = local; |
158 | sta->dev = dev; | 146 | sta->dev = dev; |
159 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | 147 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); |
148 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
160 | for (i = 0; i < STA_TID_NUM; i++) { | 149 | for (i = 0; i < STA_TID_NUM; i++) { |
161 | /* timer_to_tid must be initialized with identity mapping to | 150 | /* timer_to_tid must be initialized with identity mapping to |
162 | * enable session_timer's data differentiation. refer to | 151 | * enable session_timer's data differentiation. refer to |
163 | * sta_rx_agg_session_timer_expired for useage */ | 152 | * sta_rx_agg_session_timer_expired for useage */ |
164 | sta->timer_to_tid[i] = i; | 153 | sta->timer_to_tid[i] = i; |
154 | /* tid to tx queue: initialize according to HW (0 is valid) */ | ||
155 | sta->tid_to_tx_q[i] = local->hw.queues; | ||
165 | /* rx timers */ | 156 | /* rx timers */ |
166 | sta->ampdu_mlme.tid_rx[i].session_timer.function = | 157 | sta->ampdu_mlme.tid_rx[i].session_timer.function = |
167 | sta_rx_agg_session_timer_expired; | 158 | sta_rx_agg_session_timer_expired; |
168 | sta->ampdu_mlme.tid_rx[i].session_timer.data = | 159 | sta->ampdu_mlme.tid_rx[i].session_timer.data = |
169 | (unsigned long)&sta->timer_to_tid[i]; | 160 | (unsigned long)&sta->timer_to_tid[i]; |
170 | init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer); | 161 | init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer); |
162 | /* tx timers */ | ||
163 | sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function = | ||
164 | sta_addba_resp_timer_expired; | ||
165 | sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data = | ||
166 | (unsigned long)&sta->timer_to_tid[i]; | ||
167 | init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer); | ||
171 | } | 168 | } |
172 | skb_queue_head_init(&sta->ps_tx_buf); | 169 | skb_queue_head_init(&sta->ps_tx_buf); |
173 | skb_queue_head_init(&sta->tx_filtered); | 170 | skb_queue_head_init(&sta->tx_filtered); |
174 | __sta_info_get(sta); /* sta used by caller, decremented by | ||
175 | * sta_info_put() */ | ||
176 | write_lock_bh(&local->sta_lock); | 171 | write_lock_bh(&local->sta_lock); |
172 | /* mark sta as used (by caller) */ | ||
173 | __sta_info_get(sta); | ||
174 | /* check if STA exists already */ | ||
175 | if (__sta_info_find(local, addr)) { | ||
176 | write_unlock_bh(&local->sta_lock); | ||
177 | sta_info_put(sta); | ||
178 | return ERR_PTR(-EEXIST); | ||
179 | } | ||
177 | list_add(&sta->list, &local->sta_list); | 180 | list_add(&sta->list, &local->sta_list); |
178 | local->num_sta++; | 181 | local->num_sta++; |
179 | sta_info_hash_add(local, sta); | 182 | sta_info_hash_add(local, sta); |
@@ -204,6 +207,64 @@ struct sta_info * sta_info_add(struct ieee80211_local *local, | |||
204 | return sta; | 207 | return sta; |
205 | } | 208 | } |
206 | 209 | ||
210 | static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) | ||
211 | { | ||
212 | /* | ||
213 | * This format has been mandated by the IEEE specifications, | ||
214 | * so this line may not be changed to use the __set_bit() format. | ||
215 | */ | ||
216 | bss->tim[aid / 8] |= (1 << (aid % 8)); | ||
217 | } | ||
218 | |||
219 | static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | ||
220 | { | ||
221 | /* | ||
222 | * This format has been mandated by the IEEE specifications, | ||
223 | * so this line may not be changed to use the __clear_bit() format. | ||
224 | */ | ||
225 | bss->tim[aid / 8] &= ~(1 << (aid % 8)); | ||
226 | } | ||
227 | |||
228 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | ||
229 | struct sta_info *sta) | ||
230 | { | ||
231 | if (bss) | ||
232 | __bss_tim_set(bss, sta->aid); | ||
233 | if (sta->local->ops->set_tim) | ||
234 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | ||
235 | } | ||
236 | |||
237 | void sta_info_set_tim_bit(struct sta_info *sta) | ||
238 | { | ||
239 | struct ieee80211_sub_if_data *sdata; | ||
240 | |||
241 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
242 | |||
243 | read_lock_bh(&sta->local->sta_lock); | ||
244 | __sta_info_set_tim_bit(sdata->bss, sta); | ||
245 | read_unlock_bh(&sta->local->sta_lock); | ||
246 | } | ||
247 | |||
248 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | ||
249 | struct sta_info *sta) | ||
250 | { | ||
251 | if (bss) | ||
252 | __bss_tim_clear(bss, sta->aid); | ||
253 | if (sta->local->ops->set_tim) | ||
254 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | ||
255 | } | ||
256 | |||
257 | void sta_info_clear_tim_bit(struct sta_info *sta) | ||
258 | { | ||
259 | struct ieee80211_sub_if_data *sdata; | ||
260 | |||
261 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
262 | |||
263 | read_lock_bh(&sta->local->sta_lock); | ||
264 | __sta_info_clear_tim_bit(sdata->bss, sta); | ||
265 | read_unlock_bh(&sta->local->sta_lock); | ||
266 | } | ||
267 | |||
207 | /* Caller must hold local->sta_lock */ | 268 | /* Caller must hold local->sta_lock */ |
208 | void sta_info_remove(struct sta_info *sta) | 269 | void sta_info_remove(struct sta_info *sta) |
209 | { | 270 | { |
@@ -220,10 +281,9 @@ void sta_info_remove(struct sta_info *sta) | |||
220 | sta->flags &= ~WLAN_STA_PS; | 281 | sta->flags &= ~WLAN_STA_PS; |
221 | if (sdata->bss) | 282 | if (sdata->bss) |
222 | atomic_dec(&sdata->bss->num_sta_ps); | 283 | atomic_dec(&sdata->bss->num_sta_ps); |
284 | __sta_info_clear_tim_bit(sdata->bss, sta); | ||
223 | } | 285 | } |
224 | local->num_sta--; | 286 | local->num_sta--; |
225 | sta_info_remove_aid_ptr(sta); | ||
226 | |||
227 | } | 287 | } |
228 | 288 | ||
229 | void sta_info_free(struct sta_info *sta) | 289 | void sta_info_free(struct sta_info *sta) |
@@ -252,7 +312,7 @@ void sta_info_free(struct sta_info *sta) | |||
252 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 312 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
253 | 313 | ||
254 | ieee80211_key_free(sta->key); | 314 | ieee80211_key_free(sta->key); |
255 | sta->key = NULL; | 315 | WARN_ON(sta->key); |
256 | 316 | ||
257 | if (local->ops->sta_notify) { | 317 | if (local->ops->sta_notify) { |
258 | struct ieee80211_sub_if_data *sdata; | 318 | struct ieee80211_sub_if_data *sdata; |
@@ -299,6 +359,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
299 | { | 359 | { |
300 | unsigned long flags; | 360 | unsigned long flags; |
301 | struct sk_buff *skb; | 361 | struct sk_buff *skb; |
362 | struct ieee80211_sub_if_data *sdata; | ||
302 | DECLARE_MAC_BUF(mac); | 363 | DECLARE_MAC_BUF(mac); |
303 | 364 | ||
304 | if (skb_queue_empty(&sta->ps_tx_buf)) | 365 | if (skb_queue_empty(&sta->ps_tx_buf)) |
@@ -307,21 +368,23 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
307 | for (;;) { | 368 | for (;;) { |
308 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); | 369 | spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); |
309 | skb = skb_peek(&sta->ps_tx_buf); | 370 | skb = skb_peek(&sta->ps_tx_buf); |
310 | if (sta_info_buffer_expired(local, sta, skb)) { | 371 | if (sta_info_buffer_expired(local, sta, skb)) |
311 | skb = __skb_dequeue(&sta->ps_tx_buf); | 372 | skb = __skb_dequeue(&sta->ps_tx_buf); |
312 | if (skb_queue_empty(&sta->ps_tx_buf)) | 373 | else |
313 | sta->flags &= ~WLAN_STA_TIM; | ||
314 | } else | ||
315 | skb = NULL; | 374 | skb = NULL; |
316 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); | 375 | spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); |
317 | 376 | ||
318 | if (skb) { | 377 | if (!skb) |
319 | local->total_ps_buffered--; | ||
320 | printk(KERN_DEBUG "Buffered frame expired (STA " | ||
321 | "%s)\n", print_mac(mac, sta->addr)); | ||
322 | dev_kfree_skb(skb); | ||
323 | } else | ||
324 | break; | 378 | break; |
379 | |||
380 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
381 | local->total_ps_buffered--; | ||
382 | printk(KERN_DEBUG "Buffered frame expired (STA " | ||
383 | "%s)\n", print_mac(mac, sta->addr)); | ||
384 | dev_kfree_skb(skb); | ||
385 | |||
386 | if (skb_queue_empty(&sta->ps_tx_buf)) | ||
387 | sta_info_clear_tim_bit(sta); | ||
325 | } | 388 | } |
326 | } | 389 | } |
327 | 390 | ||
@@ -400,23 +463,6 @@ void sta_info_stop(struct ieee80211_local *local) | |||
400 | sta_info_flush(local, NULL); | 463 | sta_info_flush(local, NULL); |
401 | } | 464 | } |
402 | 465 | ||
403 | void sta_info_remove_aid_ptr(struct sta_info *sta) | ||
404 | { | ||
405 | struct ieee80211_sub_if_data *sdata; | ||
406 | |||
407 | if (sta->aid <= 0) | ||
408 | return; | ||
409 | |||
410 | sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); | ||
411 | |||
412 | if (sdata->local->ops->set_tim) | ||
413 | sdata->local->ops->set_tim(local_to_hw(sdata->local), | ||
414 | sta->aid, 0); | ||
415 | if (sdata->bss) | ||
416 | __bss_tim_clear(sdata->bss, sta->aid); | ||
417 | } | ||
418 | |||
419 | |||
420 | /** | 466 | /** |
421 | * sta_info_flush - flush matching STA entries from the STA table | 467 | * sta_info_flush - flush matching STA entries from the STA table |
422 | * @local: local interface data | 468 | * @local: local interface data |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 96fe3ed95038..86eed40ada78 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -15,31 +15,72 @@ | |||
15 | #include <linux/kref.h> | 15 | #include <linux/kref.h> |
16 | #include "ieee80211_key.h" | 16 | #include "ieee80211_key.h" |
17 | 17 | ||
18 | /* Stations flags (struct sta_info::flags) */ | 18 | /** |
19 | #define WLAN_STA_AUTH BIT(0) | 19 | * enum ieee80211_sta_info_flags - Stations flags |
20 | #define WLAN_STA_ASSOC BIT(1) | 20 | * |
21 | #define WLAN_STA_PS BIT(2) | 21 | * These flags are used with &struct sta_info's @flags member. |
22 | #define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */ | 22 | * |
23 | #define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */ | 23 | * @WLAN_STA_AUTH: Station is authenticated. |
24 | #define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is | 24 | * @WLAN_STA_ASSOC: Station is associated. |
25 | * controlling whether STA is authorized to | 25 | * @WLAN_STA_PS: Station is in power-save mode |
26 | * send and receive non-IEEE 802.1X frames | 26 | * @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic. |
27 | */ | 27 | * This bit is always checked so needs to be enabled for all stations |
28 | #define WLAN_STA_SHORT_PREAMBLE BIT(7) | 28 | * when virtual port control is not in use. |
29 | /* whether this is an AP that we are associated with as a client */ | 29 | * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble |
30 | #define WLAN_STA_ASSOC_AP BIT(8) | 30 | * frames. |
31 | #define WLAN_STA_WME BIT(9) | 31 | * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. |
32 | #define WLAN_STA_WDS BIT(27) | 32 | * @WLAN_STA_WME: Station is a QoS-STA. |
33 | * @WLAN_STA_WDS: Station is one of our WDS peers. | ||
34 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. | ||
35 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the | ||
36 | * IEEE80211_TXCTL_CLEAR_PS_FILT control flag) when the next | ||
37 | * frame to this station is transmitted. | ||
38 | */ | ||
39 | enum ieee80211_sta_info_flags { | ||
40 | WLAN_STA_AUTH = 1<<0, | ||
41 | WLAN_STA_ASSOC = 1<<1, | ||
42 | WLAN_STA_PS = 1<<2, | ||
43 | WLAN_STA_AUTHORIZED = 1<<3, | ||
44 | WLAN_STA_SHORT_PREAMBLE = 1<<4, | ||
45 | WLAN_STA_ASSOC_AP = 1<<5, | ||
46 | WLAN_STA_WME = 1<<6, | ||
47 | WLAN_STA_WDS = 1<<7, | ||
48 | WLAN_STA_PSPOLL = 1<<8, | ||
49 | WLAN_STA_CLEAR_PS_FILT = 1<<9, | ||
50 | }; | ||
33 | 51 | ||
34 | #define STA_TID_NUM 16 | 52 | #define STA_TID_NUM 16 |
35 | #define ADDBA_RESP_INTERVAL HZ | 53 | #define ADDBA_RESP_INTERVAL HZ |
54 | #define HT_AGG_MAX_RETRIES (0x3) | ||
36 | 55 | ||
37 | #define HT_AGG_STATE_INITIATOR_SHIFT (4) | 56 | #define HT_AGG_STATE_INITIATOR_SHIFT (4) |
38 | 57 | ||
58 | #define HT_ADDBA_REQUESTED_MSK BIT(0) | ||
59 | #define HT_ADDBA_DRV_READY_MSK BIT(1) | ||
60 | #define HT_ADDBA_RECEIVED_MSK BIT(2) | ||
39 | #define HT_AGG_STATE_REQ_STOP_BA_MSK BIT(3) | 61 | #define HT_AGG_STATE_REQ_STOP_BA_MSK BIT(3) |
40 | 62 | #define HT_AGG_STATE_INITIATOR_MSK BIT(HT_AGG_STATE_INITIATOR_SHIFT) | |
41 | #define HT_AGG_STATE_IDLE (0x0) | 63 | #define HT_AGG_STATE_IDLE (0x0) |
42 | #define HT_AGG_STATE_OPERATIONAL (0x7) | 64 | #define HT_AGG_STATE_OPERATIONAL (HT_ADDBA_REQUESTED_MSK | \ |
65 | HT_ADDBA_DRV_READY_MSK | \ | ||
66 | HT_ADDBA_RECEIVED_MSK) | ||
67 | |||
68 | /** | ||
69 | * struct tid_ampdu_tx - TID aggregation information (Tx). | ||
70 | * | ||
71 | * @state: TID's state in session state machine. | ||
72 | * @dialog_token: dialog token for aggregation session | ||
73 | * @ssn: Starting Sequence Number expected to be aggregated. | ||
74 | * @addba_resp_timer: timer for peer's response to addba request | ||
75 | * @addba_req_num: number of times addBA request has been sent. | ||
76 | */ | ||
77 | struct tid_ampdu_tx { | ||
78 | u8 state; | ||
79 | u8 dialog_token; | ||
80 | u16 ssn; | ||
81 | struct timer_list addba_resp_timer; | ||
82 | u8 addba_req_num; | ||
83 | }; | ||
43 | 84 | ||
44 | /** | 85 | /** |
45 | * struct tid_ampdu_rx - TID aggregation information (Rx). | 86 | * struct tid_ampdu_rx - TID aggregation information (Rx). |
@@ -69,12 +110,18 @@ struct tid_ampdu_rx { | |||
69 | /** | 110 | /** |
70 | * struct sta_ampdu_mlme - STA aggregation information. | 111 | * struct sta_ampdu_mlme - STA aggregation information. |
71 | * | 112 | * |
72 | * @tid_agg_info_rx: aggregation info for Rx per TID | 113 | * @tid_rx: aggregation info for Rx per TID |
114 | * @tid_tx: aggregation info for Tx per TID | ||
73 | * @ampdu_rx: for locking sections in aggregation Rx flow | 115 | * @ampdu_rx: for locking sections in aggregation Rx flow |
116 | * @ampdu_tx: for locking sectionsi in aggregation Tx flow | ||
117 | * @dialog_token_allocator: dialog token enumerator for each new session; | ||
74 | */ | 118 | */ |
75 | struct sta_ampdu_mlme { | 119 | struct sta_ampdu_mlme { |
76 | struct tid_ampdu_rx tid_rx[STA_TID_NUM]; | 120 | struct tid_ampdu_rx tid_rx[STA_TID_NUM]; |
121 | struct tid_ampdu_tx tid_tx[STA_TID_NUM]; | ||
77 | spinlock_t ampdu_rx; | 122 | spinlock_t ampdu_rx; |
123 | spinlock_t ampdu_tx; | ||
124 | u8 dialog_token_allocator; | ||
78 | }; | 125 | }; |
79 | 126 | ||
80 | struct sta_info { | 127 | struct sta_info { |
@@ -90,12 +137,9 @@ struct sta_info { | |||
90 | 137 | ||
91 | struct sk_buff_head ps_tx_buf; /* buffer of TX frames for station in | 138 | struct sk_buff_head ps_tx_buf; /* buffer of TX frames for station in |
92 | * power saving state */ | 139 | * power saving state */ |
93 | int pspoll; /* whether STA has send a PS Poll frame */ | ||
94 | struct sk_buff_head tx_filtered; /* buffer of TX frames that were | 140 | struct sk_buff_head tx_filtered; /* buffer of TX frames that were |
95 | * already given to low-level driver, | 141 | * already given to low-level driver, |
96 | * but were filtered */ | 142 | * but were filtered */ |
97 | int clear_dst_mask; | ||
98 | |||
99 | unsigned long rx_packets, tx_packets; /* number of RX/TX MSDUs */ | 143 | unsigned long rx_packets, tx_packets; /* number of RX/TX MSDUs */ |
100 | unsigned long rx_bytes, tx_bytes; | 144 | unsigned long rx_bytes, tx_bytes; |
101 | unsigned long tx_retry_failed, tx_retry_count; | 145 | unsigned long tx_retry_failed, tx_retry_count; |
@@ -104,10 +148,11 @@ struct sta_info { | |||
104 | unsigned int wep_weak_iv_count; /* number of RX frames with weak IV */ | 148 | unsigned int wep_weak_iv_count; /* number of RX frames with weak IV */ |
105 | 149 | ||
106 | unsigned long last_rx; | 150 | unsigned long last_rx; |
107 | u32 supp_rates; /* bitmap of supported rates in local->curr_rates */ | 151 | /* bitmap of supported rates per band */ |
108 | int txrate; /* index in local->curr_rates */ | 152 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
109 | int last_txrate; /* last rate used to send a frame to this STA */ | 153 | int txrate_idx; |
110 | int last_nonerp_idx; | 154 | /* last rates used to send a frame to this STA */ |
155 | int last_txrate_idx, last_nonerp_txrate_idx; | ||
111 | 156 | ||
112 | struct net_device *dev; /* which net device is this station associated | 157 | struct net_device *dev; /* which net device is this station associated |
113 | * to */ | 158 | * to */ |
@@ -132,8 +177,6 @@ struct sta_info { | |||
132 | int last_rssi; /* RSSI of last received frame from this STA */ | 177 | int last_rssi; /* RSSI of last received frame from this STA */ |
133 | int last_signal; /* signal of last received frame from this STA */ | 178 | int last_signal; /* signal of last received frame from this STA */ |
134 | int last_noise; /* noise of last received frame from this STA */ | 179 | int last_noise; /* noise of last received frame from this STA */ |
135 | int last_ack_rssi[3]; /* RSSI of last received ACKs from this STA */ | ||
136 | unsigned long last_ack; | ||
137 | int channel_use; | 180 | int channel_use; |
138 | int channel_use_raw; | 181 | int channel_use_raw; |
139 | 182 | ||
@@ -148,20 +191,20 @@ struct sta_info { | |||
148 | of this STA */ | 191 | of this STA */ |
149 | struct sta_ampdu_mlme ampdu_mlme; | 192 | struct sta_ampdu_mlme ampdu_mlme; |
150 | u8 timer_to_tid[STA_TID_NUM]; /* convert timer id to tid */ | 193 | u8 timer_to_tid[STA_TID_NUM]; /* convert timer id to tid */ |
194 | u8 tid_to_tx_q[STA_TID_NUM]; /* map tid to tx queue */ | ||
151 | 195 | ||
152 | #ifdef CONFIG_MAC80211_DEBUGFS | 196 | #ifdef CONFIG_MAC80211_DEBUGFS |
153 | struct sta_info_debugfsdentries { | 197 | struct sta_info_debugfsdentries { |
154 | struct dentry *dir; | 198 | struct dentry *dir; |
155 | struct dentry *flags; | 199 | struct dentry *flags; |
156 | struct dentry *num_ps_buf_frames; | 200 | struct dentry *num_ps_buf_frames; |
157 | struct dentry *last_ack_rssi; | ||
158 | struct dentry *last_ack_ms; | ||
159 | struct dentry *inactive_ms; | 201 | struct dentry *inactive_ms; |
160 | struct dentry *last_seq_ctrl; | 202 | struct dentry *last_seq_ctrl; |
161 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 203 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
162 | struct dentry *wme_rx_queue; | 204 | struct dentry *wme_rx_queue; |
163 | struct dentry *wme_tx_queue; | 205 | struct dentry *wme_tx_queue; |
164 | #endif | 206 | #endif |
207 | struct dentry *agg_status; | ||
165 | } debugfs; | 208 | } debugfs; |
166 | #endif | 209 | #endif |
167 | }; | 210 | }; |
@@ -191,16 +234,17 @@ static inline void __sta_info_get(struct sta_info *sta) | |||
191 | } | 234 | } |
192 | 235 | ||
193 | struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr); | 236 | struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr); |
194 | int sta_info_min_txrate_get(struct ieee80211_local *local); | ||
195 | void sta_info_put(struct sta_info *sta); | 237 | void sta_info_put(struct sta_info *sta); |
196 | struct sta_info * sta_info_add(struct ieee80211_local *local, | 238 | struct sta_info *sta_info_add(struct ieee80211_local *local, |
197 | struct net_device *dev, u8 *addr, gfp_t gfp); | 239 | struct net_device *dev, u8 *addr, gfp_t gfp); |
198 | void sta_info_remove(struct sta_info *sta); | 240 | void sta_info_remove(struct sta_info *sta); |
199 | void sta_info_free(struct sta_info *sta); | 241 | void sta_info_free(struct sta_info *sta); |
200 | void sta_info_init(struct ieee80211_local *local); | 242 | void sta_info_init(struct ieee80211_local *local); |
201 | int sta_info_start(struct ieee80211_local *local); | 243 | int sta_info_start(struct ieee80211_local *local); |
202 | void sta_info_stop(struct ieee80211_local *local); | 244 | void sta_info_stop(struct ieee80211_local *local); |
203 | void sta_info_remove_aid_ptr(struct sta_info *sta); | ||
204 | void sta_info_flush(struct ieee80211_local *local, struct net_device *dev); | 245 | void sta_info_flush(struct ieee80211_local *local, struct net_device *dev); |
205 | 246 | ||
247 | void sta_info_set_tim_bit(struct sta_info *sta); | ||
248 | void sta_info_clear_tim_bit(struct sta_info *sta); | ||
249 | |||
206 | #endif /* STA_INFO_H */ | 250 | #endif /* STA_INFO_H */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 67b509edd431..1cd58e01f1ee 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -92,9 +92,13 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
92 | int rate, mrate, erp, dur, i; | 92 | int rate, mrate, erp, dur, i; |
93 | struct ieee80211_rate *txrate = tx->u.tx.rate; | 93 | struct ieee80211_rate *txrate = tx->u.tx.rate; |
94 | struct ieee80211_local *local = tx->local; | 94 | struct ieee80211_local *local = tx->local; |
95 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | 95 | struct ieee80211_supported_band *sband; |
96 | 96 | ||
97 | erp = txrate->flags & IEEE80211_RATE_ERP; | 97 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
98 | |||
99 | erp = 0; | ||
100 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
101 | erp = txrate->flags & IEEE80211_RATE_ERP_G; | ||
98 | 102 | ||
99 | /* | 103 | /* |
100 | * data and mgmt (except PS Poll): | 104 | * data and mgmt (except PS Poll): |
@@ -150,20 +154,36 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
150 | * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps | 154 | * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps |
151 | */ | 155 | */ |
152 | rate = -1; | 156 | rate = -1; |
153 | mrate = 10; /* use 1 Mbps if everything fails */ | 157 | /* use lowest available if everything fails */ |
154 | for (i = 0; i < mode->num_rates; i++) { | 158 | mrate = sband->bitrates[0].bitrate; |
155 | struct ieee80211_rate *r = &mode->rates[i]; | 159 | for (i = 0; i < sband->n_bitrates; i++) { |
156 | if (r->rate > txrate->rate) | 160 | struct ieee80211_rate *r = &sband->bitrates[i]; |
157 | break; | ||
158 | 161 | ||
159 | if (IEEE80211_RATE_MODULATION(txrate->flags) != | 162 | if (r->bitrate > txrate->bitrate) |
160 | IEEE80211_RATE_MODULATION(r->flags)) | 163 | break; |
161 | continue; | ||
162 | 164 | ||
163 | if (r->flags & IEEE80211_RATE_BASIC) | 165 | if (tx->sdata->basic_rates & BIT(i)) |
164 | rate = r->rate; | 166 | rate = r->bitrate; |
165 | else if (r->flags & IEEE80211_RATE_MANDATORY) | 167 | |
166 | mrate = r->rate; | 168 | switch (sband->band) { |
169 | case IEEE80211_BAND_2GHZ: { | ||
170 | u32 flag; | ||
171 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
172 | flag = IEEE80211_RATE_MANDATORY_G; | ||
173 | else | ||
174 | flag = IEEE80211_RATE_MANDATORY_B; | ||
175 | if (r->flags & flag) | ||
176 | mrate = r->bitrate; | ||
177 | break; | ||
178 | } | ||
179 | case IEEE80211_BAND_5GHZ: | ||
180 | if (r->flags & IEEE80211_RATE_MANDATORY_A) | ||
181 | mrate = r->bitrate; | ||
182 | break; | ||
183 | case IEEE80211_NUM_BANDS: | ||
184 | WARN_ON(1); | ||
185 | break; | ||
186 | } | ||
167 | } | 187 | } |
168 | if (rate == -1) { | 188 | if (rate == -1) { |
169 | /* No matching basic rate found; use highest suitable mandatory | 189 | /* No matching basic rate found; use highest suitable mandatory |
@@ -184,7 +204,7 @@ static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, | |||
184 | dur *= 2; /* ACK + SIFS */ | 204 | dur *= 2; /* ACK + SIFS */ |
185 | /* next fragment */ | 205 | /* next fragment */ |
186 | dur += ieee80211_frame_duration(local, next_frag_len, | 206 | dur += ieee80211_frame_duration(local, next_frag_len, |
187 | txrate->rate, erp, | 207 | txrate->bitrate, erp, |
188 | tx->sdata->bss_conf.use_short_preamble); | 208 | tx->sdata->bss_conf.use_short_preamble); |
189 | } | 209 | } |
190 | 210 | ||
@@ -212,7 +232,7 @@ static int inline is_ieee80211_device(struct net_device *dev, | |||
212 | 232 | ||
213 | /* tx handlers */ | 233 | /* tx handlers */ |
214 | 234 | ||
215 | static ieee80211_txrx_result | 235 | static ieee80211_tx_result |
216 | ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) | 236 | ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) |
217 | { | 237 | { |
218 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 238 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
@@ -222,15 +242,15 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) | |||
222 | u32 sta_flags; | 242 | u32 sta_flags; |
223 | 243 | ||
224 | if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) | 244 | if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) |
225 | return TXRX_CONTINUE; | 245 | return TX_CONTINUE; |
226 | 246 | ||
227 | if (unlikely(tx->local->sta_sw_scanning) && | 247 | if (unlikely(tx->local->sta_sw_scanning) && |
228 | ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 248 | ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || |
229 | (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ)) | 249 | (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ)) |
230 | return TXRX_DROP; | 250 | return TX_DROP; |
231 | 251 | ||
232 | if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED) | 252 | if (tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED) |
233 | return TXRX_CONTINUE; | 253 | return TX_CONTINUE; |
234 | 254 | ||
235 | sta_flags = tx->sta ? tx->sta->flags : 0; | 255 | sta_flags = tx->sta ? tx->sta->flags : 0; |
236 | 256 | ||
@@ -245,7 +265,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) | |||
245 | tx->dev->name, print_mac(mac, hdr->addr1)); | 265 | tx->dev->name, print_mac(mac, hdr->addr1)); |
246 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 266 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
247 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 267 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
248 | return TXRX_DROP; | 268 | return TX_DROP; |
249 | } | 269 | } |
250 | } else { | 270 | } else { |
251 | if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 271 | if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && |
@@ -255,15 +275,15 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) | |||
255 | * No associated STAs - no need to send multicast | 275 | * No associated STAs - no need to send multicast |
256 | * frames. | 276 | * frames. |
257 | */ | 277 | */ |
258 | return TXRX_DROP; | 278 | return TX_DROP; |
259 | } | 279 | } |
260 | return TXRX_CONTINUE; | 280 | return TX_CONTINUE; |
261 | } | 281 | } |
262 | 282 | ||
263 | return TXRX_CONTINUE; | 283 | return TX_CONTINUE; |
264 | } | 284 | } |
265 | 285 | ||
266 | static ieee80211_txrx_result | 286 | static ieee80211_tx_result |
267 | ieee80211_tx_h_sequence(struct ieee80211_txrx_data *tx) | 287 | ieee80211_tx_h_sequence(struct ieee80211_txrx_data *tx) |
268 | { | 288 | { |
269 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 289 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
@@ -271,7 +291,7 @@ ieee80211_tx_h_sequence(struct ieee80211_txrx_data *tx) | |||
271 | if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) | 291 | if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) |
272 | ieee80211_include_sequence(tx->sdata, hdr); | 292 | ieee80211_include_sequence(tx->sdata, hdr); |
273 | 293 | ||
274 | return TXRX_CONTINUE; | 294 | return TX_CONTINUE; |
275 | } | 295 | } |
276 | 296 | ||
277 | /* This function is called whenever the AP is about to exceed the maximum limit | 297 | /* This function is called whenever the AP is about to exceed the maximum limit |
@@ -321,7 +341,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
321 | wiphy_name(local->hw.wiphy), purged); | 341 | wiphy_name(local->hw.wiphy), purged); |
322 | } | 342 | } |
323 | 343 | ||
324 | static ieee80211_txrx_result | 344 | static ieee80211_tx_result |
325 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) | 345 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) |
326 | { | 346 | { |
327 | /* | 347 | /* |
@@ -334,11 +354,11 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
334 | 354 | ||
335 | /* not AP/IBSS or ordered frame */ | 355 | /* not AP/IBSS or ordered frame */ |
336 | if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER)) | 356 | if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER)) |
337 | return TXRX_CONTINUE; | 357 | return TX_CONTINUE; |
338 | 358 | ||
339 | /* no stations in PS mode */ | 359 | /* no stations in PS mode */ |
340 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) | 360 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) |
341 | return TXRX_CONTINUE; | 361 | return TX_CONTINUE; |
342 | 362 | ||
343 | /* buffered in mac80211 */ | 363 | /* buffered in mac80211 */ |
344 | if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) { | 364 | if (tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING) { |
@@ -355,16 +375,16 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
355 | } else | 375 | } else |
356 | tx->local->total_ps_buffered++; | 376 | tx->local->total_ps_buffered++; |
357 | skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); | 377 | skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); |
358 | return TXRX_QUEUED; | 378 | return TX_QUEUED; |
359 | } | 379 | } |
360 | 380 | ||
361 | /* buffered in hardware */ | 381 | /* buffered in hardware */ |
362 | tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM; | 382 | tx->u.tx.control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM; |
363 | 383 | ||
364 | return TXRX_CONTINUE; | 384 | return TX_CONTINUE; |
365 | } | 385 | } |
366 | 386 | ||
367 | static ieee80211_txrx_result | 387 | static ieee80211_tx_result |
368 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | 388 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) |
369 | { | 389 | { |
370 | struct sta_info *sta = tx->sta; | 390 | struct sta_info *sta = tx->sta; |
@@ -373,9 +393,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
373 | if (unlikely(!sta || | 393 | if (unlikely(!sta || |
374 | ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && | 394 | ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && |
375 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) | 395 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) |
376 | return TXRX_CONTINUE; | 396 | return TX_CONTINUE; |
377 | 397 | ||
378 | if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) { | 398 | if (unlikely((sta->flags & WLAN_STA_PS) && |
399 | !(sta->flags & WLAN_STA_PSPOLL))) { | ||
379 | struct ieee80211_tx_packet_data *pkt_data; | 400 | struct ieee80211_tx_packet_data *pkt_data; |
380 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 401 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
381 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 402 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " |
@@ -383,7 +404,6 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
383 | print_mac(mac, sta->addr), sta->aid, | 404 | print_mac(mac, sta->addr), sta->aid, |
384 | skb_queue_len(&sta->ps_tx_buf)); | 405 | skb_queue_len(&sta->ps_tx_buf)); |
385 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 406 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
386 | sta->flags |= WLAN_STA_TIM; | ||
387 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 407 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
388 | purge_old_ps_buffers(tx->local); | 408 | purge_old_ps_buffers(tx->local); |
389 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 409 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { |
@@ -396,18 +416,15 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
396 | dev_kfree_skb(old); | 416 | dev_kfree_skb(old); |
397 | } else | 417 | } else |
398 | tx->local->total_ps_buffered++; | 418 | tx->local->total_ps_buffered++; |
419 | |||
399 | /* Queue frame to be sent after STA sends an PS Poll frame */ | 420 | /* Queue frame to be sent after STA sends an PS Poll frame */ |
400 | if (skb_queue_empty(&sta->ps_tx_buf)) { | 421 | if (skb_queue_empty(&sta->ps_tx_buf)) |
401 | if (tx->local->ops->set_tim) | 422 | sta_info_set_tim_bit(sta); |
402 | tx->local->ops->set_tim(local_to_hw(tx->local), | 423 | |
403 | sta->aid, 1); | ||
404 | if (tx->sdata->bss) | ||
405 | bss_tim_set(tx->local, tx->sdata->bss, sta->aid); | ||
406 | } | ||
407 | pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; | 424 | pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; |
408 | pkt_data->jiffies = jiffies; | 425 | pkt_data->jiffies = jiffies; |
409 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 426 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
410 | return TXRX_QUEUED; | 427 | return TX_QUEUED; |
411 | } | 428 | } |
412 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 429 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
413 | else if (unlikely(sta->flags & WLAN_STA_PS)) { | 430 | else if (unlikely(sta->flags & WLAN_STA_PS)) { |
@@ -416,16 +433,16 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) | |||
416 | print_mac(mac, sta->addr)); | 433 | print_mac(mac, sta->addr)); |
417 | } | 434 | } |
418 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 435 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
419 | sta->pspoll = 0; | 436 | sta->flags &= ~WLAN_STA_PSPOLL; |
420 | 437 | ||
421 | return TXRX_CONTINUE; | 438 | return TX_CONTINUE; |
422 | } | 439 | } |
423 | 440 | ||
424 | static ieee80211_txrx_result | 441 | static ieee80211_tx_result |
425 | ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx) | 442 | ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx) |
426 | { | 443 | { |
427 | if (unlikely(tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED)) | 444 | if (unlikely(tx->flags & IEEE80211_TXRXD_TXPS_BUFFERED)) |
428 | return TXRX_CONTINUE; | 445 | return TX_CONTINUE; |
429 | 446 | ||
430 | if (tx->flags & IEEE80211_TXRXD_TXUNICAST) | 447 | if (tx->flags & IEEE80211_TXRXD_TXUNICAST) |
431 | return ieee80211_tx_h_unicast_ps_buf(tx); | 448 | return ieee80211_tx_h_unicast_ps_buf(tx); |
@@ -433,7 +450,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx) | |||
433 | return ieee80211_tx_h_multicast_ps_buf(tx); | 450 | return ieee80211_tx_h_multicast_ps_buf(tx); |
434 | } | 451 | } |
435 | 452 | ||
436 | static ieee80211_txrx_result | 453 | static ieee80211_tx_result |
437 | ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | 454 | ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) |
438 | { | 455 | { |
439 | struct ieee80211_key *key; | 456 | struct ieee80211_key *key; |
@@ -449,7 +466,7 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | |||
449 | !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) && | 466 | !(tx->u.tx.control->flags & IEEE80211_TXCTL_EAPOL_FRAME) && |
450 | !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) { | 467 | !(tx->flags & IEEE80211_TXRXD_TX_INJECTED)) { |
451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 468 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
452 | return TXRX_DROP; | 469 | return TX_DROP; |
453 | } else | 470 | } else |
454 | tx->key = NULL; | 471 | tx->key = NULL; |
455 | 472 | ||
@@ -478,10 +495,10 @@ ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) | |||
478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 495 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
479 | tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 496 | tx->u.tx.control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; |
480 | 497 | ||
481 | return TXRX_CONTINUE; | 498 | return TX_CONTINUE; |
482 | } | 499 | } |
483 | 500 | ||
484 | static ieee80211_txrx_result | 501 | static ieee80211_tx_result |
485 | ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | 502 | ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) |
486 | { | 503 | { |
487 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 504 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; |
@@ -493,7 +510,7 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | |||
493 | int frag_threshold = tx->local->fragmentation_threshold; | 510 | int frag_threshold = tx->local->fragmentation_threshold; |
494 | 511 | ||
495 | if (!(tx->flags & IEEE80211_TXRXD_FRAGMENTED)) | 512 | if (!(tx->flags & IEEE80211_TXRXD_FRAGMENTED)) |
496 | return TXRX_CONTINUE; | 513 | return TX_CONTINUE; |
497 | 514 | ||
498 | first = tx->skb; | 515 | first = tx->skb; |
499 | 516 | ||
@@ -547,7 +564,7 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | |||
547 | tx->u.tx.num_extra_frag = num_fragm - 1; | 564 | tx->u.tx.num_extra_frag = num_fragm - 1; |
548 | tx->u.tx.extra_frag = frags; | 565 | tx->u.tx.extra_frag = frags; |
549 | 566 | ||
550 | return TXRX_CONTINUE; | 567 | return TX_CONTINUE; |
551 | 568 | ||
552 | fail: | 569 | fail: |
553 | printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); | 570 | printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); |
@@ -558,14 +575,14 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) | |||
558 | kfree(frags); | 575 | kfree(frags); |
559 | } | 576 | } |
560 | I802_DEBUG_INC(tx->local->tx_handlers_drop_fragment); | 577 | I802_DEBUG_INC(tx->local->tx_handlers_drop_fragment); |
561 | return TXRX_DROP; | 578 | return TX_DROP; |
562 | } | 579 | } |
563 | 580 | ||
564 | static ieee80211_txrx_result | 581 | static ieee80211_tx_result |
565 | ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx) | 582 | ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx) |
566 | { | 583 | { |
567 | if (!tx->key) | 584 | if (!tx->key) |
568 | return TXRX_CONTINUE; | 585 | return TX_CONTINUE; |
569 | 586 | ||
570 | switch (tx->key->conf.alg) { | 587 | switch (tx->key->conf.alg) { |
571 | case ALG_WEP: | 588 | case ALG_WEP: |
@@ -578,33 +595,35 @@ ieee80211_tx_h_encrypt(struct ieee80211_txrx_data *tx) | |||
578 | 595 | ||
579 | /* not reached */ | 596 | /* not reached */ |
580 | WARN_ON(1); | 597 | WARN_ON(1); |
581 | return TXRX_DROP; | 598 | return TX_DROP; |
582 | } | 599 | } |
583 | 600 | ||
584 | static ieee80211_txrx_result | 601 | static ieee80211_tx_result |
585 | ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | 602 | ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) |
586 | { | 603 | { |
587 | struct rate_selection rsel; | 604 | struct rate_selection rsel; |
605 | struct ieee80211_supported_band *sband; | ||
606 | |||
607 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
588 | 608 | ||
589 | if (likely(!tx->u.tx.rate)) { | 609 | if (likely(!tx->u.tx.rate)) { |
590 | rate_control_get_rate(tx->dev, tx->u.tx.mode, tx->skb, &rsel); | 610 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); |
591 | tx->u.tx.rate = rsel.rate; | 611 | tx->u.tx.rate = rsel.rate; |
592 | if (unlikely(rsel.probe != NULL)) { | 612 | if (unlikely(rsel.probe)) { |
593 | tx->u.tx.control->flags |= | 613 | tx->u.tx.control->flags |= |
594 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 614 | IEEE80211_TXCTL_RATE_CTRL_PROBE; |
595 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; | 615 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; |
596 | tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; | 616 | tx->u.tx.control->alt_retry_rate = tx->u.tx.rate; |
597 | tx->u.tx.rate = rsel.probe; | 617 | tx->u.tx.rate = rsel.probe; |
598 | } else | 618 | } else |
599 | tx->u.tx.control->alt_retry_rate = -1; | 619 | tx->u.tx.control->alt_retry_rate = NULL; |
600 | 620 | ||
601 | if (!tx->u.tx.rate) | 621 | if (!tx->u.tx.rate) |
602 | return TXRX_DROP; | 622 | return TX_DROP; |
603 | } else | 623 | } else |
604 | tx->u.tx.control->alt_retry_rate = -1; | 624 | tx->u.tx.control->alt_retry_rate = NULL; |
605 | 625 | ||
606 | if (tx->u.tx.mode->mode == MODE_IEEE80211G && | 626 | if (tx->sdata->bss_conf.use_cts_prot && |
607 | tx->sdata->bss_conf.use_cts_prot && | ||
608 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { | 627 | (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && rsel.nonerp) { |
609 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 628 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
610 | if (rsel.probe) | 629 | if (rsel.probe) |
@@ -612,25 +631,24 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) | |||
612 | else | 631 | else |
613 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; | 632 | tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; |
614 | tx->u.tx.rate = rsel.nonerp; | 633 | tx->u.tx.rate = rsel.nonerp; |
615 | tx->u.tx.control->rate = rsel.nonerp; | 634 | tx->u.tx.control->tx_rate = rsel.nonerp; |
616 | tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | 635 | tx->u.tx.control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; |
617 | } else { | 636 | } else { |
618 | tx->u.tx.last_frag_rate = tx->u.tx.rate; | 637 | tx->u.tx.last_frag_rate = tx->u.tx.rate; |
619 | tx->u.tx.control->rate = tx->u.tx.rate; | 638 | tx->u.tx.control->tx_rate = tx->u.tx.rate; |
620 | } | 639 | } |
621 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val; | 640 | tx->u.tx.control->tx_rate = tx->u.tx.rate; |
622 | 641 | ||
623 | return TXRX_CONTINUE; | 642 | return TX_CONTINUE; |
624 | } | 643 | } |
625 | 644 | ||
626 | static ieee80211_txrx_result | 645 | static ieee80211_tx_result |
627 | ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | 646 | ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) |
628 | { | 647 | { |
629 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 648 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; |
630 | u16 fc = le16_to_cpu(hdr->frame_control); | 649 | u16 fc = le16_to_cpu(hdr->frame_control); |
631 | u16 dur; | 650 | u16 dur; |
632 | struct ieee80211_tx_control *control = tx->u.tx.control; | 651 | struct ieee80211_tx_control *control = tx->u.tx.control; |
633 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | ||
634 | 652 | ||
635 | if (!control->retry_limit) { | 653 | if (!control->retry_limit) { |
636 | if (!is_multicast_ether_addr(hdr->addr1)) { | 654 | if (!is_multicast_ether_addr(hdr->addr1)) { |
@@ -657,14 +675,14 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
657 | * frames. | 675 | * frames. |
658 | * TODO: The last fragment could still use multiple retry | 676 | * TODO: The last fragment could still use multiple retry |
659 | * rates. */ | 677 | * rates. */ |
660 | control->alt_retry_rate = -1; | 678 | control->alt_retry_rate = NULL; |
661 | } | 679 | } |
662 | 680 | ||
663 | /* Use CTS protection for unicast frames sent using extended rates if | 681 | /* Use CTS protection for unicast frames sent using extended rates if |
664 | * there are associated non-ERP stations and RTS/CTS is not configured | 682 | * there are associated non-ERP stations and RTS/CTS is not configured |
665 | * for the frame. */ | 683 | * for the frame. */ |
666 | if (mode->mode == MODE_IEEE80211G && | 684 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && |
667 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && | 685 | (tx->u.tx.rate->flags & IEEE80211_RATE_ERP_G) && |
668 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && | 686 | (tx->flags & IEEE80211_TXRXD_TXUNICAST) && |
669 | tx->sdata->bss_conf.use_cts_prot && | 687 | tx->sdata->bss_conf.use_cts_prot && |
670 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | 688 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) |
@@ -674,10 +692,10 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
674 | * short preambles at the selected rate and short preambles are | 692 | * short preambles at the selected rate and short preambles are |
675 | * available on the network at the current point in time. */ | 693 | * available on the network at the current point in time. */ |
676 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 694 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
677 | (tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) && | 695 | (tx->u.tx.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
678 | tx->sdata->bss_conf.use_short_preamble && | 696 | tx->sdata->bss_conf.use_short_preamble && |
679 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | 697 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { |
680 | tx->u.tx.control->tx_rate = tx->u.tx.rate->val2; | 698 | tx->u.tx.control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
681 | } | 699 | } |
682 | 700 | ||
683 | /* Setup duration field for the first fragment of the frame. Duration | 701 | /* Setup duration field for the first fragment of the frame. Duration |
@@ -690,19 +708,33 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
690 | 708 | ||
691 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || | 709 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || |
692 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { | 710 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { |
693 | struct ieee80211_rate *rate; | 711 | struct ieee80211_supported_band *sband; |
712 | struct ieee80211_rate *rate, *baserate; | ||
713 | int idx; | ||
714 | |||
715 | sband = tx->local->hw.wiphy->bands[ | ||
716 | tx->local->hw.conf.channel->band]; | ||
694 | 717 | ||
695 | /* Do not use multiple retry rates when using RTS/CTS */ | 718 | /* Do not use multiple retry rates when using RTS/CTS */ |
696 | control->alt_retry_rate = -1; | 719 | control->alt_retry_rate = NULL; |
697 | 720 | ||
698 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | 721 | /* Use min(data rate, max base rate) as CTS/RTS rate */ |
699 | rate = tx->u.tx.rate; | 722 | rate = tx->u.tx.rate; |
700 | while (rate > mode->rates && | 723 | baserate = NULL; |
701 | !(rate->flags & IEEE80211_RATE_BASIC)) | ||
702 | rate--; | ||
703 | 724 | ||
704 | control->rts_cts_rate = rate->val; | 725 | for (idx = 0; idx < sband->n_bitrates; idx++) { |
705 | control->rts_rate = rate; | 726 | if (sband->bitrates[idx].bitrate > rate->bitrate) |
727 | continue; | ||
728 | if (tx->sdata->basic_rates & BIT(idx) && | ||
729 | (!baserate || | ||
730 | (baserate->bitrate < sband->bitrates[idx].bitrate))) | ||
731 | baserate = &sband->bitrates[idx]; | ||
732 | } | ||
733 | |||
734 | if (baserate) | ||
735 | control->rts_cts_rate = baserate; | ||
736 | else | ||
737 | control->rts_cts_rate = &sband->bitrates[0]; | ||
706 | } | 738 | } |
707 | 739 | ||
708 | if (tx->sta) { | 740 | if (tx->sta) { |
@@ -719,17 +751,17 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) | |||
719 | } | 751 | } |
720 | } | 752 | } |
721 | 753 | ||
722 | return TXRX_CONTINUE; | 754 | return TX_CONTINUE; |
723 | } | 755 | } |
724 | 756 | ||
725 | static ieee80211_txrx_result | 757 | static ieee80211_tx_result |
726 | ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | 758 | ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) |
727 | { | 759 | { |
728 | struct ieee80211_local *local = tx->local; | 760 | struct ieee80211_local *local = tx->local; |
729 | struct ieee80211_hw_mode *mode = tx->u.tx.mode; | ||
730 | struct sk_buff *skb = tx->skb; | 761 | struct sk_buff *skb = tx->skb; |
731 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 762 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
732 | u32 load = 0, hdrtime; | 763 | u32 load = 0, hdrtime; |
764 | struct ieee80211_rate *rate = tx->u.tx.rate; | ||
733 | 765 | ||
734 | /* TODO: this could be part of tx_status handling, so that the number | 766 | /* TODO: this could be part of tx_status handling, so that the number |
735 | * of retries would be known; TX rate should in that case be stored | 767 | * of retries would be known; TX rate should in that case be stored |
@@ -740,9 +772,9 @@ ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | |||
740 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | 772 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, |
741 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | 773 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ |
742 | 774 | ||
743 | if (mode->mode == MODE_IEEE80211A || | 775 | if (tx->u.tx.channel->band == IEEE80211_BAND_5GHZ || |
744 | (mode->mode == MODE_IEEE80211G && | 776 | (tx->u.tx.channel->band == IEEE80211_BAND_2GHZ && |
745 | tx->u.tx.rate->flags & IEEE80211_RATE_ERP)) | 777 | rate->flags & IEEE80211_RATE_ERP_G)) |
746 | hdrtime = CHAN_UTIL_HDR_SHORT; | 778 | hdrtime = CHAN_UTIL_HDR_SHORT; |
747 | else | 779 | else |
748 | hdrtime = CHAN_UTIL_HDR_LONG; | 780 | hdrtime = CHAN_UTIL_HDR_LONG; |
@@ -756,14 +788,15 @@ ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | |||
756 | else if (tx->u.tx.control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 788 | else if (tx->u.tx.control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
757 | load += hdrtime; | 789 | load += hdrtime; |
758 | 790 | ||
759 | load += skb->len * tx->u.tx.rate->rate_inv; | 791 | /* TODO: optimise again */ |
792 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
760 | 793 | ||
761 | if (tx->u.tx.extra_frag) { | 794 | if (tx->u.tx.extra_frag) { |
762 | int i; | 795 | int i; |
763 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { | 796 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { |
764 | load += 2 * hdrtime; | 797 | load += 2 * hdrtime; |
765 | load += tx->u.tx.extra_frag[i]->len * | 798 | load += tx->u.tx.extra_frag[i]->len * |
766 | tx->u.tx.rate->rate; | 799 | tx->u.tx.rate->bitrate; |
767 | } | 800 | } |
768 | } | 801 | } |
769 | 802 | ||
@@ -774,13 +807,12 @@ ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) | |||
774 | tx->sta->channel_use_raw += load; | 807 | tx->sta->channel_use_raw += load; |
775 | tx->sdata->channel_use_raw += load; | 808 | tx->sdata->channel_use_raw += load; |
776 | 809 | ||
777 | return TXRX_CONTINUE; | 810 | return TX_CONTINUE; |
778 | } | 811 | } |
779 | 812 | ||
780 | /* TODO: implement register/unregister functions for adding TX/RX handlers | ||
781 | * into ordered list */ | ||
782 | 813 | ||
783 | ieee80211_tx_handler ieee80211_tx_handlers[] = | 814 | typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_txrx_data *); |
815 | static ieee80211_tx_handler ieee80211_tx_handlers[] = | ||
784 | { | 816 | { |
785 | ieee80211_tx_h_check_assoc, | 817 | ieee80211_tx_h_check_assoc, |
786 | ieee80211_tx_h_sequence, | 818 | ieee80211_tx_h_sequence, |
@@ -801,7 +833,7 @@ ieee80211_tx_handler ieee80211_tx_handlers[] = | |||
801 | * deal with packet injection down monitor interface | 833 | * deal with packet injection down monitor interface |
802 | * with Radiotap Header -- only called for monitor mode interface | 834 | * with Radiotap Header -- only called for monitor mode interface |
803 | */ | 835 | */ |
804 | static ieee80211_txrx_result | 836 | static ieee80211_tx_result |
805 | __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | 837 | __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, |
806 | struct sk_buff *skb) | 838 | struct sk_buff *skb) |
807 | { | 839 | { |
@@ -816,10 +848,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
816 | struct ieee80211_radiotap_iterator iterator; | 848 | struct ieee80211_radiotap_iterator iterator; |
817 | struct ieee80211_radiotap_header *rthdr = | 849 | struct ieee80211_radiotap_header *rthdr = |
818 | (struct ieee80211_radiotap_header *) skb->data; | 850 | (struct ieee80211_radiotap_header *) skb->data; |
819 | struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode; | 851 | struct ieee80211_supported_band *sband; |
820 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 852 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
821 | struct ieee80211_tx_control *control = tx->u.tx.control; | 853 | struct ieee80211_tx_control *control = tx->u.tx.control; |
822 | 854 | ||
855 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
856 | |||
823 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 857 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; |
824 | tx->flags |= IEEE80211_TXRXD_TX_INJECTED; | 858 | tx->flags |= IEEE80211_TXRXD_TX_INJECTED; |
825 | tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED; | 859 | tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED; |
@@ -852,10 +886,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
852 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps | 886 | * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps |
853 | */ | 887 | */ |
854 | target_rate = (*iterator.this_arg) * 5; | 888 | target_rate = (*iterator.this_arg) * 5; |
855 | for (i = 0; i < mode->num_rates; i++) { | 889 | for (i = 0; i < sband->n_bitrates; i++) { |
856 | struct ieee80211_rate *r = &mode->rates[i]; | 890 | struct ieee80211_rate *r; |
891 | |||
892 | r = &sband->bitrates[i]; | ||
857 | 893 | ||
858 | if (r->rate == target_rate) { | 894 | if (r->bitrate == target_rate) { |
859 | tx->u.tx.rate = r; | 895 | tx->u.tx.rate = r; |
860 | break; | 896 | break; |
861 | } | 897 | } |
@@ -870,9 +906,11 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
870 | control->antenna_sel_tx = (*iterator.this_arg) + 1; | 906 | control->antenna_sel_tx = (*iterator.this_arg) + 1; |
871 | break; | 907 | break; |
872 | 908 | ||
909 | #if 0 | ||
873 | case IEEE80211_RADIOTAP_DBM_TX_POWER: | 910 | case IEEE80211_RADIOTAP_DBM_TX_POWER: |
874 | control->power_level = *iterator.this_arg; | 911 | control->power_level = *iterator.this_arg; |
875 | break; | 912 | break; |
913 | #endif | ||
876 | 914 | ||
877 | case IEEE80211_RADIOTAP_FLAGS: | 915 | case IEEE80211_RADIOTAP_FLAGS: |
878 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { | 916 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) { |
@@ -884,7 +922,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
884 | * on transmission | 922 | * on transmission |
885 | */ | 923 | */ |
886 | if (skb->len < (iterator.max_length + FCS_LEN)) | 924 | if (skb->len < (iterator.max_length + FCS_LEN)) |
887 | return TXRX_DROP; | 925 | return TX_DROP; |
888 | 926 | ||
889 | skb_trim(skb, skb->len - FCS_LEN); | 927 | skb_trim(skb, skb->len - FCS_LEN); |
890 | } | 928 | } |
@@ -907,7 +945,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
907 | } | 945 | } |
908 | 946 | ||
909 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ | 947 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ |
910 | return TXRX_DROP; | 948 | return TX_DROP; |
911 | 949 | ||
912 | /* | 950 | /* |
913 | * remove the radiotap header | 951 | * remove the radiotap header |
@@ -916,13 +954,13 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx, | |||
916 | */ | 954 | */ |
917 | skb_pull(skb, iterator.max_length); | 955 | skb_pull(skb, iterator.max_length); |
918 | 956 | ||
919 | return TXRX_CONTINUE; | 957 | return TX_CONTINUE; |
920 | } | 958 | } |
921 | 959 | ||
922 | /* | 960 | /* |
923 | * initialises @tx | 961 | * initialises @tx |
924 | */ | 962 | */ |
925 | static ieee80211_txrx_result | 963 | static ieee80211_tx_result |
926 | __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | 964 | __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, |
927 | struct sk_buff *skb, | 965 | struct sk_buff *skb, |
928 | struct net_device *dev, | 966 | struct net_device *dev, |
@@ -949,8 +987,8 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
949 | /* process and remove the injection radiotap header */ | 987 | /* process and remove the injection radiotap header */ |
950 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 988 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
951 | if (unlikely(sdata->vif.type == IEEE80211_IF_TYPE_MNTR)) { | 989 | if (unlikely(sdata->vif.type == IEEE80211_IF_TYPE_MNTR)) { |
952 | if (__ieee80211_parse_tx_radiotap(tx, skb) == TXRX_DROP) | 990 | if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) |
953 | return TXRX_DROP; | 991 | return TX_DROP; |
954 | 992 | ||
955 | /* | 993 | /* |
956 | * __ieee80211_parse_tx_radiotap has now removed | 994 | * __ieee80211_parse_tx_radiotap has now removed |
@@ -982,10 +1020,10 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
982 | } | 1020 | } |
983 | 1021 | ||
984 | if (!tx->sta) | 1022 | if (!tx->sta) |
985 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; | 1023 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
986 | else if (tx->sta->clear_dst_mask) { | 1024 | else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { |
987 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; | 1025 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
988 | tx->sta->clear_dst_mask = 0; | 1026 | tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT; |
989 | } | 1027 | } |
990 | 1028 | ||
991 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1029 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
@@ -995,7 +1033,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, | |||
995 | } | 1033 | } |
996 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; | 1034 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; |
997 | 1035 | ||
998 | return TXRX_CONTINUE; | 1036 | return TX_CONTINUE; |
999 | } | 1037 | } |
1000 | 1038 | ||
1001 | /* | 1039 | /* |
@@ -1046,7 +1084,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1046 | if (tx->u.tx.extra_frag) { | 1084 | if (tx->u.tx.extra_frag) { |
1047 | control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | | 1085 | control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | |
1048 | IEEE80211_TXCTL_USE_CTS_PROTECT | | 1086 | IEEE80211_TXCTL_USE_CTS_PROTECT | |
1049 | IEEE80211_TXCTL_CLEAR_DST_MASK | | 1087 | IEEE80211_TXCTL_CLEAR_PS_FILT | |
1050 | IEEE80211_TXCTL_FIRST_FRAGMENT); | 1088 | IEEE80211_TXCTL_FIRST_FRAGMENT); |
1051 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { | 1089 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { |
1052 | if (!tx->u.tx.extra_frag[i]) | 1090 | if (!tx->u.tx.extra_frag[i]) |
@@ -1054,8 +1092,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1054 | if (__ieee80211_queue_stopped(local, control->queue)) | 1092 | if (__ieee80211_queue_stopped(local, control->queue)) |
1055 | return IEEE80211_TX_FRAG_AGAIN; | 1093 | return IEEE80211_TX_FRAG_AGAIN; |
1056 | if (i == tx->u.tx.num_extra_frag) { | 1094 | if (i == tx->u.tx.num_extra_frag) { |
1057 | control->tx_rate = tx->u.tx.last_frag_hwrate; | 1095 | control->tx_rate = tx->u.tx.last_frag_rate; |
1058 | control->rate = tx->u.tx.last_frag_rate; | 1096 | |
1059 | if (tx->flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG) | 1097 | if (tx->flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG) |
1060 | control->flags |= | 1098 | control->flags |= |
1061 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1099 | IEEE80211_TXCTL_RATE_CTRL_PROBE; |
@@ -1089,7 +1127,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1089 | struct sta_info *sta; | 1127 | struct sta_info *sta; |
1090 | ieee80211_tx_handler *handler; | 1128 | ieee80211_tx_handler *handler; |
1091 | struct ieee80211_txrx_data tx; | 1129 | struct ieee80211_txrx_data tx; |
1092 | ieee80211_txrx_result res = TXRX_DROP, res_prepare; | 1130 | ieee80211_tx_result res = TX_DROP, res_prepare; |
1093 | int ret, i; | 1131 | int ret, i; |
1094 | 1132 | ||
1095 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); | 1133 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); |
@@ -1102,7 +1140,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1102 | /* initialises tx */ | 1140 | /* initialises tx */ |
1103 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); | 1141 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); |
1104 | 1142 | ||
1105 | if (res_prepare == TXRX_DROP) { | 1143 | if (res_prepare == TX_DROP) { |
1106 | dev_kfree_skb(skb); | 1144 | dev_kfree_skb(skb); |
1107 | return 0; | 1145 | return 0; |
1108 | } | 1146 | } |
@@ -1114,12 +1152,12 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1114 | rcu_read_lock(); | 1152 | rcu_read_lock(); |
1115 | 1153 | ||
1116 | sta = tx.sta; | 1154 | sta = tx.sta; |
1117 | tx.u.tx.mode = local->hw.conf.mode; | 1155 | tx.u.tx.channel = local->hw.conf.channel; |
1118 | 1156 | ||
1119 | for (handler = local->tx_handlers; *handler != NULL; | 1157 | for (handler = ieee80211_tx_handlers; *handler != NULL; |
1120 | handler++) { | 1158 | handler++) { |
1121 | res = (*handler)(&tx); | 1159 | res = (*handler)(&tx); |
1122 | if (res != TXRX_CONTINUE) | 1160 | if (res != TX_CONTINUE) |
1123 | break; | 1161 | break; |
1124 | } | 1162 | } |
1125 | 1163 | ||
@@ -1128,12 +1166,12 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1128 | if (sta) | 1166 | if (sta) |
1129 | sta_info_put(sta); | 1167 | sta_info_put(sta); |
1130 | 1168 | ||
1131 | if (unlikely(res == TXRX_DROP)) { | 1169 | if (unlikely(res == TX_DROP)) { |
1132 | I802_DEBUG_INC(local->tx_handlers_drop); | 1170 | I802_DEBUG_INC(local->tx_handlers_drop); |
1133 | goto drop; | 1171 | goto drop; |
1134 | } | 1172 | } |
1135 | 1173 | ||
1136 | if (unlikely(res == TXRX_QUEUED)) { | 1174 | if (unlikely(res == TX_QUEUED)) { |
1137 | I802_DEBUG_INC(local->tx_handlers_queued); | 1175 | I802_DEBUG_INC(local->tx_handlers_queued); |
1138 | rcu_read_unlock(); | 1176 | rcu_read_unlock(); |
1139 | return 0; | 1177 | return 0; |
@@ -1151,7 +1189,6 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1151 | } else { | 1189 | } else { |
1152 | next_len = 0; | 1190 | next_len = 0; |
1153 | tx.u.tx.rate = tx.u.tx.last_frag_rate; | 1191 | tx.u.tx.rate = tx.u.tx.last_frag_rate; |
1154 | tx.u.tx.last_frag_hwrate = tx.u.tx.rate->val; | ||
1155 | } | 1192 | } |
1156 | dur = ieee80211_duration(&tx, 0, next_len); | 1193 | dur = ieee80211_duration(&tx, 0, next_len); |
1157 | hdr->duration_id = cpu_to_le16(dur); | 1194 | hdr->duration_id = cpu_to_le16(dur); |
@@ -1188,7 +1225,6 @@ retry: | |||
1188 | store->skb = skb; | 1225 | store->skb = skb; |
1189 | store->extra_frag = tx.u.tx.extra_frag; | 1226 | store->extra_frag = tx.u.tx.extra_frag; |
1190 | store->num_extra_frag = tx.u.tx.num_extra_frag; | 1227 | store->num_extra_frag = tx.u.tx.num_extra_frag; |
1191 | store->last_frag_hwrate = tx.u.tx.last_frag_hwrate; | ||
1192 | store->last_frag_rate = tx.u.tx.last_frag_rate; | 1228 | store->last_frag_rate = tx.u.tx.last_frag_rate; |
1193 | store->last_frag_rate_ctrl_probe = | 1229 | store->last_frag_rate_ctrl_probe = |
1194 | !!(tx.flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG); | 1230 | !!(tx.flags & IEEE80211_TXRXD_TXPROBE_LAST_FRAG); |
@@ -1260,6 +1296,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1260 | control.flags |= IEEE80211_TXCTL_REQUEUE; | 1296 | control.flags |= IEEE80211_TXCTL_REQUEUE; |
1261 | if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME) | 1297 | if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME) |
1262 | control.flags |= IEEE80211_TXCTL_EAPOL_FRAME; | 1298 | control.flags |= IEEE80211_TXCTL_EAPOL_FRAME; |
1299 | if (pkt_data->flags & IEEE80211_TXPD_AMPDU) | ||
1300 | control.flags |= IEEE80211_TXCTL_AMPDU; | ||
1263 | control.queue = pkt_data->queue; | 1301 | control.queue = pkt_data->queue; |
1264 | 1302 | ||
1265 | ret = ieee80211_tx(odev, skb, &control); | 1303 | ret = ieee80211_tx(odev, skb, &control); |
@@ -1409,10 +1447,17 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1409 | goto fail; | 1447 | goto fail; |
1410 | } | 1448 | } |
1411 | 1449 | ||
1412 | sta = sta_info_get(local, hdr.addr1); | 1450 | /* |
1413 | if (sta) { | 1451 | * There's no need to try to look up the destination |
1414 | sta_flags = sta->flags; | 1452 | * if it is a multicast address (which can only happen |
1415 | sta_info_put(sta); | 1453 | * in AP mode) |
1454 | */ | ||
1455 | if (!is_multicast_ether_addr(hdr.addr1)) { | ||
1456 | sta = sta_info_get(local, hdr.addr1); | ||
1457 | if (sta) { | ||
1458 | sta_flags = sta->flags; | ||
1459 | sta_info_put(sta); | ||
1460 | } | ||
1416 | } | 1461 | } |
1417 | 1462 | ||
1418 | /* receiver is QoS enabled, use a QoS type frame */ | 1463 | /* receiver is QoS enabled, use a QoS type frame */ |
@@ -1422,10 +1467,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1422 | } | 1467 | } |
1423 | 1468 | ||
1424 | /* | 1469 | /* |
1425 | * If port access control is enabled, drop frames to unauthorised | 1470 | * Drop unicast frames to unauthorised stations unless they are |
1426 | * stations unless they are EAPOL frames from the local station. | 1471 | * EAPOL frames from the local station. |
1427 | */ | 1472 | */ |
1428 | if (unlikely(sdata->ieee802_1x_pac && | 1473 | if (unlikely(!is_multicast_ether_addr(hdr.addr1) && |
1429 | !(sta_flags & WLAN_STA_AUTHORIZED) && | 1474 | !(sta_flags & WLAN_STA_AUTHORIZED) && |
1430 | !(ethertype == ETH_P_PAE && | 1475 | !(ethertype == ETH_P_PAE && |
1431 | compare_ether_addr(dev->dev_addr, | 1476 | compare_ether_addr(dev->dev_addr, |
@@ -1598,7 +1643,6 @@ void ieee80211_tx_pending(unsigned long data) | |||
1598 | tx.u.tx.control = &store->control; | 1643 | tx.u.tx.control = &store->control; |
1599 | tx.u.tx.extra_frag = store->extra_frag; | 1644 | tx.u.tx.extra_frag = store->extra_frag; |
1600 | tx.u.tx.num_extra_frag = store->num_extra_frag; | 1645 | tx.u.tx.num_extra_frag = store->num_extra_frag; |
1601 | tx.u.tx.last_frag_hwrate = store->last_frag_hwrate; | ||
1602 | tx.u.tx.last_frag_rate = store->last_frag_rate; | 1646 | tx.u.tx.last_frag_rate = store->last_frag_rate; |
1603 | tx.flags = 0; | 1647 | tx.flags = 0; |
1604 | if (store->last_frag_rate_ctrl_probe) | 1648 | if (store->last_frag_rate_ctrl_probe) |
@@ -1701,6 +1745,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1701 | struct ieee80211_if_ap *ap = NULL; | 1745 | struct ieee80211_if_ap *ap = NULL; |
1702 | struct rate_selection rsel; | 1746 | struct rate_selection rsel; |
1703 | struct beacon_data *beacon; | 1747 | struct beacon_data *beacon; |
1748 | struct ieee80211_supported_band *sband; | ||
1749 | |||
1750 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1704 | 1751 | ||
1705 | rcu_read_lock(); | 1752 | rcu_read_lock(); |
1706 | 1753 | ||
@@ -1739,8 +1786,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1739 | beacon->tail_len); | 1786 | beacon->tail_len); |
1740 | 1787 | ||
1741 | if (control) { | 1788 | if (control) { |
1742 | rate_control_get_rate(local->mdev, local->oper_hw_mode, skb, | 1789 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1743 | &rsel); | ||
1744 | if (!rsel.rate) { | 1790 | if (!rsel.rate) { |
1745 | if (net_ratelimit()) { | 1791 | if (net_ratelimit()) { |
1746 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1792 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " |
@@ -1753,15 +1799,14 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1753 | } | 1799 | } |
1754 | 1800 | ||
1755 | control->vif = vif; | 1801 | control->vif = vif; |
1756 | control->tx_rate = | 1802 | control->tx_rate = rsel.rate; |
1757 | (sdata->bss_conf.use_short_preamble && | 1803 | if (sdata->bss_conf.use_short_preamble && |
1758 | (rsel.rate->flags & IEEE80211_RATE_PREAMBLE2)) ? | 1804 | rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) |
1759 | rsel.rate->val2 : rsel.rate->val; | 1805 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; |
1760 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1806 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
1761 | control->power_level = local->hw.conf.power_level; | ||
1762 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 1807 | control->flags |= IEEE80211_TXCTL_NO_ACK; |
1763 | control->retry_limit = 1; | 1808 | control->retry_limit = 1; |
1764 | control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; | 1809 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; |
1765 | } | 1810 | } |
1766 | 1811 | ||
1767 | ap->num_beacons++; | 1812 | ap->num_beacons++; |
@@ -1815,7 +1860,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1815 | struct sta_info *sta; | 1860 | struct sta_info *sta; |
1816 | ieee80211_tx_handler *handler; | 1861 | ieee80211_tx_handler *handler; |
1817 | struct ieee80211_txrx_data tx; | 1862 | struct ieee80211_txrx_data tx; |
1818 | ieee80211_txrx_result res = TXRX_DROP; | 1863 | ieee80211_tx_result res = TX_DROP; |
1819 | struct net_device *bdev; | 1864 | struct net_device *bdev; |
1820 | struct ieee80211_sub_if_data *sdata; | 1865 | struct ieee80211_sub_if_data *sdata; |
1821 | struct ieee80211_if_ap *bss = NULL; | 1866 | struct ieee80211_if_ap *bss = NULL; |
@@ -1863,20 +1908,20 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1863 | } | 1908 | } |
1864 | sta = tx.sta; | 1909 | sta = tx.sta; |
1865 | tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED; | 1910 | tx.flags |= IEEE80211_TXRXD_TXPS_BUFFERED; |
1866 | tx.u.tx.mode = local->hw.conf.mode; | 1911 | tx.u.tx.channel = local->hw.conf.channel; |
1867 | 1912 | ||
1868 | for (handler = local->tx_handlers; *handler != NULL; handler++) { | 1913 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { |
1869 | res = (*handler)(&tx); | 1914 | res = (*handler)(&tx); |
1870 | if (res == TXRX_DROP || res == TXRX_QUEUED) | 1915 | if (res == TX_DROP || res == TX_QUEUED) |
1871 | break; | 1916 | break; |
1872 | } | 1917 | } |
1873 | skb = tx.skb; /* handlers are allowed to change skb */ | 1918 | skb = tx.skb; /* handlers are allowed to change skb */ |
1874 | 1919 | ||
1875 | if (res == TXRX_DROP) { | 1920 | if (res == TX_DROP) { |
1876 | I802_DEBUG_INC(local->tx_handlers_drop); | 1921 | I802_DEBUG_INC(local->tx_handlers_drop); |
1877 | dev_kfree_skb(skb); | 1922 | dev_kfree_skb(skb); |
1878 | skb = NULL; | 1923 | skb = NULL; |
1879 | } else if (res == TXRX_QUEUED) { | 1924 | } else if (res == TX_QUEUED) { |
1880 | I802_DEBUG_INC(local->tx_handlers_queued); | 1925 | I802_DEBUG_INC(local->tx_handlers_queued); |
1881 | skb = NULL; | 1926 | skb = NULL; |
1882 | } | 1927 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5e631ce98d7e..f64804fed0a9 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -41,92 +41,6 @@ const unsigned char bridge_tunnel_header[] = | |||
41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; | 41 | { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; |
42 | 42 | ||
43 | 43 | ||
44 | static int rate_list_match(const int *rate_list, int rate) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | if (!rate_list) | ||
49 | return 0; | ||
50 | |||
51 | for (i = 0; rate_list[i] >= 0; i++) | ||
52 | if (rate_list[i] == rate) | ||
53 | return 1; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | void ieee80211_prepare_rates(struct ieee80211_local *local, | ||
59 | struct ieee80211_hw_mode *mode) | ||
60 | { | ||
61 | int i; | ||
62 | |||
63 | for (i = 0; i < mode->num_rates; i++) { | ||
64 | struct ieee80211_rate *rate = &mode->rates[i]; | ||
65 | |||
66 | rate->flags &= ~(IEEE80211_RATE_SUPPORTED | | ||
67 | IEEE80211_RATE_BASIC); | ||
68 | |||
69 | if (local->supp_rates[mode->mode]) { | ||
70 | if (!rate_list_match(local->supp_rates[mode->mode], | ||
71 | rate->rate)) | ||
72 | continue; | ||
73 | } | ||
74 | |||
75 | rate->flags |= IEEE80211_RATE_SUPPORTED; | ||
76 | |||
77 | /* Use configured basic rate set if it is available. If not, | ||
78 | * use defaults that are sane for most cases. */ | ||
79 | if (local->basic_rates[mode->mode]) { | ||
80 | if (rate_list_match(local->basic_rates[mode->mode], | ||
81 | rate->rate)) | ||
82 | rate->flags |= IEEE80211_RATE_BASIC; | ||
83 | } else switch (mode->mode) { | ||
84 | case MODE_IEEE80211A: | ||
85 | if (rate->rate == 60 || rate->rate == 120 || | ||
86 | rate->rate == 240) | ||
87 | rate->flags |= IEEE80211_RATE_BASIC; | ||
88 | break; | ||
89 | case MODE_IEEE80211B: | ||
90 | if (rate->rate == 10 || rate->rate == 20) | ||
91 | rate->flags |= IEEE80211_RATE_BASIC; | ||
92 | break; | ||
93 | case MODE_IEEE80211G: | ||
94 | if (rate->rate == 10 || rate->rate == 20 || | ||
95 | rate->rate == 55 || rate->rate == 110) | ||
96 | rate->flags |= IEEE80211_RATE_BASIC; | ||
97 | break; | ||
98 | case NUM_IEEE80211_MODES: | ||
99 | /* not useful */ | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | /* Set ERP and MANDATORY flags based on phymode */ | ||
104 | switch (mode->mode) { | ||
105 | case MODE_IEEE80211A: | ||
106 | if (rate->rate == 60 || rate->rate == 120 || | ||
107 | rate->rate == 240) | ||
108 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
109 | break; | ||
110 | case MODE_IEEE80211B: | ||
111 | if (rate->rate == 10) | ||
112 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
113 | break; | ||
114 | case MODE_IEEE80211G: | ||
115 | if (rate->rate == 10 || rate->rate == 20 || | ||
116 | rate->rate == 55 || rate->rate == 110 || | ||
117 | rate->rate == 60 || rate->rate == 120 || | ||
118 | rate->rate == 240) | ||
119 | rate->flags |= IEEE80211_RATE_MANDATORY; | ||
120 | break; | ||
121 | case NUM_IEEE80211_MODES: | ||
122 | /* not useful */ | ||
123 | break; | ||
124 | } | ||
125 | if (ieee80211_is_erp_rate(mode->mode, rate->rate)) | ||
126 | rate->flags |= IEEE80211_RATE_ERP; | ||
127 | } | ||
128 | } | ||
129 | |||
130 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 44 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
131 | enum ieee80211_if_types type) | 45 | enum ieee80211_if_types type) |
132 | { | 46 | { |
@@ -262,7 +176,7 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
262 | * DIV_ROUND_UP() operations. | 176 | * DIV_ROUND_UP() operations. |
263 | */ | 177 | */ |
264 | 178 | ||
265 | if (local->hw.conf.phymode == MODE_IEEE80211A || erp) { | 179 | if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) { |
266 | /* | 180 | /* |
267 | * OFDM: | 181 | * OFDM: |
268 | * | 182 | * |
@@ -304,15 +218,19 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
304 | /* Exported duration function for driver use */ | 218 | /* Exported duration function for driver use */ |
305 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, | 219 | __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, |
306 | struct ieee80211_vif *vif, | 220 | struct ieee80211_vif *vif, |
307 | size_t frame_len, int rate) | 221 | size_t frame_len, |
222 | struct ieee80211_rate *rate) | ||
308 | { | 223 | { |
309 | struct ieee80211_local *local = hw_to_local(hw); | 224 | struct ieee80211_local *local = hw_to_local(hw); |
310 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 225 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
311 | u16 dur; | 226 | u16 dur; |
312 | int erp; | 227 | int erp; |
313 | 228 | ||
314 | erp = ieee80211_is_erp_rate(hw->conf.phymode, rate); | 229 | erp = 0; |
315 | dur = ieee80211_frame_duration(local, frame_len, rate, erp, | 230 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
231 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
232 | |||
233 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, | ||
316 | sdata->bss_conf.use_short_preamble); | 234 | sdata->bss_conf.use_short_preamble); |
317 | 235 | ||
318 | return cpu_to_le16(dur); | 236 | return cpu_to_le16(dur); |
@@ -332,17 +250,20 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
332 | 250 | ||
333 | short_preamble = sdata->bss_conf.use_short_preamble; | 251 | short_preamble = sdata->bss_conf.use_short_preamble; |
334 | 252 | ||
335 | rate = frame_txctl->rts_rate; | 253 | rate = frame_txctl->rts_cts_rate; |
336 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 254 | |
255 | erp = 0; | ||
256 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
257 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
337 | 258 | ||
338 | /* CTS duration */ | 259 | /* CTS duration */ |
339 | dur = ieee80211_frame_duration(local, 10, rate->rate, | 260 | dur = ieee80211_frame_duration(local, 10, rate->bitrate, |
340 | erp, short_preamble); | 261 | erp, short_preamble); |
341 | /* Data frame duration */ | 262 | /* Data frame duration */ |
342 | dur += ieee80211_frame_duration(local, frame_len, rate->rate, | 263 | dur += ieee80211_frame_duration(local, frame_len, rate->bitrate, |
343 | erp, short_preamble); | 264 | erp, short_preamble); |
344 | /* ACK duration */ | 265 | /* ACK duration */ |
345 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 266 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
346 | erp, short_preamble); | 267 | erp, short_preamble); |
347 | 268 | ||
348 | return cpu_to_le16(dur); | 269 | return cpu_to_le16(dur); |
@@ -363,15 +284,17 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
363 | 284 | ||
364 | short_preamble = sdata->bss_conf.use_short_preamble; | 285 | short_preamble = sdata->bss_conf.use_short_preamble; |
365 | 286 | ||
366 | rate = frame_txctl->rts_rate; | 287 | rate = frame_txctl->rts_cts_rate; |
367 | erp = !!(rate->flags & IEEE80211_RATE_ERP); | 288 | erp = 0; |
289 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | ||
290 | erp = rate->flags & IEEE80211_RATE_ERP_G; | ||
368 | 291 | ||
369 | /* Data frame duration */ | 292 | /* Data frame duration */ |
370 | dur = ieee80211_frame_duration(local, frame_len, rate->rate, | 293 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, |
371 | erp, short_preamble); | 294 | erp, short_preamble); |
372 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { | 295 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { |
373 | /* ACK duration */ | 296 | /* ACK duration */ |
374 | dur += ieee80211_frame_duration(local, 10, rate->rate, | 297 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
375 | erp, short_preamble); | 298 | erp, short_preamble); |
376 | } | 299 | } |
377 | 300 | ||
@@ -379,27 +302,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
379 | } | 302 | } |
380 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); | 303 | EXPORT_SYMBOL(ieee80211_ctstoself_duration); |
381 | 304 | ||
382 | struct ieee80211_rate * | ||
383 | ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) | ||
384 | { | ||
385 | struct ieee80211_hw_mode *mode; | ||
386 | int r; | ||
387 | |||
388 | list_for_each_entry(mode, &local->modes_list, list) { | ||
389 | if (mode->mode != phymode) | ||
390 | continue; | ||
391 | for (r = 0; r < mode->num_rates; r++) { | ||
392 | struct ieee80211_rate *rate = &mode->rates[r]; | ||
393 | if (rate->val == hw_rate || | ||
394 | (rate->flags & IEEE80211_RATE_PREAMBLE2 && | ||
395 | rate->val2 == hw_rate)) | ||
396 | return rate; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return NULL; | ||
401 | } | ||
402 | |||
403 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | 305 | void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) |
404 | { | 306 | { |
405 | struct ieee80211_local *local = hw_to_local(hw); | 307 | struct ieee80211_local *local = hw_to_local(hw); |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index a0cff72a580b..a33ef5cfa9ad 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -305,13 +305,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | |||
305 | return NULL; | 305 | return NULL; |
306 | } | 306 | } |
307 | 307 | ||
308 | ieee80211_txrx_result | 308 | ieee80211_rx_result |
309 | ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) | 309 | ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) |
310 | { | 310 | { |
311 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 311 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
312 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 312 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || |
313 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) | 313 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) |
314 | return TXRX_CONTINUE; | 314 | return RX_CONTINUE; |
315 | 315 | ||
316 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { | 316 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { |
317 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 317 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { |
@@ -320,7 +320,7 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) | |||
320 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | 320 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " |
321 | "failed\n", rx->dev->name); | 321 | "failed\n", rx->dev->name); |
322 | #endif /* CONFIG_MAC80211_DEBUG */ | 322 | #endif /* CONFIG_MAC80211_DEBUG */ |
323 | return TXRX_DROP; | 323 | return RX_DROP_UNUSABLE; |
324 | } | 324 | } |
325 | } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { | 325 | } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { |
326 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 326 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
@@ -328,7 +328,7 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx) | |||
328 | skb_trim(rx->skb, rx->skb->len - 4); | 328 | skb_trim(rx->skb, rx->skb->len - 4); |
329 | } | 329 | } |
330 | 330 | ||
331 | return TXRX_CONTINUE; | 331 | return RX_CONTINUE; |
332 | } | 332 | } |
333 | 333 | ||
334 | static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) | 334 | static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) |
@@ -346,7 +346,7 @@ static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) | |||
346 | return 0; | 346 | return 0; |
347 | } | 347 | } |
348 | 348 | ||
349 | ieee80211_txrx_result | 349 | ieee80211_tx_result |
350 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) | 350 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) |
351 | { | 351 | { |
352 | tx->u.tx.control->iv_len = WEP_IV_LEN; | 352 | tx->u.tx.control->iv_len = WEP_IV_LEN; |
@@ -355,7 +355,7 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) | |||
355 | 355 | ||
356 | if (wep_encrypt_skb(tx, tx->skb) < 0) { | 356 | if (wep_encrypt_skb(tx, tx->skb) < 0) { |
357 | I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); | 357 | I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); |
358 | return TXRX_DROP; | 358 | return TX_DROP; |
359 | } | 359 | } |
360 | 360 | ||
361 | if (tx->u.tx.extra_frag) { | 361 | if (tx->u.tx.extra_frag) { |
@@ -364,10 +364,10 @@ ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx) | |||
364 | if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) { | 364 | if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) { |
365 | I802_DEBUG_INC(tx->local-> | 365 | I802_DEBUG_INC(tx->local-> |
366 | tx_handlers_drop_wep); | 366 | tx_handlers_drop_wep); |
367 | return TXRX_DROP; | 367 | return TX_DROP; |
368 | } | 368 | } |
369 | } | 369 | } |
370 | } | 370 | } |
371 | 371 | ||
372 | return TXRX_CONTINUE; | 372 | return TX_CONTINUE; |
373 | } | 373 | } |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 785fbb4e0dd7..43aef50cd0d6 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
@@ -28,9 +28,9 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
28 | struct ieee80211_key *key); | 28 | struct ieee80211_key *key); |
29 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 29 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
30 | 30 | ||
31 | ieee80211_txrx_result | 31 | ieee80211_rx_result |
32 | ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx); | 32 | ieee80211_crypto_wep_decrypt(struct ieee80211_txrx_data *rx); |
33 | ieee80211_txrx_result | 33 | ieee80211_tx_result |
34 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx); | 34 | ieee80211_crypto_wep_encrypt(struct ieee80211_txrx_data *tx); |
35 | 35 | ||
36 | #endif /* WEP_H */ | 36 | #endif /* WEP_H */ |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 4e236599dd31..8cc036decc82 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -19,10 +19,13 @@ | |||
19 | #include "wme.h" | 19 | #include "wme.h" |
20 | 20 | ||
21 | /* maximum number of hardware queues we support. */ | 21 | /* maximum number of hardware queues we support. */ |
22 | #define TC_80211_MAX_QUEUES 8 | 22 | #define TC_80211_MAX_QUEUES 16 |
23 | |||
24 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | ||
23 | 25 | ||
24 | struct ieee80211_sched_data | 26 | struct ieee80211_sched_data |
25 | { | 27 | { |
28 | unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)]; | ||
26 | struct tcf_proto *filter_list; | 29 | struct tcf_proto *filter_list; |
27 | struct Qdisc *queues[TC_80211_MAX_QUEUES]; | 30 | struct Qdisc *queues[TC_80211_MAX_QUEUES]; |
28 | struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; | 31 | struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; |
@@ -98,7 +101,6 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) | |||
98 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 101 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
99 | unsigned short fc = le16_to_cpu(hdr->frame_control); | 102 | unsigned short fc = le16_to_cpu(hdr->frame_control); |
100 | int qos; | 103 | int qos; |
101 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | ||
102 | 104 | ||
103 | /* see if frame is data or non data frame */ | 105 | /* see if frame is data or non data frame */ |
104 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { | 106 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { |
@@ -146,9 +148,25 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
146 | unsigned short fc = le16_to_cpu(hdr->frame_control); | 148 | unsigned short fc = le16_to_cpu(hdr->frame_control); |
147 | struct Qdisc *qdisc; | 149 | struct Qdisc *qdisc; |
148 | int err, queue; | 150 | int err, queue; |
151 | struct sta_info *sta; | ||
152 | u8 tid; | ||
149 | 153 | ||
150 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { | 154 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { |
151 | skb_queue_tail(&q->requeued[pkt_data->queue], skb); | 155 | queue = pkt_data->queue; |
156 | sta = sta_info_get(local, hdr->addr1); | ||
157 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | ||
158 | if (sta) { | ||
159 | int ampdu_queue = sta->tid_to_tx_q[tid]; | ||
160 | if ((ampdu_queue < local->hw.queues) && | ||
161 | test_bit(ampdu_queue, q->qdisc_pool)) { | ||
162 | queue = ampdu_queue; | ||
163 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | ||
164 | } else { | ||
165 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | ||
166 | } | ||
167 | sta_info_put(sta); | ||
168 | } | ||
169 | skb_queue_tail(&q->requeued[queue], skb); | ||
152 | qd->q.qlen++; | 170 | qd->q.qlen++; |
153 | return 0; | 171 | return 0; |
154 | } | 172 | } |
@@ -159,14 +177,28 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
159 | */ | 177 | */ |
160 | if (WLAN_FC_IS_QOS_DATA(fc)) { | 178 | if (WLAN_FC_IS_QOS_DATA(fc)) { |
161 | u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; | 179 | u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; |
162 | u8 qos_hdr = skb->priority & QOS_CONTROL_TAG1D_MASK; | 180 | u8 ack_policy = 0; |
181 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | ||
163 | if (local->wifi_wme_noack_test) | 182 | if (local->wifi_wme_noack_test) |
164 | qos_hdr |= QOS_CONTROL_ACK_POLICY_NOACK << | 183 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << |
165 | QOS_CONTROL_ACK_POLICY_SHIFT; | 184 | QOS_CONTROL_ACK_POLICY_SHIFT; |
166 | /* qos header is 2 bytes, second reserved */ | 185 | /* qos header is 2 bytes, second reserved */ |
167 | *p = qos_hdr; | 186 | *p = ack_policy | tid; |
168 | p++; | 187 | p++; |
169 | *p = 0; | 188 | *p = 0; |
189 | |||
190 | sta = sta_info_get(local, hdr->addr1); | ||
191 | if (sta) { | ||
192 | int ampdu_queue = sta->tid_to_tx_q[tid]; | ||
193 | if ((ampdu_queue < local->hw.queues) && | ||
194 | test_bit(ampdu_queue, q->qdisc_pool)) { | ||
195 | queue = ampdu_queue; | ||
196 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | ||
197 | } else { | ||
198 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | ||
199 | } | ||
200 | sta_info_put(sta); | ||
201 | } | ||
170 | } | 202 | } |
171 | 203 | ||
172 | if (unlikely(queue >= local->hw.queues)) { | 204 | if (unlikely(queue >= local->hw.queues)) { |
@@ -184,6 +216,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
184 | kfree_skb(skb); | 216 | kfree_skb(skb); |
185 | err = NET_XMIT_DROP; | 217 | err = NET_XMIT_DROP; |
186 | } else { | 218 | } else { |
219 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | ||
187 | pkt_data->queue = (unsigned int) queue; | 220 | pkt_data->queue = (unsigned int) queue; |
188 | qdisc = q->queues[queue]; | 221 | qdisc = q->queues[queue]; |
189 | err = qdisc->enqueue(skb, qdisc); | 222 | err = qdisc->enqueue(skb, qdisc); |
@@ -235,10 +268,11 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd) | |||
235 | /* check all the h/w queues in numeric/priority order */ | 268 | /* check all the h/w queues in numeric/priority order */ |
236 | for (queue = 0; queue < hw->queues; queue++) { | 269 | for (queue = 0; queue < hw->queues; queue++) { |
237 | /* see if there is room in this hardware queue */ | 270 | /* see if there is room in this hardware queue */ |
238 | if (test_bit(IEEE80211_LINK_STATE_XOFF, | 271 | if ((test_bit(IEEE80211_LINK_STATE_XOFF, |
239 | &local->state[queue]) || | 272 | &local->state[queue])) || |
240 | test_bit(IEEE80211_LINK_STATE_PENDING, | 273 | (test_bit(IEEE80211_LINK_STATE_PENDING, |
241 | &local->state[queue])) | 274 | &local->state[queue])) || |
275 | (!test_bit(queue, q->qdisc_pool))) | ||
242 | continue; | 276 | continue; |
243 | 277 | ||
244 | /* there is space - try and get a frame */ | 278 | /* there is space - try and get a frame */ |
@@ -360,6 +394,10 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | |||
360 | } | 394 | } |
361 | } | 395 | } |
362 | 396 | ||
397 | /* reserve all legacy QoS queues */ | ||
398 | for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++) | ||
399 | set_bit(i, q->qdisc_pool); | ||
400 | |||
363 | return err; | 401 | return err; |
364 | } | 402 | } |
365 | 403 | ||
@@ -605,3 +643,80 @@ void ieee80211_wme_unregister(void) | |||
605 | { | 643 | { |
606 | unregister_qdisc(&wme_qdisc_ops); | 644 | unregister_qdisc(&wme_qdisc_ops); |
607 | } | 645 | } |
646 | |||
647 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | ||
648 | struct sta_info *sta, u16 tid) | ||
649 | { | ||
650 | int i; | ||
651 | struct ieee80211_sched_data *q = | ||
652 | qdisc_priv(local->mdev->qdisc_sleeping); | ||
653 | DECLARE_MAC_BUF(mac); | ||
654 | |||
655 | /* prepare the filter and save it for the SW queue | ||
656 | * matching the recieved HW queue */ | ||
657 | |||
658 | /* try to get a Qdisc from the pool */ | ||
659 | for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++) | ||
660 | if (!test_and_set_bit(i, q->qdisc_pool)) { | ||
661 | ieee80211_stop_queue(local_to_hw(local), i); | ||
662 | sta->tid_to_tx_q[tid] = i; | ||
663 | |||
664 | /* IF there are already pending packets | ||
665 | * on this tid first we need to drain them | ||
666 | * on the previous queue | ||
667 | * since HT is strict in order */ | ||
668 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
669 | if (net_ratelimit()) | ||
670 | printk(KERN_DEBUG "allocated aggregation queue" | ||
671 | " %d tid %d addr %s pool=0x%lX", | ||
672 | i, tid, print_mac(mac, sta->addr), | ||
673 | q->qdisc_pool[0]); | ||
674 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
675 | return 0; | ||
676 | } | ||
677 | |||
678 | return -EAGAIN; | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * the caller needs to hold local->mdev->queue_lock | ||
683 | */ | ||
684 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | ||
685 | struct sta_info *sta, u16 tid, | ||
686 | u8 requeue) | ||
687 | { | ||
688 | struct ieee80211_sched_data *q = | ||
689 | qdisc_priv(local->mdev->qdisc_sleeping); | ||
690 | int agg_queue = sta->tid_to_tx_q[tid]; | ||
691 | |||
692 | /* return the qdisc to the pool */ | ||
693 | clear_bit(agg_queue, q->qdisc_pool); | ||
694 | sta->tid_to_tx_q[tid] = local->hw.queues; | ||
695 | |||
696 | if (requeue) | ||
697 | ieee80211_requeue(local, agg_queue); | ||
698 | else | ||
699 | q->queues[agg_queue]->ops->reset(q->queues[agg_queue]); | ||
700 | } | ||
701 | |||
702 | void ieee80211_requeue(struct ieee80211_local *local, int queue) | ||
703 | { | ||
704 | struct Qdisc *root_qd = local->mdev->qdisc_sleeping; | ||
705 | struct ieee80211_sched_data *q = qdisc_priv(root_qd); | ||
706 | struct Qdisc *qdisc = q->queues[queue]; | ||
707 | struct sk_buff *skb = NULL; | ||
708 | u32 len = qdisc->q.qlen; | ||
709 | |||
710 | if (!qdisc || !qdisc->dequeue) | ||
711 | return; | ||
712 | |||
713 | printk(KERN_DEBUG "requeue: qlen = %d\n", qdisc->q.qlen); | ||
714 | for (len = qdisc->q.qlen; len > 0; len--) { | ||
715 | skb = qdisc->dequeue(qdisc); | ||
716 | root_qd->q.qlen--; | ||
717 | /* packet will be classified again and */ | ||
718 | /* skb->packet_data->queue will be overridden if needed */ | ||
719 | if (skb) | ||
720 | wme_qdiscop_enqueue(skb, root_qd); | ||
721 | } | ||
722 | } | ||
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index 76c713a6450c..fcc6b05508cc 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h | |||
@@ -24,6 +24,8 @@ | |||
24 | 24 | ||
25 | #define QOS_CONTROL_TAG1D_MASK 0x07 | 25 | #define QOS_CONTROL_TAG1D_MASK 0x07 |
26 | 26 | ||
27 | extern const int ieee802_1d_to_ac[8]; | ||
28 | |||
27 | static inline int WLAN_FC_IS_QOS_DATA(u16 fc) | 29 | static inline int WLAN_FC_IS_QOS_DATA(u16 fc) |
28 | { | 30 | { |
29 | return (fc & 0x8C) == 0x88; | 31 | return (fc & 0x8C) == 0x88; |
@@ -32,7 +34,12 @@ static inline int WLAN_FC_IS_QOS_DATA(u16 fc) | |||
32 | #ifdef CONFIG_NET_SCHED | 34 | #ifdef CONFIG_NET_SCHED |
33 | void ieee80211_install_qdisc(struct net_device *dev); | 35 | void ieee80211_install_qdisc(struct net_device *dev); |
34 | int ieee80211_qdisc_installed(struct net_device *dev); | 36 | int ieee80211_qdisc_installed(struct net_device *dev); |
35 | 37 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |
38 | struct sta_info *sta, u16 tid); | ||
39 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | ||
40 | struct sta_info *sta, u16 tid, | ||
41 | u8 requeue); | ||
42 | void ieee80211_requeue(struct ieee80211_local *local, int queue); | ||
36 | int ieee80211_wme_register(void); | 43 | int ieee80211_wme_register(void); |
37 | void ieee80211_wme_unregister(void); | 44 | void ieee80211_wme_unregister(void); |
38 | #else | 45 | #else |
@@ -43,7 +50,19 @@ static inline int ieee80211_qdisc_installed(struct net_device *dev) | |||
43 | { | 50 | { |
44 | return 0; | 51 | return 0; |
45 | } | 52 | } |
46 | 53 | static inline int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |
54 | struct sta_info *sta, u16 tid) | ||
55 | { | ||
56 | return -EAGAIN; | ||
57 | } | ||
58 | static inline void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | ||
59 | struct sta_info *sta, u16 tid, | ||
60 | u8 requeue) | ||
61 | { | ||
62 | } | ||
63 | static inline void ieee80211_requeue(struct ieee80211_local *local, int queue) | ||
64 | { | ||
65 | } | ||
47 | static inline int ieee80211_wme_register(void) | 66 | static inline int ieee80211_wme_register(void) |
48 | { | 67 | { |
49 | return 0; | 68 | return 0; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 6f04311cf0a0..b35e51c6ce0c 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -70,7 +70,7 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | |||
70 | } | 70 | } |
71 | 71 | ||
72 | 72 | ||
73 | ieee80211_txrx_result | 73 | ieee80211_tx_result |
74 | ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | 74 | ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) |
75 | { | 75 | { |
76 | u8 *data, *sa, *da, *key, *mic, qos_tid; | 76 | u8 *data, *sa, *da, *key, *mic, qos_tid; |
@@ -84,10 +84,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | |||
84 | 84 | ||
85 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || | 85 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || |
86 | !WLAN_FC_DATA_PRESENT(fc)) | 86 | !WLAN_FC_DATA_PRESENT(fc)) |
87 | return TXRX_CONTINUE; | 87 | return TX_CONTINUE; |
88 | 88 | ||
89 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) | 89 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) |
90 | return TXRX_DROP; | 90 | return TX_DROP; |
91 | 91 | ||
92 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 92 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
93 | !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && | 93 | !(tx->flags & IEEE80211_TXRXD_FRAGMENTED) && |
@@ -95,7 +95,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | |||
95 | !wpa_test) { | 95 | !wpa_test) { |
96 | /* hwaccel - with no need for preallocated room for Michael MIC | 96 | /* hwaccel - with no need for preallocated room for Michael MIC |
97 | */ | 97 | */ |
98 | return TXRX_CONTINUE; | 98 | return TX_CONTINUE; |
99 | } | 99 | } |
100 | 100 | ||
101 | if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { | 101 | if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { |
@@ -105,7 +105,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | |||
105 | GFP_ATOMIC))) { | 105 | GFP_ATOMIC))) { |
106 | printk(KERN_DEBUG "%s: failed to allocate more memory " | 106 | printk(KERN_DEBUG "%s: failed to allocate more memory " |
107 | "for Michael MIC\n", tx->dev->name); | 107 | "for Michael MIC\n", tx->dev->name); |
108 | return TXRX_DROP; | 108 | return TX_DROP; |
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
@@ -119,11 +119,11 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) | |||
119 | mic = skb_put(skb, MICHAEL_MIC_LEN); | 119 | mic = skb_put(skb, MICHAEL_MIC_LEN); |
120 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 120 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); |
121 | 121 | ||
122 | return TXRX_CONTINUE; | 122 | return TX_CONTINUE; |
123 | } | 123 | } |
124 | 124 | ||
125 | 125 | ||
126 | ieee80211_txrx_result | 126 | ieee80211_rx_result |
127 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | 127 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) |
128 | { | 128 | { |
129 | u8 *data, *sa, *da, *key = NULL, qos_tid; | 129 | u8 *data, *sa, *da, *key = NULL, qos_tid; |
@@ -140,15 +140,15 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
140 | * No way to verify the MIC if the hardware stripped it | 140 | * No way to verify the MIC if the hardware stripped it |
141 | */ | 141 | */ |
142 | if (rx->u.rx.status->flag & RX_FLAG_MMIC_STRIPPED) | 142 | if (rx->u.rx.status->flag & RX_FLAG_MMIC_STRIPPED) |
143 | return TXRX_CONTINUE; | 143 | return RX_CONTINUE; |
144 | 144 | ||
145 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 145 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
146 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) | 146 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) |
147 | return TXRX_CONTINUE; | 147 | return RX_CONTINUE; |
148 | 148 | ||
149 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) | 149 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) |
150 | || data_len < MICHAEL_MIC_LEN) | 150 | || data_len < MICHAEL_MIC_LEN) |
151 | return TXRX_DROP; | 151 | return RX_DROP_UNUSABLE; |
152 | 152 | ||
153 | data_len -= MICHAEL_MIC_LEN; | 153 | data_len -= MICHAEL_MIC_LEN; |
154 | 154 | ||
@@ -162,14 +162,14 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
162 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 162 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); |
163 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 163 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
164 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) | 164 | if (!(rx->flags & IEEE80211_TXRXD_RXRA_MATCH)) |
165 | return TXRX_DROP; | 165 | return RX_DROP_UNUSABLE; |
166 | 166 | ||
167 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " | 167 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " |
168 | "%s\n", rx->dev->name, print_mac(mac, sa)); | 168 | "%s\n", rx->dev->name, print_mac(mac, sa)); |
169 | 169 | ||
170 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, | 170 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, |
171 | (void *) skb->data); | 171 | (void *) skb->data); |
172 | return TXRX_DROP; | 172 | return RX_DROP_UNUSABLE; |
173 | } | 173 | } |
174 | 174 | ||
175 | /* remove Michael MIC from payload */ | 175 | /* remove Michael MIC from payload */ |
@@ -179,7 +179,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) | |||
179 | rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32; | 179 | rx->key->u.tkip.iv32_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv32; |
180 | rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16; | 180 | rx->key->u.tkip.iv16_rx[rx->u.rx.queue] = rx->u.rx.tkip_iv16; |
181 | 181 | ||
182 | return TXRX_CONTINUE; | 182 | return RX_CONTINUE; |
183 | } | 183 | } |
184 | 184 | ||
185 | 185 | ||
@@ -242,7 +242,7 @@ static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx, | |||
242 | } | 242 | } |
243 | 243 | ||
244 | 244 | ||
245 | ieee80211_txrx_result | 245 | ieee80211_tx_result |
246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx) | 246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx) |
247 | { | 247 | { |
248 | struct sk_buff *skb = tx->skb; | 248 | struct sk_buff *skb = tx->skb; |
@@ -257,26 +257,26 @@ ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx) | |||
257 | !wpa_test) { | 257 | !wpa_test) { |
258 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 258 | /* hwaccel - with no need for preallocated room for IV/ICV */ |
259 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; | 259 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; |
260 | return TXRX_CONTINUE; | 260 | return TX_CONTINUE; |
261 | } | 261 | } |
262 | 262 | ||
263 | if (tkip_encrypt_skb(tx, skb, test) < 0) | 263 | if (tkip_encrypt_skb(tx, skb, test) < 0) |
264 | return TXRX_DROP; | 264 | return TX_DROP; |
265 | 265 | ||
266 | if (tx->u.tx.extra_frag) { | 266 | if (tx->u.tx.extra_frag) { |
267 | int i; | 267 | int i; |
268 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { | 268 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { |
269 | if (tkip_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) | 269 | if (tkip_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) |
270 | < 0) | 270 | < 0) |
271 | return TXRX_DROP; | 271 | return TX_DROP; |
272 | } | 272 | } |
273 | } | 273 | } |
274 | 274 | ||
275 | return TXRX_CONTINUE; | 275 | return TX_CONTINUE; |
276 | } | 276 | } |
277 | 277 | ||
278 | 278 | ||
279 | ieee80211_txrx_result | 279 | ieee80211_rx_result |
280 | ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | 280 | ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) |
281 | { | 281 | { |
282 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 282 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
@@ -290,10 +290,10 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
290 | hdrlen = ieee80211_get_hdrlen(fc); | 290 | hdrlen = ieee80211_get_hdrlen(fc); |
291 | 291 | ||
292 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 292 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
293 | return TXRX_CONTINUE; | 293 | return RX_CONTINUE; |
294 | 294 | ||
295 | if (!rx->sta || skb->len - hdrlen < 12) | 295 | if (!rx->sta || skb->len - hdrlen < 12) |
296 | return TXRX_DROP; | 296 | return RX_DROP_UNUSABLE; |
297 | 297 | ||
298 | if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) { | 298 | if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) { |
299 | if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) { | 299 | if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) { |
@@ -302,7 +302,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
302 | * replay protection, and stripped the ICV/IV so | 302 | * replay protection, and stripped the ICV/IV so |
303 | * we cannot do any checks here. | 303 | * we cannot do any checks here. |
304 | */ | 304 | */ |
305 | return TXRX_CONTINUE; | 305 | return RX_CONTINUE; |
306 | } | 306 | } |
307 | 307 | ||
308 | /* let TKIP code verify IV, but skip decryption */ | 308 | /* let TKIP code verify IV, but skip decryption */ |
@@ -322,7 +322,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
322 | "frame from %s (res=%d)\n", rx->dev->name, | 322 | "frame from %s (res=%d)\n", rx->dev->name, |
323 | print_mac(mac, rx->sta->addr), res); | 323 | print_mac(mac, rx->sta->addr), res); |
324 | #endif /* CONFIG_MAC80211_DEBUG */ | 324 | #endif /* CONFIG_MAC80211_DEBUG */ |
325 | return TXRX_DROP; | 325 | return RX_DROP_UNUSABLE; |
326 | } | 326 | } |
327 | 327 | ||
328 | /* Trim ICV */ | 328 | /* Trim ICV */ |
@@ -332,7 +332,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx) | |||
332 | memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); | 332 | memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); |
333 | skb_pull(skb, TKIP_IV_LEN); | 333 | skb_pull(skb, TKIP_IV_LEN); |
334 | 334 | ||
335 | return TXRX_CONTINUE; | 335 | return RX_CONTINUE; |
336 | } | 336 | } |
337 | 337 | ||
338 | 338 | ||
@@ -491,7 +491,7 @@ static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx, | |||
491 | } | 491 | } |
492 | 492 | ||
493 | 493 | ||
494 | ieee80211_txrx_result | 494 | ieee80211_tx_result |
495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx) | 495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx) |
496 | { | 496 | { |
497 | struct sk_buff *skb = tx->skb; | 497 | struct sk_buff *skb = tx->skb; |
@@ -506,26 +506,26 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx) | |||
506 | /* hwaccel - with no need for preallocated room for CCMP " | 506 | /* hwaccel - with no need for preallocated room for CCMP " |
507 | * header or MIC fields */ | 507 | * header or MIC fields */ |
508 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; | 508 | tx->u.tx.control->key_idx = tx->key->conf.hw_key_idx; |
509 | return TXRX_CONTINUE; | 509 | return TX_CONTINUE; |
510 | } | 510 | } |
511 | 511 | ||
512 | if (ccmp_encrypt_skb(tx, skb, test) < 0) | 512 | if (ccmp_encrypt_skb(tx, skb, test) < 0) |
513 | return TXRX_DROP; | 513 | return TX_DROP; |
514 | 514 | ||
515 | if (tx->u.tx.extra_frag) { | 515 | if (tx->u.tx.extra_frag) { |
516 | int i; | 516 | int i; |
517 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { | 517 | for (i = 0; i < tx->u.tx.num_extra_frag; i++) { |
518 | if (ccmp_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) | 518 | if (ccmp_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) |
519 | < 0) | 519 | < 0) |
520 | return TXRX_DROP; | 520 | return TX_DROP; |
521 | } | 521 | } |
522 | } | 522 | } |
523 | 523 | ||
524 | return TXRX_CONTINUE; | 524 | return TX_CONTINUE; |
525 | } | 525 | } |
526 | 526 | ||
527 | 527 | ||
528 | ieee80211_txrx_result | 528 | ieee80211_rx_result |
529 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | 529 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) |
530 | { | 530 | { |
531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
@@ -541,15 +541,15 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
541 | hdrlen = ieee80211_get_hdrlen(fc); | 541 | hdrlen = ieee80211_get_hdrlen(fc); |
542 | 542 | ||
543 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 543 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
544 | return TXRX_CONTINUE; | 544 | return RX_CONTINUE; |
545 | 545 | ||
546 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; | 546 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; |
547 | if (!rx->sta || data_len < 0) | 547 | if (!rx->sta || data_len < 0) |
548 | return TXRX_DROP; | 548 | return RX_DROP_UNUSABLE; |
549 | 549 | ||
550 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && | 550 | if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && |
551 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) | 551 | (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) |
552 | return TXRX_CONTINUE; | 552 | return RX_CONTINUE; |
553 | 553 | ||
554 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 554 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); |
555 | 555 | ||
@@ -565,7 +565,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
565 | ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); | 565 | ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); |
566 | #endif /* CONFIG_MAC80211_DEBUG */ | 566 | #endif /* CONFIG_MAC80211_DEBUG */ |
567 | key->u.ccmp.replays++; | 567 | key->u.ccmp.replays++; |
568 | return TXRX_DROP; | 568 | return RX_DROP_UNUSABLE; |
569 | } | 569 | } |
570 | 570 | ||
571 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { | 571 | if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { |
@@ -589,7 +589,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
589 | "for RX frame from %s\n", rx->dev->name, | 589 | "for RX frame from %s\n", rx->dev->name, |
590 | print_mac(mac, rx->sta->addr)); | 590 | print_mac(mac, rx->sta->addr)); |
591 | #endif /* CONFIG_MAC80211_DEBUG */ | 591 | #endif /* CONFIG_MAC80211_DEBUG */ |
592 | return TXRX_DROP; | 592 | return RX_DROP_UNUSABLE; |
593 | } | 593 | } |
594 | } | 594 | } |
595 | 595 | ||
@@ -600,5 +600,5 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx) | |||
600 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); | 600 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); |
601 | skb_pull(skb, CCMP_HDR_LEN); | 601 | skb_pull(skb, CCMP_HDR_LEN); |
602 | 602 | ||
603 | return TXRX_CONTINUE; | 603 | return RX_CONTINUE; |
604 | } | 604 | } |
diff --git a/net/mac80211/wpa.h b/net/mac80211/wpa.h index 49d80cf0cd75..16e4dba4aa70 100644 --- a/net/mac80211/wpa.h +++ b/net/mac80211/wpa.h | |||
@@ -13,19 +13,19 @@ | |||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include "ieee80211_i.h" | 14 | #include "ieee80211_i.h" |
15 | 15 | ||
16 | ieee80211_txrx_result | 16 | ieee80211_tx_result |
17 | ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx); | 17 | ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx); |
18 | ieee80211_txrx_result | 18 | ieee80211_rx_result |
19 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx); | 19 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx); |
20 | 20 | ||
21 | ieee80211_txrx_result | 21 | ieee80211_tx_result |
22 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx); | 22 | ieee80211_crypto_tkip_encrypt(struct ieee80211_txrx_data *tx); |
23 | ieee80211_txrx_result | 23 | ieee80211_rx_result |
24 | ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx); | 24 | ieee80211_crypto_tkip_decrypt(struct ieee80211_txrx_data *rx); |
25 | 25 | ||
26 | ieee80211_txrx_result | 26 | ieee80211_tx_result |
27 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx); | 27 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_txrx_data *tx); |
28 | ieee80211_txrx_result | 28 | ieee80211_rx_result |
29 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx); | 29 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_txrx_data *rx); |
30 | 30 | ||
31 | #endif /* WPA_H */ | 31 | #endif /* WPA_H */ |
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 65710a42e5a7..b9f943c45f3b 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o | 1 | obj-$(CONFIG_WIRELESS_EXT) += wext.o |
2 | obj-$(CONFIG_CFG80211) += cfg80211.o | 2 | obj-$(CONFIG_CFG80211) += cfg80211.o |
3 | 3 | ||
4 | cfg80211-y += core.o sysfs.o radiotap.o | 4 | cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o |
5 | cfg80211-$(CONFIG_NL80211) += nl80211.o | 5 | cfg80211-$(CONFIG_NL80211) += nl80211.o |
diff --git a/net/wireless/core.c b/net/wireless/core.c index cfc5fc5f9e75..80afacdae46c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -232,6 +232,47 @@ int wiphy_register(struct wiphy *wiphy) | |||
232 | { | 232 | { |
233 | struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); | 233 | struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy); |
234 | int res; | 234 | int res; |
235 | enum ieee80211_band band; | ||
236 | struct ieee80211_supported_band *sband; | ||
237 | bool have_band = false; | ||
238 | int i; | ||
239 | |||
240 | /* sanity check supported bands/channels */ | ||
241 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
242 | sband = wiphy->bands[band]; | ||
243 | if (!sband) | ||
244 | continue; | ||
245 | |||
246 | sband->band = band; | ||
247 | |||
248 | if (!sband->n_channels || !sband->n_bitrates) { | ||
249 | WARN_ON(1); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | |||
253 | for (i = 0; i < sband->n_channels; i++) { | ||
254 | sband->channels[i].orig_flags = | ||
255 | sband->channels[i].flags; | ||
256 | sband->channels[i].orig_mag = | ||
257 | sband->channels[i].max_antenna_gain; | ||
258 | sband->channels[i].orig_mpwr = | ||
259 | sband->channels[i].max_power; | ||
260 | sband->channels[i].band = band; | ||
261 | } | ||
262 | |||
263 | have_band = true; | ||
264 | } | ||
265 | |||
266 | if (!have_band) { | ||
267 | WARN_ON(1); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | /* check and set up bitrates */ | ||
272 | ieee80211_set_bitrate_flags(wiphy); | ||
273 | |||
274 | /* set up regulatory info */ | ||
275 | wiphy_update_regulatory(wiphy); | ||
235 | 276 | ||
236 | mutex_lock(&cfg80211_drv_mutex); | 277 | mutex_lock(&cfg80211_drv_mutex); |
237 | 278 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index eb0f846b40df..7a02c356d63d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -78,4 +78,7 @@ extern void cfg80211_dev_free(struct cfg80211_registered_device *drv); | |||
78 | extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, | 78 | extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv, |
79 | char *newname); | 79 | char *newname); |
80 | 80 | ||
81 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | ||
82 | void wiphy_update_regulatory(struct wiphy *wiphy); | ||
83 | |||
81 | #endif /* __NET_WIRELESS_CORE_H */ | 84 | #endif /* __NET_WIRELESS_CORE_H */ |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e3a214f63f91..5b3474798b8d 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -82,6 +82,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = { | |||
82 | [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, | 82 | [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, |
83 | .len = NL80211_MAX_SUPP_RATES }, | 83 | .len = NL80211_MAX_SUPP_RATES }, |
84 | [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, | 84 | [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, |
85 | [NL80211_ATTR_MNTR_FLAGS] = { .type = NLA_NESTED }, | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | /* message building helper */ | 88 | /* message building helper */ |
@@ -98,6 +99,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
98 | struct cfg80211_registered_device *dev) | 99 | struct cfg80211_registered_device *dev) |
99 | { | 100 | { |
100 | void *hdr; | 101 | void *hdr; |
102 | struct nlattr *nl_bands, *nl_band; | ||
103 | struct nlattr *nl_freqs, *nl_freq; | ||
104 | struct nlattr *nl_rates, *nl_rate; | ||
105 | enum ieee80211_band band; | ||
106 | struct ieee80211_channel *chan; | ||
107 | struct ieee80211_rate *rate; | ||
108 | int i; | ||
101 | 109 | ||
102 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); | 110 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); |
103 | if (!hdr) | 111 | if (!hdr) |
@@ -105,6 +113,73 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
105 | 113 | ||
106 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); | 114 | NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); |
107 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); | 115 | NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); |
116 | |||
117 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); | ||
118 | if (!nl_bands) | ||
119 | goto nla_put_failure; | ||
120 | |||
121 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
122 | if (!dev->wiphy.bands[band]) | ||
123 | continue; | ||
124 | |||
125 | nl_band = nla_nest_start(msg, band); | ||
126 | if (!nl_band) | ||
127 | goto nla_put_failure; | ||
128 | |||
129 | /* add frequencies */ | ||
130 | nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); | ||
131 | if (!nl_freqs) | ||
132 | goto nla_put_failure; | ||
133 | |||
134 | for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) { | ||
135 | nl_freq = nla_nest_start(msg, i); | ||
136 | if (!nl_freq) | ||
137 | goto nla_put_failure; | ||
138 | |||
139 | chan = &dev->wiphy.bands[band]->channels[i]; | ||
140 | NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ, | ||
141 | chan->center_freq); | ||
142 | |||
143 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
144 | NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED); | ||
145 | if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) | ||
146 | NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN); | ||
147 | if (chan->flags & IEEE80211_CHAN_NO_IBSS) | ||
148 | NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS); | ||
149 | if (chan->flags & IEEE80211_CHAN_RADAR) | ||
150 | NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR); | ||
151 | |||
152 | nla_nest_end(msg, nl_freq); | ||
153 | } | ||
154 | |||
155 | nla_nest_end(msg, nl_freqs); | ||
156 | |||
157 | /* add bitrates */ | ||
158 | nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES); | ||
159 | if (!nl_rates) | ||
160 | goto nla_put_failure; | ||
161 | |||
162 | for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) { | ||
163 | nl_rate = nla_nest_start(msg, i); | ||
164 | if (!nl_rate) | ||
165 | goto nla_put_failure; | ||
166 | |||
167 | rate = &dev->wiphy.bands[band]->bitrates[i]; | ||
168 | NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE, | ||
169 | rate->bitrate); | ||
170 | if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
171 | NLA_PUT_FLAG(msg, | ||
172 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE); | ||
173 | |||
174 | nla_nest_end(msg, nl_rate); | ||
175 | } | ||
176 | |||
177 | nla_nest_end(msg, nl_rates); | ||
178 | |||
179 | nla_nest_end(msg, nl_band); | ||
180 | } | ||
181 | nla_nest_end(msg, nl_bands); | ||
182 | |||
108 | return genlmsg_end(msg, hdr); | 183 | return genlmsg_end(msg, hdr); |
109 | 184 | ||
110 | nla_put_failure: | 185 | nla_put_failure: |
@@ -262,12 +337,42 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
262 | return -ENOBUFS; | 337 | return -ENOBUFS; |
263 | } | 338 | } |
264 | 339 | ||
340 | static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { | ||
341 | [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG }, | ||
342 | [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG }, | ||
343 | [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, | ||
344 | [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, | ||
345 | [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, | ||
346 | }; | ||
347 | |||
348 | static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) | ||
349 | { | ||
350 | struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1]; | ||
351 | int flag; | ||
352 | |||
353 | *mntrflags = 0; | ||
354 | |||
355 | if (!nla) | ||
356 | return -EINVAL; | ||
357 | |||
358 | if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, | ||
359 | nla, mntr_flags_policy)) | ||
360 | return -EINVAL; | ||
361 | |||
362 | for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++) | ||
363 | if (flags[flag]) | ||
364 | *mntrflags |= (1<<flag); | ||
365 | |||
366 | return 0; | ||
367 | } | ||
368 | |||
265 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | 369 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) |
266 | { | 370 | { |
267 | struct cfg80211_registered_device *drv; | 371 | struct cfg80211_registered_device *drv; |
268 | int err, ifindex; | 372 | int err, ifindex; |
269 | enum nl80211_iftype type; | 373 | enum nl80211_iftype type; |
270 | struct net_device *dev; | 374 | struct net_device *dev; |
375 | u32 flags; | ||
271 | 376 | ||
272 | if (info->attrs[NL80211_ATTR_IFTYPE]) { | 377 | if (info->attrs[NL80211_ATTR_IFTYPE]) { |
273 | type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); | 378 | type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); |
@@ -288,7 +393,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | |||
288 | } | 393 | } |
289 | 394 | ||
290 | rtnl_lock(); | 395 | rtnl_lock(); |
291 | err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, type); | 396 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
397 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | ||
398 | &flags); | ||
399 | err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, | ||
400 | type, err ? NULL : &flags); | ||
292 | rtnl_unlock(); | 401 | rtnl_unlock(); |
293 | 402 | ||
294 | unlock: | 403 | unlock: |
@@ -301,6 +410,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
301 | struct cfg80211_registered_device *drv; | 410 | struct cfg80211_registered_device *drv; |
302 | int err; | 411 | int err; |
303 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 412 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
413 | u32 flags; | ||
304 | 414 | ||
305 | if (!info->attrs[NL80211_ATTR_IFNAME]) | 415 | if (!info->attrs[NL80211_ATTR_IFNAME]) |
306 | return -EINVAL; | 416 | return -EINVAL; |
@@ -321,8 +431,12 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
321 | } | 431 | } |
322 | 432 | ||
323 | rtnl_lock(); | 433 | rtnl_lock(); |
434 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | ||
435 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | ||
436 | &flags); | ||
324 | err = drv->ops->add_virtual_intf(&drv->wiphy, | 437 | err = drv->ops->add_virtual_intf(&drv->wiphy, |
325 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), type); | 438 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
439 | type, err ? NULL : &flags); | ||
326 | rtnl_unlock(); | 440 | rtnl_unlock(); |
327 | 441 | ||
328 | unlock: | 442 | unlock: |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c new file mode 100644 index 000000000000..8cc6037eb2ae --- /dev/null +++ b/net/wireless/reg.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | ||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | ||
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This regulatory domain control implementation is highly incomplete, it | ||
13 | * only exists for the purpose of not regressing mac80211. | ||
14 | * | ||
15 | * For now, drivers can restrict the set of allowed channels by either | ||
16 | * not registering those channels or setting the IEEE80211_CHAN_DISABLED | ||
17 | * flag; that flag will only be *set* by this code, never *cleared. | ||
18 | * | ||
19 | * The usual implementation is for a driver to read a device EEPROM to | ||
20 | * determine which regulatory domain it should be operating under, then | ||
21 | * looking up the allowable channels in a driver-local table and finally | ||
22 | * registering those channels in the wiphy structure. | ||
23 | * | ||
24 | * Alternatively, drivers that trust the regulatory domain control here | ||
25 | * will register a complete set of capabilities and the control code | ||
26 | * will restrict the set by setting the IEEE80211_CHAN_* flags. | ||
27 | */ | ||
28 | #include <linux/kernel.h> | ||
29 | #include <net/wireless.h> | ||
30 | #include "core.h" | ||
31 | |||
32 | static char *ieee80211_regdom = "US"; | ||
33 | module_param(ieee80211_regdom, charp, 0444); | ||
34 | MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); | ||
35 | |||
36 | struct ieee80211_channel_range { | ||
37 | short start_freq; | ||
38 | short end_freq; | ||
39 | int max_power; | ||
40 | int max_antenna_gain; | ||
41 | u32 flags; | ||
42 | }; | ||
43 | |||
44 | struct ieee80211_regdomain { | ||
45 | const char *code; | ||
46 | const struct ieee80211_channel_range *ranges; | ||
47 | int n_ranges; | ||
48 | }; | ||
49 | |||
50 | #define RANGE_PWR(_start, _end, _pwr, _ag, _flags) \ | ||
51 | { _start, _end, _pwr, _ag, _flags } | ||
52 | |||
53 | |||
54 | /* | ||
55 | * Ideally, in the future, these definitions will be loaded from a | ||
56 | * userspace table via some daemon. | ||
57 | */ | ||
58 | static const struct ieee80211_channel_range ieee80211_US_channels[] = { | ||
59 | /* IEEE 802.11b/g, channels 1..11 */ | ||
60 | RANGE_PWR(2412, 2462, 27, 6, 0), | ||
61 | /* IEEE 802.11a, channel 36*/ | ||
62 | RANGE_PWR(5180, 5180, 23, 6, 0), | ||
63 | /* IEEE 802.11a, channel 40*/ | ||
64 | RANGE_PWR(5200, 5200, 23, 6, 0), | ||
65 | /* IEEE 802.11a, channel 44*/ | ||
66 | RANGE_PWR(5220, 5220, 23, 6, 0), | ||
67 | /* IEEE 802.11a, channels 48..64 */ | ||
68 | RANGE_PWR(5240, 5320, 23, 6, 0), | ||
69 | /* IEEE 802.11a, channels 149..165, outdoor */ | ||
70 | RANGE_PWR(5745, 5825, 30, 6, 0), | ||
71 | }; | ||
72 | |||
73 | static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | ||
74 | /* IEEE 802.11b/g, channels 1..14 */ | ||
75 | RANGE_PWR(2412, 2484, 20, 6, 0), | ||
76 | /* IEEE 802.11a, channels 34..48 */ | ||
77 | RANGE_PWR(5170, 5240, 20, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
78 | /* IEEE 802.11a, channels 52..64 */ | ||
79 | RANGE_PWR(5260, 5320, 20, 6, IEEE80211_CHAN_NO_IBSS | | ||
80 | IEEE80211_CHAN_RADAR), | ||
81 | }; | ||
82 | |||
83 | #define REGDOM(_code) \ | ||
84 | { \ | ||
85 | .code = __stringify(_code), \ | ||
86 | .ranges = ieee80211_ ##_code## _channels, \ | ||
87 | .n_ranges = ARRAY_SIZE(ieee80211_ ##_code## _channels), \ | ||
88 | } | ||
89 | |||
90 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { | ||
91 | REGDOM(US), | ||
92 | REGDOM(JP), | ||
93 | }; | ||
94 | |||
95 | |||
96 | static const struct ieee80211_regdomain *get_regdom(void) | ||
97 | { | ||
98 | static const struct ieee80211_channel_range | ||
99 | ieee80211_world_channels[] = { | ||
100 | /* IEEE 802.11b/g, channels 1..11 */ | ||
101 | RANGE_PWR(2412, 2462, 27, 6, 0), | ||
102 | }; | ||
103 | static const struct ieee80211_regdomain regdom_world = REGDOM(world); | ||
104 | int i; | ||
105 | |||
106 | for (i = 0; i < ARRAY_SIZE(ieee80211_regdoms); i++) | ||
107 | if (strcmp(ieee80211_regdom, ieee80211_regdoms[i].code) == 0) | ||
108 | return &ieee80211_regdoms[i]; | ||
109 | |||
110 | return ®dom_world; | ||
111 | } | ||
112 | |||
113 | |||
114 | static void handle_channel(struct ieee80211_channel *chan, | ||
115 | const struct ieee80211_regdomain *rd) | ||
116 | { | ||
117 | int i; | ||
118 | u32 flags = chan->orig_flags; | ||
119 | const struct ieee80211_channel_range *rg = NULL; | ||
120 | |||
121 | for (i = 0; i < rd->n_ranges; i++) { | ||
122 | if (rd->ranges[i].start_freq <= chan->center_freq && | ||
123 | chan->center_freq <= rd->ranges[i].end_freq) { | ||
124 | rg = &rd->ranges[i]; | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | if (!rg) { | ||
130 | /* not found */ | ||
131 | flags |= IEEE80211_CHAN_DISABLED; | ||
132 | chan->flags = flags; | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | chan->flags = flags; | ||
137 | chan->max_antenna_gain = min(chan->orig_mag, | ||
138 | rg->max_antenna_gain); | ||
139 | chan->max_power = min(chan->orig_mpwr, rg->max_power); | ||
140 | } | ||
141 | |||
142 | static void handle_band(struct ieee80211_supported_band *sband, | ||
143 | const struct ieee80211_regdomain *rd) | ||
144 | { | ||
145 | int i; | ||
146 | |||
147 | for (i = 0; i < sband->n_channels; i++) | ||
148 | handle_channel(&sband->channels[i], rd); | ||
149 | } | ||
150 | |||
151 | void wiphy_update_regulatory(struct wiphy *wiphy) | ||
152 | { | ||
153 | enum ieee80211_band band; | ||
154 | const struct ieee80211_regdomain *rd = get_regdom(); | ||
155 | |||
156 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
157 | if (wiphy->bands[band]) | ||
158 | handle_band(wiphy->bands[band], rd); | ||
159 | } | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c new file mode 100644 index 000000000000..77336c22fcf2 --- /dev/null +++ b/net/wireless/util.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Wireless utility functions | ||
3 | * | ||
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | ||
5 | */ | ||
6 | #include <net/wireless.h> | ||
7 | #include <asm/bitops.h> | ||
8 | #include "core.h" | ||
9 | |||
10 | int ieee80211_channel_to_frequency(int chan) | ||
11 | { | ||
12 | if (chan < 14) | ||
13 | return 2407 + chan * 5; | ||
14 | |||
15 | if (chan == 14) | ||
16 | return 2484; | ||
17 | |||
18 | /* FIXME: 802.11j 17.3.8.3.2 */ | ||
19 | return (chan + 1000) * 5; | ||
20 | } | ||
21 | EXPORT_SYMBOL(ieee80211_channel_to_frequency); | ||
22 | |||
23 | int ieee80211_frequency_to_channel(int freq) | ||
24 | { | ||
25 | if (freq == 2484) | ||
26 | return 14; | ||
27 | |||
28 | if (freq < 2484) | ||
29 | return (freq - 2407) / 5; | ||
30 | |||
31 | /* FIXME: 802.11j 17.3.8.3.2 */ | ||
32 | return freq/5 - 1000; | ||
33 | } | ||
34 | EXPORT_SYMBOL(ieee80211_frequency_to_channel); | ||
35 | |||
36 | static void set_mandatory_flags_band(struct ieee80211_supported_band *sband, | ||
37 | enum ieee80211_band band) | ||
38 | { | ||
39 | int i, want; | ||
40 | |||
41 | switch (band) { | ||
42 | case IEEE80211_BAND_5GHZ: | ||
43 | want = 3; | ||
44 | for (i = 0; i < sband->n_bitrates; i++) { | ||
45 | if (sband->bitrates[i].bitrate == 60 || | ||
46 | sband->bitrates[i].bitrate == 120 || | ||
47 | sband->bitrates[i].bitrate == 240) { | ||
48 | sband->bitrates[i].flags |= | ||
49 | IEEE80211_RATE_MANDATORY_A; | ||
50 | want--; | ||
51 | } | ||
52 | } | ||
53 | WARN_ON(want); | ||
54 | break; | ||
55 | case IEEE80211_BAND_2GHZ: | ||
56 | want = 7; | ||
57 | for (i = 0; i < sband->n_bitrates; i++) { | ||
58 | if (sband->bitrates[i].bitrate == 10) { | ||
59 | sband->bitrates[i].flags |= | ||
60 | IEEE80211_RATE_MANDATORY_B | | ||
61 | IEEE80211_RATE_MANDATORY_G; | ||
62 | want--; | ||
63 | } | ||
64 | |||
65 | if (sband->bitrates[i].bitrate == 20 || | ||
66 | sband->bitrates[i].bitrate == 55 || | ||
67 | sband->bitrates[i].bitrate == 110 || | ||
68 | sband->bitrates[i].bitrate == 60 || | ||
69 | sband->bitrates[i].bitrate == 120 || | ||
70 | sband->bitrates[i].bitrate == 240) { | ||
71 | sband->bitrates[i].flags |= | ||
72 | IEEE80211_RATE_MANDATORY_G; | ||
73 | want--; | ||
74 | } | ||
75 | |||
76 | if (sband->bitrates[i].bitrate != 10 && | ||
77 | sband->bitrates[i].bitrate != 20 && | ||
78 | sband->bitrates[i].bitrate != 55 && | ||
79 | sband->bitrates[i].bitrate != 110) | ||
80 | sband->bitrates[i].flags |= | ||
81 | IEEE80211_RATE_ERP_G; | ||
82 | } | ||
83 | WARN_ON(want != 0 && want != 3 && want != 6); | ||
84 | break; | ||
85 | case IEEE80211_NUM_BANDS: | ||
86 | WARN_ON(1); | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | void ieee80211_set_bitrate_flags(struct wiphy *wiphy) | ||
92 | { | ||
93 | enum ieee80211_band band; | ||
94 | |||
95 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | ||
96 | if (wiphy->bands[band]) | ||
97 | set_mandatory_flags_band(wiphy->bands[band], band); | ||
98 | } | ||