diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-14 20:15:39 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-14 20:15:39 -0400 |
commit | 942e7b102a4827fdb69a39c7f07c544542589ef9 (patch) | |
tree | 4c47174c91eb76aaa31abc141adbee1acc649987 | |
parent | 7d06b2e053d2d536348e3a0f6bb02982a41bea37 (diff) | |
parent | 87291c0269e77b029282676448fed3706a54211a (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
74 files changed, 3854 insertions, 2974 deletions
diff --git a/Documentation/networking/mac80211_hwsim/README b/Documentation/networking/mac80211_hwsim/README new file mode 100644 index 000000000000..2ff8ccb8dc37 --- /dev/null +++ b/Documentation/networking/mac80211_hwsim/README | |||
@@ -0,0 +1,67 @@ | |||
1 | mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 | ||
2 | Copyright (c) 2008, Jouni Malinen <j@w1.fi> | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License version 2 as | ||
6 | published by the Free Software Foundation. | ||
7 | |||
8 | |||
9 | Introduction | ||
10 | |||
11 | mac80211_hwsim is a Linux kernel module that can be used to simulate | ||
12 | arbitrary number of IEEE 802.11 radios for mac80211. It can be used to | ||
13 | test most of the mac80211 functionality and user space tools (e.g., | ||
14 | hostapd and wpa_supplicant) in a way that matches very closely with | ||
15 | the normal case of using real WLAN hardware. From the mac80211 view | ||
16 | point, mac80211_hwsim is yet another hardware driver, i.e., no changes | ||
17 | to mac80211 are needed to use this testing tool. | ||
18 | |||
19 | The main goal for mac80211_hwsim is to make it easier for developers | ||
20 | to test their code and work with new features to mac80211, hostapd, | ||
21 | and wpa_supplicant. The simulated radios do not have the limitations | ||
22 | of real hardware, so it is easy to generate an arbitrary test setup | ||
23 | and always reproduce the same setup for future tests. In addition, | ||
24 | since all radio operation is simulated, any channel can be used in | ||
25 | tests regardless of regulatory rules. | ||
26 | |||
27 | mac80211_hwsim kernel module has a parameter 'radios' that can be used | ||
28 | to select how many radios are simulated (default 2). This allows | ||
29 | configuration of both very simply setups (e.g., just a single access | ||
30 | point and a station) or large scale tests (multiple access points with | ||
31 | hundreds of stations). | ||
32 | |||
33 | mac80211_hwsim works by tracking the current channel of each virtual | ||
34 | radio and copying all transmitted frames to all other radios that are | ||
35 | currently enabled and on the same channel as the transmitting | ||
36 | radio. Software encryption in mac80211 is used so that the frames are | ||
37 | actually encrypted over the virtual air interface to allow more | ||
38 | complete testing of encryption. | ||
39 | |||
40 | A global monitoring netdev, hwsim#, is created independent of | ||
41 | mac80211. This interface can be used to monitor all transmitted frames | ||
42 | regardless of channel. | ||
43 | |||
44 | |||
45 | Simple example | ||
46 | |||
47 | This example shows how to use mac80211_hwsim to simulate two radios: | ||
48 | one to act as an access point and the other as a station that | ||
49 | associates with the AP. hostapd and wpa_supplicant are used to take | ||
50 | care of WPA2-PSK authentication. In addition, hostapd is also | ||
51 | processing access point side of association. | ||
52 | |||
53 | Please note that the current Linux kernel does not enable AP mode, so a | ||
54 | simple patch is needed to enable AP mode selection: | ||
55 | http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch | ||
56 | |||
57 | |||
58 | # Build mac80211_hwsim as part of kernel configuration | ||
59 | |||
60 | # Load the module | ||
61 | modprobe mac80211_hwsim | ||
62 | |||
63 | # Run hostapd (AP) for wlan0 | ||
64 | hostapd hostapd.conf | ||
65 | |||
66 | # Run wpa_supplicant (station) for wlan1 | ||
67 | wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf | ||
diff --git a/Documentation/networking/mac80211_hwsim/hostapd.conf b/Documentation/networking/mac80211_hwsim/hostapd.conf new file mode 100644 index 000000000000..08cde7e35f2e --- /dev/null +++ b/Documentation/networking/mac80211_hwsim/hostapd.conf | |||
@@ -0,0 +1,11 @@ | |||
1 | interface=wlan0 | ||
2 | driver=nl80211 | ||
3 | |||
4 | hw_mode=g | ||
5 | channel=1 | ||
6 | ssid=mac80211 test | ||
7 | |||
8 | wpa=2 | ||
9 | wpa_key_mgmt=WPA-PSK | ||
10 | wpa_pairwise=CCMP | ||
11 | wpa_passphrase=12345678 | ||
diff --git a/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf b/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf new file mode 100644 index 000000000000..299128cff035 --- /dev/null +++ b/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf | |||
@@ -0,0 +1,10 @@ | |||
1 | ctrl_interface=/var/run/wpa_supplicant | ||
2 | |||
3 | network={ | ||
4 | ssid="mac80211 test" | ||
5 | psk="12345678" | ||
6 | key_mgmt=WPA-PSK | ||
7 | proto=WPA2 | ||
8 | pairwise=CCMP | ||
9 | group=CCMP | ||
10 | } | ||
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index fdf5aa8b8429..22e1e9a1fb73 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -673,6 +673,19 @@ config ADM8211 | |||
673 | 673 | ||
674 | Thanks to Infineon-ADMtek for their support of this driver. | 674 | Thanks to Infineon-ADMtek for their support of this driver. |
675 | 675 | ||
676 | config MAC80211_HWSIM | ||
677 | tristate "Simulated radio testing tool for mac80211" | ||
678 | depends on MAC80211 && WLAN_80211 | ||
679 | ---help--- | ||
680 | This driver is a developer testing tool that can be used to test | ||
681 | IEEE 802.11 networking stack (mac80211) functionality. This is not | ||
682 | needed for normal wireless LAN usage and is only for testing. See | ||
683 | Documentation/networking/mac80211_hwsim for more information on how | ||
684 | to use this tool. | ||
685 | |||
686 | To compile this driver as a module, choose M here: the module will be | ||
687 | called mac80211_hwsim. If unsure, say N. | ||
688 | |||
676 | source "drivers/net/wireless/p54/Kconfig" | 689 | source "drivers/net/wireless/p54/Kconfig" |
677 | source "drivers/net/wireless/ath5k/Kconfig" | 690 | source "drivers/net/wireless/ath5k/Kconfig" |
678 | source "drivers/net/wireless/iwlwifi/Kconfig" | 691 | source "drivers/net/wireless/iwlwifi/Kconfig" |
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 2c343aae38d4..54a4f6f1db67 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile | |||
@@ -62,3 +62,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/ | |||
62 | obj-$(CONFIG_P54_COMMON) += p54/ | 62 | obj-$(CONFIG_P54_COMMON) += p54/ |
63 | 63 | ||
64 | obj-$(CONFIG_ATH5K) += ath5k/ | 64 | obj-$(CONFIG_ATH5K) += ath5k/ |
65 | |||
66 | obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o | ||
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 1e1446bf4b48..e30f8b79ea89 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -4561,22 +4561,13 @@ static ssize_t proc_read( struct file *file, | |||
4561 | size_t len, | 4561 | size_t len, |
4562 | loff_t *offset ) | 4562 | loff_t *offset ) |
4563 | { | 4563 | { |
4564 | loff_t pos = *offset; | 4564 | struct proc_data *priv = file->private_data; |
4565 | struct proc_data *priv = (struct proc_data*)file->private_data; | ||
4566 | 4565 | ||
4567 | if (!priv->rbuffer) | 4566 | if (!priv->rbuffer) |
4568 | return -EINVAL; | 4567 | return -EINVAL; |
4569 | 4568 | ||
4570 | if (pos < 0) | 4569 | return simple_read_from_buffer(buffer, len, offset, priv->rbuffer, |
4571 | return -EINVAL; | 4570 | priv->readlen); |
4572 | if (pos >= priv->readlen) | ||
4573 | return 0; | ||
4574 | if (len > priv->readlen - pos) | ||
4575 | len = priv->readlen - pos; | ||
4576 | if (copy_to_user(buffer, priv->rbuffer + pos, len)) | ||
4577 | return -EFAULT; | ||
4578 | *offset = pos + len; | ||
4579 | return len; | ||
4580 | } | 4571 | } |
4581 | 4572 | ||
4582 | /* | 4573 | /* |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 5f3e849043f7..a382c0078923 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -14,15 +14,6 @@ config IWLWIFI_LEDS | |||
14 | bool | 14 | bool |
15 | default n | 15 | default n |
16 | 16 | ||
17 | config IWLWIFI_RUN_TIME_CALIB | ||
18 | bool | ||
19 | depends on IWLCORE | ||
20 | default n | ||
21 | ---help--- | ||
22 | This option will enable run time calibration for the iwlwifi driver. | ||
23 | These calibrations are Sensitivity and Chain Noise. | ||
24 | |||
25 | |||
26 | config IWLWIFI_RFKILL | 17 | config IWLWIFI_RFKILL |
27 | boolean "IWLWIFI RF kill support" | 18 | boolean "IWLWIFI RF kill support" |
28 | depends on IWLCORE | 19 | depends on IWLCORE |
@@ -54,14 +45,6 @@ config IWL4965 | |||
54 | say M here and read <file:Documentation/kbuild/modules.txt>. The | 45 | say M here and read <file:Documentation/kbuild/modules.txt>. The |
55 | module will be called iwl4965.ko. | 46 | module will be called iwl4965.ko. |
56 | 47 | ||
57 | config IWL4965_HT | ||
58 | bool "Enable 802.11n HT features in iwl4965 driver" | ||
59 | depends on EXPERIMENTAL | ||
60 | depends on IWL4965 | ||
61 | ---help--- | ||
62 | This option enables IEEE 802.11n High Throughput features | ||
63 | for the iwl4965 driver. | ||
64 | |||
65 | config IWL4965_LEDS | 48 | config IWL4965_LEDS |
66 | bool "Enable LEDS features in iwl4965 driver" | 49 | bool "Enable LEDS features in iwl4965 driver" |
67 | depends on IWL4965 | 50 | depends on IWL4965 |
@@ -76,15 +59,6 @@ config IWL4965_SPECTRUM_MEASUREMENT | |||
76 | ---help--- | 59 | ---help--- |
77 | This option will enable spectrum measurement for the iwl4965 driver. | 60 | This option will enable spectrum measurement for the iwl4965 driver. |
78 | 61 | ||
79 | config IWL4965_RUN_TIME_CALIB | ||
80 | bool "Enable run time Calibration for 4965 NIC" | ||
81 | select IWLWIFI_RUN_TIME_CALIB | ||
82 | depends on IWL4965 | ||
83 | default y | ||
84 | ---help--- | ||
85 | This option will enable run time calibration for the iwl4965 driver. | ||
86 | These calibrations are Sensitivity and Chain Noise. If unsure, say yes | ||
87 | |||
88 | config IWLWIFI_DEBUG | 62 | config IWLWIFI_DEBUG |
89 | bool "Enable full debugging output in iwl4965 driver" | 63 | bool "Enable full debugging output in iwl4965 driver" |
90 | depends on IWL4965 | 64 | depends on IWL4965 |
@@ -118,16 +92,6 @@ config IWL5000 | |||
118 | This option enables support for Intel Wireless WiFi Link 5000AGN Family | 92 | This option enables support for Intel Wireless WiFi Link 5000AGN Family |
119 | Dependency on 4965 is temporary | 93 | Dependency on 4965 is temporary |
120 | 94 | ||
121 | config IWL5000_RUN_TIME_CALIB | ||
122 | bool "Enable run time Calibration for 5000 NIC" | ||
123 | select IWLWIFI_RUN_TIME_CALIB | ||
124 | depends on IWL5000 | ||
125 | default y | ||
126 | ---help--- | ||
127 | This option will enable run time calibration for the iwl5000 driver. | ||
128 | These calibrations are Sensitivity and Chain Noise. If unsure, say yes | ||
129 | |||
130 | |||
131 | config IWLWIFI_DEBUGFS | 95 | config IWLWIFI_DEBUGFS |
132 | bool "Iwlwifi debugfs support" | 96 | bool "Iwlwifi debugfs support" |
133 | depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS | 97 | depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 5c73eede7193..1f52b92f08b5 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,10 +1,10 @@ | |||
1 | obj-$(CONFIG_IWLCORE) += iwlcore.o | 1 | obj-$(CONFIG_IWLCORE) += iwlcore.o |
2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o | 2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o |
3 | iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o | 3 | iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o |
4 | iwlcore-objs += iwl-scan.o | ||
4 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
5 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
6 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | 7 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o |
7 | iwlcore-$(CONFIG_IWLWIFI_RUN_TIME_CALIB) += iwl-calib.o | ||
8 | 8 | ||
9 | obj-$(CONFIG_IWL3945) += iwl3945.o | 9 | obj-$(CONFIG_IWL3945) += iwl3945.o |
10 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o | 10 | iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 0ba6889dfd41..63f20370032d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -388,7 +388,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
388 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | 388 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ |
389 | u32 hundred = 0; | 389 | u32 hundred = 0; |
390 | u32 dataframe = 0; | 390 | u32 dataframe = 0; |
391 | u16 fc; | 391 | __le16 fc; |
392 | u16 seq_ctl; | 392 | u16 seq_ctl; |
393 | u16 channel; | 393 | u16 channel; |
394 | u16 phy_flags; | 394 | u16 phy_flags; |
@@ -407,7 +407,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
407 | u8 *data = IWL_RX_DATA(pkt); | 407 | u8 *data = IWL_RX_DATA(pkt); |
408 | 408 | ||
409 | /* MAC header */ | 409 | /* MAC header */ |
410 | fc = le16_to_cpu(header->frame_control); | 410 | fc = header->frame_control; |
411 | seq_ctl = le16_to_cpu(header->seq_ctrl); | 411 | seq_ctl = le16_to_cpu(header->seq_ctrl); |
412 | 412 | ||
413 | /* metadata */ | 413 | /* metadata */ |
@@ -431,8 +431,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
431 | 431 | ||
432 | /* if data frame is to us and all is good, | 432 | /* if data frame is to us and all is good, |
433 | * (optionally) print summary for only 1 out of every 100 */ | 433 | * (optionally) print summary for only 1 out of every 100 */ |
434 | if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == | 434 | if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == |
435 | (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | 435 | cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { |
436 | dataframe = 1; | 436 | dataframe = 1; |
437 | if (!group100) | 437 | if (!group100) |
438 | print_summary = 1; /* print each frame */ | 438 | print_summary = 1; /* print each frame */ |
@@ -455,13 +455,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
455 | 455 | ||
456 | if (hundred) | 456 | if (hundred) |
457 | title = "100Frames"; | 457 | title = "100Frames"; |
458 | else if (fc & IEEE80211_FCTL_RETRY) | 458 | else if (ieee80211_has_retry(fc)) |
459 | title = "Retry"; | 459 | title = "Retry"; |
460 | else if (ieee80211_is_assoc_response(fc)) | 460 | else if (ieee80211_is_assoc_resp(fc)) |
461 | title = "AscRsp"; | 461 | title = "AscRsp"; |
462 | else if (ieee80211_is_reassoc_response(fc)) | 462 | else if (ieee80211_is_reassoc_resp(fc)) |
463 | title = "RasRsp"; | 463 | title = "RasRsp"; |
464 | else if (ieee80211_is_probe_response(fc)) { | 464 | else if (ieee80211_is_probe_resp(fc)) { |
465 | title = "PrbRsp"; | 465 | title = "PrbRsp"; |
466 | print_dump = 1; /* dump frame contents */ | 466 | print_dump = 1; /* dump frame contents */ |
467 | } else if (ieee80211_is_beacon(fc)) { | 467 | } else if (ieee80211_is_beacon(fc)) { |
@@ -490,14 +490,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
490 | if (dataframe) | 490 | if (dataframe) |
491 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | 491 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " |
492 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | 492 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", |
493 | title, fc, header->addr1[5], | 493 | title, le16_to_cpu(fc), header->addr1[5], |
494 | length, rssi, channel, rate); | 494 | length, rssi, channel, rate); |
495 | else { | 495 | else { |
496 | /* src/dst addresses assume managed mode */ | 496 | /* src/dst addresses assume managed mode */ |
497 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | 497 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " |
498 | "src=0x%02x, rssi=%u, tim=%lu usec, " | 498 | "src=0x%02x, rssi=%u, tim=%lu usec, " |
499 | "phy=0x%02x, chnl=%d\n", | 499 | "phy=0x%02x, chnl=%d\n", |
500 | title, fc, header->addr1[5], | 500 | title, le16_to_cpu(fc), header->addr1[5], |
501 | header->addr3[5], rssi, | 501 | header->addr3[5], rssi, |
502 | tsf_low - priv->scan_start_tsf, | 502 | tsf_low - priv->scan_start_tsf, |
503 | phy_flags, channel); | 503 | phy_flags, channel); |
@@ -971,7 +971,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
971 | u8 rts_retry_limit; | 971 | u8 rts_retry_limit; |
972 | u8 data_retry_limit; | 972 | u8 data_retry_limit; |
973 | __le32 tx_flags; | 973 | __le32 tx_flags; |
974 | u16 fc = le16_to_cpu(hdr->frame_control); | 974 | __le16 fc = hdr->frame_control; |
975 | 975 | ||
976 | rate = iwl3945_rates[rate_index].plcp; | 976 | rate = iwl3945_rates[rate_index].plcp; |
977 | tx_flags = cmd->cmd.tx.tx_flags; | 977 | tx_flags = cmd->cmd.tx.tx_flags; |
@@ -996,7 +996,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
996 | else | 996 | else |
997 | rts_retry_limit = 7; | 997 | rts_retry_limit = 7; |
998 | 998 | ||
999 | if (ieee80211_is_probe_response(fc)) { | 999 | if (ieee80211_is_probe_resp(fc)) { |
1000 | data_retry_limit = 3; | 1000 | data_retry_limit = 3; |
1001 | if (data_retry_limit < rts_retry_limit) | 1001 | if (data_retry_limit < rts_retry_limit) |
1002 | rts_retry_limit = data_retry_limit; | 1002 | rts_retry_limit = data_retry_limit; |
@@ -1006,12 +1006,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
1006 | if (priv->data_retry_limit != -1) | 1006 | if (priv->data_retry_limit != -1) |
1007 | data_retry_limit = priv->data_retry_limit; | 1007 | data_retry_limit = priv->data_retry_limit; |
1008 | 1008 | ||
1009 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 1009 | if (ieee80211_is_mgmt(fc)) { |
1010 | switch (fc & IEEE80211_FCTL_STYPE) { | 1010 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { |
1011 | case IEEE80211_STYPE_AUTH: | 1011 | case cpu_to_le16(IEEE80211_STYPE_AUTH): |
1012 | case IEEE80211_STYPE_DEAUTH: | 1012 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
1013 | case IEEE80211_STYPE_ASSOC_REQ: | 1013 | case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): |
1014 | case IEEE80211_STYPE_REASSOC_REQ: | 1014 | case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): |
1015 | if (tx_flags & TX_CMD_FLG_RTS_MSK) { | 1015 | if (tx_flags & TX_CMD_FLG_RTS_MSK) { |
1016 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 1016 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
1017 | tx_flags |= TX_CMD_FLG_CTS_MSK; | 1017 | tx_flags |= TX_CMD_FLG_CTS_MSK; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index fc118335b60f..10f630e1afa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -82,7 +82,7 @@ | |||
82 | */ | 82 | */ |
83 | #define IWL_CMD_QUEUE_NUM 4 | 83 | #define IWL_CMD_QUEUE_NUM 4 |
84 | #define IWL_CMD_FIFO_NUM 4 | 84 | #define IWL_CMD_FIFO_NUM 4 |
85 | #define IWL_BACK_QUEUE_FIRST_ID 7 | 85 | #define IWL49_FIRST_AMPDU_QUEUE 7 |
86 | 86 | ||
87 | /* Tx rates */ | 87 | /* Tx rates */ |
88 | #define IWL_CCK_RATES 4 | 88 | #define IWL_CCK_RATES 4 |
@@ -793,19 +793,6 @@ enum { | |||
793 | 793 | ||
794 | /********************* END TXPOWER *****************************************/ | 794 | /********************* END TXPOWER *****************************************/ |
795 | 795 | ||
796 | static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags) | ||
797 | { | ||
798 | return le32_to_cpu(rate_n_flags) & 0xFF; | ||
799 | } | ||
800 | static inline u32 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags) | ||
801 | { | ||
802 | return le32_to_cpu(rate_n_flags) & 0x1FFFF; | ||
803 | } | ||
804 | static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | ||
805 | { | ||
806 | return cpu_to_le32(flags|(u16)rate); | ||
807 | } | ||
808 | |||
809 | 796 | ||
810 | /** | 797 | /** |
811 | * Tx/Rx Queues | 798 | * Tx/Rx Queues |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index d8f2b4d33fd9..202303117285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "../net/mac80211/rate.h" | 38 | #include "../net/mac80211/rate.h" |
39 | 39 | ||
40 | #include "iwl-dev.h" | 40 | #include "iwl-dev.h" |
41 | #include "iwl-sta.h" | ||
41 | #include "iwl-core.h" | 42 | #include "iwl-core.h" |
42 | #include "iwl-helpers.h" | 43 | #include "iwl-helpers.h" |
43 | 44 | ||
@@ -105,8 +106,6 @@ struct iwl4965_scale_tbl_info { | |||
105 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ | 106 | struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ |
106 | }; | 107 | }; |
107 | 108 | ||
108 | #ifdef CONFIG_IWL4965_HT | ||
109 | |||
110 | struct iwl4965_traffic_load { | 109 | struct iwl4965_traffic_load { |
111 | unsigned long time_stamp; /* age of the oldest statistics */ | 110 | unsigned long time_stamp; /* age of the oldest statistics */ |
112 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time | 111 | u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time |
@@ -118,8 +117,6 @@ struct iwl4965_traffic_load { | |||
118 | u8 head; /* start of the circular buffer */ | 117 | u8 head; /* start of the circular buffer */ |
119 | }; | 118 | }; |
120 | 119 | ||
121 | #endif /* CONFIG_IWL4965_HT */ | ||
122 | |||
123 | /** | 120 | /** |
124 | * struct iwl4965_lq_sta -- driver's rate scaling private structure | 121 | * struct iwl4965_lq_sta -- driver's rate scaling private structure |
125 | * | 122 | * |
@@ -157,16 +154,12 @@ struct iwl4965_lq_sta { | |||
157 | 154 | ||
158 | struct iwl_link_quality_cmd lq; | 155 | struct iwl_link_quality_cmd lq; |
159 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ | 156 | struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ |
160 | #ifdef CONFIG_IWL4965_HT | ||
161 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; | 157 | struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; |
162 | u8 tx_agg_tid_en; | 158 | u8 tx_agg_tid_en; |
163 | #endif | ||
164 | #ifdef CONFIG_MAC80211_DEBUGFS | 159 | #ifdef CONFIG_MAC80211_DEBUGFS |
165 | struct dentry *rs_sta_dbgfs_scale_table_file; | 160 | struct dentry *rs_sta_dbgfs_scale_table_file; |
166 | struct dentry *rs_sta_dbgfs_stats_table_file; | 161 | struct dentry *rs_sta_dbgfs_stats_table_file; |
167 | #ifdef CONFIG_IWL4965_HT | ||
168 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; | 162 | struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; |
169 | #endif | ||
170 | u32 dbg_fixed_rate; | 163 | u32 dbg_fixed_rate; |
171 | #endif | 164 | #endif |
172 | struct iwl_priv *drv; | 165 | struct iwl_priv *drv; |
@@ -256,7 +249,6 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) | |||
256 | return ((ant_type & valid_antenna) == ant_type); | 249 | return ((ant_type & valid_antenna) == ant_type); |
257 | } | 250 | } |
258 | 251 | ||
259 | #ifdef CONFIG_IWL4965_HT | ||
260 | /* | 252 | /* |
261 | * removes the old data from the statistics. All data that is older than | 253 | * removes the old data from the statistics. All data that is older than |
262 | * TID_MAX_TIME_DIFF, will be deleted. | 254 | * TID_MAX_TIME_DIFF, will be deleted. |
@@ -282,21 +274,21 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) | |||
282 | * increment traffic load value for tid and also remove | 274 | * increment traffic load value for tid and also remove |
283 | * any old values if passed the certain time period | 275 | * any old values if passed the certain time period |
284 | */ | 276 | */ |
285 | static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, | 277 | static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, |
286 | struct ieee80211_hdr *hdr) | 278 | struct ieee80211_hdr *hdr) |
287 | { | 279 | { |
288 | u32 curr_time = jiffies_to_msecs(jiffies); | 280 | u32 curr_time = jiffies_to_msecs(jiffies); |
289 | u32 time_diff; | 281 | u32 time_diff; |
290 | s32 index; | 282 | s32 index; |
291 | struct iwl4965_traffic_load *tl = NULL; | 283 | struct iwl4965_traffic_load *tl = NULL; |
292 | u16 fc = le16_to_cpu(hdr->frame_control); | 284 | __le16 fc = hdr->frame_control; |
293 | u8 tid; | 285 | u8 tid; |
294 | 286 | ||
295 | if (ieee80211_is_qos_data(fc)) { | 287 | if (ieee80211_is_data_qos(fc)) { |
296 | u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); | 288 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
297 | tid = qc[0] & 0xf; | 289 | tid = qc[0] & 0xf; |
298 | } else | 290 | } else |
299 | return; | 291 | return MAX_TID_COUNT; |
300 | 292 | ||
301 | tl = &lq_data->load[tid]; | 293 | tl = &lq_data->load[tid]; |
302 | 294 | ||
@@ -309,7 +301,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, | |||
309 | tl->queue_count = 1; | 301 | tl->queue_count = 1; |
310 | tl->head = 0; | 302 | tl->head = 0; |
311 | tl->packet_count[0] = 1; | 303 | tl->packet_count[0] = 1; |
312 | return; | 304 | return MAX_TID_COUNT; |
313 | } | 305 | } |
314 | 306 | ||
315 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); | 307 | time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); |
@@ -326,6 +318,8 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, | |||
326 | 318 | ||
327 | if ((index + 1) > tl->queue_count) | 319 | if ((index + 1) > tl->queue_count) |
328 | tl->queue_count = index + 1; | 320 | tl->queue_count = index + 1; |
321 | |||
322 | return tid; | ||
329 | } | 323 | } |
330 | 324 | ||
331 | /* | 325 | /* |
@@ -389,8 +383,6 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, | |||
389 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); | 383 | rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); |
390 | } | 384 | } |
391 | 385 | ||
392 | #endif /* CONFIG_IWLWIFI_HT */ | ||
393 | |||
394 | static inline int get_num_of_ant_from_rate(u32 rate_n_flags) | 386 | static inline int get_num_of_ant_from_rate(u32 rate_n_flags) |
395 | { | 387 | { |
396 | return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) + | 388 | return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) + |
@@ -545,7 +537,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, | |||
545 | u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); | 537 | u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); |
546 | u8 mcs; | 538 | u8 mcs; |
547 | 539 | ||
548 | *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags); | 540 | *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); |
549 | 541 | ||
550 | if (*rate_idx == IWL_RATE_INVALID) { | 542 | if (*rate_idx == IWL_RATE_INVALID) { |
551 | *rate_idx = -1; | 543 | *rate_idx = -1; |
@@ -626,7 +618,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | |||
626 | 618 | ||
627 | /* FIXME:RS: in 4965 we don't use greenfield at all */ | 619 | /* FIXME:RS: in 4965 we don't use greenfield at all */ |
628 | /* FIXME:RS: don't use greenfield for now in TX */ | 620 | /* FIXME:RS: don't use greenfield for now in TX */ |
629 | /* #ifdef CONFIG_IWL4965_HT */ | ||
630 | #if 0 | 621 | #if 0 |
631 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) | 622 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) |
632 | { | 623 | { |
@@ -634,12 +625,11 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf | |||
634 | priv->current_ht_config.is_green_field && | 625 | priv->current_ht_config.is_green_field && |
635 | !priv->current_ht_config.non_GF_STA_present); | 626 | !priv->current_ht_config.non_GF_STA_present); |
636 | } | 627 | } |
637 | #else | 628 | #endif |
638 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) | 629 | static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) |
639 | { | 630 | { |
640 | return 0; | 631 | return 0; |
641 | } | 632 | } |
642 | #endif /* CONFIG_IWL4965_HT */ | ||
643 | 633 | ||
644 | /** | 634 | /** |
645 | * rs_get_supported_rates - get the available rates | 635 | * rs_get_supported_rates - get the available rates |
@@ -804,7 +794,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
804 | struct iwl4965_scale_tbl_info tbl_type; | 794 | struct iwl4965_scale_tbl_info tbl_type; |
805 | struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; | 795 | struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; |
806 | u8 active_index = 0; | 796 | u8 active_index = 0; |
807 | u16 fc = le16_to_cpu(hdr->frame_control); | 797 | __le16 fc = hdr->frame_control; |
808 | s32 tpt = 0; | 798 | s32 tpt = 0; |
809 | 799 | ||
810 | IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); | 800 | IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); |
@@ -1050,7 +1040,6 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, | |||
1050 | tbl->expected_tpt = expected_tpt_G; | 1040 | tbl->expected_tpt = expected_tpt_G; |
1051 | } | 1041 | } |
1052 | 1042 | ||
1053 | #ifdef CONFIG_IWL4965_HT | ||
1054 | /* | 1043 | /* |
1055 | * Find starting rate for new "search" high-throughput mode of modulation. | 1044 | * Find starting rate for new "search" high-throughput mode of modulation. |
1056 | * Goal is to find lowest expected rate (under perfect conditions) that is | 1045 | * Goal is to find lowest expected rate (under perfect conditions) that is |
@@ -1152,12 +1141,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1152 | 1141 | ||
1153 | return new_rate; | 1142 | return new_rate; |
1154 | } | 1143 | } |
1155 | #endif /* CONFIG_IWL4965_HT */ | ||
1156 | 1144 | ||
1157 | /* | 1145 | /* |
1158 | * Set up search table for MIMO | 1146 | * Set up search table for MIMO |
1159 | */ | 1147 | */ |
1160 | #ifdef CONFIG_IWL4965_HT | ||
1161 | static int rs_switch_to_mimo2(struct iwl_priv *priv, | 1148 | static int rs_switch_to_mimo2(struct iwl_priv *priv, |
1162 | struct iwl4965_lq_sta *lq_sta, | 1149 | struct iwl4965_lq_sta *lq_sta, |
1163 | struct ieee80211_conf *conf, | 1150 | struct ieee80211_conf *conf, |
@@ -1221,16 +1208,6 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, | |||
1221 | tbl->current_rate, is_green); | 1208 | tbl->current_rate, is_green); |
1222 | return 0; | 1209 | return 0; |
1223 | } | 1210 | } |
1224 | #else | ||
1225 | static int rs_switch_to_mimo2(struct iwl_priv *priv, | ||
1226 | struct iwl4965_lq_sta *lq_sta, | ||
1227 | struct ieee80211_conf *conf, | ||
1228 | struct sta_info *sta, | ||
1229 | struct iwl4965_scale_tbl_info *tbl, int index) | ||
1230 | { | ||
1231 | return -1; | ||
1232 | } | ||
1233 | #endif /*CONFIG_IWL4965_HT */ | ||
1234 | 1211 | ||
1235 | /* | 1212 | /* |
1236 | * Set up search table for SISO | 1213 | * Set up search table for SISO |
@@ -1241,7 +1218,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1241 | struct sta_info *sta, | 1218 | struct sta_info *sta, |
1242 | struct iwl4965_scale_tbl_info *tbl, int index) | 1219 | struct iwl4965_scale_tbl_info *tbl, int index) |
1243 | { | 1220 | { |
1244 | #ifdef CONFIG_IWL4965_HT | ||
1245 | u16 rate_mask; | 1221 | u16 rate_mask; |
1246 | u8 is_green = lq_sta->is_green; | 1222 | u8 is_green = lq_sta->is_green; |
1247 | s32 rate; | 1223 | s32 rate; |
@@ -1291,9 +1267,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv, | |||
1291 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", | 1267 | IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", |
1292 | tbl->current_rate, is_green); | 1268 | tbl->current_rate, is_green); |
1293 | return 0; | 1269 | return 0; |
1294 | #else | ||
1295 | return -1; | ||
1296 | #endif /*CONFIG_IWL4965_HT */ | ||
1297 | } | 1270 | } |
1298 | 1271 | ||
1299 | /* | 1272 | /* |
@@ -1678,7 +1651,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1678 | int high_tpt = IWL_INVALID_VALUE; | 1651 | int high_tpt = IWL_INVALID_VALUE; |
1679 | u32 fail_count; | 1652 | u32 fail_count; |
1680 | s8 scale_action = 0; | 1653 | s8 scale_action = 0; |
1681 | u16 fc, rate_mask; | 1654 | __le16 fc; |
1655 | u16 rate_mask; | ||
1682 | u8 update_lq = 0; | 1656 | u8 update_lq = 0; |
1683 | struct iwl4965_lq_sta *lq_sta; | 1657 | struct iwl4965_lq_sta *lq_sta; |
1684 | struct iwl4965_scale_tbl_info *tbl, *tbl1; | 1658 | struct iwl4965_scale_tbl_info *tbl, *tbl1; |
@@ -1689,13 +1663,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1689 | u8 done_search = 0; | 1663 | u8 done_search = 0; |
1690 | u16 high_low; | 1664 | u16 high_low; |
1691 | s32 sr; | 1665 | s32 sr; |
1692 | #ifdef CONFIG_IWL4965_HT | ||
1693 | u8 tid = MAX_TID_COUNT; | 1666 | u8 tid = MAX_TID_COUNT; |
1694 | #endif | ||
1695 | 1667 | ||
1696 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); | 1668 | IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); |
1697 | 1669 | ||
1698 | fc = le16_to_cpu(hdr->frame_control); | 1670 | fc = hdr->frame_control; |
1699 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { | 1671 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { |
1700 | /* Send management frames and broadcast/multicast data using | 1672 | /* Send management frames and broadcast/multicast data using |
1701 | * lowest rate. */ | 1673 | * lowest rate. */ |
@@ -1712,9 +1684,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1712 | } | 1684 | } |
1713 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; | 1685 | lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; |
1714 | 1686 | ||
1715 | #ifdef CONFIG_IWL4965_HT | 1687 | tid = rs_tl_add_packet(lq_sta, hdr); |
1716 | rs_tl_add_packet(lq_sta, hdr); | 1688 | |
1717 | #endif | ||
1718 | /* | 1689 | /* |
1719 | * Select rate-scale / modulation-mode table to work with in | 1690 | * Select rate-scale / modulation-mode table to work with in |
1720 | * the rest of this function: "search" if searching for better | 1691 | * the rest of this function: "search" if searching for better |
@@ -1842,8 +1813,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
1842 | tbl = &(lq_sta->lq_info[active_tbl]); | 1813 | tbl = &(lq_sta->lq_info[active_tbl]); |
1843 | 1814 | ||
1844 | /* Revert to "active" rate and throughput info */ | 1815 | /* Revert to "active" rate and throughput info */ |
1845 | index = iwl4965_hwrate_to_plcp_idx( | 1816 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); |
1846 | tbl->current_rate); | ||
1847 | current_tpt = lq_sta->last_tpt; | 1817 | current_tpt = lq_sta->last_tpt; |
1848 | 1818 | ||
1849 | /* Need to set up a new rate table in uCode */ | 1819 | /* Need to set up a new rate table in uCode */ |
@@ -1997,8 +1967,7 @@ lq_update: | |||
1997 | rs_rate_scale_clear_window(&(tbl->win[i])); | 1967 | rs_rate_scale_clear_window(&(tbl->win[i])); |
1998 | 1968 | ||
1999 | /* Use new "search" start rate */ | 1969 | /* Use new "search" start rate */ |
2000 | index = iwl4965_hwrate_to_plcp_idx( | 1970 | index = iwl_hwrate_to_plcp_idx(tbl->current_rate); |
2001 | tbl->current_rate); | ||
2002 | 1971 | ||
2003 | IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n", | 1972 | IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n", |
2004 | tbl->current_rate, index); | 1973 | tbl->current_rate, index); |
@@ -2013,9 +1982,7 @@ lq_update: | |||
2013 | * before next round of mode comparisons. */ | 1982 | * before next round of mode comparisons. */ |
2014 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); | 1983 | tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); |
2015 | if (is_legacy(tbl1->lq_type) && | 1984 | if (is_legacy(tbl1->lq_type) && |
2016 | #ifdef CONFIG_IWL4965_HT | ||
2017 | (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && | 1985 | (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && |
2018 | #endif | ||
2019 | (lq_sta->action_counter >= 1)) { | 1986 | (lq_sta->action_counter >= 1)) { |
2020 | lq_sta->action_counter = 0; | 1987 | lq_sta->action_counter = 0; |
2021 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); | 1988 | IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); |
@@ -2027,14 +1994,12 @@ lq_update: | |||
2027 | * mode for a while before next round of mode comparisons. */ | 1994 | * mode for a while before next round of mode comparisons. */ |
2028 | if (lq_sta->enable_counter && | 1995 | if (lq_sta->enable_counter && |
2029 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { | 1996 | (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { |
2030 | #ifdef CONFIG_IWL4965_HT | ||
2031 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && | 1997 | if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && |
2032 | (lq_sta->tx_agg_tid_en & (1 << tid)) && | 1998 | (lq_sta->tx_agg_tid_en & (1 << tid)) && |
2033 | (tid != MAX_TID_COUNT)) { | 1999 | (tid != MAX_TID_COUNT)) { |
2034 | IWL_DEBUG_RATE("try to aggregate tid %d\n", tid); | 2000 | IWL_DEBUG_RATE("try to aggregate tid %d\n", tid); |
2035 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); | 2001 | rs_tl_turn_on_agg(priv, tid, lq_sta, sta); |
2036 | } | 2002 | } |
2037 | #endif /*CONFIG_IWL4965_HT */ | ||
2038 | lq_sta->action_counter = 0; | 2003 | lq_sta->action_counter = 0; |
2039 | rs_set_stay_in_table(priv, 0, lq_sta); | 2004 | rs_set_stay_in_table(priv, 0, lq_sta); |
2040 | } | 2005 | } |
@@ -2136,7 +2101,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2136 | struct ieee80211_conf *conf = &local->hw.conf; | 2101 | struct ieee80211_conf *conf = &local->hw.conf; |
2137 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2102 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2138 | struct sta_info *sta; | 2103 | struct sta_info *sta; |
2139 | u16 fc; | 2104 | __le16 fc; |
2140 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; | 2105 | struct iwl_priv *priv = (struct iwl_priv *)priv_rate; |
2141 | struct iwl4965_lq_sta *lq_sta; | 2106 | struct iwl4965_lq_sta *lq_sta; |
2142 | 2107 | ||
@@ -2148,7 +2113,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, | |||
2148 | 2113 | ||
2149 | /* Send management frames and broadcast/multicast data using lowest | 2114 | /* Send management frames and broadcast/multicast data using lowest |
2150 | * rate. */ | 2115 | * rate. */ |
2151 | fc = le16_to_cpu(hdr->frame_control); | 2116 | fc = hdr->frame_control; |
2152 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || | 2117 | if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || |
2153 | !sta || !sta->rate_ctrl_priv) { | 2118 | !sta || !sta->rate_ctrl_priv) { |
2154 | sel->rate_idx = rate_lowest_index(local, sband, sta); | 2119 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
@@ -2279,30 +2244,23 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2279 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); | 2244 | lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); |
2280 | lq_sta->active_rate_basic = priv->active_rate_basic; | 2245 | lq_sta->active_rate_basic = priv->active_rate_basic; |
2281 | lq_sta->band = priv->band; | 2246 | lq_sta->band = priv->band; |
2282 | #ifdef CONFIG_IWL4965_HT | ||
2283 | /* | 2247 | /* |
2284 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), | 2248 | * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), |
2285 | * supp_rates[] does not; shift to convert format, force 9 MBits off. | 2249 | * supp_rates[] does not; shift to convert format, force 9 MBits off. |
2286 | */ | 2250 | */ |
2287 | lq_sta->active_siso_rate = | 2251 | lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1; |
2288 | priv->current_ht_config.supp_mcs_set[0] << 1; | 2252 | lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1; |
2289 | lq_sta->active_siso_rate |= | ||
2290 | priv->current_ht_config.supp_mcs_set[0] & 0x1; | ||
2291 | lq_sta->active_siso_rate &= ~((u16)0x2); | 2253 | lq_sta->active_siso_rate &= ~((u16)0x2); |
2292 | lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; | 2254 | lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; |
2293 | 2255 | ||
2294 | /* Same here */ | 2256 | /* Same here */ |
2295 | lq_sta->active_mimo2_rate = | 2257 | lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1; |
2296 | priv->current_ht_config.supp_mcs_set[1] << 1; | 2258 | lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1; |
2297 | lq_sta->active_mimo2_rate |= | ||
2298 | priv->current_ht_config.supp_mcs_set[1] & 0x1; | ||
2299 | lq_sta->active_mimo2_rate &= ~((u16)0x2); | 2259 | lq_sta->active_mimo2_rate &= ~((u16)0x2); |
2300 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; | 2260 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; |
2301 | 2261 | ||
2302 | lq_sta->active_mimo3_rate = | 2262 | lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1; |
2303 | priv->current_ht_config.supp_mcs_set[2] << 1; | 2263 | lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1; |
2304 | lq_sta->active_mimo3_rate |= | ||
2305 | priv->current_ht_config.supp_mcs_set[2] & 0x1; | ||
2306 | lq_sta->active_mimo3_rate &= ~((u16)0x2); | 2264 | lq_sta->active_mimo3_rate &= ~((u16)0x2); |
2307 | lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; | 2265 | lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; |
2308 | 2266 | ||
@@ -2317,7 +2275,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, | |||
2317 | 2275 | ||
2318 | /* as default allow aggregation for all tids */ | 2276 | /* as default allow aggregation for all tids */ |
2319 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; | 2277 | lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; |
2320 | #endif /*CONFIG_IWL4965_HT*/ | ||
2321 | #ifdef CONFIG_MAC80211_DEBUGFS | 2278 | #ifdef CONFIG_MAC80211_DEBUGFS |
2322 | lq_sta->drv = priv; | 2279 | lq_sta->drv = priv; |
2323 | #endif | 2280 | #endif |
@@ -2635,11 +2592,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta, | |||
2635 | lq_sta->rs_sta_dbgfs_stats_table_file = | 2592 | lq_sta->rs_sta_dbgfs_stats_table_file = |
2636 | debugfs_create_file("rate_stats_table", 0600, dir, | 2593 | debugfs_create_file("rate_stats_table", 0600, dir, |
2637 | lq_sta, &rs_sta_dbgfs_stats_table_ops); | 2594 | lq_sta, &rs_sta_dbgfs_stats_table_ops); |
2638 | #ifdef CONFIG_IWL4965_HT | ||
2639 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = | 2595 | lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = |
2640 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, | 2596 | debugfs_create_u8("tx_agg_tid_enable", 0600, dir, |
2641 | &lq_sta->tx_agg_tid_en); | 2597 | &lq_sta->tx_agg_tid_en); |
2642 | #endif | ||
2643 | 2598 | ||
2644 | } | 2599 | } |
2645 | 2600 | ||
@@ -2648,9 +2603,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) | |||
2648 | struct iwl4965_lq_sta *lq_sta = priv_sta; | 2603 | struct iwl4965_lq_sta *lq_sta = priv_sta; |
2649 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); | 2604 | debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); |
2650 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); | 2605 | debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); |
2651 | #ifdef CONFIG_IWL4965_HT | ||
2652 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); | 2606 | debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); |
2653 | #endif | ||
2654 | } | 2607 | } |
2655 | #endif | 2608 | #endif |
2656 | 2609 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index 1dd4124227a5..cbd126418490 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h | |||
@@ -286,8 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index) | |||
286 | return rate; | 286 | return rate; |
287 | } | 287 | } |
288 | 288 | ||
289 | extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags); | ||
290 | |||
291 | /** | 289 | /** |
292 | * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation | 290 | * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation |
293 | * | 291 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index aee7014bcb94..ab5027345a01 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -46,6 +46,9 @@ | |||
46 | #include "iwl-calib.h" | 46 | #include "iwl-calib.h" |
47 | #include "iwl-sta.h" | 47 | #include "iwl-sta.h" |
48 | 48 | ||
49 | static int iwl4965_send_tx_power(struct iwl_priv *priv); | ||
50 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); | ||
51 | |||
49 | /* module parameters */ | 52 | /* module parameters */ |
50 | static struct iwl_mod_params iwl4965_mod_params = { | 53 | static struct iwl_mod_params iwl4965_mod_params = { |
51 | .num_of_queues = IWL49_NUM_QUEUES, | 54 | .num_of_queues = IWL49_NUM_QUEUES, |
@@ -281,7 +284,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) | |||
281 | } | 284 | } |
282 | 285 | ||
283 | /* Calculate temperature */ | 286 | /* Calculate temperature */ |
284 | priv->temperature = iwl4965_get_temperature(priv); | 287 | priv->temperature = iwl4965_hw_get_temperature(priv); |
285 | 288 | ||
286 | /* Send pointers to protocol/runtime uCode image ... init code will | 289 | /* Send pointers to protocol/runtime uCode image ... init code will |
287 | * load and launch runtime uCode, which will send us another "Alive" | 290 | * load and launch runtime uCode, which will send us another "Alive" |
@@ -305,60 +308,6 @@ static int is_fat_channel(__le32 rxon_flags) | |||
305 | (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); | 308 | (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); |
306 | } | 309 | } |
307 | 310 | ||
308 | int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) | ||
309 | { | ||
310 | int idx = 0; | ||
311 | |||
312 | /* 4965 HT rate format */ | ||
313 | if (rate_n_flags & RATE_MCS_HT_MSK) { | ||
314 | idx = (rate_n_flags & 0xff); | ||
315 | |||
316 | if (idx >= IWL_RATE_MIMO2_6M_PLCP) | ||
317 | idx = idx - IWL_RATE_MIMO2_6M_PLCP; | ||
318 | |||
319 | idx += IWL_FIRST_OFDM_RATE; | ||
320 | /* skip 9M not supported in ht*/ | ||
321 | if (idx >= IWL_RATE_9M_INDEX) | ||
322 | idx += 1; | ||
323 | if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) | ||
324 | return idx; | ||
325 | |||
326 | /* 4965 legacy rate format, search for match in table */ | ||
327 | } else { | ||
328 | for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) | ||
329 | if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) | ||
330 | return idx; | ||
331 | } | ||
332 | |||
333 | return -1; | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * translate ucode response to mac80211 tx status control values | ||
338 | */ | ||
339 | void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | ||
340 | struct ieee80211_tx_info *control) | ||
341 | { | ||
342 | int rate_index; | ||
343 | |||
344 | control->antenna_sel_tx = | ||
345 | ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); | ||
346 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
347 | control->flags |= IEEE80211_TX_CTL_OFDM_HT; | ||
348 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
349 | control->flags |= IEEE80211_TX_CTL_GREEN_FIELD; | ||
350 | if (rate_n_flags & RATE_MCS_FAT_MSK) | ||
351 | control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH; | ||
352 | if (rate_n_flags & RATE_MCS_DUP_MSK) | ||
353 | control->flags |= IEEE80211_TX_CTL_DUP_DATA; | ||
354 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
355 | control->flags |= IEEE80211_TX_CTL_SHORT_GI; | ||
356 | rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags); | ||
357 | if (control->band == IEEE80211_BAND_5GHZ) | ||
358 | rate_index -= IWL_FIRST_OFDM_RATE; | ||
359 | control->tx_rate_idx = rate_index; | ||
360 | } | ||
361 | |||
362 | /* | 311 | /* |
363 | * EEPROM handlers | 312 | * EEPROM handlers |
364 | */ | 313 | */ |
@@ -608,52 +557,6 @@ out: | |||
608 | 557 | ||
609 | #define REG_RECALIB_PERIOD (60) | 558 | #define REG_RECALIB_PERIOD (60) |
610 | 559 | ||
611 | /** | ||
612 | * iwl4965_bg_statistics_periodic - Timer callback to queue statistics | ||
613 | * | ||
614 | * This callback is provided in order to send a statistics request. | ||
615 | * | ||
616 | * This timer function is continually reset to execute within | ||
617 | * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION | ||
618 | * was received. We need to ensure we receive the statistics in order | ||
619 | * to update the temperature used for calibrating the TXPOWER. | ||
620 | */ | ||
621 | static void iwl4965_bg_statistics_periodic(unsigned long data) | ||
622 | { | ||
623 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
624 | |||
625 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
626 | return; | ||
627 | |||
628 | iwl_send_statistics_request(priv, CMD_ASYNC); | ||
629 | } | ||
630 | |||
631 | void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) | ||
632 | { | ||
633 | struct iwl4965_ct_kill_config cmd; | ||
634 | unsigned long flags; | ||
635 | int ret = 0; | ||
636 | |||
637 | spin_lock_irqsave(&priv->lock, flags); | ||
638 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
639 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | ||
640 | spin_unlock_irqrestore(&priv->lock, flags); | ||
641 | |||
642 | cmd.critical_temperature_R = | ||
643 | cpu_to_le32(priv->hw_params.ct_kill_threshold); | ||
644 | |||
645 | ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, | ||
646 | sizeof(cmd), &cmd); | ||
647 | if (ret) | ||
648 | IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); | ||
649 | else | ||
650 | IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " | ||
651 | "critical temperature is %d\n", | ||
652 | cmd.critical_temperature_R); | ||
653 | } | ||
654 | |||
655 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | ||
656 | |||
657 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. | 560 | /* Reset differential Rx gains in NIC to prepare for chain noise calibration. |
658 | * Called after every association, but this runs only once! | 561 | * Called after every association, but this runs only once! |
659 | * ... once chain noise is calibrated the first time, it's good forever. */ | 562 | * ... once chain noise is calibrated the first time, it's good forever. */ |
@@ -741,30 +644,6 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, | |||
741 | data->beacon_count = 0; | 644 | data->beacon_count = 0; |
742 | } | 645 | } |
743 | 646 | ||
744 | static void iwl4965_bg_sensitivity_work(struct work_struct *work) | ||
745 | { | ||
746 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | ||
747 | sensitivity_work); | ||
748 | |||
749 | mutex_lock(&priv->mutex); | ||
750 | |||
751 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | ||
752 | test_bit(STATUS_SCANNING, &priv->status)) { | ||
753 | mutex_unlock(&priv->mutex); | ||
754 | return; | ||
755 | } | ||
756 | |||
757 | if (priv->start_calib) { | ||
758 | iwl_chain_noise_calibration(priv, &priv->statistics); | ||
759 | |||
760 | iwl_sensitivity_calibration(priv, &priv->statistics); | ||
761 | } | ||
762 | |||
763 | mutex_unlock(&priv->mutex); | ||
764 | return; | ||
765 | } | ||
766 | #endif /*CONFIG_IWL4965_RUN_TIME_CALIB*/ | ||
767 | |||
768 | static void iwl4965_bg_txpower_work(struct work_struct *work) | 647 | static void iwl4965_bg_txpower_work(struct work_struct *work) |
769 | { | 648 | { |
770 | struct iwl_priv *priv = container_of(work, struct iwl_priv, | 649 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
@@ -783,7 +662,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) | |||
783 | /* Regardless of if we are assocaited, we must reconfigure the | 662 | /* Regardless of if we are assocaited, we must reconfigure the |
784 | * TX power since frames can be sent on non-radar channels while | 663 | * TX power since frames can be sent on non-radar channels while |
785 | * not associated */ | 664 | * not associated */ |
786 | iwl4965_hw_reg_send_txpower(priv); | 665 | iwl4965_send_tx_power(priv); |
787 | 666 | ||
788 | /* Update last_temperature to keep is_calib_needed from running | 667 | /* Update last_temperature to keep is_calib_needed from running |
789 | * when it isn't needed... */ | 668 | * when it isn't needed... */ |
@@ -843,7 +722,7 @@ static const u16 default_queue_to_tx_fifo[] = { | |||
843 | IWL_TX_FIFO_HCCA_2 | 722 | IWL_TX_FIFO_HCCA_2 |
844 | }; | 723 | }; |
845 | 724 | ||
846 | int iwl4965_alive_notify(struct iwl_priv *priv) | 725 | static int iwl4965_alive_notify(struct iwl_priv *priv) |
847 | { | 726 | { |
848 | u32 a; | 727 | u32 a; |
849 | int i = 0; | 728 | int i = 0; |
@@ -920,7 +799,6 @@ int iwl4965_alive_notify(struct iwl_priv *priv) | |||
920 | return ret; | 799 | return ret; |
921 | } | 800 | } |
922 | 801 | ||
923 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | ||
924 | static struct iwl_sensitivity_ranges iwl4965_sensitivity = { | 802 | static struct iwl_sensitivity_ranges iwl4965_sensitivity = { |
925 | .min_nrg_cck = 97, | 803 | .min_nrg_cck = 97, |
926 | .max_nrg_cck = 0, | 804 | .max_nrg_cck = 0, |
@@ -943,14 +821,13 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = { | |||
943 | .nrg_th_cck = 100, | 821 | .nrg_th_cck = 100, |
944 | .nrg_th_ofdm = 100, | 822 | .nrg_th_ofdm = 100, |
945 | }; | 823 | }; |
946 | #endif | ||
947 | 824 | ||
948 | /** | 825 | /** |
949 | * iwl4965_hw_set_hw_params | 826 | * iwl4965_hw_set_hw_params |
950 | * | 827 | * |
951 | * Called when initializing driver | 828 | * Called when initializing driver |
952 | */ | 829 | */ |
953 | int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | 830 | static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) |
954 | { | 831 | { |
955 | 832 | ||
956 | if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || | 833 | if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || |
@@ -961,6 +838,7 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
961 | } | 838 | } |
962 | 839 | ||
963 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 840 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
841 | priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; | ||
964 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; | 842 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; |
965 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 843 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
966 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 844 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
@@ -983,9 +861,7 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
983 | priv->hw_params.valid_rx_ant = ANT_A | ANT_B; | 861 | priv->hw_params.valid_rx_ant = ANT_A | ANT_B; |
984 | priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); | 862 | priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); |
985 | 863 | ||
986 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | ||
987 | priv->hw_params.sens = &iwl4965_sensitivity; | 864 | priv->hw_params.sens = &iwl4965_sensitivity; |
988 | #endif | ||
989 | 865 | ||
990 | return 0; | 866 | return 0; |
991 | } | 867 | } |
@@ -1001,11 +877,6 @@ static int iwl4965_set_power(struct iwl_priv *priv, | |||
1001 | cmd, NULL); | 877 | cmd, NULL); |
1002 | return ret; | 878 | return ret; |
1003 | } | 879 | } |
1004 | int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) | ||
1005 | { | ||
1006 | IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n"); | ||
1007 | return -EINVAL; | ||
1008 | } | ||
1009 | 880 | ||
1010 | static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) | 881 | static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) |
1011 | { | 882 | { |
@@ -1056,20 +927,6 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, | |||
1056 | return comp; | 927 | return comp; |
1057 | } | 928 | } |
1058 | 929 | ||
1059 | static const struct iwl_channel_info * | ||
1060 | iwl4965_get_channel_txpower_info(struct iwl_priv *priv, | ||
1061 | enum ieee80211_band band, u16 channel) | ||
1062 | { | ||
1063 | const struct iwl_channel_info *ch_info; | ||
1064 | |||
1065 | ch_info = iwl_get_channel_info(priv, band, channel); | ||
1066 | |||
1067 | if (!is_channel_valid(ch_info)) | ||
1068 | return NULL; | ||
1069 | |||
1070 | return ch_info; | ||
1071 | } | ||
1072 | |||
1073 | static s32 iwl4965_get_tx_atten_grp(u16 channel) | 930 | static s32 iwl4965_get_tx_atten_grp(u16 channel) |
1074 | { | 931 | { |
1075 | if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && | 932 | if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && |
@@ -1493,30 +1350,17 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1493 | s32 factory_actual_pwr[2]; | 1350 | s32 factory_actual_pwr[2]; |
1494 | s32 power_index; | 1351 | s32 power_index; |
1495 | 1352 | ||
1496 | /* Sanity check requested level (dBm) */ | ||
1497 | if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) { | ||
1498 | IWL_WARNING("Requested user TXPOWER %d below limit.\n", | ||
1499 | priv->user_txpower_limit); | ||
1500 | return -EINVAL; | ||
1501 | } | ||
1502 | if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) { | ||
1503 | IWL_WARNING("Requested user TXPOWER %d above limit.\n", | ||
1504 | priv->user_txpower_limit); | ||
1505 | return -EINVAL; | ||
1506 | } | ||
1507 | |||
1508 | /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units | 1353 | /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units |
1509 | * are used for indexing into txpower table) */ | 1354 | * are used for indexing into txpower table) */ |
1510 | user_target_power = 2 * priv->user_txpower_limit; | 1355 | user_target_power = 2 * priv->tx_power_user_lmt; |
1511 | 1356 | ||
1512 | /* Get current (RXON) channel, band, width */ | 1357 | /* Get current (RXON) channel, band, width */ |
1513 | ch_info = | ||
1514 | iwl4965_get_channel_txpower_info(priv, priv->band, channel); | ||
1515 | |||
1516 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, | 1358 | IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, |
1517 | is_fat); | 1359 | is_fat); |
1518 | 1360 | ||
1519 | if (!ch_info) | 1361 | ch_info = iwl_get_channel_info(priv, priv->band, channel); |
1362 | |||
1363 | if (!is_channel_valid(ch_info)) | ||
1520 | return -EINVAL; | 1364 | return -EINVAL; |
1521 | 1365 | ||
1522 | /* get txatten group, used to select 1) thermal txpower adjustment | 1366 | /* get txatten group, used to select 1) thermal txpower adjustment |
@@ -1717,12 +1561,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
1717 | } | 1561 | } |
1718 | 1562 | ||
1719 | /** | 1563 | /** |
1720 | * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit | 1564 | * iwl4965_send_tx_power - Configure the TXPOWER level user limit |
1721 | * | 1565 | * |
1722 | * Uses the active RXON for channel, band, and characteristics (fat, high) | 1566 | * Uses the active RXON for channel, band, and characteristics (fat, high) |
1723 | * The power limit is taken from priv->user_txpower_limit. | 1567 | * The power limit is taken from priv->tx_power_user_lmt. |
1724 | */ | 1568 | */ |
1725 | int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv) | 1569 | static int iwl4965_send_tx_power(struct iwl_priv *priv) |
1726 | { | 1570 | { |
1727 | struct iwl4965_txpowertable_cmd cmd = { 0 }; | 1571 | struct iwl4965_txpowertable_cmd cmd = { 0 }; |
1728 | int ret; | 1572 | int ret; |
@@ -1848,11 +1692,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) | |||
1848 | return le32_to_cpu(s->rb_closed) & 0xFFF; | 1692 | return le32_to_cpu(s->rb_closed) & 0xFFF; |
1849 | } | 1693 | } |
1850 | 1694 | ||
1851 | int iwl4965_hw_get_temperature(struct iwl_priv *priv) | ||
1852 | { | ||
1853 | return priv->temperature; | ||
1854 | } | ||
1855 | |||
1856 | unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | 1695 | unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, |
1857 | struct iwl_frame *frame, u8 rate) | 1696 | struct iwl_frame *frame, u8 rate) |
1858 | { | 1697 | { |
@@ -1875,10 +1714,10 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
1875 | 1714 | ||
1876 | if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) | 1715 | if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) |
1877 | tx_beacon_cmd->tx.rate_n_flags = | 1716 | tx_beacon_cmd->tx.rate_n_flags = |
1878 | iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); | 1717 | iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); |
1879 | else | 1718 | else |
1880 | tx_beacon_cmd->tx.rate_n_flags = | 1719 | tx_beacon_cmd->tx.rate_n_flags = |
1881 | iwl4965_hw_set_rate_n_flags(rate, 0); | 1720 | iwl_hw_set_rate_n_flags(rate, 0); |
1882 | 1721 | ||
1883 | tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | | 1722 | tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | |
1884 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK); | 1723 | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK); |
@@ -1950,12 +1789,12 @@ static s32 sign_extend(u32 oper, int index) | |||
1950 | } | 1789 | } |
1951 | 1790 | ||
1952 | /** | 1791 | /** |
1953 | * iwl4965_get_temperature - return the calibrated temperature (in Kelvin) | 1792 | * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) |
1954 | * @statistics: Provides the temperature reading from the uCode | 1793 | * @statistics: Provides the temperature reading from the uCode |
1955 | * | 1794 | * |
1956 | * A return of <0 indicates bogus data in the statistics | 1795 | * A return of <0 indicates bogus data in the statistics |
1957 | */ | 1796 | */ |
1958 | int iwl4965_get_temperature(const struct iwl_priv *priv) | 1797 | static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) |
1959 | { | 1798 | { |
1960 | s32 temperature; | 1799 | s32 temperature; |
1961 | s32 vt; | 1800 | s32 vt; |
@@ -1990,8 +1829,7 @@ int iwl4965_get_temperature(const struct iwl_priv *priv) | |||
1990 | vt = sign_extend( | 1829 | vt = sign_extend( |
1991 | le32_to_cpu(priv->statistics.general.temperature), 23); | 1830 | le32_to_cpu(priv->statistics.general.temperature), 23); |
1992 | 1831 | ||
1993 | IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", | 1832 | IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); |
1994 | R1, R2, R3, vt); | ||
1995 | 1833 | ||
1996 | if (R3 == R1) { | 1834 | if (R3 == R1) { |
1997 | IWL_ERROR("Calibration conflict R1 == R3\n"); | 1835 | IWL_ERROR("Calibration conflict R1 == R3\n"); |
@@ -2002,11 +1840,10 @@ int iwl4965_get_temperature(const struct iwl_priv *priv) | |||
2002 | * Add offset to center the adjustment around 0 degrees Centigrade. */ | 1840 | * Add offset to center the adjustment around 0 degrees Centigrade. */ |
2003 | temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); | 1841 | temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); |
2004 | temperature /= (R3 - R1); | 1842 | temperature /= (R3 - R1); |
2005 | temperature = (temperature * 97) / 100 + | 1843 | temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; |
2006 | TEMPERATURE_CALIB_KELVIN_OFFSET; | ||
2007 | 1844 | ||
2008 | IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature, | 1845 | IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", |
2009 | KELVIN_TO_CELSIUS(temperature)); | 1846 | temperature, KELVIN_TO_CELSIUS(temperature)); |
2010 | 1847 | ||
2011 | return temperature; | 1848 | return temperature; |
2012 | } | 1849 | } |
@@ -2123,9 +1960,7 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | |||
2123 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | 1960 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
2124 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { | 1961 | (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { |
2125 | iwl4965_rx_calc_noise(priv); | 1962 | iwl4965_rx_calc_noise(priv); |
2126 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 1963 | queue_work(priv->workqueue, &priv->run_time_calib_work); |
2127 | queue_work(priv->workqueue, &priv->sensitivity_work); | ||
2128 | #endif | ||
2129 | } | 1964 | } |
2130 | 1965 | ||
2131 | iwl_leds_background(priv); | 1966 | iwl_leds_background(priv); |
@@ -2136,7 +1971,7 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | |||
2136 | if (!change) | 1971 | if (!change) |
2137 | return; | 1972 | return; |
2138 | 1973 | ||
2139 | temp = iwl4965_get_temperature(priv); | 1974 | temp = iwl4965_hw_get_temperature(priv); |
2140 | if (temp < 0) | 1975 | if (temp < 0) |
2141 | return; | 1976 | return; |
2142 | 1977 | ||
@@ -2155,8 +1990,9 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | |||
2155 | priv->temperature = temp; | 1990 | priv->temperature = temp; |
2156 | set_bit(STATUS_TEMPERATURE, &priv->status); | 1991 | set_bit(STATUS_TEMPERATURE, &priv->status); |
2157 | 1992 | ||
2158 | if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && | 1993 | if (!priv->disable_tx_power_cal && |
2159 | iwl4965_is_temp_calib_needed(priv)) | 1994 | unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && |
1995 | iwl4965_is_temp_calib_needed(priv)) | ||
2160 | queue_work(priv->workqueue, &priv->txpower_work); | 1996 | queue_work(priv->workqueue, &priv->txpower_work); |
2161 | } | 1997 | } |
2162 | 1998 | ||
@@ -2552,7 +2388,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2552 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | 2388 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ |
2553 | u32 hundred = 0; | 2389 | u32 hundred = 0; |
2554 | u32 dataframe = 0; | 2390 | u32 dataframe = 0; |
2555 | u16 fc; | 2391 | __le16 fc; |
2556 | u16 seq_ctl; | 2392 | u16 seq_ctl; |
2557 | u16 channel; | 2393 | u16 channel; |
2558 | u16 phy_flags; | 2394 | u16 phy_flags; |
@@ -2575,7 +2411,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2575 | return; | 2411 | return; |
2576 | 2412 | ||
2577 | /* MAC header */ | 2413 | /* MAC header */ |
2578 | fc = le16_to_cpu(header->frame_control); | 2414 | fc = header->frame_control; |
2579 | seq_ctl = le16_to_cpu(header->seq_ctrl); | 2415 | seq_ctl = le16_to_cpu(header->seq_ctrl); |
2580 | 2416 | ||
2581 | /* metadata */ | 2417 | /* metadata */ |
@@ -2600,8 +2436,8 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2600 | 2436 | ||
2601 | /* if data frame is to us and all is good, | 2437 | /* if data frame is to us and all is good, |
2602 | * (optionally) print summary for only 1 out of every 100 */ | 2438 | * (optionally) print summary for only 1 out of every 100 */ |
2603 | if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == | 2439 | if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == |
2604 | (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | 2440 | cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { |
2605 | dataframe = 1; | 2441 | dataframe = 1; |
2606 | if (!group100) | 2442 | if (!group100) |
2607 | print_summary = 1; /* print each frame */ | 2443 | print_summary = 1; /* print each frame */ |
@@ -2625,13 +2461,13 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2625 | 2461 | ||
2626 | if (hundred) | 2462 | if (hundred) |
2627 | title = "100Frames"; | 2463 | title = "100Frames"; |
2628 | else if (fc & IEEE80211_FCTL_RETRY) | 2464 | else if (ieee80211_has_retry(fc)) |
2629 | title = "Retry"; | 2465 | title = "Retry"; |
2630 | else if (ieee80211_is_assoc_response(fc)) | 2466 | else if (ieee80211_is_assoc_resp(fc)) |
2631 | title = "AscRsp"; | 2467 | title = "AscRsp"; |
2632 | else if (ieee80211_is_reassoc_response(fc)) | 2468 | else if (ieee80211_is_reassoc_resp(fc)) |
2633 | title = "RasRsp"; | 2469 | title = "RasRsp"; |
2634 | else if (ieee80211_is_probe_response(fc)) { | 2470 | else if (ieee80211_is_probe_resp(fc)) { |
2635 | title = "PrbRsp"; | 2471 | title = "PrbRsp"; |
2636 | print_dump = 1; /* dump frame contents */ | 2472 | print_dump = 1; /* dump frame contents */ |
2637 | } else if (ieee80211_is_beacon(fc)) { | 2473 | } else if (ieee80211_is_beacon(fc)) { |
@@ -2648,7 +2484,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2648 | else | 2484 | else |
2649 | title = "Frame"; | 2485 | title = "Frame"; |
2650 | 2486 | ||
2651 | rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym); | 2487 | rate_idx = iwl_hwrate_to_plcp_idx(rate_sym); |
2652 | if (unlikely(rate_idx == -1)) | 2488 | if (unlikely(rate_idx == -1)) |
2653 | bitrate = 0; | 2489 | bitrate = 0; |
2654 | else | 2490 | else |
@@ -2660,14 +2496,14 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, | |||
2660 | if (dataframe) | 2496 | if (dataframe) |
2661 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | 2497 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " |
2662 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", | 2498 | "len=%u, rssi=%d, chnl=%d, rate=%u, \n", |
2663 | title, fc, header->addr1[5], | 2499 | title, le16_to_cpu(fc), header->addr1[5], |
2664 | length, rssi, channel, bitrate); | 2500 | length, rssi, channel, bitrate); |
2665 | else { | 2501 | else { |
2666 | /* src/dst addresses assume managed mode */ | 2502 | /* src/dst addresses assume managed mode */ |
2667 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | 2503 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " |
2668 | "src=0x%02x, rssi=%u, tim=%lu usec, " | 2504 | "src=0x%02x, rssi=%u, tim=%lu usec, " |
2669 | "phy=0x%02x, chnl=%d\n", | 2505 | "phy=0x%02x, chnl=%d\n", |
2670 | title, fc, header->addr1[5], | 2506 | title, le16_to_cpu(fc), header->addr1[5], |
2671 | header->addr3[5], rssi, | 2507 | header->addr3[5], rssi, |
2672 | tsf_low - priv->scan_start_tsf, | 2508 | tsf_low - priv->scan_start_tsf, |
2673 | phy_flags, channel); | 2509 | phy_flags, channel); |
@@ -2713,7 +2549,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
2713 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? | 2549 | rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? |
2714 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; | 2550 | IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; |
2715 | rx_status.rate_idx = | 2551 | rx_status.rate_idx = |
2716 | iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); | 2552 | iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); |
2717 | if (rx_status.band == IEEE80211_BAND_5GHZ) | 2553 | if (rx_status.band == IEEE80211_BAND_5GHZ) |
2718 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; | 2554 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; |
2719 | 2555 | ||
@@ -2819,7 +2655,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
2819 | break; | 2655 | break; |
2820 | 2656 | ||
2821 | case IEEE80211_FTYPE_CTL: | 2657 | case IEEE80211_FTYPE_CTL: |
2822 | #ifdef CONFIG_IWL4965_HT | ||
2823 | switch (fc & IEEE80211_FCTL_STYPE) { | 2658 | switch (fc & IEEE80211_FCTL_STYPE) { |
2824 | case IEEE80211_STYPE_BACK_REQ: | 2659 | case IEEE80211_STYPE_BACK_REQ: |
2825 | IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); | 2660 | IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); |
@@ -2829,7 +2664,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
2829 | default: | 2664 | default: |
2830 | break; | 2665 | break; |
2831 | } | 2666 | } |
2832 | #endif | ||
2833 | break; | 2667 | break; |
2834 | 2668 | ||
2835 | case IEEE80211_FTYPE_DATA: { | 2669 | case IEEE80211_FTYPE_DATA: { |
@@ -2863,8 +2697,6 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, | |||
2863 | } | 2697 | } |
2864 | } | 2698 | } |
2865 | 2699 | ||
2866 | #ifdef CONFIG_IWL4965_HT | ||
2867 | |||
2868 | /** | 2700 | /** |
2869 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack | 2701 | * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack |
2870 | * | 2702 | * |
@@ -2926,7 +2758,7 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
2926 | info->flags |= IEEE80211_TX_STAT_AMPDU; | 2758 | info->flags |= IEEE80211_TX_STAT_AMPDU; |
2927 | info->status.ampdu_ack_map = successes; | 2759 | info->status.ampdu_ack_map = successes; |
2928 | info->status.ampdu_ack_len = agg->frame_count; | 2760 | info->status.ampdu_ack_len = agg->frame_count; |
2929 | iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info); | 2761 | iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info); |
2930 | 2762 | ||
2931 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); | 2763 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); |
2932 | 2764 | ||
@@ -2948,7 +2780,7 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, | |||
2948 | } | 2780 | } |
2949 | 2781 | ||
2950 | /** | 2782 | /** |
2951 | * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID | 2783 | * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE |
2952 | * priv->lock must be held by the caller | 2784 | * priv->lock must be held by the caller |
2953 | */ | 2785 | */ |
2954 | static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | 2786 | static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, |
@@ -2956,9 +2788,9 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | |||
2956 | { | 2788 | { |
2957 | int ret = 0; | 2789 | int ret = 0; |
2958 | 2790 | ||
2959 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { | 2791 | if (IWL49_FIRST_AMPDU_QUEUE > txq_id) { |
2960 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 2792 | IWL_WARNING("queue number too small: %d, must be > %d\n", |
2961 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | 2793 | txq_id, IWL49_FIRST_AMPDU_QUEUE); |
2962 | return -EINVAL; | 2794 | return -EINVAL; |
2963 | } | 2795 | } |
2964 | 2796 | ||
@@ -3046,7 +2878,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
3046 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 2878 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
3047 | /* calculate mac80211 ampdu sw queue to wake */ | 2879 | /* calculate mac80211 ampdu sw queue to wake */ |
3048 | int ampdu_q = | 2880 | int ampdu_q = |
3049 | scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; | 2881 | scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues; |
3050 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | 2882 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); |
3051 | priv->stations[ba_resp->sta_id]. | 2883 | priv->stations[ba_resp->sta_id]. |
3052 | tid[ba_resp->tid].tfds_in_queue -= freed; | 2884 | tid[ba_resp->tid].tfds_in_queue -= freed; |
@@ -3091,7 +2923,7 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, | |||
3091 | /** | 2923 | /** |
3092 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue | 2924 | * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue |
3093 | * | 2925 | * |
3094 | * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID, | 2926 | * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, |
3095 | * i.e. it must be one of the higher queues used for aggregation | 2927 | * i.e. it must be one of the higher queues used for aggregation |
3096 | */ | 2928 | */ |
3097 | static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | 2929 | static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, |
@@ -3101,9 +2933,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
3101 | int ret; | 2933 | int ret; |
3102 | u16 ra_tid; | 2934 | u16 ra_tid; |
3103 | 2935 | ||
3104 | if (IWL_BACK_QUEUE_FIRST_ID > txq_id) | 2936 | if (IWL49_FIRST_AMPDU_QUEUE > txq_id) |
3105 | IWL_WARNING("queue number too small: %d, must be > %d\n", | 2937 | IWL_WARNING("queue number too small: %d, must be > %d\n", |
3106 | txq_id, IWL_BACK_QUEUE_FIRST_ID); | 2938 | txq_id, IWL49_FIRST_AMPDU_QUEUE); |
3107 | 2939 | ||
3108 | ra_tid = BUILD_RAxTID(sta_id, tid); | 2940 | ra_tid = BUILD_RAxTID(sta_id, tid); |
3109 | 2941 | ||
@@ -3154,10 +2986,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, | |||
3154 | return 0; | 2986 | return 0; |
3155 | } | 2987 | } |
3156 | 2988 | ||
3157 | #endif /* CONFIG_IWL4965_HT */ | ||
3158 | |||
3159 | |||
3160 | #ifdef CONFIG_IWL4965_HT | ||
3161 | static int iwl4965_rx_agg_start(struct iwl_priv *priv, | 2989 | static int iwl4965_rx_agg_start(struct iwl_priv *priv, |
3162 | const u8 *addr, int tid, u16 ssn) | 2990 | const u8 *addr, int tid, u16 ssn) |
3163 | { | 2991 | { |
@@ -3231,8 +3059,6 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | |||
3231 | } | 3059 | } |
3232 | return 0; | 3060 | return 0; |
3233 | } | 3061 | } |
3234 | #endif /* CONFIG_IWL4965_HT */ | ||
3235 | |||
3236 | 3062 | ||
3237 | static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) | 3063 | static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) |
3238 | { | 3064 | { |
@@ -3262,13 +3088,9 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | |||
3262 | return (u16)sizeof(struct iwl4965_addsta_cmd); | 3088 | return (u16)sizeof(struct iwl4965_addsta_cmd); |
3263 | } | 3089 | } |
3264 | 3090 | ||
3265 | #ifdef CONFIG_IWL4965_HT | ||
3266 | static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | 3091 | static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) |
3267 | { | 3092 | { |
3268 | __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + | 3093 | return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; |
3269 | tx_resp->frame_count); | ||
3270 | return le32_to_cpu(*scd_ssn) & MAX_SN; | ||
3271 | |||
3272 | } | 3094 | } |
3273 | 3095 | ||
3274 | /** | 3096 | /** |
@@ -3276,32 +3098,29 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) | |||
3276 | */ | 3098 | */ |
3277 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | 3099 | static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, |
3278 | struct iwl_ht_agg *agg, | 3100 | struct iwl_ht_agg *agg, |
3279 | struct iwl4965_tx_resp_agg *tx_resp, | 3101 | struct iwl4965_tx_resp *tx_resp, |
3280 | u16 start_idx) | 3102 | int txq_id, u16 start_idx) |
3281 | { | 3103 | { |
3282 | u16 status; | 3104 | u16 status; |
3283 | struct agg_tx_status *frame_status = &tx_resp->status; | 3105 | struct agg_tx_status *frame_status = tx_resp->u.agg_status; |
3284 | struct ieee80211_tx_info *info = NULL; | 3106 | struct ieee80211_tx_info *info = NULL; |
3285 | struct ieee80211_hdr *hdr = NULL; | 3107 | struct ieee80211_hdr *hdr = NULL; |
3286 | int i, sh; | 3108 | u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
3287 | int txq_id, idx; | 3109 | int i, sh, idx; |
3288 | u16 seq; | 3110 | u16 seq; |
3289 | |||
3290 | if (agg->wait_for_ba) | 3111 | if (agg->wait_for_ba) |
3291 | IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); | 3112 | IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); |
3292 | 3113 | ||
3293 | agg->frame_count = tx_resp->frame_count; | 3114 | agg->frame_count = tx_resp->frame_count; |
3294 | agg->start_idx = start_idx; | 3115 | agg->start_idx = start_idx; |
3295 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 3116 | agg->rate_n_flags = rate_n_flags; |
3296 | agg->bitmap = 0; | 3117 | agg->bitmap = 0; |
3297 | 3118 | ||
3298 | /* # frames attempted by Tx command */ | 3119 | /* # frames attempted by Tx command */ |
3299 | if (agg->frame_count == 1) { | 3120 | if (agg->frame_count == 1) { |
3300 | /* Only one frame was attempted; no block-ack will arrive */ | 3121 | /* Only one frame was attempted; no block-ack will arrive */ |
3301 | status = le16_to_cpu(frame_status[0].status); | 3122 | status = le16_to_cpu(frame_status[0].status); |
3302 | seq = le16_to_cpu(frame_status[0].sequence); | 3123 | idx = start_idx; |
3303 | idx = SEQ_TO_INDEX(seq); | ||
3304 | txq_id = SEQ_TO_QUEUE(seq); | ||
3305 | 3124 | ||
3306 | /* FIXME: code repetition */ | 3125 | /* FIXME: code repetition */ |
3307 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", | 3126 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", |
@@ -3312,15 +3131,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
3312 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 3131 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
3313 | info->flags |= iwl_is_tx_success(status)? | 3132 | info->flags |= iwl_is_tx_success(status)? |
3314 | IEEE80211_TX_STAT_ACK : 0; | 3133 | IEEE80211_TX_STAT_ACK : 0; |
3315 | iwl4965_hwrate_to_tx_control(priv, | 3134 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); |
3316 | le32_to_cpu(tx_resp->rate_n_flags), | ||
3317 | info); | ||
3318 | /* FIXME: code repetition end */ | 3135 | /* FIXME: code repetition end */ |
3319 | 3136 | ||
3320 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | 3137 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", |
3321 | status & 0xff, tx_resp->failure_frame); | 3138 | status & 0xff, tx_resp->failure_frame); |
3322 | IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", | 3139 | IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); |
3323 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); | ||
3324 | 3140 | ||
3325 | agg->wait_for_ba = 0; | 3141 | agg->wait_for_ba = 0; |
3326 | } else { | 3142 | } else { |
@@ -3378,7 +3194,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
3378 | 3194 | ||
3379 | agg->bitmap = bitmap; | 3195 | agg->bitmap = bitmap; |
3380 | agg->start_idx = start; | 3196 | agg->start_idx = start; |
3381 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | ||
3382 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", | 3197 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", |
3383 | agg->frame_count, agg->start_idx, | 3198 | agg->frame_count, agg->start_idx, |
3384 | (unsigned long long)agg->bitmap); | 3199 | (unsigned long long)agg->bitmap); |
@@ -3388,7 +3203,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
3388 | } | 3203 | } |
3389 | return 0; | 3204 | return 0; |
3390 | } | 3205 | } |
3391 | #endif | ||
3392 | 3206 | ||
3393 | /** | 3207 | /** |
3394 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response | 3208 | * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response |
@@ -3403,13 +3217,11 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3403 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 3217 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
3404 | struct ieee80211_tx_info *info; | 3218 | struct ieee80211_tx_info *info; |
3405 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 3219 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
3406 | u32 status = le32_to_cpu(tx_resp->status); | 3220 | u32 status = le32_to_cpu(tx_resp->u.status); |
3407 | #ifdef CONFIG_IWL4965_HT | ||
3408 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; | 3221 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; |
3409 | u16 fc; | 3222 | __le16 fc; |
3410 | struct ieee80211_hdr *hdr; | 3223 | struct ieee80211_hdr *hdr; |
3411 | u8 *qc = NULL; | 3224 | u8 *qc = NULL; |
3412 | #endif | ||
3413 | 3225 | ||
3414 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 3226 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
3415 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 3227 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -3422,11 +3234,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3422 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); | 3234 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
3423 | memset(&info->status, 0, sizeof(info->status)); | 3235 | memset(&info->status, 0, sizeof(info->status)); |
3424 | 3236 | ||
3425 | #ifdef CONFIG_IWL4965_HT | ||
3426 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); | 3237 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); |
3427 | fc = le16_to_cpu(hdr->frame_control); | 3238 | fc = hdr->frame_control; |
3428 | if (ieee80211_is_qos_data(fc)) { | 3239 | if (ieee80211_is_data_qos(fc)) { |
3429 | qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); | 3240 | qc = ieee80211_get_qos_ctl(hdr); |
3430 | tid = qc[0] & 0xf; | 3241 | tid = qc[0] & 0xf; |
3431 | } | 3242 | } |
3432 | 3243 | ||
@@ -3445,8 +3256,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3445 | 3256 | ||
3446 | agg = &priv->stations[sta_id].tid[tid].agg; | 3257 | agg = &priv->stations[sta_id].tid[tid].agg; |
3447 | 3258 | ||
3448 | iwl4965_tx_status_reply_tx(priv, agg, | 3259 | iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); |
3449 | (struct iwl4965_tx_resp_agg *)tx_resp, index); | ||
3450 | 3260 | ||
3451 | if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { | 3261 | if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { |
3452 | /* TODO: send BAR */ | 3262 | /* TODO: send BAR */ |
@@ -3464,7 +3274,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3464 | txq_id >= 0 && priv->mac80211_registered && | 3274 | txq_id >= 0 && priv->mac80211_registered && |
3465 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { | 3275 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { |
3466 | /* calculate mac80211 ampdu sw queue to wake */ | 3276 | /* calculate mac80211 ampdu sw queue to wake */ |
3467 | ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + | 3277 | ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE + |
3468 | priv->hw->queues; | 3278 | priv->hw->queues; |
3469 | if (agg->state == IWL_AGG_OFF) | 3279 | if (agg->state == IWL_AGG_OFF) |
3470 | ieee80211_wake_queue(priv->hw, txq_id); | 3280 | ieee80211_wake_queue(priv->hw, txq_id); |
@@ -3474,32 +3284,32 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3474 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 3284 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
3475 | } | 3285 | } |
3476 | } else { | 3286 | } else { |
3477 | #endif /* CONFIG_IWL4965_HT */ | 3287 | info->status.retry_count = tx_resp->failure_frame; |
3478 | 3288 | info->flags |= | |
3479 | info->status.retry_count = tx_resp->failure_frame; | 3289 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; |
3480 | info->flags |= iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 3290 | iwl_hwrate_to_tx_control(priv, |
3481 | iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 3291 | le32_to_cpu(tx_resp->rate_n_flags), |
3482 | info); | 3292 | info); |
3483 | 3293 | ||
3484 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 3294 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " |
3485 | "retries %d\n", txq_id, iwl_get_tx_fail_reason(status), | 3295 | "0x%x retries %d\n", txq_id, |
3486 | status, le32_to_cpu(tx_resp->rate_n_flags), | 3296 | iwl_get_tx_fail_reason(status), |
3487 | tx_resp->failure_frame); | 3297 | status, le32_to_cpu(tx_resp->rate_n_flags), |
3488 | 3298 | tx_resp->failure_frame); | |
3489 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 3299 | |
3490 | #ifdef CONFIG_IWL4965_HT | 3300 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
3491 | if (index != -1) { | 3301 | |
3492 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 3302 | if (index != -1) { |
3493 | if (tid != MAX_TID_COUNT) | 3303 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
3304 | if (tid != MAX_TID_COUNT) | ||
3494 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 3305 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
3495 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 3306 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && |
3496 | (txq_id >= 0) && priv->mac80211_registered) | 3307 | (txq_id >= 0) && priv->mac80211_registered) |
3497 | ieee80211_wake_queue(priv->hw, txq_id); | 3308 | ieee80211_wake_queue(priv->hw, txq_id); |
3498 | if (tid != MAX_TID_COUNT) | 3309 | if (tid != MAX_TID_COUNT) |
3499 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 3310 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
3311 | } | ||
3500 | } | 3312 | } |
3501 | } | ||
3502 | #endif /* CONFIG_IWL4965_HT */ | ||
3503 | 3313 | ||
3504 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 3314 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
3505 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 3315 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); |
@@ -3513,28 +3323,18 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) | |||
3513 | priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; | 3323 | priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; |
3514 | /* Tx response */ | 3324 | /* Tx response */ |
3515 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; | 3325 | priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; |
3516 | 3326 | /* block ack */ | |
3517 | #ifdef CONFIG_IWL4965_HT | ||
3518 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; | 3327 | priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; |
3519 | #endif /* CONFIG_IWL4965_HT */ | ||
3520 | } | 3328 | } |
3521 | 3329 | ||
3522 | void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv) | 3330 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) |
3523 | { | 3331 | { |
3524 | INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); | 3332 | INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); |
3525 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | ||
3526 | INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); | ||
3527 | #endif | ||
3528 | init_timer(&priv->statistics_periodic); | ||
3529 | priv->statistics_periodic.data = (unsigned long)priv; | ||
3530 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | ||
3531 | } | 3333 | } |
3532 | 3334 | ||
3533 | void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv) | 3335 | static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) |
3534 | { | 3336 | { |
3535 | del_timer_sync(&priv->statistics_periodic); | 3337 | cancel_work_sync(&priv->txpower_work); |
3536 | |||
3537 | cancel_delayed_work(&priv->init_alive_start); | ||
3538 | } | 3338 | } |
3539 | 3339 | ||
3540 | 3340 | ||
@@ -3545,10 +3345,8 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { | |||
3545 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { | 3345 | static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { |
3546 | .get_hcmd_size = iwl4965_get_hcmd_size, | 3346 | .get_hcmd_size = iwl4965_get_hcmd_size, |
3547 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, | 3347 | .build_addsta_hcmd = iwl4965_build_addsta_hcmd, |
3548 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | ||
3549 | .chain_noise_reset = iwl4965_chain_noise_reset, | 3348 | .chain_noise_reset = iwl4965_chain_noise_reset, |
3550 | .gain_computation = iwl4965_gain_computation, | 3349 | .gain_computation = iwl4965_gain_computation, |
3551 | #endif | ||
3552 | }; | 3350 | }; |
3553 | 3351 | ||
3554 | static struct iwl_lib_ops iwl4965_lib = { | 3352 | static struct iwl_lib_ops iwl4965_lib = { |
@@ -3558,11 +3356,11 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
3558 | .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, | 3356 | .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, |
3559 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, | 3357 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, |
3560 | .txq_set_sched = iwl4965_txq_set_sched, | 3358 | .txq_set_sched = iwl4965_txq_set_sched, |
3561 | #ifdef CONFIG_IWL4965_HT | ||
3562 | .txq_agg_enable = iwl4965_txq_agg_enable, | 3359 | .txq_agg_enable = iwl4965_txq_agg_enable, |
3563 | .txq_agg_disable = iwl4965_txq_agg_disable, | 3360 | .txq_agg_disable = iwl4965_txq_agg_disable, |
3564 | #endif | ||
3565 | .rx_handler_setup = iwl4965_rx_handler_setup, | 3361 | .rx_handler_setup = iwl4965_rx_handler_setup, |
3362 | .setup_deferred_work = iwl4965_setup_deferred_work, | ||
3363 | .cancel_deferred_work = iwl4965_cancel_deferred_work, | ||
3566 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | 3364 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, |
3567 | .alive_notify = iwl4965_alive_notify, | 3365 | .alive_notify = iwl4965_alive_notify, |
3568 | .init_alive_start = iwl4965_init_alive_start, | 3366 | .init_alive_start = iwl4965_init_alive_start, |
@@ -3590,8 +3388,8 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
3590 | .check_version = iwl4965_eeprom_check_version, | 3388 | .check_version = iwl4965_eeprom_check_version, |
3591 | .query_addr = iwlcore_eeprom_query_addr, | 3389 | .query_addr = iwlcore_eeprom_query_addr, |
3592 | }, | 3390 | }, |
3593 | .radio_kill_sw = iwl4965_radio_kill_sw, | ||
3594 | .set_power = iwl4965_set_power, | 3391 | .set_power = iwl4965_set_power, |
3392 | .send_tx_power = iwl4965_send_tx_power, | ||
3595 | .update_chain_flags = iwl4965_update_chain_flags, | 3393 | .update_chain_flags = iwl4965_update_chain_flags, |
3596 | }; | 3394 | }; |
3597 | 3395 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 9e557ce315b7..4efe0c06b5b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -81,7 +81,7 @@ | |||
81 | #define IWL50_QUEUE_SIZE 256 | 81 | #define IWL50_QUEUE_SIZE 256 |
82 | #define IWL50_CMD_FIFO_NUM 7 | 82 | #define IWL50_CMD_FIFO_NUM 7 |
83 | #define IWL50_NUM_QUEUES 20 | 83 | #define IWL50_NUM_QUEUES 20 |
84 | #define IWL50_BACK_QUEUE_FIRST_ID 10 | 84 | #define IWL50_FIRST_AMPDU_QUEUE 10 |
85 | 85 | ||
86 | #define IWL_sta_id_POS 12 | 86 | #define IWL_sta_id_POS 12 |
87 | #define IWL_sta_id_LEN 4 | 87 | #define IWL_sta_id_LEN 4 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 7e525ad45135..438c3812c390 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "iwl-dev.h" | 41 | #include "iwl-dev.h" |
42 | #include "iwl-core.h" | 42 | #include "iwl-core.h" |
43 | #include "iwl-io.h" | 43 | #include "iwl-io.h" |
44 | #include "iwl-sta.h" | ||
44 | #include "iwl-helpers.h" | 45 | #include "iwl-helpers.h" |
45 | #include "iwl-5000-hw.h" | 46 | #include "iwl-5000-hw.h" |
46 | 47 | ||
@@ -300,8 +301,6 @@ err: | |||
300 | 301 | ||
301 | } | 302 | } |
302 | 303 | ||
303 | #ifdef CONFIG_IWL5000_RUN_TIME_CALIB | ||
304 | |||
305 | static void iwl5000_gain_computation(struct iwl_priv *priv, | 304 | static void iwl5000_gain_computation(struct iwl_priv *priv, |
306 | u32 average_noise[NUM_RX_CHAINS], | 305 | u32 average_noise[NUM_RX_CHAINS], |
307 | u16 min_average_noise_antenna_i, | 306 | u16 min_average_noise_antenna_i, |
@@ -354,7 +353,6 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, | |||
354 | data->beacon_count = 0; | 353 | data->beacon_count = 0; |
355 | } | 354 | } |
356 | 355 | ||
357 | |||
358 | static void iwl5000_chain_noise_reset(struct iwl_priv *priv) | 356 | static void iwl5000_chain_noise_reset(struct iwl_priv *priv) |
359 | { | 357 | { |
360 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; | 358 | struct iwl_chain_noise_data *data = &priv->chain_noise_data; |
@@ -393,10 +391,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { | |||
393 | .nrg_th_ofdm = 95, | 391 | .nrg_th_ofdm = 95, |
394 | }; | 392 | }; |
395 | 393 | ||
396 | #endif /* CONFIG_IWL5000_RUN_TIME_CALIB */ | ||
397 | |||
398 | |||
399 | |||
400 | static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 394 | static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, |
401 | size_t offset) | 395 | size_t offset) |
402 | { | 396 | { |
@@ -832,6 +826,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
832 | } | 826 | } |
833 | 827 | ||
834 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 828 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
829 | priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE; | ||
835 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; | 830 | priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; |
836 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 831 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
837 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | 832 | priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; |
@@ -847,9 +842,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
847 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; | 842 | priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; |
848 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | | 843 | priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | |
849 | BIT(IEEE80211_BAND_5GHZ); | 844 | BIT(IEEE80211_BAND_5GHZ); |
850 | #ifdef CONFIG_IWL5000_RUN_TIME_CALIB | ||
851 | priv->hw_params.sens = &iwl5000_sensitivity; | 845 | priv->hw_params.sens = &iwl5000_sensitivity; |
852 | #endif | ||
853 | 846 | ||
854 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { | 847 | switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { |
855 | case CSR_HW_REV_TYPE_5100: | 848 | case CSR_HW_REV_TYPE_5100: |
@@ -984,6 +977,135 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | |||
984 | } | 977 | } |
985 | } | 978 | } |
986 | 979 | ||
980 | static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, | ||
981 | u16 txq_id) | ||
982 | { | ||
983 | u32 tbl_dw_addr; | ||
984 | u32 tbl_dw; | ||
985 | u16 scd_q2ratid; | ||
986 | |||
987 | scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; | ||
988 | |||
989 | tbl_dw_addr = priv->scd_base_addr + | ||
990 | IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); | ||
991 | |||
992 | tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); | ||
993 | |||
994 | if (txq_id & 0x1) | ||
995 | tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); | ||
996 | else | ||
997 | tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); | ||
998 | |||
999 | iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw); | ||
1000 | |||
1001 | return 0; | ||
1002 | } | ||
1003 | static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id) | ||
1004 | { | ||
1005 | /* Simply stop the queue, but don't change any configuration; | ||
1006 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | ||
1007 | iwl_write_prph(priv, | ||
1008 | IWL50_SCD_QUEUE_STATUS_BITS(txq_id), | ||
1009 | (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)| | ||
1010 | (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); | ||
1011 | } | ||
1012 | |||
1013 | static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | ||
1014 | int tx_fifo, int sta_id, int tid, u16 ssn_idx) | ||
1015 | { | ||
1016 | unsigned long flags; | ||
1017 | int ret; | ||
1018 | u16 ra_tid; | ||
1019 | |||
1020 | if (IWL50_FIRST_AMPDU_QUEUE > txq_id) | ||
1021 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
1022 | txq_id, IWL50_FIRST_AMPDU_QUEUE); | ||
1023 | |||
1024 | ra_tid = BUILD_RAxTID(sta_id, tid); | ||
1025 | |||
1026 | /* Modify device's station table to Tx this TID */ | ||
1027 | iwl_sta_modify_enable_tid_tx(priv, sta_id, tid); | ||
1028 | |||
1029 | spin_lock_irqsave(&priv->lock, flags); | ||
1030 | ret = iwl_grab_nic_access(priv); | ||
1031 | if (ret) { | ||
1032 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1033 | return ret; | ||
1034 | } | ||
1035 | |||
1036 | /* Stop this Tx queue before configuring it */ | ||
1037 | iwl5000_tx_queue_stop_scheduler(priv, txq_id); | ||
1038 | |||
1039 | /* Map receiver-address / traffic-ID to this queue */ | ||
1040 | iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id); | ||
1041 | |||
1042 | /* Set this queue as a chain-building queue */ | ||
1043 | iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id)); | ||
1044 | |||
1045 | /* enable aggregations for the queue */ | ||
1046 | iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id)); | ||
1047 | |||
1048 | /* Place first TFD at index corresponding to start sequence number. | ||
1049 | * Assumes that ssn_idx is valid (!= 0xFFF) */ | ||
1050 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
1051 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
1052 | iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
1053 | |||
1054 | /* Set up Tx window size and frame limit for this queue */ | ||
1055 | iwl_write_targ_mem(priv, priv->scd_base_addr + | ||
1056 | IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + | ||
1057 | sizeof(u32), | ||
1058 | ((SCD_WIN_SIZE << | ||
1059 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & | ||
1060 | IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | | ||
1061 | ((SCD_FRAME_LIMIT << | ||
1062 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & | ||
1063 | IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); | ||
1064 | |||
1065 | iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
1066 | |||
1067 | /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ | ||
1068 | iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); | ||
1069 | |||
1070 | iwl_release_nic_access(priv); | ||
1071 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1072 | |||
1073 | return 0; | ||
1074 | } | ||
1075 | |||
1076 | static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | ||
1077 | u16 ssn_idx, u8 tx_fifo) | ||
1078 | { | ||
1079 | int ret; | ||
1080 | |||
1081 | if (IWL50_FIRST_AMPDU_QUEUE > txq_id) { | ||
1082 | IWL_WARNING("queue number too small: %d, must be > %d\n", | ||
1083 | txq_id, IWL50_FIRST_AMPDU_QUEUE); | ||
1084 | return -EINVAL; | ||
1085 | } | ||
1086 | |||
1087 | ret = iwl_grab_nic_access(priv); | ||
1088 | if (ret) | ||
1089 | return ret; | ||
1090 | |||
1091 | iwl5000_tx_queue_stop_scheduler(priv, txq_id); | ||
1092 | |||
1093 | iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id)); | ||
1094 | |||
1095 | priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); | ||
1096 | priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); | ||
1097 | /* supposes that ssn_idx is valid (!= 0xFFF) */ | ||
1098 | iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx); | ||
1099 | |||
1100 | iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id)); | ||
1101 | iwl_txq_ctx_deactivate(priv, txq_id); | ||
1102 | iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); | ||
1103 | |||
1104 | iwl_release_nic_access(priv); | ||
1105 | |||
1106 | return 0; | ||
1107 | } | ||
1108 | |||
987 | static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | 1109 | static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) |
988 | { | 1110 | { |
989 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); | 1111 | u16 size = (u16)sizeof(struct iwl_addsta_cmd); |
@@ -1004,23 +1126,21 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) | |||
1004 | 1126 | ||
1005 | static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) | 1127 | static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) |
1006 | { | 1128 | { |
1007 | __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + | 1129 | return le32_to_cpup((__le32*)&tx_resp->status + |
1008 | tx_resp->frame_count); | 1130 | tx_resp->frame_count) & MAX_SN; |
1009 | return le32_to_cpu(*scd_ssn) & MAX_SN; | ||
1010 | |||
1011 | } | 1131 | } |
1012 | 1132 | ||
1013 | static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | 1133 | static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, |
1014 | struct iwl_ht_agg *agg, | 1134 | struct iwl_ht_agg *agg, |
1015 | struct iwl5000_tx_resp *tx_resp, | 1135 | struct iwl5000_tx_resp *tx_resp, |
1016 | u16 start_idx) | 1136 | int txq_id, u16 start_idx) |
1017 | { | 1137 | { |
1018 | u16 status; | 1138 | u16 status; |
1019 | struct agg_tx_status *frame_status = &tx_resp->status; | 1139 | struct agg_tx_status *frame_status = &tx_resp->status; |
1020 | struct ieee80211_tx_info *info = NULL; | 1140 | struct ieee80211_tx_info *info = NULL; |
1021 | struct ieee80211_hdr *hdr = NULL; | 1141 | struct ieee80211_hdr *hdr = NULL; |
1022 | int i, sh; | 1142 | u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); |
1023 | int txq_id, idx; | 1143 | int i, sh, idx; |
1024 | u16 seq; | 1144 | u16 seq; |
1025 | 1145 | ||
1026 | if (agg->wait_for_ba) | 1146 | if (agg->wait_for_ba) |
@@ -1028,16 +1148,14 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1028 | 1148 | ||
1029 | agg->frame_count = tx_resp->frame_count; | 1149 | agg->frame_count = tx_resp->frame_count; |
1030 | agg->start_idx = start_idx; | 1150 | agg->start_idx = start_idx; |
1031 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | 1151 | agg->rate_n_flags = rate_n_flags; |
1032 | agg->bitmap = 0; | 1152 | agg->bitmap = 0; |
1033 | 1153 | ||
1034 | /* # frames attempted by Tx command */ | 1154 | /* # frames attempted by Tx command */ |
1035 | if (agg->frame_count == 1) { | 1155 | if (agg->frame_count == 1) { |
1036 | /* Only one frame was attempted; no block-ack will arrive */ | 1156 | /* Only one frame was attempted; no block-ack will arrive */ |
1037 | status = le16_to_cpu(frame_status[0].status); | 1157 | status = le16_to_cpu(frame_status[0].status); |
1038 | seq = le16_to_cpu(frame_status[0].sequence); | 1158 | idx = start_idx; |
1039 | idx = SEQ_TO_INDEX(seq); | ||
1040 | txq_id = SEQ_TO_QUEUE(seq); | ||
1041 | 1159 | ||
1042 | /* FIXME: code repetition */ | 1160 | /* FIXME: code repetition */ |
1043 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", | 1161 | IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", |
@@ -1048,15 +1166,13 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1048 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 1166 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
1049 | info->flags |= iwl_is_tx_success(status)? | 1167 | info->flags |= iwl_is_tx_success(status)? |
1050 | IEEE80211_TX_STAT_ACK : 0; | 1168 | IEEE80211_TX_STAT_ACK : 0; |
1051 | iwl4965_hwrate_to_tx_control(priv, | 1169 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); |
1052 | le32_to_cpu(tx_resp->rate_n_flags), | 1170 | |
1053 | info); | ||
1054 | /* FIXME: code repetition end */ | 1171 | /* FIXME: code repetition end */ |
1055 | 1172 | ||
1056 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | 1173 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", |
1057 | status & 0xff, tx_resp->failure_frame); | 1174 | status & 0xff, tx_resp->failure_frame); |
1058 | IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", | 1175 | IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); |
1059 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); | ||
1060 | 1176 | ||
1061 | agg->wait_for_ba = 0; | 1177 | agg->wait_for_ba = 0; |
1062 | } else { | 1178 | } else { |
@@ -1114,7 +1230,6 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1114 | 1230 | ||
1115 | agg->bitmap = bitmap; | 1231 | agg->bitmap = bitmap; |
1116 | agg->start_idx = start; | 1232 | agg->start_idx = start; |
1117 | agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); | ||
1118 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", | 1233 | IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", |
1119 | agg->frame_count, agg->start_idx, | 1234 | agg->frame_count, agg->start_idx, |
1120 | (unsigned long long)agg->bitmap); | 1235 | (unsigned long long)agg->bitmap); |
@@ -1136,12 +1251,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1136 | struct ieee80211_tx_info *info; | 1251 | struct ieee80211_tx_info *info; |
1137 | struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 1252 | struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
1138 | u32 status = le16_to_cpu(tx_resp->status.status); | 1253 | u32 status = le16_to_cpu(tx_resp->status.status); |
1139 | #ifdef CONFIG_IWL4965_HT | ||
1140 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; | 1254 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; |
1141 | u16 fc; | ||
1142 | struct ieee80211_hdr *hdr; | 1255 | struct ieee80211_hdr *hdr; |
1143 | u8 *qc = NULL; | 1256 | u8 *qc = NULL; |
1144 | #endif | ||
1145 | 1257 | ||
1146 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 1258 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
1147 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 1259 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -1154,11 +1266,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1154 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); | 1266 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
1155 | memset(&info->status, 0, sizeof(info->status)); | 1267 | memset(&info->status, 0, sizeof(info->status)); |
1156 | 1268 | ||
1157 | #ifdef CONFIG_IWL4965_HT | ||
1158 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); | 1269 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); |
1159 | fc = le16_to_cpu(hdr->frame_control); | 1270 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
1160 | if (ieee80211_is_qos_data(fc)) { | 1271 | qc = ieee80211_get_qos_ctl(hdr); |
1161 | qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); | ||
1162 | tid = qc[0] & 0xf; | 1272 | tid = qc[0] & 0xf; |
1163 | } | 1273 | } |
1164 | 1274 | ||
@@ -1177,7 +1287,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1177 | 1287 | ||
1178 | agg = &priv->stations[sta_id].tid[tid].agg; | 1288 | agg = &priv->stations[sta_id].tid[tid].agg; |
1179 | 1289 | ||
1180 | iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index); | 1290 | iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); |
1181 | 1291 | ||
1182 | if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { | 1292 | if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { |
1183 | /* TODO: send BAR */ | 1293 | /* TODO: send BAR */ |
@@ -1195,7 +1305,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1195 | txq_id >= 0 && priv->mac80211_registered && | 1305 | txq_id >= 0 && priv->mac80211_registered && |
1196 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { | 1306 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { |
1197 | /* calculate mac80211 ampdu sw queue to wake */ | 1307 | /* calculate mac80211 ampdu sw queue to wake */ |
1198 | ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + | 1308 | ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE + |
1199 | priv->hw->queues; | 1309 | priv->hw->queues; |
1200 | if (agg->state == IWL_AGG_OFF) | 1310 | if (agg->state == IWL_AGG_OFF) |
1201 | ieee80211_wake_queue(priv->hw, txq_id); | 1311 | ieee80211_wake_queue(priv->hw, txq_id); |
@@ -1205,32 +1315,31 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1205 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 1315 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1206 | } | 1316 | } |
1207 | } else { | 1317 | } else { |
1208 | #endif /* CONFIG_IWL4965_HT */ | 1318 | info->status.retry_count = tx_resp->failure_frame; |
1209 | 1319 | info->flags = | |
1210 | info->status.retry_count = tx_resp->failure_frame; | 1320 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; |
1211 | info->flags = iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 1321 | iwl_hwrate_to_tx_control(priv, |
1212 | iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 1322 | le32_to_cpu(tx_resp->rate_n_flags), |
1213 | info); | 1323 | info); |
1214 | 1324 | ||
1215 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 1325 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " |
1216 | "retries %d\n", txq_id, iwl_get_tx_fail_reason(status), | 1326 | "0x%x retries %d\n", txq_id, |
1217 | status, le32_to_cpu(tx_resp->rate_n_flags), | 1327 | iwl_get_tx_fail_reason(status), |
1218 | tx_resp->failure_frame); | 1328 | status, le32_to_cpu(tx_resp->rate_n_flags), |
1219 | 1329 | tx_resp->failure_frame); | |
1220 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 1330 | |
1221 | #ifdef CONFIG_IWL4965_HT | 1331 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
1222 | if (index != -1) { | 1332 | if (index != -1) { |
1223 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1333 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1224 | if (tid != MAX_TID_COUNT) | 1334 | if (tid != MAX_TID_COUNT) |
1225 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1335 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
1226 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1336 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && |
1227 | (txq_id >= 0) && priv->mac80211_registered) | 1337 | (txq_id >= 0) && priv->mac80211_registered) |
1228 | ieee80211_wake_queue(priv->hw, txq_id); | 1338 | ieee80211_wake_queue(priv->hw, txq_id); |
1229 | if (tid != MAX_TID_COUNT) | 1339 | if (tid != MAX_TID_COUNT) |
1230 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | 1340 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); |
1341 | } | ||
1231 | } | 1342 | } |
1232 | } | ||
1233 | #endif /* CONFIG_IWL4965_HT */ | ||
1234 | 1343 | ||
1235 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 1344 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1236 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 1345 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); |
@@ -1242,6 +1351,12 @@ static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len) | |||
1242 | return len; | 1351 | return len; |
1243 | } | 1352 | } |
1244 | 1353 | ||
1354 | static void iwl5000_setup_deferred_work(struct iwl_priv *priv) | ||
1355 | { | ||
1356 | /* in 5000 the tx power calibration is done in uCode */ | ||
1357 | priv->disable_tx_power_cal = 1; | ||
1358 | } | ||
1359 | |||
1245 | static void iwl5000_rx_handler_setup(struct iwl_priv *priv) | 1360 | static void iwl5000_rx_handler_setup(struct iwl_priv *priv) |
1246 | { | 1361 | { |
1247 | /* init calibration handlers */ | 1362 | /* init calibration handlers */ |
@@ -1305,6 +1420,19 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv) | |||
1305 | 1420 | ||
1306 | return ret; | 1421 | return ret; |
1307 | } | 1422 | } |
1423 | static int iwl5000_send_tx_power(struct iwl_priv *priv) | ||
1424 | { | ||
1425 | struct iwl5000_tx_power_dbm_cmd tx_power_cmd; | ||
1426 | |||
1427 | /* half dBm need to multiply */ | ||
1428 | tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); | ||
1429 | tx_power_cmd.flags = 0; | ||
1430 | tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; | ||
1431 | return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD, | ||
1432 | sizeof(tx_power_cmd), &tx_power_cmd, | ||
1433 | NULL); | ||
1434 | } | ||
1435 | |||
1308 | 1436 | ||
1309 | static struct iwl_hcmd_ops iwl5000_hcmd = { | 1437 | static struct iwl_hcmd_ops iwl5000_hcmd = { |
1310 | .rxon_assoc = iwl5000_send_rxon_assoc, | 1438 | .rxon_assoc = iwl5000_send_rxon_assoc, |
@@ -1313,10 +1441,8 @@ static struct iwl_hcmd_ops iwl5000_hcmd = { | |||
1313 | static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { | 1441 | static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { |
1314 | .get_hcmd_size = iwl5000_get_hcmd_size, | 1442 | .get_hcmd_size = iwl5000_get_hcmd_size, |
1315 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, | 1443 | .build_addsta_hcmd = iwl5000_build_addsta_hcmd, |
1316 | #ifdef CONFIG_IWL5000_RUN_TIME_CALIB | ||
1317 | .gain_computation = iwl5000_gain_computation, | 1444 | .gain_computation = iwl5000_gain_computation, |
1318 | .chain_noise_reset = iwl5000_chain_noise_reset, | 1445 | .chain_noise_reset = iwl5000_chain_noise_reset, |
1319 | #endif | ||
1320 | }; | 1446 | }; |
1321 | 1447 | ||
1322 | static struct iwl_lib_ops iwl5000_lib = { | 1448 | static struct iwl_lib_ops iwl5000_lib = { |
@@ -1327,11 +1453,15 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
1327 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, | 1453 | .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, |
1328 | .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, | 1454 | .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, |
1329 | .txq_set_sched = iwl5000_txq_set_sched, | 1455 | .txq_set_sched = iwl5000_txq_set_sched, |
1456 | .txq_agg_enable = iwl5000_txq_agg_enable, | ||
1457 | .txq_agg_disable = iwl5000_txq_agg_disable, | ||
1330 | .rx_handler_setup = iwl5000_rx_handler_setup, | 1458 | .rx_handler_setup = iwl5000_rx_handler_setup, |
1459 | .setup_deferred_work = iwl5000_setup_deferred_work, | ||
1331 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, | 1460 | .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, |
1332 | .load_ucode = iwl5000_load_ucode, | 1461 | .load_ucode = iwl5000_load_ucode, |
1333 | .init_alive_start = iwl5000_init_alive_start, | 1462 | .init_alive_start = iwl5000_init_alive_start, |
1334 | .alive_notify = iwl5000_alive_notify, | 1463 | .alive_notify = iwl5000_alive_notify, |
1464 | .send_tx_power = iwl5000_send_tx_power, | ||
1335 | .apm_ops = { | 1465 | .apm_ops = { |
1336 | .init = iwl5000_apm_init, | 1466 | .init = iwl5000_apm_init, |
1337 | .reset = iwl5000_apm_reset, | 1467 | .reset = iwl5000_apm_reset, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index a6c7f0d9a414..48f58000b64b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c | |||
@@ -60,13 +60,11 @@ | |||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
61 | *****************************************************************************/ | 61 | *****************************************************************************/ |
62 | 62 | ||
63 | #include <linux/kernel.h> | ||
64 | #include <net/mac80211.h> | 63 | #include <net/mac80211.h> |
65 | 64 | ||
66 | #include "iwl-dev.h" | 65 | #include "iwl-dev.h" |
67 | #include "iwl-core.h" | 66 | #include "iwl-core.h" |
68 | #include "iwl-calib.h" | 67 | #include "iwl-calib.h" |
69 | #include "iwl-eeprom.h" | ||
70 | 68 | ||
71 | /* "false alarms" are signals that our DSP tries to lock onto, | 69 | /* "false alarms" are signals that our DSP tries to lock onto, |
72 | * but then determines that they are either noise, or transmissions | 70 | * but then determines that they are either noise, or transmissions |
@@ -435,8 +433,6 @@ void iwl_init_sensitivity(struct iwl_priv *priv) | |||
435 | data = &(priv->sensitivity_data); | 433 | data = &(priv->sensitivity_data); |
436 | 434 | ||
437 | if (ranges == NULL) | 435 | if (ranges == NULL) |
438 | /* can happen if IWLWIFI_RUN_TIME_CALIB is selected | ||
439 | * but no IWLXXXX_RUN_TIME_CALIB for specific is selected */ | ||
440 | return; | 436 | return; |
441 | 437 | ||
442 | memset(data, 0, sizeof(struct iwl_sensitivity_data)); | 438 | memset(data, 0, sizeof(struct iwl_sensitivity_data)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h index b8e57c59eac8..5524a29e22d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-calib.h | |||
@@ -62,16 +62,10 @@ | |||
62 | #ifndef __iwl_calib_h__ | 62 | #ifndef __iwl_calib_h__ |
63 | #define __iwl_calib_h__ | 63 | #define __iwl_calib_h__ |
64 | 64 | ||
65 | #include <linux/kernel.h> | ||
66 | #include <linux/module.h> | ||
67 | #include <linux/version.h> | ||
68 | |||
69 | #include <net/mac80211.h> | ||
70 | #include "iwl-eeprom.h" | ||
71 | #include "iwl-core.h" | ||
72 | #include "iwl-dev.h" | 65 | #include "iwl-dev.h" |
66 | #include "iwl-core.h" | ||
67 | #include "iwl-commands.h" | ||
73 | 68 | ||
74 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
75 | void iwl_chain_noise_calibration(struct iwl_priv *priv, | 69 | void iwl_chain_noise_calibration(struct iwl_priv *priv, |
76 | struct iwl4965_notif_statistics *stat_resp); | 70 | struct iwl4965_notif_statistics *stat_resp); |
77 | void iwl_sensitivity_calibration(struct iwl_priv *priv, | 71 | void iwl_sensitivity_calibration(struct iwl_priv *priv, |
@@ -86,24 +80,5 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv) | |||
86 | priv->cfg->ops->utils->chain_noise_reset) | 80 | priv->cfg->ops->utils->chain_noise_reset) |
87 | priv->cfg->ops->utils->chain_noise_reset(priv); | 81 | priv->cfg->ops->utils->chain_noise_reset(priv); |
88 | } | 82 | } |
89 | #else | ||
90 | static inline void iwl_chain_noise_calibration(struct iwl_priv *priv, | ||
91 | struct iwl4965_notif_statistics *stat_resp) | ||
92 | { | ||
93 | } | ||
94 | static inline void iwl_sensitivity_calibration(struct iwl_priv *priv, | ||
95 | struct iwl4965_notif_statistics *resp) | ||
96 | { | ||
97 | } | ||
98 | static inline void iwl_init_sensitivity(struct iwl_priv *priv) | ||
99 | { | ||
100 | } | ||
101 | static inline void iwl_chain_noise_reset(struct iwl_priv *priv) | ||
102 | { | ||
103 | } | ||
104 | static inline void iwl_reset_run_time_calib(struct iwl_priv *priv) | ||
105 | { | ||
106 | } | ||
107 | #endif | ||
108 | 83 | ||
109 | #endif /* __iwl_calib_h__ */ | 84 | #endif /* __iwl_calib_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index fb6f5ffb9f1d..920dfc1b2db2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -126,6 +126,7 @@ enum { | |||
126 | /* Miscellaneous commands */ | 126 | /* Miscellaneous commands */ |
127 | QUIET_NOTIFICATION = 0x96, /* not used */ | 127 | QUIET_NOTIFICATION = 0x96, /* not used */ |
128 | REPLY_TX_PWR_TABLE_CMD = 0x97, | 128 | REPLY_TX_PWR_TABLE_CMD = 0x97, |
129 | REPLY_TX_POWER_DBM_CMD = 0x98, | ||
129 | MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ | 130 | MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ |
130 | 131 | ||
131 | /* Bluetooth device coexistance config command */ | 132 | /* Bluetooth device coexistance config command */ |
@@ -280,16 +281,7 @@ struct iwl_cmd_header { | |||
280 | #define RATE_MCS_ANT_C_MSK 0x10000 | 281 | #define RATE_MCS_ANT_C_MSK 0x10000 |
281 | #define RATE_MCS_ANT_ABC_MSK 0x1C000 | 282 | #define RATE_MCS_ANT_ABC_MSK 0x1C000 |
282 | 283 | ||
283 | 284 | #define RATE_MCS_ANT_INIT_IND 1 | |
284 | /** | ||
285 | * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD | ||
286 | * | ||
287 | * Scan uses only one transmitter, so only one analog/dsp gain pair is needed. | ||
288 | */ | ||
289 | struct iwl4965_tx_power { | ||
290 | u8 tx_gain; /* gain for analog radio */ | ||
291 | u8 dsp_atten; /* gain for DSP */ | ||
292 | } __attribute__ ((packed)); | ||
293 | 285 | ||
294 | #define POWER_TABLE_NUM_ENTRIES 33 | 286 | #define POWER_TABLE_NUM_ENTRIES 33 |
295 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 | 287 | #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 |
@@ -339,6 +331,17 @@ struct iwl4965_tx_power_db { | |||
339 | struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; | 331 | struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; |
340 | } __attribute__ ((packed)); | 332 | } __attribute__ ((packed)); |
341 | 333 | ||
334 | /** | ||
335 | * Commad REPLY_TX_POWER_DBM_CMD = 0x98 | ||
336 | * struct iwl5000_tx_power_dbm_cmd | ||
337 | */ | ||
338 | #define IWL50_TX_POWER_AUTO 0x7f | ||
339 | struct iwl5000_tx_power_dbm_cmd { | ||
340 | s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ | ||
341 | u8 flags; | ||
342 | s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ | ||
343 | u8 reserved; | ||
344 | } __attribute__ ((packed)); | ||
342 | 345 | ||
343 | /****************************************************************************** | 346 | /****************************************************************************** |
344 | * (0a) | 347 | * (0a) |
@@ -990,6 +993,7 @@ struct iwl_wep_cmd { | |||
990 | #define WEP_KEY_WEP_TYPE 1 | 993 | #define WEP_KEY_WEP_TYPE 1 |
991 | #define WEP_KEYS_MAX 4 | 994 | #define WEP_KEYS_MAX 4 |
992 | #define WEP_INVALID_OFFSET 0xff | 995 | #define WEP_INVALID_OFFSET 0xff |
996 | #define WEP_KEY_LEN_64 5 | ||
993 | #define WEP_KEY_LEN_128 13 | 997 | #define WEP_KEY_LEN_128 13 |
994 | 998 | ||
995 | /****************************************************************************** | 999 | /****************************************************************************** |
@@ -1481,21 +1485,10 @@ struct iwl4965_tx_resp { | |||
1481 | * table entry used for all frames in the new agg. | 1485 | * table entry used for all frames in the new agg. |
1482 | * 31-16: Sequence # for this frame's Tx cmd (not SSN!) | 1486 | * 31-16: Sequence # for this frame's Tx cmd (not SSN!) |
1483 | */ | 1487 | */ |
1484 | __le32 status; /* TX status (for aggregation status of 1st frame) */ | 1488 | union { |
1485 | } __attribute__ ((packed)); | 1489 | __le32 status; |
1486 | 1490 | struct agg_tx_status agg_status[0]; /* for each agg frame */ | |
1487 | struct iwl4965_tx_resp_agg { | 1491 | } u; |
1488 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ | ||
1489 | u8 reserved1; | ||
1490 | u8 failure_rts; | ||
1491 | u8 failure_frame; | ||
1492 | __le32 rate_n_flags; | ||
1493 | __le16 wireless_media_time; | ||
1494 | __le16 reserved3; | ||
1495 | __le32 pa_power1; | ||
1496 | __le32 pa_power2; | ||
1497 | struct agg_tx_status status; /* TX status (for aggregation status */ | ||
1498 | /* of 1st frame) */ | ||
1499 | } __attribute__ ((packed)); | 1492 | } __attribute__ ((packed)); |
1500 | 1493 | ||
1501 | struct iwl5000_tx_resp { | 1494 | struct iwl5000_tx_resp { |
@@ -2085,7 +2078,7 @@ struct iwl4965_card_state_notif { | |||
2085 | #define RF_CARD_DISABLED 0x04 | 2078 | #define RF_CARD_DISABLED 0x04 |
2086 | #define RXON_CARD_DISABLED 0x10 | 2079 | #define RXON_CARD_DISABLED 0x10 |
2087 | 2080 | ||
2088 | struct iwl4965_ct_kill_config { | 2081 | struct iwl_ct_kill_config { |
2089 | __le32 reserved; | 2082 | __le32 reserved; |
2090 | __le32 critical_temperature_M; | 2083 | __le32 critical_temperature_M; |
2091 | __le32 critical_temperature_R; | 2084 | __le32 critical_temperature_R; |
@@ -2098,7 +2091,7 @@ struct iwl4965_ct_kill_config { | |||
2098 | *****************************************************************************/ | 2091 | *****************************************************************************/ |
2099 | 2092 | ||
2100 | /** | 2093 | /** |
2101 | * struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table | 2094 | * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table |
2102 | * | 2095 | * |
2103 | * One for each channel in the scan list. | 2096 | * One for each channel in the scan list. |
2104 | * Each channel can independently select: | 2097 | * Each channel can independently select: |
@@ -2108,7 +2101,7 @@ struct iwl4965_ct_kill_config { | |||
2108 | * quiet_plcp_th, good_CRC_th) | 2101 | * quiet_plcp_th, good_CRC_th) |
2109 | * | 2102 | * |
2110 | * To avoid uCode errors, make sure the following are true (see comments | 2103 | * To avoid uCode errors, make sure the following are true (see comments |
2111 | * under struct iwl4965_scan_cmd about max_out_time and quiet_time): | 2104 | * under struct iwl_scan_cmd about max_out_time and quiet_time): |
2112 | * 1) If using passive_dwell (i.e. passive_dwell != 0): | 2105 | * 1) If using passive_dwell (i.e. passive_dwell != 0): |
2113 | * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) | 2106 | * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) |
2114 | * 2) quiet_time <= active_dwell | 2107 | * 2) quiet_time <= active_dwell |
@@ -2116,7 +2109,7 @@ struct iwl4965_ct_kill_config { | |||
2116 | * passive_dwell < max_out_time | 2109 | * passive_dwell < max_out_time |
2117 | * active_dwell < max_out_time | 2110 | * active_dwell < max_out_time |
2118 | */ | 2111 | */ |
2119 | struct iwl4965_scan_channel { | 2112 | struct iwl_scan_channel { |
2120 | /* | 2113 | /* |
2121 | * type is defined as: | 2114 | * type is defined as: |
2122 | * 0:0 1 = active, 0 = passive | 2115 | * 0:0 1 = active, 0 = passive |
@@ -2126,19 +2119,20 @@ struct iwl4965_scan_channel { | |||
2126 | */ | 2119 | */ |
2127 | u8 type; | 2120 | u8 type; |
2128 | u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */ | 2121 | u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */ |
2129 | struct iwl4965_tx_power tpc; | 2122 | u8 tx_gain; /* gain for analog radio */ |
2123 | u8 dsp_atten; /* gain for DSP */ | ||
2130 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ | 2124 | __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ |
2131 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ | 2125 | __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ |
2132 | } __attribute__ ((packed)); | 2126 | } __attribute__ ((packed)); |
2133 | 2127 | ||
2134 | /** | 2128 | /** |
2135 | * struct iwl4965_ssid_ie - directed scan network information element | 2129 | * struct iwl_ssid_ie - directed scan network information element |
2136 | * | 2130 | * |
2137 | * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field | 2131 | * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field |
2138 | * in struct iwl4965_scan_channel; each channel may select different ssids from | 2132 | * in struct iwl4965_scan_channel; each channel may select different ssids from |
2139 | * among the 4 entries. SSID IEs get transmitted in reverse order of entry. | 2133 | * among the 4 entries. SSID IEs get transmitted in reverse order of entry. |
2140 | */ | 2134 | */ |
2141 | struct iwl4965_ssid_ie { | 2135 | struct iwl_ssid_ie { |
2142 | u8 id; | 2136 | u8 id; |
2143 | u8 len; | 2137 | u8 len; |
2144 | u8 ssid[32]; | 2138 | u8 ssid[32]; |
@@ -2199,9 +2193,9 @@ struct iwl4965_ssid_ie { | |||
2199 | * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. | 2193 | * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. |
2200 | * | 2194 | * |
2201 | * To avoid uCode errors, see timing restrictions described under | 2195 | * To avoid uCode errors, see timing restrictions described under |
2202 | * struct iwl4965_scan_channel. | 2196 | * struct iwl_scan_channel. |
2203 | */ | 2197 | */ |
2204 | struct iwl4965_scan_cmd { | 2198 | struct iwl_scan_cmd { |
2205 | __le16 len; | 2199 | __le16 len; |
2206 | u8 reserved0; | 2200 | u8 reserved0; |
2207 | u8 channel_count; /* # channels in channel list */ | 2201 | u8 channel_count; /* # channels in channel list */ |
@@ -2225,7 +2219,7 @@ struct iwl4965_scan_cmd { | |||
2225 | struct iwl_tx_cmd tx_cmd; | 2219 | struct iwl_tx_cmd tx_cmd; |
2226 | 2220 | ||
2227 | /* For directed active scans (set to all-0s otherwise) */ | 2221 | /* For directed active scans (set to all-0s otherwise) */ |
2228 | struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX]; | 2222 | struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; |
2229 | 2223 | ||
2230 | /* | 2224 | /* |
2231 | * Probe request frame, followed by channel list. | 2225 | * Probe request frame, followed by channel list. |
@@ -2253,14 +2247,14 @@ struct iwl4965_scan_cmd { | |||
2253 | /* | 2247 | /* |
2254 | * REPLY_SCAN_CMD = 0x80 (response) | 2248 | * REPLY_SCAN_CMD = 0x80 (response) |
2255 | */ | 2249 | */ |
2256 | struct iwl4965_scanreq_notification { | 2250 | struct iwl_scanreq_notification { |
2257 | __le32 status; /* 1: okay, 2: cannot fulfill request */ | 2251 | __le32 status; /* 1: okay, 2: cannot fulfill request */ |
2258 | } __attribute__ ((packed)); | 2252 | } __attribute__ ((packed)); |
2259 | 2253 | ||
2260 | /* | 2254 | /* |
2261 | * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) | 2255 | * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) |
2262 | */ | 2256 | */ |
2263 | struct iwl4965_scanstart_notification { | 2257 | struct iwl_scanstart_notification { |
2264 | __le32 tsf_low; | 2258 | __le32 tsf_low; |
2265 | __le32 tsf_high; | 2259 | __le32 tsf_high; |
2266 | __le32 beacon_timer; | 2260 | __le32 beacon_timer; |
@@ -2277,7 +2271,7 @@ struct iwl4965_scanstart_notification { | |||
2277 | /* | 2271 | /* |
2278 | * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) | 2272 | * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) |
2279 | */ | 2273 | */ |
2280 | struct iwl4965_scanresults_notification { | 2274 | struct iwl_scanresults_notification { |
2281 | u8 channel; | 2275 | u8 channel; |
2282 | u8 band; | 2276 | u8 band; |
2283 | u8 reserved[2]; | 2277 | u8 reserved[2]; |
@@ -2289,7 +2283,7 @@ struct iwl4965_scanresults_notification { | |||
2289 | /* | 2283 | /* |
2290 | * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) | 2284 | * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) |
2291 | */ | 2285 | */ |
2292 | struct iwl4965_scancomplete_notification { | 2286 | struct iwl_scancomplete_notification { |
2293 | u8 scanned_channels; | 2287 | u8 scanned_channels; |
2294 | u8 status; | 2288 | u8 status; |
2295 | u8 reserved; | 2289 | u8 reserved; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 61716ba90427..eb74a40a62eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -85,6 +85,63 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { | |||
85 | }; | 85 | }; |
86 | EXPORT_SYMBOL(iwl_rates); | 86 | EXPORT_SYMBOL(iwl_rates); |
87 | 87 | ||
88 | /** | ||
89 | * translate ucode response to mac80211 tx status control values | ||
90 | */ | ||
91 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | ||
92 | struct ieee80211_tx_info *control) | ||
93 | { | ||
94 | int rate_index; | ||
95 | |||
96 | control->antenna_sel_tx = | ||
97 | ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); | ||
98 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
99 | control->flags |= IEEE80211_TX_CTL_OFDM_HT; | ||
100 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
101 | control->flags |= IEEE80211_TX_CTL_GREEN_FIELD; | ||
102 | if (rate_n_flags & RATE_MCS_FAT_MSK) | ||
103 | control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH; | ||
104 | if (rate_n_flags & RATE_MCS_DUP_MSK) | ||
105 | control->flags |= IEEE80211_TX_CTL_DUP_DATA; | ||
106 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
107 | control->flags |= IEEE80211_TX_CTL_SHORT_GI; | ||
108 | rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); | ||
109 | if (control->band == IEEE80211_BAND_5GHZ) | ||
110 | rate_index -= IWL_FIRST_OFDM_RATE; | ||
111 | control->tx_rate_idx = rate_index; | ||
112 | } | ||
113 | EXPORT_SYMBOL(iwl_hwrate_to_tx_control); | ||
114 | |||
115 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) | ||
116 | { | ||
117 | int idx = 0; | ||
118 | |||
119 | /* HT rate format */ | ||
120 | if (rate_n_flags & RATE_MCS_HT_MSK) { | ||
121 | idx = (rate_n_flags & 0xff); | ||
122 | |||
123 | if (idx >= IWL_RATE_MIMO2_6M_PLCP) | ||
124 | idx = idx - IWL_RATE_MIMO2_6M_PLCP; | ||
125 | |||
126 | idx += IWL_FIRST_OFDM_RATE; | ||
127 | /* skip 9M not supported in ht*/ | ||
128 | if (idx >= IWL_RATE_9M_INDEX) | ||
129 | idx += 1; | ||
130 | if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) | ||
131 | return idx; | ||
132 | |||
133 | /* legacy rate format, search for match in table */ | ||
134 | } else { | ||
135 | for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) | ||
136 | if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) | ||
137 | return idx; | ||
138 | } | ||
139 | |||
140 | return -1; | ||
141 | } | ||
142 | EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); | ||
143 | |||
144 | |||
88 | 145 | ||
89 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 146 | const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
90 | EXPORT_SYMBOL(iwl_bcast_addr); | 147 | EXPORT_SYMBOL(iwl_bcast_addr); |
@@ -321,7 +378,6 @@ void iwl_reset_qos(struct iwl_priv *priv) | |||
321 | } | 378 | } |
322 | EXPORT_SYMBOL(iwl_reset_qos); | 379 | EXPORT_SYMBOL(iwl_reset_qos); |
323 | 380 | ||
324 | #ifdef CONFIG_IWL4965_HT | ||
325 | #define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */ | 381 | #define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */ |
326 | #define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */ | 382 | #define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */ |
327 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | 383 | static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, |
@@ -374,13 +430,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
374 | ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2); | 430 | ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2); |
375 | } | 431 | } |
376 | } | 432 | } |
377 | #else | ||
378 | static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | ||
379 | struct ieee80211_ht_info *ht_info, | ||
380 | enum ieee80211_band band) | ||
381 | { | ||
382 | } | ||
383 | #endif /* CONFIG_IWL4965_HT */ | ||
384 | 433 | ||
385 | static void iwlcore_init_hw_rates(struct iwl_priv *priv, | 434 | static void iwlcore_init_hw_rates(struct iwl_priv *priv, |
386 | struct ieee80211_rate *rates) | 435 | struct ieee80211_rate *rates) |
@@ -486,28 +535,10 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
486 | if (ch->flags & EEPROM_CHANNEL_RADAR) | 535 | if (ch->flags & EEPROM_CHANNEL_RADAR) |
487 | geo_ch->flags |= IEEE80211_CHAN_RADAR; | 536 | geo_ch->flags |= IEEE80211_CHAN_RADAR; |
488 | 537 | ||
489 | switch (ch->fat_extension_channel) { | 538 | geo_ch->flags |= ch->fat_extension_channel; |
490 | case HT_IE_EXT_CHANNEL_ABOVE: | ||
491 | /* only above is allowed, disable below */ | ||
492 | geo_ch->flags |= IEEE80211_CHAN_NO_FAT_BELOW; | ||
493 | break; | ||
494 | case HT_IE_EXT_CHANNEL_BELOW: | ||
495 | /* only below is allowed, disable above */ | ||
496 | geo_ch->flags |= IEEE80211_CHAN_NO_FAT_ABOVE; | ||
497 | break; | ||
498 | case HT_IE_EXT_CHANNEL_NONE: | ||
499 | /* fat not allowed: disable both*/ | ||
500 | geo_ch->flags |= (IEEE80211_CHAN_NO_FAT_ABOVE | | ||
501 | IEEE80211_CHAN_NO_FAT_BELOW); | ||
502 | break; | ||
503 | case HT_IE_EXT_CHANNEL_MAX: | ||
504 | /* both above and below are permitted */ | ||
505 | break; | ||
506 | } | ||
507 | 539 | ||
508 | if (ch->max_power_avg > priv->max_channel_txpower_limit) | 540 | if (ch->max_power_avg > priv->tx_power_channel_lmt) |
509 | priv->max_channel_txpower_limit = | 541 | priv->tx_power_channel_lmt = ch->max_power_avg; |
510 | ch->max_power_avg; | ||
511 | } else { | 542 | } else { |
512 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; | 543 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; |
513 | } | 544 | } |
@@ -515,7 +546,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv) | |||
515 | /* Save flags for reg domain usage */ | 546 | /* Save flags for reg domain usage */ |
516 | geo_ch->orig_flags = geo_ch->flags; | 547 | geo_ch->orig_flags = geo_ch->flags; |
517 | 548 | ||
518 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", | 549 | IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", |
519 | ch->channel, geo_ch->center_freq, | 550 | ch->channel, geo_ch->center_freq, |
520 | is_channel_a_band(ch) ? "5.2" : "2.4", | 551 | is_channel_a_band(ch) ? "5.2" : "2.4", |
521 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? | 552 | geo_ch->flags & IEEE80211_CHAN_DISABLED ? |
@@ -553,7 +584,6 @@ static void iwlcore_free_geos(struct iwl_priv *priv) | |||
553 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); | 584 | clear_bit(STATUS_GEO_CONFIGURED, &priv->status); |
554 | } | 585 | } |
555 | 586 | ||
556 | #ifdef CONFIG_IWL4965_HT | ||
557 | static u8 is_single_rx_stream(struct iwl_priv *priv) | 587 | static u8 is_single_rx_stream(struct iwl_priv *priv) |
558 | { | 588 | { |
559 | return !priv->current_ht_config.is_ht || | 589 | return !priv->current_ht_config.is_ht || |
@@ -561,6 +591,7 @@ static u8 is_single_rx_stream(struct iwl_priv *priv) | |||
561 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || | 591 | (priv->current_ht_config.supp_mcs_set[2] == 0)) || |
562 | priv->ps_mode == IWL_MIMO_PS_STATIC; | 592 | priv->ps_mode == IWL_MIMO_PS_STATIC; |
563 | } | 593 | } |
594 | |||
564 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, | 595 | static u8 iwl_is_channel_extension(struct iwl_priv *priv, |
565 | enum ieee80211_band band, | 596 | enum ieee80211_band band, |
566 | u16 channel, u8 extension_chan_offset) | 597 | u16 channel, u8 extension_chan_offset) |
@@ -571,12 +602,12 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, | |||
571 | if (!is_channel_valid(ch_info)) | 602 | if (!is_channel_valid(ch_info)) |
572 | return 0; | 603 | return 0; |
573 | 604 | ||
574 | if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) | 605 | if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) |
575 | return 0; | 606 | return !(ch_info->fat_extension_channel & |
576 | 607 | IEEE80211_CHAN_NO_FAT_ABOVE); | |
577 | if ((ch_info->fat_extension_channel == extension_chan_offset) || | 608 | else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) |
578 | (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) | 609 | return !(ch_info->fat_extension_channel & |
579 | return 1; | 610 | IEEE80211_CHAN_NO_FAT_BELOW); |
580 | 611 | ||
581 | return 0; | 612 | return 0; |
582 | } | 613 | } |
@@ -588,7 +619,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | |||
588 | 619 | ||
589 | if ((!iwl_ht_conf->is_ht) || | 620 | if ((!iwl_ht_conf->is_ht) || |
590 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || | 621 | (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || |
591 | (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) | 622 | (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE)) |
592 | return 0; | 623 | return 0; |
593 | 624 | ||
594 | if (sta_ht_inf) { | 625 | if (sta_ht_inf) { |
@@ -622,19 +653,18 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
622 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", | 653 | IWL_DEBUG_ASSOC("control diff than current %d %d\n", |
623 | le16_to_cpu(rxon->channel), | 654 | le16_to_cpu(rxon->channel), |
624 | ht_info->control_channel); | 655 | ht_info->control_channel); |
625 | rxon->channel = cpu_to_le16(ht_info->control_channel); | ||
626 | return; | 656 | return; |
627 | } | 657 | } |
628 | 658 | ||
629 | /* Note: control channel is opposite of extension channel */ | 659 | /* Note: control channel is opposite of extension channel */ |
630 | switch (ht_info->extension_chan_offset) { | 660 | switch (ht_info->extension_chan_offset) { |
631 | case IWL_EXT_CHANNEL_OFFSET_ABOVE: | 661 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: |
632 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); | 662 | rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); |
633 | break; | 663 | break; |
634 | case IWL_EXT_CHANNEL_OFFSET_BELOW: | 664 | case IEEE80211_HT_IE_CHA_SEC_BELOW: |
635 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; | 665 | rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; |
636 | break; | 666 | break; |
637 | case IWL_EXT_CHANNEL_OFFSET_NONE: | 667 | case IEEE80211_HT_IE_CHA_SEC_NONE: |
638 | default: | 668 | default: |
639 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; | 669 | rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; |
640 | break; | 670 | break; |
@@ -660,13 +690,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) | |||
660 | } | 690 | } |
661 | EXPORT_SYMBOL(iwl_set_rxon_ht); | 691 | EXPORT_SYMBOL(iwl_set_rxon_ht); |
662 | 692 | ||
663 | #else | ||
664 | static inline u8 is_single_rx_stream(struct iwl_priv *priv) | ||
665 | { | ||
666 | return 1; | ||
667 | } | ||
668 | #endif /*CONFIG_IWL4965_HT */ | ||
669 | |||
670 | /* | 693 | /* |
671 | * Determine how many receiver/antenna chains to use. | 694 | * Determine how many receiver/antenna chains to use. |
672 | * More provides better reception via diversity. Fewer saves power. | 695 | * More provides better reception via diversity. Fewer saves power. |
@@ -791,10 +814,8 @@ int iwl_setup_mac(struct iwl_priv *priv) | |||
791 | IEEE80211_HW_NOISE_DBM; | 814 | IEEE80211_HW_NOISE_DBM; |
792 | /* Default value; 4 EDCA QOS priorities */ | 815 | /* Default value; 4 EDCA QOS priorities */ |
793 | hw->queues = 4; | 816 | hw->queues = 4; |
794 | #ifdef CONFIG_IWL4965_HT | ||
795 | /* Enhanced value; more queues, to support 11n aggregation */ | 817 | /* Enhanced value; more queues, to support 11n aggregation */ |
796 | hw->ampdu_queues = 12; | 818 | hw->ampdu_queues = 12; |
797 | #endif /* CONFIG_IWL4965_HT */ | ||
798 | 819 | ||
799 | hw->conf.beacon_int = 100; | 820 | hw->conf.beacon_int = 100; |
800 | 821 | ||
@@ -853,6 +874,7 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
853 | 874 | ||
854 | /* Choose which receivers/antennas to use */ | 875 | /* Choose which receivers/antennas to use */ |
855 | iwl_set_rxon_chain(priv); | 876 | iwl_set_rxon_chain(priv); |
877 | iwl_init_scan_params(priv); | ||
856 | 878 | ||
857 | if (priv->cfg->mod_params->enable_qos) | 879 | if (priv->cfg->mod_params->enable_qos) |
858 | priv->qos_data.qos_enable = 1; | 880 | priv->qos_data.qos_enable = 1; |
@@ -867,7 +889,7 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
867 | priv->rates_mask = IWL_RATES_MASK; | 889 | priv->rates_mask = IWL_RATES_MASK; |
868 | /* If power management is turned on, default to AC mode */ | 890 | /* If power management is turned on, default to AC mode */ |
869 | priv->power_mode = IWL_POWER_AC; | 891 | priv->power_mode = IWL_POWER_AC; |
870 | priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; | 892 | priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX; |
871 | 893 | ||
872 | ret = iwl_init_channel_map(priv); | 894 | ret = iwl_init_channel_map(priv); |
873 | if (ret) { | 895 | if (ret) { |
@@ -906,6 +928,34 @@ void iwl_free_calib_results(struct iwl_priv *priv) | |||
906 | } | 928 | } |
907 | EXPORT_SYMBOL(iwl_free_calib_results); | 929 | EXPORT_SYMBOL(iwl_free_calib_results); |
908 | 930 | ||
931 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | ||
932 | { | ||
933 | int ret = 0; | ||
934 | if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { | ||
935 | IWL_WARNING("Requested user TXPOWER %d below limit.\n", | ||
936 | priv->tx_power_user_lmt); | ||
937 | return -EINVAL; | ||
938 | } | ||
939 | |||
940 | if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) { | ||
941 | IWL_WARNING("Requested user TXPOWER %d above limit.\n", | ||
942 | priv->tx_power_user_lmt); | ||
943 | return -EINVAL; | ||
944 | } | ||
945 | |||
946 | if (priv->tx_power_user_lmt != tx_power) | ||
947 | force = true; | ||
948 | |||
949 | priv->tx_power_user_lmt = tx_power; | ||
950 | |||
951 | if (force && priv->cfg->ops->lib->send_tx_power) | ||
952 | ret = priv->cfg->ops->lib->send_tx_power(priv); | ||
953 | |||
954 | return ret; | ||
955 | } | ||
956 | EXPORT_SYMBOL(iwl_set_tx_power); | ||
957 | |||
958 | |||
909 | void iwl_uninit_drv(struct iwl_priv *priv) | 959 | void iwl_uninit_drv(struct iwl_priv *priv) |
910 | { | 960 | { |
911 | iwl_free_calib_results(priv); | 961 | iwl_free_calib_results(priv); |
@@ -915,35 +965,6 @@ void iwl_uninit_drv(struct iwl_priv *priv) | |||
915 | } | 965 | } |
916 | EXPORT_SYMBOL(iwl_uninit_drv); | 966 | EXPORT_SYMBOL(iwl_uninit_drv); |
917 | 967 | ||
918 | /* Low level driver call this function to update iwlcore with | ||
919 | * driver status. | ||
920 | */ | ||
921 | int iwlcore_low_level_notify(struct iwl_priv *priv, | ||
922 | enum iwlcore_card_notify notify) | ||
923 | { | ||
924 | int ret; | ||
925 | switch (notify) { | ||
926 | case IWLCORE_INIT_EVT: | ||
927 | ret = iwl_rfkill_init(priv); | ||
928 | if (ret) | ||
929 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
930 | "Ignoring error: %d\n", ret); | ||
931 | iwl_power_initialize(priv); | ||
932 | break; | ||
933 | case IWLCORE_START_EVT: | ||
934 | iwl_power_update_mode(priv, 1); | ||
935 | break; | ||
936 | case IWLCORE_STOP_EVT: | ||
937 | break; | ||
938 | case IWLCORE_REMOVE_EVT: | ||
939 | iwl_rfkill_unregister(priv); | ||
940 | break; | ||
941 | } | ||
942 | |||
943 | return 0; | ||
944 | } | ||
945 | EXPORT_SYMBOL(iwlcore_low_level_notify); | ||
946 | |||
947 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) | 968 | int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) |
948 | { | 969 | { |
949 | u32 stat_flags = 0; | 970 | u32 stat_flags = 0; |
@@ -1204,12 +1225,14 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
1204 | ptr += sizeof(u32); | 1225 | ptr += sizeof(u32); |
1205 | time = iwl_read_targ_mem(priv, ptr); | 1226 | time = iwl_read_targ_mem(priv, ptr); |
1206 | ptr += sizeof(u32); | 1227 | ptr += sizeof(u32); |
1207 | if (mode == 0) | 1228 | if (mode == 0) { |
1208 | IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ | 1229 | /* data, ev */ |
1209 | else { | 1230 | IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev); |
1231 | } else { | ||
1210 | data = iwl_read_targ_mem(priv, ptr); | 1232 | data = iwl_read_targ_mem(priv, ptr); |
1211 | ptr += sizeof(u32); | 1233 | ptr += sizeof(u32); |
1212 | IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); | 1234 | IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n", |
1235 | time, data, ev); | ||
1213 | } | 1236 | } |
1214 | } | 1237 | } |
1215 | } | 1238 | } |
@@ -1272,4 +1295,114 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) | |||
1272 | } | 1295 | } |
1273 | EXPORT_SYMBOL(iwl_dump_nic_event_log); | 1296 | EXPORT_SYMBOL(iwl_dump_nic_event_log); |
1274 | 1297 | ||
1298 | void iwl_rf_kill_ct_config(struct iwl_priv *priv) | ||
1299 | { | ||
1300 | struct iwl_ct_kill_config cmd; | ||
1301 | unsigned long flags; | ||
1302 | int ret = 0; | ||
1303 | |||
1304 | spin_lock_irqsave(&priv->lock, flags); | ||
1305 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||
1306 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | ||
1307 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1308 | |||
1309 | cmd.critical_temperature_R = | ||
1310 | cpu_to_le32(priv->hw_params.ct_kill_threshold); | ||
1311 | |||
1312 | ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, | ||
1313 | sizeof(cmd), &cmd); | ||
1314 | if (ret) | ||
1315 | IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); | ||
1316 | else | ||
1317 | IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " | ||
1318 | "critical temperature is %d\n", | ||
1319 | cmd.critical_temperature_R); | ||
1320 | } | ||
1321 | EXPORT_SYMBOL(iwl_rf_kill_ct_config); | ||
1322 | |||
1323 | /* | ||
1324 | * CARD_STATE_CMD | ||
1325 | * | ||
1326 | * Use: Sets the device's internal card state to enable, disable, or halt | ||
1327 | * | ||
1328 | * When in the 'enable' state the card operates as normal. | ||
1329 | * When in the 'disable' state, the card enters into a low power mode. | ||
1330 | * When in the 'halt' state, the card is shut down and must be fully | ||
1331 | * restarted to come back on. | ||
1332 | */ | ||
1333 | static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | ||
1334 | { | ||
1335 | struct iwl_host_cmd cmd = { | ||
1336 | .id = REPLY_CARD_STATE_CMD, | ||
1337 | .len = sizeof(u32), | ||
1338 | .data = &flags, | ||
1339 | .meta.flags = meta_flag, | ||
1340 | }; | ||
1341 | |||
1342 | return iwl_send_cmd(priv, &cmd); | ||
1343 | } | ||
1344 | |||
1345 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) | ||
1346 | { | ||
1347 | unsigned long flags; | ||
1348 | |||
1349 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
1350 | return; | ||
1351 | |||
1352 | IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n"); | ||
1353 | |||
1354 | iwl_scan_cancel(priv); | ||
1355 | /* FIXME: This is a workaround for AP */ | ||
1356 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | ||
1357 | spin_lock_irqsave(&priv->lock, flags); | ||
1358 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
1359 | CSR_UCODE_SW_BIT_RFKILL); | ||
1360 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1361 | /* call the host command only if no hw rf-kill set */ | ||
1362 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
1363 | iwl_is_ready(priv)) | ||
1364 | iwl_send_card_state(priv, | ||
1365 | CARD_STATE_CMD_DISABLE, 0); | ||
1366 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1367 | /* make sure mac80211 stop sending Tx frame */ | ||
1368 | if (priv->mac80211_registered) | ||
1369 | ieee80211_stop_queues(priv->hw); | ||
1370 | } | ||
1371 | } | ||
1372 | EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); | ||
1275 | 1373 | ||
1374 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | ||
1375 | { | ||
1376 | unsigned long flags; | ||
1377 | |||
1378 | if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
1379 | return 0; | ||
1380 | |||
1381 | IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n"); | ||
1382 | |||
1383 | spin_lock_irqsave(&priv->lock, flags); | ||
1384 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1385 | |||
1386 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1387 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1388 | |||
1389 | /* wake up ucode */ | ||
1390 | msleep(10); | ||
1391 | |||
1392 | spin_lock_irqsave(&priv->lock, flags); | ||
1393 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
1394 | if (!iwl_grab_nic_access(priv)) | ||
1395 | iwl_release_nic_access(priv); | ||
1396 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1397 | |||
1398 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
1399 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | ||
1400 | "disabled by HW switch\n"); | ||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1404 | if (priv->is_open) | ||
1405 | queue_work(priv->workqueue, &priv->restart); | ||
1406 | return 1; | ||
1407 | } | ||
1408 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6b5af7afbb25..2838093b4459 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -88,13 +88,11 @@ struct iwl_hcmd_ops { | |||
88 | struct iwl_hcmd_utils_ops { | 88 | struct iwl_hcmd_utils_ops { |
89 | u16 (*get_hcmd_size)(u8 cmd_id, u16 len); | 89 | u16 (*get_hcmd_size)(u8 cmd_id, u16 len); |
90 | u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); | 90 | u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); |
91 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
92 | void (*gain_computation)(struct iwl_priv *priv, | 91 | void (*gain_computation)(struct iwl_priv *priv, |
93 | u32 *average_noise, | 92 | u32 *average_noise, |
94 | u16 min_average_noise_antennat_i, | 93 | u16 min_average_noise_antennat_i, |
95 | u32 min_average_noise); | 94 | u32 min_average_noise); |
96 | void (*chain_noise_reset)(struct iwl_priv *priv); | 95 | void (*chain_noise_reset)(struct iwl_priv *priv); |
97 | #endif | ||
98 | }; | 96 | }; |
99 | 97 | ||
100 | struct iwl_lib_ops { | 98 | struct iwl_lib_ops { |
@@ -111,15 +109,17 @@ struct iwl_lib_ops { | |||
111 | void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, | 109 | void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, |
112 | struct iwl_tx_queue *txq); | 110 | struct iwl_tx_queue *txq); |
113 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); | 111 | void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); |
114 | #ifdef CONFIG_IWL4965_HT | ||
115 | /* aggregations */ | 112 | /* aggregations */ |
116 | int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, | 113 | int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, |
117 | int sta_id, int tid, u16 ssn_idx); | 114 | int sta_id, int tid, u16 ssn_idx); |
118 | int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, | 115 | int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, |
119 | u8 tx_fifo); | 116 | u8 tx_fifo); |
120 | #endif /* CONFIG_IWL4965_HT */ | ||
121 | /* setup Rx handler */ | 117 | /* setup Rx handler */ |
122 | void (*rx_handler_setup)(struct iwl_priv *priv); | 118 | void (*rx_handler_setup)(struct iwl_priv *priv); |
119 | /* setup deferred work */ | ||
120 | void (*setup_deferred_work)(struct iwl_priv *priv); | ||
121 | /* cancel deferred work */ | ||
122 | void (*cancel_deferred_work)(struct iwl_priv *priv); | ||
123 | /* alive notification after init uCode load */ | 123 | /* alive notification after init uCode load */ |
124 | void (*init_alive_start)(struct iwl_priv *priv); | 124 | void (*init_alive_start)(struct iwl_priv *priv); |
125 | /* alive notification */ | 125 | /* alive notification */ |
@@ -128,8 +128,6 @@ struct iwl_lib_ops { | |||
128 | int (*is_valid_rtc_data_addr)(u32 addr); | 128 | int (*is_valid_rtc_data_addr)(u32 addr); |
129 | /* 1st ucode load */ | 129 | /* 1st ucode load */ |
130 | int (*load_ucode)(struct iwl_priv *priv); | 130 | int (*load_ucode)(struct iwl_priv *priv); |
131 | /* rfkill */ | ||
132 | void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); | ||
133 | /* power management */ | 131 | /* power management */ |
134 | struct { | 132 | struct { |
135 | int (*init)(struct iwl_priv *priv); | 133 | int (*init)(struct iwl_priv *priv); |
@@ -140,6 +138,7 @@ struct iwl_lib_ops { | |||
140 | } apm_ops; | 138 | } apm_ops; |
141 | /* power */ | 139 | /* power */ |
142 | int (*set_power)(struct iwl_priv *priv, void *cmd); | 140 | int (*set_power)(struct iwl_priv *priv, void *cmd); |
141 | int (*send_tx_power) (struct iwl_priv *priv); | ||
143 | void (*update_chain_flags)(struct iwl_priv *priv); | 142 | void (*update_chain_flags)(struct iwl_priv *priv); |
144 | /* eeprom operations (as defined in iwl-eeprom.h) */ | 143 | /* eeprom operations (as defined in iwl-eeprom.h) */ |
145 | struct iwl_eeprom_ops eeprom_ops; | 144 | struct iwl_eeprom_ops eeprom_ops; |
@@ -233,11 +232,53 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | |||
233 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, | 232 | int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, |
234 | dma_addr_t addr, u16 len); | 233 | dma_addr_t addr, u16 len); |
235 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); | 234 | int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); |
236 | #ifdef CONFIG_IWL4965_HT | ||
237 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); | 235 | int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); |
238 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); | 236 | int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); |
239 | int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); | 237 | int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); |
240 | #endif | 238 | |
239 | /***************************************************** | ||
240 | * TX power | ||
241 | ****************************************************/ | ||
242 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | ||
243 | |||
244 | /***************************************************** | ||
245 | * RF -Kill - here and not in iwl-rfkill.h to be available when | ||
246 | * RF-kill subsystem is not compiled. | ||
247 | ****************************************************/ | ||
248 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); | ||
249 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); | ||
250 | |||
251 | /******************************************************************************* | ||
252 | * Rate | ||
253 | ******************************************************************************/ | ||
254 | |||
255 | void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, | ||
256 | struct ieee80211_tx_info *info); | ||
257 | int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); | ||
258 | |||
259 | static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) | ||
260 | { | ||
261 | return le32_to_cpu(rate_n_flags) & 0xFF; | ||
262 | } | ||
263 | static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags) | ||
264 | { | ||
265 | return le32_to_cpu(rate_n_flags) & 0x1FFFF; | ||
266 | } | ||
267 | static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | ||
268 | { | ||
269 | return cpu_to_le32(flags|(u32)rate); | ||
270 | } | ||
271 | |||
272 | /******************************************************************************* | ||
273 | * Scanning | ||
274 | ******************************************************************************/ | ||
275 | void iwl_init_scan_params(struct iwl_priv *priv); | ||
276 | int iwl_scan_cancel(struct iwl_priv *priv); | ||
277 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); | ||
278 | const char *iwl_escape_essid(const char *essid, u8 essid_len); | ||
279 | int iwl_scan_initiate(struct iwl_priv *priv); | ||
280 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); | ||
281 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv); | ||
241 | 282 | ||
242 | /***************************************************** | 283 | /***************************************************** |
243 | * S e n d i n g H o s t C o m m a n d s * | 284 | * S e n d i n g H o s t C o m m a n d s * |
@@ -286,6 +327,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv); | |||
286 | #define STATUS_POWER_PMI 16 | 327 | #define STATUS_POWER_PMI 16 |
287 | #define STATUS_FW_ERROR 17 | 328 | #define STATUS_FW_ERROR 17 |
288 | #define STATUS_CONF_PENDING 18 | 329 | #define STATUS_CONF_PENDING 18 |
330 | #define STATUS_MODE_PENDING 19 | ||
289 | 331 | ||
290 | 332 | ||
291 | static inline int iwl_is_ready(struct iwl_priv *priv) | 333 | static inline int iwl_is_ready(struct iwl_priv *priv) |
@@ -322,19 +364,10 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) | |||
322 | return iwl_is_ready(priv); | 364 | return iwl_is_ready(priv); |
323 | } | 365 | } |
324 | 366 | ||
325 | 367 | extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); | |
326 | enum iwlcore_card_notify { | ||
327 | IWLCORE_INIT_EVT = 0, | ||
328 | IWLCORE_START_EVT = 1, | ||
329 | IWLCORE_STOP_EVT = 2, | ||
330 | IWLCORE_REMOVE_EVT = 3, | ||
331 | }; | ||
332 | |||
333 | int iwlcore_low_level_notify(struct iwl_priv *priv, | ||
334 | enum iwlcore_card_notify notify); | ||
335 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); | 368 | extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); |
336 | extern int iwl_verify_ucode(struct iwl_priv *priv); | 369 | extern int iwl_verify_ucode(struct iwl_priv *priv); |
337 | int iwl_send_lq_cmd(struct iwl_priv *priv, | 370 | extern int iwl_send_lq_cmd(struct iwl_priv *priv, |
338 | struct iwl_link_quality_cmd *lq, u8 flags); | 371 | struct iwl_link_quality_cmd *lq, u8 flags); |
339 | 372 | ||
340 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | 373 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 11de561c7bf8..58384805a494 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -55,10 +55,9 @@ struct iwl_debugfs { | |||
55 | struct dentry *file_log_event; | 55 | struct dentry *file_log_event; |
56 | } dbgfs_data_files; | 56 | } dbgfs_data_files; |
57 | struct dir_rf_files { | 57 | struct dir_rf_files { |
58 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
59 | struct dentry *file_disable_sensitivity; | 58 | struct dentry *file_disable_sensitivity; |
60 | struct dentry *file_disable_chain_noise; | 59 | struct dentry *file_disable_chain_noise; |
61 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | 60 | struct dentry *file_disable_tx_power; |
62 | } dbgfs_rf_files; | 61 | } dbgfs_rf_files; |
63 | u32 sram_offset; | 62 | u32 sram_offset; |
64 | u32 sram_len; | 63 | u32 sram_len; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 29e16ba69cdb..ed948dc59b3d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -255,21 +255,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
255 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); | 255 | pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); |
256 | pos += scnprintf(buf + pos, bufsz - pos, | 256 | pos += scnprintf(buf + pos, bufsz - pos, |
257 | "seq_num\t\ttxq_id"); | 257 | "seq_num\t\ttxq_id"); |
258 | #ifdef CONFIG_IWL4965_HT | ||
259 | pos += scnprintf(buf + pos, bufsz - pos, | 258 | pos += scnprintf(buf + pos, bufsz - pos, |
260 | "\tframe_count\twait_for_ba\t"); | 259 | "\tframe_count\twait_for_ba\t"); |
261 | pos += scnprintf(buf + pos, bufsz - pos, | 260 | pos += scnprintf(buf + pos, bufsz - pos, |
262 | "start_idx\tbitmap0\t"); | 261 | "start_idx\tbitmap0\t"); |
263 | pos += scnprintf(buf + pos, bufsz - pos, | 262 | pos += scnprintf(buf + pos, bufsz - pos, |
264 | "bitmap1\trate_n_flags"); | 263 | "bitmap1\trate_n_flags"); |
265 | #endif | ||
266 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 264 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
267 | 265 | ||
268 | for (j = 0; j < MAX_TID_COUNT; j++) { | 266 | for (j = 0; j < MAX_TID_COUNT; j++) { |
269 | pos += scnprintf(buf + pos, bufsz - pos, | 267 | pos += scnprintf(buf + pos, bufsz - pos, |
270 | "[%d]:\t\t%u", j, | 268 | "[%d]:\t\t%u", j, |
271 | station->tid[j].seq_number); | 269 | station->tid[j].seq_number); |
272 | #ifdef CONFIG_IWL4965_HT | ||
273 | pos += scnprintf(buf + pos, bufsz - pos, | 270 | pos += scnprintf(buf + pos, bufsz - pos, |
274 | "\t%u\t\t%u\t\t%u\t\t", | 271 | "\t%u\t\t%u\t\t%u\t\t", |
275 | station->tid[j].agg.txq_id, | 272 | station->tid[j].agg.txq_id, |
@@ -280,7 +277,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, | |||
280 | station->tid[j].agg.start_idx, | 277 | station->tid[j].agg.start_idx, |
281 | (unsigned long long)station->tid[j].agg.bitmap, | 278 | (unsigned long long)station->tid[j].agg.bitmap, |
282 | station->tid[j].agg.rate_n_flags); | 279 | station->tid[j].agg.rate_n_flags); |
283 | #endif | ||
284 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 280 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
285 | } | 281 | } |
286 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); | 282 | pos += scnprintf(buf + pos, bufsz - pos, "\n"); |
@@ -389,11 +385,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) | |||
389 | DEBUGFS_ADD_FILE(stations, data); | 385 | DEBUGFS_ADD_FILE(stations, data); |
390 | DEBUGFS_ADD_FILE(rx_statistics, data); | 386 | DEBUGFS_ADD_FILE(rx_statistics, data); |
391 | DEBUGFS_ADD_FILE(tx_statistics, data); | 387 | DEBUGFS_ADD_FILE(tx_statistics, data); |
392 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
393 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); | 388 | DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); |
394 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, | 389 | DEBUGFS_ADD_BOOL(disable_chain_noise, rf, |
395 | &priv->disable_chain_noise_cal); | 390 | &priv->disable_chain_noise_cal); |
396 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | 391 | DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal); |
397 | return 0; | 392 | return 0; |
398 | 393 | ||
399 | err: | 394 | err: |
@@ -419,10 +414,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
419 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); | 414 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); |
420 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); | 415 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); |
421 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); | 416 | DEBUGFS_REMOVE(priv->dbgfs->dir_data); |
422 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
423 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); | 417 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); |
424 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); | 418 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); |
425 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | 419 | DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); |
426 | DEBUGFS_REMOVE(priv->dbgfs->dir_rf); | 420 | DEBUGFS_REMOVE(priv->dbgfs->dir_rf); |
427 | DEBUGFS_REMOVE(priv->dbgfs->dir_drv); | 421 | DEBUGFS_REMOVE(priv->dbgfs->dir_drv); |
428 | kfree(priv->dbgfs); | 422 | kfree(priv->dbgfs); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 802f1a12b1aa..81ff4c2c6a5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -29,8 +29,8 @@ | |||
29 | * Please use iwl-4965-hw.h for hardware-related definitions. | 29 | * Please use iwl-4965-hw.h for hardware-related definitions. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #ifndef __iwl_4965_h__ | 32 | #ifndef __iwl_dev_h__ |
33 | #define __iwl_4965_h__ | 33 | #define __iwl_dev_h__ |
34 | 34 | ||
35 | #include <linux/pci.h> /* for struct pci_device_id */ | 35 | #include <linux/pci.h> /* for struct pci_device_id */ |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -157,44 +157,11 @@ struct iwl4965_channel_tgh_info { | |||
157 | s64 last_radar_time; | 157 | s64 last_radar_time; |
158 | }; | 158 | }; |
159 | 159 | ||
160 | /* current Tx power values to use, one for each rate for each channel. | ||
161 | * requested power is limited by: | ||
162 | * -- regulatory EEPROM limits for this channel | ||
163 | * -- hardware capabilities (clip-powers) | ||
164 | * -- spectrum management | ||
165 | * -- user preference (e.g. iwconfig) | ||
166 | * when requested power is set, base power index must also be set. */ | ||
167 | struct iwl4965_channel_power_info { | ||
168 | struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ | ||
169 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
170 | s8 base_power_index; /* gain index for power at factory temp. */ | ||
171 | s8 requested_power; /* power (dBm) requested for this chnl/rate */ | ||
172 | }; | ||
173 | |||
174 | /* current scan Tx power values to use, one for each scan rate for each | ||
175 | * channel. */ | ||
176 | struct iwl4965_scan_power_info { | ||
177 | struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ | ||
178 | s8 power_table_index; /* actual (compenst'd) index into gain table */ | ||
179 | s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ | ||
180 | }; | ||
181 | |||
182 | /* For fat_extension_channel */ | ||
183 | enum { | ||
184 | HT_IE_EXT_CHANNEL_NONE = 0, | ||
185 | HT_IE_EXT_CHANNEL_ABOVE, | ||
186 | HT_IE_EXT_CHANNEL_INVALID, | ||
187 | HT_IE_EXT_CHANNEL_BELOW, | ||
188 | HT_IE_EXT_CHANNEL_MAX | ||
189 | }; | ||
190 | |||
191 | /* | 160 | /* |
192 | * One for each channel, holds all channel setup data | 161 | * One for each channel, holds all channel setup data |
193 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant | 162 | * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant |
194 | * with one another! | 163 | * with one another! |
195 | */ | 164 | */ |
196 | #define IWL4965_MAX_RATE (33) | ||
197 | |||
198 | struct iwl_channel_info { | 165 | struct iwl_channel_info { |
199 | struct iwl4965_channel_tgd_info tgd; | 166 | struct iwl4965_channel_tgd_info tgd; |
200 | struct iwl4965_channel_tgh_info tgh; | 167 | struct iwl4965_channel_tgh_info tgh; |
@@ -213,11 +180,6 @@ struct iwl_channel_info { | |||
213 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ | 180 | u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ |
214 | enum ieee80211_band band; | 181 | enum ieee80211_band band; |
215 | 182 | ||
216 | /* Radio/DSP gain settings for each "normal" data Tx rate. | ||
217 | * These include, in addition to RF and DSP gain, a few fields for | ||
218 | * remembering/modifying gain settings (indexes). */ | ||
219 | struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE]; | ||
220 | |||
221 | /* FAT channel info */ | 183 | /* FAT channel info */ |
222 | s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ | 184 | s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ |
223 | s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ | 185 | s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ |
@@ -225,9 +187,6 @@ struct iwl_channel_info { | |||
225 | s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ | 187 | s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ |
226 | u8 fat_flags; /* flags copied from EEPROM */ | 188 | u8 fat_flags; /* flags copied from EEPROM */ |
227 | u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ | 189 | u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ |
228 | |||
229 | /* Radio/DSP gain settings for each scan rate, for directed scans. */ | ||
230 | struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; | ||
231 | }; | 190 | }; |
232 | 191 | ||
233 | struct iwl4965_clip_group { | 192 | struct iwl4965_clip_group { |
@@ -401,7 +360,6 @@ struct iwl_rx_queue { | |||
401 | #define IWL_INVALID_RATE 0xFF | 360 | #define IWL_INVALID_RATE 0xFF |
402 | #define IWL_INVALID_VALUE -1 | 361 | #define IWL_INVALID_VALUE -1 |
403 | 362 | ||
404 | #ifdef CONFIG_IWL4965_HT | ||
405 | /** | 363 | /** |
406 | * struct iwl_ht_agg -- aggregation status while waiting for block-ack | 364 | * struct iwl_ht_agg -- aggregation status while waiting for block-ack |
407 | * @txq_id: Tx queue used for Tx attempt | 365 | * @txq_id: Tx queue used for Tx attempt |
@@ -430,14 +388,11 @@ struct iwl_ht_agg { | |||
430 | u8 state; | 388 | u8 state; |
431 | }; | 389 | }; |
432 | 390 | ||
433 | #endif /* CONFIG_IWL4965_HT */ | ||
434 | 391 | ||
435 | struct iwl_tid_data { | 392 | struct iwl_tid_data { |
436 | u16 seq_number; | 393 | u16 seq_number; |
437 | u16 tfds_in_queue; | 394 | u16 tfds_in_queue; |
438 | #ifdef CONFIG_IWL4965_HT | ||
439 | struct iwl_ht_agg agg; | 395 | struct iwl_ht_agg agg; |
440 | #endif /* CONFIG_IWL4965_HT */ | ||
441 | }; | 396 | }; |
442 | 397 | ||
443 | struct iwl_hw_key { | 398 | struct iwl_hw_key { |
@@ -525,7 +480,7 @@ struct fw_desc { | |||
525 | }; | 480 | }; |
526 | 481 | ||
527 | /* uCode file layout */ | 482 | /* uCode file layout */ |
528 | struct iwl4965_ucode { | 483 | struct iwl_ucode { |
529 | __le32 ver; /* major/minor/subminor */ | 484 | __le32 ver; /* major/minor/subminor */ |
530 | __le32 inst_size; /* bytes of runtime instructions */ | 485 | __le32 inst_size; /* bytes of runtime instructions */ |
531 | __le32 data_size; /* bytes of runtime data */ | 486 | __le32 data_size; /* bytes of runtime data */ |
@@ -587,6 +542,7 @@ struct iwl_sensitivity_ranges { | |||
587 | * @max_xxx_size: for ucode uses | 542 | * @max_xxx_size: for ucode uses |
588 | * @ct_kill_threshold: temperature threshold | 543 | * @ct_kill_threshold: temperature threshold |
589 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 544 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
545 | * @first_ampdu_q: first HW queue available for ampdu | ||
590 | */ | 546 | */ |
591 | struct iwl_hw_params { | 547 | struct iwl_hw_params { |
592 | u16 max_txq_num; | 548 | u16 max_txq_num; |
@@ -606,9 +562,8 @@ struct iwl_hw_params { | |||
606 | u32 max_data_size; | 562 | u32 max_data_size; |
607 | u32 max_bsm_size; | 563 | u32 max_bsm_size; |
608 | u32 ct_kill_threshold; /* value in hw-dependent units */ | 564 | u32 ct_kill_threshold; /* value in hw-dependent units */ |
609 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
610 | const struct iwl_sensitivity_ranges *sens; | 565 | const struct iwl_sensitivity_ranges *sens; |
611 | #endif | 566 | u8 first_ampdu_q; |
612 | }; | 567 | }; |
613 | 568 | ||
614 | #define HT_SHORT_GI_20MHZ (1 << 0) | 569 | #define HT_SHORT_GI_20MHZ (1 << 0) |
@@ -638,15 +593,8 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | |||
638 | u8 flags, struct ieee80211_ht_info *ht_info); | 593 | u8 flags, struct ieee80211_ht_info *ht_info); |
639 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, | 594 | extern int iwl4965_is_network_packet(struct iwl_priv *priv, |
640 | struct ieee80211_hdr *header); | 595 | struct ieee80211_hdr *header); |
641 | extern int iwl4965_power_init_handle(struct iwl_priv *priv); | ||
642 | extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv, | ||
643 | struct iwl_rx_mem_buffer *rxb, | ||
644 | void *data, short len, | ||
645 | struct ieee80211_rx_status *stats, | ||
646 | u16 phy_flags); | ||
647 | extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, | 596 | extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, |
648 | struct ieee80211_hdr *header); | 597 | struct ieee80211_hdr *header); |
649 | extern int iwl4965_calc_db_from_ratio(int sig_ratio); | ||
650 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); | 598 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); |
651 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | 599 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, |
652 | struct ieee80211_hdr *hdr, | 600 | struct ieee80211_hdr *hdr, |
@@ -654,18 +602,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | |||
654 | extern void iwl4965_update_chain_flags(struct iwl_priv *priv); | 602 | extern void iwl4965_update_chain_flags(struct iwl_priv *priv); |
655 | int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); | 603 | int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); |
656 | 604 | ||
657 | int iwl4965_init_geos(struct iwl_priv *priv); | ||
658 | void iwl4965_free_geos(struct iwl_priv *priv); | ||
659 | |||
660 | extern const u8 iwl_bcast_addr[ETH_ALEN]; | 605 | extern const u8 iwl_bcast_addr[ETH_ALEN]; |
661 | int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | ||
662 | |||
663 | /* | ||
664 | * Currently used by iwl-3945-rs... look at restructuring so that it doesn't | ||
665 | * call this... todo... fix that. | ||
666 | */ | ||
667 | extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id, | ||
668 | u16 tx_rate, u8 flags); | ||
669 | 606 | ||
670 | /****************************************************************************** | 607 | /****************************************************************************** |
671 | * | 608 | * |
@@ -683,38 +620,16 @@ extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id, | |||
683 | * iwl4965_mac_ <-- mac80211 callback | 620 | * iwl4965_mac_ <-- mac80211 callback |
684 | * | 621 | * |
685 | ****************************************************************************/ | 622 | ****************************************************************************/ |
686 | extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); | ||
687 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); | ||
688 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); | ||
689 | extern int iwl_rxq_stop(struct iwl_priv *priv); | 623 | extern int iwl_rxq_stop(struct iwl_priv *priv); |
690 | extern void iwl_txq_ctx_stop(struct iwl_priv *priv); | 624 | extern void iwl_txq_ctx_stop(struct iwl_priv *priv); |
691 | extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); | ||
692 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | 625 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, |
693 | struct iwl_frame *frame, u8 rate); | 626 | struct iwl_frame *frame, u8 rate); |
694 | extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, | ||
695 | struct iwl_cmd *cmd, | ||
696 | struct ieee80211_tx_info *info, | ||
697 | struct ieee80211_hdr *hdr, | ||
698 | int sta_id, int tx_id); | ||
699 | extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv); | ||
700 | extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); | ||
701 | extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, | 627 | extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, |
702 | struct iwl_rx_mem_buffer *rxb); | 628 | struct iwl_rx_mem_buffer *rxb); |
703 | extern void iwl4965_disable_events(struct iwl_priv *priv); | 629 | extern void iwl4965_disable_events(struct iwl_priv *priv); |
704 | extern int iwl4965_get_temperature(const struct iwl_priv *priv); | ||
705 | extern void iwl4965_rx_reply_rx(struct iwl_priv *priv, | 630 | extern void iwl4965_rx_reply_rx(struct iwl_priv *priv, |
706 | struct iwl_rx_mem_buffer *rxb); | 631 | struct iwl_rx_mem_buffer *rxb); |
707 | 632 | ||
708 | /** | ||
709 | * iwl_find_station - Find station id for a given BSSID | ||
710 | * @bssid: MAC address of station ID to find | ||
711 | * | ||
712 | * NOTE: This should not be hardware specific but the code has | ||
713 | * not yet been merged into a single common layer for managing the | ||
714 | * station tables. | ||
715 | */ | ||
716 | extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid); | ||
717 | |||
718 | extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); | 633 | extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); |
719 | extern int iwl_queue_space(const struct iwl_queue *q); | 634 | extern int iwl_queue_space(const struct iwl_queue *q); |
720 | static inline int iwl_queue_used(const struct iwl_queue *q, int i) | 635 | static inline int iwl_queue_used(const struct iwl_queue *q, int i) |
@@ -738,37 +653,17 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) | |||
738 | 653 | ||
739 | struct iwl_priv; | 654 | struct iwl_priv; |
740 | 655 | ||
741 | extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); | ||
742 | /* | 656 | /* |
743 | * Forward declare iwl-4965.c functions for iwl-base.c | 657 | * Forward declare iwl-4965.c functions for iwl-base.c |
744 | */ | 658 | */ |
745 | extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, | ||
746 | struct iwl_tx_queue *txq, | ||
747 | u16 byte_cnt); | ||
748 | extern int iwl4965_alive_notify(struct iwl_priv *priv); | ||
749 | extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); | ||
750 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); | 659 | extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); |
751 | extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, | 660 | |
752 | u32 rate_n_flags, | ||
753 | struct ieee80211_tx_info *info); | ||
754 | |||
755 | #ifdef CONFIG_IWL4965_HT | ||
756 | extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, | ||
757 | struct ieee80211_ht_info *ht_info, | ||
758 | enum ieee80211_band band); | ||
759 | void iwl4965_set_rxon_ht(struct iwl_priv *priv, | ||
760 | struct iwl_ht_info *ht_info); | ||
761 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, | 661 | int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, |
762 | enum ieee80211_ampdu_mlme_action action, | 662 | enum ieee80211_ampdu_mlme_action action, |
763 | const u8 *addr, u16 tid, u16 *ssn); | 663 | const u8 *addr, u16 tid, u16 *ssn); |
764 | int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, | 664 | int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, |
765 | u8 tid, int txq_id); | 665 | u8 tid, int txq_id); |
766 | #else | ||
767 | static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, | ||
768 | struct ieee80211_ht_info *ht_info, | ||
769 | enum ieee80211_band band) {} | ||
770 | 666 | ||
771 | #endif /*CONFIG_IWL4965_HT */ | ||
772 | /* Structures, enum, and defines specific to the 4965 */ | 667 | /* Structures, enum, and defines specific to the 4965 */ |
773 | 668 | ||
774 | #define IWL_KW_SIZE 0x1000 /*4k */ | 669 | #define IWL_KW_SIZE 0x1000 /*4k */ |
@@ -792,11 +687,6 @@ struct iwl_kw { | |||
792 | #define IWL_OPERATION_MODE_MIXED 2 | 687 | #define IWL_OPERATION_MODE_MIXED 2 |
793 | #define IWL_OPERATION_MODE_20MHZ 3 | 688 | #define IWL_OPERATION_MODE_20MHZ 3 |
794 | 689 | ||
795 | #define IWL_EXT_CHANNEL_OFFSET_NONE 0 | ||
796 | #define IWL_EXT_CHANNEL_OFFSET_ABOVE 1 | ||
797 | #define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2 | ||
798 | #define IWL_EXT_CHANNEL_OFFSET_BELOW 3 | ||
799 | |||
800 | #define IWL_TX_CRC_SIZE 4 | 690 | #define IWL_TX_CRC_SIZE 4 |
801 | #define IWL_TX_DELIMITER_SIZE 4 | 691 | #define IWL_TX_DELIMITER_SIZE 4 |
802 | 692 | ||
@@ -892,7 +782,6 @@ enum ucode_type { | |||
892 | UCODE_RT | 782 | UCODE_RT |
893 | }; | 783 | }; |
894 | 784 | ||
895 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
896 | /* Sensitivity calib data */ | 785 | /* Sensitivity calib data */ |
897 | struct iwl_sensitivity_data { | 786 | struct iwl_sensitivity_data { |
898 | u32 auto_corr_ofdm; | 787 | u32 auto_corr_ofdm; |
@@ -934,7 +823,6 @@ struct iwl_chain_noise_data { | |||
934 | u8 delta_gain_code[NUM_RX_CHAINS]; | 823 | u8 delta_gain_code[NUM_RX_CHAINS]; |
935 | u8 radio_write; | 824 | u8 radio_write; |
936 | }; | 825 | }; |
937 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | ||
938 | 826 | ||
939 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ | 827 | #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ |
940 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ | 828 | #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ |
@@ -1006,7 +894,8 @@ struct iwl_priv { | |||
1006 | int one_direct_scan; | 894 | int one_direct_scan; |
1007 | u8 direct_ssid_len; | 895 | u8 direct_ssid_len; |
1008 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; | 896 | u8 direct_ssid[IW_ESSID_MAX_SIZE]; |
1009 | struct iwl4965_scan_cmd *scan; | 897 | struct iwl_scan_cmd *scan; |
898 | u32 scan_tx_ant[IEEE80211_NUM_BANDS]; | ||
1010 | 899 | ||
1011 | /* spinlock */ | 900 | /* spinlock */ |
1012 | spinlock_t lock; /* protect general shared data */ | 901 | spinlock_t lock; /* protect general shared data */ |
@@ -1067,15 +956,11 @@ struct iwl_priv { | |||
1067 | u8 assoc_station_added; | 956 | u8 assoc_station_added; |
1068 | u8 use_ant_b_for_management_frame; /* Tx antenna selection */ | 957 | u8 use_ant_b_for_management_frame; /* Tx antenna selection */ |
1069 | u8 start_calib; | 958 | u8 start_calib; |
1070 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
1071 | struct iwl_sensitivity_data sensitivity_data; | 959 | struct iwl_sensitivity_data sensitivity_data; |
1072 | struct iwl_chain_noise_data chain_noise_data; | 960 | struct iwl_chain_noise_data chain_noise_data; |
1073 | __le16 sensitivity_tbl[HD_TABLE_SIZE]; | 961 | __le16 sensitivity_tbl[HD_TABLE_SIZE]; |
1074 | #endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/ | ||
1075 | 962 | ||
1076 | #ifdef CONFIG_IWL4965_HT | ||
1077 | struct iwl_ht_info current_ht_config; | 963 | struct iwl_ht_info current_ht_config; |
1078 | #endif | ||
1079 | u8 last_phy_res[100]; | 964 | u8 last_phy_res[100]; |
1080 | 965 | ||
1081 | /* Rate scaling data */ | 966 | /* Rate scaling data */ |
@@ -1197,15 +1082,11 @@ struct iwl_priv { | |||
1197 | 1082 | ||
1198 | struct delayed_work init_alive_start; | 1083 | struct delayed_work init_alive_start; |
1199 | struct delayed_work alive_start; | 1084 | struct delayed_work alive_start; |
1200 | struct delayed_work activity_timer; | ||
1201 | struct delayed_work thermal_periodic; | ||
1202 | struct delayed_work gather_stats; | ||
1203 | struct delayed_work scan_check; | 1085 | struct delayed_work scan_check; |
1204 | struct delayed_work post_associate; | 1086 | struct delayed_work post_associate; |
1205 | 1087 | /* TX Power */ | |
1206 | #define IWL_DEFAULT_TX_POWER 0x0F | 1088 | s8 tx_power_user_lmt; |
1207 | s8 user_txpower_limit; | 1089 | s8 tx_power_channel_lmt; |
1208 | s8 max_channel_txpower_limit; | ||
1209 | 1090 | ||
1210 | #ifdef CONFIG_PM | 1091 | #ifdef CONFIG_PM |
1211 | u32 pm_state[16]; | 1092 | u32 pm_state[16]; |
@@ -1223,13 +1104,10 @@ struct iwl_priv { | |||
1223 | #endif /* CONFIG_IWLWIFI_DEBUG */ | 1104 | #endif /* CONFIG_IWLWIFI_DEBUG */ |
1224 | 1105 | ||
1225 | struct work_struct txpower_work; | 1106 | struct work_struct txpower_work; |
1226 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
1227 | u32 disable_sens_cal; | 1107 | u32 disable_sens_cal; |
1228 | u32 disable_chain_noise_cal; | 1108 | u32 disable_chain_noise_cal; |
1229 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | 1109 | u32 disable_tx_power_cal; |
1230 | #ifdef CONFIG_IWL4965_RUN_TIME_CALIB | 1110 | struct work_struct run_time_calib_work; |
1231 | struct work_struct sensitivity_work; | ||
1232 | #endif /* CONFIG_IWL4965_RUN_TIME_CALIB */ | ||
1233 | struct timer_list statistics_periodic; | 1111 | struct timer_list statistics_periodic; |
1234 | }; /*iwl_priv */ | 1112 | }; /*iwl_priv */ |
1235 | 1113 | ||
@@ -1250,18 +1128,6 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } | |||
1250 | #endif | 1128 | #endif |
1251 | 1129 | ||
1252 | 1130 | ||
1253 | #ifdef CONFIG_IWL4965_HT | ||
1254 | static inline int iwl_get_ra_sta_id(struct iwl_priv *priv, | ||
1255 | struct ieee80211_hdr *hdr) | ||
1256 | { | ||
1257 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { | ||
1258 | return IWL_AP_ID; | ||
1259 | } else { | ||
1260 | u8 *da = ieee80211_get_DA(hdr); | ||
1261 | return iwl_find_station(priv, da); | ||
1262 | } | ||
1263 | } | ||
1264 | |||
1265 | static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, | 1131 | static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, |
1266 | int txq_id, int idx) | 1132 | int txq_id, int idx) |
1267 | { | 1133 | { |
@@ -1270,7 +1136,6 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, | |||
1270 | txb[idx].skb[0]->data; | 1136 | txb[idx].skb[0]->data; |
1271 | return NULL; | 1137 | return NULL; |
1272 | } | 1138 | } |
1273 | #endif | ||
1274 | 1139 | ||
1275 | 1140 | ||
1276 | static inline int iwl_is_associated(struct iwl_priv *priv) | 1141 | static inline int iwl_is_associated(struct iwl_priv *priv) |
@@ -1332,4 +1197,4 @@ extern const struct iwl_channel_info *iwl_get_channel_info( | |||
1332 | 1197 | ||
1333 | /* Requires full declaration of iwl_priv before including */ | 1198 | /* Requires full declaration of iwl_priv before including */ |
1334 | 1199 | ||
1335 | #endif /* __iwl4965_4965_h__ */ | 1200 | #endif /* __iwl_dev_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 11f9d9557a0e..4a08a1b50979 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c | |||
@@ -382,8 +382,8 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv, | |||
382 | if (!is_channel_valid(ch_info)) | 382 | if (!is_channel_valid(ch_info)) |
383 | return -1; | 383 | return -1; |
384 | 384 | ||
385 | IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x" | 385 | IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" |
386 | " %ddBm): Ad-Hoc %ssupported\n", | 386 | " Ad-Hoc %ssupported\n", |
387 | ch_info->channel, | 387 | ch_info->channel, |
388 | is_channel_a_band(ch_info) ? | 388 | is_channel_a_band(ch_info) ? |
389 | "5.2" : "2.4", | 389 | "5.2" : "2.4", |
@@ -470,6 +470,11 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
470 | /* Copy the run-time flags so they are there even on | 470 | /* Copy the run-time flags so they are there even on |
471 | * invalid channels */ | 471 | * invalid channels */ |
472 | ch_info->flags = eeprom_ch_info[ch].flags; | 472 | ch_info->flags = eeprom_ch_info[ch].flags; |
473 | /* First write that fat is not enabled, and then enable | ||
474 | * one by one */ | ||
475 | ch_info->fat_extension_channel = | ||
476 | (IEEE80211_CHAN_NO_FAT_ABOVE | | ||
477 | IEEE80211_CHAN_NO_FAT_BELOW); | ||
473 | 478 | ||
474 | if (!(is_channel_valid(ch_info))) { | 479 | if (!(is_channel_valid(ch_info))) { |
475 | IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - " | 480 | IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - " |
@@ -488,8 +493,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
488 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; | 493 | ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; |
489 | ch_info->min_power = 0; | 494 | ch_info->min_power = 0; |
490 | 495 | ||
491 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" | 496 | IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" |
492 | " %ddBm): Ad-Hoc %ssupported\n", | 497 | " Ad-Hoc %ssupported\n", |
493 | ch_info->channel, | 498 | ch_info->channel, |
494 | is_channel_a_band(ch_info) ? | 499 | is_channel_a_band(ch_info) ? |
495 | "5.2" : "2.4", | 500 | "5.2" : "2.4", |
@@ -510,8 +515,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
510 | /* Set the user_txpower_limit to the highest power | 515 | /* Set the user_txpower_limit to the highest power |
511 | * supported by any channel */ | 516 | * supported by any channel */ |
512 | if (eeprom_ch_info[ch].max_power_avg > | 517 | if (eeprom_ch_info[ch].max_power_avg > |
513 | priv->user_txpower_limit) | 518 | priv->tx_power_user_lmt) |
514 | priv->user_txpower_limit = | 519 | priv->tx_power_user_lmt = |
515 | eeprom_ch_info[ch].max_power_avg; | 520 | eeprom_ch_info[ch].max_power_avg; |
516 | 521 | ||
517 | ch_info++; | 522 | ch_info++; |
@@ -534,12 +539,14 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
534 | for (ch = 0; ch < eeprom_ch_count; ch++) { | 539 | for (ch = 0; ch < eeprom_ch_count; ch++) { |
535 | 540 | ||
536 | if ((band == 6) && | 541 | if ((band == 6) && |
537 | ((eeprom_ch_index[ch] == 5) || | 542 | ((eeprom_ch_index[ch] == 5) || |
538 | (eeprom_ch_index[ch] == 6) || | 543 | (eeprom_ch_index[ch] == 6) || |
539 | (eeprom_ch_index[ch] == 7))) | 544 | (eeprom_ch_index[ch] == 7))) |
540 | fat_extension_chan = HT_IE_EXT_CHANNEL_MAX; | 545 | /* both are allowed: above and below */ |
546 | fat_extension_chan = 0; | ||
541 | else | 547 | else |
542 | fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; | 548 | fat_extension_chan = |
549 | IEEE80211_CHAN_NO_FAT_BELOW; | ||
543 | 550 | ||
544 | /* Set up driver's info for lower half */ | 551 | /* Set up driver's info for lower half */ |
545 | iwl_set_fat_chan_info(priv, ieeeband, | 552 | iwl_set_fat_chan_info(priv, ieeeband, |
@@ -551,7 +558,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
551 | iwl_set_fat_chan_info(priv, ieeeband, | 558 | iwl_set_fat_chan_info(priv, ieeeband, |
552 | (eeprom_ch_index[ch] + 4), | 559 | (eeprom_ch_index[ch] + 4), |
553 | &(eeprom_ch_info[ch]), | 560 | &(eeprom_ch_info[ch]), |
554 | HT_IE_EXT_CHANNEL_BELOW); | 561 | IEEE80211_CHAN_NO_FAT_ABOVE); |
555 | } | 562 | } |
556 | } | 563 | } |
557 | 564 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index dedefa06ad8f..41eed6793328 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -139,123 +139,12 @@ static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val) | |||
139 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | 139 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |
140 | 140 | ||
141 | 141 | ||
142 | #define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010 | ||
143 | |||
144 | static inline struct ieee80211_conf *ieee80211_get_hw_conf( | 142 | static inline struct ieee80211_conf *ieee80211_get_hw_conf( |
145 | struct ieee80211_hw *hw) | 143 | struct ieee80211_hw *hw) |
146 | { | 144 | { |
147 | return &hw->conf; | 145 | return &hw->conf; |
148 | } | 146 | } |
149 | 147 | ||
150 | #define QOS_CONTROL_LEN 2 | ||
151 | |||
152 | |||
153 | static inline int ieee80211_is_management(u16 fc) | ||
154 | { | ||
155 | return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT; | ||
156 | } | ||
157 | |||
158 | static inline int ieee80211_is_control(u16 fc) | ||
159 | { | ||
160 | return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL; | ||
161 | } | ||
162 | |||
163 | static inline int ieee80211_is_data(u16 fc) | ||
164 | { | ||
165 | return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA; | ||
166 | } | ||
167 | |||
168 | static inline int ieee80211_is_back_request(u16 fc) | ||
169 | { | ||
170 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | ||
171 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ); | ||
172 | } | ||
173 | |||
174 | static inline int ieee80211_is_probe_response(u16 fc) | ||
175 | { | ||
176 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
177 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP); | ||
178 | } | ||
179 | |||
180 | static inline int ieee80211_is_probe_request(u16 fc) | ||
181 | { | ||
182 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
183 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ); | ||
184 | } | ||
185 | |||
186 | static inline int ieee80211_is_beacon(u16 fc) | ||
187 | { | ||
188 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
189 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON); | ||
190 | } | ||
191 | |||
192 | static inline int ieee80211_is_atim(u16 fc) | ||
193 | { | ||
194 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
195 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM); | ||
196 | } | ||
197 | |||
198 | static inline int ieee80211_is_assoc_request(u16 fc) | ||
199 | { | ||
200 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
201 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); | ||
202 | } | ||
203 | |||
204 | static inline int ieee80211_is_assoc_response(u16 fc) | ||
205 | { | ||
206 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
207 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP); | ||
208 | } | ||
209 | |||
210 | static inline int ieee80211_is_auth(u16 fc) | ||
211 | { | ||
212 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
213 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); | ||
214 | } | ||
215 | |||
216 | static inline int ieee80211_is_deauth(u16 fc) | ||
217 | { | ||
218 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
219 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); | ||
220 | } | ||
221 | |||
222 | static inline int ieee80211_is_disassoc(u16 fc) | ||
223 | { | ||
224 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
225 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); | ||
226 | } | ||
227 | |||
228 | static inline int ieee80211_is_reassoc_request(u16 fc) | ||
229 | { | ||
230 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
231 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ); | ||
232 | } | ||
233 | |||
234 | static inline int ieee80211_is_reassoc_response(u16 fc) | ||
235 | { | ||
236 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
237 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP); | ||
238 | } | ||
239 | |||
240 | static inline int ieee80211_is_qos_data(u16 fc) | ||
241 | { | ||
242 | return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | ||
243 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA); | ||
244 | } | ||
245 | /** | ||
246 | * ieee80211_get_qos_ctrl - get pointer to the QoS control field | ||
247 | * | ||
248 | * This function returns the pointer to 802.11 header QoS field (2 bytes) | ||
249 | * This function doesn't check whether hdr is a QoS hdr, use with care | ||
250 | * @hdr: struct ieee80211_hdr *hdr | ||
251 | * @hdr_len: header length | ||
252 | */ | ||
253 | |||
254 | static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len) | ||
255 | { | ||
256 | return ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN); | ||
257 | } | ||
258 | |||
259 | static inline int iwl_check_bits(unsigned long field, unsigned long mask) | 148 | static inline int iwl_check_bits(unsigned long field, unsigned long mask) |
260 | { | 149 | { |
261 | return ((field & mask) == mask) ? 1 : 0; | 150 | return ((field & mask) == mask) ? 1 : 0; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 59c8a716bd96..5f098747cf95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -55,13 +55,13 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
55 | 55 | ||
56 | switch (state) { | 56 | switch (state) { |
57 | case RFKILL_STATE_ON: | 57 | case RFKILL_STATE_ON: |
58 | priv->cfg->ops->lib->radio_kill_sw(priv, 0); | 58 | iwl_radio_kill_sw_enable_radio(priv); |
59 | /* if HW rf-kill is set dont allow ON state */ | 59 | /* if HW rf-kill is set dont allow ON state */ |
60 | if (iwl_is_rfkill(priv)) | 60 | if (iwl_is_rfkill(priv)) |
61 | err = -EBUSY; | 61 | err = -EBUSY; |
62 | break; | 62 | break; |
63 | case RFKILL_STATE_OFF: | 63 | case RFKILL_STATE_OFF: |
64 | priv->cfg->ops->lib->radio_kill_sw(priv, 1); | 64 | iwl_radio_kill_sw_disable_radio(priv); |
65 | if (!iwl_is_rfkill(priv)) | 65 | if (!iwl_is_rfkill(priv)) |
66 | err = -EBUSY; | 66 | err = -EBUSY; |
67 | break; | 67 | break; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h index a7f04b855403..b3c04dba45cf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.h | |||
@@ -33,7 +33,6 @@ struct iwl_priv; | |||
33 | #include <linux/rfkill.h> | 33 | #include <linux/rfkill.h> |
34 | #include <linux/input.h> | 34 | #include <linux/input.h> |
35 | 35 | ||
36 | |||
37 | #ifdef CONFIG_IWLWIFI_RFKILL | 36 | #ifdef CONFIG_IWLWIFI_RFKILL |
38 | struct iwl_rfkill_mngr { | 37 | struct iwl_rfkill_mngr { |
39 | struct rfkill *rfkill; | 38 | struct rfkill *rfkill; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index cc61c937320f..c24844802a88 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -451,7 +451,6 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
451 | struct iwl_rx_mem_buffer *rxb) | 451 | struct iwl_rx_mem_buffer *rxb) |
452 | 452 | ||
453 | { | 453 | { |
454 | #ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB | ||
455 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 454 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
456 | struct iwl4965_missed_beacon_notif *missed_beacon; | 455 | struct iwl4965_missed_beacon_notif *missed_beacon; |
457 | 456 | ||
@@ -465,6 +464,5 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, | |||
465 | if (!test_bit(STATUS_SCANNING, &priv->status)) | 464 | if (!test_bit(STATUS_SCANNING, &priv->status)) |
466 | iwl_init_sensitivity(priv); | 465 | iwl_init_sensitivity(priv); |
467 | } | 466 | } |
468 | #endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ | ||
469 | } | 467 | } |
470 | EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); | 468 | EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c new file mode 100644 index 000000000000..5ca181f7125d --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
@@ -0,0 +1,921 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * GPL LICENSE SUMMARY | ||
4 | * | ||
5 | * Copyright(c) 2008 Intel Corporation. All rights reserved. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of version 2 of the GNU General Public License as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
19 | * USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution | ||
22 | * in the file called LICENSE.GPL. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Tomas Winkler <tomas.winkler@intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | #include <net/mac80211.h> | ||
29 | #include <linux/etherdevice.h> | ||
30 | |||
31 | #include "iwl-eeprom.h" | ||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-core.h" | ||
34 | #include "iwl-sta.h" | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-helpers.h" | ||
37 | |||
38 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | ||
39 | * sending probe req. This should be set long enough to hear probe responses | ||
40 | * from more than one AP. */ | ||
41 | #define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
42 | #define IWL_ACTIVE_DWELL_TIME_52 (10) | ||
43 | |||
44 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
45 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
46 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
47 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
48 | * no other traffic). | ||
49 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
50 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
51 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ | ||
52 | |||
53 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | ||
54 | * Must be set longer than active dwell time. | ||
55 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ | ||
56 | #define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
57 | #define IWL_PASSIVE_DWELL_TIME_52 (10) | ||
58 | #define IWL_PASSIVE_DWELL_BASE (100) | ||
59 | #define IWL_CHANNEL_TUNE_TIME 5 | ||
60 | |||
61 | static int scan_tx_ant[3] = { | ||
62 | RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK | ||
63 | }; | ||
64 | |||
65 | static int iwl_is_empty_essid(const char *essid, int essid_len) | ||
66 | { | ||
67 | /* Single white space is for Linksys APs */ | ||
68 | if (essid_len == 1 && essid[0] == ' ') | ||
69 | return 1; | ||
70 | |||
71 | /* Otherwise, if the entire essid is 0, we assume it is hidden */ | ||
72 | while (essid_len) { | ||
73 | essid_len--; | ||
74 | if (essid[essid_len] != '\0') | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | const char *iwl_escape_essid(const char *essid, u8 essid_len) | ||
84 | { | ||
85 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | ||
86 | const char *s = essid; | ||
87 | char *d = escaped; | ||
88 | |||
89 | if (iwl_is_empty_essid(essid, essid_len)) { | ||
90 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | ||
91 | return escaped; | ||
92 | } | ||
93 | |||
94 | essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); | ||
95 | while (essid_len--) { | ||
96 | if (*s == '\0') { | ||
97 | *d++ = '\\'; | ||
98 | *d++ = '0'; | ||
99 | s++; | ||
100 | } else | ||
101 | *d++ = *s++; | ||
102 | } | ||
103 | *d = '\0'; | ||
104 | return escaped; | ||
105 | } | ||
106 | EXPORT_SYMBOL(iwl_escape_essid); | ||
107 | |||
108 | /** | ||
109 | * iwl_scan_cancel - Cancel any currently executing HW scan | ||
110 | * | ||
111 | * NOTE: priv->mutex is not required before calling this function | ||
112 | */ | ||
113 | int iwl_scan_cancel(struct iwl_priv *priv) | ||
114 | { | ||
115 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
116 | clear_bit(STATUS_SCANNING, &priv->status); | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
121 | if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
122 | IWL_DEBUG_SCAN("Queuing scan abort.\n"); | ||
123 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
124 | queue_work(priv->workqueue, &priv->abort_scan); | ||
125 | |||
126 | } else | ||
127 | IWL_DEBUG_SCAN("Scan abort already in progress.\n"); | ||
128 | |||
129 | return test_bit(STATUS_SCANNING, &priv->status); | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | EXPORT_SYMBOL(iwl_scan_cancel); | ||
135 | /** | ||
136 | * iwl_scan_cancel_timeout - Cancel any currently executing HW scan | ||
137 | * @ms: amount of time to wait (in milliseconds) for scan to abort | ||
138 | * | ||
139 | * NOTE: priv->mutex must be held before calling this function | ||
140 | */ | ||
141 | int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | ||
142 | { | ||
143 | unsigned long now = jiffies; | ||
144 | int ret; | ||
145 | |||
146 | ret = iwl_scan_cancel(priv); | ||
147 | if (ret && ms) { | ||
148 | mutex_unlock(&priv->mutex); | ||
149 | while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && | ||
150 | test_bit(STATUS_SCANNING, &priv->status)) | ||
151 | msleep(1); | ||
152 | mutex_lock(&priv->mutex); | ||
153 | |||
154 | return test_bit(STATUS_SCANNING, &priv->status); | ||
155 | } | ||
156 | |||
157 | return ret; | ||
158 | } | ||
159 | EXPORT_SYMBOL(iwl_scan_cancel_timeout); | ||
160 | |||
161 | static int iwl_send_scan_abort(struct iwl_priv *priv) | ||
162 | { | ||
163 | int ret = 0; | ||
164 | struct iwl_rx_packet *res; | ||
165 | struct iwl_host_cmd cmd = { | ||
166 | .id = REPLY_SCAN_ABORT_CMD, | ||
167 | .meta.flags = CMD_WANT_SKB, | ||
168 | }; | ||
169 | |||
170 | /* If there isn't a scan actively going on in the hardware | ||
171 | * then we are in between scan bands and not actually | ||
172 | * actively scanning, so don't send the abort command */ | ||
173 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
174 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | ret = iwl_send_cmd_sync(priv, &cmd); | ||
179 | if (ret) { | ||
180 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
181 | return ret; | ||
182 | } | ||
183 | |||
184 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | ||
185 | if (res->u.status != CAN_ABORT_STATUS) { | ||
186 | /* The scan abort will return 1 for success or | ||
187 | * 2 for "failure". A failure condition can be | ||
188 | * due to simply not being in an active scan which | ||
189 | * can occur if we send the scan abort before we | ||
190 | * the microcode has notified us that a scan is | ||
191 | * completed. */ | ||
192 | IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); | ||
193 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
194 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
195 | } | ||
196 | |||
197 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
198 | |||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | |||
203 | /* Service response to REPLY_SCAN_CMD (0x80) */ | ||
204 | static void iwl_rx_reply_scan(struct iwl_priv *priv, | ||
205 | struct iwl_rx_mem_buffer *rxb) | ||
206 | { | ||
207 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
208 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
209 | struct iwl_scanreq_notification *notif = | ||
210 | (struct iwl_scanreq_notification *)pkt->u.raw; | ||
211 | |||
212 | IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); | ||
213 | #endif | ||
214 | } | ||
215 | |||
216 | /* Service SCAN_START_NOTIFICATION (0x82) */ | ||
217 | static void iwl_rx_scan_start_notif(struct iwl_priv *priv, | ||
218 | struct iwl_rx_mem_buffer *rxb) | ||
219 | { | ||
220 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
221 | struct iwl_scanstart_notification *notif = | ||
222 | (struct iwl_scanstart_notification *)pkt->u.raw; | ||
223 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | ||
224 | IWL_DEBUG_SCAN("Scan start: " | ||
225 | "%d [802.11%s] " | ||
226 | "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", | ||
227 | notif->channel, | ||
228 | notif->band ? "bg" : "a", | ||
229 | notif->tsf_high, | ||
230 | notif->tsf_low, notif->status, notif->beacon_timer); | ||
231 | } | ||
232 | |||
233 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | ||
234 | static void iwl_rx_scan_results_notif(struct iwl_priv *priv, | ||
235 | struct iwl_rx_mem_buffer *rxb) | ||
236 | { | ||
237 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
238 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
239 | struct iwl_scanresults_notification *notif = | ||
240 | (struct iwl_scanresults_notification *)pkt->u.raw; | ||
241 | |||
242 | IWL_DEBUG_SCAN("Scan ch.res: " | ||
243 | "%d [802.11%s] " | ||
244 | "(TSF: 0x%08X:%08X) - %d " | ||
245 | "elapsed=%lu usec (%dms since last)\n", | ||
246 | notif->channel, | ||
247 | notif->band ? "bg" : "a", | ||
248 | le32_to_cpu(notif->tsf_high), | ||
249 | le32_to_cpu(notif->tsf_low), | ||
250 | le32_to_cpu(notif->statistics[0]), | ||
251 | le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, | ||
252 | jiffies_to_msecs(elapsed_jiffies | ||
253 | (priv->last_scan_jiffies, jiffies))); | ||
254 | #endif | ||
255 | |||
256 | priv->last_scan_jiffies = jiffies; | ||
257 | priv->next_scan_jiffies = 0; | ||
258 | } | ||
259 | |||
260 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | ||
261 | static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, | ||
262 | struct iwl_rx_mem_buffer *rxb) | ||
263 | { | ||
264 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
265 | struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | ||
266 | |||
267 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | ||
268 | scan_notif->scanned_channels, | ||
269 | scan_notif->tsf_low, | ||
270 | scan_notif->tsf_high, scan_notif->status); | ||
271 | |||
272 | /* The HW is no longer scanning */ | ||
273 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
274 | |||
275 | /* The scan completion notification came in, so kill that timer... */ | ||
276 | cancel_delayed_work(&priv->scan_check); | ||
277 | |||
278 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | ||
279 | (priv->scan_bands == 2) ? "2.4" : "5.2", | ||
280 | jiffies_to_msecs(elapsed_jiffies | ||
281 | (priv->scan_pass_start, jiffies))); | ||
282 | |||
283 | /* Remove this scanned band from the list | ||
284 | * of pending bands to scan */ | ||
285 | priv->scan_bands--; | ||
286 | |||
287 | /* If a request to abort was given, or the scan did not succeed | ||
288 | * then we reset the scan state machine and terminate, | ||
289 | * re-queuing another scan if one has been requested */ | ||
290 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
291 | IWL_DEBUG_INFO("Aborted scan completed.\n"); | ||
292 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
293 | } else { | ||
294 | /* If there are more bands on this scan pass reschedule */ | ||
295 | if (priv->scan_bands > 0) | ||
296 | goto reschedule; | ||
297 | } | ||
298 | |||
299 | priv->last_scan_jiffies = jiffies; | ||
300 | priv->next_scan_jiffies = 0; | ||
301 | IWL_DEBUG_INFO("Setting scan to off\n"); | ||
302 | |||
303 | clear_bit(STATUS_SCANNING, &priv->status); | ||
304 | |||
305 | IWL_DEBUG_INFO("Scan took %dms\n", | ||
306 | jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies))); | ||
307 | |||
308 | queue_work(priv->workqueue, &priv->scan_completed); | ||
309 | |||
310 | return; | ||
311 | |||
312 | reschedule: | ||
313 | priv->scan_pass_start = jiffies; | ||
314 | queue_work(priv->workqueue, &priv->request_scan); | ||
315 | } | ||
316 | |||
317 | void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) | ||
318 | { | ||
319 | /* scan handlers */ | ||
320 | priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan; | ||
321 | priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif; | ||
322 | priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = | ||
323 | iwl_rx_scan_results_notif; | ||
324 | priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = | ||
325 | iwl_rx_scan_complete_notif; | ||
326 | } | ||
327 | EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); | ||
328 | |||
329 | static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, | ||
330 | enum ieee80211_band band) | ||
331 | { | ||
332 | if (band == IEEE80211_BAND_5GHZ) | ||
333 | return IWL_ACTIVE_DWELL_TIME_52; | ||
334 | else | ||
335 | return IWL_ACTIVE_DWELL_TIME_24; | ||
336 | } | ||
337 | |||
338 | static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, | ||
339 | enum ieee80211_band band) | ||
340 | { | ||
341 | u16 active = iwl_get_active_dwell_time(priv, band); | ||
342 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? | ||
343 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | ||
344 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | ||
345 | |||
346 | if (iwl_is_associated(priv)) { | ||
347 | /* If we're associated, we clamp the maximum passive | ||
348 | * dwell time to be 98% of the beacon interval (minus | ||
349 | * 2 * channel tune time) */ | ||
350 | passive = priv->beacon_int; | ||
351 | if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) | ||
352 | passive = IWL_PASSIVE_DWELL_BASE; | ||
353 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
354 | } | ||
355 | |||
356 | if (passive <= active) | ||
357 | passive = active + 1; | ||
358 | |||
359 | return passive; | ||
360 | } | ||
361 | |||
362 | static int iwl_get_channels_for_scan(struct iwl_priv *priv, | ||
363 | enum ieee80211_band band, | ||
364 | u8 is_active, u8 direct_mask, | ||
365 | struct iwl_scan_channel *scan_ch) | ||
366 | { | ||
367 | const struct ieee80211_channel *channels = NULL; | ||
368 | const struct ieee80211_supported_band *sband; | ||
369 | const struct iwl_channel_info *ch_info; | ||
370 | u16 passive_dwell = 0; | ||
371 | u16 active_dwell = 0; | ||
372 | int added, i; | ||
373 | |||
374 | sband = iwl_get_hw_mode(priv, band); | ||
375 | if (!sband) | ||
376 | return 0; | ||
377 | |||
378 | channels = sband->channels; | ||
379 | |||
380 | active_dwell = iwl_get_active_dwell_time(priv, band); | ||
381 | passive_dwell = iwl_get_passive_dwell_time(priv, band); | ||
382 | |||
383 | for (i = 0, added = 0; i < sband->n_channels; i++) { | ||
384 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | ||
385 | continue; | ||
386 | |||
387 | scan_ch->channel = | ||
388 | ieee80211_frequency_to_channel(channels[i].center_freq); | ||
389 | |||
390 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); | ||
391 | if (!is_channel_valid(ch_info)) { | ||
392 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | ||
393 | scan_ch->channel); | ||
394 | continue; | ||
395 | } | ||
396 | |||
397 | if (!is_active || is_channel_passive(ch_info) || | ||
398 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) | ||
399 | scan_ch->type = 0; | ||
400 | else | ||
401 | scan_ch->type = 1; | ||
402 | |||
403 | if (scan_ch->type & 1) | ||
404 | scan_ch->type |= (direct_mask << 1); | ||
405 | |||
406 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
407 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
408 | |||
409 | /* Set txpower levels to defaults */ | ||
410 | scan_ch->dsp_atten = 110; | ||
411 | |||
412 | if (band == IEEE80211_BAND_5GHZ) | ||
413 | scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
414 | else { | ||
415 | scan_ch->tx_gain = ((1 << 5) | (5 << 3)); | ||
416 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
417 | * power level: | ||
418 | * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
419 | */ | ||
420 | } | ||
421 | |||
422 | IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", | ||
423 | scan_ch->channel, | ||
424 | (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", | ||
425 | (scan_ch->type & 1) ? | ||
426 | active_dwell : passive_dwell); | ||
427 | |||
428 | scan_ch++; | ||
429 | added++; | ||
430 | } | ||
431 | |||
432 | IWL_DEBUG_SCAN("total channels to scan %d \n", added); | ||
433 | return added; | ||
434 | } | ||
435 | |||
436 | void iwl_init_scan_params(struct iwl_priv *priv) | ||
437 | { | ||
438 | if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) | ||
439 | priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND; | ||
440 | if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) | ||
441 | priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND; | ||
442 | } | ||
443 | |||
444 | int iwl_scan_initiate(struct iwl_priv *priv) | ||
445 | { | ||
446 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | ||
447 | IWL_ERROR("APs don't scan.\n"); | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | if (!iwl_is_ready_rf(priv)) { | ||
452 | IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); | ||
453 | return -EIO; | ||
454 | } | ||
455 | |||
456 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
457 | IWL_DEBUG_SCAN("Scan already in progress.\n"); | ||
458 | return -EAGAIN; | ||
459 | } | ||
460 | |||
461 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
462 | IWL_DEBUG_SCAN("Scan request while abort pending. " | ||
463 | "Queuing.\n"); | ||
464 | return -EAGAIN; | ||
465 | } | ||
466 | |||
467 | IWL_DEBUG_INFO("Starting scan...\n"); | ||
468 | priv->scan_bands = 2; | ||
469 | set_bit(STATUS_SCANNING, &priv->status); | ||
470 | priv->scan_start = jiffies; | ||
471 | priv->scan_pass_start = priv->scan_start; | ||
472 | |||
473 | queue_work(priv->workqueue, &priv->request_scan); | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | EXPORT_SYMBOL(iwl_scan_initiate); | ||
478 | |||
479 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | ||
480 | |||
481 | static void iwl_bg_scan_check(struct work_struct *data) | ||
482 | { | ||
483 | struct iwl_priv *priv = | ||
484 | container_of(data, struct iwl_priv, scan_check.work); | ||
485 | |||
486 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
487 | return; | ||
488 | |||
489 | mutex_lock(&priv->mutex); | ||
490 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
491 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
492 | IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " | ||
493 | "adapter (%dms)\n", | ||
494 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | ||
495 | |||
496 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
497 | iwl_send_scan_abort(priv); | ||
498 | } | ||
499 | mutex_unlock(&priv->mutex); | ||
500 | } | ||
501 | /** | ||
502 | * iwl_supported_rate_to_ie - fill in the supported rate in IE field | ||
503 | * | ||
504 | * return : set the bit for each supported rate insert in ie | ||
505 | */ | ||
506 | static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, | ||
507 | u16 basic_rate, int *left) | ||
508 | { | ||
509 | u16 ret_rates = 0, bit; | ||
510 | int i; | ||
511 | u8 *cnt = ie; | ||
512 | u8 *rates = ie + 1; | ||
513 | |||
514 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | ||
515 | if (bit & supported_rate) { | ||
516 | ret_rates |= bit; | ||
517 | rates[*cnt] = iwl_rates[i].ieee | | ||
518 | ((bit & basic_rate) ? 0x80 : 0x00); | ||
519 | (*cnt)++; | ||
520 | (*left)--; | ||
521 | if ((*left <= 0) || | ||
522 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
523 | break; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | return ret_rates; | ||
528 | } | ||
529 | |||
530 | |||
531 | static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | ||
532 | u8 *pos, int *left) | ||
533 | { | ||
534 | struct ieee80211_ht_cap *ht_cap; | ||
535 | |||
536 | if (!sband || !sband->ht_info.ht_supported) | ||
537 | return; | ||
538 | |||
539 | if (*left < sizeof(struct ieee80211_ht_cap)) | ||
540 | return; | ||
541 | |||
542 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
543 | ht_cap = (struct ieee80211_ht_cap *) pos; | ||
544 | |||
545 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); | ||
546 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
547 | ht_cap->ampdu_params_info = | ||
548 | (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
549 | ((sband->ht_info.ampdu_density << 2) & | ||
550 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
551 | *left -= sizeof(struct ieee80211_ht_cap); | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * iwl_fill_probe_req - fill in all required fields and IE for probe request | ||
556 | */ | ||
557 | |||
558 | static u16 iwl_fill_probe_req(struct iwl_priv *priv, | ||
559 | enum ieee80211_band band, | ||
560 | struct ieee80211_mgmt *frame, | ||
561 | int left) | ||
562 | { | ||
563 | int len = 0; | ||
564 | u8 *pos = NULL; | ||
565 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | ||
566 | const struct ieee80211_supported_band *sband = | ||
567 | iwl_get_hw_mode(priv, band); | ||
568 | |||
569 | |||
570 | /* Make sure there is enough space for the probe request, | ||
571 | * two mandatory IEs and the data */ | ||
572 | left -= 24; | ||
573 | if (left < 0) | ||
574 | return 0; | ||
575 | |||
576 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
577 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
578 | memcpy(frame->sa, priv->mac_addr, ETH_ALEN); | ||
579 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
580 | frame->seq_ctrl = 0; | ||
581 | |||
582 | len += 24; | ||
583 | |||
584 | /* ...next IE... */ | ||
585 | pos = &frame->u.probe_req.variable[0]; | ||
586 | |||
587 | /* fill in our indirect SSID IE */ | ||
588 | left -= 2; | ||
589 | if (left < 0) | ||
590 | return 0; | ||
591 | *pos++ = WLAN_EID_SSID; | ||
592 | *pos++ = 0; | ||
593 | |||
594 | len += 2; | ||
595 | |||
596 | /* fill in supported rate */ | ||
597 | left -= 2; | ||
598 | if (left < 0) | ||
599 | return 0; | ||
600 | |||
601 | *pos++ = WLAN_EID_SUPP_RATES; | ||
602 | *pos = 0; | ||
603 | |||
604 | /* exclude 60M rate */ | ||
605 | active_rates = priv->rates_mask; | ||
606 | active_rates &= ~IWL_RATE_60M_MASK; | ||
607 | |||
608 | active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; | ||
609 | |||
610 | cck_rates = IWL_CCK_RATES_MASK & active_rates; | ||
611 | ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, | ||
612 | active_rate_basic, &left); | ||
613 | active_rates &= ~ret_rates; | ||
614 | |||
615 | ret_rates = iwl_supported_rate_to_ie(pos, active_rates, | ||
616 | active_rate_basic, &left); | ||
617 | active_rates &= ~ret_rates; | ||
618 | |||
619 | len += 2 + *pos; | ||
620 | pos += (*pos) + 1; | ||
621 | |||
622 | if (active_rates == 0) | ||
623 | goto fill_end; | ||
624 | |||
625 | /* fill in supported extended rate */ | ||
626 | /* ...next IE... */ | ||
627 | left -= 2; | ||
628 | if (left < 0) | ||
629 | return 0; | ||
630 | /* ... fill it in... */ | ||
631 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
632 | *pos = 0; | ||
633 | iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left); | ||
634 | if (*pos > 0) { | ||
635 | len += 2 + *pos; | ||
636 | pos += (*pos) + 1; | ||
637 | } else { | ||
638 | pos--; | ||
639 | } | ||
640 | |||
641 | fill_end: | ||
642 | |||
643 | left -= 2; | ||
644 | if (left < 0) | ||
645 | return 0; | ||
646 | |||
647 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
648 | *pos = 0; | ||
649 | iwl_ht_cap_to_ie(sband, pos, &left); | ||
650 | if (*pos > 0) | ||
651 | len += 2 + *pos; | ||
652 | |||
653 | return (u16)len; | ||
654 | } | ||
655 | |||
656 | static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band) | ||
657 | { | ||
658 | int i, ind; | ||
659 | |||
660 | ind = priv->scan_tx_ant[band]; | ||
661 | for (i = 0; i < priv->hw_params.tx_chains_num; i++) { | ||
662 | ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1; | ||
663 | if (priv->hw_params.valid_tx_ant & (1 << ind)) { | ||
664 | priv->scan_tx_ant[band] = ind; | ||
665 | break; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | return scan_tx_ant[ind]; | ||
670 | } | ||
671 | |||
672 | |||
673 | static void iwl_bg_request_scan(struct work_struct *data) | ||
674 | { | ||
675 | struct iwl_priv *priv = | ||
676 | container_of(data, struct iwl_priv, request_scan); | ||
677 | struct iwl_host_cmd cmd = { | ||
678 | .id = REPLY_SCAN_CMD, | ||
679 | .len = sizeof(struct iwl_scan_cmd), | ||
680 | .meta.flags = CMD_SIZE_HUGE, | ||
681 | }; | ||
682 | struct iwl_scan_cmd *scan; | ||
683 | struct ieee80211_conf *conf = NULL; | ||
684 | int ret = 0; | ||
685 | u32 tx_ant; | ||
686 | u16 cmd_len; | ||
687 | enum ieee80211_band band; | ||
688 | u8 direct_mask; | ||
689 | u8 rx_chain = 0x7; /* bitmap: ABC chains */ | ||
690 | |||
691 | conf = ieee80211_get_hw_conf(priv->hw); | ||
692 | |||
693 | mutex_lock(&priv->mutex); | ||
694 | |||
695 | if (!iwl_is_ready(priv)) { | ||
696 | IWL_WARNING("request scan called when driver not ready.\n"); | ||
697 | goto done; | ||
698 | } | ||
699 | |||
700 | /* Make sure the scan wasn't cancelled before this queued work | ||
701 | * was given the chance to run... */ | ||
702 | if (!test_bit(STATUS_SCANNING, &priv->status)) | ||
703 | goto done; | ||
704 | |||
705 | /* This should never be called or scheduled if there is currently | ||
706 | * a scan active in the hardware. */ | ||
707 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
708 | IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. " | ||
709 | "Ignoring second request.\n"); | ||
710 | ret = -EIO; | ||
711 | goto done; | ||
712 | } | ||
713 | |||
714 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
715 | IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n"); | ||
716 | goto done; | ||
717 | } | ||
718 | |||
719 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
720 | IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | ||
721 | goto done; | ||
722 | } | ||
723 | |||
724 | if (iwl_is_rfkill(priv)) { | ||
725 | IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | ||
726 | goto done; | ||
727 | } | ||
728 | |||
729 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
730 | IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n"); | ||
731 | goto done; | ||
732 | } | ||
733 | |||
734 | if (!priv->scan_bands) { | ||
735 | IWL_DEBUG_HC("Aborting scan due to no requested bands\n"); | ||
736 | goto done; | ||
737 | } | ||
738 | |||
739 | if (!priv->scan) { | ||
740 | priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + | ||
741 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | ||
742 | if (!priv->scan) { | ||
743 | ret = -ENOMEM; | ||
744 | goto done; | ||
745 | } | ||
746 | } | ||
747 | scan = priv->scan; | ||
748 | memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); | ||
749 | |||
750 | scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; | ||
751 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | ||
752 | |||
753 | if (iwl_is_associated(priv)) { | ||
754 | u16 interval = 0; | ||
755 | u32 extra; | ||
756 | u32 suspend_time = 100; | ||
757 | u32 scan_suspend_time = 100; | ||
758 | unsigned long flags; | ||
759 | |||
760 | IWL_DEBUG_INFO("Scanning while associated...\n"); | ||
761 | |||
762 | spin_lock_irqsave(&priv->lock, flags); | ||
763 | interval = priv->beacon_int; | ||
764 | spin_unlock_irqrestore(&priv->lock, flags); | ||
765 | |||
766 | scan->suspend_time = 0; | ||
767 | scan->max_out_time = cpu_to_le32(200 * 1024); | ||
768 | if (!interval) | ||
769 | interval = suspend_time; | ||
770 | |||
771 | extra = (suspend_time / interval) << 22; | ||
772 | scan_suspend_time = (extra | | ||
773 | ((suspend_time % interval) * 1024)); | ||
774 | scan->suspend_time = cpu_to_le32(scan_suspend_time); | ||
775 | IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n", | ||
776 | scan_suspend_time, interval); | ||
777 | } | ||
778 | |||
779 | /* We should add the ability for user to lock to PASSIVE ONLY */ | ||
780 | if (priv->one_direct_scan) { | ||
781 | IWL_DEBUG_SCAN("Start direct scan for '%s'\n", | ||
782 | iwl_escape_essid(priv->direct_ssid, | ||
783 | priv->direct_ssid_len)); | ||
784 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
785 | scan->direct_scan[0].len = priv->direct_ssid_len; | ||
786 | memcpy(scan->direct_scan[0].ssid, | ||
787 | priv->direct_ssid, priv->direct_ssid_len); | ||
788 | direct_mask = 1; | ||
789 | } else if (!iwl_is_associated(priv) && priv->essid_len) { | ||
790 | IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n", | ||
791 | iwl_escape_essid(priv->essid, priv->essid_len)); | ||
792 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
793 | scan->direct_scan[0].len = priv->essid_len; | ||
794 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | ||
795 | direct_mask = 1; | ||
796 | } else { | ||
797 | IWL_DEBUG_SCAN("Start indirect scan.\n"); | ||
798 | direct_mask = 0; | ||
799 | } | ||
800 | |||
801 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | ||
802 | scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; | ||
803 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
804 | |||
805 | |||
806 | switch (priv->scan_bands) { | ||
807 | case 2: | ||
808 | band = IEEE80211_BAND_2GHZ; | ||
809 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | ||
810 | tx_ant = iwl_scan_tx_ant(priv, band); | ||
811 | if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) | ||
812 | scan->tx_cmd.rate_n_flags = | ||
813 | iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | ||
814 | tx_ant); | ||
815 | else | ||
816 | scan->tx_cmd.rate_n_flags = | ||
817 | iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | ||
818 | tx_ant | | ||
819 | RATE_MCS_CCK_MSK); | ||
820 | scan->good_CRC_th = 0; | ||
821 | break; | ||
822 | |||
823 | case 1: | ||
824 | band = IEEE80211_BAND_5GHZ; | ||
825 | tx_ant = iwl_scan_tx_ant(priv, band); | ||
826 | scan->tx_cmd.rate_n_flags = | ||
827 | iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | ||
828 | tx_ant); | ||
829 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | ||
830 | |||
831 | /* Force use of chains B and C (0x6) for scan Rx for 4965 | ||
832 | * Avoid A (0x1) because of its off-channel reception on A-band. | ||
833 | * MIMO is not used here, but value is required */ | ||
834 | if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) | ||
835 | rx_chain = 0x6; | ||
836 | |||
837 | break; | ||
838 | default: | ||
839 | IWL_WARNING("Invalid scan band count\n"); | ||
840 | goto done; | ||
841 | } | ||
842 | |||
843 | scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | | ||
844 | cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | | ||
845 | (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | | ||
846 | (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); | ||
847 | |||
848 | cmd_len = iwl_fill_probe_req(priv, band, | ||
849 | (struct ieee80211_mgmt *)scan->data, | ||
850 | IWL_MAX_SCAN_SIZE - sizeof(*scan)); | ||
851 | |||
852 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | ||
853 | |||
854 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | ||
855 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | ||
856 | |||
857 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | | ||
858 | RXON_FILTER_BCON_AWARE_MSK); | ||
859 | |||
860 | if (direct_mask) | ||
861 | scan->channel_count = | ||
862 | iwl_get_channels_for_scan(priv, band, 1, /* active */ | ||
863 | direct_mask, | ||
864 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
865 | else | ||
866 | scan->channel_count = | ||
867 | iwl_get_channels_for_scan(priv, band, 0, /* passive */ | ||
868 | direct_mask, | ||
869 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
870 | if (scan->channel_count == 0) { | ||
871 | IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); | ||
872 | goto done; | ||
873 | } | ||
874 | |||
875 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | ||
876 | scan->channel_count * sizeof(struct iwl_scan_channel); | ||
877 | cmd.data = scan; | ||
878 | scan->len = cpu_to_le16(cmd.len); | ||
879 | |||
880 | set_bit(STATUS_SCAN_HW, &priv->status); | ||
881 | ret = iwl_send_cmd_sync(priv, &cmd); | ||
882 | if (ret) | ||
883 | goto done; | ||
884 | |||
885 | queue_delayed_work(priv->workqueue, &priv->scan_check, | ||
886 | IWL_SCAN_CHECK_WATCHDOG); | ||
887 | |||
888 | mutex_unlock(&priv->mutex); | ||
889 | return; | ||
890 | |||
891 | done: | ||
892 | /* inform mac80211 scan aborted */ | ||
893 | queue_work(priv->workqueue, &priv->scan_completed); | ||
894 | mutex_unlock(&priv->mutex); | ||
895 | } | ||
896 | |||
897 | static void iwl_bg_abort_scan(struct work_struct *work) | ||
898 | { | ||
899 | struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); | ||
900 | |||
901 | if (!iwl_is_ready(priv)) | ||
902 | return; | ||
903 | |||
904 | mutex_lock(&priv->mutex); | ||
905 | |||
906 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
907 | iwl_send_scan_abort(priv); | ||
908 | |||
909 | mutex_unlock(&priv->mutex); | ||
910 | } | ||
911 | |||
912 | void iwl_setup_scan_deferred_work(struct iwl_priv *priv) | ||
913 | { | ||
914 | /* FIXME: move here when resolved PENDING | ||
915 | * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */ | ||
916 | INIT_WORK(&priv->request_scan, iwl_bg_request_scan); | ||
917 | INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); | ||
918 | INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); | ||
919 | } | ||
920 | EXPORT_SYMBOL(iwl_setup_scan_deferred_work); | ||
921 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 983f10760fb0..f874e7d7b225 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -30,11 +30,9 @@ | |||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | #include <linux/etherdevice.h> | 31 | #include <linux/etherdevice.h> |
32 | 32 | ||
33 | #include "iwl-eeprom.h" | ||
34 | #include "iwl-dev.h" | 33 | #include "iwl-dev.h" |
35 | #include "iwl-core.h" | 34 | #include "iwl-core.h" |
36 | #include "iwl-sta.h" | 35 | #include "iwl-sta.h" |
37 | #include "iwl-io.h" | ||
38 | #include "iwl-helpers.h" | 36 | #include "iwl-helpers.h" |
39 | 37 | ||
40 | 38 | ||
@@ -74,6 +72,17 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) | |||
74 | } | 72 | } |
75 | EXPORT_SYMBOL(iwl_find_station); | 73 | EXPORT_SYMBOL(iwl_find_station); |
76 | 74 | ||
75 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | ||
76 | { | ||
77 | if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { | ||
78 | return IWL_AP_ID; | ||
79 | } else { | ||
80 | u8 *da = ieee80211_get_DA(hdr); | ||
81 | return iwl_find_station(priv, da); | ||
82 | } | ||
83 | } | ||
84 | EXPORT_SYMBOL(iwl_get_ra_sta_id); | ||
85 | |||
77 | static int iwl_add_sta_callback(struct iwl_priv *priv, | 86 | static int iwl_add_sta_callback(struct iwl_priv *priv, |
78 | struct iwl_cmd *cmd, struct sk_buff *skb) | 87 | struct iwl_cmd *cmd, struct sk_buff *skb) |
79 | { | 88 | { |
@@ -105,8 +114,6 @@ static int iwl_add_sta_callback(struct iwl_priv *priv, | |||
105 | return 1; | 114 | return 1; |
106 | } | 115 | } |
107 | 116 | ||
108 | |||
109 | |||
110 | int iwl_send_add_sta(struct iwl_priv *priv, | 117 | int iwl_send_add_sta(struct iwl_priv *priv, |
111 | struct iwl_addsta_cmd *sta, u8 flags) | 118 | struct iwl_addsta_cmd *sta, u8 flags) |
112 | { | 119 | { |
@@ -156,8 +163,6 @@ int iwl_send_add_sta(struct iwl_priv *priv, | |||
156 | } | 163 | } |
157 | EXPORT_SYMBOL(iwl_send_add_sta); | 164 | EXPORT_SYMBOL(iwl_send_add_sta); |
158 | 165 | ||
159 | #ifdef CONFIG_IWL4965_HT | ||
160 | |||
161 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | 166 | static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, |
162 | struct ieee80211_ht_info *sta_ht_inf) | 167 | struct ieee80211_ht_info *sta_ht_inf) |
163 | { | 168 | { |
@@ -202,12 +207,6 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | |||
202 | done: | 207 | done: |
203 | return; | 208 | return; |
204 | } | 209 | } |
205 | #else | ||
206 | static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, | ||
207 | struct ieee80211_ht_info *sta_ht_info) | ||
208 | { | ||
209 | } | ||
210 | #endif | ||
211 | 210 | ||
212 | /** | 211 | /** |
213 | * iwl_add_station_flags - Add station to tables in driver and device | 212 | * iwl_add_station_flags - Add station to tables in driver and device |
@@ -280,7 +279,6 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | |||
280 | } | 279 | } |
281 | EXPORT_SYMBOL(iwl_add_station_flags); | 280 | EXPORT_SYMBOL(iwl_add_station_flags); |
282 | 281 | ||
283 | |||
284 | static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | 282 | static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) |
285 | { | 283 | { |
286 | unsigned long flags; | 284 | unsigned long flags; |
@@ -384,9 +382,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | |||
384 | 382 | ||
385 | return ret; | 383 | return ret; |
386 | } | 384 | } |
385 | |||
387 | /** | 386 | /** |
388 | * iwl_remove_station - Remove driver's knowledge of station. | 387 | * iwl_remove_station - Remove driver's knowledge of station. |
389 | * | ||
390 | */ | 388 | */ |
391 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 389 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) |
392 | { | 390 | { |
@@ -426,7 +424,7 @@ out: | |||
426 | return 0; | 424 | return 0; |
427 | } | 425 | } |
428 | EXPORT_SYMBOL(iwl_remove_station); | 426 | EXPORT_SYMBOL(iwl_remove_station); |
429 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | 427 | static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) |
430 | { | 428 | { |
431 | int i; | 429 | int i; |
432 | 430 | ||
@@ -496,6 +494,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, | |||
496 | priv->default_wep_key--; | 494 | priv->default_wep_key--; |
497 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); | 495 | memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); |
498 | ret = iwl_send_static_wepkey_cmd(priv, 1); | 496 | ret = iwl_send_static_wepkey_cmd(priv, 1); |
497 | IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n", | ||
498 | keyconf->keyidx, ret); | ||
499 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 499 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
500 | 500 | ||
501 | return ret; | 501 | return ret; |
@@ -508,6 +508,12 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
508 | int ret; | 508 | int ret; |
509 | unsigned long flags; | 509 | unsigned long flags; |
510 | 510 | ||
511 | if (keyconf->keylen != WEP_KEY_LEN_128 && | ||
512 | keyconf->keylen != WEP_KEY_LEN_64) { | ||
513 | IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen); | ||
514 | return -EINVAL; | ||
515 | } | ||
516 | |||
511 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; | 517 | keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; |
512 | keyconf->hw_key_idx = HW_KEY_DEFAULT; | 518 | keyconf->hw_key_idx = HW_KEY_DEFAULT; |
513 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; | 519 | priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; |
@@ -524,6 +530,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, | |||
524 | keyconf->keylen); | 530 | keyconf->keylen); |
525 | 531 | ||
526 | ret = iwl_send_static_wepkey_cmd(priv, 0); | 532 | ret = iwl_send_static_wepkey_cmd(priv, 0); |
533 | IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", | ||
534 | keyconf->keylen, keyconf->keyidx, ret); | ||
527 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 535 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
528 | 536 | ||
529 | return ret; | 537 | return ret; |
@@ -670,6 +678,9 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
670 | key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); | 678 | key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); |
671 | keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; | 679 | keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; |
672 | 680 | ||
681 | IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n", | ||
682 | keyconf->keyidx, sta_id); | ||
683 | |||
673 | if (keyconf->keyidx != keyidx) { | 684 | if (keyconf->keyidx != keyidx) { |
674 | /* We need to remove a key with index different that the one | 685 | /* We need to remove a key with index different that the one |
675 | * in the uCode. This means that the key we need to remove has | 686 | * in the uCode. This means that the key we need to remove has |
@@ -694,7 +705,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
694 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; | 705 | priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; |
695 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; | 706 | priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; |
696 | 707 | ||
697 | IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); | ||
698 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); | 708 | ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); |
699 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 709 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
700 | return ret; | 710 | return ret; |
@@ -724,6 +734,10 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
724 | ret = -EINVAL; | 734 | ret = -EINVAL; |
725 | } | 735 | } |
726 | 736 | ||
737 | IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", | ||
738 | keyconf->alg, keyconf->keylen, keyconf->keyidx, | ||
739 | sta_id, ret); | ||
740 | |||
727 | return ret; | 741 | return ret; |
728 | } | 742 | } |
729 | EXPORT_SYMBOL(iwl_set_dynamic_key); | 743 | EXPORT_SYMBOL(iwl_set_dynamic_key); |
@@ -816,7 +830,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
816 | rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/ | 830 | rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/ |
817 | 831 | ||
818 | link_cmd.rs_table[i].rate_n_flags = | 832 | link_cmd.rs_table[i].rate_n_flags = |
819 | iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); | 833 | iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); |
820 | r = iwl4965_get_prev_ieee_rate(r); | 834 | r = iwl4965_get_prev_ieee_rate(r); |
821 | } | 835 | } |
822 | 836 | ||
@@ -842,7 +856,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
842 | u8 sta_id; | 856 | u8 sta_id; |
843 | 857 | ||
844 | /* Add station to device's station table */ | 858 | /* Add station to device's station table */ |
845 | #ifdef CONFIG_IWL4965_HT | ||
846 | struct ieee80211_conf *conf = &priv->hw->conf; | 859 | struct ieee80211_conf *conf = &priv->hw->conf; |
847 | struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; | 860 | struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; |
848 | 861 | ||
@@ -852,7 +865,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
852 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | 865 | sta_id = iwl_add_station_flags(priv, addr, is_ap, |
853 | 0, cur_ht_config); | 866 | 0, cur_ht_config); |
854 | else | 867 | else |
855 | #endif /* CONFIG_IWL4965_HT */ | ||
856 | sta_id = iwl_add_station_flags(priv, addr, is_ap, | 868 | sta_id = iwl_add_station_flags(priv, addr, is_ap, |
857 | 0, NULL); | 869 | 0, NULL); |
858 | 870 | ||
@@ -863,7 +875,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
863 | } | 875 | } |
864 | EXPORT_SYMBOL(iwl_rxon_add_station); | 876 | EXPORT_SYMBOL(iwl_rxon_add_station); |
865 | 877 | ||
866 | |||
867 | /** | 878 | /** |
868 | * iwl_get_sta_id - Find station's index within station table | 879 | * iwl_get_sta_id - Find station's index within station table |
869 | * | 880 | * |
@@ -921,7 +932,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) | |||
921 | } | 932 | } |
922 | EXPORT_SYMBOL(iwl_get_sta_id); | 933 | EXPORT_SYMBOL(iwl_get_sta_id); |
923 | 934 | ||
924 | |||
925 | /** | 935 | /** |
926 | * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table | 936 | * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table |
927 | */ | 937 | */ |
@@ -940,4 +950,3 @@ void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid) | |||
940 | } | 950 | } |
941 | EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx); | 951 | EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx); |
942 | 952 | ||
943 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 3d55716f5301..b6bb209fdd58 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -32,18 +32,24 @@ | |||
32 | #define HW_KEY_DYNAMIC 0 | 32 | #define HW_KEY_DYNAMIC 0 |
33 | #define HW_KEY_DEFAULT 1 | 33 | #define HW_KEY_DEFAULT 1 |
34 | 34 | ||
35 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); | 35 | /** |
36 | * iwl_find_station - Find station id for a given BSSID | ||
37 | * @bssid: MAC address of station ID to find | ||
38 | */ | ||
39 | u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid); | ||
40 | |||
36 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); | 41 | int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); |
37 | int iwl_remove_default_wep_key(struct iwl_priv *priv, | 42 | int iwl_remove_default_wep_key(struct iwl_priv *priv, |
38 | struct ieee80211_key_conf *key); | 43 | struct ieee80211_key_conf *key); |
39 | int iwl_set_default_wep_key(struct iwl_priv *priv, | 44 | int iwl_set_default_wep_key(struct iwl_priv *priv, |
40 | struct ieee80211_key_conf *key); | 45 | struct ieee80211_key_conf *key); |
41 | int iwl_set_dynamic_key(struct iwl_priv *priv, | 46 | int iwl_set_dynamic_key(struct iwl_priv *priv, |
42 | struct ieee80211_key_conf *key, u8 sta_id); | 47 | struct ieee80211_key_conf *key, u8 sta_id); |
43 | int iwl_remove_dynamic_key(struct iwl_priv *priv, | 48 | int iwl_remove_dynamic_key(struct iwl_priv *priv, |
44 | struct ieee80211_key_conf *key, u8 sta_id); | 49 | struct ieee80211_key_conf *key, u8 sta_id); |
45 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 50 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); |
46 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 51 | u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); |
47 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 52 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
48 | void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid); | 53 | void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid); |
54 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | ||
49 | #endif /* __iwl_sta_h__ */ | 55 | #endif /* __iwl_sta_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index cfe6f4b233dd..7296e2846ec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -36,8 +36,6 @@ | |||
36 | #include "iwl-io.h" | 36 | #include "iwl-io.h" |
37 | #include "iwl-helpers.h" | 37 | #include "iwl-helpers.h" |
38 | 38 | ||
39 | #ifdef CONFIG_IWL4965_HT | ||
40 | |||
41 | static const u16 default_tid_to_tx_fifo[] = { | 39 | static const u16 default_tid_to_tx_fifo[] = { |
42 | IWL_TX_FIFO_AC1, | 40 | IWL_TX_FIFO_AC1, |
43 | IWL_TX_FIFO_AC0, | 41 | IWL_TX_FIFO_AC0, |
@@ -58,9 +56,6 @@ static const u16 default_tid_to_tx_fifo[] = { | |||
58 | IWL_TX_FIFO_AC3 | 56 | IWL_TX_FIFO_AC3 |
59 | }; | 57 | }; |
60 | 58 | ||
61 | #endif /*CONFIG_IWL4965_HT */ | ||
62 | |||
63 | |||
64 | 59 | ||
65 | /** | 60 | /** |
66 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | 61 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] |
@@ -574,15 +569,15 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
574 | struct ieee80211_hdr *hdr, | 569 | struct ieee80211_hdr *hdr, |
575 | int is_unicast, u8 std_id) | 570 | int is_unicast, u8 std_id) |
576 | { | 571 | { |
577 | u16 fc = le16_to_cpu(hdr->frame_control); | 572 | __le16 fc = hdr->frame_control; |
578 | __le32 tx_flags = tx_cmd->tx_flags; | 573 | __le32 tx_flags = tx_cmd->tx_flags; |
579 | 574 | ||
580 | tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 575 | tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
581 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 576 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
582 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 577 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
583 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) | 578 | if (ieee80211_is_mgmt(fc)) |
584 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 579 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
585 | if (ieee80211_is_probe_response(fc) && | 580 | if (ieee80211_is_probe_resp(fc) && |
586 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) | 581 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) |
587 | tx_flags |= TX_CMD_FLG_TSF_MSK; | 582 | tx_flags |= TX_CMD_FLG_TSF_MSK; |
588 | } else { | 583 | } else { |
@@ -590,16 +585,16 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
590 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 585 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
591 | } | 586 | } |
592 | 587 | ||
593 | if (ieee80211_is_back_request(fc)) | 588 | if (ieee80211_is_back_req(fc)) |
594 | tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; | 589 | tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; |
595 | 590 | ||
596 | 591 | ||
597 | tx_cmd->sta_id = std_id; | 592 | tx_cmd->sta_id = std_id; |
598 | if (ieee80211_get_morefrag(hdr)) | 593 | if (ieee80211_has_morefrags(fc)) |
599 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 594 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
600 | 595 | ||
601 | if (ieee80211_is_qos_data(fc)) { | 596 | if (ieee80211_is_data_qos(fc)) { |
602 | u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); | 597 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
603 | tx_cmd->tid_tspec = qc[0] & 0xf; | 598 | tx_cmd->tid_tspec = qc[0] & 0xf; |
604 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | 599 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; |
605 | } else { | 600 | } else { |
@@ -618,9 +613,8 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
618 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | 613 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; |
619 | 614 | ||
620 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | 615 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); |
621 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 616 | if (ieee80211_is_mgmt(fc)) { |
622 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || | 617 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) |
623 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) | ||
624 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); | 618 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); |
625 | else | 619 | else |
626 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); | 620 | tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); |
@@ -639,7 +633,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
639 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | 633 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, |
640 | struct iwl_tx_cmd *tx_cmd, | 634 | struct iwl_tx_cmd *tx_cmd, |
641 | struct ieee80211_tx_info *info, | 635 | struct ieee80211_tx_info *info, |
642 | u16 fc, int sta_id, | 636 | __le16 fc, int sta_id, |
643 | int is_hcca) | 637 | int is_hcca) |
644 | { | 638 | { |
645 | u8 rts_retry_limit = 0; | 639 | u8 rts_retry_limit = 0; |
@@ -660,7 +654,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
660 | rate_flags |= RATE_MCS_CCK_MSK; | 654 | rate_flags |= RATE_MCS_CCK_MSK; |
661 | 655 | ||
662 | 656 | ||
663 | if (ieee80211_is_probe_response(fc)) { | 657 | if (ieee80211_is_probe_resp(fc)) { |
664 | data_retry_limit = 3; | 658 | data_retry_limit = 3; |
665 | if (data_retry_limit < rts_retry_limit) | 659 | if (data_retry_limit < rts_retry_limit) |
666 | rts_retry_limit = data_retry_limit; | 660 | rts_retry_limit = data_retry_limit; |
@@ -675,11 +669,11 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
675 | tx_cmd->initial_rate_index = 0; | 669 | tx_cmd->initial_rate_index = 0; |
676 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; | 670 | tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; |
677 | } else { | 671 | } else { |
678 | switch (fc & IEEE80211_FCTL_STYPE) { | 672 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { |
679 | case IEEE80211_STYPE_AUTH: | 673 | case cpu_to_le16(IEEE80211_STYPE_AUTH): |
680 | case IEEE80211_STYPE_DEAUTH: | 674 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
681 | case IEEE80211_STYPE_ASSOC_REQ: | 675 | case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): |
682 | case IEEE80211_STYPE_REASSOC_REQ: | 676 | case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): |
683 | if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { | 677 | if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { |
684 | tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 678 | tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
685 | tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; | 679 | tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; |
@@ -701,7 +695,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
701 | 695 | ||
702 | tx_cmd->rts_retry_limit = rts_retry_limit; | 696 | tx_cmd->rts_retry_limit = rts_retry_limit; |
703 | tx_cmd->data_retry_limit = data_retry_limit; | 697 | tx_cmd->data_retry_limit = data_retry_limit; |
704 | tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); | 698 | tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags); |
705 | } | 699 | } |
706 | 700 | ||
707 | static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | 701 | static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, |
@@ -776,7 +770,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
776 | u16 seq_number = 0; | 770 | u16 seq_number = 0; |
777 | u8 id, hdr_len, unicast; | 771 | u8 id, hdr_len, unicast; |
778 | u8 sta_id; | 772 | u8 sta_id; |
779 | u16 fc; | 773 | __le16 fc; |
780 | u8 wait_write_ptr = 0; | 774 | u8 wait_write_ptr = 0; |
781 | u8 tid = 0; | 775 | u8 tid = 0; |
782 | u8 *qc = NULL; | 776 | u8 *qc = NULL; |
@@ -803,19 +797,19 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
803 | unicast = !is_multicast_ether_addr(hdr->addr1); | 797 | unicast = !is_multicast_ether_addr(hdr->addr1); |
804 | id = 0; | 798 | id = 0; |
805 | 799 | ||
806 | fc = le16_to_cpu(hdr->frame_control); | 800 | fc = hdr->frame_control; |
807 | 801 | ||
808 | #ifdef CONFIG_IWLWIFI_DEBUG | 802 | #ifdef CONFIG_IWLWIFI_DEBUG |
809 | if (ieee80211_is_auth(fc)) | 803 | if (ieee80211_is_auth(fc)) |
810 | IWL_DEBUG_TX("Sending AUTH frame\n"); | 804 | IWL_DEBUG_TX("Sending AUTH frame\n"); |
811 | else if (ieee80211_is_assoc_request(fc)) | 805 | else if (ieee80211_is_assoc_req(fc)) |
812 | IWL_DEBUG_TX("Sending ASSOC frame\n"); | 806 | IWL_DEBUG_TX("Sending ASSOC frame\n"); |
813 | else if (ieee80211_is_reassoc_request(fc)) | 807 | else if (ieee80211_is_reassoc_req(fc)) |
814 | IWL_DEBUG_TX("Sending REASSOC frame\n"); | 808 | IWL_DEBUG_TX("Sending REASSOC frame\n"); |
815 | #endif | 809 | #endif |
816 | 810 | ||
817 | /* drop all data frame if we are not associated */ | 811 | /* drop all data frame if we are not associated */ |
818 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 812 | if (ieee80211_is_data(fc) && |
819 | (!iwl_is_associated(priv) || | 813 | (!iwl_is_associated(priv) || |
820 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || | 814 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || |
821 | !priv->assoc_station_added)) { | 815 | !priv->assoc_station_added)) { |
@@ -825,7 +819,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
825 | 819 | ||
826 | spin_unlock_irqrestore(&priv->lock, flags); | 820 | spin_unlock_irqrestore(&priv->lock, flags); |
827 | 821 | ||
828 | hdr_len = ieee80211_get_hdrlen(fc); | 822 | hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc)); |
829 | 823 | ||
830 | /* Find (or create) index into station table for destination station */ | 824 | /* Find (or create) index into station table for destination station */ |
831 | sta_id = iwl_get_sta_id(priv, hdr); | 825 | sta_id = iwl_get_sta_id(priv, hdr); |
@@ -839,8 +833,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
839 | 833 | ||
840 | IWL_DEBUG_TX("station Id %d\n", sta_id); | 834 | IWL_DEBUG_TX("station Id %d\n", sta_id); |
841 | 835 | ||
842 | if (ieee80211_is_qos_data(fc)) { | 836 | if (ieee80211_is_data_qos(fc)) { |
843 | qc = ieee80211_get_qos_ctrl(hdr, hdr_len); | 837 | qc = ieee80211_get_qos_ctl(hdr); |
844 | tid = qc[0] & 0xf; | 838 | tid = qc[0] & 0xf; |
845 | seq_number = priv->stations[sta_id].tid[tid].seq_number & | 839 | seq_number = priv->stations[sta_id].tid[tid].seq_number & |
846 | IEEE80211_SCTL_SEQ; | 840 | IEEE80211_SCTL_SEQ; |
@@ -848,12 +842,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
848 | (hdr->seq_ctrl & | 842 | (hdr->seq_ctrl & |
849 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); | 843 | __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); |
850 | seq_number += 0x10; | 844 | seq_number += 0x10; |
851 | #ifdef CONFIG_IWL4965_HT | ||
852 | /* aggregation is on for this <sta,tid> */ | 845 | /* aggregation is on for this <sta,tid> */ |
853 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 846 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
854 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 847 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
855 | priv->stations[sta_id].tid[tid].tfds_in_queue++; | 848 | priv->stations[sta_id].tid[tid].tfds_in_queue++; |
856 | #endif /* CONFIG_IWL4965_HT */ | ||
857 | } | 849 | } |
858 | 850 | ||
859 | /* Descriptor for chosen Tx queue */ | 851 | /* Descriptor for chosen Tx queue */ |
@@ -945,14 +937,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
945 | /* set is_hcca to 0; it probably will never be implemented */ | 937 | /* set is_hcca to 0; it probably will never be implemented */ |
946 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); | 938 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); |
947 | 939 | ||
948 | iwl_update_tx_stats(priv, fc, len); | 940 | iwl_update_tx_stats(priv, le16_to_cpu(fc), len); |
949 | 941 | ||
950 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | 942 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + |
951 | offsetof(struct iwl_tx_cmd, scratch); | 943 | offsetof(struct iwl_tx_cmd, scratch); |
952 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 944 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
953 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); | 945 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); |
954 | 946 | ||
955 | if (!ieee80211_get_morefrag(hdr)) { | 947 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
956 | txq->need_update = 1; | 948 | txq->need_update = 1; |
957 | if (qc) | 949 | if (qc) |
958 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | 950 | priv->stations[sta_id].tid[tid].seq_number = seq_number; |
@@ -1196,8 +1188,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
1196 | } | 1188 | } |
1197 | EXPORT_SYMBOL(iwl_tx_cmd_complete); | 1189 | EXPORT_SYMBOL(iwl_tx_cmd_complete); |
1198 | 1190 | ||
1199 | |||
1200 | #ifdef CONFIG_IWL4965_HT | ||
1201 | /* | 1191 | /* |
1202 | * Find first available (lowest unused) Tx Queue, mark it "active". | 1192 | * Find first available (lowest unused) Tx Queue, mark it "active". |
1203 | * Called only when finding queue for aggregation. | 1193 | * Called only when finding queue for aggregation. |
@@ -1359,7 +1349,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1359 | return 0; | 1349 | return 0; |
1360 | } | 1350 | } |
1361 | EXPORT_SYMBOL(iwl_txq_check_empty); | 1351 | EXPORT_SYMBOL(iwl_txq_check_empty); |
1362 | #endif /* CONFIG_IWL4965_HT */ | ||
1363 | 1352 | ||
1364 | #ifdef CONFIG_IWLWIF_DEBUG | 1353 | #ifdef CONFIG_IWLWIF_DEBUG |
1365 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x | 1354 | #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 72279e07fe32..47cf4b997f50 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2431,15 +2431,15 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2431 | struct ieee80211_hdr *hdr, | 2431 | struct ieee80211_hdr *hdr, |
2432 | int is_unicast, u8 std_id) | 2432 | int is_unicast, u8 std_id) |
2433 | { | 2433 | { |
2434 | u16 fc = le16_to_cpu(hdr->frame_control); | 2434 | __le16 fc = hdr->frame_control; |
2435 | __le32 tx_flags = cmd->cmd.tx.tx_flags; | 2435 | __le32 tx_flags = cmd->cmd.tx.tx_flags; |
2436 | 2436 | ||
2437 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 2437 | cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
2438 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { | 2438 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
2439 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 2439 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
2440 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) | 2440 | if (ieee80211_is_mgmt(fc)) |
2441 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 2441 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
2442 | if (ieee80211_is_probe_response(fc) && | 2442 | if (ieee80211_is_probe_resp(fc) && |
2443 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) | 2443 | !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) |
2444 | tx_flags |= TX_CMD_FLG_TSF_MSK; | 2444 | tx_flags |= TX_CMD_FLG_TSF_MSK; |
2445 | } else { | 2445 | } else { |
@@ -2448,11 +2448,11 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2448 | } | 2448 | } |
2449 | 2449 | ||
2450 | cmd->cmd.tx.sta_id = std_id; | 2450 | cmd->cmd.tx.sta_id = std_id; |
2451 | if (ieee80211_get_morefrag(hdr)) | 2451 | if (ieee80211_has_morefrags(fc)) |
2452 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; | 2452 | tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; |
2453 | 2453 | ||
2454 | if (ieee80211_is_qos_data(fc)) { | 2454 | if (ieee80211_is_data_qos(fc)) { |
2455 | u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); | 2455 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
2456 | cmd->cmd.tx.tid_tspec = qc[0] & 0xf; | 2456 | cmd->cmd.tx.tid_tspec = qc[0] & 0xf; |
2457 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; | 2457 | tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; |
2458 | } else { | 2458 | } else { |
@@ -2471,9 +2471,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, | |||
2471 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; | 2471 | tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; |
2472 | 2472 | ||
2473 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); | 2473 | tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); |
2474 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 2474 | if (ieee80211_is_mgmt(fc)) { |
2475 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || | 2475 | if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) |
2476 | (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) | ||
2477 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); | 2476 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); |
2478 | else | 2477 | else |
2479 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); | 2478 | cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); |
@@ -2564,7 +2563,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2564 | u8 sta_id; | 2563 | u8 sta_id; |
2565 | u8 tid = 0; | 2564 | u8 tid = 0; |
2566 | u16 seq_number = 0; | 2565 | u16 seq_number = 0; |
2567 | u16 fc; | 2566 | __le16 fc; |
2568 | u8 wait_write_ptr = 0; | 2567 | u8 wait_write_ptr = 0; |
2569 | u8 *qc = NULL; | 2568 | u8 *qc = NULL; |
2570 | unsigned long flags; | 2569 | unsigned long flags; |
@@ -2589,28 +2588,28 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2589 | unicast = !is_multicast_ether_addr(hdr->addr1); | 2588 | unicast = !is_multicast_ether_addr(hdr->addr1); |
2590 | id = 0; | 2589 | id = 0; |
2591 | 2590 | ||
2592 | fc = le16_to_cpu(hdr->frame_control); | 2591 | fc = hdr->frame_control; |
2593 | 2592 | ||
2594 | #ifdef CONFIG_IWL3945_DEBUG | 2593 | #ifdef CONFIG_IWL3945_DEBUG |
2595 | if (ieee80211_is_auth(fc)) | 2594 | if (ieee80211_is_auth(fc)) |
2596 | IWL_DEBUG_TX("Sending AUTH frame\n"); | 2595 | IWL_DEBUG_TX("Sending AUTH frame\n"); |
2597 | else if (ieee80211_is_assoc_request(fc)) | 2596 | else if (ieee80211_is_assoc_req(fc)) |
2598 | IWL_DEBUG_TX("Sending ASSOC frame\n"); | 2597 | IWL_DEBUG_TX("Sending ASSOC frame\n"); |
2599 | else if (ieee80211_is_reassoc_request(fc)) | 2598 | else if (ieee80211_is_reassoc_req(fc)) |
2600 | IWL_DEBUG_TX("Sending REASSOC frame\n"); | 2599 | IWL_DEBUG_TX("Sending REASSOC frame\n"); |
2601 | #endif | 2600 | #endif |
2602 | 2601 | ||
2603 | /* drop all data frame if we are not associated */ | 2602 | /* drop all data frame if we are not associated */ |
2604 | if ((!iwl3945_is_associated(priv) || | 2603 | if ((!iwl3945_is_associated(priv) || |
2605 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && | 2604 | ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && |
2606 | ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { | 2605 | ieee80211_is_data(fc)) { |
2607 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); | 2606 | IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); |
2608 | goto drop_unlock; | 2607 | goto drop_unlock; |
2609 | } | 2608 | } |
2610 | 2609 | ||
2611 | spin_unlock_irqrestore(&priv->lock, flags); | 2610 | spin_unlock_irqrestore(&priv->lock, flags); |
2612 | 2611 | ||
2613 | hdr_len = ieee80211_get_hdrlen(fc); | 2612 | hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc)); |
2614 | 2613 | ||
2615 | /* Find (or create) index into station table for destination station */ | 2614 | /* Find (or create) index into station table for destination station */ |
2616 | sta_id = iwl3945_get_sta_id(priv, hdr); | 2615 | sta_id = iwl3945_get_sta_id(priv, hdr); |
@@ -2624,8 +2623,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2624 | 2623 | ||
2625 | IWL_DEBUG_RATE("station Id %d\n", sta_id); | 2624 | IWL_DEBUG_RATE("station Id %d\n", sta_id); |
2626 | 2625 | ||
2627 | if (ieee80211_is_qos_data(fc)) { | 2626 | if (ieee80211_is_data_qos(fc)) { |
2628 | qc = ieee80211_get_qos_ctrl(hdr, hdr_len); | 2627 | qc = ieee80211_get_qos_ctl(hdr); |
2629 | tid = qc[0] & 0xf; | 2628 | tid = qc[0] & 0xf; |
2630 | seq_number = priv->stations[sta_id].tid[tid].seq_number & | 2629 | seq_number = priv->stations[sta_id].tid[tid].seq_number & |
2631 | IEEE80211_SCTL_SEQ; | 2630 | IEEE80211_SCTL_SEQ; |
@@ -2732,7 +2731,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2732 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; | 2731 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; |
2733 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; | 2732 | out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; |
2734 | 2733 | ||
2735 | if (!ieee80211_get_morefrag(hdr)) { | 2734 | if (!ieee80211_has_morefrags(hdr->frame_control)) { |
2736 | txq->need_update = 1; | 2735 | txq->need_update = 1; |
2737 | if (qc) { | 2736 | if (qc) { |
2738 | priv->stations[sta_id].tid[tid].seq_number = seq_number; | 2737 | priv->stations[sta_id].tid[tid].seq_number = seq_number; |
@@ -2746,7 +2745,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) | |||
2746 | sizeof(out_cmd->cmd.tx)); | 2745 | sizeof(out_cmd->cmd.tx)); |
2747 | 2746 | ||
2748 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, | 2747 | iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, |
2749 | ieee80211_get_hdrlen(fc)); | 2748 | ieee80211_get_hdrlen(le16_to_cpu(fc))); |
2750 | 2749 | ||
2751 | /* Tell device the write index *just past* this latest filled TFD */ | 2750 | /* Tell device the write index *just past* this latest filled TFD */ |
2752 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 2751 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
@@ -2875,7 +2874,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) | |||
2875 | return; | 2874 | return; |
2876 | } | 2875 | } |
2877 | 2876 | ||
2878 | queue_work(priv->workqueue, &priv->restart); | 2877 | if (priv->is_open) |
2878 | queue_work(priv->workqueue, &priv->restart); | ||
2879 | return; | 2879 | return; |
2880 | } | 2880 | } |
2881 | 2881 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index c71daec8c746..f5911687671b 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -87,46 +87,6 @@ MODULE_VERSION(DRV_VERSION); | |||
87 | MODULE_AUTHOR(DRV_COPYRIGHT); | 87 | MODULE_AUTHOR(DRV_COPYRIGHT); |
88 | MODULE_LICENSE("GPL"); | 88 | MODULE_LICENSE("GPL"); |
89 | 89 | ||
90 | static int iwl4965_is_empty_essid(const char *essid, int essid_len) | ||
91 | { | ||
92 | /* Single white space is for Linksys APs */ | ||
93 | if (essid_len == 1 && essid[0] == ' ') | ||
94 | return 1; | ||
95 | |||
96 | /* Otherwise, if the entire essid is 0, we assume it is hidden */ | ||
97 | while (essid_len) { | ||
98 | essid_len--; | ||
99 | if (essid[essid_len] != '\0') | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | return 1; | ||
104 | } | ||
105 | |||
106 | static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) | ||
107 | { | ||
108 | static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; | ||
109 | const char *s = essid; | ||
110 | char *d = escaped; | ||
111 | |||
112 | if (iwl4965_is_empty_essid(essid, essid_len)) { | ||
113 | memcpy(escaped, "<hidden>", sizeof("<hidden>")); | ||
114 | return escaped; | ||
115 | } | ||
116 | |||
117 | essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); | ||
118 | while (essid_len--) { | ||
119 | if (*s == '\0') { | ||
120 | *d++ = '\\'; | ||
121 | *d++ = '0'; | ||
122 | s++; | ||
123 | } else | ||
124 | *d++ = *s++; | ||
125 | } | ||
126 | *d = '\0'; | ||
127 | return escaped; | ||
128 | } | ||
129 | |||
130 | /*************** STATION TABLE MANAGEMENT **** | 90 | /*************** STATION TABLE MANAGEMENT **** |
131 | * mac80211 should be examined to determine if sta_info is duplicating | 91 | * mac80211 should be examined to determine if sta_info is duplicating |
132 | * the functionality provided here | 92 | * the functionality provided here |
@@ -367,9 +327,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) | |||
367 | 327 | ||
368 | /* If we issue a new RXON command which required a tune then we must | 328 | /* If we issue a new RXON command which required a tune then we must |
369 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 329 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
370 | rc = iwl4965_hw_reg_send_txpower(priv); | 330 | rc = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
371 | if (rc) { | 331 | if (rc) { |
372 | IWL_ERROR("Error setting Tx power (%d).\n", rc); | 332 | IWL_ERROR("Error sending TX power (%d).\n", rc); |
373 | return rc; | 333 | return rc; |
374 | } | 334 | } |
375 | 335 | ||
@@ -419,69 +379,6 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv) | |||
419 | sizeof(struct iwl4965_bt_cmd), &bt_cmd); | 379 | sizeof(struct iwl4965_bt_cmd), &bt_cmd); |
420 | } | 380 | } |
421 | 381 | ||
422 | static int iwl4965_send_scan_abort(struct iwl_priv *priv) | ||
423 | { | ||
424 | int ret = 0; | ||
425 | struct iwl_rx_packet *res; | ||
426 | struct iwl_host_cmd cmd = { | ||
427 | .id = REPLY_SCAN_ABORT_CMD, | ||
428 | .meta.flags = CMD_WANT_SKB, | ||
429 | }; | ||
430 | |||
431 | /* If there isn't a scan actively going on in the hardware | ||
432 | * then we are in between scan bands and not actually | ||
433 | * actively scanning, so don't send the abort command */ | ||
434 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
435 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | ret = iwl_send_cmd_sync(priv, &cmd); | ||
440 | if (ret) { | ||
441 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; | ||
446 | if (res->u.status != CAN_ABORT_STATUS) { | ||
447 | /* The scan abort will return 1 for success or | ||
448 | * 2 for "failure". A failure condition can be | ||
449 | * due to simply not being in an active scan which | ||
450 | * can occur if we send the scan abort before we | ||
451 | * the microcode has notified us that a scan is | ||
452 | * completed. */ | ||
453 | IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); | ||
454 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
455 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
456 | } | ||
457 | |||
458 | dev_kfree_skb_any(cmd.meta.u.skb); | ||
459 | |||
460 | return ret; | ||
461 | } | ||
462 | |||
463 | /* | ||
464 | * CARD_STATE_CMD | ||
465 | * | ||
466 | * Use: Sets the device's internal card state to enable, disable, or halt | ||
467 | * | ||
468 | * When in the 'enable' state the card operates as normal. | ||
469 | * When in the 'disable' state, the card enters into a low power mode. | ||
470 | * When in the 'halt' state, the card is shut down and must be fully | ||
471 | * restarted to come back on. | ||
472 | */ | ||
473 | static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | ||
474 | { | ||
475 | struct iwl_host_cmd cmd = { | ||
476 | .id = REPLY_CARD_STATE_CMD, | ||
477 | .len = sizeof(u32), | ||
478 | .data = &flags, | ||
479 | .meta.flags = meta_flag, | ||
480 | }; | ||
481 | |||
482 | return iwl_send_cmd(priv, &cmd); | ||
483 | } | ||
484 | |||
485 | static void iwl_clear_free_frames(struct iwl_priv *priv) | 382 | static void iwl_clear_free_frames(struct iwl_priv *priv) |
486 | { | 383 | { |
487 | struct list_head *element; | 384 | struct list_head *element; |
@@ -605,36 +502,6 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | |||
605 | * | 502 | * |
606 | ******************************************************************************/ | 503 | ******************************************************************************/ |
607 | 504 | ||
608 | /** | ||
609 | * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field | ||
610 | * | ||
611 | * return : set the bit for each supported rate insert in ie | ||
612 | */ | ||
613 | static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, | ||
614 | u16 basic_rate, int *left) | ||
615 | { | ||
616 | u16 ret_rates = 0, bit; | ||
617 | int i; | ||
618 | u8 *cnt = ie; | ||
619 | u8 *rates = ie + 1; | ||
620 | |||
621 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | ||
622 | if (bit & supported_rate) { | ||
623 | ret_rates |= bit; | ||
624 | rates[*cnt] = iwl_rates[i].ieee | | ||
625 | ((bit & basic_rate) ? 0x80 : 0x00); | ||
626 | (*cnt)++; | ||
627 | (*left)--; | ||
628 | if ((*left <= 0) || | ||
629 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
630 | break; | ||
631 | } | ||
632 | } | ||
633 | |||
634 | return ret_rates; | ||
635 | } | ||
636 | |||
637 | #ifdef CONFIG_IWL4965_HT | ||
638 | static void iwl4965_ht_conf(struct iwl_priv *priv, | 505 | static void iwl4965_ht_conf(struct iwl_priv *priv, |
639 | struct ieee80211_bss_conf *bss_conf) | 506 | struct ieee80211_bss_conf *bss_conf) |
640 | { | 507 | { |
@@ -665,9 +532,11 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
665 | iwl_conf->extension_chan_offset = | 532 | iwl_conf->extension_chan_offset = |
666 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; | 533 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; |
667 | /* If no above or below channel supplied disable FAT channel */ | 534 | /* If no above or below channel supplied disable FAT channel */ |
668 | if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE && | 535 | if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE && |
669 | iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW) | 536 | iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) { |
537 | iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE; | ||
670 | iwl_conf->supported_chan_width = 0; | 538 | iwl_conf->supported_chan_width = 0; |
539 | } | ||
671 | 540 | ||
672 | iwl_conf->tx_mimo_ps_mode = | 541 | iwl_conf->tx_mimo_ps_mode = |
673 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | 542 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); |
@@ -685,151 +554,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, | |||
685 | IWL_DEBUG_MAC80211("leave\n"); | 554 | IWL_DEBUG_MAC80211("leave\n"); |
686 | } | 555 | } |
687 | 556 | ||
688 | static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | ||
689 | u8 *pos, int *left) | ||
690 | { | ||
691 | struct ieee80211_ht_cap *ht_cap; | ||
692 | |||
693 | if (!sband || !sband->ht_info.ht_supported) | ||
694 | return; | ||
695 | |||
696 | if (*left < sizeof(struct ieee80211_ht_cap)) | ||
697 | return; | ||
698 | |||
699 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
700 | ht_cap = (struct ieee80211_ht_cap *) pos; | ||
701 | |||
702 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); | ||
703 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
704 | ht_cap->ampdu_params_info = | ||
705 | (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
706 | ((sband->ht_info.ampdu_density << 2) & | ||
707 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
708 | *left -= sizeof(struct ieee80211_ht_cap); | ||
709 | } | ||
710 | #else | ||
711 | static inline void iwl4965_ht_conf(struct iwl_priv *priv, | ||
712 | struct ieee80211_bss_conf *bss_conf) | ||
713 | { | ||
714 | } | ||
715 | static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | ||
716 | u8 *pos, int *left) | ||
717 | { | ||
718 | } | ||
719 | #endif | ||
720 | |||
721 | |||
722 | /** | ||
723 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request | ||
724 | */ | ||
725 | static u16 iwl4965_fill_probe_req(struct iwl_priv *priv, | ||
726 | enum ieee80211_band band, | ||
727 | struct ieee80211_mgmt *frame, | ||
728 | int left, int is_direct) | ||
729 | { | ||
730 | int len = 0; | ||
731 | u8 *pos = NULL; | ||
732 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | ||
733 | const struct ieee80211_supported_band *sband = | ||
734 | iwl_get_hw_mode(priv, band); | ||
735 | |||
736 | /* Make sure there is enough space for the probe request, | ||
737 | * two mandatory IEs and the data */ | ||
738 | left -= 24; | ||
739 | if (left < 0) | ||
740 | return 0; | ||
741 | len += 24; | ||
742 | |||
743 | frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | ||
744 | memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); | ||
745 | memcpy(frame->sa, priv->mac_addr, ETH_ALEN); | ||
746 | memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); | ||
747 | frame->seq_ctrl = 0; | ||
748 | |||
749 | /* fill in our indirect SSID IE */ | ||
750 | /* ...next IE... */ | ||
751 | |||
752 | left -= 2; | ||
753 | if (left < 0) | ||
754 | return 0; | ||
755 | len += 2; | ||
756 | pos = &(frame->u.probe_req.variable[0]); | ||
757 | *pos++ = WLAN_EID_SSID; | ||
758 | *pos++ = 0; | ||
759 | |||
760 | /* fill in our direct SSID IE... */ | ||
761 | if (is_direct) { | ||
762 | /* ...next IE... */ | ||
763 | left -= 2 + priv->essid_len; | ||
764 | if (left < 0) | ||
765 | return 0; | ||
766 | /* ... fill it in... */ | ||
767 | *pos++ = WLAN_EID_SSID; | ||
768 | *pos++ = priv->essid_len; | ||
769 | memcpy(pos, priv->essid, priv->essid_len); | ||
770 | pos += priv->essid_len; | ||
771 | len += 2 + priv->essid_len; | ||
772 | } | ||
773 | |||
774 | /* fill in supported rate */ | ||
775 | /* ...next IE... */ | ||
776 | left -= 2; | ||
777 | if (left < 0) | ||
778 | return 0; | ||
779 | |||
780 | /* ... fill it in... */ | ||
781 | *pos++ = WLAN_EID_SUPP_RATES; | ||
782 | *pos = 0; | ||
783 | |||
784 | /* exclude 60M rate */ | ||
785 | active_rates = priv->rates_mask; | ||
786 | active_rates &= ~IWL_RATE_60M_MASK; | ||
787 | |||
788 | active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; | ||
789 | |||
790 | cck_rates = IWL_CCK_RATES_MASK & active_rates; | ||
791 | ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates, | ||
792 | active_rate_basic, &left); | ||
793 | active_rates &= ~ret_rates; | ||
794 | |||
795 | ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates, | ||
796 | active_rate_basic, &left); | ||
797 | active_rates &= ~ret_rates; | ||
798 | |||
799 | len += 2 + *pos; | ||
800 | pos += (*pos) + 1; | ||
801 | if (active_rates == 0) | ||
802 | goto fill_end; | ||
803 | |||
804 | /* fill in supported extended rate */ | ||
805 | /* ...next IE... */ | ||
806 | left -= 2; | ||
807 | if (left < 0) | ||
808 | return 0; | ||
809 | /* ... fill it in... */ | ||
810 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
811 | *pos = 0; | ||
812 | iwl4965_supported_rate_to_ie(pos, active_rates, | ||
813 | active_rate_basic, &left); | ||
814 | if (*pos > 0) | ||
815 | len += 2 + *pos; | ||
816 | |||
817 | fill_end: | ||
818 | /* fill in HT IE */ | ||
819 | left -= 2; | ||
820 | if (left < 0) | ||
821 | return 0; | ||
822 | |||
823 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
824 | *pos = 0; | ||
825 | |||
826 | iwl_ht_cap_to_ie(sband, pos, &left); | ||
827 | |||
828 | if (*pos > 0) | ||
829 | len += 2 + *pos; | ||
830 | return (u16)len; | ||
831 | } | ||
832 | |||
833 | /* | 557 | /* |
834 | * QoS support | 558 | * QoS support |
835 | */ | 559 | */ |
@@ -862,10 +586,8 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) | |||
862 | priv->qos_data.def_qos_parm.qos_flags |= | 586 | priv->qos_data.def_qos_parm.qos_flags |= |
863 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; | 587 | QOS_PARAM_FLG_UPDATE_EDCA_MSK; |
864 | 588 | ||
865 | #ifdef CONFIG_IWL4965_HT | ||
866 | if (priv->current_ht_config.is_ht) | 589 | if (priv->current_ht_config.is_ht) |
867 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; | 590 | priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; |
868 | #endif /* CONFIG_IWL4965_HT */ | ||
869 | 591 | ||
870 | spin_unlock_irqrestore(&priv->lock, flags); | 592 | spin_unlock_irqrestore(&priv->lock, flags); |
871 | 593 | ||
@@ -909,60 +631,6 @@ int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *heade | |||
909 | return 1; | 631 | return 1; |
910 | } | 632 | } |
911 | 633 | ||
912 | |||
913 | |||
914 | /** | ||
915 | * iwl4965_scan_cancel - Cancel any currently executing HW scan | ||
916 | * | ||
917 | * NOTE: priv->mutex is not required before calling this function | ||
918 | */ | ||
919 | static int iwl4965_scan_cancel(struct iwl_priv *priv) | ||
920 | { | ||
921 | if (!test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
922 | clear_bit(STATUS_SCANNING, &priv->status); | ||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
927 | if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
928 | IWL_DEBUG_SCAN("Queuing scan abort.\n"); | ||
929 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
930 | queue_work(priv->workqueue, &priv->abort_scan); | ||
931 | |||
932 | } else | ||
933 | IWL_DEBUG_SCAN("Scan abort already in progress.\n"); | ||
934 | |||
935 | return test_bit(STATUS_SCANNING, &priv->status); | ||
936 | } | ||
937 | |||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | /** | ||
942 | * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan | ||
943 | * @ms: amount of time to wait (in milliseconds) for scan to abort | ||
944 | * | ||
945 | * NOTE: priv->mutex must be held before calling this function | ||
946 | */ | ||
947 | static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) | ||
948 | { | ||
949 | unsigned long now = jiffies; | ||
950 | int ret; | ||
951 | |||
952 | ret = iwl4965_scan_cancel(priv); | ||
953 | if (ret && ms) { | ||
954 | mutex_unlock(&priv->mutex); | ||
955 | while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && | ||
956 | test_bit(STATUS_SCANNING, &priv->status)) | ||
957 | msleep(1); | ||
958 | mutex_lock(&priv->mutex); | ||
959 | |||
960 | return test_bit(STATUS_SCANNING, &priv->status); | ||
961 | } | ||
962 | |||
963 | return ret; | ||
964 | } | ||
965 | |||
966 | static void iwl4965_sequence_reset(struct iwl_priv *priv) | 634 | static void iwl4965_sequence_reset(struct iwl_priv *priv) |
967 | { | 635 | { |
968 | /* Reset ieee stats */ | 636 | /* Reset ieee stats */ |
@@ -974,7 +642,7 @@ static void iwl4965_sequence_reset(struct iwl_priv *priv) | |||
974 | priv->last_frag_num = -1; | 642 | priv->last_frag_num = -1; |
975 | priv->last_packet_time = 0; | 643 | priv->last_packet_time = 0; |
976 | 644 | ||
977 | iwl4965_scan_cancel(priv); | 645 | iwl_scan_cancel(priv); |
978 | } | 646 | } |
979 | 647 | ||
980 | #define MAX_UCODE_BEACON_INTERVAL 4096 | 648 | #define MAX_UCODE_BEACON_INTERVAL 4096 |
@@ -1049,41 +717,6 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv) | |||
1049 | le16_to_cpu(priv->rxon_timing.atim_window)); | 717 | le16_to_cpu(priv->rxon_timing.atim_window)); |
1050 | } | 718 | } |
1051 | 719 | ||
1052 | static int iwl4965_scan_initiate(struct iwl_priv *priv) | ||
1053 | { | ||
1054 | if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { | ||
1055 | IWL_ERROR("APs don't scan.\n"); | ||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | if (!iwl_is_ready_rf(priv)) { | ||
1060 | IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); | ||
1061 | return -EIO; | ||
1062 | } | ||
1063 | |||
1064 | if (test_bit(STATUS_SCANNING, &priv->status)) { | ||
1065 | IWL_DEBUG_SCAN("Scan already in progress.\n"); | ||
1066 | return -EAGAIN; | ||
1067 | } | ||
1068 | |||
1069 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1070 | IWL_DEBUG_SCAN("Scan request while abort pending. " | ||
1071 | "Queuing.\n"); | ||
1072 | return -EAGAIN; | ||
1073 | } | ||
1074 | |||
1075 | IWL_DEBUG_INFO("Starting scan...\n"); | ||
1076 | priv->scan_bands = 2; | ||
1077 | set_bit(STATUS_SCANNING, &priv->status); | ||
1078 | priv->scan_start = jiffies; | ||
1079 | priv->scan_pass_start = priv->scan_start; | ||
1080 | |||
1081 | queue_work(priv->workqueue, &priv->request_scan); | ||
1082 | |||
1083 | return 0; | ||
1084 | } | ||
1085 | |||
1086 | |||
1087 | static void iwl_set_flags_for_band(struct iwl_priv *priv, | 720 | static void iwl_set_flags_for_band(struct iwl_priv *priv, |
1088 | enum ieee80211_band band) | 721 | enum ieee80211_band band) |
1089 | { | 722 | { |
@@ -1188,22 +821,11 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) | |||
1188 | 821 | ||
1189 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | 822 | static int iwl4965_set_mode(struct iwl_priv *priv, int mode) |
1190 | { | 823 | { |
1191 | if (mode == IEEE80211_IF_TYPE_IBSS) { | ||
1192 | const struct iwl_channel_info *ch_info; | ||
1193 | |||
1194 | ch_info = iwl_get_channel_info(priv, | ||
1195 | priv->band, | ||
1196 | le16_to_cpu(priv->staging_rxon.channel)); | ||
1197 | |||
1198 | if (!ch_info || !is_channel_ibss(ch_info)) { | ||
1199 | IWL_ERROR("channel %d not IBSS channel\n", | ||
1200 | le16_to_cpu(priv->staging_rxon.channel)); | ||
1201 | return -EINVAL; | ||
1202 | } | ||
1203 | } | ||
1204 | |||
1205 | priv->iw_mode = mode; | 824 | priv->iw_mode = mode; |
1206 | 825 | ||
826 | /* init channel/phymode to values given at driver init */ | ||
827 | iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); | ||
828 | |||
1207 | iwl4965_connection_init_rx_config(priv); | 829 | iwl4965_connection_init_rx_config(priv); |
1208 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 830 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
1209 | 831 | ||
@@ -1214,7 +836,7 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode) | |||
1214 | return -EAGAIN; | 836 | return -EAGAIN; |
1215 | 837 | ||
1216 | cancel_delayed_work(&priv->scan_check); | 838 | cancel_delayed_work(&priv->scan_check); |
1217 | if (iwl4965_scan_cancel_timeout(priv, 100)) { | 839 | if (iwl_scan_cancel_timeout(priv, 100)) { |
1218 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); | 840 | IWL_WARNING("Aborted scan still in progress after 100ms\n"); |
1219 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 841 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
1220 | return -EAGAIN; | 842 | return -EAGAIN; |
@@ -1272,64 +894,6 @@ static void iwl4965_set_rate(struct iwl_priv *priv) | |||
1272 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; | 894 | (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; |
1273 | } | 895 | } |
1274 | 896 | ||
1275 | void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) | ||
1276 | { | ||
1277 | unsigned long flags; | ||
1278 | |||
1279 | if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
1280 | return; | ||
1281 | |||
1282 | IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n", | ||
1283 | disable_radio ? "OFF" : "ON"); | ||
1284 | |||
1285 | if (disable_radio) { | ||
1286 | iwl4965_scan_cancel(priv); | ||
1287 | /* FIXME: This is a workaround for AP */ | ||
1288 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | ||
1289 | spin_lock_irqsave(&priv->lock, flags); | ||
1290 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
1291 | CSR_UCODE_SW_BIT_RFKILL); | ||
1292 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1293 | /* call the host command only if no hw rf-kill set */ | ||
1294 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
1295 | iwl_is_ready(priv)) | ||
1296 | iwl4965_send_card_state(priv, | ||
1297 | CARD_STATE_CMD_DISABLE, | ||
1298 | 0); | ||
1299 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1300 | |||
1301 | /* make sure mac80211 stop sending Tx frame */ | ||
1302 | if (priv->mac80211_registered) | ||
1303 | ieee80211_stop_queues(priv->hw); | ||
1304 | } | ||
1305 | return; | ||
1306 | } | ||
1307 | |||
1308 | spin_lock_irqsave(&priv->lock, flags); | ||
1309 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
1310 | |||
1311 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1312 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1313 | |||
1314 | /* wake up ucode */ | ||
1315 | msleep(10); | ||
1316 | |||
1317 | spin_lock_irqsave(&priv->lock, flags); | ||
1318 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
1319 | if (!iwl_grab_nic_access(priv)) | ||
1320 | iwl_release_nic_access(priv); | ||
1321 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1322 | |||
1323 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
1324 | IWL_DEBUG_RF_KILL("Can not turn radio back on - " | ||
1325 | "disabled by HW switch\n"); | ||
1326 | return; | ||
1327 | } | ||
1328 | |||
1329 | queue_work(priv->workqueue, &priv->restart); | ||
1330 | return; | ||
1331 | } | ||
1332 | |||
1333 | #define IWL_PACKET_RETRY_TIME HZ | 897 | #define IWL_PACKET_RETRY_TIME HZ |
1334 | 898 | ||
1335 | int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) | 899 | int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) |
@@ -1661,17 +1225,37 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) | |||
1661 | iwl4965_send_beacon_cmd(priv); | 1225 | iwl4965_send_beacon_cmd(priv); |
1662 | } | 1226 | } |
1663 | 1227 | ||
1228 | /** | ||
1229 | * iwl4965_bg_statistics_periodic - Timer callback to queue statistics | ||
1230 | * | ||
1231 | * This callback is provided in order to send a statistics request. | ||
1232 | * | ||
1233 | * This timer function is continually reset to execute within | ||
1234 | * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION | ||
1235 | * was received. We need to ensure we receive the statistics in order | ||
1236 | * to update the temperature used for calibrating the TXPOWER. | ||
1237 | */ | ||
1238 | static void iwl4965_bg_statistics_periodic(unsigned long data) | ||
1239 | { | ||
1240 | struct iwl_priv *priv = (struct iwl_priv *)data; | ||
1241 | |||
1242 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
1243 | return; | ||
1244 | |||
1245 | iwl_send_statistics_request(priv, CMD_ASYNC); | ||
1246 | } | ||
1247 | |||
1664 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | 1248 | static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, |
1665 | struct iwl_rx_mem_buffer *rxb) | 1249 | struct iwl_rx_mem_buffer *rxb) |
1666 | { | 1250 | { |
1667 | #ifdef CONFIG_IWLWIFI_DEBUG | 1251 | #ifdef CONFIG_IWLWIFI_DEBUG |
1668 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1252 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
1669 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); | 1253 | struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); |
1670 | u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); | 1254 | u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); |
1671 | 1255 | ||
1672 | IWL_DEBUG_RX("beacon status %x retries %d iss %d " | 1256 | IWL_DEBUG_RX("beacon status %x retries %d iss %d " |
1673 | "tsf %d %d rate %d\n", | 1257 | "tsf %d %d rate %d\n", |
1674 | le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, | 1258 | le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, |
1675 | beacon->beacon_notify_hdr.failure_frame, | 1259 | beacon->beacon_notify_hdr.failure_frame, |
1676 | le32_to_cpu(beacon->ibss_mgr_status), | 1260 | le32_to_cpu(beacon->ibss_mgr_status), |
1677 | le32_to_cpu(beacon->high_tsf), | 1261 | le32_to_cpu(beacon->high_tsf), |
@@ -1683,118 +1267,6 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, | |||
1683 | queue_work(priv->workqueue, &priv->beacon_update); | 1267 | queue_work(priv->workqueue, &priv->beacon_update); |
1684 | } | 1268 | } |
1685 | 1269 | ||
1686 | /* Service response to REPLY_SCAN_CMD (0x80) */ | ||
1687 | static void iwl4965_rx_reply_scan(struct iwl_priv *priv, | ||
1688 | struct iwl_rx_mem_buffer *rxb) | ||
1689 | { | ||
1690 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1691 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1692 | struct iwl4965_scanreq_notification *notif = | ||
1693 | (struct iwl4965_scanreq_notification *)pkt->u.raw; | ||
1694 | |||
1695 | IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); | ||
1696 | #endif | ||
1697 | } | ||
1698 | |||
1699 | /* Service SCAN_START_NOTIFICATION (0x82) */ | ||
1700 | static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, | ||
1701 | struct iwl_rx_mem_buffer *rxb) | ||
1702 | { | ||
1703 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1704 | struct iwl4965_scanstart_notification *notif = | ||
1705 | (struct iwl4965_scanstart_notification *)pkt->u.raw; | ||
1706 | priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); | ||
1707 | IWL_DEBUG_SCAN("Scan start: " | ||
1708 | "%d [802.11%s] " | ||
1709 | "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", | ||
1710 | notif->channel, | ||
1711 | notif->band ? "bg" : "a", | ||
1712 | notif->tsf_high, | ||
1713 | notif->tsf_low, notif->status, notif->beacon_timer); | ||
1714 | } | ||
1715 | |||
1716 | /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ | ||
1717 | static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, | ||
1718 | struct iwl_rx_mem_buffer *rxb) | ||
1719 | { | ||
1720 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1721 | struct iwl4965_scanresults_notification *notif = | ||
1722 | (struct iwl4965_scanresults_notification *)pkt->u.raw; | ||
1723 | |||
1724 | IWL_DEBUG_SCAN("Scan ch.res: " | ||
1725 | "%d [802.11%s] " | ||
1726 | "(TSF: 0x%08X:%08X) - %d " | ||
1727 | "elapsed=%lu usec (%dms since last)\n", | ||
1728 | notif->channel, | ||
1729 | notif->band ? "bg" : "a", | ||
1730 | le32_to_cpu(notif->tsf_high), | ||
1731 | le32_to_cpu(notif->tsf_low), | ||
1732 | le32_to_cpu(notif->statistics[0]), | ||
1733 | le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, | ||
1734 | jiffies_to_msecs(elapsed_jiffies | ||
1735 | (priv->last_scan_jiffies, jiffies))); | ||
1736 | |||
1737 | priv->last_scan_jiffies = jiffies; | ||
1738 | priv->next_scan_jiffies = 0; | ||
1739 | } | ||
1740 | |||
1741 | /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ | ||
1742 | static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | ||
1743 | struct iwl_rx_mem_buffer *rxb) | ||
1744 | { | ||
1745 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1746 | struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; | ||
1747 | |||
1748 | IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", | ||
1749 | scan_notif->scanned_channels, | ||
1750 | scan_notif->tsf_low, | ||
1751 | scan_notif->tsf_high, scan_notif->status); | ||
1752 | |||
1753 | /* The HW is no longer scanning */ | ||
1754 | clear_bit(STATUS_SCAN_HW, &priv->status); | ||
1755 | |||
1756 | /* The scan completion notification came in, so kill that timer... */ | ||
1757 | cancel_delayed_work(&priv->scan_check); | ||
1758 | |||
1759 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | ||
1760 | (priv->scan_bands == 2) ? "2.4" : "5.2", | ||
1761 | jiffies_to_msecs(elapsed_jiffies | ||
1762 | (priv->scan_pass_start, jiffies))); | ||
1763 | |||
1764 | /* Remove this scanned band from the list | ||
1765 | * of pending bands to scan */ | ||
1766 | priv->scan_bands--; | ||
1767 | |||
1768 | /* If a request to abort was given, or the scan did not succeed | ||
1769 | * then we reset the scan state machine and terminate, | ||
1770 | * re-queuing another scan if one has been requested */ | ||
1771 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
1772 | IWL_DEBUG_INFO("Aborted scan completed.\n"); | ||
1773 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
1774 | } else { | ||
1775 | /* If there are more bands on this scan pass reschedule */ | ||
1776 | if (priv->scan_bands > 0) | ||
1777 | goto reschedule; | ||
1778 | } | ||
1779 | |||
1780 | priv->last_scan_jiffies = jiffies; | ||
1781 | priv->next_scan_jiffies = 0; | ||
1782 | IWL_DEBUG_INFO("Setting scan to off\n"); | ||
1783 | |||
1784 | clear_bit(STATUS_SCANNING, &priv->status); | ||
1785 | |||
1786 | IWL_DEBUG_INFO("Scan took %dms\n", | ||
1787 | jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies))); | ||
1788 | |||
1789 | queue_work(priv->workqueue, &priv->scan_completed); | ||
1790 | |||
1791 | return; | ||
1792 | |||
1793 | reschedule: | ||
1794 | priv->scan_pass_start = jiffies; | ||
1795 | queue_work(priv->workqueue, &priv->request_scan); | ||
1796 | } | ||
1797 | |||
1798 | /* Handle notification from uCode that card's power state is changing | 1270 | /* Handle notification from uCode that card's power state is changing |
1799 | * due to software, hardware, or critical temperature RFKILL */ | 1271 | * due to software, hardware, or critical temperature RFKILL */ |
1800 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | 1272 | static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, |
@@ -1855,7 +1327,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, | |||
1855 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | 1327 | clear_bit(STATUS_RF_KILL_SW, &priv->status); |
1856 | 1328 | ||
1857 | if (!(flags & RXON_CARD_DISABLED)) | 1329 | if (!(flags & RXON_CARD_DISABLED)) |
1858 | iwl4965_scan_cancel(priv); | 1330 | iwl_scan_cancel(priv); |
1859 | 1331 | ||
1860 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1332 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
1861 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1333 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || |
@@ -1905,13 +1377,9 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
1905 | */ | 1377 | */ |
1906 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; | 1378 | priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; |
1907 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; | 1379 | priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; |
1908 | /* scan handlers */ | 1380 | |
1909 | priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan; | 1381 | iwl_setup_rx_scan_handlers(priv); |
1910 | priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif; | 1382 | |
1911 | priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = | ||
1912 | iwl4965_rx_scan_results_notif; | ||
1913 | priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = | ||
1914 | iwl4965_rx_scan_complete_notif; | ||
1915 | /* status change handler */ | 1383 | /* status change handler */ |
1916 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; | 1384 | priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; |
1917 | 1385 | ||
@@ -2049,42 +1517,6 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
2049 | priv->rxq.read = i; | 1517 | priv->rxq.read = i; |
2050 | iwl_rx_queue_restock(priv); | 1518 | iwl_rx_queue_restock(priv); |
2051 | } | 1519 | } |
2052 | /* Convert linear signal-to-noise ratio into dB */ | ||
2053 | static u8 ratio2dB[100] = { | ||
2054 | /* 0 1 2 3 4 5 6 7 8 9 */ | ||
2055 | 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ | ||
2056 | 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ | ||
2057 | 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ | ||
2058 | 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ | ||
2059 | 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ | ||
2060 | 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ | ||
2061 | 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ | ||
2062 | 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ | ||
2063 | 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ | ||
2064 | 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ | ||
2065 | }; | ||
2066 | |||
2067 | /* Calculates a relative dB value from a ratio of linear | ||
2068 | * (i.e. not dB) signal levels. | ||
2069 | * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ | ||
2070 | int iwl4965_calc_db_from_ratio(int sig_ratio) | ||
2071 | { | ||
2072 | /* 1000:1 or higher just report as 60 dB */ | ||
2073 | if (sig_ratio >= 1000) | ||
2074 | return 60; | ||
2075 | |||
2076 | /* 100:1 or higher, divide by 10 and use table, | ||
2077 | * add 20 dB to make up for divide by 10 */ | ||
2078 | if (sig_ratio >= 100) | ||
2079 | return (20 + (int)ratio2dB[sig_ratio/10]); | ||
2080 | |||
2081 | /* We shouldn't see this */ | ||
2082 | if (sig_ratio < 1) | ||
2083 | return 0; | ||
2084 | |||
2085 | /* Use table for ratios 1:1 - 99:1 */ | ||
2086 | return (int)ratio2dB[sig_ratio]; | ||
2087 | } | ||
2088 | 1520 | ||
2089 | #define PERFECT_RSSI (-20) /* dBm */ | 1521 | #define PERFECT_RSSI (-20) /* dBm */ |
2090 | #define WORST_RSSI (-95) /* dBm */ | 1522 | #define WORST_RSSI (-95) /* dBm */ |
@@ -2459,138 +1891,6 @@ static irqreturn_t iwl4965_isr(int irq, void *data) | |||
2459 | return IRQ_NONE; | 1891 | return IRQ_NONE; |
2460 | } | 1892 | } |
2461 | 1893 | ||
2462 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | ||
2463 | * sending probe req. This should be set long enough to hear probe responses | ||
2464 | * from more than one AP. */ | ||
2465 | #define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
2466 | #define IWL_ACTIVE_DWELL_TIME_52 (10) | ||
2467 | |||
2468 | /* For faster active scanning, scan will move to the next channel if fewer than | ||
2469 | * PLCP_QUIET_THRESH packets are heard on this channel within | ||
2470 | * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell | ||
2471 | * time if it's a quiet channel (nothing responded to our probe, and there's | ||
2472 | * no other traffic). | ||
2473 | * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ | ||
2474 | #define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ | ||
2475 | #define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ | ||
2476 | |||
2477 | /* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. | ||
2478 | * Must be set longer than active dwell time. | ||
2479 | * For the most reliable scan, set > AP beacon interval (typically 100msec). */ | ||
2480 | #define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ | ||
2481 | #define IWL_PASSIVE_DWELL_TIME_52 (10) | ||
2482 | #define IWL_PASSIVE_DWELL_BASE (100) | ||
2483 | #define IWL_CHANNEL_TUNE_TIME 5 | ||
2484 | |||
2485 | static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv, | ||
2486 | enum ieee80211_band band) | ||
2487 | { | ||
2488 | if (band == IEEE80211_BAND_5GHZ) | ||
2489 | return IWL_ACTIVE_DWELL_TIME_52; | ||
2490 | else | ||
2491 | return IWL_ACTIVE_DWELL_TIME_24; | ||
2492 | } | ||
2493 | |||
2494 | static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv, | ||
2495 | enum ieee80211_band band) | ||
2496 | { | ||
2497 | u16 active = iwl4965_get_active_dwell_time(priv, band); | ||
2498 | u16 passive = (band != IEEE80211_BAND_5GHZ) ? | ||
2499 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : | ||
2500 | IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; | ||
2501 | |||
2502 | if (iwl_is_associated(priv)) { | ||
2503 | /* If we're associated, we clamp the maximum passive | ||
2504 | * dwell time to be 98% of the beacon interval (minus | ||
2505 | * 2 * channel tune time) */ | ||
2506 | passive = priv->beacon_int; | ||
2507 | if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) | ||
2508 | passive = IWL_PASSIVE_DWELL_BASE; | ||
2509 | passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; | ||
2510 | } | ||
2511 | |||
2512 | if (passive <= active) | ||
2513 | passive = active + 1; | ||
2514 | |||
2515 | return passive; | ||
2516 | } | ||
2517 | |||
2518 | static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | ||
2519 | enum ieee80211_band band, | ||
2520 | u8 is_active, u8 direct_mask, | ||
2521 | struct iwl4965_scan_channel *scan_ch) | ||
2522 | { | ||
2523 | const struct ieee80211_channel *channels = NULL; | ||
2524 | const struct ieee80211_supported_band *sband; | ||
2525 | const struct iwl_channel_info *ch_info; | ||
2526 | u16 passive_dwell = 0; | ||
2527 | u16 active_dwell = 0; | ||
2528 | int added, i; | ||
2529 | |||
2530 | sband = iwl_get_hw_mode(priv, band); | ||
2531 | if (!sband) | ||
2532 | return 0; | ||
2533 | |||
2534 | channels = sband->channels; | ||
2535 | |||
2536 | active_dwell = iwl4965_get_active_dwell_time(priv, band); | ||
2537 | passive_dwell = iwl4965_get_passive_dwell_time(priv, band); | ||
2538 | |||
2539 | for (i = 0, added = 0; i < sband->n_channels; i++) { | ||
2540 | if (channels[i].flags & IEEE80211_CHAN_DISABLED) | ||
2541 | continue; | ||
2542 | |||
2543 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); | ||
2544 | |||
2545 | ch_info = iwl_get_channel_info(priv, band, | ||
2546 | scan_ch->channel); | ||
2547 | if (!is_channel_valid(ch_info)) { | ||
2548 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | ||
2549 | scan_ch->channel); | ||
2550 | continue; | ||
2551 | } | ||
2552 | |||
2553 | if (!is_active || is_channel_passive(ch_info) || | ||
2554 | (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) | ||
2555 | scan_ch->type = 0; /* passive */ | ||
2556 | else | ||
2557 | scan_ch->type = 1; /* active */ | ||
2558 | |||
2559 | if (scan_ch->type & 1) | ||
2560 | scan_ch->type |= (direct_mask << 1); | ||
2561 | |||
2562 | scan_ch->active_dwell = cpu_to_le16(active_dwell); | ||
2563 | scan_ch->passive_dwell = cpu_to_le16(passive_dwell); | ||
2564 | |||
2565 | /* Set txpower levels to defaults */ | ||
2566 | scan_ch->tpc.dsp_atten = 110; | ||
2567 | /* scan_pwr_info->tpc.dsp_atten; */ | ||
2568 | |||
2569 | /*scan_pwr_info->tpc.tx_gain; */ | ||
2570 | if (band == IEEE80211_BAND_5GHZ) | ||
2571 | scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; | ||
2572 | else { | ||
2573 | scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); | ||
2574 | /* NOTE: if we were doing 6Mb OFDM for scans we'd use | ||
2575 | * power level: | ||
2576 | * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; | ||
2577 | */ | ||
2578 | } | ||
2579 | |||
2580 | IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", | ||
2581 | scan_ch->channel, | ||
2582 | (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", | ||
2583 | (scan_ch->type & 1) ? | ||
2584 | active_dwell : passive_dwell); | ||
2585 | |||
2586 | scan_ch++; | ||
2587 | added++; | ||
2588 | } | ||
2589 | |||
2590 | IWL_DEBUG_SCAN("total channels to scan %d \n", added); | ||
2591 | return added; | ||
2592 | } | ||
2593 | |||
2594 | /****************************************************************************** | 1894 | /****************************************************************************** |
2595 | * | 1895 | * |
2596 | * uCode download functions | 1896 | * uCode download functions |
@@ -2621,7 +1921,7 @@ static void iwl4965_nic_start(struct iwl_priv *priv) | |||
2621 | */ | 1921 | */ |
2622 | static int iwl4965_read_ucode(struct iwl_priv *priv) | 1922 | static int iwl4965_read_ucode(struct iwl_priv *priv) |
2623 | { | 1923 | { |
2624 | struct iwl4965_ucode *ucode; | 1924 | struct iwl_ucode *ucode; |
2625 | int ret; | 1925 | int ret; |
2626 | const struct firmware *ucode_raw; | 1926 | const struct firmware *ucode_raw; |
2627 | const char *name = priv->cfg->fw_name; | 1927 | const char *name = priv->cfg->fw_name; |
@@ -2849,9 +2149,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2849 | /* After the ALIVE response, we can send host commands to 4965 uCode */ | 2149 | /* After the ALIVE response, we can send host commands to 4965 uCode */ |
2850 | set_bit(STATUS_ALIVE, &priv->status); | 2150 | set_bit(STATUS_ALIVE, &priv->status); |
2851 | 2151 | ||
2852 | /* Clear out the uCode error bit if it is set */ | ||
2853 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
2854 | |||
2855 | if (iwl_is_rfkill(priv)) | 2152 | if (iwl_is_rfkill(priv)) |
2856 | return; | 2153 | return; |
2857 | 2154 | ||
@@ -2882,7 +2179,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2882 | iwl4965_commit_rxon(priv); | 2179 | iwl4965_commit_rxon(priv); |
2883 | 2180 | ||
2884 | /* At this point, the NIC is initialized and operational */ | 2181 | /* At this point, the NIC is initialized and operational */ |
2885 | iwl4965_rf_kill_ct_config(priv); | 2182 | iwl_rf_kill_ct_config(priv); |
2886 | 2183 | ||
2887 | iwl_leds_register(priv); | 2184 | iwl_leds_register(priv); |
2888 | 2185 | ||
@@ -2893,15 +2190,19 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2893 | if (priv->error_recovering) | 2190 | if (priv->error_recovering) |
2894 | iwl4965_error_recovery(priv); | 2191 | iwl4965_error_recovery(priv); |
2895 | 2192 | ||
2896 | iwlcore_low_level_notify(priv, IWLCORE_START_EVT); | 2193 | iwl_power_update_mode(priv, 1); |
2897 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); | 2194 | ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); |
2195 | |||
2196 | if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) | ||
2197 | iwl4965_set_mode(priv, priv->iw_mode); | ||
2198 | |||
2898 | return; | 2199 | return; |
2899 | 2200 | ||
2900 | restart: | 2201 | restart: |
2901 | queue_work(priv->workqueue, &priv->restart); | 2202 | queue_work(priv->workqueue, &priv->restart); |
2902 | } | 2203 | } |
2903 | 2204 | ||
2904 | static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); | 2205 | static void iwl_cancel_deferred_work(struct iwl_priv *priv); |
2905 | 2206 | ||
2906 | static void __iwl4965_down(struct iwl_priv *priv) | 2207 | static void __iwl4965_down(struct iwl_priv *priv) |
2907 | { | 2208 | { |
@@ -2915,8 +2216,6 @@ static void __iwl4965_down(struct iwl_priv *priv) | |||
2915 | 2216 | ||
2916 | iwl_leds_unregister(priv); | 2217 | iwl_leds_unregister(priv); |
2917 | 2218 | ||
2918 | iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT); | ||
2919 | |||
2920 | iwlcore_clear_stations_table(priv); | 2219 | iwlcore_clear_stations_table(priv); |
2921 | 2220 | ||
2922 | /* Unblock any waiting calls */ | 2221 | /* Unblock any waiting calls */ |
@@ -3005,7 +2304,7 @@ static void iwl4965_down(struct iwl_priv *priv) | |||
3005 | __iwl4965_down(priv); | 2304 | __iwl4965_down(priv); |
3006 | mutex_unlock(&priv->mutex); | 2305 | mutex_unlock(&priv->mutex); |
3007 | 2306 | ||
3008 | iwl4965_cancel_deferred_work(priv); | 2307 | iwl_cancel_deferred_work(priv); |
3009 | } | 2308 | } |
3010 | 2309 | ||
3011 | #define MAX_HW_RESTARTS 5 | 2310 | #define MAX_HW_RESTARTS 5 |
@@ -3020,13 +2319,6 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
3020 | return -EIO; | 2319 | return -EIO; |
3021 | } | 2320 | } |
3022 | 2321 | ||
3023 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
3024 | IWL_WARNING("Radio disabled by SW RF kill (module " | ||
3025 | "parameter)\n"); | ||
3026 | iwl_rfkill_set_hw_state(priv); | ||
3027 | return -ENODEV; | ||
3028 | } | ||
3029 | |||
3030 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2322 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
3031 | IWL_ERROR("ucode not available for device bringup\n"); | 2323 | IWL_ERROR("ucode not available for device bringup\n"); |
3032 | return -EIO; | 2324 | return -EIO; |
@@ -3080,7 +2372,8 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
3080 | priv->ucode_data.len); | 2372 | priv->ucode_data.len); |
3081 | 2373 | ||
3082 | /* We return success when we resume from suspend and rf_kill is on. */ | 2374 | /* We return success when we resume from suspend and rf_kill is on. */ |
3083 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2375 | if (test_bit(STATUS_RF_KILL_HW, &priv->status) || |
2376 | test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
3084 | return 0; | 2377 | return 0; |
3085 | 2378 | ||
3086 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2379 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
@@ -3097,6 +2390,9 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
3097 | continue; | 2390 | continue; |
3098 | } | 2391 | } |
3099 | 2392 | ||
2393 | /* Clear out the uCode error bit if it is set */ | ||
2394 | clear_bit(STATUS_FW_ERROR, &priv->status); | ||
2395 | |||
3100 | /* start card; "initialize" will load runtime ucode */ | 2396 | /* start card; "initialize" will load runtime ucode */ |
3101 | iwl4965_nic_start(priv); | 2397 | iwl4965_nic_start(priv); |
3102 | 2398 | ||
@@ -3107,6 +2403,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
3107 | 2403 | ||
3108 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2404 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
3109 | __iwl4965_down(priv); | 2405 | __iwl4965_down(priv); |
2406 | clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||
3110 | 2407 | ||
3111 | /* tried to restart and config the device for as long as our | 2408 | /* tried to restart and config the device for as long as our |
3112 | * patience could withstand */ | 2409 | * patience could withstand */ |
@@ -3186,255 +2483,45 @@ static void iwl4965_bg_set_monitor(struct work_struct *work) | |||
3186 | { | 2483 | { |
3187 | struct iwl_priv *priv = container_of(work, | 2484 | struct iwl_priv *priv = container_of(work, |
3188 | struct iwl_priv, set_monitor); | 2485 | struct iwl_priv, set_monitor); |
2486 | int ret; | ||
3189 | 2487 | ||
3190 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); | 2488 | IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); |
3191 | 2489 | ||
3192 | mutex_lock(&priv->mutex); | 2490 | mutex_lock(&priv->mutex); |
3193 | 2491 | ||
3194 | if (!iwl_is_ready(priv)) | 2492 | ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR); |
3195 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); | ||
3196 | else | ||
3197 | if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) | ||
3198 | IWL_ERROR("iwl4965_set_mode() failed\n"); | ||
3199 | |||
3200 | mutex_unlock(&priv->mutex); | ||
3201 | } | ||
3202 | 2493 | ||
3203 | #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) | 2494 | if (ret) { |
3204 | 2495 | if (ret == -EAGAIN) | |
3205 | static void iwl4965_bg_scan_check(struct work_struct *data) | 2496 | IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); |
3206 | { | 2497 | else |
3207 | struct iwl_priv *priv = | 2498 | IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret); |
3208 | container_of(data, struct iwl_priv, scan_check.work); | ||
3209 | |||
3210 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
3211 | return; | ||
3212 | |||
3213 | mutex_lock(&priv->mutex); | ||
3214 | if (test_bit(STATUS_SCANNING, &priv->status) || | ||
3215 | test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
3216 | IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " | ||
3217 | "adapter (%dms)\n", | ||
3218 | jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); | ||
3219 | |||
3220 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
3221 | iwl4965_send_scan_abort(priv); | ||
3222 | } | 2499 | } |
2500 | |||
3223 | mutex_unlock(&priv->mutex); | 2501 | mutex_unlock(&priv->mutex); |
3224 | } | 2502 | } |
3225 | 2503 | ||
3226 | static void iwl4965_bg_request_scan(struct work_struct *data) | 2504 | static void iwl_bg_run_time_calib_work(struct work_struct *work) |
3227 | { | 2505 | { |
3228 | struct iwl_priv *priv = | 2506 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
3229 | container_of(data, struct iwl_priv, request_scan); | 2507 | run_time_calib_work); |
3230 | struct iwl_host_cmd cmd = { | ||
3231 | .id = REPLY_SCAN_CMD, | ||
3232 | .len = sizeof(struct iwl4965_scan_cmd), | ||
3233 | .meta.flags = CMD_SIZE_HUGE, | ||
3234 | }; | ||
3235 | struct iwl4965_scan_cmd *scan; | ||
3236 | struct ieee80211_conf *conf = NULL; | ||
3237 | u16 cmd_len; | ||
3238 | enum ieee80211_band band; | ||
3239 | u8 direct_mask; | ||
3240 | int ret = 0; | ||
3241 | |||
3242 | conf = ieee80211_get_hw_conf(priv->hw); | ||
3243 | 2508 | ||
3244 | mutex_lock(&priv->mutex); | 2509 | mutex_lock(&priv->mutex); |
3245 | 2510 | ||
3246 | if (!iwl_is_ready(priv)) { | 2511 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
3247 | IWL_WARNING("request scan called when driver not ready.\n"); | 2512 | test_bit(STATUS_SCANNING, &priv->status)) { |
3248 | goto done; | 2513 | mutex_unlock(&priv->mutex); |
3249 | } | 2514 | return; |
3250 | |||
3251 | /* Make sure the scan wasn't cancelled before this queued work | ||
3252 | * was given the chance to run... */ | ||
3253 | if (!test_bit(STATUS_SCANNING, &priv->status)) | ||
3254 | goto done; | ||
3255 | |||
3256 | /* This should never be called or scheduled if there is currently | ||
3257 | * a scan active in the hardware. */ | ||
3258 | if (test_bit(STATUS_SCAN_HW, &priv->status)) { | ||
3259 | IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. " | ||
3260 | "Ignoring second request.\n"); | ||
3261 | ret = -EIO; | ||
3262 | goto done; | ||
3263 | } | ||
3264 | |||
3265 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
3266 | IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n"); | ||
3267 | goto done; | ||
3268 | } | ||
3269 | |||
3270 | if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { | ||
3271 | IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | ||
3272 | goto done; | ||
3273 | } | ||
3274 | |||
3275 | if (iwl_is_rfkill(priv)) { | ||
3276 | IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | ||
3277 | goto done; | ||
3278 | } | ||
3279 | |||
3280 | if (!test_bit(STATUS_READY, &priv->status)) { | ||
3281 | IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n"); | ||
3282 | goto done; | ||
3283 | } | ||
3284 | |||
3285 | if (!priv->scan_bands) { | ||
3286 | IWL_DEBUG_HC("Aborting scan due to no requested bands\n"); | ||
3287 | goto done; | ||
3288 | } | ||
3289 | |||
3290 | if (!priv->scan) { | ||
3291 | priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) + | ||
3292 | IWL_MAX_SCAN_SIZE, GFP_KERNEL); | ||
3293 | if (!priv->scan) { | ||
3294 | ret = -ENOMEM; | ||
3295 | goto done; | ||
3296 | } | ||
3297 | } | ||
3298 | scan = priv->scan; | ||
3299 | memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE); | ||
3300 | |||
3301 | scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; | ||
3302 | scan->quiet_time = IWL_ACTIVE_QUIET_TIME; | ||
3303 | |||
3304 | if (iwl_is_associated(priv)) { | ||
3305 | u16 interval = 0; | ||
3306 | u32 extra; | ||
3307 | u32 suspend_time = 100; | ||
3308 | u32 scan_suspend_time = 100; | ||
3309 | unsigned long flags; | ||
3310 | |||
3311 | IWL_DEBUG_INFO("Scanning while associated...\n"); | ||
3312 | |||
3313 | spin_lock_irqsave(&priv->lock, flags); | ||
3314 | interval = priv->beacon_int; | ||
3315 | spin_unlock_irqrestore(&priv->lock, flags); | ||
3316 | |||
3317 | scan->suspend_time = 0; | ||
3318 | scan->max_out_time = cpu_to_le32(200 * 1024); | ||
3319 | if (!interval) | ||
3320 | interval = suspend_time; | ||
3321 | |||
3322 | extra = (suspend_time / interval) << 22; | ||
3323 | scan_suspend_time = (extra | | ||
3324 | ((suspend_time % interval) * 1024)); | ||
3325 | scan->suspend_time = cpu_to_le32(scan_suspend_time); | ||
3326 | IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n", | ||
3327 | scan_suspend_time, interval); | ||
3328 | } | ||
3329 | |||
3330 | /* We should add the ability for user to lock to PASSIVE ONLY */ | ||
3331 | if (priv->one_direct_scan) { | ||
3332 | IWL_DEBUG_SCAN | ||
3333 | ("Kicking off one direct scan for '%s'\n", | ||
3334 | iwl4965_escape_essid(priv->direct_ssid, | ||
3335 | priv->direct_ssid_len)); | ||
3336 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
3337 | scan->direct_scan[0].len = priv->direct_ssid_len; | ||
3338 | memcpy(scan->direct_scan[0].ssid, | ||
3339 | priv->direct_ssid, priv->direct_ssid_len); | ||
3340 | direct_mask = 1; | ||
3341 | } else if (!iwl_is_associated(priv) && priv->essid_len) { | ||
3342 | IWL_DEBUG_SCAN | ||
3343 | ("Kicking off one direct scan for '%s' when not associated\n", | ||
3344 | iwl4965_escape_essid(priv->essid, priv->essid_len)); | ||
3345 | scan->direct_scan[0].id = WLAN_EID_SSID; | ||
3346 | scan->direct_scan[0].len = priv->essid_len; | ||
3347 | memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); | ||
3348 | direct_mask = 1; | ||
3349 | } else { | ||
3350 | IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); | ||
3351 | direct_mask = 0; | ||
3352 | } | 2515 | } |
3353 | 2516 | ||
3354 | scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; | 2517 | if (priv->start_calib) { |
3355 | scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; | 2518 | iwl_chain_noise_calibration(priv, &priv->statistics); |
3356 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | ||
3357 | |||
3358 | |||
3359 | switch (priv->scan_bands) { | ||
3360 | case 2: | ||
3361 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | ||
3362 | scan->tx_cmd.rate_n_flags = | ||
3363 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | ||
3364 | RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); | ||
3365 | |||
3366 | scan->good_CRC_th = 0; | ||
3367 | band = IEEE80211_BAND_2GHZ; | ||
3368 | break; | ||
3369 | |||
3370 | case 1: | ||
3371 | scan->tx_cmd.rate_n_flags = | ||
3372 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | ||
3373 | RATE_MCS_ANT_B_MSK); | ||
3374 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | ||
3375 | band = IEEE80211_BAND_5GHZ; | ||
3376 | break; | ||
3377 | 2519 | ||
3378 | default: | 2520 | iwl_sensitivity_calibration(priv, &priv->statistics); |
3379 | IWL_WARNING("Invalid scan band count\n"); | ||
3380 | goto done; | ||
3381 | } | 2521 | } |
3382 | 2522 | ||
3383 | /* We don't build a direct scan probe request; the uCode will do | ||
3384 | * that based on the direct_mask added to each channel entry */ | ||
3385 | cmd_len = iwl4965_fill_probe_req(priv, band, | ||
3386 | (struct ieee80211_mgmt *)scan->data, | ||
3387 | IWL_MAX_SCAN_SIZE - sizeof(*scan), 0); | ||
3388 | |||
3389 | scan->tx_cmd.len = cpu_to_le16(cmd_len); | ||
3390 | /* select Rx chains */ | ||
3391 | |||
3392 | /* Force use of chains B and C (0x6) for scan Rx. | ||
3393 | * Avoid A (0x1) because of its off-channel reception on A-band. | ||
3394 | * MIMO is not used here, but value is required to make uCode happy. */ | ||
3395 | scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | | ||
3396 | cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | | ||
3397 | (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) | | ||
3398 | (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); | ||
3399 | |||
3400 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) | ||
3401 | scan->filter_flags = RXON_FILTER_PROMISC_MSK; | ||
3402 | |||
3403 | if (direct_mask) | ||
3404 | scan->channel_count = | ||
3405 | iwl4965_get_channels_for_scan( | ||
3406 | priv, band, 1, /* active */ | ||
3407 | direct_mask, | ||
3408 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
3409 | else | ||
3410 | scan->channel_count = | ||
3411 | iwl4965_get_channels_for_scan( | ||
3412 | priv, band, 0, /* passive */ | ||
3413 | direct_mask, | ||
3414 | (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); | ||
3415 | |||
3416 | scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | | ||
3417 | RXON_FILTER_BCON_AWARE_MSK); | ||
3418 | cmd.len += le16_to_cpu(scan->tx_cmd.len) + | ||
3419 | scan->channel_count * sizeof(struct iwl4965_scan_channel); | ||
3420 | cmd.data = scan; | ||
3421 | scan->len = cpu_to_le16(cmd.len); | ||
3422 | |||
3423 | set_bit(STATUS_SCAN_HW, &priv->status); | ||
3424 | ret = iwl_send_cmd_sync(priv, &cmd); | ||
3425 | if (ret) | ||
3426 | goto done; | ||
3427 | |||
3428 | queue_delayed_work(priv->workqueue, &priv->scan_check, | ||
3429 | IWL_SCAN_CHECK_WATCHDOG); | ||
3430 | |||
3431 | mutex_unlock(&priv->mutex); | 2523 | mutex_unlock(&priv->mutex); |
3432 | return; | 2524 | return; |
3433 | |||
3434 | done: | ||
3435 | /* inform mac80211 scan aborted */ | ||
3436 | queue_work(priv->workqueue, &priv->scan_completed); | ||
3437 | mutex_unlock(&priv->mutex); | ||
3438 | } | 2525 | } |
3439 | 2526 | ||
3440 | static void iwl4965_bg_up(struct work_struct *data) | 2527 | static void iwl4965_bg_up(struct work_struct *data) |
@@ -3498,7 +2585,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
3498 | if (!priv->vif || !priv->is_open) | 2585 | if (!priv->vif || !priv->is_open) |
3499 | return; | 2586 | return; |
3500 | 2587 | ||
3501 | iwl4965_scan_cancel_timeout(priv, 200); | 2588 | iwl_scan_cancel_timeout(priv, 200); |
3502 | 2589 | ||
3503 | conf = ieee80211_get_hw_conf(priv->hw); | 2590 | conf = ieee80211_get_hw_conf(priv->hw); |
3504 | 2591 | ||
@@ -3515,10 +2602,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
3515 | 2602 | ||
3516 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 2603 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3517 | 2604 | ||
3518 | #ifdef CONFIG_IWL4965_HT | ||
3519 | if (priv->current_ht_config.is_ht) | 2605 | if (priv->current_ht_config.is_ht) |
3520 | iwl_set_rxon_ht(priv, &priv->current_ht_config); | 2606 | iwl_set_rxon_ht(priv, &priv->current_ht_config); |
3521 | #endif /* CONFIG_IWL4965_HT*/ | 2607 | |
3522 | iwl_set_rxon_chain(priv); | 2608 | iwl_set_rxon_chain(priv); |
3523 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); | 2609 | priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); |
3524 | 2610 | ||
@@ -3550,10 +2636,9 @@ static void iwl4965_post_associate(struct iwl_priv *priv) | |||
3550 | 2636 | ||
3551 | case IEEE80211_IF_TYPE_IBSS: | 2637 | case IEEE80211_IF_TYPE_IBSS: |
3552 | 2638 | ||
3553 | /* clear out the station table */ | 2639 | /* assume default assoc id */ |
3554 | iwlcore_clear_stations_table(priv); | 2640 | priv->assoc_id = 1; |
3555 | 2641 | ||
3556 | iwl_rxon_add_station(priv, iwl_bcast_addr, 0); | ||
3557 | iwl_rxon_add_station(priv, priv->bssid, 0); | 2642 | iwl_rxon_add_station(priv, priv->bssid, 0); |
3558 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); | 2643 | iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); |
3559 | iwl4965_send_beacon_cmd(priv); | 2644 | iwl4965_send_beacon_cmd(priv); |
@@ -3594,29 +2679,14 @@ static void iwl4965_bg_post_associate(struct work_struct *data) | |||
3594 | 2679 | ||
3595 | } | 2680 | } |
3596 | 2681 | ||
3597 | static void iwl4965_bg_abort_scan(struct work_struct *work) | ||
3598 | { | ||
3599 | struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); | ||
3600 | |||
3601 | if (!iwl_is_ready(priv)) | ||
3602 | return; | ||
3603 | |||
3604 | mutex_lock(&priv->mutex); | ||
3605 | |||
3606 | set_bit(STATUS_SCAN_ABORTING, &priv->status); | ||
3607 | iwl4965_send_scan_abort(priv); | ||
3608 | |||
3609 | mutex_unlock(&priv->mutex); | ||
3610 | } | ||
3611 | |||
3612 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); | 2682 | static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); |
3613 | 2683 | ||
3614 | static void iwl4965_bg_scan_completed(struct work_struct *work) | 2684 | static void iwl_bg_scan_completed(struct work_struct *work) |
3615 | { | 2685 | { |
3616 | struct iwl_priv *priv = | 2686 | struct iwl_priv *priv = |
3617 | container_of(work, struct iwl_priv, scan_completed); | 2687 | container_of(work, struct iwl_priv, scan_completed); |
3618 | 2688 | ||
3619 | IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n"); | 2689 | IWL_DEBUG_SCAN("SCAN complete scan\n"); |
3620 | 2690 | ||
3621 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2691 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
3622 | return; | 2692 | return; |
@@ -3629,7 +2699,7 @@ static void iwl4965_bg_scan_completed(struct work_struct *work) | |||
3629 | /* Since setting the TXPOWER may have been deferred while | 2699 | /* Since setting the TXPOWER may have been deferred while |
3630 | * performing the scan, fire one off */ | 2700 | * performing the scan, fire one off */ |
3631 | mutex_lock(&priv->mutex); | 2701 | mutex_lock(&priv->mutex); |
3632 | iwl4965_hw_reg_send_txpower(priv); | 2702 | iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); |
3633 | mutex_unlock(&priv->mutex); | 2703 | mutex_unlock(&priv->mutex); |
3634 | } | 2704 | } |
3635 | 2705 | ||
@@ -3738,7 +2808,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
3738 | * RXON_FILTER_ASSOC_MSK BIT | 2808 | * RXON_FILTER_ASSOC_MSK BIT |
3739 | */ | 2809 | */ |
3740 | mutex_lock(&priv->mutex); | 2810 | mutex_lock(&priv->mutex); |
3741 | iwl4965_scan_cancel_timeout(priv, 100); | 2811 | iwl_scan_cancel_timeout(priv, 100); |
3742 | cancel_delayed_work(&priv->post_associate); | 2812 | cancel_delayed_work(&priv->post_associate); |
3743 | mutex_unlock(&priv->mutex); | 2813 | mutex_unlock(&priv->mutex); |
3744 | } | 2814 | } |
@@ -3801,8 +2871,9 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, | |||
3801 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); | 2871 | memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); |
3802 | } | 2872 | } |
3803 | 2873 | ||
3804 | if (iwl_is_ready(priv)) | 2874 | if (iwl4965_set_mode(priv, conf->type) == -EAGAIN) |
3805 | iwl4965_set_mode(priv, conf->type); | 2875 | /* we are not ready, will run again when ready */ |
2876 | set_bit(STATUS_MODE_PENDING, &priv->status); | ||
3806 | 2877 | ||
3807 | mutex_unlock(&priv->mutex); | 2878 | mutex_unlock(&priv->mutex); |
3808 | 2879 | ||
@@ -3830,6 +2901,14 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
3830 | 2901 | ||
3831 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); | 2902 | priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); |
3832 | 2903 | ||
2904 | if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { | ||
2905 | IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); | ||
2906 | goto out; | ||
2907 | } | ||
2908 | |||
2909 | if (!conf->radio_enabled) | ||
2910 | iwl_radio_kill_sw_disable_radio(priv); | ||
2911 | |||
3833 | if (!iwl_is_ready(priv)) { | 2912 | if (!iwl_is_ready(priv)) { |
3834 | IWL_DEBUG_MAC80211("leave - not ready\n"); | 2913 | IWL_DEBUG_MAC80211("leave - not ready\n"); |
3835 | ret = -EIO; | 2914 | ret = -EIO; |
@@ -3852,9 +2931,16 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
3852 | goto out; | 2931 | goto out; |
3853 | } | 2932 | } |
3854 | 2933 | ||
2934 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && | ||
2935 | !is_channel_ibss(ch_info)) { | ||
2936 | IWL_ERROR("channel %d in band %d not IBSS channel\n", | ||
2937 | conf->channel->hw_value, conf->channel->band); | ||
2938 | ret = -EINVAL; | ||
2939 | goto out; | ||
2940 | } | ||
2941 | |||
3855 | spin_lock_irqsave(&priv->lock, flags); | 2942 | spin_lock_irqsave(&priv->lock, flags); |
3856 | 2943 | ||
3857 | #ifdef CONFIG_IWL4965_HT | ||
3858 | /* if we are switching from ht to 2.4 clear flags | 2944 | /* if we are switching from ht to 2.4 clear flags |
3859 | * from any ht related info since 2.4 does not | 2945 | * from any ht related info since 2.4 does not |
3860 | * support ht */ | 2946 | * support ht */ |
@@ -3864,7 +2950,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
3864 | #endif | 2950 | #endif |
3865 | ) | 2951 | ) |
3866 | priv->staging_rxon.flags = 0; | 2952 | priv->staging_rxon.flags = 0; |
3867 | #endif /* CONFIG_IWL4965_HT */ | ||
3868 | 2953 | ||
3869 | iwl_set_rxon_channel(priv, conf->channel->band, channel); | 2954 | iwl_set_rxon_channel(priv, conf->channel->band, channel); |
3870 | 2955 | ||
@@ -3884,9 +2969,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
3884 | } | 2969 | } |
3885 | #endif | 2970 | #endif |
3886 | 2971 | ||
3887 | if (priv->cfg->ops->lib->radio_kill_sw) | ||
3888 | priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled); | ||
3889 | |||
3890 | if (!conf->radio_enabled) { | 2972 | if (!conf->radio_enabled) { |
3891 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); | 2973 | IWL_DEBUG_MAC80211("leave - radio disabled\n"); |
3892 | goto out; | 2974 | goto out; |
@@ -3898,6 +2980,11 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co | |||
3898 | goto out; | 2980 | goto out; |
3899 | } | 2981 | } |
3900 | 2982 | ||
2983 | IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n", | ||
2984 | priv->tx_power_user_lmt, conf->power_level); | ||
2985 | |||
2986 | iwl_set_tx_power(priv, conf->power_level, false); | ||
2987 | |||
3901 | iwl4965_set_rate(priv); | 2988 | iwl4965_set_rate(priv); |
3902 | 2989 | ||
3903 | if (memcmp(&priv->active_rxon, | 2990 | if (memcmp(&priv->active_rxon, |
@@ -4034,7 +3121,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
4034 | !is_multicast_ether_addr(conf->bssid)) { | 3121 | !is_multicast_ether_addr(conf->bssid)) { |
4035 | /* If there is currently a HW scan going on in the background | 3122 | /* If there is currently a HW scan going on in the background |
4036 | * then we need to cancel it else the RXON below will fail. */ | 3123 | * then we need to cancel it else the RXON below will fail. */ |
4037 | if (iwl4965_scan_cancel_timeout(priv, 100)) { | 3124 | if (iwl_scan_cancel_timeout(priv, 100)) { |
4038 | IWL_WARNING("Aborted scan still in progress " | 3125 | IWL_WARNING("Aborted scan still in progress " |
4039 | "after 100ms\n"); | 3126 | "after 100ms\n"); |
4040 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); | 3127 | IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); |
@@ -4059,7 +3146,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, | |||
4059 | } | 3146 | } |
4060 | 3147 | ||
4061 | } else { | 3148 | } else { |
4062 | iwl4965_scan_cancel_timeout(priv, 100); | 3149 | iwl_scan_cancel_timeout(priv, 100); |
4063 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3150 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
4064 | iwl4965_commit_rxon(priv); | 3151 | iwl4965_commit_rxon(priv); |
4065 | } | 3152 | } |
@@ -4117,7 +3204,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
4117 | mutex_lock(&priv->mutex); | 3204 | mutex_lock(&priv->mutex); |
4118 | 3205 | ||
4119 | if (iwl_is_ready_rf(priv)) { | 3206 | if (iwl_is_ready_rf(priv)) { |
4120 | iwl4965_scan_cancel_timeout(priv, 100); | 3207 | iwl_scan_cancel_timeout(priv, 100); |
4121 | cancel_delayed_work(&priv->post_associate); | 3208 | cancel_delayed_work(&priv->post_associate); |
4122 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3209 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
4123 | iwl4965_commit_rxon(priv); | 3210 | iwl4965_commit_rxon(priv); |
@@ -4231,7 +3318,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
4231 | } | 3318 | } |
4232 | if (len) { | 3319 | if (len) { |
4233 | IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", | 3320 | IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", |
4234 | iwl4965_escape_essid(ssid, len), (int)len); | 3321 | iwl_escape_essid(ssid, len), (int)len); |
4235 | 3322 | ||
4236 | priv->one_direct_scan = 1; | 3323 | priv->one_direct_scan = 1; |
4237 | priv->direct_ssid_len = (u8) | 3324 | priv->direct_ssid_len = (u8) |
@@ -4240,7 +3327,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) | |||
4240 | } else | 3327 | } else |
4241 | priv->one_direct_scan = 0; | 3328 | priv->one_direct_scan = 0; |
4242 | 3329 | ||
4243 | rc = iwl4965_scan_initiate(priv); | 3330 | rc = iwl_scan_initiate(priv); |
4244 | 3331 | ||
4245 | IWL_DEBUG_MAC80211("leave\n"); | 3332 | IWL_DEBUG_MAC80211("leave\n"); |
4246 | 3333 | ||
@@ -4271,7 +3358,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
4271 | return; | 3358 | return; |
4272 | } | 3359 | } |
4273 | 3360 | ||
4274 | iwl4965_scan_cancel_timeout(priv, 100); | 3361 | iwl_scan_cancel_timeout(priv, 100); |
4275 | 3362 | ||
4276 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); | 3363 | key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); |
4277 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); | 3364 | key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
@@ -4329,7 +3416,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
4329 | } | 3416 | } |
4330 | 3417 | ||
4331 | mutex_lock(&priv->mutex); | 3418 | mutex_lock(&priv->mutex); |
4332 | iwl4965_scan_cancel_timeout(priv, 100); | 3419 | iwl_scan_cancel_timeout(priv, 100); |
4333 | mutex_unlock(&priv->mutex); | 3420 | mutex_unlock(&priv->mutex); |
4334 | 3421 | ||
4335 | /* If we are getting WEP group key and we didn't receive any key mapping | 3422 | /* If we are getting WEP group key and we didn't receive any key mapping |
@@ -4489,11 +3576,9 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
4489 | IWL_DEBUG_MAC80211("enter\n"); | 3576 | IWL_DEBUG_MAC80211("enter\n"); |
4490 | 3577 | ||
4491 | priv->lq_mngr.lq_ready = 0; | 3578 | priv->lq_mngr.lq_ready = 0; |
4492 | #ifdef CONFIG_IWL4965_HT | ||
4493 | spin_lock_irqsave(&priv->lock, flags); | 3579 | spin_lock_irqsave(&priv->lock, flags); |
4494 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); | 3580 | memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); |
4495 | spin_unlock_irqrestore(&priv->lock, flags); | 3581 | spin_unlock_irqrestore(&priv->lock, flags); |
4496 | #endif /* CONFIG_IWL4965_HT */ | ||
4497 | 3582 | ||
4498 | iwl_reset_qos(priv); | 3583 | iwl_reset_qos(priv); |
4499 | 3584 | ||
@@ -4527,7 +3612,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) | |||
4527 | * clear RXON_FILTER_ASSOC_MSK bit | 3612 | * clear RXON_FILTER_ASSOC_MSK bit |
4528 | */ | 3613 | */ |
4529 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { | 3614 | if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { |
4530 | iwl4965_scan_cancel_timeout(priv, 100); | 3615 | iwl_scan_cancel_timeout(priv, 100); |
4531 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3616 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
4532 | iwl4965_commit_rxon(priv); | 3617 | iwl4965_commit_rxon(priv); |
4533 | } | 3618 | } |
@@ -4583,7 +3668,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk | |||
4583 | 3668 | ||
4584 | iwl_reset_qos(priv); | 3669 | iwl_reset_qos(priv); |
4585 | 3670 | ||
4586 | queue_work(priv->workqueue, &priv->post_associate.work); | 3671 | iwl4965_post_associate(priv); |
4587 | 3672 | ||
4588 | mutex_unlock(&priv->mutex); | 3673 | mutex_unlock(&priv->mutex); |
4589 | 3674 | ||
@@ -4665,7 +3750,7 @@ static ssize_t show_temperature(struct device *d, | |||
4665 | if (!iwl_is_alive(priv)) | 3750 | if (!iwl_is_alive(priv)) |
4666 | return -EAGAIN; | 3751 | return -EAGAIN; |
4667 | 3752 | ||
4668 | return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv)); | 3753 | return sprintf(buf, "%d\n", priv->temperature); |
4669 | } | 3754 | } |
4670 | 3755 | ||
4671 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); | 3756 | static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); |
@@ -4683,7 +3768,7 @@ static ssize_t show_tx_power(struct device *d, | |||
4683 | struct device_attribute *attr, char *buf) | 3768 | struct device_attribute *attr, char *buf) |
4684 | { | 3769 | { |
4685 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; | 3770 | struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; |
4686 | return sprintf(buf, "%d\n", priv->user_txpower_limit); | 3771 | return sprintf(buf, "%d\n", priv->tx_power_user_lmt); |
4687 | } | 3772 | } |
4688 | 3773 | ||
4689 | static ssize_t store_tx_power(struct device *d, | 3774 | static ssize_t store_tx_power(struct device *d, |
@@ -4699,7 +3784,7 @@ static ssize_t store_tx_power(struct device *d, | |||
4699 | printk(KERN_INFO DRV_NAME | 3784 | printk(KERN_INFO DRV_NAME |
4700 | ": %s is not in decimal form.\n", buf); | 3785 | ": %s is not in decimal form.\n", buf); |
4701 | else | 3786 | else |
4702 | iwl4965_hw_reg_set_txpower(priv, val); | 3787 | iwl_set_tx_power(priv, val, false); |
4703 | 3788 | ||
4704 | return count; | 3789 | return count; |
4705 | } | 3790 | } |
@@ -4724,7 +3809,7 @@ static ssize_t store_flags(struct device *d, | |||
4724 | mutex_lock(&priv->mutex); | 3809 | mutex_lock(&priv->mutex); |
4725 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { | 3810 | if (le32_to_cpu(priv->staging_rxon.flags) != flags) { |
4726 | /* Cancel any currently running scans... */ | 3811 | /* Cancel any currently running scans... */ |
4727 | if (iwl4965_scan_cancel_timeout(priv, 100)) | 3812 | if (iwl_scan_cancel_timeout(priv, 100)) |
4728 | IWL_WARNING("Could not cancel scan.\n"); | 3813 | IWL_WARNING("Could not cancel scan.\n"); |
4729 | else { | 3814 | else { |
4730 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", | 3815 | IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", |
@@ -4759,7 +3844,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
4759 | mutex_lock(&priv->mutex); | 3844 | mutex_lock(&priv->mutex); |
4760 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { | 3845 | if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { |
4761 | /* Cancel any currently running scans... */ | 3846 | /* Cancel any currently running scans... */ |
4762 | if (iwl4965_scan_cancel_timeout(priv, 100)) | 3847 | if (iwl_scan_cancel_timeout(priv, 100)) |
4763 | IWL_WARNING("Could not cancel scan.\n"); | 3848 | IWL_WARNING("Could not cancel scan.\n"); |
4764 | else { | 3849 | else { |
4765 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " | 3850 | IWL_DEBUG_INFO("Committing rxon.filter_flags = " |
@@ -4957,8 +4042,62 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, | |||
4957 | static ssize_t show_channels(struct device *d, | 4042 | static ssize_t show_channels(struct device *d, |
4958 | struct device_attribute *attr, char *buf) | 4043 | struct device_attribute *attr, char *buf) |
4959 | { | 4044 | { |
4960 | /* all this shit doesn't belong into sysfs anyway */ | 4045 | |
4961 | return 0; | 4046 | struct iwl_priv *priv = dev_get_drvdata(d); |
4047 | struct ieee80211_channel *channels = NULL; | ||
4048 | const struct ieee80211_supported_band *supp_band = NULL; | ||
4049 | int len = 0, i; | ||
4050 | int count = 0; | ||
4051 | |||
4052 | if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) | ||
4053 | return -EAGAIN; | ||
4054 | |||
4055 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); | ||
4056 | channels = supp_band->channels; | ||
4057 | count = supp_band->n_channels; | ||
4058 | |||
4059 | len += sprintf(&buf[len], | ||
4060 | "Displaying %d channels in 2.4GHz band " | ||
4061 | "(802.11bg):\n", count); | ||
4062 | |||
4063 | for (i = 0; i < count; i++) | ||
4064 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
4065 | ieee80211_frequency_to_channel( | ||
4066 | channels[i].center_freq), | ||
4067 | channels[i].max_power, | ||
4068 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
4069 | " (IEEE 802.11h required)" : "", | ||
4070 | (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
4071 | || (channels[i].flags & | ||
4072 | IEEE80211_CHAN_RADAR)) ? "" : | ||
4073 | ", IBSS", | ||
4074 | channels[i].flags & | ||
4075 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
4076 | "passive only" : "active/passive"); | ||
4077 | |||
4078 | supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); | ||
4079 | channels = supp_band->channels; | ||
4080 | count = supp_band->n_channels; | ||
4081 | |||
4082 | len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " | ||
4083 | "(802.11a):\n", count); | ||
4084 | |||
4085 | for (i = 0; i < count; i++) | ||
4086 | len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", | ||
4087 | ieee80211_frequency_to_channel( | ||
4088 | channels[i].center_freq), | ||
4089 | channels[i].max_power, | ||
4090 | channels[i].flags & IEEE80211_CHAN_RADAR ? | ||
4091 | " (IEEE 802.11h required)" : "", | ||
4092 | ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) | ||
4093 | || (channels[i].flags & | ||
4094 | IEEE80211_CHAN_RADAR)) ? "" : | ||
4095 | ", IBSS", | ||
4096 | channels[i].flags & | ||
4097 | IEEE80211_CHAN_PASSIVE_SCAN ? | ||
4098 | "passive only" : "active/passive"); | ||
4099 | |||
4100 | return len; | ||
4962 | } | 4101 | } |
4963 | 4102 | ||
4964 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); | 4103 | static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); |
@@ -5018,7 +4157,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); | |||
5018 | * | 4157 | * |
5019 | *****************************************************************************/ | 4158 | *****************************************************************************/ |
5020 | 4159 | ||
5021 | static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | 4160 | static void iwl_setup_deferred_work(struct iwl_priv *priv) |
5022 | { | 4161 | { |
5023 | priv->workqueue = create_workqueue(DRV_NAME); | 4162 | priv->workqueue = create_workqueue(DRV_NAME); |
5024 | 4163 | ||
@@ -5027,32 +4166,40 @@ static void iwl4965_setup_deferred_work(struct iwl_priv *priv) | |||
5027 | INIT_WORK(&priv->up, iwl4965_bg_up); | 4166 | INIT_WORK(&priv->up, iwl4965_bg_up); |
5028 | INIT_WORK(&priv->restart, iwl4965_bg_restart); | 4167 | INIT_WORK(&priv->restart, iwl4965_bg_restart); |
5029 | INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); | 4168 | INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); |
5030 | INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed); | ||
5031 | INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan); | ||
5032 | INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); | ||
5033 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); | 4169 | INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); |
5034 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); | 4170 | INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); |
5035 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); | 4171 | INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); |
4172 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | ||
5036 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); | 4173 | INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); |
5037 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 4174 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
5038 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | 4175 | INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); |
5039 | INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check); | ||
5040 | 4176 | ||
5041 | iwl4965_hw_setup_deferred_work(priv); | 4177 | /* FIXME : remove when resolved PENDING */ |
4178 | INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); | ||
4179 | iwl_setup_scan_deferred_work(priv); | ||
4180 | |||
4181 | if (priv->cfg->ops->lib->setup_deferred_work) | ||
4182 | priv->cfg->ops->lib->setup_deferred_work(priv); | ||
4183 | |||
4184 | init_timer(&priv->statistics_periodic); | ||
4185 | priv->statistics_periodic.data = (unsigned long)priv; | ||
4186 | priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; | ||
5042 | 4187 | ||
5043 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 4188 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
5044 | iwl4965_irq_tasklet, (unsigned long)priv); | 4189 | iwl4965_irq_tasklet, (unsigned long)priv); |
5045 | } | 4190 | } |
5046 | 4191 | ||
5047 | static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) | 4192 | static void iwl_cancel_deferred_work(struct iwl_priv *priv) |
5048 | { | 4193 | { |
5049 | iwl4965_hw_cancel_deferred_work(priv); | 4194 | if (priv->cfg->ops->lib->cancel_deferred_work) |
4195 | priv->cfg->ops->lib->cancel_deferred_work(priv); | ||
5050 | 4196 | ||
5051 | cancel_delayed_work_sync(&priv->init_alive_start); | 4197 | cancel_delayed_work_sync(&priv->init_alive_start); |
5052 | cancel_delayed_work(&priv->scan_check); | 4198 | cancel_delayed_work(&priv->scan_check); |
5053 | cancel_delayed_work(&priv->alive_start); | 4199 | cancel_delayed_work(&priv->alive_start); |
5054 | cancel_delayed_work(&priv->post_associate); | 4200 | cancel_delayed_work(&priv->post_associate); |
5055 | cancel_work_sync(&priv->beacon_update); | 4201 | cancel_work_sync(&priv->beacon_update); |
4202 | del_timer_sync(&priv->statistics_periodic); | ||
5056 | } | 4203 | } |
5057 | 4204 | ||
5058 | static struct attribute *iwl4965_sysfs_entries[] = { | 4205 | static struct attribute *iwl4965_sysfs_entries[] = { |
@@ -5100,9 +4247,7 @@ static struct ieee80211_ops iwl4965_hw_ops = { | |||
5100 | .reset_tsf = iwl4965_mac_reset_tsf, | 4247 | .reset_tsf = iwl4965_mac_reset_tsf, |
5101 | .beacon_update = iwl4965_mac_beacon_update, | 4248 | .beacon_update = iwl4965_mac_beacon_update, |
5102 | .bss_info_changed = iwl4965_bss_info_changed, | 4249 | .bss_info_changed = iwl4965_bss_info_changed, |
5103 | #ifdef CONFIG_IWL4965_HT | ||
5104 | .ampdu_action = iwl4965_mac_ampdu_action, | 4250 | .ampdu_action = iwl4965_mac_ampdu_action, |
5105 | #endif /* CONFIG_IWL4965_HT */ | ||
5106 | .hw_scan = iwl4965_mac_hw_scan | 4251 | .hw_scan = iwl4965_mac_hw_scan |
5107 | }; | 4252 | }; |
5108 | 4253 | ||
@@ -5266,7 +4411,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5266 | } | 4411 | } |
5267 | 4412 | ||
5268 | 4413 | ||
5269 | iwl4965_setup_deferred_work(priv); | 4414 | iwl_setup_deferred_work(priv); |
5270 | iwl4965_setup_rx_handlers(priv); | 4415 | iwl4965_setup_rx_handlers(priv); |
5271 | 4416 | ||
5272 | /******************** | 4417 | /******************** |
@@ -5287,8 +4432,11 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
5287 | if (err) | 4432 | if (err) |
5288 | IWL_ERROR("failed to create debugfs files\n"); | 4433 | IWL_ERROR("failed to create debugfs files\n"); |
5289 | 4434 | ||
5290 | /* notify iwlcore to init */ | 4435 | err = iwl_rfkill_init(priv); |
5291 | iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); | 4436 | if (err) |
4437 | IWL_ERROR("Unable to initialize RFKILL system. " | ||
4438 | "Ignoring error: %d\n", err); | ||
4439 | iwl_power_initialize(priv); | ||
5292 | return 0; | 4440 | return 0; |
5293 | 4441 | ||
5294 | out_remove_sysfs: | 4442 | out_remove_sysfs: |
@@ -5351,8 +4499,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
5351 | } | 4499 | } |
5352 | } | 4500 | } |
5353 | 4501 | ||
5354 | iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT); | 4502 | iwl_rfkill_unregister(priv); |
5355 | |||
5356 | iwl4965_dealloc_ucode_pci(priv); | 4503 | iwl4965_dealloc_ucode_pci(priv); |
5357 | 4504 | ||
5358 | if (priv->rxq.bd) | 4505 | if (priv->rxq.bd) |
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 873ab10a0786..cc70d53fadd3 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c | |||
@@ -159,7 +159,9 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
159 | 159 | ||
160 | 160 | ||
161 | 161 | ||
162 | /* First the bitmasks for the host/card interrupt/status registers: */ | 162 | /* |
163 | * First the bitmasks for the host/card interrupt/status registers: | ||
164 | */ | ||
163 | #define IF_CS_BIT_TX 0x0001 | 165 | #define IF_CS_BIT_TX 0x0001 |
164 | #define IF_CS_BIT_RX 0x0002 | 166 | #define IF_CS_BIT_RX 0x0002 |
165 | #define IF_CS_BIT_COMMAND 0x0004 | 167 | #define IF_CS_BIT_COMMAND 0x0004 |
@@ -167,35 +169,110 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
167 | #define IF_CS_BIT_EVENT 0x0010 | 169 | #define IF_CS_BIT_EVENT 0x0010 |
168 | #define IF_CS_BIT_MASK 0x001f | 170 | #define IF_CS_BIT_MASK 0x001f |
169 | 171 | ||
170 | /* And now the individual registers and assorted masks */ | 172 | |
173 | |||
174 | /* | ||
175 | * It's not really clear to me what the host status register is for. It | ||
176 | * needs to be set almost in union with "host int cause". The following | ||
177 | * bits from above are used: | ||
178 | * | ||
179 | * IF_CS_BIT_TX driver downloaded a data packet | ||
180 | * IF_CS_BIT_RX driver got a data packet | ||
181 | * IF_CS_BIT_COMMAND driver downloaded a command | ||
182 | * IF_CS_BIT_RESP not used (has some meaning with powerdown) | ||
183 | * IF_CS_BIT_EVENT driver read a host event | ||
184 | */ | ||
171 | #define IF_CS_HOST_STATUS 0x00000000 | 185 | #define IF_CS_HOST_STATUS 0x00000000 |
172 | 186 | ||
187 | /* | ||
188 | * With the host int cause register can the host (that is, Linux) cause | ||
189 | * an interrupt in the firmware, to tell the firmware about those events: | ||
190 | * | ||
191 | * IF_CS_BIT_TX a data packet has been downloaded | ||
192 | * IF_CS_BIT_RX a received data packet has retrieved | ||
193 | * IF_CS_BIT_COMMAND a firmware block or a command has been downloaded | ||
194 | * IF_CS_BIT_RESP not used (has some meaning with powerdown) | ||
195 | * IF_CS_BIT_EVENT a host event (link lost etc) has been retrieved | ||
196 | */ | ||
173 | #define IF_CS_HOST_INT_CAUSE 0x00000002 | 197 | #define IF_CS_HOST_INT_CAUSE 0x00000002 |
174 | 198 | ||
199 | /* | ||
200 | * The host int mask register is used to enable/disable interrupt. However, | ||
201 | * I have the suspicion that disabled interrupts are lost. | ||
202 | */ | ||
175 | #define IF_CS_HOST_INT_MASK 0x00000004 | 203 | #define IF_CS_HOST_INT_MASK 0x00000004 |
176 | 204 | ||
177 | #define IF_CS_HOST_WRITE 0x00000016 | 205 | /* |
178 | #define IF_CS_HOST_WRITE_LEN 0x00000014 | 206 | * Used to send or receive data packets: |
179 | 207 | */ | |
180 | #define IF_CS_HOST_CMD 0x0000001A | 208 | #define IF_CS_WRITE 0x00000016 |
181 | #define IF_CS_HOST_CMD_LEN 0x00000018 | 209 | #define IF_CS_WRITE_LEN 0x00000014 |
182 | |||
183 | #define IF_CS_READ 0x00000010 | 210 | #define IF_CS_READ 0x00000010 |
184 | #define IF_CS_READ_LEN 0x00000024 | 211 | #define IF_CS_READ_LEN 0x00000024 |
185 | 212 | ||
186 | #define IF_CS_CARD_CMD 0x00000012 | 213 | /* |
187 | #define IF_CS_CARD_CMD_LEN 0x00000030 | 214 | * Used to send commands (and to send firmware block) and to |
215 | * receive command responses: | ||
216 | */ | ||
217 | #define IF_CS_CMD 0x0000001A | ||
218 | #define IF_CS_CMD_LEN 0x00000018 | ||
219 | #define IF_CS_RESP 0x00000012 | ||
220 | #define IF_CS_RESP_LEN 0x00000030 | ||
188 | 221 | ||
222 | /* | ||
223 | * The card status registers shows what the card/firmware actually | ||
224 | * accepts: | ||
225 | * | ||
226 | * IF_CS_BIT_TX you may send a data packet | ||
227 | * IF_CS_BIT_RX you may retrieve a data packet | ||
228 | * IF_CS_BIT_COMMAND you may send a command | ||
229 | * IF_CS_BIT_RESP you may retrieve a command response | ||
230 | * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc) | ||
231 | * | ||
232 | * When reading this register several times, you will get back the same | ||
233 | * results --- with one exception: the IF_CS_BIT_EVENT clear itself | ||
234 | * automatically. | ||
235 | * | ||
236 | * Not that we don't rely on BIT_RX,_BIT_RESP or BIT_EVENT because | ||
237 | * we handle this via the card int cause register. | ||
238 | */ | ||
189 | #define IF_CS_CARD_STATUS 0x00000020 | 239 | #define IF_CS_CARD_STATUS 0x00000020 |
190 | #define IF_CS_CARD_STATUS_MASK 0x7f00 | 240 | #define IF_CS_CARD_STATUS_MASK 0x7f00 |
191 | 241 | ||
242 | /* | ||
243 | * The card int cause register is used by the card/firmware to notify us | ||
244 | * about the following events: | ||
245 | * | ||
246 | * IF_CS_BIT_TX a data packet has successfully been sentx | ||
247 | * IF_CS_BIT_RX a data packet has been received and can be retrieved | ||
248 | * IF_CS_BIT_COMMAND not used | ||
249 | * IF_CS_BIT_RESP the firmware has a command response for us | ||
250 | * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc) | ||
251 | */ | ||
192 | #define IF_CS_CARD_INT_CAUSE 0x00000022 | 252 | #define IF_CS_CARD_INT_CAUSE 0x00000022 |
193 | 253 | ||
194 | #define IF_CS_CARD_SQ_READ_LOW 0x00000028 | 254 | /* |
195 | #define IF_CS_CARD_SQ_HELPER_OK 0x10 | 255 | * This is used to for handshaking with the card's bootloader/helper image |
256 | * to synchronize downloading of firmware blocks. | ||
257 | */ | ||
258 | #define IF_CS_SQ_READ_LOW 0x00000028 | ||
259 | #define IF_CS_SQ_HELPER_OK 0x10 | ||
196 | 260 | ||
261 | /* | ||
262 | * The scratch register tells us ... | ||
263 | * | ||
264 | * IF_CS_SCRATCH_BOOT_OK the bootloader runs | ||
265 | * IF_CS_SCRATCH_HELPER_OK the helper firmware already runs | ||
266 | */ | ||
197 | #define IF_CS_SCRATCH 0x0000003F | 267 | #define IF_CS_SCRATCH 0x0000003F |
268 | #define IF_CS_SCRATCH_BOOT_OK 0x00 | ||
269 | #define IF_CS_SCRATCH_HELPER_OK 0x5a | ||
198 | 270 | ||
271 | /* | ||
272 | * Used to detect ancient chips: | ||
273 | */ | ||
274 | #define IF_CS_PRODUCT_ID 0x0000001C | ||
275 | #define IF_CS_CF8385_B1_REV 0x12 | ||
199 | 276 | ||
200 | 277 | ||
201 | /********************************************************************/ | 278 | /********************************************************************/ |
@@ -228,8 +305,8 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) | |||
228 | 305 | ||
229 | /* Is hardware ready? */ | 306 | /* Is hardware ready? */ |
230 | while (1) { | 307 | while (1) { |
231 | u16 val = if_cs_read16(card, IF_CS_CARD_STATUS); | 308 | u16 status = if_cs_read16(card, IF_CS_CARD_STATUS); |
232 | if (val & IF_CS_BIT_COMMAND) | 309 | if (status & IF_CS_BIT_COMMAND) |
233 | break; | 310 | break; |
234 | if (++loops > 100) { | 311 | if (++loops > 100) { |
235 | lbs_pr_err("card not ready for commands\n"); | 312 | lbs_pr_err("card not ready for commands\n"); |
@@ -238,12 +315,12 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) | |||
238 | mdelay(1); | 315 | mdelay(1); |
239 | } | 316 | } |
240 | 317 | ||
241 | if_cs_write16(card, IF_CS_HOST_CMD_LEN, nb); | 318 | if_cs_write16(card, IF_CS_CMD_LEN, nb); |
242 | 319 | ||
243 | if_cs_write16_rep(card, IF_CS_HOST_CMD, buf, nb / 2); | 320 | if_cs_write16_rep(card, IF_CS_CMD, buf, nb / 2); |
244 | /* Are we supposed to transfer an odd amount of bytes? */ | 321 | /* Are we supposed to transfer an odd amount of bytes? */ |
245 | if (nb & 1) | 322 | if (nb & 1) |
246 | if_cs_write8(card, IF_CS_HOST_CMD, buf[nb-1]); | 323 | if_cs_write8(card, IF_CS_CMD, buf[nb-1]); |
247 | 324 | ||
248 | /* "Assert the download over interrupt command in the Host | 325 | /* "Assert the download over interrupt command in the Host |
249 | * status register" */ | 326 | * status register" */ |
@@ -274,12 +351,12 @@ static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb) | |||
274 | status = if_cs_read16(card, IF_CS_CARD_STATUS); | 351 | status = if_cs_read16(card, IF_CS_CARD_STATUS); |
275 | BUG_ON((status & IF_CS_BIT_TX) == 0); | 352 | BUG_ON((status & IF_CS_BIT_TX) == 0); |
276 | 353 | ||
277 | if_cs_write16(card, IF_CS_HOST_WRITE_LEN, nb); | 354 | if_cs_write16(card, IF_CS_WRITE_LEN, nb); |
278 | 355 | ||
279 | /* write even number of bytes, then odd byte if necessary */ | 356 | /* write even number of bytes, then odd byte if necessary */ |
280 | if_cs_write16_rep(card, IF_CS_HOST_WRITE, buf, nb / 2); | 357 | if_cs_write16_rep(card, IF_CS_WRITE, buf, nb / 2); |
281 | if (nb & 1) | 358 | if (nb & 1) |
282 | if_cs_write8(card, IF_CS_HOST_WRITE, buf[nb-1]); | 359 | if_cs_write8(card, IF_CS_WRITE, buf[nb-1]); |
283 | 360 | ||
284 | if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX); | 361 | if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX); |
285 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX); | 362 | if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX); |
@@ -307,16 +384,16 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len) | |||
307 | goto out; | 384 | goto out; |
308 | } | 385 | } |
309 | 386 | ||
310 | *len = if_cs_read16(priv->card, IF_CS_CARD_CMD_LEN); | 387 | *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); |
311 | if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { | 388 | if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { |
312 | lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); | 389 | lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); |
313 | goto out; | 390 | goto out; |
314 | } | 391 | } |
315 | 392 | ||
316 | /* read even number of bytes, then odd byte if necessary */ | 393 | /* read even number of bytes, then odd byte if necessary */ |
317 | if_cs_read16_rep(priv->card, IF_CS_CARD_CMD, data, *len/sizeof(u16)); | 394 | if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16)); |
318 | if (*len & 1) | 395 | if (*len & 1) |
319 | data[*len-1] = if_cs_read8(priv->card, IF_CS_CARD_CMD); | 396 | data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP); |
320 | 397 | ||
321 | /* This is a workaround for a firmware that reports too much | 398 | /* This is a workaround for a firmware that reports too much |
322 | * bytes */ | 399 | * bytes */ |
@@ -379,6 +456,8 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) | |||
379 | 456 | ||
380 | /* Ask card interrupt cause register if there is something for us */ | 457 | /* Ask card interrupt cause register if there is something for us */ |
381 | cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE); | 458 | cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE); |
459 | lbs_deb_cs("cause 0x%04x\n", cause); | ||
460 | |||
382 | if (cause == 0) { | 461 | if (cause == 0) { |
383 | /* Not for us */ | 462 | /* Not for us */ |
384 | return IRQ_NONE; | 463 | return IRQ_NONE; |
@@ -390,10 +469,6 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) | |||
390 | return IRQ_HANDLED; | 469 | return IRQ_HANDLED; |
391 | } | 470 | } |
392 | 471 | ||
393 | /* Clear interrupt cause */ | ||
394 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK); | ||
395 | lbs_deb_cs("cause 0x%04x\n", cause); | ||
396 | |||
397 | if (cause & IF_CS_BIT_RX) { | 472 | if (cause & IF_CS_BIT_RX) { |
398 | struct sk_buff *skb; | 473 | struct sk_buff *skb; |
399 | lbs_deb_cs("rx packet\n"); | 474 | lbs_deb_cs("rx packet\n"); |
@@ -426,14 +501,15 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) | |||
426 | } | 501 | } |
427 | 502 | ||
428 | if (cause & IF_CS_BIT_EVENT) { | 503 | if (cause & IF_CS_BIT_EVENT) { |
429 | u16 event = if_cs_read16(priv->card, IF_CS_CARD_STATUS) | 504 | u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); |
430 | & IF_CS_CARD_STATUS_MASK; | ||
431 | if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, | 505 | if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, |
432 | IF_CS_BIT_EVENT); | 506 | IF_CS_BIT_EVENT); |
433 | lbs_deb_cs("host event 0x%04x\n", event); | 507 | lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8); |
434 | lbs_queue_event(priv, event >> 8 & 0xff); | ||
435 | } | 508 | } |
436 | 509 | ||
510 | /* Clear interrupt cause */ | ||
511 | if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK); | ||
512 | |||
437 | lbs_deb_leave(LBS_DEB_CS); | 513 | lbs_deb_leave(LBS_DEB_CS); |
438 | return IRQ_HANDLED; | 514 | return IRQ_HANDLED; |
439 | } | 515 | } |
@@ -464,11 +540,11 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
464 | /* "If the value is 0x5a, the firmware is already | 540 | /* "If the value is 0x5a, the firmware is already |
465 | * downloaded successfully" | 541 | * downloaded successfully" |
466 | */ | 542 | */ |
467 | if (scratch == 0x5a) | 543 | if (scratch == IF_CS_SCRATCH_HELPER_OK) |
468 | goto done; | 544 | goto done; |
469 | 545 | ||
470 | /* "If the value is != 00, it is invalid value of register */ | 546 | /* "If the value is != 00, it is invalid value of register */ |
471 | if (scratch != 0x00) { | 547 | if (scratch != IF_CS_SCRATCH_BOOT_OK) { |
472 | ret = -ENODEV; | 548 | ret = -ENODEV; |
473 | goto done; | 549 | goto done; |
474 | } | 550 | } |
@@ -496,11 +572,11 @@ static int if_cs_prog_helper(struct if_cs_card *card) | |||
496 | 572 | ||
497 | /* "write the number of bytes to be sent to the I/O Command | 573 | /* "write the number of bytes to be sent to the I/O Command |
498 | * write length register" */ | 574 | * write length register" */ |
499 | if_cs_write16(card, IF_CS_HOST_CMD_LEN, count); | 575 | if_cs_write16(card, IF_CS_CMD_LEN, count); |
500 | 576 | ||
501 | /* "write this to I/O Command port register as 16 bit writes */ | 577 | /* "write this to I/O Command port register as 16 bit writes */ |
502 | if (count) | 578 | if (count) |
503 | if_cs_write16_rep(card, IF_CS_HOST_CMD, | 579 | if_cs_write16_rep(card, IF_CS_CMD, |
504 | &fw->data[sent], | 580 | &fw->data[sent], |
505 | count >> 1); | 581 | count >> 1); |
506 | 582 | ||
@@ -557,15 +633,15 @@ static int if_cs_prog_real(struct if_cs_card *card) | |||
557 | } | 633 | } |
558 | lbs_deb_cs("fw size %td\n", fw->size); | 634 | lbs_deb_cs("fw size %td\n", fw->size); |
559 | 635 | ||
560 | ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_SQ_READ_LOW, | 636 | ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, |
561 | IF_CS_CARD_SQ_HELPER_OK); | 637 | IF_CS_SQ_HELPER_OK); |
562 | if (ret < 0) { | 638 | if (ret < 0) { |
563 | lbs_pr_err("helper firmware doesn't answer\n"); | 639 | lbs_pr_err("helper firmware doesn't answer\n"); |
564 | goto err_release; | 640 | goto err_release; |
565 | } | 641 | } |
566 | 642 | ||
567 | for (sent = 0; sent < fw->size; sent += len) { | 643 | for (sent = 0; sent < fw->size; sent += len) { |
568 | len = if_cs_read16(card, IF_CS_CARD_SQ_READ_LOW); | 644 | len = if_cs_read16(card, IF_CS_SQ_READ_LOW); |
569 | if (len & 1) { | 645 | if (len & 1) { |
570 | retry++; | 646 | retry++; |
571 | lbs_pr_info("odd, need to retry this firmware block\n"); | 647 | lbs_pr_info("odd, need to retry this firmware block\n"); |
@@ -583,9 +659,9 @@ static int if_cs_prog_real(struct if_cs_card *card) | |||
583 | } | 659 | } |
584 | 660 | ||
585 | 661 | ||
586 | if_cs_write16(card, IF_CS_HOST_CMD_LEN, len); | 662 | if_cs_write16(card, IF_CS_CMD_LEN, len); |
587 | 663 | ||
588 | if_cs_write16_rep(card, IF_CS_HOST_CMD, | 664 | if_cs_write16_rep(card, IF_CS_CMD, |
589 | &fw->data[sent], | 665 | &fw->data[sent], |
590 | (len+1) >> 1); | 666 | (len+1) >> 1); |
591 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); | 667 | if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); |
@@ -789,6 +865,12 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
789 | p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, | 865 | p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, |
790 | p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); | 866 | p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); |
791 | 867 | ||
868 | /* Check if we have a current silicon */ | ||
869 | if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) { | ||
870 | lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); | ||
871 | ret = -ENODEV; | ||
872 | goto out2; | ||
873 | } | ||
792 | 874 | ||
793 | /* Load the firmware early, before calling into libertas.ko */ | 875 | /* Load the firmware early, before calling into libertas.ko */ |
794 | ret = if_cs_prog_helper(card); | 876 | ret = if_cs_prog_helper(card); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c new file mode 100644 index 000000000000..8da352ae6825 --- /dev/null +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -0,0 +1,514 @@ | |||
1 | /* | ||
2 | * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 | ||
3 | * Copyright (c) 2008, Jouni Malinen <j@w1.fi> | ||
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 | * TODO: | ||
12 | * - IBSS mode simulation (Beacon transmission with competition for "air time") | ||
13 | * - IEEE 802.11a and 802.11n modes | ||
14 | * - RX filtering based on filter configuration (data->rx_filter) | ||
15 | */ | ||
16 | |||
17 | #include <net/mac80211.h> | ||
18 | #include <net/ieee80211_radiotap.h> | ||
19 | #include <linux/if_arp.h> | ||
20 | #include <linux/rtnetlink.h> | ||
21 | #include <linux/etherdevice.h> | ||
22 | |||
23 | MODULE_AUTHOR("Jouni Malinen"); | ||
24 | MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); | ||
25 | MODULE_LICENSE("GPL"); | ||
26 | |||
27 | static int radios = 2; | ||
28 | module_param(radios, int, 0444); | ||
29 | MODULE_PARM_DESC(radios, "Number of simulated radios"); | ||
30 | |||
31 | |||
32 | static struct class *hwsim_class; | ||
33 | |||
34 | static struct ieee80211_hw **hwsim_radios; | ||
35 | static int hwsim_radio_count; | ||
36 | static struct net_device *hwsim_mon; /* global monitor netdev */ | ||
37 | |||
38 | |||
39 | static const struct ieee80211_channel hwsim_channels[] = { | ||
40 | { .center_freq = 2412 }, | ||
41 | { .center_freq = 2417 }, | ||
42 | { .center_freq = 2422 }, | ||
43 | { .center_freq = 2427 }, | ||
44 | { .center_freq = 2432 }, | ||
45 | { .center_freq = 2437 }, | ||
46 | { .center_freq = 2442 }, | ||
47 | { .center_freq = 2447 }, | ||
48 | { .center_freq = 2452 }, | ||
49 | { .center_freq = 2457 }, | ||
50 | { .center_freq = 2462 }, | ||
51 | { .center_freq = 2467 }, | ||
52 | { .center_freq = 2472 }, | ||
53 | { .center_freq = 2484 }, | ||
54 | }; | ||
55 | |||
56 | static const struct ieee80211_rate hwsim_rates[] = { | ||
57 | { .bitrate = 10 }, | ||
58 | { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
59 | { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
60 | { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
61 | { .bitrate = 60 }, | ||
62 | { .bitrate = 90 }, | ||
63 | { .bitrate = 120 }, | ||
64 | { .bitrate = 180 }, | ||
65 | { .bitrate = 240 }, | ||
66 | { .bitrate = 360 }, | ||
67 | { .bitrate = 480 }, | ||
68 | { .bitrate = 540 } | ||
69 | }; | ||
70 | |||
71 | struct mac80211_hwsim_data { | ||
72 | struct device *dev; | ||
73 | struct ieee80211_supported_band band; | ||
74 | struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)]; | ||
75 | struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; | ||
76 | |||
77 | struct ieee80211_channel *channel; | ||
78 | int radio_enabled; | ||
79 | unsigned long beacon_int; /* in jiffies unit */ | ||
80 | unsigned int rx_filter; | ||
81 | int started; | ||
82 | struct timer_list beacon_timer; | ||
83 | }; | ||
84 | |||
85 | |||
86 | struct hwsim_radiotap_hdr { | ||
87 | struct ieee80211_radiotap_header hdr; | ||
88 | u8 rt_flags; | ||
89 | u8 rt_rate; | ||
90 | __le16 rt_channel; | ||
91 | __le16 rt_chbitmask; | ||
92 | } __attribute__ ((packed)); | ||
93 | |||
94 | |||
95 | static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev) | ||
96 | { | ||
97 | /* TODO: allow packet injection */ | ||
98 | dev_kfree_skb(skb); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | |||
103 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | ||
104 | struct sk_buff *tx_skb) | ||
105 | { | ||
106 | struct mac80211_hwsim_data *data = hw->priv; | ||
107 | struct sk_buff *skb; | ||
108 | struct hwsim_radiotap_hdr *hdr; | ||
109 | u16 flags; | ||
110 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); | ||
111 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); | ||
112 | |||
113 | if (!netif_running(hwsim_mon)) | ||
114 | return; | ||
115 | |||
116 | skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); | ||
117 | if (skb == NULL) | ||
118 | return; | ||
119 | |||
120 | hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); | ||
121 | hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; | ||
122 | hdr->hdr.it_pad = 0; | ||
123 | hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); | ||
124 | hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
125 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
126 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | ||
127 | hdr->rt_flags = 0; | ||
128 | hdr->rt_rate = txrate->bitrate / 5; | ||
129 | hdr->rt_channel = data->channel->center_freq; | ||
130 | flags = IEEE80211_CHAN_2GHZ; | ||
131 | if (txrate->flags & IEEE80211_RATE_ERP_G) | ||
132 | flags |= IEEE80211_CHAN_OFDM; | ||
133 | else | ||
134 | flags |= IEEE80211_CHAN_CCK; | ||
135 | hdr->rt_chbitmask = cpu_to_le16(flags); | ||
136 | |||
137 | skb->dev = hwsim_mon; | ||
138 | skb_set_mac_header(skb, 0); | ||
139 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
140 | skb->pkt_type = PACKET_OTHERHOST; | ||
141 | skb->protocol = htons(ETH_P_802_2); | ||
142 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
143 | netif_rx(skb); | ||
144 | } | ||
145 | |||
146 | |||
147 | static int mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | ||
148 | struct sk_buff *skb) | ||
149 | { | ||
150 | struct mac80211_hwsim_data *data = hw->priv; | ||
151 | int i, ack = 0; | ||
152 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
153 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
154 | struct ieee80211_rx_status rx_status; | ||
155 | |||
156 | memset(&rx_status, 0, sizeof(rx_status)); | ||
157 | /* TODO: set mactime */ | ||
158 | rx_status.freq = data->channel->center_freq; | ||
159 | rx_status.band = data->channel->band; | ||
160 | rx_status.rate_idx = info->tx_rate_idx; | ||
161 | /* TODO: simulate signal strength (and optional packet drop) */ | ||
162 | |||
163 | /* Copy skb to all enabled radios that are on the current frequency */ | ||
164 | for (i = 0; i < hwsim_radio_count; i++) { | ||
165 | struct mac80211_hwsim_data *data2; | ||
166 | struct sk_buff *nskb; | ||
167 | |||
168 | if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw) | ||
169 | continue; | ||
170 | data2 = hwsim_radios[i]->priv; | ||
171 | if (!data2->started || !data2->radio_enabled || | ||
172 | data->channel->center_freq != data2->channel->center_freq) | ||
173 | continue; | ||
174 | |||
175 | nskb = skb_copy(skb, GFP_ATOMIC); | ||
176 | if (nskb == NULL) | ||
177 | continue; | ||
178 | |||
179 | if (memcmp(hdr->addr1, hwsim_radios[i]->wiphy->perm_addr, | ||
180 | ETH_ALEN) == 0) | ||
181 | ack = 1; | ||
182 | ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status); | ||
183 | } | ||
184 | |||
185 | return ack; | ||
186 | } | ||
187 | |||
188 | |||
189 | static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
190 | { | ||
191 | struct mac80211_hwsim_data *data = hw->priv; | ||
192 | int ack; | ||
193 | struct ieee80211_tx_info *txi; | ||
194 | |||
195 | mac80211_hwsim_monitor_rx(hw, skb); | ||
196 | |||
197 | if (skb->len < 10) { | ||
198 | /* Should not happen; just a sanity check for addr1 use */ | ||
199 | dev_kfree_skb(skb); | ||
200 | return NETDEV_TX_OK; | ||
201 | } | ||
202 | |||
203 | if (!data->radio_enabled) { | ||
204 | printk(KERN_DEBUG "%s: dropped TX frame since radio " | ||
205 | "disabled\n", wiphy_name(hw->wiphy)); | ||
206 | dev_kfree_skb(skb); | ||
207 | return NETDEV_TX_OK; | ||
208 | } | ||
209 | |||
210 | ack = mac80211_hwsim_tx_frame(hw, skb); | ||
211 | |||
212 | txi = IEEE80211_SKB_CB(skb); | ||
213 | memset(&txi->status, 0, sizeof(txi->status)); | ||
214 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { | ||
215 | if (ack) | ||
216 | txi->flags |= IEEE80211_TX_STAT_ACK; | ||
217 | else | ||
218 | txi->status.excessive_retries = 1; | ||
219 | } | ||
220 | ieee80211_tx_status_irqsafe(hw, skb); | ||
221 | return NETDEV_TX_OK; | ||
222 | } | ||
223 | |||
224 | |||
225 | static int mac80211_hwsim_start(struct ieee80211_hw *hw) | ||
226 | { | ||
227 | struct mac80211_hwsim_data *data = hw->priv; | ||
228 | printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||
229 | data->started = 1; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | |||
234 | static void mac80211_hwsim_stop(struct ieee80211_hw *hw) | ||
235 | { | ||
236 | struct mac80211_hwsim_data *data = hw->priv; | ||
237 | data->started = 0; | ||
238 | printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||
239 | } | ||
240 | |||
241 | |||
242 | static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, | ||
243 | struct ieee80211_if_init_conf *conf) | ||
244 | { | ||
245 | DECLARE_MAC_BUF(mac); | ||
246 | printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", | ||
247 | wiphy_name(hw->wiphy), __func__, conf->type, | ||
248 | print_mac(mac, conf->mac_addr)); | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | |||
253 | static void mac80211_hwsim_remove_interface( | ||
254 | struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) | ||
255 | { | ||
256 | DECLARE_MAC_BUF(mac); | ||
257 | printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", | ||
258 | wiphy_name(hw->wiphy), __func__, conf->type, | ||
259 | print_mac(mac, conf->mac_addr)); | ||
260 | } | ||
261 | |||
262 | |||
263 | static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | ||
264 | struct ieee80211_vif *vif) | ||
265 | { | ||
266 | struct ieee80211_hw *hw = arg; | ||
267 | struct sk_buff *skb; | ||
268 | struct ieee80211_tx_info *info; | ||
269 | |||
270 | if (vif->type != IEEE80211_IF_TYPE_AP) | ||
271 | return; | ||
272 | |||
273 | skb = ieee80211_beacon_get(hw, vif); | ||
274 | if (skb == NULL) | ||
275 | return; | ||
276 | info = IEEE80211_SKB_CB(skb); | ||
277 | |||
278 | mac80211_hwsim_monitor_rx(hw, skb); | ||
279 | mac80211_hwsim_tx_frame(hw, skb); | ||
280 | dev_kfree_skb(skb); | ||
281 | } | ||
282 | |||
283 | |||
284 | static void mac80211_hwsim_beacon(unsigned long arg) | ||
285 | { | ||
286 | struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; | ||
287 | struct mac80211_hwsim_data *data = hw->priv; | ||
288 | |||
289 | if (!data->started || !data->radio_enabled) | ||
290 | return; | ||
291 | |||
292 | ieee80211_iterate_active_interfaces_atomic( | ||
293 | hw, mac80211_hwsim_beacon_tx, hw); | ||
294 | |||
295 | data->beacon_timer.expires = jiffies + data->beacon_int; | ||
296 | add_timer(&data->beacon_timer); | ||
297 | } | ||
298 | |||
299 | |||
300 | static int mac80211_hwsim_config(struct ieee80211_hw *hw, | ||
301 | struct ieee80211_conf *conf) | ||
302 | { | ||
303 | struct mac80211_hwsim_data *data = hw->priv; | ||
304 | |||
305 | printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n", | ||
306 | wiphy_name(hw->wiphy), __func__, | ||
307 | conf->channel->center_freq, conf->radio_enabled, | ||
308 | conf->beacon_int); | ||
309 | |||
310 | data->channel = conf->channel; | ||
311 | data->radio_enabled = conf->radio_enabled; | ||
312 | data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000; | ||
313 | if (data->beacon_int < 1) | ||
314 | data->beacon_int = 1; | ||
315 | |||
316 | if (!data->started || !data->radio_enabled) | ||
317 | del_timer(&data->beacon_timer); | ||
318 | else | ||
319 | mod_timer(&data->beacon_timer, jiffies + data->beacon_int); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | |||
325 | static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, | ||
326 | unsigned int changed_flags, | ||
327 | unsigned int *total_flags, | ||
328 | int mc_count, | ||
329 | struct dev_addr_list *mc_list) | ||
330 | { | ||
331 | struct mac80211_hwsim_data *data = hw->priv; | ||
332 | |||
333 | printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); | ||
334 | |||
335 | data->rx_filter = 0; | ||
336 | if (*total_flags & FIF_PROMISC_IN_BSS) | ||
337 | data->rx_filter |= FIF_PROMISC_IN_BSS; | ||
338 | if (*total_flags & FIF_ALLMULTI) | ||
339 | data->rx_filter |= FIF_ALLMULTI; | ||
340 | |||
341 | *total_flags = data->rx_filter; | ||
342 | } | ||
343 | |||
344 | |||
345 | |||
346 | static const struct ieee80211_ops mac80211_hwsim_ops = | ||
347 | { | ||
348 | .tx = mac80211_hwsim_tx, | ||
349 | .start = mac80211_hwsim_start, | ||
350 | .stop = mac80211_hwsim_stop, | ||
351 | .add_interface = mac80211_hwsim_add_interface, | ||
352 | .remove_interface = mac80211_hwsim_remove_interface, | ||
353 | .config = mac80211_hwsim_config, | ||
354 | .configure_filter = mac80211_hwsim_configure_filter, | ||
355 | }; | ||
356 | |||
357 | |||
358 | static void mac80211_hwsim_free(void) | ||
359 | { | ||
360 | int i; | ||
361 | |||
362 | for (i = 0; i < hwsim_radio_count; i++) { | ||
363 | if (hwsim_radios[i]) { | ||
364 | struct mac80211_hwsim_data *data; | ||
365 | data = hwsim_radios[i]->priv; | ||
366 | ieee80211_unregister_hw(hwsim_radios[i]); | ||
367 | if (!IS_ERR(data->dev)) | ||
368 | device_unregister(data->dev); | ||
369 | ieee80211_free_hw(hwsim_radios[i]); | ||
370 | } | ||
371 | } | ||
372 | kfree(hwsim_radios); | ||
373 | class_destroy(hwsim_class); | ||
374 | } | ||
375 | |||
376 | |||
377 | static struct device_driver mac80211_hwsim_driver = { | ||
378 | .name = "mac80211_hwsim" | ||
379 | }; | ||
380 | |||
381 | |||
382 | static void hwsim_mon_setup(struct net_device *dev) | ||
383 | { | ||
384 | dev->hard_start_xmit = hwsim_mon_xmit; | ||
385 | dev->destructor = free_netdev; | ||
386 | ether_setup(dev); | ||
387 | dev->tx_queue_len = 0; | ||
388 | dev->type = ARPHRD_IEEE80211_RADIOTAP; | ||
389 | memset(dev->dev_addr, 0, ETH_ALEN); | ||
390 | dev->dev_addr[0] = 0x12; | ||
391 | } | ||
392 | |||
393 | |||
394 | static int __init init_mac80211_hwsim(void) | ||
395 | { | ||
396 | int i, err = 0; | ||
397 | u8 addr[ETH_ALEN]; | ||
398 | struct mac80211_hwsim_data *data; | ||
399 | struct ieee80211_hw *hw; | ||
400 | DECLARE_MAC_BUF(mac); | ||
401 | |||
402 | if (radios < 1 || radios > 65535) | ||
403 | return -EINVAL; | ||
404 | |||
405 | hwsim_radio_count = radios; | ||
406 | hwsim_radios = kcalloc(hwsim_radio_count, | ||
407 | sizeof(struct ieee80211_hw *), GFP_KERNEL); | ||
408 | if (hwsim_radios == NULL) | ||
409 | return -ENOMEM; | ||
410 | |||
411 | hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); | ||
412 | if (IS_ERR(hwsim_class)) { | ||
413 | kfree(hwsim_radios); | ||
414 | return PTR_ERR(hwsim_class); | ||
415 | } | ||
416 | |||
417 | memset(addr, 0, ETH_ALEN); | ||
418 | addr[0] = 0x02; | ||
419 | |||
420 | for (i = 0; i < hwsim_radio_count; i++) { | ||
421 | printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", | ||
422 | i); | ||
423 | hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); | ||
424 | if (hw == NULL) { | ||
425 | printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw " | ||
426 | "failed\n"); | ||
427 | err = -ENOMEM; | ||
428 | goto failed; | ||
429 | } | ||
430 | hwsim_radios[i] = hw; | ||
431 | |||
432 | data = hw->priv; | ||
433 | data->dev = device_create(hwsim_class, NULL, 0, "hwsim%d", i); | ||
434 | if (IS_ERR(data->dev)) { | ||
435 | printk(KERN_DEBUG "mac80211_hwsim: device_create " | ||
436 | "failed (%ld)\n", PTR_ERR(data->dev)); | ||
437 | err = -ENOMEM; | ||
438 | goto failed; | ||
439 | } | ||
440 | data->dev->driver = &mac80211_hwsim_driver; | ||
441 | dev_set_drvdata(data->dev, hw); | ||
442 | |||
443 | SET_IEEE80211_DEV(hw, data->dev); | ||
444 | addr[3] = i >> 8; | ||
445 | addr[4] = i; | ||
446 | SET_IEEE80211_PERM_ADDR(hw, addr); | ||
447 | |||
448 | hw->channel_change_time = 1; | ||
449 | hw->queues = 1; | ||
450 | |||
451 | memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); | ||
452 | memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); | ||
453 | data->band.channels = data->channels; | ||
454 | data->band.n_channels = ARRAY_SIZE(hwsim_channels); | ||
455 | data->band.bitrates = data->rates; | ||
456 | data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); | ||
457 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; | ||
458 | |||
459 | err = ieee80211_register_hw(hw); | ||
460 | if (err < 0) { | ||
461 | printk(KERN_DEBUG "mac80211_hwsim: " | ||
462 | "ieee80211_register_hw failed (%d)\n", err); | ||
463 | goto failed; | ||
464 | } | ||
465 | |||
466 | printk(KERN_DEBUG "%s: hwaddr %s registered\n", | ||
467 | wiphy_name(hw->wiphy), | ||
468 | print_mac(mac, hw->wiphy->perm_addr)); | ||
469 | |||
470 | setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, | ||
471 | (unsigned long) hw); | ||
472 | } | ||
473 | |||
474 | hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); | ||
475 | if (hwsim_mon == NULL) | ||
476 | goto failed; | ||
477 | |||
478 | rtnl_lock(); | ||
479 | |||
480 | err = dev_alloc_name(hwsim_mon, hwsim_mon->name); | ||
481 | if (err < 0) { | ||
482 | goto failed_mon; | ||
483 | } | ||
484 | |||
485 | err = register_netdevice(hwsim_mon); | ||
486 | if (err < 0) | ||
487 | goto failed_mon; | ||
488 | |||
489 | rtnl_unlock(); | ||
490 | |||
491 | return 0; | ||
492 | |||
493 | failed_mon: | ||
494 | rtnl_unlock(); | ||
495 | free_netdev(hwsim_mon); | ||
496 | |||
497 | failed: | ||
498 | mac80211_hwsim_free(); | ||
499 | return err; | ||
500 | } | ||
501 | |||
502 | |||
503 | static void __exit exit_mac80211_hwsim(void) | ||
504 | { | ||
505 | printk(KERN_DEBUG "mac80211_hwsim: unregister %d radios\n", | ||
506 | hwsim_radio_count); | ||
507 | |||
508 | unregister_netdev(hwsim_mon); | ||
509 | mac80211_hwsim_free(); | ||
510 | } | ||
511 | |||
512 | |||
513 | module_init(init_mac80211_hwsim); | ||
514 | module_exit(exit_mac80211_hwsim); | ||
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 3954897d0678..a36d2c85e26e 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -310,8 +310,11 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, | |||
310 | #define CAP_MODE_MASK 7 | 310 | #define CAP_MODE_MASK 7 |
311 | #define CAP_SUPPORT_TXPOWER 8 | 311 | #define CAP_SUPPORT_TXPOWER 8 |
312 | 312 | ||
313 | #define WORK_CONNECTION_EVENT (1<<0) | 313 | #define WORK_LINK_UP (1<<0) |
314 | #define WORK_SET_MULTICAST_LIST (1<<1) | 314 | #define WORK_LINK_DOWN (1<<1) |
315 | #define WORK_SET_MULTICAST_LIST (1<<2) | ||
316 | |||
317 | #define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) | ||
315 | 318 | ||
316 | /* RNDIS device private data */ | 319 | /* RNDIS device private data */ |
317 | struct rndis_wext_private { | 320 | struct rndis_wext_private { |
@@ -361,6 +364,8 @@ struct rndis_wext_private { | |||
361 | u8 *wpa_ie; | 364 | u8 *wpa_ie; |
362 | int wpa_cipher_pair; | 365 | int wpa_cipher_pair; |
363 | int wpa_cipher_group; | 366 | int wpa_cipher_group; |
367 | |||
368 | u8 command_buffer[COMMAND_BUFFER_SIZE]; | ||
364 | }; | 369 | }; |
365 | 370 | ||
366 | 371 | ||
@@ -427,18 +432,23 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
427 | buflen = *len + sizeof(*u.get); | 432 | buflen = *len + sizeof(*u.get); |
428 | if (buflen < CONTROL_BUFFER_SIZE) | 433 | if (buflen < CONTROL_BUFFER_SIZE) |
429 | buflen = CONTROL_BUFFER_SIZE; | 434 | buflen = CONTROL_BUFFER_SIZE; |
430 | u.buf = kmalloc(buflen, GFP_KERNEL); | 435 | |
431 | if (!u.buf) | 436 | if (buflen > COMMAND_BUFFER_SIZE) { |
432 | return -ENOMEM; | 437 | u.buf = kmalloc(buflen, GFP_KERNEL); |
438 | if (!u.buf) | ||
439 | return -ENOMEM; | ||
440 | } else { | ||
441 | u.buf = priv->command_buffer; | ||
442 | } | ||
443 | |||
444 | mutex_lock(&priv->command_lock); | ||
445 | |||
433 | memset(u.get, 0, sizeof *u.get); | 446 | memset(u.get, 0, sizeof *u.get); |
434 | u.get->msg_type = RNDIS_MSG_QUERY; | 447 | u.get->msg_type = RNDIS_MSG_QUERY; |
435 | u.get->msg_len = ccpu2(sizeof *u.get); | 448 | u.get->msg_len = ccpu2(sizeof *u.get); |
436 | u.get->oid = oid; | 449 | u.get->oid = oid; |
437 | 450 | ||
438 | mutex_lock(&priv->command_lock); | ||
439 | ret = rndis_command(dev, u.header); | 451 | ret = rndis_command(dev, u.header); |
440 | mutex_unlock(&priv->command_lock); | ||
441 | |||
442 | if (ret == 0) { | 452 | if (ret == 0) { |
443 | ret = le32_to_cpu(u.get_c->len); | 453 | ret = le32_to_cpu(u.get_c->len); |
444 | *len = (*len > ret) ? ret : *len; | 454 | *len = (*len > ret) ? ret : *len; |
@@ -446,7 +456,10 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
446 | ret = rndis_error_status(u.get_c->status); | 456 | ret = rndis_error_status(u.get_c->status); |
447 | } | 457 | } |
448 | 458 | ||
449 | kfree(u.buf); | 459 | mutex_unlock(&priv->command_lock); |
460 | |||
461 | if (u.buf != priv->command_buffer) | ||
462 | kfree(u.buf); | ||
450 | return ret; | 463 | return ret; |
451 | } | 464 | } |
452 | 465 | ||
@@ -465,9 +478,16 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | |||
465 | buflen = len + sizeof(*u.set); | 478 | buflen = len + sizeof(*u.set); |
466 | if (buflen < CONTROL_BUFFER_SIZE) | 479 | if (buflen < CONTROL_BUFFER_SIZE) |
467 | buflen = CONTROL_BUFFER_SIZE; | 480 | buflen = CONTROL_BUFFER_SIZE; |
468 | u.buf = kmalloc(buflen, GFP_KERNEL); | 481 | |
469 | if (!u.buf) | 482 | if (buflen > COMMAND_BUFFER_SIZE) { |
470 | return -ENOMEM; | 483 | u.buf = kmalloc(buflen, GFP_KERNEL); |
484 | if (!u.buf) | ||
485 | return -ENOMEM; | ||
486 | } else { | ||
487 | u.buf = priv->command_buffer; | ||
488 | } | ||
489 | |||
490 | mutex_lock(&priv->command_lock); | ||
471 | 491 | ||
472 | memset(u.set, 0, sizeof *u.set); | 492 | memset(u.set, 0, sizeof *u.set); |
473 | u.set->msg_type = RNDIS_MSG_SET; | 493 | u.set->msg_type = RNDIS_MSG_SET; |
@@ -478,14 +498,14 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | |||
478 | u.set->handle = ccpu2(0); | 498 | u.set->handle = ccpu2(0); |
479 | memcpy(u.buf + sizeof(*u.set), data, len); | 499 | memcpy(u.buf + sizeof(*u.set), data, len); |
480 | 500 | ||
481 | mutex_lock(&priv->command_lock); | ||
482 | ret = rndis_command(dev, u.header); | 501 | ret = rndis_command(dev, u.header); |
483 | mutex_unlock(&priv->command_lock); | ||
484 | |||
485 | if (ret == 0) | 502 | if (ret == 0) |
486 | ret = rndis_error_status(u.set_c->status); | 503 | ret = rndis_error_status(u.set_c->status); |
487 | 504 | ||
488 | kfree(u.buf); | 505 | mutex_unlock(&priv->command_lock); |
506 | |||
507 | if (u.buf != priv->command_buffer) | ||
508 | kfree(u.buf); | ||
489 | return ret; | 509 | return ret; |
490 | } | 510 | } |
491 | 511 | ||
@@ -620,8 +640,7 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq) | |||
620 | static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) | 640 | static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) |
621 | { | 641 | { |
622 | if (freq->m < 1000 && freq->e == 0) { | 642 | if (freq->m < 1000 && freq->e == 0) { |
623 | if (freq->m >= 1 && | 643 | if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan)) |
624 | freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0]))) | ||
625 | *dsconfig = freq_chan[freq->m - 1] * 1000; | 644 | *dsconfig = freq_chan[freq->m - 1] * 1000; |
626 | else | 645 | else |
627 | return -1; | 646 | return -1; |
@@ -1159,10 +1178,9 @@ static int rndis_iw_get_range(struct net_device *dev, | |||
1159 | range->throughput = 11 * 1000 * 1000 / 2; | 1178 | range->throughput = 11 * 1000 * 1000 / 2; |
1160 | } | 1179 | } |
1161 | 1180 | ||
1162 | range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); | 1181 | range->num_channels = ARRAY_SIZE(freq_chan); |
1163 | 1182 | ||
1164 | for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && | 1183 | for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { |
1165 | i < IW_MAX_FREQUENCIES; i++) { | ||
1166 | range->freq[i].i = i + 1; | 1184 | range->freq[i].i = i + 1; |
1167 | range->freq[i].m = freq_chan[i] * 100000; | 1185 | range->freq[i].m = freq_chan[i] * 100000; |
1168 | range->freq[i].e = 1; | 1186 | range->freq[i].e = 1; |
@@ -2213,7 +2231,9 @@ static void rndis_wext_worker(struct work_struct *work) | |||
2213 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; | 2231 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; |
2214 | int ret, offset; | 2232 | int ret, offset; |
2215 | 2233 | ||
2216 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { | 2234 | if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) { |
2235 | netif_carrier_on(usbdev->net); | ||
2236 | |||
2217 | info = kzalloc(assoc_size, GFP_KERNEL); | 2237 | info = kzalloc(assoc_size, GFP_KERNEL); |
2218 | if (!info) | 2238 | if (!info) |
2219 | goto get_bssid; | 2239 | goto get_bssid; |
@@ -2251,6 +2271,15 @@ get_bssid: | |||
2251 | } | 2271 | } |
2252 | } | 2272 | } |
2253 | 2273 | ||
2274 | if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { | ||
2275 | netif_carrier_off(usbdev->net); | ||
2276 | |||
2277 | evt.data.flags = 0; | ||
2278 | evt.data.length = 0; | ||
2279 | memset(evt.ap_addr.sa_data, 0, ETH_ALEN); | ||
2280 | wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); | ||
2281 | } | ||
2282 | |||
2254 | if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) | 2283 | if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) |
2255 | set_multicast_list(usbdev); | 2284 | set_multicast_list(usbdev); |
2256 | } | 2285 | } |
@@ -2260,29 +2289,24 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) | |||
2260 | struct usbnet *usbdev = dev->priv; | 2289 | struct usbnet *usbdev = dev->priv; |
2261 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2290 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); |
2262 | 2291 | ||
2292 | if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) | ||
2293 | return; | ||
2294 | |||
2263 | set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending); | 2295 | set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending); |
2264 | queue_work(priv->workqueue, &priv->work); | 2296 | queue_work(priv->workqueue, &priv->work); |
2265 | } | 2297 | } |
2266 | 2298 | ||
2267 | static void rndis_wext_link_change(struct usbnet *dev, int state) | 2299 | static void rndis_wext_link_change(struct usbnet *usbdev, int state) |
2268 | { | 2300 | { |
2269 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 2301 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); |
2270 | union iwreq_data evt; | ||
2271 | 2302 | ||
2272 | if (state) { | 2303 | /* queue work to avoid recursive calls into rndis_command */ |
2273 | /* queue work to avoid recursive calls into rndis_command */ | 2304 | set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); |
2274 | set_bit(WORK_CONNECTION_EVENT, &priv->work_pending); | 2305 | queue_work(priv->workqueue, &priv->work); |
2275 | queue_work(priv->workqueue, &priv->work); | ||
2276 | } else { | ||
2277 | evt.data.flags = 0; | ||
2278 | evt.data.length = 0; | ||
2279 | memset(evt.ap_addr.sa_data, 0, ETH_ALEN); | ||
2280 | wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL); | ||
2281 | } | ||
2282 | } | 2306 | } |
2283 | 2307 | ||
2284 | 2308 | ||
2285 | static int rndis_wext_get_caps(struct usbnet *dev) | 2309 | static int rndis_wext_get_caps(struct usbnet *usbdev) |
2286 | { | 2310 | { |
2287 | struct { | 2311 | struct { |
2288 | __le32 num_items; | 2312 | __le32 num_items; |
@@ -2290,18 +2314,18 @@ static int rndis_wext_get_caps(struct usbnet *dev) | |||
2290 | } networks_supported; | 2314 | } networks_supported; |
2291 | int len, retval, i, n; | 2315 | int len, retval, i, n; |
2292 | __le32 tx_power; | 2316 | __le32 tx_power; |
2293 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 2317 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); |
2294 | 2318 | ||
2295 | /* determine if supports setting txpower */ | 2319 | /* determine if supports setting txpower */ |
2296 | len = sizeof(tx_power); | 2320 | len = sizeof(tx_power); |
2297 | retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power, | 2321 | retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power, |
2298 | &len); | 2322 | &len); |
2299 | if (retval == 0 && le32_to_cpu(tx_power) != 0xFF) | 2323 | if (retval == 0 && le32_to_cpu(tx_power) != 0xFF) |
2300 | priv->caps |= CAP_SUPPORT_TXPOWER; | 2324 | priv->caps |= CAP_SUPPORT_TXPOWER; |
2301 | 2325 | ||
2302 | /* determine supported modes */ | 2326 | /* determine supported modes */ |
2303 | len = sizeof(networks_supported); | 2327 | len = sizeof(networks_supported); |
2304 | retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED, | 2328 | retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, |
2305 | &networks_supported, &len); | 2329 | &networks_supported, &len); |
2306 | if (retval >= 0) { | 2330 | if (retval >= 0) { |
2307 | n = le32_to_cpu(networks_supported.num_items); | 2331 | n = le32_to_cpu(networks_supported.num_items); |
@@ -2440,9 +2464,9 @@ end: | |||
2440 | } | 2464 | } |
2441 | 2465 | ||
2442 | 2466 | ||
2443 | static int bcm4320_early_init(struct usbnet *dev) | 2467 | static int bcm4320_early_init(struct usbnet *usbdev) |
2444 | { | 2468 | { |
2445 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 2469 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); |
2446 | char buf[8]; | 2470 | char buf[8]; |
2447 | 2471 | ||
2448 | /* Early initialization settings, setting these won't have effect | 2472 | /* Early initialization settings, setting these won't have effect |
@@ -2490,51 +2514,48 @@ static int bcm4320_early_init(struct usbnet *dev) | |||
2490 | else | 2514 | else |
2491 | priv->param_workaround_interval = modparam_workaround_interval; | 2515 | priv->param_workaround_interval = modparam_workaround_interval; |
2492 | 2516 | ||
2493 | rndis_set_config_parameter_str(dev, "Country", priv->param_country); | 2517 | rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); |
2494 | rndis_set_config_parameter_str(dev, "FrameBursting", | 2518 | rndis_set_config_parameter_str(usbdev, "FrameBursting", |
2495 | priv->param_frameburst ? "1" : "0"); | 2519 | priv->param_frameburst ? "1" : "0"); |
2496 | rndis_set_config_parameter_str(dev, "Afterburner", | 2520 | rndis_set_config_parameter_str(usbdev, "Afterburner", |
2497 | priv->param_afterburner ? "1" : "0"); | 2521 | priv->param_afterburner ? "1" : "0"); |
2498 | sprintf(buf, "%d", priv->param_power_save); | 2522 | sprintf(buf, "%d", priv->param_power_save); |
2499 | rndis_set_config_parameter_str(dev, "PowerSaveMode", buf); | 2523 | rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf); |
2500 | sprintf(buf, "%d", priv->param_power_output); | 2524 | sprintf(buf, "%d", priv->param_power_output); |
2501 | rndis_set_config_parameter_str(dev, "PwrOut", buf); | 2525 | rndis_set_config_parameter_str(usbdev, "PwrOut", buf); |
2502 | sprintf(buf, "%d", priv->param_roamtrigger); | 2526 | sprintf(buf, "%d", priv->param_roamtrigger); |
2503 | rndis_set_config_parameter_str(dev, "RoamTrigger", buf); | 2527 | rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf); |
2504 | sprintf(buf, "%d", priv->param_roamdelta); | 2528 | sprintf(buf, "%d", priv->param_roamdelta); |
2505 | rndis_set_config_parameter_str(dev, "RoamDelta", buf); | 2529 | rndis_set_config_parameter_str(usbdev, "RoamDelta", buf); |
2506 | 2530 | ||
2507 | return 0; | 2531 | return 0; |
2508 | } | 2532 | } |
2509 | 2533 | ||
2510 | 2534 | ||
2511 | static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) | 2535 | static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) |
2512 | { | 2536 | { |
2513 | struct net_device *net = dev->net; | ||
2514 | struct rndis_wext_private *priv; | 2537 | struct rndis_wext_private *priv; |
2515 | int retval, len; | 2538 | int retval, len; |
2516 | __le32 tmp; | 2539 | __le32 tmp; |
2517 | 2540 | ||
2518 | /* allocate rndis private data */ | 2541 | /* allocate rndis private data */ |
2519 | priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); | 2542 | priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); |
2520 | if (!priv) | 2543 | if (!priv) |
2521 | return -ENOMEM; | 2544 | return -ENOMEM; |
2522 | 2545 | ||
2523 | /* These have to be initialized before calling generic_rndis_bind(). | 2546 | /* These have to be initialized before calling generic_rndis_bind(). |
2524 | * Otherwise we'll be in big trouble in rndis_wext_early_init(). | 2547 | * Otherwise we'll be in big trouble in rndis_wext_early_init(). |
2525 | */ | 2548 | */ |
2526 | dev->driver_priv = priv; | 2549 | usbdev->driver_priv = priv; |
2527 | memset(priv, 0, sizeof(*priv)); | ||
2528 | memset(priv->name, 0, sizeof(priv->name)); | ||
2529 | strcpy(priv->name, "IEEE802.11"); | 2550 | strcpy(priv->name, "IEEE802.11"); |
2530 | net->wireless_handlers = &rndis_iw_handlers; | 2551 | usbdev->net->wireless_handlers = &rndis_iw_handlers; |
2531 | priv->usbdev = dev; | 2552 | priv->usbdev = usbdev; |
2532 | 2553 | ||
2533 | mutex_init(&priv->command_lock); | 2554 | mutex_init(&priv->command_lock); |
2534 | spin_lock_init(&priv->stats_lock); | 2555 | spin_lock_init(&priv->stats_lock); |
2535 | 2556 | ||
2536 | /* try bind rndis_host */ | 2557 | /* try bind rndis_host */ |
2537 | retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS); | 2558 | retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); |
2538 | if (retval < 0) | 2559 | if (retval < 0) |
2539 | goto fail; | 2560 | goto fail; |
2540 | 2561 | ||
@@ -2545,20 +2566,21 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) | |||
2545 | * rndis_host wants to avoid all OID as much as possible | 2566 | * rndis_host wants to avoid all OID as much as possible |
2546 | * so do promisc/multicast handling in rndis_wext. | 2567 | * so do promisc/multicast handling in rndis_wext. |
2547 | */ | 2568 | */ |
2548 | dev->net->set_multicast_list = rndis_wext_set_multicast_list; | 2569 | usbdev->net->set_multicast_list = rndis_wext_set_multicast_list; |
2549 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; | 2570 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; |
2550 | retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, | 2571 | retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, |
2551 | sizeof(tmp)); | 2572 | sizeof(tmp)); |
2552 | 2573 | ||
2553 | len = sizeof(tmp); | 2574 | len = sizeof(tmp); |
2554 | retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len); | 2575 | retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, |
2576 | &len); | ||
2555 | priv->multicast_size = le32_to_cpu(tmp); | 2577 | priv->multicast_size = le32_to_cpu(tmp); |
2556 | if (retval < 0 || priv->multicast_size < 0) | 2578 | if (retval < 0 || priv->multicast_size < 0) |
2557 | priv->multicast_size = 0; | 2579 | priv->multicast_size = 0; |
2558 | if (priv->multicast_size > 0) | 2580 | if (priv->multicast_size > 0) |
2559 | dev->net->flags |= IFF_MULTICAST; | 2581 | usbdev->net->flags |= IFF_MULTICAST; |
2560 | else | 2582 | else |
2561 | dev->net->flags &= ~IFF_MULTICAST; | 2583 | usbdev->net->flags &= ~IFF_MULTICAST; |
2562 | 2584 | ||
2563 | priv->iwstats.qual.qual = 0; | 2585 | priv->iwstats.qual.qual = 0; |
2564 | priv->iwstats.qual.level = 0; | 2586 | priv->iwstats.qual.level = 0; |
@@ -2568,12 +2590,13 @@ static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) | |||
2568 | | IW_QUAL_QUAL_INVALID | 2590 | | IW_QUAL_QUAL_INVALID |
2569 | | IW_QUAL_LEVEL_INVALID; | 2591 | | IW_QUAL_LEVEL_INVALID; |
2570 | 2592 | ||
2571 | rndis_wext_get_caps(dev); | 2593 | rndis_wext_get_caps(usbdev); |
2572 | set_default_iw_params(dev); | 2594 | set_default_iw_params(usbdev); |
2573 | 2595 | ||
2574 | /* turn radio on */ | 2596 | /* turn radio on */ |
2575 | priv->radio_on = 1; | 2597 | priv->radio_on = 1; |
2576 | disassociate(dev, 1); | 2598 | disassociate(usbdev, 1); |
2599 | netif_carrier_off(usbdev->net); | ||
2577 | 2600 | ||
2578 | /* because rndis_command() sleeps we need to use workqueue */ | 2601 | /* because rndis_command() sleeps we need to use workqueue */ |
2579 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); | 2602 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); |
@@ -2590,12 +2613,12 @@ fail: | |||
2590 | } | 2613 | } |
2591 | 2614 | ||
2592 | 2615 | ||
2593 | static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf) | 2616 | static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) |
2594 | { | 2617 | { |
2595 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 2618 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); |
2596 | 2619 | ||
2597 | /* turn radio off */ | 2620 | /* turn radio off */ |
2598 | disassociate(dev, 0); | 2621 | disassociate(usbdev, 0); |
2599 | 2622 | ||
2600 | cancel_delayed_work_sync(&priv->stats_work); | 2623 | cancel_delayed_work_sync(&priv->stats_work); |
2601 | cancel_work_sync(&priv->work); | 2624 | cancel_work_sync(&priv->work); |
@@ -2606,13 +2629,13 @@ static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
2606 | kfree(priv->wpa_ie); | 2629 | kfree(priv->wpa_ie); |
2607 | kfree(priv); | 2630 | kfree(priv); |
2608 | 2631 | ||
2609 | rndis_unbind(dev, intf); | 2632 | rndis_unbind(usbdev, intf); |
2610 | } | 2633 | } |
2611 | 2634 | ||
2612 | 2635 | ||
2613 | static int rndis_wext_reset(struct usbnet *dev) | 2636 | static int rndis_wext_reset(struct usbnet *usbdev) |
2614 | { | 2637 | { |
2615 | return deauthenticate(dev); | 2638 | return deauthenticate(usbdev); |
2616 | } | 2639 | } |
2617 | 2640 | ||
2618 | 2641 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 900140d3b304..bb3d83560d02 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -277,6 +277,17 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev, | |||
277 | 277 | ||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | |||
281 | static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev, | ||
282 | struct rt2x00_led *led, | ||
283 | enum led_type type) | ||
284 | { | ||
285 | led->rt2x00dev = rt2x00dev; | ||
286 | led->type = type; | ||
287 | led->led_dev.brightness_set = rt2400pci_brightness_set; | ||
288 | led->led_dev.blink_set = rt2400pci_blink_set; | ||
289 | led->flags = LED_INITIALIZED; | ||
290 | } | ||
280 | #endif /* CONFIG_RT2400PCI_LEDS */ | 291 | #endif /* CONFIG_RT2400PCI_LEDS */ |
281 | 292 | ||
282 | /* | 293 | /* |
@@ -781,25 +792,32 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
781 | return 0; | 792 | return 0; |
782 | } | 793 | } |
783 | 794 | ||
784 | static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) | 795 | static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
785 | { | 796 | { |
786 | unsigned int i; | 797 | unsigned int i; |
787 | u16 eeprom; | ||
788 | u8 reg_id; | ||
789 | u8 value; | 798 | u8 value; |
790 | 799 | ||
791 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 800 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
792 | rt2400pci_bbp_read(rt2x00dev, 0, &value); | 801 | rt2400pci_bbp_read(rt2x00dev, 0, &value); |
793 | if ((value != 0xff) && (value != 0x00)) | 802 | if ((value != 0xff) && (value != 0x00)) |
794 | goto continue_csr_init; | 803 | return 0; |
795 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
796 | udelay(REGISTER_BUSY_DELAY); | 804 | udelay(REGISTER_BUSY_DELAY); |
797 | } | 805 | } |
798 | 806 | ||
799 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 807 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
800 | return -EACCES; | 808 | return -EACCES; |
809 | } | ||
810 | |||
811 | static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
812 | { | ||
813 | unsigned int i; | ||
814 | u16 eeprom; | ||
815 | u8 reg_id; | ||
816 | u8 value; | ||
817 | |||
818 | if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev))) | ||
819 | return -EACCES; | ||
801 | 820 | ||
802 | continue_csr_init: | ||
803 | rt2400pci_bbp_write(rt2x00dev, 1, 0x00); | 821 | rt2400pci_bbp_write(rt2x00dev, 1, 0x00); |
804 | rt2400pci_bbp_write(rt2x00dev, 3, 0x27); | 822 | rt2400pci_bbp_write(rt2x00dev, 3, 0x27); |
805 | rt2400pci_bbp_write(rt2x00dev, 4, 0x08); | 823 | rt2400pci_bbp_write(rt2x00dev, 4, 0x08); |
@@ -838,7 +856,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
838 | 856 | ||
839 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 857 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); |
840 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | 858 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, |
841 | state == STATE_RADIO_RX_OFF); | 859 | (state == STATE_RADIO_RX_OFF) || |
860 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
842 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 861 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); |
843 | } | 862 | } |
844 | 863 | ||
@@ -875,17 +894,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
875 | /* | 894 | /* |
876 | * Initialize all registers. | 895 | * Initialize all registers. |
877 | */ | 896 | */ |
878 | if (rt2400pci_init_queues(rt2x00dev) || | 897 | if (unlikely(rt2400pci_init_queues(rt2x00dev) || |
879 | rt2400pci_init_registers(rt2x00dev) || | 898 | rt2400pci_init_registers(rt2x00dev) || |
880 | rt2400pci_init_bbp(rt2x00dev)) { | 899 | rt2400pci_init_bbp(rt2x00dev))) |
881 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
882 | return -EIO; | 900 | return -EIO; |
883 | } | ||
884 | |||
885 | /* | ||
886 | * Enable interrupts. | ||
887 | */ | ||
888 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
889 | 901 | ||
890 | return 0; | 902 | return 0; |
891 | } | 903 | } |
@@ -907,11 +919,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
907 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 919 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
908 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | 920 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); |
909 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 921 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
910 | |||
911 | /* | ||
912 | * Disable interrupts. | ||
913 | */ | ||
914 | rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
915 | } | 922 | } |
916 | 923 | ||
917 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | 924 | static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -946,10 +953,6 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
946 | msleep(10); | 953 | msleep(10); |
947 | } | 954 | } |
948 | 955 | ||
949 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
950 | "current device state: bbp %d and rf %d.\n", | ||
951 | state, bbp_state, rf_state); | ||
952 | |||
953 | return -EBUSY; | 956 | return -EBUSY; |
954 | } | 957 | } |
955 | 958 | ||
@@ -967,11 +970,13 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
967 | break; | 970 | break; |
968 | case STATE_RADIO_RX_ON: | 971 | case STATE_RADIO_RX_ON: |
969 | case STATE_RADIO_RX_ON_LINK: | 972 | case STATE_RADIO_RX_ON_LINK: |
970 | rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
971 | break; | ||
972 | case STATE_RADIO_RX_OFF: | 973 | case STATE_RADIO_RX_OFF: |
973 | case STATE_RADIO_RX_OFF_LINK: | 974 | case STATE_RADIO_RX_OFF_LINK: |
974 | rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 975 | rt2400pci_toggle_rx(rt2x00dev, state); |
976 | break; | ||
977 | case STATE_RADIO_IRQ_ON: | ||
978 | case STATE_RADIO_IRQ_OFF: | ||
979 | rt2400pci_toggle_irq(rt2x00dev, state); | ||
975 | break; | 980 | break; |
976 | case STATE_DEEP_SLEEP: | 981 | case STATE_DEEP_SLEEP: |
977 | case STATE_SLEEP: | 982 | case STATE_SLEEP: |
@@ -984,6 +989,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
984 | break; | 989 | break; |
985 | } | 990 | } |
986 | 991 | ||
992 | if (unlikely(retval)) | ||
993 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
994 | state, retval); | ||
995 | |||
987 | return retval; | 996 | return retval; |
988 | } | 997 | } |
989 | 998 | ||
@@ -1007,8 +1016,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1007 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1016 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1008 | 1017 | ||
1009 | rt2x00_desc_read(txd, 2, &word); | 1018 | rt2x00_desc_read(txd, 2, &word); |
1010 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skbdesc->data_len); | 1019 | rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); |
1011 | rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len); | 1020 | rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); |
1012 | rt2x00_desc_write(txd, 2, word); | 1021 | rt2x00_desc_write(txd, 2, word); |
1013 | 1022 | ||
1014 | rt2x00_desc_read(txd, 3, &word); | 1023 | rt2x00_desc_read(txd, 3, &word); |
@@ -1300,23 +1309,10 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1300 | #ifdef CONFIG_RT2400PCI_LEDS | 1309 | #ifdef CONFIG_RT2400PCI_LEDS |
1301 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1310 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1302 | 1311 | ||
1303 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 1312 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1304 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 1313 | if (value == LED_MODE_TXRX_ACTIVITY) |
1305 | rt2x00dev->led_radio.led_dev.brightness_set = | 1314 | rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1306 | rt2400pci_brightness_set; | 1315 | LED_TYPE_ACTIVITY); |
1307 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1308 | rt2400pci_blink_set; | ||
1309 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1310 | |||
1311 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1312 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1313 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; | ||
1314 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1315 | rt2400pci_brightness_set; | ||
1316 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1317 | rt2400pci_blink_set; | ||
1318 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1319 | } | ||
1320 | #endif /* CONFIG_RT2400PCI_LEDS */ | 1316 | #endif /* CONFIG_RT2400PCI_LEDS */ |
1321 | 1317 | ||
1322 | /* | 1318 | /* |
@@ -1511,9 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1511 | */ | 1507 | */ |
1512 | skbdesc = get_skb_frame_desc(skb); | 1508 | skbdesc = get_skb_frame_desc(skb); |
1513 | memset(skbdesc, 0, sizeof(*skbdesc)); | 1509 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1514 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1515 | skbdesc->data = skb->data; | ||
1516 | skbdesc->data_len = skb->len; | ||
1517 | skbdesc->desc = entry_priv->desc; | 1510 | skbdesc->desc = entry_priv->desc; |
1518 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 1511 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1519 | skbdesc->entry = intf->beacon; | 1512 | skbdesc->entry = intf->beacon; |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index e9aa326be9f6..bc5564258228 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -37,8 +37,6 @@ | |||
37 | * Signal information. | 37 | * Signal information. |
38 | * Defaul offset is required for RSSI <-> dBm conversion. | 38 | * Defaul offset is required for RSSI <-> dBm conversion. |
39 | */ | 39 | */ |
40 | #define MAX_SIGNAL 100 | ||
41 | #define MAX_RX_SSI -1 | ||
42 | #define DEFAULT_RSSI_OFFSET 100 | 40 | #define DEFAULT_RSSI_OFFSET 100 |
43 | 41 | ||
44 | /* | 42 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 673350953b89..3c956b91c4e3 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -277,6 +277,17 @@ static int rt2500pci_blink_set(struct led_classdev *led_cdev, | |||
277 | 277 | ||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | |||
281 | static void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev, | ||
282 | struct rt2x00_led *led, | ||
283 | enum led_type type) | ||
284 | { | ||
285 | led->rt2x00dev = rt2x00dev; | ||
286 | led->type = type; | ||
287 | led->led_dev.brightness_set = rt2500pci_brightness_set; | ||
288 | led->led_dev.blink_set = rt2500pci_blink_set; | ||
289 | led->flags = LED_INITIALIZED; | ||
290 | } | ||
280 | #endif /* CONFIG_RT2500PCI_LEDS */ | 291 | #endif /* CONFIG_RT2500PCI_LEDS */ |
281 | 292 | ||
282 | /* | 293 | /* |
@@ -924,25 +935,32 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
924 | return 0; | 935 | return 0; |
925 | } | 936 | } |
926 | 937 | ||
927 | static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) | 938 | static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
928 | { | 939 | { |
929 | unsigned int i; | 940 | unsigned int i; |
930 | u16 eeprom; | ||
931 | u8 reg_id; | ||
932 | u8 value; | 941 | u8 value; |
933 | 942 | ||
934 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 943 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
935 | rt2500pci_bbp_read(rt2x00dev, 0, &value); | 944 | rt2500pci_bbp_read(rt2x00dev, 0, &value); |
936 | if ((value != 0xff) && (value != 0x00)) | 945 | if ((value != 0xff) && (value != 0x00)) |
937 | goto continue_csr_init; | 946 | return 0; |
938 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
939 | udelay(REGISTER_BUSY_DELAY); | 947 | udelay(REGISTER_BUSY_DELAY); |
940 | } | 948 | } |
941 | 949 | ||
942 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 950 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
943 | return -EACCES; | 951 | return -EACCES; |
952 | } | ||
953 | |||
954 | static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
955 | { | ||
956 | unsigned int i; | ||
957 | u16 eeprom; | ||
958 | u8 reg_id; | ||
959 | u8 value; | ||
960 | |||
961 | if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev))) | ||
962 | return -EACCES; | ||
944 | 963 | ||
945 | continue_csr_init: | ||
946 | rt2500pci_bbp_write(rt2x00dev, 3, 0x02); | 964 | rt2500pci_bbp_write(rt2x00dev, 3, 0x02); |
947 | rt2500pci_bbp_write(rt2x00dev, 4, 0x19); | 965 | rt2500pci_bbp_write(rt2x00dev, 4, 0x19); |
948 | rt2500pci_bbp_write(rt2x00dev, 14, 0x1c); | 966 | rt2500pci_bbp_write(rt2x00dev, 14, 0x1c); |
@@ -997,7 +1015,8 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
997 | 1015 | ||
998 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); | 1016 | rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); |
999 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, | 1017 | rt2x00_set_field32(®, RXCSR0_DISABLE_RX, |
1000 | state == STATE_RADIO_RX_OFF); | 1018 | (state == STATE_RADIO_RX_OFF) || |
1019 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
1001 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); | 1020 | rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); |
1002 | } | 1021 | } |
1003 | 1022 | ||
@@ -1034,17 +1053,10 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1034 | /* | 1053 | /* |
1035 | * Initialize all registers. | 1054 | * Initialize all registers. |
1036 | */ | 1055 | */ |
1037 | if (rt2500pci_init_queues(rt2x00dev) || | 1056 | if (unlikely(rt2500pci_init_queues(rt2x00dev) || |
1038 | rt2500pci_init_registers(rt2x00dev) || | 1057 | rt2500pci_init_registers(rt2x00dev) || |
1039 | rt2500pci_init_bbp(rt2x00dev)) { | 1058 | rt2500pci_init_bbp(rt2x00dev))) |
1040 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1041 | return -EIO; | 1059 | return -EIO; |
1042 | } | ||
1043 | |||
1044 | /* | ||
1045 | * Enable interrupts. | ||
1046 | */ | ||
1047 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
1048 | 1060 | ||
1049 | return 0; | 1061 | return 0; |
1050 | } | 1062 | } |
@@ -1066,11 +1078,6 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1066 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); | 1078 | rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); |
1067 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); | 1079 | rt2x00_set_field32(®, TXCSR0_ABORT, 1); |
1068 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); | 1080 | rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); |
1069 | |||
1070 | /* | ||
1071 | * Disable interrupts. | ||
1072 | */ | ||
1073 | rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
1074 | } | 1081 | } |
1075 | 1082 | ||
1076 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | 1083 | static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, |
@@ -1105,10 +1112,6 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, | |||
1105 | msleep(10); | 1112 | msleep(10); |
1106 | } | 1113 | } |
1107 | 1114 | ||
1108 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1109 | "current device state: bbp %d and rf %d.\n", | ||
1110 | state, bbp_state, rf_state); | ||
1111 | |||
1112 | return -EBUSY; | 1115 | return -EBUSY; |
1113 | } | 1116 | } |
1114 | 1117 | ||
@@ -1126,11 +1129,13 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1126 | break; | 1129 | break; |
1127 | case STATE_RADIO_RX_ON: | 1130 | case STATE_RADIO_RX_ON: |
1128 | case STATE_RADIO_RX_ON_LINK: | 1131 | case STATE_RADIO_RX_ON_LINK: |
1129 | rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1130 | break; | ||
1131 | case STATE_RADIO_RX_OFF: | 1132 | case STATE_RADIO_RX_OFF: |
1132 | case STATE_RADIO_RX_OFF_LINK: | 1133 | case STATE_RADIO_RX_OFF_LINK: |
1133 | rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1134 | rt2500pci_toggle_rx(rt2x00dev, state); |
1135 | break; | ||
1136 | case STATE_RADIO_IRQ_ON: | ||
1137 | case STATE_RADIO_IRQ_OFF: | ||
1138 | rt2500pci_toggle_irq(rt2x00dev, state); | ||
1134 | break; | 1139 | break; |
1135 | case STATE_DEEP_SLEEP: | 1140 | case STATE_DEEP_SLEEP: |
1136 | case STATE_SLEEP: | 1141 | case STATE_SLEEP: |
@@ -1143,6 +1148,10 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1143 | break; | 1148 | break; |
1144 | } | 1149 | } |
1145 | 1150 | ||
1151 | if (unlikely(retval)) | ||
1152 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1153 | state, retval); | ||
1154 | |||
1146 | return retval; | 1155 | return retval; |
1147 | } | 1156 | } |
1148 | 1157 | ||
@@ -1478,23 +1487,10 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1478 | #ifdef CONFIG_RT2500PCI_LEDS | 1487 | #ifdef CONFIG_RT2500PCI_LEDS |
1479 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1488 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1480 | 1489 | ||
1481 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 1490 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1482 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 1491 | if (value == LED_MODE_TXRX_ACTIVITY) |
1483 | rt2x00dev->led_radio.led_dev.brightness_set = | 1492 | rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1484 | rt2500pci_brightness_set; | 1493 | LED_TYPE_ACTIVITY); |
1485 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1486 | rt2500pci_blink_set; | ||
1487 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1488 | |||
1489 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1490 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1491 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; | ||
1492 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1493 | rt2500pci_brightness_set; | ||
1494 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1495 | rt2500pci_blink_set; | ||
1496 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1497 | } | ||
1498 | #endif /* CONFIG_RT2500PCI_LEDS */ | 1494 | #endif /* CONFIG_RT2500PCI_LEDS */ |
1499 | 1495 | ||
1500 | /* | 1496 | /* |
@@ -1827,9 +1823,6 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1827 | */ | 1823 | */ |
1828 | skbdesc = get_skb_frame_desc(skb); | 1824 | skbdesc = get_skb_frame_desc(skb); |
1829 | memset(skbdesc, 0, sizeof(*skbdesc)); | 1825 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1830 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1831 | skbdesc->data = skb->data; | ||
1832 | skbdesc->data_len = skb->len; | ||
1833 | skbdesc->desc = entry_priv->desc; | 1826 | skbdesc->desc = entry_priv->desc; |
1834 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 1827 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1835 | skbdesc->entry = intf->beacon; | 1828 | skbdesc->entry = intf->beacon; |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index ea93b8f423a9..cb648c30a5b3 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h | |||
@@ -48,8 +48,6 @@ | |||
48 | * Signal information. | 48 | * Signal information. |
49 | * Defaul offset is required for RSSI <-> dBm conversion. | 49 | * Defaul offset is required for RSSI <-> dBm conversion. |
50 | */ | 50 | */ |
51 | #define MAX_SIGNAL 100 | ||
52 | #define MAX_RX_SSI -1 | ||
53 | #define DEFAULT_RSSI_OFFSET 121 | 51 | #define DEFAULT_RSSI_OFFSET 121 |
54 | 52 | ||
55 | /* | 53 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cca1504550dc..9851cefaabf3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -316,6 +316,17 @@ static int rt2500usb_blink_set(struct led_classdev *led_cdev, | |||
316 | 316 | ||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | |||
320 | static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev, | ||
321 | struct rt2x00_led *led, | ||
322 | enum led_type type) | ||
323 | { | ||
324 | led->rt2x00dev = rt2x00dev; | ||
325 | led->type = type; | ||
326 | led->led_dev.brightness_set = rt2500usb_brightness_set; | ||
327 | led->led_dev.blink_set = rt2500usb_blink_set; | ||
328 | led->flags = LED_INITIALIZED; | ||
329 | } | ||
319 | #endif /* CONFIG_RT2500USB_LEDS */ | 330 | #endif /* CONFIG_RT2500USB_LEDS */ |
320 | 331 | ||
321 | /* | 332 | /* |
@@ -847,25 +858,32 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
847 | return 0; | 858 | return 0; |
848 | } | 859 | } |
849 | 860 | ||
850 | static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) | 861 | static int rt2500usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
851 | { | 862 | { |
852 | unsigned int i; | 863 | unsigned int i; |
853 | u16 eeprom; | ||
854 | u8 value; | 864 | u8 value; |
855 | u8 reg_id; | ||
856 | 865 | ||
857 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 866 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
858 | rt2500usb_bbp_read(rt2x00dev, 0, &value); | 867 | rt2500usb_bbp_read(rt2x00dev, 0, &value); |
859 | if ((value != 0xff) && (value != 0x00)) | 868 | if ((value != 0xff) && (value != 0x00)) |
860 | goto continue_csr_init; | 869 | return 0; |
861 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
862 | udelay(REGISTER_BUSY_DELAY); | 870 | udelay(REGISTER_BUSY_DELAY); |
863 | } | 871 | } |
864 | 872 | ||
865 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 873 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
866 | return -EACCES; | 874 | return -EACCES; |
875 | } | ||
876 | |||
877 | static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
878 | { | ||
879 | unsigned int i; | ||
880 | u16 eeprom; | ||
881 | u8 value; | ||
882 | u8 reg_id; | ||
883 | |||
884 | if (unlikely(rt2500usb_wait_bbp_ready(rt2x00dev))) | ||
885 | return -EACCES; | ||
867 | 886 | ||
868 | continue_csr_init: | ||
869 | rt2500usb_bbp_write(rt2x00dev, 3, 0x02); | 887 | rt2500usb_bbp_write(rt2x00dev, 3, 0x02); |
870 | rt2500usb_bbp_write(rt2x00dev, 4, 0x19); | 888 | rt2500usb_bbp_write(rt2x00dev, 4, 0x19); |
871 | rt2500usb_bbp_write(rt2x00dev, 14, 0x1c); | 889 | rt2500usb_bbp_write(rt2x00dev, 14, 0x1c); |
@@ -921,7 +939,8 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
921 | 939 | ||
922 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | 940 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); |
923 | rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, | 941 | rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, |
924 | state == STATE_RADIO_RX_OFF); | 942 | (state == STATE_RADIO_RX_OFF) || |
943 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
925 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | 944 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); |
926 | } | 945 | } |
927 | 946 | ||
@@ -930,11 +949,9 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
930 | /* | 949 | /* |
931 | * Initialize all registers. | 950 | * Initialize all registers. |
932 | */ | 951 | */ |
933 | if (rt2500usb_init_registers(rt2x00dev) || | 952 | if (unlikely(rt2500usb_init_registers(rt2x00dev) || |
934 | rt2500usb_init_bbp(rt2x00dev)) { | 953 | rt2500usb_init_bbp(rt2x00dev))) |
935 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
936 | return -EIO; | 954 | return -EIO; |
937 | } | ||
938 | 955 | ||
939 | return 0; | 956 | return 0; |
940 | } | 957 | } |
@@ -987,10 +1004,6 @@ static int rt2500usb_set_state(struct rt2x00_dev *rt2x00dev, | |||
987 | msleep(30); | 1004 | msleep(30); |
988 | } | 1005 | } |
989 | 1006 | ||
990 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
991 | "current device state: bbp %d and rf %d.\n", | ||
992 | state, bbp_state, rf_state); | ||
993 | |||
994 | return -EBUSY; | 1007 | return -EBUSY; |
995 | } | 1008 | } |
996 | 1009 | ||
@@ -1008,11 +1021,13 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1008 | break; | 1021 | break; |
1009 | case STATE_RADIO_RX_ON: | 1022 | case STATE_RADIO_RX_ON: |
1010 | case STATE_RADIO_RX_ON_LINK: | 1023 | case STATE_RADIO_RX_ON_LINK: |
1011 | rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1012 | break; | ||
1013 | case STATE_RADIO_RX_OFF: | 1024 | case STATE_RADIO_RX_OFF: |
1014 | case STATE_RADIO_RX_OFF_LINK: | 1025 | case STATE_RADIO_RX_OFF_LINK: |
1015 | rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1026 | rt2500usb_toggle_rx(rt2x00dev, state); |
1027 | break; | ||
1028 | case STATE_RADIO_IRQ_ON: | ||
1029 | case STATE_RADIO_IRQ_OFF: | ||
1030 | /* No support, but no error either */ | ||
1016 | break; | 1031 | break; |
1017 | case STATE_DEEP_SLEEP: | 1032 | case STATE_DEEP_SLEEP: |
1018 | case STATE_SLEEP: | 1033 | case STATE_SLEEP: |
@@ -1025,6 +1040,10 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1025 | break; | 1040 | break; |
1026 | } | 1041 | } |
1027 | 1042 | ||
1043 | if (unlikely(retval)) | ||
1044 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1045 | state, retval); | ||
1046 | |||
1028 | return retval; | 1047 | return retval; |
1029 | } | 1048 | } |
1030 | 1049 | ||
@@ -1069,7 +1088,8 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1069 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, | 1088 | rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, |
1070 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); | 1089 | test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); |
1071 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1090 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1072 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1091 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, |
1092 | skb->len - skbdesc->desc_len); | ||
1073 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); | 1093 | rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); |
1074 | rt2x00_desc_write(txd, 0, word); | 1094 | rt2x00_desc_write(txd, 0, word); |
1075 | } | 1095 | } |
@@ -1097,8 +1117,10 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1097 | { | 1117 | { |
1098 | u16 reg; | 1118 | u16 reg; |
1099 | 1119 | ||
1100 | if (queue != QID_BEACON) | 1120 | if (queue != QID_BEACON) { |
1121 | rt2x00usb_kick_tx_queue(rt2x00dev, queue); | ||
1101 | return; | 1122 | return; |
1123 | } | ||
1102 | 1124 | ||
1103 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 1125 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
1104 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { | 1126 | if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { |
@@ -1134,14 +1156,10 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1134 | u32 word1; | 1156 | u32 word1; |
1135 | 1157 | ||
1136 | /* | 1158 | /* |
1137 | * Copy descriptor to the skb->cb array, this has 2 benefits: | 1159 | * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of |
1138 | * 1) Each descriptor word is 4 byte aligned. | 1160 | * frame data in rt2x00usb. |
1139 | * 2) Descriptor is safe from moving of frame data in rt2x00usb. | ||
1140 | */ | 1161 | */ |
1141 | skbdesc->desc_len = | 1162 | memcpy(skbdesc->desc, rxd, skbdesc->desc_len); |
1142 | min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); | ||
1143 | memcpy(entry->skb->cb, rxd, skbdesc->desc_len); | ||
1144 | skbdesc->desc = entry->skb->cb; | ||
1145 | rxd = (__le32 *)skbdesc->desc; | 1163 | rxd = (__le32 *)skbdesc->desc; |
1146 | 1164 | ||
1147 | /* | 1165 | /* |
@@ -1175,8 +1193,6 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1175 | * Adjust the skb memory window to the frame boundaries. | 1193 | * Adjust the skb memory window to the frame boundaries. |
1176 | */ | 1194 | */ |
1177 | skb_trim(entry->skb, rxdesc->size); | 1195 | skb_trim(entry->skb, rxdesc->size); |
1178 | skbdesc->data = entry->skb->data; | ||
1179 | skbdesc->data_len = rxdesc->size; | ||
1180 | } | 1196 | } |
1181 | 1197 | ||
1182 | /* | 1198 | /* |
@@ -1377,23 +1393,10 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1377 | #ifdef CONFIG_RT2500USB_LEDS | 1393 | #ifdef CONFIG_RT2500USB_LEDS |
1378 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); | 1394 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); |
1379 | 1395 | ||
1380 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 1396 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1381 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 1397 | if (value == LED_MODE_TXRX_ACTIVITY) |
1382 | rt2x00dev->led_radio.led_dev.brightness_set = | 1398 | rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1383 | rt2500usb_brightness_set; | 1399 | LED_TYPE_ACTIVITY); |
1384 | rt2x00dev->led_radio.led_dev.blink_set = | ||
1385 | rt2500usb_blink_set; | ||
1386 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1387 | |||
1388 | if (value == LED_MODE_TXRX_ACTIVITY) { | ||
1389 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1390 | rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; | ||
1391 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1392 | rt2500usb_brightness_set; | ||
1393 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1394 | rt2500usb_blink_set; | ||
1395 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1396 | } | ||
1397 | #endif /* CONFIG_RT2500USB_LEDS */ | 1400 | #endif /* CONFIG_RT2500USB_LEDS */ |
1398 | 1401 | ||
1399 | /* | 1402 | /* |
@@ -1703,9 +1706,6 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1703 | */ | 1706 | */ |
1704 | skbdesc = get_skb_frame_desc(skb); | 1707 | skbdesc = get_skb_frame_desc(skb); |
1705 | memset(skbdesc, 0, sizeof(*skbdesc)); | 1708 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1706 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1707 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | ||
1708 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | ||
1709 | skbdesc->desc = skb->data; | 1709 | skbdesc->desc = skb->data; |
1710 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 1710 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1711 | skbdesc->entry = intf->beacon; | 1711 | skbdesc->entry = intf->beacon; |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index 7d50098f0cc5..3e21fdf2b00f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -48,8 +48,6 @@ | |||
48 | * Signal information. | 48 | * Signal information. |
49 | * Defaul offset is required for RSSI <-> dBm conversion. | 49 | * Defaul offset is required for RSSI <-> dBm conversion. |
50 | */ | 50 | */ |
51 | #define MAX_SIGNAL 100 | ||
52 | #define MAX_RX_SSI -1 | ||
53 | #define DEFAULT_RSSI_OFFSET 120 | 51 | #define DEFAULT_RSSI_OFFSET 120 |
54 | 52 | ||
55 | /* | 53 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 15ec797c5ec1..0da8f972a1b2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -44,7 +44,7 @@ | |||
44 | /* | 44 | /* |
45 | * Module information. | 45 | * Module information. |
46 | */ | 46 | */ |
47 | #define DRV_VERSION "2.1.6" | 47 | #define DRV_VERSION "2.1.7" |
48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
49 | 49 | ||
50 | /* | 50 | /* |
@@ -546,8 +546,7 @@ struct rt2x00lib_ops { | |||
546 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, | 546 | void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, |
547 | struct sk_buff *skb, | 547 | struct sk_buff *skb, |
548 | struct txentry_desc *txdesc); | 548 | struct txentry_desc *txdesc); |
549 | int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, | 549 | int (*write_tx_data) (struct queue_entry *entry); |
550 | struct data_queue *queue, struct sk_buff *skb); | ||
551 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, | 550 | int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, |
552 | struct sk_buff *skb); | 551 | struct sk_buff *skb); |
553 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, | 552 | void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, |
@@ -827,7 +826,7 @@ struct rt2x00_dev { | |||
827 | * The Beacon array also contains the Atim queue | 826 | * The Beacon array also contains the Atim queue |
828 | * if that is supported by the device. | 827 | * if that is supported by the device. |
829 | */ | 828 | */ |
830 | int data_queues; | 829 | unsigned int data_queues; |
831 | struct data_queue *rx; | 830 | struct data_queue *rx; |
832 | struct data_queue *tx; | 831 | struct data_queue *tx; |
833 | struct data_queue *bcn; | 832 | struct data_queue *bcn; |
@@ -931,6 +930,12 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
931 | } | 930 | } |
932 | 931 | ||
933 | /** | 932 | /** |
933 | * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. | ||
934 | * @queue: The queue for which the skb will be applicable. | ||
935 | */ | ||
936 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); | ||
937 | |||
938 | /** | ||
934 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | 939 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input |
935 | * @entry: The entry which will be used to transfer the TX frame. | 940 | * @entry: The entry which will be used to transfer the TX frame. |
936 | * @txdesc: rt2x00 TX descriptor which will be initialized by this function. | 941 | * @txdesc: rt2x00 TX descriptor which will be initialized by this function. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index bd92cb8e68e0..300cf061035f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -133,7 +133,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
133 | return; | 133 | return; |
134 | } | 134 | } |
135 | 135 | ||
136 | skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len, | 136 | skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len, |
137 | GFP_ATOMIC); | 137 | GFP_ATOMIC); |
138 | if (!skbcopy) { | 138 | if (!skbcopy) { |
139 | DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); | 139 | DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); |
@@ -144,7 +144,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
144 | dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); | 144 | dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); |
145 | dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); | 145 | dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); |
146 | dump_hdr->desc_length = cpu_to_le32(desc->desc_len); | 146 | dump_hdr->desc_length = cpu_to_le32(desc->desc_len); |
147 | dump_hdr->data_length = cpu_to_le32(desc->data_len); | 147 | dump_hdr->data_length = cpu_to_le32(skb->len); |
148 | dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); | 148 | dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); |
149 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); | 149 | dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); |
150 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); | 150 | dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); |
@@ -155,7 +155,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
155 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); | 155 | dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); |
156 | 156 | ||
157 | memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len); | 157 | memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len); |
158 | memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len); | 158 | memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len); |
159 | 159 | ||
160 | skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); | 160 | skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); |
161 | wake_up_interruptible(&intf->frame_dump_waitqueue); | 161 | wake_up_interruptible(&intf->frame_dump_waitqueue); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index dc5ab90a52c3..9ea677320daa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -112,6 +112,8 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
112 | if (status) | 112 | if (status) |
113 | return status; | 113 | return status; |
114 | 114 | ||
115 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
116 | |||
115 | rt2x00leds_led_radio(rt2x00dev, true); | 117 | rt2x00leds_led_radio(rt2x00dev, true); |
116 | rt2x00led_led_activity(rt2x00dev, true); | 118 | rt2x00led_led_activity(rt2x00dev, true); |
117 | 119 | ||
@@ -157,6 +159,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
157 | * Disable radio. | 159 | * Disable radio. |
158 | */ | 160 | */ |
159 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); | 161 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); |
162 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
160 | rt2x00led_led_activity(rt2x00dev, false); | 163 | rt2x00led_led_activity(rt2x00dev, false); |
161 | rt2x00leds_led_radio(rt2x00dev, false); | 164 | rt2x00leds_led_radio(rt2x00dev, false); |
162 | } | 165 | } |
@@ -551,14 +554,32 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
551 | { | 554 | { |
552 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 555 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
553 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 556 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
557 | unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
554 | struct ieee80211_supported_band *sband; | 558 | struct ieee80211_supported_band *sband; |
555 | struct ieee80211_hdr *hdr; | 559 | struct ieee80211_hdr *hdr; |
556 | const struct rt2x00_rate *rate; | 560 | const struct rt2x00_rate *rate; |
561 | unsigned int align; | ||
557 | unsigned int i; | 562 | unsigned int i; |
558 | int idx = -1; | 563 | int idx = -1; |
559 | u16 fc; | 564 | u16 fc; |
560 | 565 | ||
561 | /* | 566 | /* |
567 | * The data behind the ieee80211 header must be | ||
568 | * aligned on a 4 byte boundary. | ||
569 | */ | ||
570 | align = ((unsigned long)(entry->skb->data + header_size)) & 3; | ||
571 | |||
572 | if (align) { | ||
573 | skb_push(entry->skb, align); | ||
574 | /* Move entire frame in 1 command */ | ||
575 | memmove(entry->skb->data, entry->skb->data + align, | ||
576 | rxdesc->size); | ||
577 | } | ||
578 | |||
579 | /* Update data pointers, trim buffer to correct size */ | ||
580 | skb_trim(entry->skb, rxdesc->size); | ||
581 | |||
582 | /* | ||
562 | * Update RX statistics. | 583 | * Update RX statistics. |
563 | */ | 584 | */ |
564 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; | 585 | sband = &rt2x00dev->bands[rt2x00dev->curr_band]; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index c4ce534e3cdb..558f45bf27e3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -101,6 +101,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
101 | /* | 101 | /* |
102 | * Queue handlers. | 102 | * Queue handlers. |
103 | */ | 103 | */ |
104 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | ||
104 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | 105 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); |
105 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | 106 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); |
106 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | 107 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index b02dbc8a666e..c90992f613fe 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -34,7 +34,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
34 | struct sk_buff *frag_skb) | 34 | struct sk_buff *frag_skb) |
35 | { | 35 | { |
36 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); | 36 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); |
37 | struct skb_frame_desc *skbdesc; | ||
38 | struct ieee80211_tx_info *rts_info; | 37 | struct ieee80211_tx_info *rts_info; |
39 | struct sk_buff *skb; | 38 | struct sk_buff *skb; |
40 | int size; | 39 | int size; |
@@ -65,6 +64,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
65 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); | 64 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); |
66 | rts_info = IEEE80211_SKB_CB(skb); | 65 | rts_info = IEEE80211_SKB_CB(skb); |
67 | rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | 66 | rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
67 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; | ||
68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; | 68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; |
69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; | 69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; |
70 | 70 | ||
@@ -82,14 +82,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
82 | frag_skb->data, size, tx_info, | 82 | frag_skb->data, size, tx_info, |
83 | (struct ieee80211_rts *)(skb->data)); | 83 | (struct ieee80211_rts *)(skb->data)); |
84 | 84 | ||
85 | /* | 85 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
86 | * Initialize skb descriptor | ||
87 | */ | ||
88 | skbdesc = get_skb_frame_desc(skb); | ||
89 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
90 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
91 | |||
92 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { | ||
93 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); | 86 | WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); |
94 | return NETDEV_TX_BUSY; | 87 | return NETDEV_TX_BUSY; |
95 | } | 88 | } |
@@ -135,18 +128,16 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
135 | } | 128 | } |
136 | 129 | ||
137 | /* | 130 | /* |
138 | * If CTS/RTS is required. and this frame is not CTS or RTS, | 131 | * If CTS/RTS is required. create and queue that frame first. |
139 | * create and queue that frame first. But make sure we have | 132 | * Make sure we have at least enough entries available to send |
140 | * at least enough entries available to send this CTS/RTS | 133 | * this CTS/RTS frame as well as the data frame. |
141 | * frame as well as the data frame. | ||
142 | * Note that when the driver has set the set_rts_threshold() | 134 | * Note that when the driver has set the set_rts_threshold() |
143 | * callback function it doesn't need software generation of | 135 | * callback function it doesn't need software generation of |
144 | * neither RTS or CTS-to-self frames and handles everything | 136 | * either RTS or CTS-to-self frame and handles everything |
145 | * inside the hardware. | 137 | * inside the hardware. |
146 | */ | 138 | */ |
147 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); | 139 | frame_control = le16_to_cpu(ieee80211hdr->frame_control); |
148 | if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && | 140 | if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS | |
149 | (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS | | ||
150 | IEEE80211_TX_CTL_USE_CTS_PROTECT)) && | 141 | IEEE80211_TX_CTL_USE_CTS_PROTECT)) && |
151 | !rt2x00dev->ops->hw->set_rts_threshold) { | 142 | !rt2x00dev->ops->hw->set_rts_threshold) { |
152 | if (rt2x00queue_available(queue) <= 1) { | 143 | if (rt2x00queue_available(queue) <= 1) { |
@@ -160,17 +151,14 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
160 | } | 151 | } |
161 | } | 152 | } |
162 | 153 | ||
163 | if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { | 154 | if (rt2x00queue_write_tx_frame(queue, skb)) { |
164 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 155 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
165 | return NETDEV_TX_BUSY; | 156 | return NETDEV_TX_BUSY; |
166 | } | 157 | } |
167 | 158 | ||
168 | if (rt2x00queue_full(queue)) | 159 | if (rt2x00queue_threshold(queue)) |
169 | ieee80211_stop_queue(rt2x00dev->hw, qid); | 160 | ieee80211_stop_queue(rt2x00dev->hw, qid); |
170 | 161 | ||
171 | if (rt2x00dev->ops->lib->kick_tx_queue) | ||
172 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); | ||
173 | |||
174 | return NETDEV_TX_OK; | 162 | return NETDEV_TX_OK; |
175 | } | 163 | } |
176 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); | 164 | EXPORT_SYMBOL_GPL(rt2x00mac_tx); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 70a3d135f64e..82e80b69d0be 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -34,52 +34,38 @@ | |||
34 | /* | 34 | /* |
35 | * TX data handlers. | 35 | * TX data handlers. |
36 | */ | 36 | */ |
37 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 37 | int rt2x00pci_write_tx_data(struct queue_entry *entry) |
38 | struct data_queue *queue, struct sk_buff *skb) | ||
39 | { | 38 | { |
40 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
41 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 39 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
42 | struct skb_frame_desc *skbdesc; | 40 | struct skb_frame_desc *skbdesc; |
43 | struct txentry_desc txdesc; | ||
44 | u32 word; | 41 | u32 word; |
45 | 42 | ||
46 | if (rt2x00queue_full(queue)) | ||
47 | return -EINVAL; | ||
48 | |||
49 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 43 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
50 | 44 | ||
51 | if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | 45 | /* |
52 | rt2x00_get_field32(word, TXD_ENTRY_VALID)) { | 46 | * This should not happen, we already checked the entry |
53 | ERROR(rt2x00dev, | 47 | * was ours. When the hardware disagrees there has been |
54 | "Arrived at non-free entry in the non-full queue %d.\n" | 48 | * a queue corruption! |
49 | */ | ||
50 | if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || | ||
51 | rt2x00_get_field32(word, TXD_ENTRY_VALID))) { | ||
52 | ERROR(entry->queue->rt2x00dev, | ||
53 | "Corrupt queue %d, accessing entry which is not ours.\n" | ||
55 | "Please file bug report to %s.\n", | 54 | "Please file bug report to %s.\n", |
56 | entry->queue->qid, DRV_PROJECT); | 55 | entry->queue->qid, DRV_PROJECT); |
57 | return -EINVAL; | 56 | return -EINVAL; |
58 | } | 57 | } |
59 | 58 | ||
60 | /* | 59 | /* |
61 | * Copy all TX descriptor information into txdesc, | ||
62 | * after that we are free to use the skb->cb array | ||
63 | * for our information. | ||
64 | */ | ||
65 | entry->skb = skb; | ||
66 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
67 | |||
68 | /* | ||
69 | * Fill in skb descriptor | 60 | * Fill in skb descriptor |
70 | */ | 61 | */ |
71 | skbdesc = get_skb_frame_desc(skb); | 62 | skbdesc = get_skb_frame_desc(entry->skb); |
72 | memset(skbdesc, 0, sizeof(*skbdesc)); | 63 | memset(skbdesc, 0, sizeof(*skbdesc)); |
73 | skbdesc->data = skb->data; | ||
74 | skbdesc->data_len = skb->len; | ||
75 | skbdesc->desc = entry_priv->desc; | 64 | skbdesc->desc = entry_priv->desc; |
76 | skbdesc->desc_len = queue->desc_size; | 65 | skbdesc->desc_len = entry->queue->desc_size; |
77 | skbdesc->entry = entry; | 66 | skbdesc->entry = entry; |
78 | 67 | ||
79 | memcpy(entry_priv->data, skb->data, skb->len); | 68 | memcpy(entry_priv->data, entry->skb->data, entry->skb->len); |
80 | |||
81 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
82 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
83 | 69 | ||
84 | return 0; | 70 | return 0; |
85 | } | 71 | } |
@@ -93,11 +79,8 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
93 | struct data_queue *queue = rt2x00dev->rx; | 79 | struct data_queue *queue = rt2x00dev->rx; |
94 | struct queue_entry *entry; | 80 | struct queue_entry *entry; |
95 | struct queue_entry_priv_pci *entry_priv; | 81 | struct queue_entry_priv_pci *entry_priv; |
96 | struct ieee80211_hdr *hdr; | ||
97 | struct skb_frame_desc *skbdesc; | 82 | struct skb_frame_desc *skbdesc; |
98 | struct rxdone_entry_desc rxdesc; | 83 | struct rxdone_entry_desc rxdesc; |
99 | int header_size; | ||
100 | int align; | ||
101 | u32 word; | 84 | u32 word; |
102 | 85 | ||
103 | while (1) { | 86 | while (1) { |
@@ -111,35 +94,21 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
111 | memset(&rxdesc, 0, sizeof(rxdesc)); | 94 | memset(&rxdesc, 0, sizeof(rxdesc)); |
112 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | 95 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
113 | 96 | ||
114 | hdr = (struct ieee80211_hdr *)entry_priv->data; | ||
115 | header_size = | ||
116 | ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
117 | |||
118 | /* | ||
119 | * The data behind the ieee80211 header must be | ||
120 | * aligned on a 4 byte boundary. | ||
121 | */ | ||
122 | align = header_size % 4; | ||
123 | |||
124 | /* | 97 | /* |
125 | * Allocate the sk_buffer, initialize it and copy | 98 | * Allocate the sk_buffer and copy all data into it. |
126 | * all data into it. | ||
127 | */ | 99 | */ |
128 | entry->skb = dev_alloc_skb(rxdesc.size + align); | 100 | entry->skb = rt2x00queue_alloc_rxskb(queue); |
129 | if (!entry->skb) | 101 | if (!entry->skb) |
130 | return; | 102 | return; |
131 | 103 | ||
132 | skb_reserve(entry->skb, align); | 104 | memcpy(entry->skb->data, entry_priv->data, rxdesc.size); |
133 | memcpy(skb_put(entry->skb, rxdesc.size), | 105 | skb_trim(entry->skb, rxdesc.size); |
134 | entry_priv->data, rxdesc.size); | ||
135 | 106 | ||
136 | /* | 107 | /* |
137 | * Fill in skb descriptor | 108 | * Fill in skb descriptor |
138 | */ | 109 | */ |
139 | skbdesc = get_skb_frame_desc(entry->skb); | 110 | skbdesc = get_skb_frame_desc(entry->skb); |
140 | memset(skbdesc, 0, sizeof(*skbdesc)); | 111 | memset(skbdesc, 0, sizeof(*skbdesc)); |
141 | skbdesc->data = entry->skb->data; | ||
142 | skbdesc->data_len = entry->skb->len; | ||
143 | skbdesc->desc = entry_priv->desc; | 112 | skbdesc->desc = entry_priv->desc; |
144 | skbdesc->desc_len = queue->desc_size; | 113 | skbdesc->desc_len = queue->desc_size; |
145 | skbdesc->entry = entry; | 114 | skbdesc->entry = entry; |
@@ -178,14 +147,15 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | |||
178 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | 147 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); |
179 | rt2x00_desc_write(entry_priv->desc, 0, word); | 148 | rt2x00_desc_write(entry_priv->desc, 0, word); |
180 | 149 | ||
150 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
181 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 151 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
182 | 152 | ||
183 | /* | 153 | /* |
184 | * If the data queue was full before the txdone handler | 154 | * If the data queue was below the threshold before the txdone |
185 | * we must make sure the packet queue in the mac80211 stack | 155 | * handler we must make sure the packet queue in the mac80211 stack |
186 | * is reenabled when the txdone handler has finished. | 156 | * is reenabled when the txdone handler has finished. |
187 | */ | 157 | */ |
188 | if (!rt2x00queue_full(entry->queue)) | 158 | if (!rt2x00queue_threshold(entry->queue)) |
189 | ieee80211_wake_queue(rt2x00dev->hw, qid); | 159 | ieee80211_wake_queue(rt2x00dev->hw, qid); |
190 | 160 | ||
191 | } | 161 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 37c851e442c1..87c4a0cd78db 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -87,11 +87,14 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); | 87 | memcpy_toio(rt2x00dev->csr.base + offset, value, length); |
88 | } | 88 | } |
89 | 89 | ||
90 | /* | 90 | /** |
91 | * TX data handlers. | 91 | * rt2x00pci_write_tx_data - Initialize data for TX operation |
92 | * @entry: The entry where the frame is located | ||
93 | * | ||
94 | * This function will initialize the DMA and skb descriptor | ||
95 | * to prepare the entry for the actual TX operation. | ||
92 | */ | 96 | */ |
93 | int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, | 97 | int rt2x00pci_write_tx_data(struct queue_entry *entry); |
94 | struct data_queue *queue, struct sk_buff *skb); | ||
95 | 98 | ||
96 | /** | 99 | /** |
97 | * struct queue_entry_priv_pci: Per entry PCI specific information | 100 | * struct queue_entry_priv_pci: Per entry PCI specific information |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index e69ef4b19239..7b52039b01a6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -29,6 +29,45 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | ||
33 | { | ||
34 | struct sk_buff *skb; | ||
35 | unsigned int frame_size; | ||
36 | unsigned int reserved_size; | ||
37 | |||
38 | /* | ||
39 | * The frame size includes descriptor size, because the | ||
40 | * hardware directly receive the frame into the skbuffer. | ||
41 | */ | ||
42 | frame_size = queue->data_size + queue->desc_size; | ||
43 | |||
44 | /* | ||
45 | * For the allocation we should keep a few things in mind: | ||
46 | * 1) 4byte alignment of 802.11 payload | ||
47 | * | ||
48 | * For (1) we need at most 4 bytes to guarentee the correct | ||
49 | * alignment. We are going to optimize the fact that the chance | ||
50 | * that the 802.11 header_size % 4 == 2 is much bigger then | ||
51 | * anything else. However since we need to move the frame up | ||
52 | * to 3 bytes to the front, which means we need to preallocate | ||
53 | * 6 bytes. | ||
54 | */ | ||
55 | reserved_size = 6; | ||
56 | |||
57 | /* | ||
58 | * Allocate skbuffer. | ||
59 | */ | ||
60 | skb = dev_alloc_skb(frame_size + reserved_size); | ||
61 | if (!skb) | ||
62 | return NULL; | ||
63 | |||
64 | skb_reserve(skb, reserved_size); | ||
65 | skb_put(skb, frame_size); | ||
66 | |||
67 | return skb; | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); | ||
70 | |||
32 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 71 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
33 | struct txentry_desc *txdesc) | 72 | struct txentry_desc *txdesc) |
34 | { | 73 | { |
@@ -91,7 +130,7 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
91 | /* | 130 | /* |
92 | * Check if more fragments are pending | 131 | * Check if more fragments are pending |
93 | */ | 132 | */ |
94 | if (ieee80211_get_morefrag(hdr)) { | 133 | if (ieee80211_has_morefrags(hdr->frame_control)) { |
95 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); | 134 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); |
96 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); | 135 | __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); |
97 | } | 136 | } |
@@ -163,8 +202,8 @@ EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor); | |||
163 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 202 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |
164 | struct txentry_desc *txdesc) | 203 | struct txentry_desc *txdesc) |
165 | { | 204 | { |
166 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 205 | struct data_queue *queue = entry->queue; |
167 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 206 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
168 | 207 | ||
169 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 208 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); |
170 | 209 | ||
@@ -175,19 +214,61 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
175 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | 214 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); |
176 | 215 | ||
177 | /* | 216 | /* |
178 | * We are done writing the frame to the queue entry, | 217 | * Check if we need to kick the queue, there are however a few rules |
179 | * also kick the queue in case the correct flags are set, | 218 | * 1) Don't kick beacon queue |
180 | * note that this will automatically filter beacons and | 219 | * 2) Don't kick unless this is the last in frame in a burst. |
181 | * RTS/CTS frames since those frames don't have this flag | 220 | * When the burst flag is set, this frame is always followed |
182 | * set. | 221 | * by another frame which in some way are related to eachother. |
222 | * This is true for fragments, RTS or CTS-to-self frames. | ||
223 | * 3) Rule 2 can be broken when the available entries | ||
224 | * in the queue are less then a certain threshold. | ||
183 | */ | 225 | */ |
184 | if (rt2x00dev->ops->lib->kick_tx_queue && | 226 | if (entry->queue->qid == QID_BEACON) |
185 | !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | 227 | return; |
186 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, | 228 | |
187 | entry->queue->qid); | 229 | if (rt2x00queue_threshold(queue) || |
230 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | ||
231 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | ||
188 | } | 232 | } |
189 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); | 233 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); |
190 | 234 | ||
235 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | ||
236 | { | ||
237 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
238 | struct txentry_desc txdesc; | ||
239 | |||
240 | if (unlikely(rt2x00queue_full(queue))) | ||
241 | return -EINVAL; | ||
242 | |||
243 | if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { | ||
244 | ERROR(queue->rt2x00dev, | ||
245 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
246 | "Please file bug report to %s.\n", | ||
247 | queue->qid, DRV_PROJECT); | ||
248 | return -EINVAL; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Copy all TX descriptor information into txdesc, | ||
253 | * after that we are free to use the skb->cb array | ||
254 | * for our information. | ||
255 | */ | ||
256 | entry->skb = skb; | ||
257 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
258 | |||
259 | if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { | ||
260 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
261 | return -EIO; | ||
262 | } | ||
263 | |||
264 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); | ||
265 | |||
266 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
267 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
191 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 272 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
192 | const enum data_queue_qid queue) | 273 | const enum data_queue_qid queue) |
193 | { | 274 | { |
@@ -312,6 +393,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
312 | rt2x00queue_reset(queue); | 393 | rt2x00queue_reset(queue); |
313 | 394 | ||
314 | queue->limit = qdesc->entry_num; | 395 | queue->limit = qdesc->entry_num; |
396 | queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); | ||
315 | queue->data_size = qdesc->data_size; | 397 | queue->data_size = qdesc->data_size; |
316 | queue->desc_size = qdesc->desc_size; | 398 | queue->desc_size = qdesc->desc_size; |
317 | 399 | ||
@@ -439,7 +521,8 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
439 | * TX: qid = QID_AC_BE + index | 521 | * TX: qid = QID_AC_BE + index |
440 | * TX: cw_min: 2^5 = 32. | 522 | * TX: cw_min: 2^5 = 32. |
441 | * TX: cw_max: 2^10 = 1024. | 523 | * TX: cw_max: 2^10 = 1024. |
442 | * BCN & Atim: qid = QID_MGMT | 524 | * BCN: qid = QID_BEACON |
525 | * ATIM: qid = QID_ATIM | ||
443 | */ | 526 | */ |
444 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); | 527 | rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); |
445 | 528 | ||
@@ -447,9 +530,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) | |||
447 | tx_queue_for_each(rt2x00dev, queue) | 530 | tx_queue_for_each(rt2x00dev, queue) |
448 | rt2x00queue_init(rt2x00dev, queue, qid++); | 531 | rt2x00queue_init(rt2x00dev, queue, qid++); |
449 | 532 | ||
450 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); | 533 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON); |
451 | if (req_atim) | 534 | if (req_atim) |
452 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); | 535 | rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM); |
453 | 536 | ||
454 | return 0; | 537 | return 0; |
455 | } | 538 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 4d00ced14cc7..fcf52520b016 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -82,12 +82,10 @@ enum data_queue_qid { | |||
82 | /** | 82 | /** |
83 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | 83 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc |
84 | * | 84 | * |
85 | * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver | ||
86 | * and should not be reported back to mac80211 during txdone. | ||
87 | */ | 85 | */ |
88 | enum skb_frame_desc_flags { | 86 | //enum skb_frame_desc_flags { |
89 | FRAME_DESC_DRIVER_GENERATED = 1 << 0, | 87 | // TEMPORARILY EMPTY |
90 | }; | 88 | //}; |
91 | 89 | ||
92 | /** | 90 | /** |
93 | * struct skb_frame_desc: Descriptor information for the skb buffer | 91 | * struct skb_frame_desc: Descriptor information for the skb buffer |
@@ -107,11 +105,8 @@ enum skb_frame_desc_flags { | |||
107 | struct skb_frame_desc { | 105 | struct skb_frame_desc { |
108 | unsigned int flags; | 106 | unsigned int flags; |
109 | 107 | ||
110 | unsigned short data_len; | ||
111 | unsigned short desc_len; | ||
112 | |||
113 | void *data; | ||
114 | void *desc; | 108 | void *desc; |
109 | unsigned int desc_len; | ||
115 | 110 | ||
116 | struct queue_entry *entry; | 111 | struct queue_entry *entry; |
117 | }; | 112 | }; |
@@ -260,11 +255,14 @@ struct txentry_desc { | |||
260 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data | 255 | * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data |
261 | * encryption or decryption. The entry should only be touched after | 256 | * encryption or decryption. The entry should only be touched after |
262 | * the device has signaled it is done with it. | 257 | * the device has signaled it is done with it. |
258 | * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting | ||
259 | * for the signal to start sending. | ||
263 | */ | 260 | */ |
264 | enum queue_entry_flags { | 261 | enum queue_entry_flags { |
265 | ENTRY_BCN_ASSIGNED, | 262 | ENTRY_BCN_ASSIGNED, |
266 | ENTRY_OWNER_DEVICE_DATA, | 263 | ENTRY_OWNER_DEVICE_DATA, |
267 | ENTRY_OWNER_DEVICE_CRYPTO, | 264 | ENTRY_OWNER_DEVICE_CRYPTO, |
265 | ENTRY_DATA_PENDING, | ||
268 | }; | 266 | }; |
269 | 267 | ||
270 | /** | 268 | /** |
@@ -322,6 +320,7 @@ enum queue_index { | |||
322 | * index corruption due to concurrency. | 320 | * index corruption due to concurrency. |
323 | * @count: Number of frames handled in the queue. | 321 | * @count: Number of frames handled in the queue. |
324 | * @limit: Maximum number of entries in the queue. | 322 | * @limit: Maximum number of entries in the queue. |
323 | * @threshold: Minimum number of free entries before queue is kicked by force. | ||
325 | * @length: Number of frames in queue. | 324 | * @length: Number of frames in queue. |
326 | * @index: Index pointers to entry positions in the queue, | 325 | * @index: Index pointers to entry positions in the queue, |
327 | * use &enum queue_index to get a specific index field. | 326 | * use &enum queue_index to get a specific index field. |
@@ -340,6 +339,7 @@ struct data_queue { | |||
340 | spinlock_t lock; | 339 | spinlock_t lock; |
341 | unsigned int count; | 340 | unsigned int count; |
342 | unsigned short limit; | 341 | unsigned short limit; |
342 | unsigned short threshold; | ||
343 | unsigned short length; | 343 | unsigned short length; |
344 | unsigned short index[Q_INDEX_MAX]; | 344 | unsigned short index[Q_INDEX_MAX]; |
345 | 345 | ||
@@ -464,6 +464,15 @@ static inline int rt2x00queue_available(struct data_queue *queue) | |||
464 | } | 464 | } |
465 | 465 | ||
466 | /** | 466 | /** |
467 | * rt2x00queue_threshold - Check if the queue is below threshold | ||
468 | * @queue: Queue to check. | ||
469 | */ | ||
470 | static inline int rt2x00queue_threshold(struct data_queue *queue) | ||
471 | { | ||
472 | return rt2x00queue_available(queue) < queue->threshold; | ||
473 | } | ||
474 | |||
475 | /** | ||
467 | * rt2x00_desc_read - Read a word from the hardware descriptor. | 476 | * rt2x00_desc_read - Read a word from the hardware descriptor. |
468 | * @desc: Base descriptor address | 477 | * @desc: Base descriptor address |
469 | * @word: Word index from where the descriptor should be read. | 478 | * @word: Word index from where the descriptor should be read. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h index 3f255df58b78..7e88ce5651b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/drivers/net/wireless/rt2x00/rt2x00reg.h | |||
@@ -130,83 +130,107 @@ struct rt2x00_field32 { | |||
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Power of two check, this will check | 132 | * Power of two check, this will check |
133 | * if the mask that has been given contains | 133 | * if the mask that has been given contains and contiguous set of bits. |
134 | * and contiguous set of bits. | 134 | * Note that we cannot use the is_power_of_2() function since this |
135 | * check must be done at compile-time. | ||
135 | */ | 136 | */ |
136 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) | 137 | #define is_power_of_two(x) ( !((x) & ((x)-1)) ) |
137 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) | 138 | #define low_bit_mask(x) ( ((x)-1) & ~(x) ) |
138 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) | 139 | #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) |
139 | 140 | ||
141 | /* | ||
142 | * Macro's to find first set bit in a variable. | ||
143 | * These macro's behaves the same as the __ffs() function with | ||
144 | * the most important difference that this is done during | ||
145 | * compile-time rather then run-time. | ||
146 | */ | ||
147 | #define compile_ffs2(__x) \ | ||
148 | __builtin_choose_expr(((__x) & 0x1), 0, 1) | ||
149 | |||
150 | #define compile_ffs4(__x) \ | ||
151 | __builtin_choose_expr(((__x) & 0x3), \ | ||
152 | (compile_ffs2((__x))), \ | ||
153 | (compile_ffs2((__x) >> 2) + 2)) | ||
154 | |||
155 | #define compile_ffs8(__x) \ | ||
156 | __builtin_choose_expr(((__x) & 0xf), \ | ||
157 | (compile_ffs4((__x))), \ | ||
158 | (compile_ffs4((__x) >> 4) + 4)) | ||
159 | |||
160 | #define compile_ffs16(__x) \ | ||
161 | __builtin_choose_expr(((__x) & 0xff), \ | ||
162 | (compile_ffs8((__x))), \ | ||
163 | (compile_ffs8((__x) >> 8) + 8)) | ||
164 | |||
165 | #define compile_ffs32(__x) \ | ||
166 | __builtin_choose_expr(((__x) & 0xffff), \ | ||
167 | (compile_ffs16((__x))), \ | ||
168 | (compile_ffs16((__x) >> 16) + 16)) | ||
169 | |||
170 | /* | ||
171 | * This macro will check the requirements for the FIELD{8,16,32} macros | ||
172 | * The mask should be a constant non-zero contiguous set of bits which | ||
173 | * does not exceed the given typelimit. | ||
174 | */ | ||
175 | #define FIELD_CHECK(__mask, __type) \ | ||
176 | BUILD_BUG_ON(!__builtin_constant_p(__mask) || \ | ||
177 | !(__mask) || \ | ||
178 | !is_valid_mask(__mask) || \ | ||
179 | (__mask) != (__type)(__mask)) \ | ||
180 | |||
140 | #define FIELD8(__mask) \ | 181 | #define FIELD8(__mask) \ |
141 | ({ \ | 182 | ({ \ |
142 | BUILD_BUG_ON(!(__mask) || \ | 183 | FIELD_CHECK(__mask, u8); \ |
143 | !is_valid_mask(__mask) || \ | ||
144 | (__mask) != (u8)(__mask)); \ | ||
145 | (struct rt2x00_field8) { \ | 184 | (struct rt2x00_field8) { \ |
146 | __ffs(__mask), (__mask) \ | 185 | compile_ffs8(__mask), (__mask) \ |
147 | }; \ | 186 | }; \ |
148 | }) | 187 | }) |
149 | 188 | ||
150 | #define FIELD16(__mask) \ | 189 | #define FIELD16(__mask) \ |
151 | ({ \ | 190 | ({ \ |
152 | BUILD_BUG_ON(!(__mask) || \ | 191 | FIELD_CHECK(__mask, u16); \ |
153 | !is_valid_mask(__mask) || \ | ||
154 | (__mask) != (u16)(__mask));\ | ||
155 | (struct rt2x00_field16) { \ | 192 | (struct rt2x00_field16) { \ |
156 | __ffs(__mask), (__mask) \ | 193 | compile_ffs16(__mask), (__mask) \ |
157 | }; \ | 194 | }; \ |
158 | }) | 195 | }) |
159 | 196 | ||
160 | #define FIELD32(__mask) \ | 197 | #define FIELD32(__mask) \ |
161 | ({ \ | 198 | ({ \ |
162 | BUILD_BUG_ON(!(__mask) || \ | 199 | FIELD_CHECK(__mask, u32); \ |
163 | !is_valid_mask(__mask) || \ | ||
164 | (__mask) != (u32)(__mask));\ | ||
165 | (struct rt2x00_field32) { \ | 200 | (struct rt2x00_field32) { \ |
166 | __ffs(__mask), (__mask) \ | 201 | compile_ffs32(__mask), (__mask) \ |
167 | }; \ | 202 | }; \ |
168 | }) | 203 | }) |
169 | 204 | ||
170 | static inline void rt2x00_set_field32(u32 *reg, | 205 | #define SET_FIELD(__reg, __type, __field, __value)\ |
171 | const struct rt2x00_field32 field, | 206 | ({ \ |
172 | const u32 value) | 207 | typecheck(__type, __field); \ |
173 | { | 208 | *(__reg) &= ~((__field).bit_mask); \ |
174 | *reg &= ~(field.bit_mask); | 209 | *(__reg) |= ((__value) << \ |
175 | *reg |= (value << field.bit_offset) & field.bit_mask; | 210 | ((__field).bit_offset)) & \ |
176 | } | 211 | ((__field).bit_mask); \ |
177 | 212 | }) | |
178 | static inline u32 rt2x00_get_field32(const u32 reg, | 213 | |
179 | const struct rt2x00_field32 field) | 214 | #define GET_FIELD(__reg, __type, __field) \ |
180 | { | 215 | ({ \ |
181 | return (reg & field.bit_mask) >> field.bit_offset; | 216 | typecheck(__type, __field); \ |
182 | } | 217 | ((__reg) & ((__field).bit_mask)) >> \ |
183 | 218 | ((__field).bit_offset); \ | |
184 | static inline void rt2x00_set_field16(u16 *reg, | 219 | }) |
185 | const struct rt2x00_field16 field, | 220 | |
186 | const u16 value) | 221 | #define rt2x00_set_field32(__reg, __field, __value) \ |
187 | { | 222 | SET_FIELD(__reg, struct rt2x00_field32, __field, __value) |
188 | *reg &= ~(field.bit_mask); | 223 | #define rt2x00_get_field32(__reg, __field) \ |
189 | *reg |= (value << field.bit_offset) & field.bit_mask; | 224 | GET_FIELD(__reg, struct rt2x00_field32, __field) |
190 | } | 225 | |
191 | 226 | #define rt2x00_set_field16(__reg, __field, __value) \ | |
192 | static inline u16 rt2x00_get_field16(const u16 reg, | 227 | SET_FIELD(__reg, struct rt2x00_field16, __field, __value) |
193 | const struct rt2x00_field16 field) | 228 | #define rt2x00_get_field16(__reg, __field) \ |
194 | { | 229 | GET_FIELD(__reg, struct rt2x00_field16, __field) |
195 | return (reg & field.bit_mask) >> field.bit_offset; | 230 | |
196 | } | 231 | #define rt2x00_set_field8(__reg, __field, __value) \ |
197 | 232 | SET_FIELD(__reg, struct rt2x00_field8, __field, __value) | |
198 | static inline void rt2x00_set_field8(u8 *reg, | 233 | #define rt2x00_get_field8(__reg, __field) \ |
199 | const struct rt2x00_field8 field, | 234 | GET_FIELD(__reg, struct rt2x00_field8, __field) |
200 | const u8 value) | ||
201 | { | ||
202 | *reg &= ~(field.bit_mask); | ||
203 | *reg |= (value << field.bit_offset) & field.bit_mask; | ||
204 | } | ||
205 | |||
206 | static inline u8 rt2x00_get_field8(const u8 reg, | ||
207 | const struct rt2x00_field8 field) | ||
208 | { | ||
209 | return (reg & field.bit_mask) >> field.bit_offset; | ||
210 | } | ||
211 | 235 | ||
212 | #endif /* RT2X00REG_H */ | 236 | #endif /* RT2X00REG_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 52d12fdc0ccf..68d87f09e054 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -130,16 +130,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
130 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 130 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
132 | struct txdone_entry_desc txdesc; | 132 | struct txdone_entry_desc txdesc; |
133 | __le32 *txd = (__le32 *)entry->skb->data; | ||
134 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | 133 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); |
135 | u32 word; | ||
136 | 134 | ||
137 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 135 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
138 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 136 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
139 | return; | 137 | return; |
140 | 138 | ||
141 | rt2x00_desc_read(txd, 0, &word); | ||
142 | |||
143 | /* | 139 | /* |
144 | * Remove the descriptor data from the buffer. | 140 | * Remove the descriptor data from the buffer. |
145 | */ | 141 | */ |
@@ -169,124 +165,101 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
169 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | 165 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); |
170 | 166 | ||
171 | /* | 167 | /* |
172 | * If the data queue was full before the txdone handler | 168 | * If the data queue was below the threshold before the txdone |
173 | * we must make sure the packet queue in the mac80211 stack | 169 | * handler we must make sure the packet queue in the mac80211 stack |
174 | * is reenabled when the txdone handler has finished. | 170 | * is reenabled when the txdone handler has finished. |
175 | */ | 171 | */ |
176 | if (!rt2x00queue_full(entry->queue)) | 172 | if (!rt2x00queue_threshold(entry->queue)) |
177 | ieee80211_wake_queue(rt2x00dev->hw, qid); | 173 | ieee80211_wake_queue(rt2x00dev->hw, qid); |
178 | } | 174 | } |
179 | 175 | ||
180 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 176 | int rt2x00usb_write_tx_data(struct queue_entry *entry) |
181 | struct data_queue *queue, struct sk_buff *skb) | ||
182 | { | 177 | { |
178 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
183 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 179 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
184 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
185 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 180 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
186 | struct skb_frame_desc *skbdesc; | 181 | struct skb_frame_desc *skbdesc; |
187 | struct txentry_desc txdesc; | ||
188 | u32 length; | 182 | u32 length; |
189 | 183 | ||
190 | if (rt2x00queue_full(queue)) | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { | ||
194 | ERROR(rt2x00dev, | ||
195 | "Arrived at non-free entry in the non-full queue %d.\n" | ||
196 | "Please file bug report to %s.\n", | ||
197 | entry->queue->qid, DRV_PROJECT); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Copy all TX descriptor information into txdesc, | ||
203 | * after that we are free to use the skb->cb array | ||
204 | * for our information. | ||
205 | */ | ||
206 | entry->skb = skb; | ||
207 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | ||
208 | |||
209 | /* | 184 | /* |
210 | * Add the descriptor in front of the skb. | 185 | * Add the descriptor in front of the skb. |
211 | */ | 186 | */ |
212 | skb_push(skb, queue->desc_size); | 187 | skb_push(entry->skb, entry->queue->desc_size); |
213 | memset(skb->data, 0, queue->desc_size); | 188 | memset(entry->skb->data, 0, entry->queue->desc_size); |
214 | 189 | ||
215 | /* | 190 | /* |
216 | * Fill in skb descriptor | 191 | * Fill in skb descriptor |
217 | */ | 192 | */ |
218 | skbdesc = get_skb_frame_desc(skb); | 193 | skbdesc = get_skb_frame_desc(entry->skb); |
219 | memset(skbdesc, 0, sizeof(*skbdesc)); | 194 | memset(skbdesc, 0, sizeof(*skbdesc)); |
220 | skbdesc->data = skb->data + queue->desc_size; | 195 | skbdesc->desc = entry->skb->data; |
221 | skbdesc->data_len = skb->len - queue->desc_size; | 196 | skbdesc->desc_len = entry->queue->desc_size; |
222 | skbdesc->desc = skb->data; | ||
223 | skbdesc->desc_len = queue->desc_size; | ||
224 | skbdesc->entry = entry; | 197 | skbdesc->entry = entry; |
225 | 198 | ||
226 | rt2x00queue_write_tx_descriptor(entry, &txdesc); | ||
227 | |||
228 | /* | 199 | /* |
229 | * USB devices cannot blindly pass the skb->len as the | 200 | * USB devices cannot blindly pass the skb->len as the |
230 | * length of the data to usb_fill_bulk_urb. Pass the skb | 201 | * length of the data to usb_fill_bulk_urb. Pass the skb |
231 | * to the driver to determine what the length should be. | 202 | * to the driver to determine what the length should be. |
232 | */ | 203 | */ |
233 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb); | 204 | length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); |
234 | 205 | ||
235 | /* | 206 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, |
236 | * Initialize URB and send the frame to the device. | 207 | usb_sndbulkpipe(usb_dev, 1), |
237 | */ | 208 | entry->skb->data, length, |
238 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 209 | rt2x00usb_interrupt_txdone, entry); |
239 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), | ||
240 | skb->data, length, rt2x00usb_interrupt_txdone, entry); | ||
241 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); | ||
242 | |||
243 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
244 | 210 | ||
245 | return 0; | 211 | return 0; |
246 | } | 212 | } |
247 | EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); | 213 | EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); |
248 | 214 | ||
249 | /* | 215 | static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) |
250 | * RX data handlers. | ||
251 | */ | ||
252 | static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue) | ||
253 | { | 216 | { |
254 | struct sk_buff *skb; | 217 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
255 | unsigned int frame_size; | ||
256 | unsigned int reserved_size; | ||
257 | 218 | ||
258 | /* | 219 | if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) |
259 | * The frame size includes descriptor size, because the | 220 | usb_submit_urb(entry_priv->urb, GFP_ATOMIC); |
260 | * hardware directly receive the frame into the skbuffer. | 221 | } |
261 | */ | 222 | |
262 | frame_size = queue->data_size + queue->desc_size; | 223 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
224 | const enum data_queue_qid qid) | ||
225 | { | ||
226 | struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); | ||
227 | unsigned long irqflags; | ||
228 | unsigned int index; | ||
229 | unsigned int index_done; | ||
230 | unsigned int i; | ||
263 | 231 | ||
264 | /* | 232 | /* |
265 | * For the allocation we should keep a few things in mind: | 233 | * Only protect the range we are going to loop over, |
266 | * 1) 4byte alignment of 802.11 payload | 234 | * if during our loop a extra entry is set to pending |
267 | * | 235 | * it should not be kicked during this run, since it |
268 | * For (1) we need at most 4 bytes to guarentee the correct | 236 | * is part of another TX operation. |
269 | * alignment. We are going to optimize the fact that the chance | ||
270 | * that the 802.11 header_size % 4 == 2 is much bigger then | ||
271 | * anything else. However since we need to move the frame up | ||
272 | * to 3 bytes to the front, which means we need to preallocate | ||
273 | * 6 bytes. | ||
274 | */ | 237 | */ |
275 | reserved_size = 6; | 238 | spin_lock_irqsave(&queue->lock, irqflags); |
239 | index = queue->index[Q_INDEX]; | ||
240 | index_done = queue->index[Q_INDEX_DONE]; | ||
241 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
276 | 242 | ||
277 | /* | 243 | /* |
278 | * Allocate skbuffer. | 244 | * Start from the TX done pointer, this guarentees that we will |
245 | * send out all frames in the correct order. | ||
279 | */ | 246 | */ |
280 | skb = dev_alloc_skb(frame_size + reserved_size); | 247 | if (index_done < index) { |
281 | if (!skb) | 248 | for (i = index_done; i < index; i++) |
282 | return NULL; | 249 | rt2x00usb_kick_tx_entry(&queue->entries[i]); |
283 | 250 | } else { | |
284 | skb_reserve(skb, reserved_size); | 251 | for (i = index_done; i < queue->limit; i++) |
285 | skb_put(skb, frame_size); | 252 | rt2x00usb_kick_tx_entry(&queue->entries[i]); |
286 | 253 | ||
287 | return skb; | 254 | for (i = 0; i < index; i++) |
255 | rt2x00usb_kick_tx_entry(&queue->entries[i]); | ||
256 | } | ||
288 | } | 257 | } |
258 | EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); | ||
289 | 259 | ||
260 | /* | ||
261 | * RX data handlers. | ||
262 | */ | ||
290 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) | 263 | static void rt2x00usb_interrupt_rxdone(struct urb *urb) |
291 | { | 264 | { |
292 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 265 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
@@ -294,8 +267,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
294 | struct sk_buff *skb; | 267 | struct sk_buff *skb; |
295 | struct skb_frame_desc *skbdesc; | 268 | struct skb_frame_desc *skbdesc; |
296 | struct rxdone_entry_desc rxdesc; | 269 | struct rxdone_entry_desc rxdesc; |
297 | unsigned int header_size; | 270 | u8 rxd[32]; |
298 | unsigned int align; | ||
299 | 271 | ||
300 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 272 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
301 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 273 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
@@ -315,39 +287,18 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
315 | skbdesc = get_skb_frame_desc(entry->skb); | 287 | skbdesc = get_skb_frame_desc(entry->skb); |
316 | memset(skbdesc, 0, sizeof(*skbdesc)); | 288 | memset(skbdesc, 0, sizeof(*skbdesc)); |
317 | skbdesc->entry = entry; | 289 | skbdesc->entry = entry; |
290 | skbdesc->desc = rxd; | ||
291 | skbdesc->desc_len = entry->queue->desc_size; | ||
318 | 292 | ||
319 | memset(&rxdesc, 0, sizeof(rxdesc)); | 293 | memset(&rxdesc, 0, sizeof(rxdesc)); |
320 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | 294 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); |
321 | 295 | ||
322 | header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
323 | |||
324 | /* | ||
325 | * The data behind the ieee80211 header must be | ||
326 | * aligned on a 4 byte boundary. We already reserved | ||
327 | * 2 bytes for header_size % 4 == 2 optimization. | ||
328 | * To determine the number of bytes which the data | ||
329 | * should be moved to the left, we must add these | ||
330 | * 2 bytes to the header_size. | ||
331 | */ | ||
332 | align = (header_size + 2) % 4; | ||
333 | |||
334 | if (align) { | ||
335 | skb_push(entry->skb, align); | ||
336 | /* Move entire frame in 1 command */ | ||
337 | memmove(entry->skb->data, entry->skb->data + align, | ||
338 | rxdesc.size); | ||
339 | } | ||
340 | |||
341 | /* Update data pointers, trim buffer to correct size */ | ||
342 | skbdesc->data = entry->skb->data; | ||
343 | skb_trim(entry->skb, rxdesc.size); | ||
344 | |||
345 | /* | 296 | /* |
346 | * Allocate a new sk buffer to replace the current one. | 297 | * Allocate a new sk buffer to replace the current one. |
347 | * If allocation fails, we should drop the current frame | 298 | * If allocation fails, we should drop the current frame |
348 | * so we can recycle the existing sk buffer for the new frame. | 299 | * so we can recycle the existing sk buffer for the new frame. |
349 | */ | 300 | */ |
350 | skb = rt2x00usb_alloc_rxskb(entry->queue); | 301 | skb = rt2x00queue_alloc_rxskb(entry->queue); |
351 | if (!skb) | 302 | if (!skb) |
352 | goto skip_entry; | 303 | goto skip_entry; |
353 | 304 | ||
@@ -519,7 +470,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
519 | */ | 470 | */ |
520 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | 471 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; |
521 | for (i = 0; i < rt2x00dev->rx->limit; i++) { | 472 | for (i = 0; i < rt2x00dev->rx->limit; i++) { |
522 | skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); | 473 | skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx); |
523 | if (!skb) | 474 | if (!skb) |
524 | goto exit; | 475 | goto exit; |
525 | 476 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 26f53f868af6..b1187c812e7f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -212,11 +212,14 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, | |||
212 | */ | 212 | */ |
213 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); | 213 | void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); |
214 | 214 | ||
215 | /* | 215 | /** |
216 | * TX data handlers. | 216 | * rt2x00usb_write_tx_data - Initialize URB for TX operation |
217 | * @entry: The entry where the frame is located | ||
218 | * | ||
219 | * This function will initialize the URB and skb descriptor | ||
220 | * to prepare the entry for the actual TX operation. | ||
217 | */ | 221 | */ |
218 | int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, | 222 | int rt2x00usb_write_tx_data(struct queue_entry *entry); |
219 | struct data_queue *queue, struct sk_buff *skb); | ||
220 | 223 | ||
221 | /** | 224 | /** |
222 | * struct queue_entry_priv_usb: Per entry USB specific information | 225 | * struct queue_entry_priv_usb: Per entry USB specific information |
@@ -245,6 +248,17 @@ struct queue_entry_priv_usb_bcn { | |||
245 | struct urb *guardian_urb; | 248 | struct urb *guardian_urb; |
246 | }; | 249 | }; |
247 | 250 | ||
251 | /** | ||
252 | * rt2x00usb_kick_tx_queue - Kick data queue | ||
253 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
254 | * @qid: Data queue to kick | ||
255 | * | ||
256 | * This will walk through all entries of the queue and push all pending | ||
257 | * frames to the hardware as a single burst. | ||
258 | */ | ||
259 | void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | ||
260 | const enum data_queue_qid qid); | ||
261 | |||
248 | /* | 262 | /* |
249 | * Device initialization handlers. | 263 | * Device initialization handlers. |
250 | */ | 264 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e13ed5ced26e..5b7267ece1b9 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -330,6 +330,17 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev, | |||
330 | 330 | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | |||
334 | static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev, | ||
335 | struct rt2x00_led *led, | ||
336 | enum led_type type) | ||
337 | { | ||
338 | led->rt2x00dev = rt2x00dev; | ||
339 | led->type = type; | ||
340 | led->led_dev.brightness_set = rt61pci_brightness_set; | ||
341 | led->led_dev.blink_set = rt61pci_blink_set; | ||
342 | led->flags = LED_INITIALIZED; | ||
343 | } | ||
333 | #endif /* CONFIG_RT61PCI_LEDS */ | 344 | #endif /* CONFIG_RT61PCI_LEDS */ |
334 | 345 | ||
335 | /* | 346 | /* |
@@ -1270,25 +1281,32 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1270 | return 0; | 1281 | return 0; |
1271 | } | 1282 | } |
1272 | 1283 | ||
1273 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | 1284 | static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
1274 | { | 1285 | { |
1275 | unsigned int i; | 1286 | unsigned int i; |
1276 | u16 eeprom; | ||
1277 | u8 reg_id; | ||
1278 | u8 value; | 1287 | u8 value; |
1279 | 1288 | ||
1280 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1289 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1281 | rt61pci_bbp_read(rt2x00dev, 0, &value); | 1290 | rt61pci_bbp_read(rt2x00dev, 0, &value); |
1282 | if ((value != 0xff) && (value != 0x00)) | 1291 | if ((value != 0xff) && (value != 0x00)) |
1283 | goto continue_csr_init; | 1292 | return 0; |
1284 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
1285 | udelay(REGISTER_BUSY_DELAY); | 1293 | udelay(REGISTER_BUSY_DELAY); |
1286 | } | 1294 | } |
1287 | 1295 | ||
1288 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1296 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
1289 | return -EACCES; | 1297 | return -EACCES; |
1298 | } | ||
1299 | |||
1300 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
1301 | { | ||
1302 | unsigned int i; | ||
1303 | u16 eeprom; | ||
1304 | u8 reg_id; | ||
1305 | u8 value; | ||
1306 | |||
1307 | if (unlikely(rt61pci_wait_bbp_ready(rt2x00dev))) | ||
1308 | return -EACCES; | ||
1290 | 1309 | ||
1291 | continue_csr_init: | ||
1292 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); | 1310 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); |
1293 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); | 1311 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); |
1294 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); | 1312 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); |
@@ -1337,7 +1355,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
1337 | 1355 | ||
1338 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 1356 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); |
1339 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | 1357 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, |
1340 | state == STATE_RADIO_RX_OFF); | 1358 | (state == STATE_RADIO_RX_OFF) || |
1359 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
1341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 1360 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
1342 | } | 1361 | } |
1343 | 1362 | ||
@@ -1389,17 +1408,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1389 | /* | 1408 | /* |
1390 | * Initialize all registers. | 1409 | * Initialize all registers. |
1391 | */ | 1410 | */ |
1392 | if (rt61pci_init_queues(rt2x00dev) || | 1411 | if (unlikely(rt61pci_init_queues(rt2x00dev) || |
1393 | rt61pci_init_registers(rt2x00dev) || | 1412 | rt61pci_init_registers(rt2x00dev) || |
1394 | rt61pci_init_bbp(rt2x00dev)) { | 1413 | rt61pci_init_bbp(rt2x00dev))) |
1395 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1396 | return -EIO; | 1414 | return -EIO; |
1397 | } | ||
1398 | |||
1399 | /* | ||
1400 | * Enable interrupts. | ||
1401 | */ | ||
1402 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
1403 | 1415 | ||
1404 | /* | 1416 | /* |
1405 | * Enable RX. | 1417 | * Enable RX. |
@@ -1431,11 +1443,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1431 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1443 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1432 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1444 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
1433 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1445 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1434 | |||
1435 | /* | ||
1436 | * Disable interrupts. | ||
1437 | */ | ||
1438 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
1439 | } | 1446 | } |
1440 | 1447 | ||
1441 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | 1448 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) |
@@ -1443,7 +1450,6 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1443 | u32 reg; | 1450 | u32 reg; |
1444 | unsigned int i; | 1451 | unsigned int i; |
1445 | char put_to_sleep; | 1452 | char put_to_sleep; |
1446 | char current_state; | ||
1447 | 1453 | ||
1448 | put_to_sleep = (state != STATE_AWAKE); | 1454 | put_to_sleep = (state != STATE_AWAKE); |
1449 | 1455 | ||
@@ -1459,16 +1465,12 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1459 | */ | 1465 | */ |
1460 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1466 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1461 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | 1467 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); |
1462 | current_state = | 1468 | state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); |
1463 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | 1469 | if (state == !put_to_sleep) |
1464 | if (current_state == !put_to_sleep) | ||
1465 | return 0; | 1470 | return 0; |
1466 | msleep(10); | 1471 | msleep(10); |
1467 | } | 1472 | } |
1468 | 1473 | ||
1469 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1470 | "current device state %d.\n", !put_to_sleep, current_state); | ||
1471 | |||
1472 | return -EBUSY; | 1474 | return -EBUSY; |
1473 | } | 1475 | } |
1474 | 1476 | ||
@@ -1486,11 +1488,13 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1486 | break; | 1488 | break; |
1487 | case STATE_RADIO_RX_ON: | 1489 | case STATE_RADIO_RX_ON: |
1488 | case STATE_RADIO_RX_ON_LINK: | 1490 | case STATE_RADIO_RX_ON_LINK: |
1489 | rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1490 | break; | ||
1491 | case STATE_RADIO_RX_OFF: | 1491 | case STATE_RADIO_RX_OFF: |
1492 | case STATE_RADIO_RX_OFF_LINK: | 1492 | case STATE_RADIO_RX_OFF_LINK: |
1493 | rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1493 | rt61pci_toggle_rx(rt2x00dev, state); |
1494 | break; | ||
1495 | case STATE_RADIO_IRQ_ON: | ||
1496 | case STATE_RADIO_IRQ_OFF: | ||
1497 | rt61pci_toggle_irq(rt2x00dev, state); | ||
1494 | break; | 1498 | break; |
1495 | case STATE_DEEP_SLEEP: | 1499 | case STATE_DEEP_SLEEP: |
1496 | case STATE_SLEEP: | 1500 | case STATE_SLEEP: |
@@ -1503,6 +1507,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1503 | break; | 1507 | break; |
1504 | } | 1508 | } |
1505 | 1509 | ||
1510 | if (unlikely(retval)) | ||
1511 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1512 | state, retval); | ||
1513 | |||
1506 | return retval; | 1514 | return retval; |
1507 | } | 1515 | } |
1508 | 1516 | ||
@@ -1554,7 +1562,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1554 | 1562 | ||
1555 | if (skbdesc->desc_len > TXINFO_SIZE) { | 1563 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1556 | rt2x00_desc_read(txd, 11, &word); | 1564 | rt2x00_desc_read(txd, 11, &word); |
1557 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1565 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); |
1558 | rt2x00_desc_write(txd, 11, word); | 1566 | rt2x00_desc_write(txd, 11, word); |
1559 | } | 1567 | } |
1560 | 1568 | ||
@@ -1573,7 +1581,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1573 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1581 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1574 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1582 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1575 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1583 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1576 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1584 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); |
1577 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1585 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1578 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1586 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1579 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1587 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
@@ -2067,31 +2075,11 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2067 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2075 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2068 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2076 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2069 | 2077 | ||
2070 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 2078 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
2071 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 2079 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
2072 | rt2x00dev->led_radio.led_dev.brightness_set = | 2080 | if (value == LED_MODE_SIGNAL_STRENGTH) |
2073 | rt61pci_brightness_set; | 2081 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
2074 | rt2x00dev->led_radio.led_dev.blink_set = | 2082 | LED_TYPE_QUALITY); |
2075 | rt61pci_blink_set; | ||
2076 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
2077 | |||
2078 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
2079 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
2080 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
2081 | rt61pci_brightness_set; | ||
2082 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
2083 | rt61pci_blink_set; | ||
2084 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
2085 | |||
2086 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
2087 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
2088 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; | ||
2089 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
2090 | rt61pci_brightness_set; | ||
2091 | rt2x00dev->led_qual.led_dev.blink_set = | ||
2092 | rt61pci_blink_set; | ||
2093 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
2094 | } | ||
2095 | 2083 | ||
2096 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | 2084 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2097 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | 2085 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
@@ -2387,9 +2375,6 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2387 | */ | 2375 | */ |
2388 | skbdesc = get_skb_frame_desc(skb); | 2376 | skbdesc = get_skb_frame_desc(skb); |
2389 | memset(skbdesc, 0, sizeof(*skbdesc)); | 2377 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2390 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
2391 | skbdesc->data = skb->data; | ||
2392 | skbdesc->data_len = skb->len; | ||
2393 | skbdesc->desc = entry_priv->desc; | 2378 | skbdesc->desc = entry_priv->desc; |
2394 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 2379 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2395 | skbdesc->entry = intf->beacon; | 2380 | skbdesc->entry = intf->beacon; |
@@ -2414,7 +2399,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2414 | skbdesc->desc, skbdesc->desc_len); | 2399 | skbdesc->desc, skbdesc->desc_len); |
2415 | rt2x00pci_register_multiwrite(rt2x00dev, | 2400 | rt2x00pci_register_multiwrite(rt2x00dev, |
2416 | beacon_base + skbdesc->desc_len, | 2401 | beacon_base + skbdesc->desc_len, |
2417 | skbdesc->data, skbdesc->data_len); | 2402 | skb->data, skb->len); |
2418 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | 2403 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); |
2419 | 2404 | ||
2420 | return 0; | 2405 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index c5a04b9329d2..1004d5b899e6 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -39,8 +39,6 @@ | |||
39 | * Signal information. | 39 | * Signal information. |
40 | * Defaul offset is required for RSSI <-> dBm conversion. | 40 | * Defaul offset is required for RSSI <-> dBm conversion. |
41 | */ | 41 | */ |
42 | #define MAX_SIGNAL 100 | ||
43 | #define MAX_RX_SSI -1 | ||
44 | #define DEFAULT_RSSI_OFFSET 120 | 42 | #define DEFAULT_RSSI_OFFSET 120 |
45 | 43 | ||
46 | /* | 44 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 26c2e0a1a308..505a9f5e09e9 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -335,6 +335,17 @@ static int rt73usb_blink_set(struct led_classdev *led_cdev, | |||
335 | 335 | ||
336 | return 0; | 336 | return 0; |
337 | } | 337 | } |
338 | |||
339 | static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev, | ||
340 | struct rt2x00_led *led, | ||
341 | enum led_type type) | ||
342 | { | ||
343 | led->rt2x00dev = rt2x00dev; | ||
344 | led->type = type; | ||
345 | led->led_dev.brightness_set = rt73usb_brightness_set; | ||
346 | led->led_dev.blink_set = rt73usb_blink_set; | ||
347 | led->flags = LED_INITIALIZED; | ||
348 | } | ||
338 | #endif /* CONFIG_RT73USB_LEDS */ | 349 | #endif /* CONFIG_RT73USB_LEDS */ |
339 | 350 | ||
340 | /* | 351 | /* |
@@ -1084,25 +1095,32 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1084 | return 0; | 1095 | return 0; |
1085 | } | 1096 | } |
1086 | 1097 | ||
1087 | static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) | 1098 | static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
1088 | { | 1099 | { |
1089 | unsigned int i; | 1100 | unsigned int i; |
1090 | u16 eeprom; | ||
1091 | u8 reg_id; | ||
1092 | u8 value; | 1101 | u8 value; |
1093 | 1102 | ||
1094 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1103 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1095 | rt73usb_bbp_read(rt2x00dev, 0, &value); | 1104 | rt73usb_bbp_read(rt2x00dev, 0, &value); |
1096 | if ((value != 0xff) && (value != 0x00)) | 1105 | if ((value != 0xff) && (value != 0x00)) |
1097 | goto continue_csr_init; | 1106 | return 0; |
1098 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
1099 | udelay(REGISTER_BUSY_DELAY); | 1107 | udelay(REGISTER_BUSY_DELAY); |
1100 | } | 1108 | } |
1101 | 1109 | ||
1102 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1110 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
1103 | return -EACCES; | 1111 | return -EACCES; |
1112 | } | ||
1113 | |||
1114 | static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
1115 | { | ||
1116 | unsigned int i; | ||
1117 | u16 eeprom; | ||
1118 | u8 reg_id; | ||
1119 | u8 value; | ||
1120 | |||
1121 | if (unlikely(rt73usb_wait_bbp_ready(rt2x00dev))) | ||
1122 | return -EACCES; | ||
1104 | 1123 | ||
1105 | continue_csr_init: | ||
1106 | rt73usb_bbp_write(rt2x00dev, 3, 0x80); | 1124 | rt73usb_bbp_write(rt2x00dev, 3, 0x80); |
1107 | rt73usb_bbp_write(rt2x00dev, 15, 0x30); | 1125 | rt73usb_bbp_write(rt2x00dev, 15, 0x30); |
1108 | rt73usb_bbp_write(rt2x00dev, 21, 0xc8); | 1126 | rt73usb_bbp_write(rt2x00dev, 21, 0xc8); |
@@ -1152,7 +1170,8 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
1152 | 1170 | ||
1153 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 1171 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
1154 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | 1172 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, |
1155 | state == STATE_RADIO_RX_OFF); | 1173 | (state == STATE_RADIO_RX_OFF) || |
1174 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
1156 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 1175 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
1157 | } | 1176 | } |
1158 | 1177 | ||
@@ -1161,11 +1180,9 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1161 | /* | 1180 | /* |
1162 | * Initialize all registers. | 1181 | * Initialize all registers. |
1163 | */ | 1182 | */ |
1164 | if (rt73usb_init_registers(rt2x00dev) || | 1183 | if (unlikely(rt73usb_init_registers(rt2x00dev) || |
1165 | rt73usb_init_bbp(rt2x00dev)) { | 1184 | rt73usb_init_bbp(rt2x00dev))) |
1166 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1167 | return -EIO; | 1185 | return -EIO; |
1168 | } | ||
1169 | 1186 | ||
1170 | return 0; | 1187 | return 0; |
1171 | } | 1188 | } |
@@ -1187,7 +1204,6 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1187 | u32 reg; | 1204 | u32 reg; |
1188 | unsigned int i; | 1205 | unsigned int i; |
1189 | char put_to_sleep; | 1206 | char put_to_sleep; |
1190 | char current_state; | ||
1191 | 1207 | ||
1192 | put_to_sleep = (state != STATE_AWAKE); | 1208 | put_to_sleep = (state != STATE_AWAKE); |
1193 | 1209 | ||
@@ -1203,16 +1219,12 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1203 | */ | 1219 | */ |
1204 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1220 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1205 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); | 1221 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); |
1206 | current_state = | 1222 | state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); |
1207 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | 1223 | if (state == !put_to_sleep) |
1208 | if (current_state == !put_to_sleep) | ||
1209 | return 0; | 1224 | return 0; |
1210 | msleep(10); | 1225 | msleep(10); |
1211 | } | 1226 | } |
1212 | 1227 | ||
1213 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1214 | "current device state %d.\n", !put_to_sleep, current_state); | ||
1215 | |||
1216 | return -EBUSY; | 1228 | return -EBUSY; |
1217 | } | 1229 | } |
1218 | 1230 | ||
@@ -1230,11 +1242,13 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1230 | break; | 1242 | break; |
1231 | case STATE_RADIO_RX_ON: | 1243 | case STATE_RADIO_RX_ON: |
1232 | case STATE_RADIO_RX_ON_LINK: | 1244 | case STATE_RADIO_RX_ON_LINK: |
1233 | rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1234 | break; | ||
1235 | case STATE_RADIO_RX_OFF: | 1245 | case STATE_RADIO_RX_OFF: |
1236 | case STATE_RADIO_RX_OFF_LINK: | 1246 | case STATE_RADIO_RX_OFF_LINK: |
1237 | rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1247 | rt73usb_toggle_rx(rt2x00dev, state); |
1248 | break; | ||
1249 | case STATE_RADIO_IRQ_ON: | ||
1250 | case STATE_RADIO_IRQ_OFF: | ||
1251 | /* No support, but no error either */ | ||
1238 | break; | 1252 | break; |
1239 | case STATE_DEEP_SLEEP: | 1253 | case STATE_DEEP_SLEEP: |
1240 | case STATE_SLEEP: | 1254 | case STATE_SLEEP: |
@@ -1247,6 +1261,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1247 | break; | 1261 | break; |
1248 | } | 1262 | } |
1249 | 1263 | ||
1264 | if (unlikely(retval)) | ||
1265 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1266 | state, retval); | ||
1267 | |||
1250 | return retval; | 1268 | return retval; |
1251 | } | 1269 | } |
1252 | 1270 | ||
@@ -1302,7 +1320,8 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1302 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1320 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1303 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); | 1321 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1304 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1322 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1305 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1323 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, |
1324 | skb->len - skbdesc->desc_len); | ||
1306 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1325 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1307 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1326 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1308 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1327 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
@@ -1332,8 +1351,10 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1332 | { | 1351 | { |
1333 | u32 reg; | 1352 | u32 reg; |
1334 | 1353 | ||
1335 | if (queue != QID_BEACON) | 1354 | if (queue != QID_BEACON) { |
1355 | rt2x00usb_kick_tx_queue(rt2x00dev, queue); | ||
1336 | return; | 1356 | return; |
1357 | } | ||
1337 | 1358 | ||
1338 | /* | 1359 | /* |
1339 | * For Wi-Fi faily generated beacons between participating stations. | 1360 | * For Wi-Fi faily generated beacons between participating stations. |
@@ -1407,14 +1428,10 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1407 | u32 word1; | 1428 | u32 word1; |
1408 | 1429 | ||
1409 | /* | 1430 | /* |
1410 | * Copy descriptor to the skb->cb array, this has 2 benefits: | 1431 | * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of |
1411 | * 1) Each descriptor word is 4 byte aligned. | 1432 | * frame data in rt2x00usb. |
1412 | * 2) Descriptor is safe from moving of frame data in rt2x00usb. | ||
1413 | */ | 1433 | */ |
1414 | skbdesc->desc_len = | 1434 | memcpy(skbdesc->desc, rxd, skbdesc->desc_len); |
1415 | min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); | ||
1416 | memcpy(entry->skb->cb, rxd, skbdesc->desc_len); | ||
1417 | skbdesc->desc = entry->skb->cb; | ||
1418 | rxd = (__le32 *)skbdesc->desc; | 1435 | rxd = (__le32 *)skbdesc->desc; |
1419 | 1436 | ||
1420 | /* | 1437 | /* |
@@ -1446,8 +1463,6 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1446 | */ | 1463 | */ |
1447 | skb_pull(entry->skb, entry->queue->desc_size); | 1464 | skb_pull(entry->skb, entry->queue->desc_size); |
1448 | skb_trim(entry->skb, rxdesc->size); | 1465 | skb_trim(entry->skb, rxdesc->size); |
1449 | skbdesc->data = entry->skb->data; | ||
1450 | skbdesc->data_len = rxdesc->size; | ||
1451 | } | 1466 | } |
1452 | 1467 | ||
1453 | /* | 1468 | /* |
@@ -1620,31 +1635,11 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1620 | #ifdef CONFIG_RT73USB_LEDS | 1635 | #ifdef CONFIG_RT73USB_LEDS |
1621 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1636 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1622 | 1637 | ||
1623 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 1638 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1624 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 1639 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
1625 | rt2x00dev->led_radio.led_dev.brightness_set = | 1640 | if (value == LED_MODE_SIGNAL_STRENGTH) |
1626 | rt73usb_brightness_set; | 1641 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1627 | rt2x00dev->led_radio.led_dev.blink_set = | 1642 | LED_TYPE_QUALITY); |
1628 | rt73usb_blink_set; | ||
1629 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1630 | |||
1631 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
1632 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
1633 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
1634 | rt73usb_brightness_set; | ||
1635 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
1636 | rt73usb_blink_set; | ||
1637 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
1638 | |||
1639 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
1640 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1641 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; | ||
1642 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1643 | rt73usb_brightness_set; | ||
1644 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1645 | rt73usb_blink_set; | ||
1646 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1647 | } | ||
1648 | 1643 | ||
1649 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | 1644 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
1650 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1645 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
@@ -1980,9 +1975,6 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1980 | */ | 1975 | */ |
1981 | skbdesc = get_skb_frame_desc(skb); | 1976 | skbdesc = get_skb_frame_desc(skb); |
1982 | memset(skbdesc, 0, sizeof(*skbdesc)); | 1977 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1983 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
1984 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | ||
1985 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | ||
1986 | skbdesc->desc = skb->data; | 1978 | skbdesc->desc = skb->data; |
1987 | skbdesc->desc_len = intf->beacon->queue->desc_size; | 1979 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1988 | skbdesc->entry = intf->beacon; | 1980 | skbdesc->entry = intf->beacon; |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 25cdcc9bf7c4..148493501011 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -39,8 +39,6 @@ | |||
39 | * Signal information. | 39 | * Signal information. |
40 | * Defaul offset is required for RSSI <-> dBm conversion. | 40 | * Defaul offset is required for RSSI <-> dBm conversion. |
41 | */ | 41 | */ |
42 | #define MAX_SIGNAL 100 | ||
43 | #define MAX_RX_SSI -1 | ||
44 | #define DEFAULT_RSSI_OFFSET 120 | 42 | #define DEFAULT_RSSI_OFFSET 120 |
45 | 43 | ||
46 | /* | 44 | /* |
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 0078c7e9918c..bec96d762c6c 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c | |||
@@ -181,7 +181,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
181 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; | 181 | flags |= RTL8187_TX_FLAG_NO_ENCRYPT; |
182 | 182 | ||
183 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; | 183 | flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; |
184 | if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) | 184 | if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) |
185 | flags |= RTL8187_TX_FLAG_MORE_FRAG; | 185 | flags |= RTL8187_TX_FLAG_MORE_FRAG; |
186 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { | 186 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { |
187 | flags |= RTL8187_TX_FLAG_RTS; | 187 | flags |= RTL8187_TX_FLAG_RTS; |
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 9300f37cd7e8..2998e3b5f166 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -98,6 +98,7 @@ | |||
98 | 98 | ||
99 | #define IEEE80211_MAX_SSID_LEN 32 | 99 | #define IEEE80211_MAX_SSID_LEN 32 |
100 | #define IEEE80211_MAX_MESH_ID_LEN 32 | 100 | #define IEEE80211_MAX_MESH_ID_LEN 32 |
101 | #define IEEE80211_QOS_CTL_LEN 2 | ||
101 | 102 | ||
102 | struct ieee80211_hdr { | 103 | struct ieee80211_hdr { |
103 | __le16 frame_control; | 104 | __le16 frame_control; |
@@ -109,6 +110,355 @@ struct ieee80211_hdr { | |||
109 | u8 addr4[6]; | 110 | u8 addr4[6]; |
110 | } __attribute__ ((packed)); | 111 | } __attribute__ ((packed)); |
111 | 112 | ||
113 | /** | ||
114 | * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set | ||
115 | * @fc: frame control bytes in little-endian byteorder | ||
116 | */ | ||
117 | static inline int ieee80211_has_tods(__le16 fc) | ||
118 | { | ||
119 | return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0; | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set | ||
124 | * @fc: frame control bytes in little-endian byteorder | ||
125 | */ | ||
126 | static inline int ieee80211_has_fromds(__le16 fc) | ||
127 | { | ||
128 | return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set | ||
133 | * @fc: frame control bytes in little-endian byteorder | ||
134 | */ | ||
135 | static inline int ieee80211_has_a4(__le16 fc) | ||
136 | { | ||
137 | __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
138 | return (fc & tmp) == tmp; | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set | ||
143 | * @fc: frame control bytes in little-endian byteorder | ||
144 | */ | ||
145 | static inline int ieee80211_has_morefrags(__le16 fc) | ||
146 | { | ||
147 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set | ||
152 | * @fc: frame control bytes in little-endian byteorder | ||
153 | */ | ||
154 | static inline int ieee80211_has_retry(__le16 fc) | ||
155 | { | ||
156 | return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0; | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set | ||
161 | * @fc: frame control bytes in little-endian byteorder | ||
162 | */ | ||
163 | static inline int ieee80211_has_pm(__le16 fc) | ||
164 | { | ||
165 | return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set | ||
170 | * @fc: frame control bytes in little-endian byteorder | ||
171 | */ | ||
172 | static inline int ieee80211_has_moredata(__le16 fc) | ||
173 | { | ||
174 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0; | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set | ||
179 | * @fc: frame control bytes in little-endian byteorder | ||
180 | */ | ||
181 | static inline int ieee80211_has_protected(__le16 fc) | ||
182 | { | ||
183 | return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0; | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set | ||
188 | * @fc: frame control bytes in little-endian byteorder | ||
189 | */ | ||
190 | static inline int ieee80211_has_order(__le16 fc) | ||
191 | { | ||
192 | return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0; | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT | ||
197 | * @fc: frame control bytes in little-endian byteorder | ||
198 | */ | ||
199 | static inline int ieee80211_is_mgmt(__le16 fc) | ||
200 | { | ||
201 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
202 | cpu_to_le16(IEEE80211_FTYPE_MGMT); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL | ||
207 | * @fc: frame control bytes in little-endian byteorder | ||
208 | */ | ||
209 | static inline int ieee80211_is_ctl(__le16 fc) | ||
210 | { | ||
211 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
212 | cpu_to_le16(IEEE80211_FTYPE_CTL); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA | ||
217 | * @fc: frame control bytes in little-endian byteorder | ||
218 | */ | ||
219 | static inline int ieee80211_is_data(__le16 fc) | ||
220 | { | ||
221 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
222 | cpu_to_le16(IEEE80211_FTYPE_DATA); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set | ||
227 | * @fc: frame control bytes in little-endian byteorder | ||
228 | */ | ||
229 | static inline int ieee80211_is_data_qos(__le16 fc) | ||
230 | { | ||
231 | /* | ||
232 | * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need | ||
233 | * to check the one bit | ||
234 | */ | ||
235 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == | ||
236 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data | ||
241 | * @fc: frame control bytes in little-endian byteorder | ||
242 | */ | ||
243 | static inline int ieee80211_is_data_present(__le16 fc) | ||
244 | { | ||
245 | /* | ||
246 | * mask with 0x40 and test that that bit is clear to only return true | ||
247 | * for the data-containing substypes. | ||
248 | */ | ||
249 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) == | ||
250 | cpu_to_le16(IEEE80211_FTYPE_DATA); | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ | ||
255 | * @fc: frame control bytes in little-endian byteorder | ||
256 | */ | ||
257 | static inline int ieee80211_is_assoc_req(__le16 fc) | ||
258 | { | ||
259 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
260 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP | ||
265 | * @fc: frame control bytes in little-endian byteorder | ||
266 | */ | ||
267 | static inline int ieee80211_is_assoc_resp(__le16 fc) | ||
268 | { | ||
269 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
270 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ | ||
275 | * @fc: frame control bytes in little-endian byteorder | ||
276 | */ | ||
277 | static inline int ieee80211_is_reassoc_req(__le16 fc) | ||
278 | { | ||
279 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
280 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP | ||
285 | * @fc: frame control bytes in little-endian byteorder | ||
286 | */ | ||
287 | static inline int ieee80211_is_reassoc_resp(__le16 fc) | ||
288 | { | ||
289 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
290 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP); | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ | ||
295 | * @fc: frame control bytes in little-endian byteorder | ||
296 | */ | ||
297 | static inline int ieee80211_is_probe_req(__le16 fc) | ||
298 | { | ||
299 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
300 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); | ||
301 | } | ||
302 | |||
303 | /** | ||
304 | * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP | ||
305 | * @fc: frame control bytes in little-endian byteorder | ||
306 | */ | ||
307 | static inline int ieee80211_is_probe_resp(__le16 fc) | ||
308 | { | ||
309 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
310 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON | ||
315 | * @fc: frame control bytes in little-endian byteorder | ||
316 | */ | ||
317 | static inline int ieee80211_is_beacon(__le16 fc) | ||
318 | { | ||
319 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
320 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM | ||
325 | * @fc: frame control bytes in little-endian byteorder | ||
326 | */ | ||
327 | static inline int ieee80211_is_atim(__le16 fc) | ||
328 | { | ||
329 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
330 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC | ||
335 | * @fc: frame control bytes in little-endian byteorder | ||
336 | */ | ||
337 | static inline int ieee80211_is_disassoc(__le16 fc) | ||
338 | { | ||
339 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
340 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH | ||
345 | * @fc: frame control bytes in little-endian byteorder | ||
346 | */ | ||
347 | static inline int ieee80211_is_auth(__le16 fc) | ||
348 | { | ||
349 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
350 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH | ||
355 | * @fc: frame control bytes in little-endian byteorder | ||
356 | */ | ||
357 | static inline int ieee80211_is_deauth(__le16 fc) | ||
358 | { | ||
359 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
360 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION | ||
365 | * @fc: frame control bytes in little-endian byteorder | ||
366 | */ | ||
367 | static inline int ieee80211_is_action(__le16 fc) | ||
368 | { | ||
369 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
370 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ | ||
375 | * @fc: frame control bytes in little-endian byteorder | ||
376 | */ | ||
377 | static inline int ieee80211_is_back_req(__le16 fc) | ||
378 | { | ||
379 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
380 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK | ||
385 | * @fc: frame control bytes in little-endian byteorder | ||
386 | */ | ||
387 | static inline int ieee80211_is_back(__le16 fc) | ||
388 | { | ||
389 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
390 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK); | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL | ||
395 | * @fc: frame control bytes in little-endian byteorder | ||
396 | */ | ||
397 | static inline int ieee80211_is_pspoll(__le16 fc) | ||
398 | { | ||
399 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
400 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS | ||
405 | * @fc: frame control bytes in little-endian byteorder | ||
406 | */ | ||
407 | static inline int ieee80211_is_rts(__le16 fc) | ||
408 | { | ||
409 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
410 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS | ||
415 | * @fc: frame control bytes in little-endian byteorder | ||
416 | */ | ||
417 | static inline int ieee80211_is_cts(__le16 fc) | ||
418 | { | ||
419 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
420 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK | ||
425 | * @fc: frame control bytes in little-endian byteorder | ||
426 | */ | ||
427 | static inline int ieee80211_is_ack(__le16 fc) | ||
428 | { | ||
429 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
430 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK); | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND | ||
435 | * @fc: frame control bytes in little-endian byteorder | ||
436 | */ | ||
437 | static inline int ieee80211_is_cfend(__le16 fc) | ||
438 | { | ||
439 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
440 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND); | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK | ||
445 | * @fc: frame control bytes in little-endian byteorder | ||
446 | */ | ||
447 | static inline int ieee80211_is_cfendack(__le16 fc) | ||
448 | { | ||
449 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
450 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC | ||
455 | * @fc: frame control bytes in little-endian byteorder | ||
456 | */ | ||
457 | static inline int ieee80211_is_nullfunc(__le16 fc) | ||
458 | { | ||
459 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
460 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC); | ||
461 | } | ||
112 | 462 | ||
113 | struct ieee80211s_hdr { | 463 | struct ieee80211s_hdr { |
114 | u8 flags; | 464 | u8 flags; |
@@ -320,6 +670,7 @@ struct ieee80211_ht_addt_info { | |||
320 | #define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 | 670 | #define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 |
321 | /* 802.11n HT IE masks */ | 671 | /* 802.11n HT IE masks */ |
322 | #define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 | 672 | #define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 |
673 | #define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 | ||
323 | #define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 | 674 | #define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 |
324 | #define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 | 675 | #define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 |
325 | #define IEEE80211_HT_IE_CHA_WIDTH 0x04 | 676 | #define IEEE80211_HT_IE_CHA_WIDTH 0x04 |
@@ -552,65 +903,57 @@ enum ieee80211_back_parties { | |||
552 | #define WLAN_MAX_KEY_LEN 32 | 903 | #define WLAN_MAX_KEY_LEN 32 |
553 | 904 | ||
554 | /** | 905 | /** |
906 | * ieee80211_get_qos_ctl - get pointer to qos control bytes | ||
907 | * @hdr: the frame | ||
908 | * | ||
909 | * The qos ctrl bytes come after the frame_control, duration, seq_num | ||
910 | * and 3 or 4 addresses of length ETH_ALEN. | ||
911 | * 3 addr: 2 + 2 + 2 + 3*6 = 24 | ||
912 | * 4 addr: 2 + 2 + 2 + 4*6 = 30 | ||
913 | */ | ||
914 | static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) | ||
915 | { | ||
916 | if (ieee80211_has_a4(hdr->frame_control)) | ||
917 | return (u8 *)hdr + 30; | ||
918 | else | ||
919 | return (u8 *)hdr + 24; | ||
920 | } | ||
921 | |||
922 | /** | ||
555 | * ieee80211_get_SA - get pointer to SA | 923 | * ieee80211_get_SA - get pointer to SA |
924 | * @hdr: the frame | ||
556 | * | 925 | * |
557 | * Given an 802.11 frame, this function returns the offset | 926 | * Given an 802.11 frame, this function returns the offset |
558 | * to the source address (SA). It does not verify that the | 927 | * to the source address (SA). It does not verify that the |
559 | * header is long enough to contain the address, and the | 928 | * header is long enough to contain the address, and the |
560 | * header must be long enough to contain the frame control | 929 | * header must be long enough to contain the frame control |
561 | * field. | 930 | * field. |
562 | * | ||
563 | * @hdr: the frame | ||
564 | */ | 931 | */ |
565 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) | 932 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) |
566 | { | 933 | { |
567 | __le16 fc = hdr->frame_control; | 934 | if (ieee80211_has_a4(hdr->frame_control)) |
568 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
569 | |||
570 | switch (fc) { | ||
571 | case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): | ||
572 | return hdr->addr3; | ||
573 | case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS): | ||
574 | return hdr->addr4; | 935 | return hdr->addr4; |
575 | default: | 936 | if (ieee80211_has_fromds(hdr->frame_control)) |
576 | return hdr->addr2; | 937 | return hdr->addr3; |
577 | } | 938 | return hdr->addr2; |
578 | } | 939 | } |
579 | 940 | ||
580 | /** | 941 | /** |
581 | * ieee80211_get_DA - get pointer to DA | 942 | * ieee80211_get_DA - get pointer to DA |
943 | * @hdr: the frame | ||
582 | * | 944 | * |
583 | * Given an 802.11 frame, this function returns the offset | 945 | * Given an 802.11 frame, this function returns the offset |
584 | * to the destination address (DA). It does not verify that | 946 | * to the destination address (DA). It does not verify that |
585 | * the header is long enough to contain the address, and the | 947 | * the header is long enough to contain the address, and the |
586 | * header must be long enough to contain the frame control | 948 | * header must be long enough to contain the frame control |
587 | * field. | 949 | * field. |
588 | * | ||
589 | * @hdr: the frame | ||
590 | */ | 950 | */ |
591 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) | 951 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) |
592 | { | 952 | { |
593 | __le16 fc = hdr->frame_control; | 953 | if (ieee80211_has_tods(hdr->frame_control)) |
594 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
595 | |||
596 | if (fc) | ||
597 | return hdr->addr3; | 954 | return hdr->addr3; |
598 | else | 955 | else |
599 | return hdr->addr1; | 956 | return hdr->addr1; |
600 | } | 957 | } |
601 | 958 | ||
602 | /** | ||
603 | * ieee80211_get_morefrag - determine whether the MOREFRAGS bit is set | ||
604 | * | ||
605 | * This function determines whether the "more fragments" bit is set | ||
606 | * in the frame. | ||
607 | * | ||
608 | * @hdr: the frame | ||
609 | */ | ||
610 | static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) | ||
611 | { | ||
612 | __le16 fc = hdr->frame_control; | ||
613 | return !!(fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)); | ||
614 | } | ||
615 | |||
616 | #endif /* IEEE80211_H */ | 959 | #endif /* IEEE80211_H */ |
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index ea6517e58b04..aa8411e2a160 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -122,13 +122,13 @@ enum nl80211_commands { | |||
122 | NL80211_CMD_NEW_STATION, | 122 | NL80211_CMD_NEW_STATION, |
123 | NL80211_CMD_DEL_STATION, | 123 | NL80211_CMD_DEL_STATION, |
124 | 124 | ||
125 | /* add commands here */ | ||
126 | |||
127 | NL80211_CMD_GET_MPATH, | 125 | NL80211_CMD_GET_MPATH, |
128 | NL80211_CMD_SET_MPATH, | 126 | NL80211_CMD_SET_MPATH, |
129 | NL80211_CMD_NEW_MPATH, | 127 | NL80211_CMD_NEW_MPATH, |
130 | NL80211_CMD_DEL_MPATH, | 128 | NL80211_CMD_DEL_MPATH, |
131 | 129 | ||
130 | /* add commands here */ | ||
131 | |||
132 | /* used to define NL80211_CMD_MAX below */ | 132 | /* used to define NL80211_CMD_MAX below */ |
133 | __NL80211_CMD_AFTER_LAST, | 133 | __NL80211_CMD_AFTER_LAST, |
134 | NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 | 134 | NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 |
@@ -230,13 +230,13 @@ enum nl80211_attrs { | |||
230 | 230 | ||
231 | NL80211_ATTR_MNTR_FLAGS, | 231 | NL80211_ATTR_MNTR_FLAGS, |
232 | 232 | ||
233 | /* add attributes here, update the policy in nl80211.c */ | ||
234 | |||
235 | NL80211_ATTR_MESH_ID, | 233 | NL80211_ATTR_MESH_ID, |
236 | NL80211_ATTR_STA_PLINK_ACTION, | 234 | NL80211_ATTR_STA_PLINK_ACTION, |
237 | NL80211_ATTR_MPATH_NEXT_HOP, | 235 | NL80211_ATTR_MPATH_NEXT_HOP, |
238 | NL80211_ATTR_MPATH_INFO, | 236 | NL80211_ATTR_MPATH_INFO, |
239 | 237 | ||
238 | /* add attributes here, update the policy in nl80211.c */ | ||
239 | |||
240 | __NL80211_ATTR_AFTER_LAST, | 240 | __NL80211_ATTR_AFTER_LAST, |
241 | NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 | 241 | NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 |
242 | }; | 242 | }; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 1196de85f8db..7ab4ff6159a2 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1535,7 +1535,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | |||
1535 | * | 1535 | * |
1536 | * @skb: the frame | 1536 | * @skb: the frame |
1537 | */ | 1537 | */ |
1538 | int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); | 1538 | unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); |
1539 | 1539 | ||
1540 | /** | 1540 | /** |
1541 | * ieee80211_get_hdrlen - get header length from frame control | 1541 | * ieee80211_get_hdrlen - get header length from frame control |
@@ -1548,6 +1548,12 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); | |||
1548 | int ieee80211_get_hdrlen(u16 fc); | 1548 | int ieee80211_get_hdrlen(u16 fc); |
1549 | 1549 | ||
1550 | /** | 1550 | /** |
1551 | * ieee80211_hdrlen - get header length in bytes from frame control | ||
1552 | * @fc: frame control field in little-endian format | ||
1553 | */ | ||
1554 | unsigned int ieee80211_hdrlen(__le16 fc); | ||
1555 | |||
1556 | /** | ||
1551 | * ieee80211_get_tkip_key - get a TKIP rc4 for skb | 1557 | * ieee80211_get_tkip_key - get a TKIP rc4 for skb |
1552 | * | 1558 | * |
1553 | * This function computes a TKIP rc4 key for an skb. It computes | 1559 | * This function computes a TKIP rc4 key for an skb. It computes |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index b19bd16703b2..14fccf16b80f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -876,7 +876,7 @@ void ieee80211_rx_bss_list_deinit(struct net_device *dev); | |||
876 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); | 876 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); |
877 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | 877 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
878 | struct sk_buff *skb, u8 *bssid, | 878 | struct sk_buff *skb, u8 *bssid, |
879 | u8 *addr); | 879 | u8 *addr, u64 supp_rates); |
880 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); | 880 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); |
881 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); | 881 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); |
882 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 882 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b182f018a187..5c5396edad32 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1707,7 +1707,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1707 | 1707 | ||
1708 | debugfs_hw_add(local); | 1708 | debugfs_hw_add(local); |
1709 | 1709 | ||
1710 | local->hw.conf.beacon_int = 1000; | 1710 | if (local->hw.conf.beacon_int < 10) |
1711 | local->hw.conf.beacon_int = 100; | ||
1711 | 1712 | ||
1712 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | | 1713 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1713 | IEEE80211_HW_SIGNAL_DB | | 1714 | IEEE80211_HW_SIGNAL_DB | |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7f05820dc629..55659a730dc1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2863,7 +2863,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2863 | dev->name, print_mac(mac, mgmt->bssid)); | 2863 | dev->name, print_mac(mac, mgmt->bssid)); |
2864 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | 2864 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); |
2865 | ieee80211_ibss_add_sta(dev, NULL, | 2865 | ieee80211_ibss_add_sta(dev, NULL, |
2866 | mgmt->bssid, mgmt->sa); | 2866 | mgmt->bssid, mgmt->sa, |
2867 | BIT(rx_status->rate_idx)); | ||
2867 | } | 2868 | } |
2868 | } | 2869 | } |
2869 | 2870 | ||
@@ -3583,7 +3584,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3583 | sband = local->hw.wiphy->bands[bss->band]; | 3584 | sband = local->hw.wiphy->bands[bss->band]; |
3584 | 3585 | ||
3585 | if (local->hw.conf.beacon_int == 0) | 3586 | if (local->hw.conf.beacon_int == 0) |
3586 | local->hw.conf.beacon_int = 10000; | 3587 | local->hw.conf.beacon_int = 100; |
3587 | bss->beacon_int = local->hw.conf.beacon_int; | 3588 | bss->beacon_int = local->hw.conf.beacon_int; |
3588 | bss->last_update = jiffies; | 3589 | bss->last_update = jiffies; |
3589 | bss->capability = WLAN_CAPABILITY_IBSS; | 3590 | bss->capability = WLAN_CAPABILITY_IBSS; |
@@ -4307,12 +4308,13 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
4307 | 4308 | ||
4308 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | 4309 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
4309 | struct sk_buff *skb, u8 *bssid, | 4310 | struct sk_buff *skb, u8 *bssid, |
4310 | u8 *addr) | 4311 | u8 *addr, u64 supp_rates) |
4311 | { | 4312 | { |
4312 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4313 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
4313 | struct sta_info *sta; | 4314 | struct sta_info *sta; |
4314 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4315 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4315 | DECLARE_MAC_BUF(mac); | 4316 | DECLARE_MAC_BUF(mac); |
4317 | int band = local->hw.conf.channel->band; | ||
4316 | 4318 | ||
4317 | /* TODO: Could consider removing the least recently used entry and | 4319 | /* TODO: Could consider removing the least recently used entry and |
4318 | * allow new one to be added. */ | 4320 | * allow new one to be added. */ |
@@ -4324,6 +4326,9 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4324 | return NULL; | 4326 | return NULL; |
4325 | } | 4327 | } |
4326 | 4328 | ||
4329 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) | ||
4330 | return NULL; | ||
4331 | |||
4327 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 4332 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", |
4328 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 4333 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
4329 | 4334 | ||
@@ -4333,8 +4338,10 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, | |||
4333 | 4338 | ||
4334 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); | 4339 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
4335 | 4340 | ||
4336 | sta->supp_rates[local->hw.conf.channel->band] = | 4341 | if (supp_rates) |
4337 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | 4342 | sta->supp_rates[band] = supp_rates; |
4343 | else | ||
4344 | sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band]; | ||
4338 | 4345 | ||
4339 | rate_control_rate_init(sta, local); | 4346 | rate_control_rate_init(sta, local); |
4340 | 4347 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a3643fd86af9..c32a0bcd53b7 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -67,12 +67,9 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
67 | return 1; | 67 | return 1; |
68 | if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) | 68 | if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) |
69 | return 1; | 69 | return 1; |
70 | if (((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | 70 | if (ieee80211_is_ctl(hdr->frame_control) && |
71 | cpu_to_le16(IEEE80211_FTYPE_CTL)) && | 71 | !ieee80211_is_pspoll(hdr->frame_control) && |
72 | ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != | 72 | !ieee80211_is_back_req(hdr->frame_control)) |
73 | cpu_to_le16(IEEE80211_STYPE_PSPOLL)) && | ||
74 | ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != | ||
75 | cpu_to_le16(IEEE80211_STYPE_BACK_REQ))) | ||
76 | return 1; | 73 | return 1; |
77 | return 0; | 74 | return 0; |
78 | } | 75 | } |
@@ -1826,8 +1823,13 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1826 | if (!bssid) | 1823 | if (!bssid) |
1827 | return 0; | 1824 | return 0; |
1828 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && | 1825 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && |
1829 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) | 1826 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { |
1827 | if (!rx->sta) | ||
1828 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, | ||
1829 | rx->skb, bssid, hdr->addr2, | ||
1830 | BIT(rx->status->rate_idx)); | ||
1830 | return 1; | 1831 | return 1; |
1832 | } | ||
1831 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | 1833 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { |
1832 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 1834 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) |
1833 | return 0; | 1835 | return 0; |
@@ -1840,7 +1842,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1840 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1842 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1841 | } else if (!rx->sta) | 1843 | } else if (!rx->sta) |
1842 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, | 1844 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, |
1843 | bssid, hdr->addr2); | 1845 | bssid, hdr->addr2, |
1846 | BIT(rx->status->rate_idx)); | ||
1844 | break; | 1847 | break; |
1845 | case IEEE80211_IF_TYPE_MESH_POINT: | 1848 | case IEEE80211_IF_TYPE_MESH_POINT: |
1846 | if (!multicast && | 1849 | if (!multicast && |
@@ -2118,7 +2121,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2118 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2121 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2119 | struct sta_info *sta; | 2122 | struct sta_info *sta; |
2120 | struct tid_ampdu_rx *tid_agg_rx; | 2123 | struct tid_ampdu_rx *tid_agg_rx; |
2121 | u16 fc, sc; | 2124 | u16 sc; |
2122 | u16 mpdu_seq_num; | 2125 | u16 mpdu_seq_num; |
2123 | u8 ret = 0, *qc; | 2126 | u8 ret = 0, *qc; |
2124 | int tid; | 2127 | int tid; |
@@ -2127,14 +2130,12 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2127 | if (!sta) | 2130 | if (!sta) |
2128 | return ret; | 2131 | return ret; |
2129 | 2132 | ||
2130 | fc = le16_to_cpu(hdr->frame_control); | ||
2131 | |||
2132 | /* filter the QoS data rx stream according to | 2133 | /* filter the QoS data rx stream according to |
2133 | * STA/TID and check if this STA/TID is on aggregation */ | 2134 | * STA/TID and check if this STA/TID is on aggregation */ |
2134 | if (!WLAN_FC_IS_QOS_DATA(fc)) | 2135 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
2135 | goto end_reorder; | 2136 | goto end_reorder; |
2136 | 2137 | ||
2137 | qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN; | 2138 | qc = ieee80211_get_qos_ctl(hdr); |
2138 | tid = qc[0] & QOS_CONTROL_TID_MASK; | 2139 | tid = qc[0] & QOS_CONTROL_TID_MASK; |
2139 | 2140 | ||
2140 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) | 2141 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) |
@@ -2143,7 +2144,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2143 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 2144 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
2144 | 2145 | ||
2145 | /* null data frames are excluded */ | 2146 | /* null data frames are excluded */ |
2146 | if (unlikely(fc & IEEE80211_STYPE_NULLFUNC)) | 2147 | if (unlikely(ieee80211_is_nullfunc(hdr->frame_control))) |
2147 | goto end_reorder; | 2148 | goto end_reorder; |
2148 | 2149 | ||
2149 | /* new un-ordered ampdu frame - process it */ | 2150 | /* new un-ordered ampdu frame - process it */ |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index a00cf1ea7719..e710243d82e2 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -64,6 +64,14 @@ static u16 tkipS(u16 val) | |||
64 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); | 64 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
65 | } | 65 | } |
66 | 66 | ||
67 | static u8 *write_tkip_iv(u8 *pos, u16 iv16) | ||
68 | { | ||
69 | *pos++ = iv16 >> 8; | ||
70 | *pos++ = ((iv16 >> 8) | 0x20) & 0x7f; | ||
71 | *pos++ = iv16 & 0xFF; | ||
72 | return pos; | ||
73 | } | ||
74 | |||
67 | /* | 75 | /* |
68 | * P1K := Phase1(TA, TK, TSC) | 76 | * P1K := Phase1(TA, TK, TSC) |
69 | * TA = transmitter address (48 bits) | 77 | * TA = transmitter address (48 bits) |
@@ -71,11 +79,10 @@ static u16 tkipS(u16 val) | |||
71 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 79 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
72 | * P1K: 80 bits | 80 | * P1K: 80 bits |
73 | */ | 81 | */ |
74 | static void tkip_mixing_phase1(struct ieee80211_key *key, const u8 *ta, | 82 | static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, |
75 | struct tkip_ctx *ctx, u32 tsc_IV32) | 83 | const u8 *ta, u32 tsc_IV32) |
76 | { | 84 | { |
77 | int i, j; | 85 | int i, j; |
78 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
79 | u16 *p1k = ctx->p1k; | 86 | u16 *p1k = ctx->p1k; |
80 | 87 | ||
81 | p1k[0] = tsc_IV32 & 0xFFFF; | 88 | p1k[0] = tsc_IV32 & 0xFFFF; |
@@ -95,12 +102,11 @@ static void tkip_mixing_phase1(struct ieee80211_key *key, const u8 *ta, | |||
95 | ctx->initialized = 1; | 102 | ctx->initialized = 1; |
96 | } | 103 | } |
97 | 104 | ||
98 | static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx, | 105 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, |
99 | u16 tsc_IV16, u8 *rc4key) | 106 | u16 tsc_IV16, u8 *rc4key) |
100 | { | 107 | { |
101 | u16 ppk[6]; | 108 | u16 ppk[6]; |
102 | const u16 *p1k = ctx->p1k; | 109 | const u16 *p1k = ctx->p1k; |
103 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
104 | int i; | 110 | int i; |
105 | 111 | ||
106 | ppk[0] = p1k[0]; | 112 | ppk[0] = p1k[0]; |
@@ -123,12 +129,9 @@ static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx, | |||
123 | ppk[4] += ror16(ppk[3], 1); | 129 | ppk[4] += ror16(ppk[3], 1); |
124 | ppk[5] += ror16(ppk[4], 1); | 130 | ppk[5] += ror16(ppk[4], 1); |
125 | 131 | ||
126 | rc4key[0] = tsc_IV16 >> 8; | 132 | rc4key = write_tkip_iv(rc4key, tsc_IV16); |
127 | rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f; | 133 | *rc4key++ = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
128 | rc4key[2] = tsc_IV16 & 0xFF; | ||
129 | rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; | ||
130 | 134 | ||
131 | rc4key += 4; | ||
132 | for (i = 0; i < 6; i++) | 135 | for (i = 0; i < 6; i++) |
133 | put_unaligned_le16(ppk[i], rc4key + 2 * i); | 136 | put_unaligned_le16(ppk[i], rc4key + 2 * i); |
134 | } | 137 | } |
@@ -136,51 +139,41 @@ static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx, | |||
136 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 139 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
137 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 140 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
138 | * the packet payload). */ | 141 | * the packet payload). */ |
139 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | 142 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) |
140 | u8 iv0, u8 iv1, u8 iv2) | ||
141 | { | 143 | { |
142 | *pos++ = iv0; | 144 | pos = write_tkip_iv(pos, iv16); |
143 | *pos++ = iv1; | ||
144 | *pos++ = iv2; | ||
145 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 145 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
146 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); | 146 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
147 | return pos + 4; | 147 | return pos + 4; |
148 | } | 148 | } |
149 | 149 | ||
150 | static void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
151 | u8 *rc4key) | ||
152 | { | ||
153 | /* Calculate per-packet key */ | ||
154 | if (key->u.tkip.tx.iv16 == 0 || !key->u.tkip.tx.initialized) | ||
155 | tkip_mixing_phase1(key, ta, &key->u.tkip.tx, key->u.tkip.tx.iv32); | ||
156 | |||
157 | tkip_mixing_phase2(key, &key->u.tkip.tx, key->u.tkip.tx.iv16, rc4key); | ||
158 | } | ||
159 | |||
160 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 150 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, |
161 | struct sk_buff *skb, enum ieee80211_tkip_key_type type, | 151 | struct sk_buff *skb, enum ieee80211_tkip_key_type type, |
162 | u8 *outkey) | 152 | u8 *outkey) |
163 | { | 153 | { |
164 | struct ieee80211_key *key = (struct ieee80211_key *) | 154 | struct ieee80211_key *key = (struct ieee80211_key *) |
165 | container_of(keyconf, struct ieee80211_key, conf); | 155 | container_of(keyconf, struct ieee80211_key, conf); |
166 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 156 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
167 | u8 *data = (u8 *) hdr; | 157 | u8 *data; |
168 | u16 fc = le16_to_cpu(hdr->frame_control); | 158 | const u8 *tk; |
169 | int hdr_len = ieee80211_get_hdrlen(fc); | 159 | struct tkip_ctx *ctx; |
170 | u8 *ta = hdr->addr2; | ||
171 | u16 iv16; | 160 | u16 iv16; |
172 | u32 iv32; | 161 | u32 iv32; |
173 | 162 | ||
174 | iv16 = data[hdr_len + 2] | (data[hdr_len] << 8); | 163 | data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); |
175 | iv32 = get_unaligned_le32(data + hdr_len + 4); | 164 | iv16 = data[2] | (data[0] << 8); |
165 | iv32 = get_unaligned_le32(&data[4]); | ||
166 | |||
167 | tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
168 | ctx = &key->u.tkip.tx; | ||
176 | 169 | ||
177 | #ifdef CONFIG_TKIP_DEBUG | 170 | #ifdef CONFIG_TKIP_DEBUG |
178 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", | 171 | printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", |
179 | iv16, iv32); | 172 | iv16, iv32); |
180 | 173 | ||
181 | if (iv32 != key->u.tkip.tx.iv32) { | 174 | if (iv32 != ctx->iv32) { |
182 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", | 175 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", |
183 | iv32, key->u.tkip.tx.iv32); | 176 | iv32, ctx->iv32); |
184 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " | 177 | printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " |
185 | "fragmented packet\n"); | 178 | "fragmented packet\n"); |
186 | } | 179 | } |
@@ -189,15 +182,15 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
189 | /* Update the p1k only when the iv16 in the packet wraps around, this | 182 | /* Update the p1k only when the iv16 in the packet wraps around, this |
190 | * might occur after the wrap around of iv16 in the key in case of | 183 | * might occur after the wrap around of iv16 in the key in case of |
191 | * fragmented packets. */ | 184 | * fragmented packets. */ |
192 | if (iv16 == 0 || !key->u.tkip.tx.initialized) | 185 | if (iv16 == 0 || !ctx->initialized) |
193 | tkip_mixing_phase1(key, ta, &key->u.tkip.tx, iv32); | 186 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); |
194 | 187 | ||
195 | if (type == IEEE80211_TKIP_P1_KEY) { | 188 | if (type == IEEE80211_TKIP_P1_KEY) { |
196 | memcpy(outkey, key->u.tkip.tx.p1k, sizeof(u16) * 5); | 189 | memcpy(outkey, ctx->p1k, sizeof(u16) * 5); |
197 | return; | 190 | return; |
198 | } | 191 | } |
199 | 192 | ||
200 | tkip_mixing_phase2(key, &key->u.tkip.tx, iv16, outkey); | 193 | tkip_mixing_phase2(tk, ctx, iv16, outkey); |
201 | } | 194 | } |
202 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 195 | EXPORT_SYMBOL(ieee80211_get_tkip_key); |
203 | 196 | ||
@@ -211,9 +204,16 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
211 | u8 *pos, size_t payload_len, u8 *ta) | 204 | u8 *pos, size_t payload_len, u8 *ta) |
212 | { | 205 | { |
213 | u8 rc4key[16]; | 206 | u8 rc4key[16]; |
207 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
208 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
214 | 209 | ||
215 | ieee80211_tkip_gen_rc4key(key, ta, rc4key); | 210 | /* Calculate per-packet key */ |
216 | pos = ieee80211_tkip_add_iv(pos, key, rc4key[0], rc4key[1], rc4key[2]); | 211 | if (ctx->iv16 == 0 || !ctx->initialized) |
212 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); | ||
213 | |||
214 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); | ||
215 | |||
216 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); | ||
217 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 217 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
218 | } | 218 | } |
219 | 219 | ||
@@ -231,6 +231,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
231 | u32 iv16; | 231 | u32 iv16; |
232 | u8 rc4key[16], keyid, *pos = payload; | 232 | u8 rc4key[16], keyid, *pos = payload; |
233 | int res; | 233 | int res; |
234 | const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; | ||
234 | 235 | ||
235 | if (payload_len < 12) | 236 | if (payload_len < 12) |
236 | return -1; | 237 | return -1; |
@@ -281,7 +282,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
281 | if (!key->u.tkip.rx[queue].initialized || | 282 | if (!key->u.tkip.rx[queue].initialized || |
282 | key->u.tkip.rx[queue].iv32 != iv32) { | 283 | key->u.tkip.rx[queue].iv32 != iv32) { |
283 | /* IV16 wrapped around - perform TKIP phase 1 */ | 284 | /* IV16 wrapped around - perform TKIP phase 1 */ |
284 | tkip_mixing_phase1(key, ta, &key->u.tkip.rx[queue], iv32); | 285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); |
285 | #ifdef CONFIG_TKIP_DEBUG | 286 | #ifdef CONFIG_TKIP_DEBUG |
286 | { | 287 | { |
287 | int i; | 288 | int i; |
@@ -314,7 +315,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
314 | } | 315 | } |
315 | } | 316 | } |
316 | 317 | ||
317 | tkip_mixing_phase2(key, &key->u.tkip.rx[queue], iv16, rc4key); | 318 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); |
318 | #ifdef CONFIG_TKIP_DEBUG | 319 | #ifdef CONFIG_TKIP_DEBUG |
319 | { | 320 | { |
320 | int i; | 321 | int i; |
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index b890427fc959..d4714383f5fc 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
@@ -13,8 +13,8 @@ | |||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | #include "key.h" | 14 | #include "key.h" |
15 | 15 | ||
16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | 16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); |
17 | u8 iv0, u8 iv1, u8 iv2); | 17 | |
18 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | 18 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, |
19 | struct ieee80211_key *key, | 19 | struct ieee80211_key *key, |
20 | u8 *pos, size_t payload_len, u8 *ta); | 20 | u8 *pos, size_t payload_len, u8 *ta); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1ad9e664f287..195cb6dd02a0 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -660,9 +660,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
660 | 660 | ||
661 | /* | 661 | /* |
662 | * Warn when submitting a fragmented A-MPDU frame and drop it. | 662 | * Warn when submitting a fragmented A-MPDU frame and drop it. |
663 | * This is an error and needs to be fixed elsewhere, but when | 663 | * This scenario is handled in __ieee80211_tx_prepare but extra |
664 | * done needs to take care of monitor interfaces (injection) | 664 | * caution taken here as fragmented ampdu may cause Tx stop. |
665 | * etc. | ||
666 | */ | 665 | */ |
667 | if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || | 666 | if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || |
668 | skb_get_queue_mapping(tx->skb) >= | 667 | skb_get_queue_mapping(tx->skb) >= |
@@ -981,7 +980,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
981 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 980 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
982 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 981 | if ((tx->flags & IEEE80211_TX_UNICAST) && |
983 | skb->len + FCS_LEN > local->fragmentation_threshold && | 982 | skb->len + FCS_LEN > local->fragmentation_threshold && |
984 | !local->ops->set_frag_threshold) | 983 | !local->ops->set_frag_threshold && |
984 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | ||
985 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 985 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
986 | else | 986 | else |
987 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 987 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 6513bc2d2707..ce62b163b82c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -45,38 +45,37 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = | |||
45 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 45 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
46 | enum ieee80211_if_types type) | 46 | enum ieee80211_if_types type) |
47 | { | 47 | { |
48 | u16 fc; | 48 | __le16 fc = hdr->frame_control; |
49 | 49 | ||
50 | /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ | 50 | /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ |
51 | if (len < 16) | 51 | if (len < 16) |
52 | return NULL; | 52 | return NULL; |
53 | 53 | ||
54 | fc = le16_to_cpu(hdr->frame_control); | 54 | if (ieee80211_is_data(fc)) { |
55 | |||
56 | switch (fc & IEEE80211_FCTL_FTYPE) { | ||
57 | case IEEE80211_FTYPE_DATA: | ||
58 | if (len < 24) /* drop incorrect hdr len (data) */ | 55 | if (len < 24) /* drop incorrect hdr len (data) */ |
59 | return NULL; | 56 | return NULL; |
60 | switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { | 57 | |
61 | case IEEE80211_FCTL_TODS: | 58 | if (ieee80211_has_a4(fc)) |
62 | return hdr->addr1; | ||
63 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | ||
64 | return NULL; | 59 | return NULL; |
65 | case IEEE80211_FCTL_FROMDS: | 60 | if (ieee80211_has_tods(fc)) |
61 | return hdr->addr1; | ||
62 | if (ieee80211_has_fromds(fc)) | ||
66 | return hdr->addr2; | 63 | return hdr->addr2; |
67 | case 0: | 64 | |
68 | return hdr->addr3; | 65 | return hdr->addr3; |
69 | } | 66 | } |
70 | break; | 67 | |
71 | case IEEE80211_FTYPE_MGMT: | 68 | if (ieee80211_is_mgmt(fc)) { |
72 | if (len < 24) /* drop incorrect hdr len (mgmt) */ | 69 | if (len < 24) /* drop incorrect hdr len (mgmt) */ |
73 | return NULL; | 70 | return NULL; |
74 | return hdr->addr3; | 71 | return hdr->addr3; |
75 | case IEEE80211_FTYPE_CTL: | 72 | } |
76 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL) | 73 | |
74 | if (ieee80211_is_ctl(fc)) { | ||
75 | if(ieee80211_is_pspoll(fc)) | ||
77 | return hdr->addr1; | 76 | return hdr->addr1; |
78 | else if ((fc & IEEE80211_FCTL_STYPE) == | 77 | |
79 | IEEE80211_STYPE_BACK_REQ) { | 78 | if (ieee80211_is_back_req(fc)) { |
80 | switch (type) { | 79 | switch (type) { |
81 | case IEEE80211_IF_TYPE_STA: | 80 | case IEEE80211_IF_TYPE_STA: |
82 | return hdr->addr2; | 81 | return hdr->addr2; |
@@ -84,11 +83,9 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | |||
84 | case IEEE80211_IF_TYPE_VLAN: | 83 | case IEEE80211_IF_TYPE_VLAN: |
85 | return hdr->addr1; | 84 | return hdr->addr1; |
86 | default: | 85 | default: |
87 | return NULL; | 86 | break; /* fall through to the return */ |
88 | } | 87 | } |
89 | } | 88 | } |
90 | else | ||
91 | return NULL; | ||
92 | } | 89 | } |
93 | 90 | ||
94 | return NULL; | 91 | return NULL; |
@@ -133,14 +130,46 @@ int ieee80211_get_hdrlen(u16 fc) | |||
133 | } | 130 | } |
134 | EXPORT_SYMBOL(ieee80211_get_hdrlen); | 131 | EXPORT_SYMBOL(ieee80211_get_hdrlen); |
135 | 132 | ||
136 | int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | 133 | unsigned int ieee80211_hdrlen(__le16 fc) |
134 | { | ||
135 | unsigned int hdrlen = 24; | ||
136 | |||
137 | if (ieee80211_is_data(fc)) { | ||
138 | if (ieee80211_has_a4(fc)) | ||
139 | hdrlen = 30; | ||
140 | if (ieee80211_is_data_qos(fc)) | ||
141 | hdrlen += IEEE80211_QOS_CTL_LEN; | ||
142 | goto out; | ||
143 | } | ||
144 | |||
145 | if (ieee80211_is_ctl(fc)) { | ||
146 | /* | ||
147 | * ACK and CTS are 10 bytes, all others 16. To see how | ||
148 | * to get this condition consider | ||
149 | * subtype mask: 0b0000000011110000 (0x00F0) | ||
150 | * ACK subtype: 0b0000000011010000 (0x00D0) | ||
151 | * CTS subtype: 0b0000000011000000 (0x00C0) | ||
152 | * bits that matter: ^^^ (0x00E0) | ||
153 | * value of those: 0b0000000011000000 (0x00C0) | ||
154 | */ | ||
155 | if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0)) | ||
156 | hdrlen = 10; | ||
157 | else | ||
158 | hdrlen = 16; | ||
159 | } | ||
160 | out: | ||
161 | return hdrlen; | ||
162 | } | ||
163 | EXPORT_SYMBOL(ieee80211_hdrlen); | ||
164 | |||
165 | unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | ||
137 | { | 166 | { |
138 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data; | 167 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; |
139 | int hdrlen; | 168 | unsigned int hdrlen; |
140 | 169 | ||
141 | if (unlikely(skb->len < 10)) | 170 | if (unlikely(skb->len < 10)) |
142 | return 0; | 171 | return 0; |
143 | hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 172 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
144 | if (unlikely(hdrlen > skb->len)) | 173 | if (unlikely(hdrlen > skb->len)) |
145 | return 0; | 174 | return 0; |
146 | return hdrlen; | 175 | return hdrlen; |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 14a9ff10a1e9..d8c2f9688b25 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -105,11 +105,8 @@ static int classify80211(struct sk_buff *skb, struct Qdisc *qd) | |||
105 | { | 105 | { |
106 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 106 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
107 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 107 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
108 | unsigned short fc = le16_to_cpu(hdr->frame_control); | ||
109 | int qos; | ||
110 | 108 | ||
111 | /* see if frame is data or non data frame */ | 109 | if (!ieee80211_is_data(hdr->frame_control)) { |
112 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { | ||
113 | /* management frames go on AC_VO queue, but are sent | 110 | /* management frames go on AC_VO queue, but are sent |
114 | * without QoS control fields */ | 111 | * without QoS control fields */ |
115 | return 0; | 112 | return 0; |
@@ -119,10 +116,7 @@ static int classify80211(struct sk_buff *skb, struct Qdisc *qd) | |||
119 | /* use AC from radiotap */ | 116 | /* use AC from radiotap */ |
120 | } | 117 | } |
121 | 118 | ||
122 | /* is this a QoS frame? */ | 119 | if (!ieee80211_is_data_qos(hdr->frame_control)) { |
123 | qos = fc & IEEE80211_STYPE_QOS_DATA; | ||
124 | |||
125 | if (!qos) { | ||
126 | skb->priority = 0; /* required for correct WPA/11i MIC */ | 120 | skb->priority = 0; /* required for correct WPA/11i MIC */ |
127 | return ieee802_1d_to_ac[skb->priority]; | 121 | return ieee802_1d_to_ac[skb->priority]; |
128 | } | 122 | } |
@@ -151,7 +145,6 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
151 | struct ieee80211_sched_data *q = qdisc_priv(qd); | 145 | struct ieee80211_sched_data *q = qdisc_priv(qd); |
152 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 146 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
153 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 147 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
154 | unsigned short fc = le16_to_cpu(hdr->frame_control); | ||
155 | struct Qdisc *qdisc; | 148 | struct Qdisc *qdisc; |
156 | struct sta_info *sta; | 149 | struct sta_info *sta; |
157 | int err, queue; | 150 | int err, queue; |
@@ -185,16 +178,15 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
185 | 178 | ||
186 | /* now we know the 1d priority, fill in the QoS header if there is one | 179 | /* now we know the 1d priority, fill in the QoS header if there is one |
187 | */ | 180 | */ |
188 | if (WLAN_FC_IS_QOS_DATA(fc)) { | 181 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
189 | u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; | 182 | u8 *p = ieee80211_get_qos_ctl(hdr); |
190 | u8 ack_policy = 0; | 183 | u8 ack_policy = 0; |
191 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 184 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; |
192 | if (local->wifi_wme_noack_test) | 185 | if (local->wifi_wme_noack_test) |
193 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << | 186 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << |
194 | QOS_CONTROL_ACK_POLICY_SHIFT; | 187 | QOS_CONTROL_ACK_POLICY_SHIFT; |
195 | /* qos header is 2 bytes, second reserved */ | 188 | /* qos header is 2 bytes, second reserved */ |
196 | *p = ack_policy | tid; | 189 | *p++ = ack_policy | tid; |
197 | p++; | ||
198 | *p = 0; | 190 | *p = 0; |
199 | 191 | ||
200 | rcu_read_lock(); | 192 | rcu_read_lock(); |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 9f6fd20374e1..345e10e9b313 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -24,46 +24,22 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | |||
24 | { | 24 | { |
25 | struct ieee80211_hdr *hdr; | 25 | struct ieee80211_hdr *hdr; |
26 | size_t hdrlen; | 26 | size_t hdrlen; |
27 | u16 fc; | 27 | __le16 fc; |
28 | int a4_included; | ||
29 | u8 *pos; | ||
30 | 28 | ||
31 | hdr = (struct ieee80211_hdr *) skb->data; | 29 | hdr = (struct ieee80211_hdr *)skb->data; |
32 | fc = le16_to_cpu(hdr->frame_control); | 30 | fc = hdr->frame_control; |
33 | |||
34 | hdrlen = 24; | ||
35 | if ((fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) == | ||
36 | (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { | ||
37 | hdrlen += ETH_ALEN; | ||
38 | *sa = hdr->addr4; | ||
39 | *da = hdr->addr3; | ||
40 | } else if (fc & IEEE80211_FCTL_FROMDS) { | ||
41 | *sa = hdr->addr3; | ||
42 | *da = hdr->addr1; | ||
43 | } else if (fc & IEEE80211_FCTL_TODS) { | ||
44 | *sa = hdr->addr2; | ||
45 | *da = hdr->addr3; | ||
46 | } else { | ||
47 | *sa = hdr->addr2; | ||
48 | *da = hdr->addr1; | ||
49 | } | ||
50 | 31 | ||
51 | if (fc & 0x80) | 32 | hdrlen = ieee80211_hdrlen(fc); |
52 | hdrlen += 2; | 33 | |
34 | *sa = ieee80211_get_SA(hdr); | ||
35 | *da = ieee80211_get_DA(hdr); | ||
53 | 36 | ||
54 | *data = skb->data + hdrlen; | 37 | *data = skb->data + hdrlen; |
55 | *data_len = skb->len - hdrlen; | 38 | *data_len = skb->len - hdrlen; |
56 | 39 | ||
57 | a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 40 | if (ieee80211_is_data_qos(fc)) |
58 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 41 | *qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80; |
59 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 42 | else |
60 | fc & IEEE80211_STYPE_QOS_DATA) { | ||
61 | pos = (u8 *) &hdr->addr4; | ||
62 | if (a4_included) | ||
63 | pos += 6; | ||
64 | *qos_tid = pos[0] & 0x0f; | ||
65 | *qos_tid |= 0x80; /* qos_included flag */ | ||
66 | } else | ||
67 | *qos_tid = 0; | 43 | *qos_tid = 0; |
68 | 44 | ||
69 | return skb->len < hdrlen ? -1 : 0; | 45 | return skb->len < hdrlen ? -1 : 0; |
@@ -186,8 +162,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
186 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 162 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
187 | struct ieee80211_key *key = tx->key; | 163 | struct ieee80211_key *key = tx->key; |
188 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 164 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
189 | int hdrlen, len, tail; | 165 | unsigned int hdrlen; |
190 | u16 fc; | 166 | int len, tail; |
191 | u8 *pos; | 167 | u8 *pos; |
192 | 168 | ||
193 | info->control.icv_len = TKIP_ICV_LEN; | 169 | info->control.icv_len = TKIP_ICV_LEN; |
@@ -200,8 +176,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
200 | return 0; | 176 | return 0; |
201 | } | 177 | } |
202 | 178 | ||
203 | fc = le16_to_cpu(hdr->frame_control); | 179 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
204 | hdrlen = ieee80211_get_hdrlen(fc); | ||
205 | len = skb->len - hdrlen; | 180 | len = skb->len - hdrlen; |
206 | 181 | ||
207 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 182 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
@@ -223,14 +198,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
223 | key->u.tkip.tx.iv32++; | 198 | key->u.tkip.tx.iv32++; |
224 | 199 | ||
225 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 200 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
226 | hdr = (struct ieee80211_hdr *)skb->data; | ||
227 | |||
228 | /* hwaccel - with preallocated room for IV */ | 201 | /* hwaccel - with preallocated room for IV */ |
229 | ieee80211_tkip_add_iv(pos, key, | 202 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
230 | (u8) (key->u.tkip.tx.iv16 >> 8), | ||
231 | (u8) (((key->u.tkip.tx.iv16 >> 8) | 0x20) & | ||
232 | 0x7f), | ||
233 | (u8) key->u.tkip.tx.iv16); | ||
234 | 203 | ||
235 | info->control.hw_key = &tx->key->conf; | 204 | info->control.hw_key = &tx->key->conf; |
236 | return 0; | 205 | return 0; |
@@ -272,14 +241,12 @@ ieee80211_rx_result | |||
272 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | 241 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) |
273 | { | 242 | { |
274 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 243 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
275 | u16 fc; | ||
276 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 244 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
277 | struct ieee80211_key *key = rx->key; | 245 | struct ieee80211_key *key = rx->key; |
278 | struct sk_buff *skb = rx->skb; | 246 | struct sk_buff *skb = rx->skb; |
279 | DECLARE_MAC_BUF(mac); | 247 | DECLARE_MAC_BUF(mac); |
280 | 248 | ||
281 | fc = le16_to_cpu(hdr->frame_control); | 249 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
282 | hdrlen = ieee80211_get_hdrlen(fc); | ||
283 | 250 | ||
284 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 251 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
285 | return RX_CONTINUE; | 252 | return RX_CONTINUE; |
@@ -427,7 +394,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
427 | struct ieee80211_key *key = tx->key; | 394 | struct ieee80211_key *key = tx->key; |
428 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 395 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
429 | int hdrlen, len, tail; | 396 | int hdrlen, len, tail; |
430 | u16 fc; | ||
431 | u8 *pos, *pn, *b_0, *aad, *scratch; | 397 | u8 *pos, *pn, *b_0, *aad, *scratch; |
432 | int i; | 398 | int i; |
433 | 399 | ||
@@ -446,8 +412,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
446 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 412 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
447 | aad = scratch + 4 * AES_BLOCK_LEN; | 413 | aad = scratch + 4 * AES_BLOCK_LEN; |
448 | 414 | ||
449 | fc = le16_to_cpu(hdr->frame_control); | 415 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
450 | hdrlen = ieee80211_get_hdrlen(fc); | ||
451 | len = skb->len - hdrlen; | 416 | len = skb->len - hdrlen; |
452 | 417 | ||
453 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 418 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
@@ -516,7 +481,6 @@ ieee80211_rx_result | |||
516 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | 481 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) |
517 | { | 482 | { |
518 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 483 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
519 | u16 fc; | ||
520 | int hdrlen; | 484 | int hdrlen; |
521 | struct ieee80211_key *key = rx->key; | 485 | struct ieee80211_key *key = rx->key; |
522 | struct sk_buff *skb = rx->skb; | 486 | struct sk_buff *skb = rx->skb; |
@@ -524,8 +488,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
524 | int data_len; | 488 | int data_len; |
525 | DECLARE_MAC_BUF(mac); | 489 | DECLARE_MAC_BUF(mac); |
526 | 490 | ||
527 | fc = le16_to_cpu(hdr->frame_control); | 491 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
528 | hdrlen = ieee80211_get_hdrlen(fc); | ||
529 | 492 | ||
530 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 493 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
531 | return RX_CONTINUE; | 494 | return RX_CONTINUE; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 185488da2466..855bff4b3250 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -80,6 +80,23 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | |||
80 | IEEE80211_CHAN_RADAR), | 80 | IEEE80211_CHAN_RADAR), |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static const struct ieee80211_channel_range ieee80211_EU_channels[] = { | ||
84 | /* IEEE 802.11b/g, channels 1..13 */ | ||
85 | RANGE_PWR(2412, 2472, 20, 6, 0), | ||
86 | /* IEEE 802.11a, channel 36*/ | ||
87 | RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
88 | /* IEEE 802.11a, channel 40*/ | ||
89 | RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
90 | /* IEEE 802.11a, channel 44*/ | ||
91 | RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), | ||
92 | /* IEEE 802.11a, channels 48..64 */ | ||
93 | RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS | | ||
94 | IEEE80211_CHAN_RADAR), | ||
95 | /* IEEE 802.11a, channels 100..140 */ | ||
96 | RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS | | ||
97 | IEEE80211_CHAN_RADAR), | ||
98 | }; | ||
99 | |||
83 | #define REGDOM(_code) \ | 100 | #define REGDOM(_code) \ |
84 | { \ | 101 | { \ |
85 | .code = __stringify(_code), \ | 102 | .code = __stringify(_code), \ |
@@ -90,6 +107,7 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { | |||
90 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { | 107 | static const struct ieee80211_regdomain ieee80211_regdoms[] = { |
91 | REGDOM(US), | 108 | REGDOM(US), |
92 | REGDOM(JP), | 109 | REGDOM(JP), |
110 | REGDOM(EU), | ||
93 | }; | 111 | }; |
94 | 112 | ||
95 | 113 | ||