diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-07-25 05:37:07 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-07-25 05:37:07 -0400 |
| commit | 0e2f65ee30eee2db054f7fd73f462c5da33ec963 (patch) | |
| tree | 26c61eb7745da0c0d9135e9d12088f570cb8530d /net/mac80211 | |
| parent | da7878d75b8520c9ae00d27dfbbce546a7bfdfbb (diff) | |
| parent | fb2e405fc1fc8b20d9c78eaa1c7fd5a297efde43 (diff) | |
Merge branch 'linus' into x86/pebs
Conflicts:
arch/x86/Kconfig.cpu
arch/x86/kernel/cpu/intel.c
arch/x86/kernel/setup_64.c
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'net/mac80211')
41 files changed, 3212 insertions, 3861 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index a24b459dd45a..80d693392b0f 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
| @@ -7,7 +7,6 @@ config MAC80211 | |||
| 7 | select CRC32 | 7 | select CRC32 |
| 8 | select WIRELESS_EXT | 8 | select WIRELESS_EXT |
| 9 | select CFG80211 | 9 | select CFG80211 |
| 10 | select NET_SCH_FIFO | ||
| 11 | ---help--- | 10 | ---help--- |
| 12 | This option enables the hardware independent IEEE 802.11 | 11 | This option enables the hardware independent IEEE 802.11 |
| 13 | networking stack. | 12 | networking stack. |
| @@ -15,6 +14,14 @@ config MAC80211 | |||
| 15 | menu "Rate control algorithm selection" | 14 | menu "Rate control algorithm selection" |
| 16 | depends on MAC80211 != n | 15 | depends on MAC80211 != n |
| 17 | 16 | ||
| 17 | config MAC80211_RC_PID | ||
| 18 | bool "PID controller based rate control algorithm" if EMBEDDED | ||
| 19 | default y | ||
| 20 | ---help--- | ||
| 21 | This option enables a TX rate control algorithm for | ||
| 22 | mac80211 that uses a PID controller to select the TX | ||
| 23 | rate. | ||
| 24 | |||
| 18 | choice | 25 | choice |
| 19 | prompt "Default rate control algorithm" | 26 | prompt "Default rate control algorithm" |
| 20 | default MAC80211_RC_DEFAULT_PID | 27 | default MAC80211_RC_DEFAULT_PID |
| @@ -26,40 +33,19 @@ choice | |||
| 26 | 33 | ||
| 27 | config MAC80211_RC_DEFAULT_PID | 34 | config MAC80211_RC_DEFAULT_PID |
| 28 | bool "PID controller based rate control algorithm" | 35 | bool "PID controller based rate control algorithm" |
| 29 | select MAC80211_RC_PID | 36 | depends on MAC80211_RC_PID |
| 30 | ---help--- | 37 | ---help--- |
| 31 | Select the PID controller based rate control as the | 38 | Select the PID controller based rate control as the |
| 32 | default rate control algorithm. You should choose | 39 | default rate control algorithm. You should choose |
| 33 | this unless you know what you are doing. | 40 | this unless you know what you are doing. |
| 34 | 41 | ||
| 35 | config MAC80211_RC_DEFAULT_NONE | ||
| 36 | bool "No default algorithm" | ||
| 37 | depends on EMBEDDED | ||
| 38 | help | ||
| 39 | Selecting this option will select no default algorithm | ||
| 40 | and allow you to not build any. Do not choose this | ||
| 41 | option unless you know your driver comes with another | ||
| 42 | suitable algorithm. | ||
| 43 | endchoice | 42 | endchoice |
| 44 | 43 | ||
| 45 | comment "Selecting 'y' for an algorithm will" | ||
| 46 | comment "build the algorithm into mac80211." | ||
| 47 | |||
| 48 | config MAC80211_RC_DEFAULT | 44 | config MAC80211_RC_DEFAULT |
| 49 | string | 45 | string |
| 50 | default "pid" if MAC80211_RC_DEFAULT_PID | 46 | default "pid" if MAC80211_RC_DEFAULT_PID |
| 51 | default "" | 47 | default "" |
| 52 | 48 | ||
| 53 | config MAC80211_RC_PID | ||
| 54 | tristate "PID controller based rate control algorithm" | ||
| 55 | ---help--- | ||
| 56 | This option enables a TX rate control algorithm for | ||
| 57 | mac80211 that uses a PID controller to select the TX | ||
| 58 | rate. | ||
| 59 | |||
| 60 | Say Y or M unless you're sure you want to use a | ||
| 61 | different rate control algorithm. | ||
| 62 | |||
| 63 | endmenu | 49 | endmenu |
| 64 | 50 | ||
| 65 | config MAC80211_MESH | 51 | config MAC80211_MESH |
| @@ -89,10 +75,16 @@ config MAC80211_DEBUGFS | |||
| 89 | 75 | ||
| 90 | Say N unless you know you need this. | 76 | Say N unless you know you need this. |
| 91 | 77 | ||
| 78 | menuconfig MAC80211_DEBUG_MENU | ||
| 79 | bool "Select mac80211 debugging features" | ||
| 80 | depends on MAC80211 | ||
| 81 | ---help--- | ||
| 82 | This option collects various mac80211 debug settings. | ||
| 83 | |||
| 92 | config MAC80211_DEBUG_PACKET_ALIGNMENT | 84 | config MAC80211_DEBUG_PACKET_ALIGNMENT |
| 93 | bool "Enable packet alignment debugging" | 85 | bool "Enable packet alignment debugging" |
| 94 | depends on MAC80211 | 86 | depends on MAC80211_DEBUG_MENU |
| 95 | help | 87 | ---help--- |
| 96 | This option is recommended for driver authors and strongly | 88 | This option is recommended for driver authors and strongly |
| 97 | discouraged for everybody else, it will trigger a warning | 89 | discouraged for everybody else, it will trigger a warning |
| 98 | when a driver hands mac80211 a buffer that is aligned in | 90 | when a driver hands mac80211 a buffer that is aligned in |
| @@ -101,33 +93,95 @@ config MAC80211_DEBUG_PACKET_ALIGNMENT | |||
| 101 | 93 | ||
| 102 | Say N unless you're writing a mac80211 based driver. | 94 | Say N unless you're writing a mac80211 based driver. |
| 103 | 95 | ||
| 104 | config MAC80211_DEBUG | 96 | config MAC80211_NOINLINE |
| 105 | bool "Enable debugging output" | 97 | bool "Do not inline TX/RX handlers" |
| 106 | depends on MAC80211 | 98 | depends on MAC80211_DEBUG_MENU |
| 107 | ---help--- | 99 | ---help--- |
| 108 | This option will enable debug tracing output for the | 100 | This option affects code generation in mac80211, when |
| 109 | ieee80211 network stack. | 101 | selected some functions are marked "noinline" to allow |
| 102 | easier debugging of problems in the transmit and receive | ||
| 103 | paths. | ||
| 104 | |||
| 105 | This option increases code size a bit and inserts a lot | ||
| 106 | of function calls in the code, but is otherwise safe to | ||
| 107 | enable. | ||
| 110 | 108 | ||
| 111 | If you are not trying to debug or develop the ieee80211 | 109 | If unsure, say N unless you expect to be finding problems |
| 112 | subsystem, you most likely want to say N here. | 110 | in mac80211. |
| 111 | |||
| 112 | config MAC80211_VERBOSE_DEBUG | ||
| 113 | bool "Verbose debugging output" | ||
| 114 | depends on MAC80211_DEBUG_MENU | ||
| 115 | ---help--- | ||
| 116 | Selecting this option causes mac80211 to print out | ||
| 117 | many debugging messages. It should not be selected | ||
| 118 | on production systems as some of the messages are | ||
| 119 | remotely triggerable. | ||
| 120 | |||
| 121 | Do not select this option. | ||
| 113 | 122 | ||
| 114 | config MAC80211_HT_DEBUG | 123 | config MAC80211_HT_DEBUG |
| 115 | bool "Enable HT debugging output" | 124 | bool "Verbose HT debugging" |
| 116 | depends on MAC80211_DEBUG | 125 | depends on MAC80211_DEBUG_MENU |
| 117 | ---help--- | 126 | ---help--- |
| 118 | This option enables 802.11n High Throughput features | 127 | This option enables 802.11n High Throughput features |
| 119 | debug tracing output. | 128 | debug tracing output. |
| 120 | 129 | ||
| 121 | If you are not trying to debug of develop the ieee80211 | 130 | It should not be selected on production systems as some |
| 122 | subsystem, you most likely want to say N here. | 131 | of the messages are remotely triggerable. |
| 123 | 132 | ||
| 124 | config MAC80211_VERBOSE_DEBUG | 133 | Do not select this option. |
| 125 | bool "Verbose debugging output" | 134 | |
| 126 | depends on MAC80211_DEBUG | 135 | config MAC80211_TKIP_DEBUG |
| 136 | bool "Verbose TKIP debugging" | ||
| 137 | depends on MAC80211_DEBUG_MENU | ||
| 138 | ---help--- | ||
| 139 | Selecting this option causes mac80211 to print out | ||
| 140 | very verbose TKIP debugging messages. It should not | ||
| 141 | be selected on production systems as those messages | ||
| 142 | are remotely triggerable. | ||
| 143 | |||
| 144 | Do not select this option. | ||
| 145 | |||
| 146 | config MAC80211_IBSS_DEBUG | ||
| 147 | bool "Verbose IBSS debugging" | ||
| 148 | depends on MAC80211_DEBUG_MENU | ||
| 149 | ---help--- | ||
| 150 | Selecting this option causes mac80211 to print out | ||
| 151 | very verbose IBSS debugging messages. It should not | ||
| 152 | be selected on production systems as those messages | ||
| 153 | are remotely triggerable. | ||
| 154 | |||
| 155 | Do not select this option. | ||
| 156 | |||
| 157 | config MAC80211_VERBOSE_PS_DEBUG | ||
| 158 | bool "Verbose powersave mode debugging" | ||
| 159 | depends on MAC80211_DEBUG_MENU | ||
| 160 | ---help--- | ||
| 161 | Selecting this option causes mac80211 to print out very | ||
| 162 | verbose power save mode debugging messages (when mac80211 | ||
| 163 | is an AP and has power saving stations.) | ||
| 164 | It should not be selected on production systems as those | ||
| 165 | messages are remotely triggerable. | ||
| 166 | |||
| 167 | Do not select this option. | ||
| 168 | |||
| 169 | config MAC80211_VERBOSE_MPL_DEBUG | ||
| 170 | bool "Verbose mesh peer link debugging" | ||
| 171 | depends on MAC80211_DEBUG_MENU | ||
| 172 | depends on MAC80211_MESH | ||
| 173 | ---help--- | ||
| 174 | Selecting this option causes mac80211 to print out very | ||
| 175 | verbose mesh peer link debugging messages (when mac80211 | ||
| 176 | is taking part in a mesh network). | ||
| 177 | It should not be selected on production systems as those | ||
| 178 | messages are remotely triggerable. | ||
| 179 | |||
| 180 | Do not select this option. | ||
| 127 | 181 | ||
| 128 | config MAC80211_LOWTX_FRAME_DUMP | 182 | config MAC80211_LOWTX_FRAME_DUMP |
| 129 | bool "Debug frame dumping" | 183 | bool "Debug frame dumping" |
| 130 | depends on MAC80211_DEBUG | 184 | depends on MAC80211_DEBUG_MENU |
| 131 | ---help--- | 185 | ---help--- |
| 132 | Selecting this option will cause the stack to | 186 | Selecting this option will cause the stack to |
| 133 | print a message for each frame that is handed | 187 | print a message for each frame that is handed |
| @@ -138,30 +192,20 @@ config MAC80211_LOWTX_FRAME_DUMP | |||
| 138 | If unsure, say N and insert the debugging code | 192 | If unsure, say N and insert the debugging code |
| 139 | you require into the driver you are debugging. | 193 | you require into the driver you are debugging. |
| 140 | 194 | ||
| 141 | config TKIP_DEBUG | ||
| 142 | bool "TKIP debugging" | ||
| 143 | depends on MAC80211_DEBUG | ||
| 144 | |||
| 145 | config MAC80211_DEBUG_COUNTERS | 195 | config MAC80211_DEBUG_COUNTERS |
| 146 | bool "Extra statistics for TX/RX debugging" | 196 | bool "Extra statistics for TX/RX debugging" |
| 147 | depends on MAC80211_DEBUG | 197 | depends on MAC80211_DEBUG_MENU |
| 148 | 198 | depends on MAC80211_DEBUGFS | |
| 149 | config MAC80211_IBSS_DEBUG | ||
| 150 | bool "Support for IBSS testing" | ||
| 151 | depends on MAC80211_DEBUG | ||
| 152 | ---help--- | 199 | ---help--- |
| 153 | Say Y here if you intend to debug the IBSS code. | 200 | Selecting this option causes mac80211 to keep additional |
| 201 | and very verbose statistics about TX and RX handler use | ||
| 202 | and show them in debugfs. | ||
| 154 | 203 | ||
| 155 | config MAC80211_VERBOSE_PS_DEBUG | 204 | If unsure, say N. |
| 156 | bool "Verbose powersave mode debugging" | ||
| 157 | depends on MAC80211_DEBUG | ||
| 158 | ---help--- | ||
| 159 | Say Y here to print out verbose powersave | ||
| 160 | mode debug messages. | ||
| 161 | 205 | ||
| 162 | config MAC80211_VERBOSE_MPL_DEBUG | 206 | config MAC80211_VERBOSE_SPECT_MGMT_DEBUG |
| 163 | bool "Verbose mesh peer link debugging" | 207 | bool "Verbose Spectrum Management (IEEE 802.11h)debugging" |
| 164 | depends on MAC80211_DEBUG && MAC80211_MESH | 208 | depends on MAC80211_DEBUG_MENU |
| 165 | ---help--- | 209 | ---help--- |
| 166 | Say Y here to print out verbose mesh peer link | 210 | Say Y here to print out verbose Spectrum Management (IEEE 802.11h) |
| 167 | debug messages. | 211 | debug messages. |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 4e5847fd316c..a169b0201d61 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
| @@ -1,13 +1,5 @@ | |||
| 1 | obj-$(CONFIG_MAC80211) += mac80211.o | 1 | obj-$(CONFIG_MAC80211) += mac80211.o |
| 2 | 2 | ||
| 3 | # objects for PID algorithm | ||
| 4 | rc80211_pid-y := rc80211_pid_algo.o | ||
| 5 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
| 6 | |||
| 7 | # build helper for PID algorithm | ||
| 8 | rc-pid-y := $(rc80211_pid-y) | ||
| 9 | rc-pid-m := rc80211_pid.o | ||
| 10 | |||
| 11 | # mac80211 objects | 3 | # mac80211 objects |
| 12 | mac80211-y := \ | 4 | mac80211-y := \ |
| 13 | main.o \ | 5 | main.o \ |
| @@ -26,10 +18,10 @@ mac80211-y := \ | |||
| 26 | tx.o \ | 18 | tx.o \ |
| 27 | key.o \ | 19 | key.o \ |
| 28 | util.o \ | 20 | util.o \ |
| 21 | wme.o \ | ||
| 29 | event.o | 22 | event.o |
| 30 | 23 | ||
| 31 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o | 24 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o |
| 32 | mac80211-$(CONFIG_NET_SCHED) += wme.o | ||
| 33 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ | 25 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ |
| 34 | debugfs.o \ | 26 | debugfs.o \ |
| 35 | debugfs_sta.o \ | 27 | debugfs_sta.o \ |
| @@ -42,10 +34,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ | |||
| 42 | mesh_plink.o \ | 34 | mesh_plink.o \ |
| 43 | mesh_hwmp.o | 35 | mesh_hwmp.o |
| 44 | 36 | ||
| 37 | # objects for PID algorithm | ||
| 38 | rc80211_pid-y := rc80211_pid_algo.o | ||
| 39 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
| 45 | 40 | ||
| 46 | # Build rate control algorithm(s) | 41 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) |
| 47 | CFLAGS_rc80211_pid_algo.o += -DRC80211_PID_COMPILE | ||
| 48 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc-pid-$(CONFIG_MAC80211_RC_PID)) | ||
| 49 | |||
| 50 | # Modular rate algorithms are assigned to mac80211-m - make separate modules | ||
| 51 | obj-m += $(mac80211-m) | ||
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 59f1691f62c8..a87cb3ba2df6 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
| @@ -16,31 +16,28 @@ | |||
| 16 | #include "key.h" | 16 | #include "key.h" |
| 17 | #include "aes_ccm.h" | 17 | #include "aes_ccm.h" |
| 18 | 18 | ||
| 19 | 19 | static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a) | |
| 20 | static void ieee80211_aes_encrypt(struct crypto_cipher *tfm, | ||
| 21 | const u8 pt[16], u8 ct[16]) | ||
| 22 | { | ||
| 23 | crypto_cipher_encrypt_one(tfm, ct, pt); | ||
| 24 | } | ||
| 25 | |||
| 26 | |||
| 27 | static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, | ||
| 28 | u8 *b, u8 *s_0, u8 *a) | ||
| 29 | { | 20 | { |
| 30 | int i; | 21 | int i; |
| 22 | u8 *b_0, *aad, *b, *s_0; | ||
| 31 | 23 | ||
| 32 | ieee80211_aes_encrypt(tfm, b_0, b); | 24 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
| 25 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
| 26 | b = scratch; | ||
| 27 | s_0 = scratch + AES_BLOCK_LEN; | ||
| 28 | |||
| 29 | crypto_cipher_encrypt_one(tfm, b, b_0); | ||
| 33 | 30 | ||
| 34 | /* Extra Authenticate-only data (always two AES blocks) */ | 31 | /* Extra Authenticate-only data (always two AES blocks) */ |
| 35 | for (i = 0; i < AES_BLOCK_LEN; i++) | 32 | for (i = 0; i < AES_BLOCK_LEN; i++) |
| 36 | aad[i] ^= b[i]; | 33 | aad[i] ^= b[i]; |
| 37 | ieee80211_aes_encrypt(tfm, aad, b); | 34 | crypto_cipher_encrypt_one(tfm, b, aad); |
| 38 | 35 | ||
| 39 | aad += AES_BLOCK_LEN; | 36 | aad += AES_BLOCK_LEN; |
| 40 | 37 | ||
| 41 | for (i = 0; i < AES_BLOCK_LEN; i++) | 38 | for (i = 0; i < AES_BLOCK_LEN; i++) |
| 42 | aad[i] ^= b[i]; | 39 | aad[i] ^= b[i]; |
| 43 | ieee80211_aes_encrypt(tfm, aad, a); | 40 | crypto_cipher_encrypt_one(tfm, a, aad); |
| 44 | 41 | ||
| 45 | /* Mask out bits from auth-only-b_0 */ | 42 | /* Mask out bits from auth-only-b_0 */ |
| 46 | b_0[0] &= 0x07; | 43 | b_0[0] &= 0x07; |
| @@ -48,24 +45,26 @@ static inline void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, | |||
| 48 | /* S_0 is used to encrypt T (= MIC) */ | 45 | /* S_0 is used to encrypt T (= MIC) */ |
| 49 | b_0[14] = 0; | 46 | b_0[14] = 0; |
| 50 | b_0[15] = 0; | 47 | b_0[15] = 0; |
| 51 | ieee80211_aes_encrypt(tfm, b_0, s_0); | 48 | crypto_cipher_encrypt_one(tfm, s_0, b_0); |
| 52 | } | 49 | } |
| 53 | 50 | ||
| 54 | 51 | ||
| 55 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 52 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, |
| 56 | u8 *b_0, u8 *aad, u8 *data, size_t data_len, | 53 | u8 *data, size_t data_len, |
| 57 | u8 *cdata, u8 *mic) | 54 | u8 *cdata, u8 *mic) |
| 58 | { | 55 | { |
| 59 | int i, j, last_len, num_blocks; | 56 | int i, j, last_len, num_blocks; |
| 60 | u8 *pos, *cpos, *b, *s_0, *e; | 57 | u8 *pos, *cpos, *b, *s_0, *e, *b_0, *aad; |
| 61 | 58 | ||
| 62 | b = scratch; | 59 | b = scratch; |
| 63 | s_0 = scratch + AES_BLOCK_LEN; | 60 | s_0 = scratch + AES_BLOCK_LEN; |
| 64 | e = scratch + 2 * AES_BLOCK_LEN; | 61 | e = scratch + 2 * AES_BLOCK_LEN; |
| 62 | b_0 = scratch + 3 * AES_BLOCK_LEN; | ||
| 63 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
| 65 | 64 | ||
| 66 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 65 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); |
| 67 | last_len = data_len % AES_BLOCK_LEN; | 66 | last_len = data_len % AES_BLOCK_LEN; |
| 68 | aes_ccm_prepare(tfm, b_0, aad, b, s_0, b); | 67 | aes_ccm_prepare(tfm, scratch, b); |
| 69 | 68 | ||
| 70 | /* Process payload blocks */ | 69 | /* Process payload blocks */ |
| 71 | pos = data; | 70 | pos = data; |
| @@ -77,11 +76,11 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
| 77 | /* Authentication followed by encryption */ | 76 | /* Authentication followed by encryption */ |
| 78 | for (i = 0; i < blen; i++) | 77 | for (i = 0; i < blen; i++) |
| 79 | b[i] ^= pos[i]; | 78 | b[i] ^= pos[i]; |
| 80 | ieee80211_aes_encrypt(tfm, b, b); | 79 | crypto_cipher_encrypt_one(tfm, b, b); |
| 81 | 80 | ||
| 82 | b_0[14] = (j >> 8) & 0xff; | 81 | b_0[14] = (j >> 8) & 0xff; |
| 83 | b_0[15] = j & 0xff; | 82 | b_0[15] = j & 0xff; |
| 84 | ieee80211_aes_encrypt(tfm, b_0, e); | 83 | crypto_cipher_encrypt_one(tfm, e, b_0); |
| 85 | for (i = 0; i < blen; i++) | 84 | for (i = 0; i < blen; i++) |
| 86 | *cpos++ = *pos++ ^ e[i]; | 85 | *cpos++ = *pos++ ^ e[i]; |
| 87 | } | 86 | } |
| @@ -92,19 +91,20 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
| 92 | 91 | ||
| 93 | 92 | ||
| 94 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | 93 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, |
| 95 | u8 *b_0, u8 *aad, u8 *cdata, size_t data_len, | 94 | u8 *cdata, size_t data_len, u8 *mic, u8 *data) |
| 96 | u8 *mic, u8 *data) | ||
| 97 | { | 95 | { |
| 98 | int i, j, last_len, num_blocks; | 96 | int i, j, last_len, num_blocks; |
| 99 | u8 *pos, *cpos, *b, *s_0, *a; | 97 | u8 *pos, *cpos, *b, *s_0, *a, *b_0, *aad; |
| 100 | 98 | ||
| 101 | b = scratch; | 99 | b = scratch; |
| 102 | s_0 = scratch + AES_BLOCK_LEN; | 100 | s_0 = scratch + AES_BLOCK_LEN; |
| 103 | a = scratch + 2 * AES_BLOCK_LEN; | 101 | a = scratch + 2 * AES_BLOCK_LEN; |
| 102 | b_0 = scratch + 3 * AES_BLOCK_LEN; | ||
| 103 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
| 104 | 104 | ||
| 105 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); | 105 | num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); |
| 106 | last_len = data_len % AES_BLOCK_LEN; | 106 | last_len = data_len % AES_BLOCK_LEN; |
| 107 | aes_ccm_prepare(tfm, b_0, aad, b, s_0, a); | 107 | aes_ccm_prepare(tfm, scratch, a); |
| 108 | 108 | ||
| 109 | /* Process payload blocks */ | 109 | /* Process payload blocks */ |
| 110 | cpos = cdata; | 110 | cpos = cdata; |
| @@ -116,13 +116,12 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
| 116 | /* Decryption followed by authentication */ | 116 | /* Decryption followed by authentication */ |
| 117 | b_0[14] = (j >> 8) & 0xff; | 117 | b_0[14] = (j >> 8) & 0xff; |
| 118 | b_0[15] = j & 0xff; | 118 | b_0[15] = j & 0xff; |
| 119 | ieee80211_aes_encrypt(tfm, b_0, b); | 119 | crypto_cipher_encrypt_one(tfm, b, b_0); |
| 120 | for (i = 0; i < blen; i++) { | 120 | for (i = 0; i < blen; i++) { |
| 121 | *pos = *cpos++ ^ b[i]; | 121 | *pos = *cpos++ ^ b[i]; |
| 122 | a[i] ^= *pos++; | 122 | a[i] ^= *pos++; |
| 123 | } | 123 | } |
| 124 | 124 | crypto_cipher_encrypt_one(tfm, a, a); | |
| 125 | ieee80211_aes_encrypt(tfm, a, a); | ||
| 126 | } | 125 | } |
| 127 | 126 | ||
| 128 | for (i = 0; i < CCMP_MIC_LEN; i++) { | 127 | for (i = 0; i < CCMP_MIC_LEN; i++) { |
| @@ -134,7 +133,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | 135 | ||
| 137 | struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]) | 136 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) |
| 138 | { | 137 | { |
| 139 | struct crypto_cipher *tfm; | 138 | struct crypto_cipher *tfm; |
| 140 | 139 | ||
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h index 885f19030b29..6e7820ef3448 100644 --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h | |||
| @@ -14,12 +14,12 @@ | |||
| 14 | 14 | ||
| 15 | #define AES_BLOCK_LEN 16 | 15 | #define AES_BLOCK_LEN 16 |
| 16 | 16 | ||
| 17 | struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]); | 17 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); |
| 18 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 18 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, |
| 19 | u8 *b_0, u8 *aad, u8 *data, size_t data_len, | 19 | u8 *data, size_t data_len, |
| 20 | u8 *cdata, u8 *mic); | 20 | u8 *cdata, u8 *mic); |
| 21 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | 21 | int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, |
| 22 | u8 *b_0, u8 *aad, u8 *cdata, size_t data_len, | 22 | u8 *cdata, size_t data_len, |
| 23 | u8 *mic, u8 *data); | 23 | u8 *mic, u8 *data); |
| 24 | void ieee80211_aes_key_free(struct crypto_cipher *tfm); | 24 | void ieee80211_aes_key_free(struct crypto_cipher *tfm); |
| 25 | 25 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9fce4afdf21..8e7ba0e62cf5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -50,14 +50,11 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
| 50 | struct ieee80211_sub_if_data *sdata; | 50 | struct ieee80211_sub_if_data *sdata; |
| 51 | int err; | 51 | int err; |
| 52 | 52 | ||
| 53 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) | ||
| 54 | return -ENODEV; | ||
| 55 | |||
| 56 | itype = nl80211_type_to_mac80211_type(type); | 53 | itype = nl80211_type_to_mac80211_type(type); |
| 57 | if (itype == IEEE80211_IF_TYPE_INVALID) | 54 | if (itype == IEEE80211_IF_TYPE_INVALID) |
| 58 | return -EINVAL; | 55 | return -EINVAL; |
| 59 | 56 | ||
| 60 | err = ieee80211_if_add(local->mdev, name, &dev, itype, params); | 57 | err = ieee80211_if_add(local, name, &dev, itype, params); |
| 61 | if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) | 58 | if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) |
| 62 | return err; | 59 | return err; |
| 63 | 60 | ||
| @@ -68,54 +65,41 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, | |||
| 68 | 65 | ||
| 69 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | 66 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) |
| 70 | { | 67 | { |
| 71 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
| 72 | struct net_device *dev; | 68 | struct net_device *dev; |
| 73 | char *name; | ||
| 74 | |||
| 75 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) | ||
| 76 | return -ENODEV; | ||
| 77 | 69 | ||
| 78 | /* we're under RTNL */ | 70 | /* we're under RTNL */ |
| 79 | dev = __dev_get_by_index(&init_net, ifindex); | 71 | dev = __dev_get_by_index(&init_net, ifindex); |
| 80 | if (!dev) | 72 | if (!dev) |
| 81 | return 0; | 73 | return -ENODEV; |
| 82 | 74 | ||
| 83 | name = dev->name; | 75 | ieee80211_if_remove(dev); |
| 84 | 76 | ||
| 85 | return ieee80211_if_remove(local->mdev, name, -1); | 77 | return 0; |
| 86 | } | 78 | } |
| 87 | 79 | ||
| 88 | static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, | 80 | static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex, |
| 89 | enum nl80211_iftype type, u32 *flags, | 81 | enum nl80211_iftype type, u32 *flags, |
| 90 | struct vif_params *params) | 82 | struct vif_params *params) |
| 91 | { | 83 | { |
| 92 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
| 93 | struct net_device *dev; | 84 | struct net_device *dev; |
| 94 | enum ieee80211_if_types itype; | 85 | enum ieee80211_if_types itype; |
| 95 | struct ieee80211_sub_if_data *sdata; | 86 | struct ieee80211_sub_if_data *sdata; |
| 96 | 87 | int ret; | |
| 97 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) | ||
| 98 | return -ENODEV; | ||
| 99 | 88 | ||
| 100 | /* we're under RTNL */ | 89 | /* we're under RTNL */ |
| 101 | dev = __dev_get_by_index(&init_net, ifindex); | 90 | dev = __dev_get_by_index(&init_net, ifindex); |
| 102 | if (!dev) | 91 | if (!dev) |
| 103 | return -ENODEV; | 92 | return -ENODEV; |
| 104 | 93 | ||
| 105 | if (netif_running(dev)) | ||
| 106 | return -EBUSY; | ||
| 107 | |||
| 108 | itype = nl80211_type_to_mac80211_type(type); | 94 | itype = nl80211_type_to_mac80211_type(type); |
| 109 | if (itype == IEEE80211_IF_TYPE_INVALID) | 95 | if (itype == IEEE80211_IF_TYPE_INVALID) |
| 110 | return -EINVAL; | 96 | return -EINVAL; |
| 111 | 97 | ||
| 112 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 98 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 113 | 99 | ||
| 114 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 100 | ret = ieee80211_if_change_type(sdata, itype); |
| 115 | return -EOPNOTSUPP; | 101 | if (ret) |
| 116 | 102 | return ret; | |
| 117 | ieee80211_if_reinit(dev); | ||
| 118 | ieee80211_if_set_type(dev, itype); | ||
| 119 | 103 | ||
| 120 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) | 104 | if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) |
| 121 | ieee80211_if_sta_set_mesh_id(&sdata->u.sta, | 105 | ieee80211_if_sta_set_mesh_id(&sdata->u.sta, |
| @@ -256,8 +240,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
| 256 | case ALG_TKIP: | 240 | case ALG_TKIP: |
| 257 | params.cipher = WLAN_CIPHER_SUITE_TKIP; | 241 | params.cipher = WLAN_CIPHER_SUITE_TKIP; |
| 258 | 242 | ||
| 259 | iv32 = key->u.tkip.iv32; | 243 | iv32 = key->u.tkip.tx.iv32; |
| 260 | iv16 = key->u.tkip.iv16; | 244 | iv16 = key->u.tkip.tx.iv16; |
| 261 | 245 | ||
| 262 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && | 246 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
| 263 | sdata->local->ops->get_tkip_seq) | 247 | sdata->local->ops->get_tkip_seq) |
| @@ -485,7 +469,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 485 | 469 | ||
| 486 | kfree(old); | 470 | kfree(old); |
| 487 | 471 | ||
| 488 | return ieee80211_if_config_beacon(sdata->dev); | 472 | return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
| 489 | } | 473 | } |
| 490 | 474 | ||
| 491 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | 475 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, |
| @@ -539,7 +523,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) | |||
| 539 | synchronize_rcu(); | 523 | synchronize_rcu(); |
| 540 | kfree(old); | 524 | kfree(old); |
| 541 | 525 | ||
| 542 | return ieee80211_if_config_beacon(dev); | 526 | return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
| 543 | } | 527 | } |
| 544 | 528 | ||
| 545 | /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ | 529 | /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */ |
| @@ -602,6 +586,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
| 602 | */ | 586 | */ |
| 603 | 587 | ||
| 604 | if (params->station_flags & STATION_FLAG_CHANGED) { | 588 | if (params->station_flags & STATION_FLAG_CHANGED) { |
| 589 | spin_lock_bh(&sta->lock); | ||
| 605 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 590 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
| 606 | if (params->station_flags & STATION_FLAG_AUTHORIZED) | 591 | if (params->station_flags & STATION_FLAG_AUTHORIZED) |
| 607 | sta->flags |= WLAN_STA_AUTHORIZED; | 592 | sta->flags |= WLAN_STA_AUTHORIZED; |
| @@ -613,6 +598,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
| 613 | sta->flags &= ~WLAN_STA_WME; | 598 | sta->flags &= ~WLAN_STA_WME; |
| 614 | if (params->station_flags & STATION_FLAG_WME) | 599 | if (params->station_flags & STATION_FLAG_WME) |
| 615 | sta->flags |= WLAN_STA_WME; | 600 | sta->flags |= WLAN_STA_WME; |
| 601 | spin_unlock_bh(&sta->lock); | ||
| 616 | } | 602 | } |
| 617 | 603 | ||
| 618 | /* | 604 | /* |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 1cccbfd781f6..ee509f1109e2 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
| @@ -70,16 +70,6 @@ DEBUGFS_READONLY_FILE(rate_ctrl_alg, 100, "%s", | |||
| 70 | 70 | ||
| 71 | /* statistics stuff */ | 71 | /* statistics stuff */ |
| 72 | 72 | ||
| 73 | static inline int rtnl_lock_local(struct ieee80211_local *local) | ||
| 74 | { | ||
| 75 | rtnl_lock(); | ||
| 76 | if (unlikely(local->reg_state != IEEE80211_DEV_REGISTERED)) { | ||
| 77 | rtnl_unlock(); | ||
| 78 | return -ENODEV; | ||
| 79 | } | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ | 73 | #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ |
| 84 | DEBUGFS_READONLY_FILE(stats_ ##name, buflen, fmt, ##value) | 74 | DEBUGFS_READONLY_FILE(stats_ ##name, buflen, fmt, ##value) |
| 85 | 75 | ||
| @@ -96,10 +86,7 @@ static ssize_t format_devstat_counter(struct ieee80211_local *local, | |||
| 96 | if (!local->ops->get_stats) | 86 | if (!local->ops->get_stats) |
| 97 | return -EOPNOTSUPP; | 87 | return -EOPNOTSUPP; |
| 98 | 88 | ||
| 99 | res = rtnl_lock_local(local); | 89 | rtnl_lock(); |
| 100 | if (res) | ||
| 101 | return res; | ||
| 102 | |||
| 103 | res = local->ops->get_stats(local_to_hw(local), &stats); | 90 | res = local->ops->get_stats(local_to_hw(local), &stats); |
| 104 | rtnl_unlock(); | 91 | rtnl_unlock(); |
| 105 | if (!res) | 92 | if (!res) |
| @@ -197,45 +184,6 @@ DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u", | |||
| 197 | DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", | 184 | DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", |
| 198 | local->tx_status_drop); | 185 | local->tx_status_drop); |
| 199 | 186 | ||
| 200 | static ssize_t stats_wme_rx_queue_read(struct file *file, | ||
| 201 | char __user *userbuf, | ||
| 202 | size_t count, loff_t *ppos) | ||
| 203 | { | ||
| 204 | struct ieee80211_local *local = file->private_data; | ||
| 205 | char buf[NUM_RX_DATA_QUEUES*15], *p = buf; | ||
| 206 | int i; | ||
| 207 | |||
| 208 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | ||
| 209 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
| 210 | "%u\n", local->wme_rx_queue[i]); | ||
| 211 | |||
| 212 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
| 213 | } | ||
| 214 | |||
| 215 | static const struct file_operations stats_wme_rx_queue_ops = { | ||
| 216 | .read = stats_wme_rx_queue_read, | ||
| 217 | .open = mac80211_open_file_generic, | ||
| 218 | }; | ||
| 219 | |||
| 220 | static ssize_t stats_wme_tx_queue_read(struct file *file, | ||
| 221 | char __user *userbuf, | ||
| 222 | size_t count, loff_t *ppos) | ||
| 223 | { | ||
| 224 | struct ieee80211_local *local = file->private_data; | ||
| 225 | char buf[NUM_TX_DATA_QUEUES*15], *p = buf; | ||
| 226 | int i; | ||
| 227 | |||
| 228 | for (i = 0; i < NUM_TX_DATA_QUEUES; i++) | ||
| 229 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
| 230 | "%u\n", local->wme_tx_queue[i]); | ||
| 231 | |||
| 232 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
| 233 | } | ||
| 234 | |||
| 235 | static const struct file_operations stats_wme_tx_queue_ops = { | ||
| 236 | .read = stats_wme_tx_queue_read, | ||
| 237 | .open = mac80211_open_file_generic, | ||
| 238 | }; | ||
| 239 | #endif | 187 | #endif |
| 240 | 188 | ||
| 241 | DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); | 189 | DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); |
| @@ -303,8 +251,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
| 303 | DEBUGFS_STATS_ADD(rx_expand_skb_head2); | 251 | DEBUGFS_STATS_ADD(rx_expand_skb_head2); |
| 304 | DEBUGFS_STATS_ADD(rx_handlers_fragments); | 252 | DEBUGFS_STATS_ADD(rx_handlers_fragments); |
| 305 | DEBUGFS_STATS_ADD(tx_status_drop); | 253 | DEBUGFS_STATS_ADD(tx_status_drop); |
| 306 | DEBUGFS_STATS_ADD(wme_tx_queue); | ||
| 307 | DEBUGFS_STATS_ADD(wme_rx_queue); | ||
| 308 | #endif | 254 | #endif |
| 309 | DEBUGFS_STATS_ADD(dot11ACKFailureCount); | 255 | DEBUGFS_STATS_ADD(dot11ACKFailureCount); |
| 310 | DEBUGFS_STATS_ADD(dot11RTSFailureCount); | 256 | DEBUGFS_STATS_ADD(dot11RTSFailureCount); |
| @@ -356,8 +302,6 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
| 356 | DEBUGFS_STATS_DEL(rx_expand_skb_head2); | 302 | DEBUGFS_STATS_DEL(rx_expand_skb_head2); |
| 357 | DEBUGFS_STATS_DEL(rx_handlers_fragments); | 303 | DEBUGFS_STATS_DEL(rx_handlers_fragments); |
| 358 | DEBUGFS_STATS_DEL(tx_status_drop); | 304 | DEBUGFS_STATS_DEL(tx_status_drop); |
| 359 | DEBUGFS_STATS_DEL(wme_tx_queue); | ||
| 360 | DEBUGFS_STATS_DEL(wme_rx_queue); | ||
| 361 | #endif | 305 | #endif |
| 362 | DEBUGFS_STATS_DEL(dot11ACKFailureCount); | 306 | DEBUGFS_STATS_DEL(dot11ACKFailureCount); |
| 363 | DEBUGFS_STATS_DEL(dot11RTSFailureCount); | 307 | DEBUGFS_STATS_DEL(dot11RTSFailureCount); |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 19efc3a6a932..7439b63df5d0 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
| @@ -97,8 +97,8 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
| 97 | break; | 97 | break; |
| 98 | case ALG_TKIP: | 98 | case ALG_TKIP: |
| 99 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", | 99 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", |
| 100 | key->u.tkip.iv32, | 100 | key->u.tkip.tx.iv32, |
| 101 | key->u.tkip.iv16); | 101 | key->u.tkip.tx.iv16); |
| 102 | break; | 102 | break; |
| 103 | case ALG_CCMP: | 103 | case ALG_CCMP: |
| 104 | tpn = key->u.ccmp.tx_pn; | 104 | tpn = key->u.ccmp.tx_pn; |
| @@ -128,8 +128,8 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
| 128 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 128 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
| 129 | p += scnprintf(p, sizeof(buf)+buf-p, | 129 | p += scnprintf(p, sizeof(buf)+buf-p, |
| 130 | "%08x %04x\n", | 130 | "%08x %04x\n", |
| 131 | key->u.tkip.iv32_rx[i], | 131 | key->u.tkip.rx[i].iv32, |
| 132 | key->u.tkip.iv16_rx[i]); | 132 | key->u.tkip.rx[i].iv16); |
| 133 | len = p - buf; | 133 | len = p - buf; |
| 134 | break; | 134 | break; |
| 135 | case ALG_CCMP: | 135 | case ALG_CCMP: |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index e3326d046944..475f89a8aee1 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
| @@ -155,8 +155,9 @@ static const struct file_operations name##_ops = { \ | |||
| 155 | __IEEE80211_IF_WFILE(name) | 155 | __IEEE80211_IF_WFILE(name) |
| 156 | 156 | ||
| 157 | /* common attributes */ | 157 | /* common attributes */ |
| 158 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); | ||
| 159 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 158 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
| 159 | IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); | ||
| 160 | IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC); | ||
| 160 | 161 | ||
| 161 | /* STA/IBSS attributes */ | 162 | /* STA/IBSS attributes */ |
| 162 | IEEE80211_IF_FILE(state, u.sta.state, DEC); | 163 | IEEE80211_IF_FILE(state, u.sta.state, DEC); |
| @@ -192,8 +193,6 @@ __IEEE80211_IF_FILE(flags); | |||
| 192 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); | 193 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); |
| 193 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); | 194 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); |
| 194 | IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); | 195 | IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC); |
| 195 | IEEE80211_IF_FILE(force_unicast_rateidx, u.ap.force_unicast_rateidx, DEC); | ||
| 196 | IEEE80211_IF_FILE(max_ratectrl_rateidx, u.ap.max_ratectrl_rateidx, DEC); | ||
| 197 | 196 | ||
| 198 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( | 197 | static ssize_t ieee80211_if_fmt_num_buffered_multicast( |
| 199 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) | 198 | const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) |
| @@ -248,8 +247,10 @@ IEEE80211_IF_WFILE(min_discovery_timeout, | |||
| 248 | 247 | ||
| 249 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) | 248 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) |
| 250 | { | 249 | { |
| 251 | DEBUGFS_ADD(channel_use, sta); | ||
| 252 | DEBUGFS_ADD(drop_unencrypted, sta); | 250 | DEBUGFS_ADD(drop_unencrypted, sta); |
| 251 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
| 252 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
| 253 | |||
| 253 | DEBUGFS_ADD(state, sta); | 254 | DEBUGFS_ADD(state, sta); |
| 254 | DEBUGFS_ADD(bssid, sta); | 255 | DEBUGFS_ADD(bssid, sta); |
| 255 | DEBUGFS_ADD(prev_bssid, sta); | 256 | DEBUGFS_ADD(prev_bssid, sta); |
| @@ -269,27 +270,30 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
| 269 | 270 | ||
| 270 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 271 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
| 271 | { | 272 | { |
| 272 | DEBUGFS_ADD(channel_use, ap); | ||
| 273 | DEBUGFS_ADD(drop_unencrypted, ap); | 273 | DEBUGFS_ADD(drop_unencrypted, ap); |
| 274 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
| 275 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
| 276 | |||
| 274 | DEBUGFS_ADD(num_sta_ps, ap); | 277 | DEBUGFS_ADD(num_sta_ps, ap); |
| 275 | DEBUGFS_ADD(dtim_count, ap); | 278 | DEBUGFS_ADD(dtim_count, ap); |
| 276 | DEBUGFS_ADD(num_beacons, ap); | 279 | DEBUGFS_ADD(num_beacons, ap); |
| 277 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
| 278 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
| 279 | DEBUGFS_ADD(num_buffered_multicast, ap); | 280 | DEBUGFS_ADD(num_buffered_multicast, ap); |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) | 283 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) |
| 283 | { | 284 | { |
| 284 | DEBUGFS_ADD(channel_use, wds); | ||
| 285 | DEBUGFS_ADD(drop_unencrypted, wds); | 285 | DEBUGFS_ADD(drop_unencrypted, wds); |
| 286 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
| 287 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
| 288 | |||
| 286 | DEBUGFS_ADD(peer, wds); | 289 | DEBUGFS_ADD(peer, wds); |
| 287 | } | 290 | } |
| 288 | 291 | ||
| 289 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) | 292 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) |
| 290 | { | 293 | { |
| 291 | DEBUGFS_ADD(channel_use, vlan); | ||
| 292 | DEBUGFS_ADD(drop_unencrypted, vlan); | 294 | DEBUGFS_ADD(drop_unencrypted, vlan); |
| 295 | DEBUGFS_ADD(force_unicast_rateidx, ap); | ||
| 296 | DEBUGFS_ADD(max_ratectrl_rateidx, ap); | ||
| 293 | } | 297 | } |
| 294 | 298 | ||
| 295 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | 299 | static void add_monitor_files(struct ieee80211_sub_if_data *sdata) |
| @@ -376,8 +380,10 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
| 376 | 380 | ||
| 377 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) | 381 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) |
| 378 | { | 382 | { |
| 379 | DEBUGFS_DEL(channel_use, sta); | ||
| 380 | DEBUGFS_DEL(drop_unencrypted, sta); | 383 | DEBUGFS_DEL(drop_unencrypted, sta); |
| 384 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
| 385 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
| 386 | |||
| 381 | DEBUGFS_DEL(state, sta); | 387 | DEBUGFS_DEL(state, sta); |
| 382 | DEBUGFS_DEL(bssid, sta); | 388 | DEBUGFS_DEL(bssid, sta); |
| 383 | DEBUGFS_DEL(prev_bssid, sta); | 389 | DEBUGFS_DEL(prev_bssid, sta); |
| @@ -397,27 +403,30 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata) | |||
| 397 | 403 | ||
| 398 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) | 404 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) |
| 399 | { | 405 | { |
| 400 | DEBUGFS_DEL(channel_use, ap); | ||
| 401 | DEBUGFS_DEL(drop_unencrypted, ap); | 406 | DEBUGFS_DEL(drop_unencrypted, ap); |
| 407 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
| 408 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
| 409 | |||
| 402 | DEBUGFS_DEL(num_sta_ps, ap); | 410 | DEBUGFS_DEL(num_sta_ps, ap); |
| 403 | DEBUGFS_DEL(dtim_count, ap); | 411 | DEBUGFS_DEL(dtim_count, ap); |
| 404 | DEBUGFS_DEL(num_beacons, ap); | 412 | DEBUGFS_DEL(num_beacons, ap); |
| 405 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
| 406 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
| 407 | DEBUGFS_DEL(num_buffered_multicast, ap); | 413 | DEBUGFS_DEL(num_buffered_multicast, ap); |
| 408 | } | 414 | } |
| 409 | 415 | ||
| 410 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) | 416 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) |
| 411 | { | 417 | { |
| 412 | DEBUGFS_DEL(channel_use, wds); | ||
| 413 | DEBUGFS_DEL(drop_unencrypted, wds); | 418 | DEBUGFS_DEL(drop_unencrypted, wds); |
| 419 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
| 420 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
| 421 | |||
| 414 | DEBUGFS_DEL(peer, wds); | 422 | DEBUGFS_DEL(peer, wds); |
| 415 | } | 423 | } |
| 416 | 424 | ||
| 417 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) | 425 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) |
| 418 | { | 426 | { |
| 419 | DEBUGFS_DEL(channel_use, vlan); | ||
| 420 | DEBUGFS_DEL(drop_unencrypted, vlan); | 427 | DEBUGFS_DEL(drop_unencrypted, vlan); |
| 428 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
| 429 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
| 421 | } | 430 | } |
| 422 | 431 | ||
| 423 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) | 432 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) |
| @@ -467,12 +476,12 @@ static void del_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
| 467 | } | 476 | } |
| 468 | #endif | 477 | #endif |
| 469 | 478 | ||
| 470 | static void del_files(struct ieee80211_sub_if_data *sdata, int type) | 479 | static void del_files(struct ieee80211_sub_if_data *sdata) |
| 471 | { | 480 | { |
| 472 | if (!sdata->debugfsdir) | 481 | if (!sdata->debugfsdir) |
| 473 | return; | 482 | return; |
| 474 | 483 | ||
| 475 | switch (type) { | 484 | switch (sdata->vif.type) { |
| 476 | case IEEE80211_IF_TYPE_MESH_POINT: | 485 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 477 | #ifdef CONFIG_MAC80211_MESH | 486 | #ifdef CONFIG_MAC80211_MESH |
| 478 | del_mesh_stats(sdata); | 487 | del_mesh_stats(sdata); |
| @@ -512,29 +521,23 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | |||
| 512 | sprintf(buf, "netdev:%s", sdata->dev->name); | 521 | sprintf(buf, "netdev:%s", sdata->dev->name); |
| 513 | sdata->debugfsdir = debugfs_create_dir(buf, | 522 | sdata->debugfsdir = debugfs_create_dir(buf, |
| 514 | sdata->local->hw.wiphy->debugfsdir); | 523 | sdata->local->hw.wiphy->debugfsdir); |
| 524 | add_files(sdata); | ||
| 515 | } | 525 | } |
| 516 | 526 | ||
| 517 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) | 527 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) |
| 518 | { | 528 | { |
| 519 | del_files(sdata, sdata->vif.type); | 529 | del_files(sdata); |
| 520 | debugfs_remove(sdata->debugfsdir); | 530 | debugfs_remove(sdata->debugfsdir); |
| 521 | sdata->debugfsdir = NULL; | 531 | sdata->debugfsdir = NULL; |
| 522 | } | 532 | } |
| 523 | 533 | ||
| 524 | void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata, | 534 | static int netdev_notify(struct notifier_block *nb, |
| 525 | int oldtype) | ||
| 526 | { | ||
| 527 | del_files(sdata, oldtype); | ||
| 528 | add_files(sdata); | ||
| 529 | } | ||
| 530 | |||
| 531 | static int netdev_notify(struct notifier_block * nb, | ||
| 532 | unsigned long state, | 535 | unsigned long state, |
| 533 | void *ndev) | 536 | void *ndev) |
| 534 | { | 537 | { |
| 535 | struct net_device *dev = ndev; | 538 | struct net_device *dev = ndev; |
| 536 | struct dentry *dir; | 539 | struct dentry *dir; |
| 537 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 540 | struct ieee80211_sub_if_data *sdata; |
| 538 | char buf[10+IFNAMSIZ]; | 541 | char buf[10+IFNAMSIZ]; |
| 539 | 542 | ||
| 540 | if (state != NETDEV_CHANGENAME) | 543 | if (state != NETDEV_CHANGENAME) |
| @@ -546,6 +549,8 @@ static int netdev_notify(struct notifier_block * nb, | |||
| 546 | if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) | 549 | if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) |
| 547 | return 0; | 550 | return 0; |
| 548 | 551 | ||
| 552 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 553 | |||
| 549 | sprintf(buf, "netdev:%s", dev->name); | 554 | sprintf(buf, "netdev:%s", dev->name); |
| 550 | dir = sdata->debugfsdir; | 555 | dir = sdata->debugfsdir; |
| 551 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) | 556 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) |
diff --git a/net/mac80211/debugfs_netdev.h b/net/mac80211/debugfs_netdev.h index a690071fde8a..7af731f0b731 100644 --- a/net/mac80211/debugfs_netdev.h +++ b/net/mac80211/debugfs_netdev.h | |||
| @@ -6,8 +6,6 @@ | |||
| 6 | #ifdef CONFIG_MAC80211_DEBUGFS | 6 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 7 | void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata); | 7 | void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata); |
| 8 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata); | 8 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata); |
| 9 | void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata, | ||
| 10 | int oldtype); | ||
| 11 | void ieee80211_debugfs_netdev_init(void); | 9 | void ieee80211_debugfs_netdev_init(void); |
| 12 | void ieee80211_debugfs_netdev_exit(void); | 10 | void ieee80211_debugfs_netdev_exit(void); |
| 13 | #else | 11 | #else |
| @@ -17,9 +15,6 @@ static inline void ieee80211_debugfs_add_netdev( | |||
| 17 | static inline void ieee80211_debugfs_remove_netdev( | 15 | static inline void ieee80211_debugfs_remove_netdev( |
| 18 | struct ieee80211_sub_if_data *sdata) | 16 | struct ieee80211_sub_if_data *sdata) |
| 19 | {} | 17 | {} |
| 20 | static inline void ieee80211_debugfs_change_if_type( | ||
| 21 | struct ieee80211_sub_if_data *sdata, int oldtype) | ||
| 22 | {} | ||
| 23 | static inline void ieee80211_debugfs_netdev_init(void) | 18 | static inline void ieee80211_debugfs_netdev_init(void) |
| 24 | {} | 19 | {} |
| 25 | 20 | ||
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6d47a1d31b37..79a062782d52 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
| @@ -63,10 +63,9 @@ STA_FILE(tx_fragments, tx_fragments, LU); | |||
| 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
| 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
| 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
| 66 | STA_FILE(last_rssi, last_rssi, D); | ||
| 67 | STA_FILE(last_signal, last_signal, D); | 66 | STA_FILE(last_signal, last_signal, D); |
| 67 | STA_FILE(last_qual, last_qual, D); | ||
| 68 | STA_FILE(last_noise, last_noise, D); | 68 | STA_FILE(last_noise, last_noise, D); |
| 69 | STA_FILE(channel_use, channel_use, D); | ||
| 70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); | 69 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
| 71 | 70 | ||
| 72 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 71 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
| @@ -74,14 +73,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
| 74 | { | 73 | { |
| 75 | char buf[100]; | 74 | char buf[100]; |
| 76 | struct sta_info *sta = file->private_data; | 75 | struct sta_info *sta = file->private_data; |
| 76 | u32 staflags = get_sta_flags(sta); | ||
| 77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", | 77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
| 78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 78 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", |
| 79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 79 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
| 80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 80 | staflags & WLAN_STA_PS ? "PS\n" : "", |
| 81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 81 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
| 82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 82 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
| 83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 83 | staflags & WLAN_STA_WME ? "WME\n" : "", |
| 84 | sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); | 84 | staflags & WLAN_STA_WDS ? "WDS\n" : ""); |
| 85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
| 86 | } | 86 | } |
| 87 | STA_OPS(flags); | 87 | STA_OPS(flags); |
| @@ -123,36 +123,6 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, | |||
| 123 | } | 123 | } |
| 124 | STA_OPS(last_seq_ctrl); | 124 | STA_OPS(last_seq_ctrl); |
| 125 | 125 | ||
| 126 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
| 127 | static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf, | ||
| 128 | size_t count, loff_t *ppos) | ||
| 129 | { | ||
| 130 | char buf[15*NUM_RX_DATA_QUEUES], *p = buf; | ||
| 131 | int i; | ||
| 132 | struct sta_info *sta = file->private_data; | ||
| 133 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | ||
| 134 | p += scnprintf(p, sizeof(buf)+buf-p, "%u ", | ||
| 135 | sta->wme_rx_queue[i]); | ||
| 136 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
| 137 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
| 138 | } | ||
| 139 | STA_OPS(wme_rx_queue); | ||
| 140 | |||
| 141 | static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf, | ||
| 142 | size_t count, loff_t *ppos) | ||
| 143 | { | ||
| 144 | char buf[15*NUM_TX_DATA_QUEUES], *p = buf; | ||
| 145 | int i; | ||
| 146 | struct sta_info *sta = file->private_data; | ||
| 147 | for (i = 0; i < NUM_TX_DATA_QUEUES; i++) | ||
| 148 | p += scnprintf(p, sizeof(buf)+buf-p, "%u ", | ||
| 149 | sta->wme_tx_queue[i]); | ||
| 150 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
| 151 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
| 152 | } | ||
| 153 | STA_OPS(wme_tx_queue); | ||
| 154 | #endif | ||
| 155 | |||
| 156 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | 126 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, |
| 157 | size_t count, loff_t *ppos) | 127 | size_t count, loff_t *ppos) |
| 158 | { | 128 | { |
| @@ -293,10 +263,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
| 293 | DEBUGFS_ADD(num_ps_buf_frames); | 263 | DEBUGFS_ADD(num_ps_buf_frames); |
| 294 | DEBUGFS_ADD(inactive_ms); | 264 | DEBUGFS_ADD(inactive_ms); |
| 295 | DEBUGFS_ADD(last_seq_ctrl); | 265 | DEBUGFS_ADD(last_seq_ctrl); |
| 296 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
| 297 | DEBUGFS_ADD(wme_rx_queue); | ||
| 298 | DEBUGFS_ADD(wme_tx_queue); | ||
| 299 | #endif | ||
| 300 | DEBUGFS_ADD(agg_status); | 266 | DEBUGFS_ADD(agg_status); |
| 301 | } | 267 | } |
| 302 | 268 | ||
| @@ -306,10 +272,6 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta) | |||
| 306 | DEBUGFS_DEL(num_ps_buf_frames); | 272 | DEBUGFS_DEL(num_ps_buf_frames); |
| 307 | DEBUGFS_DEL(inactive_ms); | 273 | DEBUGFS_DEL(inactive_ms); |
| 308 | DEBUGFS_DEL(last_seq_ctrl); | 274 | DEBUGFS_DEL(last_seq_ctrl); |
| 309 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
| 310 | DEBUGFS_DEL(wme_rx_queue); | ||
| 311 | DEBUGFS_DEL(wme_tx_queue); | ||
| 312 | #endif | ||
| 313 | DEBUGFS_DEL(agg_status); | 275 | DEBUGFS_DEL(agg_status); |
| 314 | 276 | ||
| 315 | debugfs_remove(sta->debugfs.dir); | 277 | debugfs_remove(sta->debugfs.dir); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 006486b26726..a4f9a832722a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
| 3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
| 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
| 5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -23,6 +24,8 @@ | |||
| 23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 24 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
| 25 | #include <net/wireless.h> | 26 | #include <net/wireless.h> |
| 27 | #include <net/iw_handler.h> | ||
| 28 | #include <net/mac80211.h> | ||
| 26 | #include "key.h" | 29 | #include "key.h" |
| 27 | #include "sta_info.h" | 30 | #include "sta_info.h" |
| 28 | 31 | ||
| @@ -82,7 +85,7 @@ struct ieee80211_sta_bss { | |||
| 82 | u16 capability; /* host byte order */ | 85 | u16 capability; /* host byte order */ |
| 83 | enum ieee80211_band band; | 86 | enum ieee80211_band band; |
| 84 | int freq; | 87 | int freq; |
| 85 | int rssi, signal, noise; | 88 | int signal, noise, qual; |
| 86 | u8 *wpa_ie; | 89 | u8 *wpa_ie; |
| 87 | size_t wpa_ie_len; | 90 | size_t wpa_ie_len; |
| 88 | u8 *rsn_ie; | 91 | u8 *rsn_ie; |
| @@ -91,6 +94,8 @@ struct ieee80211_sta_bss { | |||
| 91 | size_t wmm_ie_len; | 94 | size_t wmm_ie_len; |
| 92 | u8 *ht_ie; | 95 | u8 *ht_ie; |
| 93 | size_t ht_ie_len; | 96 | size_t ht_ie_len; |
| 97 | u8 *ht_add_ie; | ||
| 98 | size_t ht_add_ie_len; | ||
| 94 | #ifdef CONFIG_MAC80211_MESH | 99 | #ifdef CONFIG_MAC80211_MESH |
| 95 | u8 *mesh_id; | 100 | u8 *mesh_id; |
| 96 | size_t mesh_id_len; | 101 | size_t mesh_id_len; |
| @@ -147,7 +152,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result; | |||
| 147 | #define IEEE80211_TX_UNICAST BIT(1) | 152 | #define IEEE80211_TX_UNICAST BIT(1) |
| 148 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 153 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
| 149 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) | 154 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) |
| 150 | #define IEEE80211_TX_INJECTED BIT(4) | ||
| 151 | 155 | ||
| 152 | struct ieee80211_tx_data { | 156 | struct ieee80211_tx_data { |
| 153 | struct sk_buff *skb; | 157 | struct sk_buff *skb; |
| @@ -157,13 +161,12 @@ struct ieee80211_tx_data { | |||
| 157 | struct sta_info *sta; | 161 | struct sta_info *sta; |
| 158 | struct ieee80211_key *key; | 162 | struct ieee80211_key *key; |
| 159 | 163 | ||
| 160 | struct ieee80211_tx_control *control; | ||
| 161 | struct ieee80211_channel *channel; | 164 | struct ieee80211_channel *channel; |
| 162 | struct ieee80211_rate *rate; | 165 | s8 rate_idx; |
| 163 | /* use this rate (if set) for last fragment; rate can | 166 | /* use this rate (if set) for last fragment; rate can |
| 164 | * be set to lower rate for the first fragments, e.g., | 167 | * be set to lower rate for the first fragments, e.g., |
| 165 | * when using CTS protection with IEEE 802.11g. */ | 168 | * when using CTS protection with IEEE 802.11g. */ |
| 166 | struct ieee80211_rate *last_frag_rate; | 169 | s8 last_frag_rate_idx; |
| 167 | 170 | ||
| 168 | /* Extra fragments (in addition to the first fragment | 171 | /* Extra fragments (in addition to the first fragment |
| 169 | * in skb) */ | 172 | * in skb) */ |
| @@ -202,32 +205,16 @@ struct ieee80211_rx_data { | |||
| 202 | unsigned int flags; | 205 | unsigned int flags; |
| 203 | int sent_ps_buffered; | 206 | int sent_ps_buffered; |
| 204 | int queue; | 207 | int queue; |
| 205 | int load; | ||
| 206 | u32 tkip_iv32; | 208 | u32 tkip_iv32; |
| 207 | u16 tkip_iv16; | 209 | u16 tkip_iv16; |
| 208 | }; | 210 | }; |
| 209 | 211 | ||
| 210 | /* flags used in struct ieee80211_tx_packet_data.flags */ | ||
| 211 | #define IEEE80211_TXPD_REQ_TX_STATUS BIT(0) | ||
| 212 | #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) | ||
| 213 | #define IEEE80211_TXPD_REQUEUE BIT(2) | ||
| 214 | #define IEEE80211_TXPD_EAPOL_FRAME BIT(3) | ||
| 215 | #define IEEE80211_TXPD_AMPDU BIT(4) | ||
| 216 | /* Stored in sk_buff->cb */ | ||
| 217 | struct ieee80211_tx_packet_data { | ||
| 218 | int ifindex; | ||
| 219 | unsigned long jiffies; | ||
| 220 | unsigned int flags; | ||
| 221 | u8 queue; | ||
| 222 | }; | ||
| 223 | |||
| 224 | struct ieee80211_tx_stored_packet { | 212 | struct ieee80211_tx_stored_packet { |
| 225 | struct ieee80211_tx_control control; | ||
| 226 | struct sk_buff *skb; | 213 | struct sk_buff *skb; |
| 227 | struct sk_buff **extra_frag; | 214 | struct sk_buff **extra_frag; |
| 228 | struct ieee80211_rate *last_frag_rate; | 215 | s8 last_frag_rate_idx; |
| 229 | int num_extra_frag; | 216 | int num_extra_frag; |
| 230 | unsigned int last_frag_rate_ctrl_probe; | 217 | bool last_frag_rate_ctrl_probe; |
| 231 | }; | 218 | }; |
| 232 | 219 | ||
| 233 | struct beacon_data { | 220 | struct beacon_data { |
| @@ -251,8 +238,6 @@ struct ieee80211_if_ap { | |||
| 251 | struct sk_buff_head ps_bc_buf; | 238 | struct sk_buff_head ps_bc_buf; |
| 252 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 239 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
| 253 | int dtim_count; | 240 | int dtim_count; |
| 254 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | ||
| 255 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | ||
| 256 | int num_beacons; /* number of TXed beacon frames for this BSS */ | 241 | int num_beacons; /* number of TXed beacon frames for this BSS */ |
| 257 | }; | 242 | }; |
| 258 | 243 | ||
| @@ -262,7 +247,6 @@ struct ieee80211_if_wds { | |||
| 262 | }; | 247 | }; |
| 263 | 248 | ||
| 264 | struct ieee80211_if_vlan { | 249 | struct ieee80211_if_vlan { |
| 265 | struct ieee80211_sub_if_data *ap; | ||
| 266 | struct list_head list; | 250 | struct list_head list; |
| 267 | }; | 251 | }; |
| 268 | 252 | ||
| @@ -436,8 +420,6 @@ struct ieee80211_sub_if_data { | |||
| 436 | */ | 420 | */ |
| 437 | u64 basic_rates; | 421 | u64 basic_rates; |
| 438 | 422 | ||
| 439 | u16 sequence; | ||
| 440 | |||
| 441 | /* Fragment table for host-based reassembly */ | 423 | /* Fragment table for host-based reassembly */ |
| 442 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 424 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
| 443 | unsigned int fragment_next; | 425 | unsigned int fragment_next; |
| @@ -446,16 +428,18 @@ struct ieee80211_sub_if_data { | |||
| 446 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; | 428 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; |
| 447 | struct ieee80211_key *default_key; | 429 | struct ieee80211_key *default_key; |
| 448 | 430 | ||
| 431 | /* BSS configuration for this interface. */ | ||
| 432 | struct ieee80211_bss_conf bss_conf; | ||
| 433 | |||
| 449 | /* | 434 | /* |
| 450 | * BSS configuration for this interface. | 435 | * AP this belongs to: self in AP mode and |
| 451 | * | 436 | * corresponding AP in VLAN mode, NULL for |
| 452 | * FIXME: I feel bad putting this here when we already have a | 437 | * all others (might be needed later in IBSS) |
| 453 | * bss pointer, but the bss pointer is just wrong when | ||
| 454 | * you have multiple virtual STA mode interfaces... | ||
| 455 | * This needs to be fixed. | ||
| 456 | */ | 438 | */ |
| 457 | struct ieee80211_bss_conf bss_conf; | 439 | struct ieee80211_if_ap *bss; |
| 458 | struct ieee80211_if_ap *bss; /* BSS that this device belongs to */ | 440 | |
| 441 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | ||
| 442 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | ||
| 459 | 443 | ||
| 460 | union { | 444 | union { |
| 461 | struct ieee80211_if_ap ap; | 445 | struct ieee80211_if_ap ap; |
| @@ -464,14 +448,11 @@ struct ieee80211_sub_if_data { | |||
| 464 | struct ieee80211_if_sta sta; | 448 | struct ieee80211_if_sta sta; |
| 465 | u32 mntr_flags; | 449 | u32 mntr_flags; |
| 466 | } u; | 450 | } u; |
| 467 | int channel_use; | ||
| 468 | int channel_use_raw; | ||
| 469 | 451 | ||
| 470 | #ifdef CONFIG_MAC80211_DEBUGFS | 452 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 471 | struct dentry *debugfsdir; | 453 | struct dentry *debugfsdir; |
| 472 | union { | 454 | union { |
| 473 | struct { | 455 | struct { |
| 474 | struct dentry *channel_use; | ||
| 475 | struct dentry *drop_unencrypted; | 456 | struct dentry *drop_unencrypted; |
| 476 | struct dentry *state; | 457 | struct dentry *state; |
| 477 | struct dentry *bssid; | 458 | struct dentry *bssid; |
| @@ -490,7 +471,6 @@ struct ieee80211_sub_if_data { | |||
| 490 | struct dentry *num_beacons_sta; | 471 | struct dentry *num_beacons_sta; |
| 491 | } sta; | 472 | } sta; |
| 492 | struct { | 473 | struct { |
| 493 | struct dentry *channel_use; | ||
| 494 | struct dentry *drop_unencrypted; | 474 | struct dentry *drop_unencrypted; |
| 495 | struct dentry *num_sta_ps; | 475 | struct dentry *num_sta_ps; |
| 496 | struct dentry *dtim_count; | 476 | struct dentry *dtim_count; |
| @@ -500,12 +480,10 @@ struct ieee80211_sub_if_data { | |||
| 500 | struct dentry *num_buffered_multicast; | 480 | struct dentry *num_buffered_multicast; |
| 501 | } ap; | 481 | } ap; |
| 502 | struct { | 482 | struct { |
| 503 | struct dentry *channel_use; | ||
| 504 | struct dentry *drop_unencrypted; | 483 | struct dentry *drop_unencrypted; |
| 505 | struct dentry *peer; | 484 | struct dentry *peer; |
| 506 | } wds; | 485 | } wds; |
| 507 | struct { | 486 | struct { |
| 508 | struct dentry *channel_use; | ||
| 509 | struct dentry *drop_unencrypted; | 487 | struct dentry *drop_unencrypted; |
| 510 | } vlan; | 488 | } vlan; |
| 511 | struct { | 489 | struct { |
| @@ -553,8 +531,6 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | |||
| 553 | return container_of(p, struct ieee80211_sub_if_data, vif); | 531 | return container_of(p, struct ieee80211_sub_if_data, vif); |
| 554 | } | 532 | } |
| 555 | 533 | ||
| 556 | #define IEEE80211_DEV_TO_SUB_IF(dev) netdev_priv(dev) | ||
| 557 | |||
| 558 | enum { | 534 | enum { |
| 559 | IEEE80211_RX_MSG = 1, | 535 | IEEE80211_RX_MSG = 1, |
| 560 | IEEE80211_TX_STATUS_MSG = 2, | 536 | IEEE80211_TX_STATUS_MSG = 2, |
| @@ -562,6 +538,9 @@ enum { | |||
| 562 | IEEE80211_ADDBA_MSG = 4, | 538 | IEEE80211_ADDBA_MSG = 4, |
| 563 | }; | 539 | }; |
| 564 | 540 | ||
| 541 | /* maximum number of hardware queues we support. */ | ||
| 542 | #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) | ||
| 543 | |||
| 565 | struct ieee80211_local { | 544 | struct ieee80211_local { |
| 566 | /* embed the driver visible part. | 545 | /* embed the driver visible part. |
| 567 | * don't cast (use the static inlines below), but we keep | 546 | * don't cast (use the static inlines below), but we keep |
| @@ -570,6 +549,8 @@ struct ieee80211_local { | |||
| 570 | 549 | ||
| 571 | const struct ieee80211_ops *ops; | 550 | const struct ieee80211_ops *ops; |
| 572 | 551 | ||
| 552 | unsigned long queue_pool[BITS_TO_LONGS(QD_MAX_QUEUES)]; | ||
| 553 | |||
| 573 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ | 554 | struct net_device *mdev; /* wmaster# - "master" 802.11 device */ |
| 574 | int open_count; | 555 | int open_count; |
| 575 | int monitors, cooked_mntrs; | 556 | int monitors, cooked_mntrs; |
| @@ -581,12 +562,6 @@ struct ieee80211_local { | |||
| 581 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ | 562 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ |
| 582 | int tx_headroom; /* required headroom for hardware/radiotap */ | 563 | int tx_headroom; /* required headroom for hardware/radiotap */ |
| 583 | 564 | ||
| 584 | enum { | ||
| 585 | IEEE80211_DEV_UNINITIALIZED = 0, | ||
| 586 | IEEE80211_DEV_REGISTERED, | ||
| 587 | IEEE80211_DEV_UNREGISTERED, | ||
| 588 | } reg_state; | ||
| 589 | |||
| 590 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 565 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
| 591 | * added to skb_queue will be processed, but frames in | 566 | * added to skb_queue will be processed, but frames in |
| 592 | * skb_queue_unreliable may be dropped if the total length of these | 567 | * skb_queue_unreliable may be dropped if the total length of these |
| @@ -610,8 +585,8 @@ struct ieee80211_local { | |||
| 610 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 585 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
| 611 | struct timer_list sta_cleanup; | 586 | struct timer_list sta_cleanup; |
| 612 | 587 | ||
| 613 | unsigned long state[NUM_TX_DATA_QUEUES_AMPDU]; | 588 | unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)]; |
| 614 | struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU]; | 589 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES]; |
| 615 | struct tasklet_struct tx_pending_tasklet; | 590 | struct tasklet_struct tx_pending_tasklet; |
| 616 | 591 | ||
| 617 | /* number of interfaces with corresponding IFF_ flags */ | 592 | /* number of interfaces with corresponding IFF_ flags */ |
| @@ -677,9 +652,6 @@ struct ieee80211_local { | |||
| 677 | assoc_led_name[32], radio_led_name[32]; | 652 | assoc_led_name[32], radio_led_name[32]; |
| 678 | #endif | 653 | #endif |
| 679 | 654 | ||
| 680 | u32 channel_use; | ||
| 681 | u32 channel_use_raw; | ||
| 682 | |||
| 683 | #ifdef CONFIG_MAC80211_DEBUGFS | 655 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 684 | struct work_struct sta_debugfs_add; | 656 | struct work_struct sta_debugfs_add; |
| 685 | #endif | 657 | #endif |
| @@ -705,8 +677,6 @@ struct ieee80211_local { | |||
| 705 | unsigned int rx_expand_skb_head2; | 677 | unsigned int rx_expand_skb_head2; |
| 706 | unsigned int rx_handlers_fragments; | 678 | unsigned int rx_handlers_fragments; |
| 707 | unsigned int tx_status_drop; | 679 | unsigned int tx_status_drop; |
| 708 | unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; | ||
| 709 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; | ||
| 710 | #define I802_DEBUG_INC(c) (c)++ | 680 | #define I802_DEBUG_INC(c) (c)++ |
| 711 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 681 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
| 712 | #define I802_DEBUG_INC(c) do { } while (0) | 682 | #define I802_DEBUG_INC(c) do { } while (0) |
| @@ -764,8 +734,6 @@ struct ieee80211_local { | |||
| 764 | struct dentry *rx_expand_skb_head2; | 734 | struct dentry *rx_expand_skb_head2; |
| 765 | struct dentry *rx_handlers_fragments; | 735 | struct dentry *rx_handlers_fragments; |
| 766 | struct dentry *tx_status_drop; | 736 | struct dentry *tx_status_drop; |
| 767 | struct dentry *wme_tx_queue; | ||
| 768 | struct dentry *wme_rx_queue; | ||
| 769 | #endif | 737 | #endif |
| 770 | struct dentry *dot11ACKFailureCount; | 738 | struct dentry *dot11ACKFailureCount; |
| 771 | struct dentry *dot11RTSFailureCount; | 739 | struct dentry *dot11RTSFailureCount; |
| @@ -778,6 +746,16 @@ struct ieee80211_local { | |||
| 778 | #endif | 746 | #endif |
| 779 | }; | 747 | }; |
| 780 | 748 | ||
| 749 | static inline struct ieee80211_sub_if_data * | ||
| 750 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | ||
| 751 | { | ||
| 752 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 753 | |||
| 754 | BUG_ON(!local || local->mdev == dev); | ||
| 755 | |||
| 756 | return netdev_priv(dev); | ||
| 757 | } | ||
| 758 | |||
| 781 | /* this struct represents 802.11n's RA/TID combination */ | 759 | /* this struct represents 802.11n's RA/TID combination */ |
| 782 | struct ieee80211_ra_tid { | 760 | struct ieee80211_ra_tid { |
| 783 | u8 ra[ETH_ALEN]; | 761 | u8 ra[ETH_ALEN]; |
| @@ -809,6 +787,10 @@ struct ieee802_11_elems { | |||
| 809 | u8 *preq; | 787 | u8 *preq; |
| 810 | u8 *prep; | 788 | u8 *prep; |
| 811 | u8 *perr; | 789 | u8 *perr; |
| 790 | u8 *ch_switch_elem; | ||
| 791 | u8 *country_elem; | ||
| 792 | u8 *pwr_constr_elem; | ||
| 793 | u8 *quiet_elem; /* first quite element */ | ||
| 812 | 794 | ||
| 813 | /* length of them, respectively */ | 795 | /* length of them, respectively */ |
| 814 | u8 ssid_len; | 796 | u8 ssid_len; |
| @@ -833,6 +815,11 @@ struct ieee802_11_elems { | |||
| 833 | u8 preq_len; | 815 | u8 preq_len; |
| 834 | u8 prep_len; | 816 | u8 prep_len; |
| 835 | u8 perr_len; | 817 | u8 perr_len; |
| 818 | u8 ch_switch_elem_len; | ||
| 819 | u8 country_elem_len; | ||
| 820 | u8 pwr_constr_elem_len; | ||
| 821 | u8 quiet_elem_len; | ||
| 822 | u8 num_of_quiet_elem; /* can be more the one */ | ||
| 836 | }; | 823 | }; |
| 837 | 824 | ||
| 838 | static inline struct ieee80211_local *hw_to_local( | 825 | static inline struct ieee80211_local *hw_to_local( |
| @@ -847,11 +834,6 @@ static inline struct ieee80211_hw *local_to_hw( | |||
| 847 | return &local->hw; | 834 | return &local->hw; |
| 848 | } | 835 | } |
| 849 | 836 | ||
| 850 | enum ieee80211_link_state_t { | ||
| 851 | IEEE80211_LINK_STATE_XOFF = 0, | ||
| 852 | IEEE80211_LINK_STATE_PENDING, | ||
| 853 | }; | ||
| 854 | |||
| 855 | struct sta_attribute { | 837 | struct sta_attribute { |
| 856 | struct attribute attr; | 838 | struct attribute attr; |
| 857 | ssize_t (*show)(const struct sta_info *, char *buf); | 839 | ssize_t (*show)(const struct sta_info *, char *buf); |
| @@ -867,39 +849,16 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | |||
| 867 | 849 | ||
| 868 | /* ieee80211.c */ | 850 | /* ieee80211.c */ |
| 869 | int ieee80211_hw_config(struct ieee80211_local *local); | 851 | int ieee80211_hw_config(struct ieee80211_local *local); |
| 870 | int ieee80211_if_config(struct net_device *dev); | 852 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); |
| 871 | int ieee80211_if_config_beacon(struct net_device *dev); | ||
| 872 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 853 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
| 873 | void ieee80211_if_setup(struct net_device *dev); | ||
| 874 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | 854 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, |
| 875 | struct ieee80211_ht_info *req_ht_cap, | 855 | struct ieee80211_ht_info *req_ht_cap, |
| 876 | struct ieee80211_ht_bss_info *req_bss_cap); | 856 | struct ieee80211_ht_bss_info *req_bss_cap); |
| 877 | 857 | ||
| 878 | /* ieee80211_ioctl.c */ | 858 | /* ieee80211_ioctl.c */ |
| 879 | extern const struct iw_handler_def ieee80211_iw_handler_def; | 859 | extern const struct iw_handler_def ieee80211_iw_handler_def; |
| 880 | |||
| 881 | |||
| 882 | /* Least common multiple of the used rates (in 100 kbps). This is used to | ||
| 883 | * calculate rate_inv values for each rate so that only integers are needed. */ | ||
| 884 | #define CHAN_UTIL_RATE_LCM 95040 | ||
| 885 | /* 1 usec is 1/8 * (95040/10) = 1188 */ | ||
| 886 | #define CHAN_UTIL_PER_USEC 1188 | ||
| 887 | /* Amount of bits to shift the result right to scale the total utilization | ||
| 888 | * to values that will not wrap around 32-bit integers. */ | ||
| 889 | #define CHAN_UTIL_SHIFT 9 | ||
| 890 | /* Theoretical maximum of channel utilization counter in 10 ms (stat_time=1): | ||
| 891 | * (CHAN_UTIL_PER_USEC * 10000) >> CHAN_UTIL_SHIFT = 23203. So dividing the | ||
| 892 | * raw value with about 23 should give utilization in 10th of a percentage | ||
| 893 | * (1/1000). However, utilization is only estimated and not all intervals | ||
| 894 | * between frames etc. are calculated. 18 seems to give numbers that are closer | ||
| 895 | * to the real maximum. */ | ||
| 896 | #define CHAN_UTIL_PER_10MS 18 | ||
| 897 | #define CHAN_UTIL_HDR_LONG (202 * CHAN_UTIL_PER_USEC) | ||
| 898 | #define CHAN_UTIL_HDR_SHORT (40 * CHAN_UTIL_PER_USEC) | ||
| 899 | |||
| 900 | |||
| 901 | /* ieee80211_ioctl.c */ | ||
| 902 | int ieee80211_set_freq(struct net_device *dev, int freq); | 860 | int ieee80211_set_freq(struct net_device *dev, int freq); |
| 861 | |||
| 903 | /* ieee80211_sta.c */ | 862 | /* ieee80211_sta.c */ |
| 904 | void ieee80211_sta_timer(unsigned long data); | 863 | void ieee80211_sta_timer(unsigned long data); |
| 905 | void ieee80211_sta_work(struct work_struct *work); | 864 | void ieee80211_sta_work(struct work_struct *work); |
| @@ -912,21 +871,23 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid); | |||
| 912 | int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); | 871 | int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); |
| 913 | void ieee80211_sta_req_auth(struct net_device *dev, | 872 | void ieee80211_sta_req_auth(struct net_device *dev, |
| 914 | struct ieee80211_if_sta *ifsta); | 873 | struct ieee80211_if_sta *ifsta); |
| 915 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); | 874 | int ieee80211_sta_scan_results(struct net_device *dev, |
| 875 | struct iw_request_info *info, | ||
| 876 | char *buf, size_t len); | ||
| 916 | ieee80211_rx_result ieee80211_sta_rx_scan( | 877 | ieee80211_rx_result ieee80211_sta_rx_scan( |
| 917 | struct net_device *dev, struct sk_buff *skb, | 878 | struct net_device *dev, struct sk_buff *skb, |
| 918 | struct ieee80211_rx_status *rx_status); | 879 | struct ieee80211_rx_status *rx_status); |
| 919 | void ieee80211_rx_bss_list_init(struct net_device *dev); | 880 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local); |
| 920 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); | 881 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local); |
| 921 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); | 882 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); |
| 922 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | 883 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
| 923 | struct sk_buff *skb, u8 *bssid, | 884 | struct sk_buff *skb, u8 *bssid, |
| 924 | u8 *addr); | 885 | u8 *addr, u64 supp_rates); |
| 925 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); | 886 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); |
| 926 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); | 887 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); |
| 927 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 888 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
| 928 | u32 changed); | 889 | u32 changed); |
| 929 | void ieee80211_reset_erp_info(struct net_device *dev); | 890 | u32 ieee80211_reset_erp_info(struct net_device *dev); |
| 930 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, | 891 | int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie, |
| 931 | struct ieee80211_ht_info *ht_info); | 892 | struct ieee80211_ht_info *ht_info); |
| 932 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( | 893 | int ieee80211_ht_addt_info_ie_to_ht_bss_info( |
| @@ -937,10 +898,10 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, | |||
| 937 | u16 agg_size, u16 timeout); | 898 | u16 agg_size, u16 timeout); |
| 938 | void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | 899 | void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, |
| 939 | u16 initiator, u16 reason_code); | 900 | u16 initiator, u16 reason_code); |
| 901 | void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn); | ||
| 940 | 902 | ||
| 941 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, | 903 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, |
| 942 | u16 tid, u16 initiator, u16 reason); | 904 | u16 tid, u16 initiator, u16 reason); |
| 943 | void sta_rx_agg_session_timer_expired(unsigned long data); | ||
| 944 | void sta_addba_resp_timer_expired(unsigned long data); | 905 | void sta_addba_resp_timer_expired(unsigned long data); |
| 945 | void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr); | 906 | void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr); |
| 946 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, | 907 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, |
| @@ -958,17 +919,15 @@ static inline void ieee80211_start_mesh(struct net_device *dev) | |||
| 958 | {} | 919 | {} |
| 959 | #endif | 920 | #endif |
| 960 | 921 | ||
| 961 | /* ieee80211_iface.c */ | 922 | /* interface handling */ |
| 962 | int ieee80211_if_add(struct net_device *dev, const char *name, | 923 | void ieee80211_if_setup(struct net_device *dev); |
| 963 | struct net_device **new_dev, int type, | 924 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
| 925 | struct net_device **new_dev, enum ieee80211_if_types type, | ||
| 964 | struct vif_params *params); | 926 | struct vif_params *params); |
| 965 | void ieee80211_if_set_type(struct net_device *dev, int type); | 927 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
| 966 | void ieee80211_if_reinit(struct net_device *dev); | 928 | enum ieee80211_if_types type); |
| 967 | void __ieee80211_if_del(struct ieee80211_local *local, | 929 | void ieee80211_if_remove(struct net_device *dev); |
| 968 | struct ieee80211_sub_if_data *sdata); | 930 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
| 969 | int ieee80211_if_remove(struct net_device *dev, const char *name, int id); | ||
| 970 | void ieee80211_if_free(struct net_device *dev); | ||
| 971 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata); | ||
| 972 | 931 | ||
| 973 | /* tx handling */ | 932 | /* tx handling */ |
| 974 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); | 933 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); |
| @@ -988,4 +947,10 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
| 988 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | 947 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, |
| 989 | struct ieee80211_hdr *hdr); | 948 | struct ieee80211_hdr *hdr); |
| 990 | 949 | ||
| 950 | #ifdef CONFIG_MAC80211_NOINLINE | ||
| 951 | #define debug_noinline noinline | ||
| 952 | #else | ||
| 953 | #define debug_noinline | ||
| 954 | #endif | ||
| 955 | |||
| 991 | #endif /* IEEE80211_I_H */ | 956 | #endif /* IEEE80211_I_H */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 06e88a5a036d..610ed1d9893a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
| 3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
| 4 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> |
| 5 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
| 5 | * | 6 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| @@ -17,38 +18,164 @@ | |||
| 17 | #include "debugfs_netdev.h" | 18 | #include "debugfs_netdev.h" |
| 18 | #include "mesh.h" | 19 | #include "mesh.h" |
| 19 | 20 | ||
| 20 | void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) | 21 | /* |
| 22 | * Called when the netdev is removed or, by the code below, before | ||
| 23 | * the interface type changes. | ||
| 24 | */ | ||
| 25 | static void ieee80211_teardown_sdata(struct net_device *dev) | ||
| 21 | { | 26 | { |
| 27 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 28 | struct ieee80211_local *local = sdata->local; | ||
| 29 | struct beacon_data *beacon; | ||
| 30 | struct sk_buff *skb; | ||
| 31 | int flushed; | ||
| 22 | int i; | 32 | int i; |
| 23 | 33 | ||
| 24 | /* Default values for sub-interface parameters */ | 34 | ieee80211_debugfs_remove_netdev(sdata); |
| 25 | sdata->drop_unencrypted = 0; | 35 | |
| 36 | /* free extra data */ | ||
| 37 | ieee80211_free_keys(sdata); | ||
| 38 | |||
| 26 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) | 39 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |
| 27 | skb_queue_head_init(&sdata->fragments[i].skb_list); | 40 | __skb_queue_purge(&sdata->fragments[i].skb_list); |
| 41 | sdata->fragment_next = 0; | ||
| 28 | 42 | ||
| 29 | INIT_LIST_HEAD(&sdata->key_list); | 43 | switch (sdata->vif.type) { |
| 44 | case IEEE80211_IF_TYPE_AP: | ||
| 45 | beacon = sdata->u.ap.beacon; | ||
| 46 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
| 47 | synchronize_rcu(); | ||
| 48 | kfree(beacon); | ||
| 49 | |||
| 50 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { | ||
| 51 | local->total_ps_buffered--; | ||
| 52 | dev_kfree_skb(skb); | ||
| 53 | } | ||
| 54 | |||
| 55 | break; | ||
| 56 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
| 57 | /* Allow compiler to elide mesh_rmc_free call. */ | ||
| 58 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
| 59 | mesh_rmc_free(dev); | ||
| 60 | /* fall through */ | ||
| 61 | case IEEE80211_IF_TYPE_STA: | ||
| 62 | case IEEE80211_IF_TYPE_IBSS: | ||
| 63 | kfree(sdata->u.sta.extra_ie); | ||
| 64 | kfree(sdata->u.sta.assocreq_ies); | ||
| 65 | kfree(sdata->u.sta.assocresp_ies); | ||
| 66 | kfree_skb(sdata->u.sta.probe_resp); | ||
| 67 | break; | ||
| 68 | case IEEE80211_IF_TYPE_WDS: | ||
| 69 | case IEEE80211_IF_TYPE_VLAN: | ||
| 70 | case IEEE80211_IF_TYPE_MNTR: | ||
| 71 | break; | ||
| 72 | case IEEE80211_IF_TYPE_INVALID: | ||
| 73 | BUG(); | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | |||
| 77 | flushed = sta_info_flush(local, sdata); | ||
| 78 | WARN_ON(flushed); | ||
| 30 | } | 79 | } |
| 31 | 80 | ||
| 32 | static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) | 81 | /* |
| 82 | * Helper function to initialise an interface to a specific type. | ||
| 83 | */ | ||
| 84 | static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | ||
| 85 | enum ieee80211_if_types type) | ||
| 33 | { | 86 | { |
| 34 | int i; | 87 | struct ieee80211_if_sta *ifsta; |
| 35 | 88 | ||
| 36 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { | 89 | /* clear type-dependent union */ |
| 37 | __skb_queue_purge(&sdata->fragments[i].skb_list); | 90 | memset(&sdata->u, 0, sizeof(sdata->u)); |
| 91 | |||
| 92 | /* and set some type-dependent values */ | ||
| 93 | sdata->vif.type = type; | ||
| 94 | |||
| 95 | /* only monitor differs */ | ||
| 96 | sdata->dev->type = ARPHRD_ETHER; | ||
| 97 | |||
| 98 | switch (type) { | ||
| 99 | case IEEE80211_IF_TYPE_AP: | ||
| 100 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | ||
| 101 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | ||
| 102 | break; | ||
| 103 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
| 104 | case IEEE80211_IF_TYPE_STA: | ||
| 105 | case IEEE80211_IF_TYPE_IBSS: | ||
| 106 | ifsta = &sdata->u.sta; | ||
| 107 | INIT_WORK(&ifsta->work, ieee80211_sta_work); | ||
| 108 | setup_timer(&ifsta->timer, ieee80211_sta_timer, | ||
| 109 | (unsigned long) sdata); | ||
| 110 | skb_queue_head_init(&ifsta->skb_queue); | ||
| 111 | |||
| 112 | ifsta->capab = WLAN_CAPABILITY_ESS; | ||
| 113 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | | ||
| 114 | IEEE80211_AUTH_ALG_SHARED_KEY; | ||
| 115 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | | ||
| 116 | IEEE80211_STA_AUTO_BSSID_SEL | | ||
| 117 | IEEE80211_STA_AUTO_CHANNEL_SEL; | ||
| 118 | if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4) | ||
| 119 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; | ||
| 120 | |||
| 121 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
| 122 | ieee80211_mesh_init_sdata(sdata); | ||
| 123 | break; | ||
| 124 | case IEEE80211_IF_TYPE_MNTR: | ||
| 125 | sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP; | ||
| 126 | sdata->dev->hard_start_xmit = ieee80211_monitor_start_xmit; | ||
| 127 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | | ||
| 128 | MONITOR_FLAG_OTHER_BSS; | ||
| 129 | break; | ||
| 130 | case IEEE80211_IF_TYPE_WDS: | ||
| 131 | case IEEE80211_IF_TYPE_VLAN: | ||
| 132 | break; | ||
| 133 | case IEEE80211_IF_TYPE_INVALID: | ||
| 134 | BUG(); | ||
| 135 | break; | ||
| 38 | } | 136 | } |
| 137 | |||
| 138 | ieee80211_debugfs_add_netdev(sdata); | ||
| 139 | } | ||
| 140 | |||
| 141 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | ||
| 142 | enum ieee80211_if_types type) | ||
| 143 | { | ||
| 144 | ASSERT_RTNL(); | ||
| 145 | |||
| 146 | if (type == sdata->vif.type) | ||
| 147 | return 0; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * We could, here, on changes between IBSS/STA/MESH modes, | ||
| 151 | * invoke an MLME function instead that disassociates etc. | ||
| 152 | * and goes into the requested mode. | ||
| 153 | */ | ||
| 154 | |||
| 155 | if (netif_running(sdata->dev)) | ||
| 156 | return -EBUSY; | ||
| 157 | |||
| 158 | /* Purge and reset type-dependent state. */ | ||
| 159 | ieee80211_teardown_sdata(sdata->dev); | ||
| 160 | ieee80211_setup_sdata(sdata, type); | ||
| 161 | |||
| 162 | /* reset some values that shouldn't be kept across type changes */ | ||
| 163 | sdata->basic_rates = 0; | ||
| 164 | sdata->drop_unencrypted = 0; | ||
| 165 | |||
| 166 | return 0; | ||
| 39 | } | 167 | } |
| 40 | 168 | ||
| 41 | /* Must be called with rtnl lock held. */ | 169 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
| 42 | int ieee80211_if_add(struct net_device *dev, const char *name, | 170 | struct net_device **new_dev, enum ieee80211_if_types type, |
| 43 | struct net_device **new_dev, int type, | ||
| 44 | struct vif_params *params) | 171 | struct vif_params *params) |
| 45 | { | 172 | { |
| 46 | struct net_device *ndev; | 173 | struct net_device *ndev; |
| 47 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 48 | struct ieee80211_sub_if_data *sdata = NULL; | 174 | struct ieee80211_sub_if_data *sdata = NULL; |
| 49 | int ret; | 175 | int ret, i; |
| 50 | 176 | ||
| 51 | ASSERT_RTNL(); | 177 | ASSERT_RTNL(); |
| 178 | |||
| 52 | ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, | 179 | ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, |
| 53 | name, ieee80211_if_setup); | 180 | name, ieee80211_if_setup); |
| 54 | if (!ndev) | 181 | if (!ndev) |
| @@ -68,26 +195,33 @@ int ieee80211_if_add(struct net_device *dev, const char *name, | |||
| 68 | goto fail; | 195 | goto fail; |
| 69 | 196 | ||
| 70 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 197 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
| 71 | ndev->base_addr = dev->base_addr; | ||
| 72 | ndev->irq = dev->irq; | ||
| 73 | ndev->mem_start = dev->mem_start; | ||
| 74 | ndev->mem_end = dev->mem_end; | ||
| 75 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 198 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
| 76 | 199 | ||
| 77 | sdata = IEEE80211_DEV_TO_SUB_IF(ndev); | 200 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
| 201 | sdata = netdev_priv(ndev); | ||
| 78 | ndev->ieee80211_ptr = &sdata->wdev; | 202 | ndev->ieee80211_ptr = &sdata->wdev; |
| 203 | |||
| 204 | /* initialise type-independent data */ | ||
| 79 | sdata->wdev.wiphy = local->hw.wiphy; | 205 | sdata->wdev.wiphy = local->hw.wiphy; |
| 80 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
| 81 | sdata->dev = ndev; | ||
| 82 | sdata->local = local; | 206 | sdata->local = local; |
| 83 | ieee80211_if_sdata_init(sdata); | 207 | sdata->dev = ndev; |
| 208 | |||
| 209 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) | ||
| 210 | skb_queue_head_init(&sdata->fragments[i].skb_list); | ||
| 211 | |||
| 212 | INIT_LIST_HEAD(&sdata->key_list); | ||
| 213 | |||
| 214 | sdata->force_unicast_rateidx = -1; | ||
| 215 | sdata->max_ratectrl_rateidx = -1; | ||
| 216 | |||
| 217 | /* setup type-dependent data */ | ||
| 218 | ieee80211_setup_sdata(sdata, type); | ||
| 84 | 219 | ||
| 85 | ret = register_netdevice(ndev); | 220 | ret = register_netdevice(ndev); |
| 86 | if (ret) | 221 | if (ret) |
| 87 | goto fail; | 222 | goto fail; |
| 88 | 223 | ||
| 89 | ieee80211_debugfs_add_netdev(sdata); | 224 | ndev->uninit = ieee80211_teardown_sdata; |
| 90 | ieee80211_if_set_type(ndev, type); | ||
| 91 | 225 | ||
| 92 | if (ieee80211_vif_is_mesh(&sdata->vif) && | 226 | if (ieee80211_vif_is_mesh(&sdata->vif) && |
| 93 | params && params->mesh_id_len) | 227 | params && params->mesh_id_len) |
| @@ -95,11 +229,6 @@ int ieee80211_if_add(struct net_device *dev, const char *name, | |||
| 95 | params->mesh_id_len, | 229 | params->mesh_id_len, |
| 96 | params->mesh_id); | 230 | params->mesh_id); |
| 97 | 231 | ||
| 98 | /* we're under RTNL so all this is fine */ | ||
| 99 | if (unlikely(local->reg_state == IEEE80211_DEV_UNREGISTERED)) { | ||
| 100 | __ieee80211_if_del(local, sdata); | ||
| 101 | return -ENODEV; | ||
| 102 | } | ||
| 103 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 232 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
| 104 | 233 | ||
| 105 | if (new_dev) | 234 | if (new_dev) |
| @@ -107,217 +236,34 @@ int ieee80211_if_add(struct net_device *dev, const char *name, | |||
| 107 | 236 | ||
| 108 | return 0; | 237 | return 0; |
| 109 | 238 | ||
| 110 | fail: | 239 | fail: |
| 111 | free_netdev(ndev); | 240 | free_netdev(ndev); |
| 112 | return ret; | 241 | return ret; |
| 113 | } | 242 | } |
| 114 | 243 | ||
| 115 | void ieee80211_if_set_type(struct net_device *dev, int type) | 244 | void ieee80211_if_remove(struct net_device *dev) |
| 116 | { | ||
| 117 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 118 | int oldtype = sdata->vif.type; | ||
| 119 | |||
| 120 | /* | ||
| 121 | * We need to call this function on the master interface | ||
| 122 | * which already has a hard_start_xmit routine assigned | ||
| 123 | * which must not be changed. | ||
| 124 | */ | ||
| 125 | if (dev != sdata->local->mdev) | ||
| 126 | dev->hard_start_xmit = ieee80211_subif_start_xmit; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Called even when register_netdevice fails, it would | ||
| 130 | * oops if assigned before initialising the rest. | ||
| 131 | */ | ||
| 132 | dev->uninit = ieee80211_if_reinit; | ||
| 133 | |||
| 134 | /* most have no BSS pointer */ | ||
| 135 | sdata->bss = NULL; | ||
| 136 | sdata->vif.type = type; | ||
| 137 | |||
| 138 | sdata->basic_rates = 0; | ||
| 139 | |||
| 140 | switch (type) { | ||
| 141 | case IEEE80211_IF_TYPE_WDS: | ||
| 142 | /* nothing special */ | ||
| 143 | break; | ||
| 144 | case IEEE80211_IF_TYPE_VLAN: | ||
| 145 | sdata->u.vlan.ap = NULL; | ||
| 146 | break; | ||
| 147 | case IEEE80211_IF_TYPE_AP: | ||
| 148 | sdata->u.ap.force_unicast_rateidx = -1; | ||
| 149 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
| 150 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | ||
| 151 | sdata->bss = &sdata->u.ap; | ||
| 152 | INIT_LIST_HEAD(&sdata->u.ap.vlans); | ||
| 153 | break; | ||
| 154 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
| 155 | case IEEE80211_IF_TYPE_STA: | ||
| 156 | case IEEE80211_IF_TYPE_IBSS: { | ||
| 157 | struct ieee80211_sub_if_data *msdata; | ||
| 158 | struct ieee80211_if_sta *ifsta; | ||
| 159 | |||
| 160 | ifsta = &sdata->u.sta; | ||
| 161 | INIT_WORK(&ifsta->work, ieee80211_sta_work); | ||
| 162 | setup_timer(&ifsta->timer, ieee80211_sta_timer, | ||
| 163 | (unsigned long) sdata); | ||
| 164 | skb_queue_head_init(&ifsta->skb_queue); | ||
| 165 | |||
| 166 | ifsta->capab = WLAN_CAPABILITY_ESS; | ||
| 167 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | | ||
| 168 | IEEE80211_AUTH_ALG_SHARED_KEY; | ||
| 169 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | | ||
| 170 | IEEE80211_STA_WMM_ENABLED | | ||
| 171 | IEEE80211_STA_AUTO_BSSID_SEL | | ||
| 172 | IEEE80211_STA_AUTO_CHANNEL_SEL; | ||
| 173 | |||
| 174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | ||
| 175 | sdata->bss = &msdata->u.ap; | ||
| 176 | |||
| 177 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
| 178 | ieee80211_mesh_init_sdata(sdata); | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | case IEEE80211_IF_TYPE_MNTR: | ||
| 182 | dev->type = ARPHRD_IEEE80211_RADIOTAP; | ||
| 183 | dev->hard_start_xmit = ieee80211_monitor_start_xmit; | ||
| 184 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | | ||
| 185 | MONITOR_FLAG_OTHER_BSS; | ||
| 186 | break; | ||
| 187 | default: | ||
| 188 | printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", | ||
| 189 | dev->name, __func__, type); | ||
| 190 | } | ||
| 191 | ieee80211_debugfs_change_if_type(sdata, oldtype); | ||
| 192 | } | ||
| 193 | |||
| 194 | /* Must be called with rtnl lock held. */ | ||
| 195 | void ieee80211_if_reinit(struct net_device *dev) | ||
| 196 | { | 245 | { |
| 197 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 198 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 246 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 199 | struct sk_buff *skb; | ||
| 200 | int flushed; | ||
| 201 | 247 | ||
| 202 | ASSERT_RTNL(); | 248 | ASSERT_RTNL(); |
| 203 | 249 | ||
| 204 | ieee80211_free_keys(sdata); | 250 | list_del_rcu(&sdata->list); |
| 205 | 251 | synchronize_rcu(); | |
| 206 | ieee80211_if_sdata_deinit(sdata); | ||
| 207 | |||
| 208 | /* Need to handle mesh specially to allow eliding the function call */ | ||
| 209 | if (ieee80211_vif_is_mesh(&sdata->vif)) | ||
| 210 | mesh_rmc_free(dev); | ||
| 211 | |||
| 212 | switch (sdata->vif.type) { | ||
| 213 | case IEEE80211_IF_TYPE_INVALID: | ||
| 214 | /* cannot happen */ | ||
| 215 | WARN_ON(1); | ||
| 216 | break; | ||
| 217 | case IEEE80211_IF_TYPE_AP: { | ||
| 218 | /* Remove all virtual interfaces that use this BSS | ||
| 219 | * as their sdata->bss */ | ||
| 220 | struct ieee80211_sub_if_data *tsdata, *n; | ||
| 221 | struct beacon_data *beacon; | ||
| 222 | |||
| 223 | list_for_each_entry_safe(tsdata, n, &local->interfaces, list) { | ||
| 224 | if (tsdata != sdata && tsdata->bss == &sdata->u.ap) { | ||
| 225 | printk(KERN_DEBUG "%s: removing virtual " | ||
| 226 | "interface %s because its BSS interface" | ||
| 227 | " is being removed\n", | ||
| 228 | sdata->dev->name, tsdata->dev->name); | ||
| 229 | list_del_rcu(&tsdata->list); | ||
| 230 | /* | ||
| 231 | * We have lots of time and can afford | ||
| 232 | * to sync for each interface | ||
| 233 | */ | ||
| 234 | synchronize_rcu(); | ||
| 235 | __ieee80211_if_del(local, tsdata); | ||
| 236 | } | ||
| 237 | } | ||
| 238 | |||
| 239 | beacon = sdata->u.ap.beacon; | ||
| 240 | rcu_assign_pointer(sdata->u.ap.beacon, NULL); | ||
| 241 | synchronize_rcu(); | ||
| 242 | kfree(beacon); | ||
| 243 | |||
| 244 | while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { | ||
| 245 | local->total_ps_buffered--; | ||
| 246 | dev_kfree_skb(skb); | ||
| 247 | } | ||
| 248 | |||
| 249 | break; | ||
| 250 | } | ||
| 251 | case IEEE80211_IF_TYPE_WDS: | ||
| 252 | /* nothing to do */ | ||
| 253 | break; | ||
| 254 | case IEEE80211_IF_TYPE_MESH_POINT: | ||
| 255 | case IEEE80211_IF_TYPE_STA: | ||
| 256 | case IEEE80211_IF_TYPE_IBSS: | ||
| 257 | kfree(sdata->u.sta.extra_ie); | ||
| 258 | sdata->u.sta.extra_ie = NULL; | ||
| 259 | kfree(sdata->u.sta.assocreq_ies); | ||
| 260 | sdata->u.sta.assocreq_ies = NULL; | ||
| 261 | kfree(sdata->u.sta.assocresp_ies); | ||
| 262 | sdata->u.sta.assocresp_ies = NULL; | ||
| 263 | if (sdata->u.sta.probe_resp) { | ||
| 264 | dev_kfree_skb(sdata->u.sta.probe_resp); | ||
| 265 | sdata->u.sta.probe_resp = NULL; | ||
| 266 | } | ||
| 267 | |||
| 268 | break; | ||
| 269 | case IEEE80211_IF_TYPE_MNTR: | ||
| 270 | dev->type = ARPHRD_ETHER; | ||
| 271 | break; | ||
| 272 | case IEEE80211_IF_TYPE_VLAN: | ||
| 273 | sdata->u.vlan.ap = NULL; | ||
| 274 | break; | ||
| 275 | } | ||
| 276 | |||
| 277 | flushed = sta_info_flush(local, sdata); | ||
| 278 | WARN_ON(flushed); | ||
| 279 | |||
| 280 | memset(&sdata->u, 0, sizeof(sdata->u)); | ||
| 281 | ieee80211_if_sdata_init(sdata); | ||
| 282 | } | ||
| 283 | |||
| 284 | /* Must be called with rtnl lock held. */ | ||
| 285 | void __ieee80211_if_del(struct ieee80211_local *local, | ||
| 286 | struct ieee80211_sub_if_data *sdata) | ||
| 287 | { | ||
| 288 | struct net_device *dev = sdata->dev; | ||
| 289 | |||
| 290 | ieee80211_debugfs_remove_netdev(sdata); | ||
| 291 | unregister_netdevice(dev); | 252 | unregister_netdevice(dev); |
| 292 | /* Except master interface, the net_device will be freed by | ||
| 293 | * net_device->destructor (i. e. ieee80211_if_free). */ | ||
| 294 | } | 253 | } |
| 295 | 254 | ||
| 296 | /* Must be called with rtnl lock held. */ | 255 | /* |
| 297 | int ieee80211_if_remove(struct net_device *dev, const char *name, int id) | 256 | * Remove all interfaces, may only be called at hardware unregistration |
| 257 | * time because it doesn't do RCU-safe list removals. | ||
| 258 | */ | ||
| 259 | void ieee80211_remove_interfaces(struct ieee80211_local *local) | ||
| 298 | { | 260 | { |
| 299 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 261 | struct ieee80211_sub_if_data *sdata, *tmp; |
| 300 | struct ieee80211_sub_if_data *sdata, *n; | ||
| 301 | 262 | ||
| 302 | ASSERT_RTNL(); | 263 | ASSERT_RTNL(); |
| 303 | 264 | ||
| 304 | list_for_each_entry_safe(sdata, n, &local->interfaces, list) { | 265 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
| 305 | if ((sdata->vif.type == id || id == -1) && | 266 | list_del(&sdata->list); |
| 306 | strcmp(name, sdata->dev->name) == 0 && | 267 | unregister_netdevice(sdata->dev); |
| 307 | sdata->dev != local->mdev) { | ||
| 308 | list_del_rcu(&sdata->list); | ||
| 309 | synchronize_rcu(); | ||
| 310 | __ieee80211_if_del(local, sdata); | ||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | } | 268 | } |
| 314 | return -ENODEV; | ||
| 315 | } | ||
| 316 | |||
| 317 | void ieee80211_if_free(struct net_device *dev) | ||
| 318 | { | ||
| 319 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 320 | |||
| 321 | ieee80211_if_sdata_deinit(sdata); | ||
| 322 | free_netdev(dev); | ||
| 323 | } | 269 | } |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 150d66dbda9d..6597c779e35a 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
| @@ -321,8 +321,15 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
| 321 | * some hardware cannot handle TKIP with QoS, so | 321 | * some hardware cannot handle TKIP with QoS, so |
| 322 | * we indicate whether QoS could be in use. | 322 | * we indicate whether QoS could be in use. |
| 323 | */ | 323 | */ |
| 324 | if (sta->flags & WLAN_STA_WME) | 324 | if (test_sta_flags(sta, WLAN_STA_WME)) |
| 325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
| 326 | |||
| 327 | /* | ||
| 328 | * This key is for a specific sta interface, | ||
| 329 | * inform the driver that it should try to store | ||
| 330 | * this key as pairwise key. | ||
| 331 | */ | ||
| 332 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | ||
| 326 | } else { | 333 | } else { |
| 327 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 334 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { |
| 328 | struct sta_info *ap; | 335 | struct sta_info *ap; |
| @@ -335,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
| 335 | /* same here, the AP could be using QoS */ | 342 | /* same here, the AP could be using QoS */ |
| 336 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); | 343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); |
| 337 | if (ap) { | 344 | if (ap) { |
| 338 | if (ap->flags & WLAN_STA_WME) | 345 | if (test_sta_flags(ap, WLAN_STA_WME)) |
| 339 | key->conf.flags |= | 346 | key->conf.flags |= |
| 340 | IEEE80211_KEY_FLAG_WMM_STA; | 347 | IEEE80211_KEY_FLAG_WMM_STA; |
| 341 | } | 348 | } |
| @@ -380,6 +387,15 @@ void ieee80211_key_free(struct ieee80211_key *key) | |||
| 380 | if (!key) | 387 | if (!key) |
| 381 | return; | 388 | return; |
| 382 | 389 | ||
| 390 | if (!key->sdata) { | ||
| 391 | /* The key has not been linked yet, simply free it | ||
| 392 | * and don't Oops */ | ||
| 393 | if (key->conf.alg == ALG_CCMP) | ||
| 394 | ieee80211_aes_key_free(key->u.ccmp.tfm); | ||
| 395 | kfree(key); | ||
| 396 | return; | ||
| 397 | } | ||
| 398 | |||
| 383 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); | 399 | spin_lock_irqsave(&key->sdata->local->key_lock, flags); |
| 384 | __ieee80211_key_free(key); | 400 | __ieee80211_key_free(key); |
| 385 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); | 401 | spin_unlock_irqrestore(&key->sdata->local->key_lock, flags); |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index f52c3df1fe9a..425816e0996c 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
| @@ -16,31 +16,18 @@ | |||
| 16 | #include <linux/rcupdate.h> | 16 | #include <linux/rcupdate.h> |
| 17 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
| 18 | 18 | ||
| 19 | /* ALG_TKIP | 19 | #define WEP_IV_LEN 4 |
| 20 | * struct ieee80211_key::key is encoded as a 256-bit (32 byte) data block: | 20 | #define WEP_ICV_LEN 4 |
| 21 | * Temporal Encryption Key (128 bits) | 21 | #define ALG_TKIP_KEY_LEN 32 |
| 22 | * Temporal Authenticator Tx MIC Key (64 bits) | 22 | #define ALG_CCMP_KEY_LEN 16 |
| 23 | * Temporal Authenticator Rx MIC Key (64 bits) | 23 | #define CCMP_HDR_LEN 8 |
| 24 | */ | 24 | #define CCMP_MIC_LEN 8 |
| 25 | 25 | #define CCMP_TK_LEN 16 | |
| 26 | #define WEP_IV_LEN 4 | 26 | #define CCMP_PN_LEN 6 |
| 27 | #define WEP_ICV_LEN 4 | 27 | #define TKIP_IV_LEN 8 |
| 28 | 28 | #define TKIP_ICV_LEN 4 | |
| 29 | #define ALG_TKIP_KEY_LEN 32 | 29 | |
| 30 | /* Starting offsets for each key */ | 30 | #define NUM_RX_DATA_QUEUES 17 |
| 31 | #define ALG_TKIP_TEMP_ENCR_KEY 0 | ||
| 32 | #define ALG_TKIP_TEMP_AUTH_TX_MIC_KEY 16 | ||
| 33 | #define ALG_TKIP_TEMP_AUTH_RX_MIC_KEY 24 | ||
| 34 | #define TKIP_IV_LEN 8 | ||
| 35 | #define TKIP_ICV_LEN 4 | ||
| 36 | |||
| 37 | #define ALG_CCMP_KEY_LEN 16 | ||
| 38 | #define CCMP_HDR_LEN 8 | ||
| 39 | #define CCMP_MIC_LEN 8 | ||
| 40 | #define CCMP_TK_LEN 16 | ||
| 41 | #define CCMP_PN_LEN 6 | ||
| 42 | |||
| 43 | #define NUM_RX_DATA_QUEUES 17 | ||
| 44 | 31 | ||
| 45 | struct ieee80211_local; | 32 | struct ieee80211_local; |
| 46 | struct ieee80211_sub_if_data; | 33 | struct ieee80211_sub_if_data; |
| @@ -69,6 +56,13 @@ enum ieee80211_internal_key_flags { | |||
| 69 | KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5), | 56 | KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5), |
| 70 | }; | 57 | }; |
| 71 | 58 | ||
| 59 | struct tkip_ctx { | ||
| 60 | u32 iv32; | ||
| 61 | u16 iv16; | ||
| 62 | u16 p1k[5]; | ||
| 63 | int initialized; | ||
| 64 | }; | ||
| 65 | |||
| 72 | struct ieee80211_key { | 66 | struct ieee80211_key { |
| 73 | struct ieee80211_local *local; | 67 | struct ieee80211_local *local; |
| 74 | struct ieee80211_sub_if_data *sdata; | 68 | struct ieee80211_sub_if_data *sdata; |
| @@ -85,16 +79,10 @@ struct ieee80211_key { | |||
| 85 | union { | 79 | union { |
| 86 | struct { | 80 | struct { |
| 87 | /* last used TSC */ | 81 | /* last used TSC */ |
| 88 | u32 iv32; | 82 | struct tkip_ctx tx; |
| 89 | u16 iv16; | ||
| 90 | u16 p1k[5]; | ||
| 91 | int tx_initialized; | ||
| 92 | 83 | ||
| 93 | /* last received RSC */ | 84 | /* last received RSC */ |
| 94 | u32 iv32_rx[NUM_RX_DATA_QUEUES]; | 85 | struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; |
| 95 | u16 iv16_rx[NUM_RX_DATA_QUEUES]; | ||
| 96 | u16 p1k_rx[NUM_RX_DATA_QUEUES][5]; | ||
| 97 | int rx_initialized[NUM_RX_DATA_QUEUES]; | ||
| 98 | } tkip; | 86 | } tkip; |
| 99 | struct { | 87 | struct { |
| 100 | u8 tx_pn[6]; | 88 | u8 tx_pn[6]; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 98c0b5e56ecc..f1a83d450ea0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -35,8 +35,6 @@ | |||
| 35 | #include "debugfs.h" | 35 | #include "debugfs.h" |
| 36 | #include "debugfs_netdev.h" | 36 | #include "debugfs_netdev.h" |
| 37 | 37 | ||
| 38 | #define SUPP_MCS_SET_LEN 16 | ||
| 39 | |||
| 40 | /* | 38 | /* |
| 41 | * For seeing transmitted packets on monitor interfaces | 39 | * For seeing transmitted packets on monitor interfaces |
| 42 | * we have a radiotap header too. | 40 | * we have a radiotap header too. |
| @@ -107,12 +105,18 @@ static int ieee80211_master_open(struct net_device *dev) | |||
| 107 | 105 | ||
| 108 | /* we hold the RTNL here so can safely walk the list */ | 106 | /* we hold the RTNL here so can safely walk the list */ |
| 109 | list_for_each_entry(sdata, &local->interfaces, list) { | 107 | list_for_each_entry(sdata, &local->interfaces, list) { |
| 110 | if (sdata->dev != dev && netif_running(sdata->dev)) { | 108 | if (netif_running(sdata->dev)) { |
| 111 | res = 0; | 109 | res = 0; |
| 112 | break; | 110 | break; |
| 113 | } | 111 | } |
| 114 | } | 112 | } |
| 115 | return res; | 113 | |
| 114 | if (res) | ||
| 115 | return res; | ||
| 116 | |||
| 117 | netif_tx_start_all_queues(local->mdev); | ||
| 118 | |||
| 119 | return 0; | ||
| 116 | } | 120 | } |
| 117 | 121 | ||
| 118 | static int ieee80211_master_stop(struct net_device *dev) | 122 | static int ieee80211_master_stop(struct net_device *dev) |
| @@ -122,7 +126,7 @@ static int ieee80211_master_stop(struct net_device *dev) | |||
| 122 | 126 | ||
| 123 | /* we hold the RTNL here so can safely walk the list */ | 127 | /* we hold the RTNL here so can safely walk the list */ |
| 124 | list_for_each_entry(sdata, &local->interfaces, list) | 128 | list_for_each_entry(sdata, &local->interfaces, list) |
| 125 | if (sdata->dev != dev && netif_running(sdata->dev)) | 129 | if (netif_running(sdata->dev)) |
| 126 | dev_close(sdata->dev); | 130 | dev_close(sdata->dev); |
| 127 | 131 | ||
| 128 | return 0; | 132 | return 0; |
| @@ -147,9 +151,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
| 147 | /* FIX: what would be proper limits for MTU? | 151 | /* FIX: what would be proper limits for MTU? |
| 148 | * This interface uses 802.3 frames. */ | 152 | * This interface uses 802.3 frames. */ |
| 149 | if (new_mtu < 256 || | 153 | if (new_mtu < 256 || |
| 150 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | 154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { |
| 151 | printk(KERN_WARNING "%s: invalid MTU %d\n", | ||
| 152 | dev->name, new_mtu); | ||
| 153 | return -EINVAL; | 155 | return -EINVAL; |
| 154 | } | 156 | } |
| 155 | 157 | ||
| @@ -180,10 +182,11 @@ static int ieee80211_open(struct net_device *dev) | |||
| 180 | { | 182 | { |
| 181 | struct ieee80211_sub_if_data *sdata, *nsdata; | 183 | struct ieee80211_sub_if_data *sdata, *nsdata; |
| 182 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 184 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 185 | struct sta_info *sta; | ||
| 183 | struct ieee80211_if_init_conf conf; | 186 | struct ieee80211_if_init_conf conf; |
| 187 | u32 changed = 0; | ||
| 184 | int res; | 188 | int res; |
| 185 | bool need_hw_reconfig = 0; | 189 | bool need_hw_reconfig = 0; |
| 186 | struct sta_info *sta; | ||
| 187 | 190 | ||
| 188 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 191 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 189 | 192 | ||
| @@ -191,7 +194,7 @@ static int ieee80211_open(struct net_device *dev) | |||
| 191 | list_for_each_entry(nsdata, &local->interfaces, list) { | 194 | list_for_each_entry(nsdata, &local->interfaces, list) { |
| 192 | struct net_device *ndev = nsdata->dev; | 195 | struct net_device *ndev = nsdata->dev; |
| 193 | 196 | ||
| 194 | if (ndev != dev && ndev != local->mdev && netif_running(ndev)) { | 197 | if (ndev != dev && netif_running(ndev)) { |
| 195 | /* | 198 | /* |
| 196 | * Allow only a single IBSS interface to be up at any | 199 | * Allow only a single IBSS interface to be up at any |
| 197 | * time. This is restricted because beacon distribution | 200 | * time. This is restricted because beacon distribution |
| @@ -207,30 +210,6 @@ static int ieee80211_open(struct net_device *dev) | |||
| 207 | return -EBUSY; | 210 | return -EBUSY; |
| 208 | 211 | ||
| 209 | /* | 212 | /* |
| 210 | * Disallow multiple IBSS/STA mode interfaces. | ||
| 211 | * | ||
| 212 | * This is a technical restriction, it is possible although | ||
| 213 | * most likely not IEEE 802.11 compliant to have multiple | ||
| 214 | * STAs with just a single hardware (the TSF timer will not | ||
| 215 | * be adjusted properly.) | ||
| 216 | * | ||
| 217 | * However, because mac80211 uses the master device's BSS | ||
| 218 | * information for each STA/IBSS interface, doing this will | ||
| 219 | * currently corrupt that BSS information completely, unless, | ||
| 220 | * a not very useful case, both STAs are associated to the | ||
| 221 | * same BSS. | ||
| 222 | * | ||
| 223 | * To remove this restriction, the BSS information needs to | ||
| 224 | * be embedded in the STA/IBSS mode sdata instead of using | ||
| 225 | * the master device's BSS structure. | ||
| 226 | */ | ||
| 227 | if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
| 228 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) && | ||
| 229 | (nsdata->vif.type == IEEE80211_IF_TYPE_STA || | ||
| 230 | nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)) | ||
| 231 | return -EBUSY; | ||
| 232 | |||
| 233 | /* | ||
| 234 | * The remaining checks are only performed for interfaces | 213 | * The remaining checks are only performed for interfaces |
| 235 | * with the same MAC address. | 214 | * with the same MAC address. |
| 236 | */ | 215 | */ |
| @@ -249,7 +228,7 @@ static int ieee80211_open(struct net_device *dev) | |||
| 249 | */ | 228 | */ |
| 250 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && | 229 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN && |
| 251 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) | 230 | nsdata->vif.type == IEEE80211_IF_TYPE_AP) |
| 252 | sdata->u.vlan.ap = nsdata; | 231 | sdata->bss = &nsdata->u.ap; |
| 253 | } | 232 | } |
| 254 | } | 233 | } |
| 255 | 234 | ||
| @@ -259,10 +238,13 @@ static int ieee80211_open(struct net_device *dev) | |||
| 259 | return -ENOLINK; | 238 | return -ENOLINK; |
| 260 | break; | 239 | break; |
| 261 | case IEEE80211_IF_TYPE_VLAN: | 240 | case IEEE80211_IF_TYPE_VLAN: |
| 262 | if (!sdata->u.vlan.ap) | 241 | if (!sdata->bss) |
| 263 | return -ENOLINK; | 242 | return -ENOLINK; |
| 243 | list_add(&sdata->u.vlan.list, &sdata->bss->vlans); | ||
| 264 | break; | 244 | break; |
| 265 | case IEEE80211_IF_TYPE_AP: | 245 | case IEEE80211_IF_TYPE_AP: |
| 246 | sdata->bss = &sdata->u.ap; | ||
| 247 | break; | ||
| 266 | case IEEE80211_IF_TYPE_STA: | 248 | case IEEE80211_IF_TYPE_STA: |
| 267 | case IEEE80211_IF_TYPE_MNTR: | 249 | case IEEE80211_IF_TYPE_MNTR: |
| 268 | case IEEE80211_IF_TYPE_IBSS: | 250 | case IEEE80211_IF_TYPE_IBSS: |
| @@ -280,14 +262,13 @@ static int ieee80211_open(struct net_device *dev) | |||
| 280 | if (local->ops->start) | 262 | if (local->ops->start) |
| 281 | res = local->ops->start(local_to_hw(local)); | 263 | res = local->ops->start(local_to_hw(local)); |
| 282 | if (res) | 264 | if (res) |
| 283 | return res; | 265 | goto err_del_bss; |
| 284 | need_hw_reconfig = 1; | 266 | need_hw_reconfig = 1; |
| 285 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 267 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
| 286 | } | 268 | } |
| 287 | 269 | ||
| 288 | switch (sdata->vif.type) { | 270 | switch (sdata->vif.type) { |
| 289 | case IEEE80211_IF_TYPE_VLAN: | 271 | case IEEE80211_IF_TYPE_VLAN: |
| 290 | list_add(&sdata->u.vlan.list, &sdata->u.vlan.ap->u.ap.vlans); | ||
| 291 | /* no need to tell driver */ | 272 | /* no need to tell driver */ |
| 292 | break; | 273 | break; |
| 293 | case IEEE80211_IF_TYPE_MNTR: | 274 | case IEEE80211_IF_TYPE_MNTR: |
| @@ -310,9 +291,9 @@ static int ieee80211_open(struct net_device *dev) | |||
| 310 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 291 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
| 311 | local->fif_other_bss++; | 292 | local->fif_other_bss++; |
| 312 | 293 | ||
| 313 | netif_tx_lock_bh(local->mdev); | 294 | netif_addr_lock_bh(local->mdev); |
| 314 | ieee80211_configure_filter(local); | 295 | ieee80211_configure_filter(local); |
| 315 | netif_tx_unlock_bh(local->mdev); | 296 | netif_addr_unlock_bh(local->mdev); |
| 316 | break; | 297 | break; |
| 317 | case IEEE80211_IF_TYPE_STA: | 298 | case IEEE80211_IF_TYPE_STA: |
| 318 | case IEEE80211_IF_TYPE_IBSS: | 299 | case IEEE80211_IF_TYPE_IBSS: |
| @@ -326,8 +307,10 @@ static int ieee80211_open(struct net_device *dev) | |||
| 326 | if (res) | 307 | if (res) |
| 327 | goto err_stop; | 308 | goto err_stop; |
| 328 | 309 | ||
| 329 | ieee80211_if_config(dev); | 310 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
| 330 | ieee80211_reset_erp_info(dev); | 311 | ieee80211_start_mesh(sdata->dev); |
| 312 | changed |= ieee80211_reset_erp_info(dev); | ||
| 313 | ieee80211_bss_info_change_notify(sdata, changed); | ||
| 331 | ieee80211_enable_keys(sdata); | 314 | ieee80211_enable_keys(sdata); |
| 332 | 315 | ||
| 333 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 316 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
| @@ -346,6 +329,7 @@ static int ieee80211_open(struct net_device *dev) | |||
| 346 | goto err_del_interface; | 329 | goto err_del_interface; |
| 347 | } | 330 | } |
| 348 | 331 | ||
| 332 | /* no locking required since STA is not live yet */ | ||
| 349 | sta->flags |= WLAN_STA_AUTHORIZED; | 333 | sta->flags |= WLAN_STA_AUTHORIZED; |
| 350 | 334 | ||
| 351 | res = sta_info_insert(sta); | 335 | res = sta_info_insert(sta); |
| @@ -385,13 +369,13 @@ static int ieee80211_open(struct net_device *dev) | |||
| 385 | * yet be effective. Trigger execution of ieee80211_sta_work | 369 | * yet be effective. Trigger execution of ieee80211_sta_work |
| 386 | * to fix this. | 370 | * to fix this. |
| 387 | */ | 371 | */ |
| 388 | if(sdata->vif.type == IEEE80211_IF_TYPE_STA || | 372 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
| 389 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 373 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
| 390 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 374 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
| 391 | queue_work(local->hw.workqueue, &ifsta->work); | 375 | queue_work(local->hw.workqueue, &ifsta->work); |
| 392 | } | 376 | } |
| 393 | 377 | ||
| 394 | netif_start_queue(dev); | 378 | netif_tx_start_all_queues(dev); |
| 395 | 379 | ||
| 396 | return 0; | 380 | return 0; |
| 397 | err_del_interface: | 381 | err_del_interface: |
| @@ -399,6 +383,10 @@ static int ieee80211_open(struct net_device *dev) | |||
| 399 | err_stop: | 383 | err_stop: |
| 400 | if (!local->open_count && local->ops->stop) | 384 | if (!local->open_count && local->ops->stop) |
| 401 | local->ops->stop(local_to_hw(local)); | 385 | local->ops->stop(local_to_hw(local)); |
| 386 | err_del_bss: | ||
| 387 | sdata->bss = NULL; | ||
| 388 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | ||
| 389 | list_del(&sdata->u.vlan.list); | ||
| 402 | return res; | 390 | return res; |
| 403 | } | 391 | } |
| 404 | 392 | ||
| @@ -412,7 +400,7 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 412 | /* | 400 | /* |
| 413 | * Stop TX on this interface first. | 401 | * Stop TX on this interface first. |
| 414 | */ | 402 | */ |
| 415 | netif_stop_queue(dev); | 403 | netif_tx_stop_all_queues(dev); |
| 416 | 404 | ||
| 417 | /* | 405 | /* |
| 418 | * Now delete all active aggregation sessions. | 406 | * Now delete all active aggregation sessions. |
| @@ -481,7 +469,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 481 | switch (sdata->vif.type) { | 469 | switch (sdata->vif.type) { |
| 482 | case IEEE80211_IF_TYPE_VLAN: | 470 | case IEEE80211_IF_TYPE_VLAN: |
| 483 | list_del(&sdata->u.vlan.list); | 471 | list_del(&sdata->u.vlan.list); |
| 484 | sdata->u.vlan.ap = NULL; | ||
| 485 | /* no need to tell driver */ | 472 | /* no need to tell driver */ |
| 486 | break; | 473 | break; |
| 487 | case IEEE80211_IF_TYPE_MNTR: | 474 | case IEEE80211_IF_TYPE_MNTR: |
| @@ -503,9 +490,9 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 503 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) | 490 | if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) |
| 504 | local->fif_other_bss--; | 491 | local->fif_other_bss--; |
| 505 | 492 | ||
| 506 | netif_tx_lock_bh(local->mdev); | 493 | netif_addr_lock_bh(local->mdev); |
| 507 | ieee80211_configure_filter(local); | 494 | ieee80211_configure_filter(local); |
| 508 | netif_tx_unlock_bh(local->mdev); | 495 | netif_addr_unlock_bh(local->mdev); |
| 509 | break; | 496 | break; |
| 510 | case IEEE80211_IF_TYPE_MESH_POINT: | 497 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 511 | case IEEE80211_IF_TYPE_STA: | 498 | case IEEE80211_IF_TYPE_STA: |
| @@ -530,8 +517,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 530 | local->sta_hw_scanning = 0; | 517 | local->sta_hw_scanning = 0; |
| 531 | } | 518 | } |
| 532 | 519 | ||
| 533 | flush_workqueue(local->hw.workqueue); | ||
| 534 | |||
| 535 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; | 520 | sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; |
| 536 | kfree(sdata->u.sta.extra_ie); | 521 | kfree(sdata->u.sta.extra_ie); |
| 537 | sdata->u.sta.extra_ie = NULL; | 522 | sdata->u.sta.extra_ie = NULL; |
| @@ -546,6 +531,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 546 | local->ops->remove_interface(local_to_hw(local), &conf); | 531 | local->ops->remove_interface(local_to_hw(local), &conf); |
| 547 | } | 532 | } |
| 548 | 533 | ||
| 534 | sdata->bss = NULL; | ||
| 535 | |||
| 549 | if (local->open_count == 0) { | 536 | if (local->open_count == 0) { |
| 550 | if (netif_running(local->mdev)) | 537 | if (netif_running(local->mdev)) |
| 551 | dev_close(local->mdev); | 538 | dev_close(local->mdev); |
| @@ -555,6 +542,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
| 555 | 542 | ||
| 556 | ieee80211_led_radio(local, 0); | 543 | ieee80211_led_radio(local, 0); |
| 557 | 544 | ||
| 545 | flush_workqueue(local->hw.workqueue); | ||
| 546 | |||
| 558 | tasklet_disable(&local->tx_pending_tasklet); | 547 | tasklet_disable(&local->tx_pending_tasklet); |
| 559 | tasklet_disable(&local->tasklet); | 548 | tasklet_disable(&local->tasklet); |
| 560 | } | 549 | } |
| @@ -584,17 +573,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 584 | 573 | ||
| 585 | sta = sta_info_get(local, ra); | 574 | sta = sta_info_get(local, ra); |
| 586 | if (!sta) { | 575 | if (!sta) { |
| 576 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 587 | printk(KERN_DEBUG "Could not find the station\n"); | 577 | printk(KERN_DEBUG "Could not find the station\n"); |
| 588 | rcu_read_unlock(); | 578 | #endif |
| 589 | return -ENOENT; | 579 | ret = -ENOENT; |
| 580 | goto exit; | ||
| 590 | } | 581 | } |
| 591 | 582 | ||
| 592 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 583 | spin_lock_bh(&sta->lock); |
| 593 | 584 | ||
| 594 | /* we have tried too many times, receiver does not want A-MPDU */ | 585 | /* we have tried too many times, receiver does not want A-MPDU */ |
| 595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 586 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
| 596 | ret = -EBUSY; | 587 | ret = -EBUSY; |
| 597 | goto start_ba_exit; | 588 | goto err_unlock_sta; |
| 598 | } | 589 | } |
| 599 | 590 | ||
| 600 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 591 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| @@ -605,18 +596,20 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 605 | "idle on tid %u\n", tid); | 596 | "idle on tid %u\n", tid); |
| 606 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 597 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 607 | ret = -EAGAIN; | 598 | ret = -EAGAIN; |
| 608 | goto start_ba_exit; | 599 | goto err_unlock_sta; |
| 609 | } | 600 | } |
| 610 | 601 | ||
| 611 | /* prepare A-MPDU MLME for Tx aggregation */ | 602 | /* prepare A-MPDU MLME for Tx aggregation */ |
| 612 | sta->ampdu_mlme.tid_tx[tid] = | 603 | sta->ampdu_mlme.tid_tx[tid] = |
| 613 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | 604 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); |
| 614 | if (!sta->ampdu_mlme.tid_tx[tid]) { | 605 | if (!sta->ampdu_mlme.tid_tx[tid]) { |
| 606 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 615 | if (net_ratelimit()) | 607 | if (net_ratelimit()) |
| 616 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | 608 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", |
| 617 | tid); | 609 | tid); |
| 610 | #endif | ||
| 618 | ret = -ENOMEM; | 611 | ret = -ENOMEM; |
| 619 | goto start_ba_exit; | 612 | goto err_unlock_sta; |
| 620 | } | 613 | } |
| 621 | /* Tx timer */ | 614 | /* Tx timer */ |
| 622 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | 615 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = |
| @@ -625,10 +618,6 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 625 | (unsigned long)&sta->timer_to_tid[tid]; | 618 | (unsigned long)&sta->timer_to_tid[tid]; |
| 626 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 619 | init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
| 627 | 620 | ||
| 628 | /* ensure that TX flow won't interrupt us | ||
| 629 | * until the end of the call to requeue function */ | ||
| 630 | spin_lock_bh(&local->mdev->queue_lock); | ||
| 631 | |||
| 632 | /* create a new queue for this aggregation */ | 621 | /* create a new queue for this aggregation */ |
| 633 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); | 622 | ret = ieee80211_ht_agg_queue_add(local, sta, tid); |
| 634 | 623 | ||
| @@ -639,7 +628,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 639 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 628 | printk(KERN_DEBUG "BA request denied - queue unavailable for" |
| 640 | " tid %d\n", tid); | 629 | " tid %d\n", tid); |
| 641 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 630 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 642 | goto start_ba_err; | 631 | goto err_unlock_queue; |
| 643 | } | 632 | } |
| 644 | sdata = sta->sdata; | 633 | sdata = sta->sdata; |
| 645 | 634 | ||
| @@ -655,18 +644,18 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 655 | /* No need to requeue the packets in the agg queue, since we | 644 | /* No need to requeue the packets in the agg queue, since we |
| 656 | * held the tx lock: no packet could be enqueued to the newly | 645 | * held the tx lock: no packet could be enqueued to the newly |
| 657 | * allocated queue */ | 646 | * allocated queue */ |
| 658 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); | 647 | ieee80211_ht_agg_queue_remove(local, sta, tid, 0); |
| 659 | #ifdef CONFIG_MAC80211_HT_DEBUG | 648 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 660 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 649 | printk(KERN_DEBUG "BA request denied - HW unavailable for" |
| 661 | " tid %d\n", tid); | 650 | " tid %d\n", tid); |
| 662 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 651 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 663 | *state = HT_AGG_STATE_IDLE; | 652 | *state = HT_AGG_STATE_IDLE; |
| 664 | goto start_ba_err; | 653 | goto err_unlock_queue; |
| 665 | } | 654 | } |
| 666 | 655 | ||
| 667 | /* Will put all the packets in the new SW queue */ | 656 | /* Will put all the packets in the new SW queue */ |
| 668 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 657 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); |
| 669 | spin_unlock_bh(&local->mdev->queue_lock); | 658 | spin_unlock_bh(&sta->lock); |
| 670 | 659 | ||
| 671 | /* send an addBA request */ | 660 | /* send an addBA request */ |
| 672 | sta->ampdu_mlme.dialog_token_allocator++; | 661 | sta->ampdu_mlme.dialog_token_allocator++; |
| @@ -674,25 +663,27 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 674 | sta->ampdu_mlme.dialog_token_allocator; | 663 | sta->ampdu_mlme.dialog_token_allocator; |
| 675 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 664 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
| 676 | 665 | ||
| 666 | |||
| 677 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | 667 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, |
| 678 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 668 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
| 679 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 669 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
| 680 | 0x40, 5000); | 670 | 0x40, 5000); |
| 681 | |||
| 682 | /* activate the timer for the recipient's addBA response */ | 671 | /* activate the timer for the recipient's addBA response */ |
| 683 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 672 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
| 684 | jiffies + ADDBA_RESP_INTERVAL; | 673 | jiffies + ADDBA_RESP_INTERVAL; |
| 685 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 674 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
| 675 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 686 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 676 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
| 687 | goto start_ba_exit; | 677 | #endif |
| 678 | goto exit; | ||
| 688 | 679 | ||
| 689 | start_ba_err: | 680 | err_unlock_queue: |
| 690 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 681 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
| 691 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 682 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
| 692 | spin_unlock_bh(&local->mdev->queue_lock); | ||
| 693 | ret = -EBUSY; | 683 | ret = -EBUSY; |
| 694 | start_ba_exit: | 684 | err_unlock_sta: |
| 695 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 685 | spin_unlock_bh(&sta->lock); |
| 686 | exit: | ||
| 696 | rcu_read_unlock(); | 687 | rcu_read_unlock(); |
| 697 | return ret; | 688 | return ret; |
| 698 | } | 689 | } |
| @@ -720,7 +711,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
| 720 | 711 | ||
| 721 | /* check if the TID is in aggregation */ | 712 | /* check if the TID is in aggregation */ |
| 722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 713 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 723 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 714 | spin_lock_bh(&sta->lock); |
| 724 | 715 | ||
| 725 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 716 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
| 726 | ret = -ENOENT; | 717 | ret = -ENOENT; |
| @@ -750,7 +741,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
| 750 | } | 741 | } |
| 751 | 742 | ||
| 752 | stop_BA_exit: | 743 | stop_BA_exit: |
| 753 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 744 | spin_unlock_bh(&sta->lock); |
| 754 | rcu_read_unlock(); | 745 | rcu_read_unlock(); |
| 755 | return ret; | 746 | return ret; |
| 756 | } | 747 | } |
| @@ -764,8 +755,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 764 | DECLARE_MAC_BUF(mac); | 755 | DECLARE_MAC_BUF(mac); |
| 765 | 756 | ||
| 766 | if (tid >= STA_TID_NUM) { | 757 | if (tid >= STA_TID_NUM) { |
| 758 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 767 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 759 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
| 768 | tid, STA_TID_NUM); | 760 | tid, STA_TID_NUM); |
| 761 | #endif | ||
| 769 | return; | 762 | return; |
| 770 | } | 763 | } |
| 771 | 764 | ||
| @@ -773,18 +766,22 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 773 | sta = sta_info_get(local, ra); | 766 | sta = sta_info_get(local, ra); |
| 774 | if (!sta) { | 767 | if (!sta) { |
| 775 | rcu_read_unlock(); | 768 | rcu_read_unlock(); |
| 769 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 776 | printk(KERN_DEBUG "Could not find station: %s\n", | 770 | printk(KERN_DEBUG "Could not find station: %s\n", |
| 777 | print_mac(mac, ra)); | 771 | print_mac(mac, ra)); |
| 772 | #endif | ||
| 778 | return; | 773 | return; |
| 779 | } | 774 | } |
| 780 | 775 | ||
| 781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 776 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 782 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 777 | spin_lock_bh(&sta->lock); |
| 783 | 778 | ||
| 784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 779 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
| 780 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 781 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
| 786 | *state); | 782 | *state); |
| 787 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 783 | #endif |
| 784 | spin_unlock_bh(&sta->lock); | ||
| 788 | rcu_read_unlock(); | 785 | rcu_read_unlock(); |
| 789 | return; | 786 | return; |
| 790 | } | 787 | } |
| @@ -794,10 +791,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 794 | *state |= HT_ADDBA_DRV_READY_MSK; | 791 | *state |= HT_ADDBA_DRV_READY_MSK; |
| 795 | 792 | ||
| 796 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 793 | if (*state == HT_AGG_STATE_OPERATIONAL) { |
| 794 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 795 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
| 796 | #endif | ||
| 798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 797 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
| 799 | } | 798 | } |
| 800 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 799 | spin_unlock_bh(&sta->lock); |
| 801 | rcu_read_unlock(); | 800 | rcu_read_unlock(); |
| 802 | } | 801 | } |
| 803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 802 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
| @@ -811,8 +810,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
| 811 | DECLARE_MAC_BUF(mac); | 810 | DECLARE_MAC_BUF(mac); |
| 812 | 811 | ||
| 813 | if (tid >= STA_TID_NUM) { | 812 | if (tid >= STA_TID_NUM) { |
| 813 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 814 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 814 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
| 815 | tid, STA_TID_NUM); | 815 | tid, STA_TID_NUM); |
| 816 | #endif | ||
| 816 | return; | 817 | return; |
| 817 | } | 818 | } |
| 818 | 819 | ||
| @@ -824,17 +825,23 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
| 824 | rcu_read_lock(); | 825 | rcu_read_lock(); |
| 825 | sta = sta_info_get(local, ra); | 826 | sta = sta_info_get(local, ra); |
| 826 | if (!sta) { | 827 | if (!sta) { |
| 828 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 827 | printk(KERN_DEBUG "Could not find station: %s\n", | 829 | printk(KERN_DEBUG "Could not find station: %s\n", |
| 828 | print_mac(mac, ra)); | 830 | print_mac(mac, ra)); |
| 831 | #endif | ||
| 829 | rcu_read_unlock(); | 832 | rcu_read_unlock(); |
| 830 | return; | 833 | return; |
| 831 | } | 834 | } |
| 832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 835 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 833 | 836 | ||
| 834 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 837 | /* NOTE: no need to use sta->lock in this state check, as |
| 838 | * ieee80211_stop_tx_ba_session will let only one stop call to | ||
| 839 | * pass through per sta/tid | ||
| 840 | */ | ||
| 835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 841 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
| 842 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 843 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
| 837 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 844 | #endif |
| 838 | rcu_read_unlock(); | 845 | rcu_read_unlock(); |
| 839 | return; | 846 | return; |
| 840 | } | 847 | } |
| @@ -845,23 +852,20 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
| 845 | 852 | ||
| 846 | agg_queue = sta->tid_to_tx_q[tid]; | 853 | agg_queue = sta->tid_to_tx_q[tid]; |
| 847 | 854 | ||
| 848 | /* avoid ordering issues: we are the only one that can modify | ||
| 849 | * the content of the qdiscs */ | ||
| 850 | spin_lock_bh(&local->mdev->queue_lock); | ||
| 851 | /* remove the queue for this aggregation */ | ||
| 852 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); | 855 | ieee80211_ht_agg_queue_remove(local, sta, tid, 1); |
| 853 | spin_unlock_bh(&local->mdev->queue_lock); | ||
| 854 | 856 | ||
| 855 | /* we just requeued the all the frames that were in the removed | 857 | /* We just requeued the all the frames that were in the |
| 856 | * queue, and since we might miss a softirq we do netif_schedule. | 858 | * removed queue, and since we might miss a softirq we do |
| 857 | * ieee80211_wake_queue is not used here as this queue is not | 859 | * netif_schedule_queue. ieee80211_wake_queue is not used |
| 858 | * necessarily stopped */ | 860 | * here as this queue is not necessarily stopped |
| 859 | netif_schedule(local->mdev); | 861 | */ |
| 862 | netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue)); | ||
| 863 | spin_lock_bh(&sta->lock); | ||
| 860 | *state = HT_AGG_STATE_IDLE; | 864 | *state = HT_AGG_STATE_IDLE; |
| 861 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 865 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
| 862 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 866 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
| 863 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 867 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
| 864 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 868 | spin_unlock_bh(&sta->lock); |
| 865 | 869 | ||
| 866 | rcu_read_unlock(); | 870 | rcu_read_unlock(); |
| 867 | } | 871 | } |
| @@ -875,9 +879,11 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
| 875 | struct sk_buff *skb = dev_alloc_skb(0); | 879 | struct sk_buff *skb = dev_alloc_skb(0); |
| 876 | 880 | ||
| 877 | if (unlikely(!skb)) { | 881 | if (unlikely(!skb)) { |
| 882 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 878 | if (net_ratelimit()) | 883 | if (net_ratelimit()) |
| 879 | printk(KERN_WARNING "%s: Not enough memory, " | 884 | printk(KERN_WARNING "%s: Not enough memory, " |
| 880 | "dropping start BA session", skb->dev->name); | 885 | "dropping start BA session", skb->dev->name); |
| 886 | #endif | ||
| 881 | return; | 887 | return; |
| 882 | } | 888 | } |
| 883 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 889 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
| @@ -898,9 +904,11 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
| 898 | struct sk_buff *skb = dev_alloc_skb(0); | 904 | struct sk_buff *skb = dev_alloc_skb(0); |
| 899 | 905 | ||
| 900 | if (unlikely(!skb)) { | 906 | if (unlikely(!skb)) { |
| 907 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 901 | if (net_ratelimit()) | 908 | if (net_ratelimit()) |
| 902 | printk(KERN_WARNING "%s: Not enough memory, " | 909 | printk(KERN_WARNING "%s: Not enough memory, " |
| 903 | "dropping stop BA session", skb->dev->name); | 910 | "dropping stop BA session", skb->dev->name); |
| 911 | #endif | ||
| 904 | return; | 912 | return; |
| 905 | } | 913 | } |
| 906 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 914 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
| @@ -951,7 +959,6 @@ static const struct header_ops ieee80211_header_ops = { | |||
| 951 | .cache_update = eth_header_cache_update, | 959 | .cache_update = eth_header_cache_update, |
| 952 | }; | 960 | }; |
| 953 | 961 | ||
| 954 | /* Must not be called for mdev */ | ||
| 955 | void ieee80211_if_setup(struct net_device *dev) | 962 | void ieee80211_if_setup(struct net_device *dev) |
| 956 | { | 963 | { |
| 957 | ether_setup(dev); | 964 | ether_setup(dev); |
| @@ -961,67 +968,52 @@ void ieee80211_if_setup(struct net_device *dev) | |||
| 961 | dev->change_mtu = ieee80211_change_mtu; | 968 | dev->change_mtu = ieee80211_change_mtu; |
| 962 | dev->open = ieee80211_open; | 969 | dev->open = ieee80211_open; |
| 963 | dev->stop = ieee80211_stop; | 970 | dev->stop = ieee80211_stop; |
| 964 | dev->destructor = ieee80211_if_free; | 971 | dev->destructor = free_netdev; |
| 965 | } | 972 | } |
| 966 | 973 | ||
| 967 | /* everything else */ | 974 | /* everything else */ |
| 968 | 975 | ||
| 969 | static int __ieee80211_if_config(struct net_device *dev, | 976 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) |
| 970 | struct sk_buff *beacon, | ||
| 971 | struct ieee80211_tx_control *control) | ||
| 972 | { | 977 | { |
| 973 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 978 | struct ieee80211_local *local = sdata->local; |
| 974 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 975 | struct ieee80211_if_conf conf; | 979 | struct ieee80211_if_conf conf; |
| 976 | 980 | ||
| 977 | if (!local->ops->config_interface || !netif_running(dev)) | 981 | if (WARN_ON(!netif_running(sdata->dev))) |
| 982 | return 0; | ||
| 983 | |||
| 984 | if (!local->ops->config_interface) | ||
| 978 | return 0; | 985 | return 0; |
| 979 | 986 | ||
| 980 | memset(&conf, 0, sizeof(conf)); | 987 | memset(&conf, 0, sizeof(conf)); |
| 981 | conf.type = sdata->vif.type; | 988 | conf.changed = changed; |
| 989 | |||
| 982 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || | 990 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
| 983 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 991 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
| 984 | conf.bssid = sdata->u.sta.bssid; | 992 | conf.bssid = sdata->u.sta.bssid; |
| 985 | conf.ssid = sdata->u.sta.ssid; | 993 | conf.ssid = sdata->u.sta.ssid; |
| 986 | conf.ssid_len = sdata->u.sta.ssid_len; | 994 | conf.ssid_len = sdata->u.sta.ssid_len; |
| 987 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
| 988 | conf.beacon = beacon; | ||
| 989 | conf.beacon_control = control; | ||
| 990 | ieee80211_start_mesh(dev); | ||
| 991 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 995 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
| 996 | conf.bssid = sdata->dev->dev_addr; | ||
| 992 | conf.ssid = sdata->u.ap.ssid; | 997 | conf.ssid = sdata->u.ap.ssid; |
| 993 | conf.ssid_len = sdata->u.ap.ssid_len; | 998 | conf.ssid_len = sdata->u.ap.ssid_len; |
| 994 | conf.beacon = beacon; | 999 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
| 995 | conf.beacon_control = control; | 1000 | u8 zero[ETH_ALEN] = { 0 }; |
| 1001 | conf.bssid = zero; | ||
| 1002 | conf.ssid = zero; | ||
| 1003 | conf.ssid_len = 0; | ||
| 1004 | } else { | ||
| 1005 | WARN_ON(1); | ||
| 1006 | return -EINVAL; | ||
| 996 | } | 1007 | } |
| 997 | return local->ops->config_interface(local_to_hw(local), | ||
| 998 | &sdata->vif, &conf); | ||
| 999 | } | ||
| 1000 | 1008 | ||
| 1001 | int ieee80211_if_config(struct net_device *dev) | 1009 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) |
| 1002 | { | 1010 | return -EINVAL; |
| 1003 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 1004 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1005 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | ||
| 1006 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | ||
| 1007 | return ieee80211_if_config_beacon(dev); | ||
| 1008 | return __ieee80211_if_config(dev, NULL, NULL); | ||
| 1009 | } | ||
| 1010 | 1011 | ||
| 1011 | int ieee80211_if_config_beacon(struct net_device *dev) | 1012 | if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID))) |
| 1012 | { | 1013 | return -EINVAL; |
| 1013 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1014 | struct ieee80211_tx_control control; | ||
| 1015 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
| 1016 | struct sk_buff *skb; | ||
| 1017 | 1014 | ||
| 1018 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1015 | return local->ops->config_interface(local_to_hw(local), |
| 1019 | return 0; | 1016 | &sdata->vif, &conf); |
| 1020 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, | ||
| 1021 | &control); | ||
| 1022 | if (!skb) | ||
| 1023 | return -ENOMEM; | ||
| 1024 | return __ieee80211_if_config(dev, skb, &control); | ||
| 1025 | } | 1017 | } |
| 1026 | 1018 | ||
| 1027 | int ieee80211_hw_config(struct ieee80211_local *local) | 1019 | int ieee80211_hw_config(struct ieee80211_local *local) |
| @@ -1068,56 +1060,84 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
| 1068 | struct ieee80211_supported_band *sband; | 1060 | struct ieee80211_supported_band *sband; |
| 1069 | struct ieee80211_ht_info ht_conf; | 1061 | struct ieee80211_ht_info ht_conf; |
| 1070 | struct ieee80211_ht_bss_info ht_bss_conf; | 1062 | struct ieee80211_ht_bss_info ht_bss_conf; |
| 1071 | int i; | ||
| 1072 | u32 changed = 0; | 1063 | u32 changed = 0; |
| 1064 | int i; | ||
| 1065 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
| 1066 | u8 tx_mcs_set_cap; | ||
| 1073 | 1067 | ||
| 1074 | sband = local->hw.wiphy->bands[conf->channel->band]; | 1068 | sband = local->hw.wiphy->bands[conf->channel->band]; |
| 1075 | 1069 | ||
| 1070 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
| 1071 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
| 1072 | |||
| 1076 | /* HT is not supported */ | 1073 | /* HT is not supported */ |
| 1077 | if (!sband->ht_info.ht_supported) { | 1074 | if (!sband->ht_info.ht_supported) { |
| 1078 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1075 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
| 1079 | return 0; | 1076 | goto out; |
| 1080 | } | 1077 | } |
| 1081 | 1078 | ||
| 1082 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | 1079 | /* disable HT */ |
| 1083 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | 1080 | if (!enable_ht) { |
| 1084 | 1081 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | |
| 1085 | if (enable_ht) { | ||
| 1086 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
| 1087 | changed |= BSS_CHANGED_HT; | 1082 | changed |= BSS_CHANGED_HT; |
| 1083 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
| 1084 | conf->ht_conf.ht_supported = 0; | ||
| 1085 | goto out; | ||
| 1086 | } | ||
| 1088 | 1087 | ||
| 1089 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
| 1090 | ht_conf.ht_supported = 1; | ||
| 1091 | 1088 | ||
| 1092 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 1089 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) |
| 1093 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1090 | changed |= BSS_CHANGED_HT; |
| 1094 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | ||
| 1095 | 1091 | ||
| 1096 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1092 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
| 1097 | ht_conf.supp_mcs_set[i] = | 1093 | ht_conf.ht_supported = 1; |
| 1098 | sband->ht_info.supp_mcs_set[i] & | ||
| 1099 | req_ht_cap->supp_mcs_set[i]; | ||
| 1100 | 1094 | ||
| 1101 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | 1095 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
| 1102 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1096 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
| 1103 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1097 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
| 1098 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
| 1099 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
| 1100 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
| 1104 | 1101 | ||
| 1105 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | 1102 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; |
| 1106 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | 1103 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; |
| 1107 | 1104 | ||
| 1108 | /* if bss configuration changed store the new one */ | 1105 | /* Bits 96-100 */ |
| 1109 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | 1106 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; |
| 1110 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | 1107 | |
| 1111 | changed |= BSS_CHANGED_HT; | 1108 | /* configure suppoerted Tx MCS according to requested MCS |
| 1112 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | 1109 | * (based in most cases on Rx capabilities of peer) and self |
| 1113 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | 1110 | * Tx MCS capabilities (as defined by low level driver HW |
| 1114 | } | 1111 | * Tx capabilities) */ |
| 1115 | } else { | 1112 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) |
| 1116 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 1113 | goto check_changed; |
| 1117 | changed |= BSS_CHANGED_HT; | 1114 | |
| 1118 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1115 | /* Counting from 0 therfore + 1 */ |
| 1119 | } | 1116 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) |
| 1117 | max_tx_streams = ((tx_mcs_set_cap & | ||
| 1118 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
| 1120 | 1119 | ||
| 1120 | for (i = 0; i < max_tx_streams; i++) | ||
| 1121 | ht_conf.supp_mcs_set[i] = | ||
| 1122 | sband->ht_info.supp_mcs_set[i] & | ||
| 1123 | req_ht_cap->supp_mcs_set[i]; | ||
| 1124 | |||
| 1125 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
| 1126 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
| 1127 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
| 1128 | ht_conf.supp_mcs_set[i] = | ||
| 1129 | sband->ht_info.supp_mcs_set[i] & | ||
| 1130 | req_ht_cap->supp_mcs_set[i]; | ||
| 1131 | |||
| 1132 | check_changed: | ||
| 1133 | /* if bss configuration changed store the new one */ | ||
| 1134 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
| 1135 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
| 1136 | changed |= BSS_CHANGED_HT; | ||
| 1137 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
| 1138 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
| 1139 | } | ||
| 1140 | out: | ||
| 1121 | return changed; | 1141 | return changed; |
| 1122 | } | 1142 | } |
| 1123 | 1143 | ||
| @@ -1136,50 +1156,30 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
| 1136 | changed); | 1156 | changed); |
| 1137 | } | 1157 | } |
| 1138 | 1158 | ||
| 1139 | void ieee80211_reset_erp_info(struct net_device *dev) | 1159 | u32 ieee80211_reset_erp_info(struct net_device *dev) |
| 1140 | { | 1160 | { |
| 1141 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1161 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1142 | 1162 | ||
| 1143 | sdata->bss_conf.use_cts_prot = 0; | 1163 | sdata->bss_conf.use_cts_prot = 0; |
| 1144 | sdata->bss_conf.use_short_preamble = 0; | 1164 | sdata->bss_conf.use_short_preamble = 0; |
| 1145 | ieee80211_bss_info_change_notify(sdata, | 1165 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; |
| 1146 | BSS_CHANGED_ERP_CTS_PROT | | ||
| 1147 | BSS_CHANGED_ERP_PREAMBLE); | ||
| 1148 | } | 1166 | } |
| 1149 | 1167 | ||
| 1150 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1168 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
| 1151 | struct sk_buff *skb, | 1169 | struct sk_buff *skb) |
| 1152 | struct ieee80211_tx_status *status) | ||
| 1153 | { | 1170 | { |
| 1154 | struct ieee80211_local *local = hw_to_local(hw); | 1171 | struct ieee80211_local *local = hw_to_local(hw); |
| 1155 | struct ieee80211_tx_status *saved; | 1172 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1156 | int tmp; | 1173 | int tmp; |
| 1157 | 1174 | ||
| 1158 | skb->dev = local->mdev; | 1175 | skb->dev = local->mdev; |
| 1159 | saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC); | ||
| 1160 | if (unlikely(!saved)) { | ||
| 1161 | if (net_ratelimit()) | ||
| 1162 | printk(KERN_WARNING "%s: Not enough memory, " | ||
| 1163 | "dropping tx status", skb->dev->name); | ||
| 1164 | /* should be dev_kfree_skb_irq, but due to this function being | ||
| 1165 | * named _irqsafe instead of just _irq we can't be sure that | ||
| 1166 | * people won't call it from non-irq contexts */ | ||
| 1167 | dev_kfree_skb_any(skb); | ||
| 1168 | return; | ||
| 1169 | } | ||
| 1170 | memcpy(saved, status, sizeof(struct ieee80211_tx_status)); | ||
| 1171 | /* copy pointer to saved status into skb->cb for use by tasklet */ | ||
| 1172 | memcpy(skb->cb, &saved, sizeof(saved)); | ||
| 1173 | |||
| 1174 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 1176 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
| 1175 | skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? | 1177 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
| 1176 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 1178 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
| 1177 | tmp = skb_queue_len(&local->skb_queue) + | 1179 | tmp = skb_queue_len(&local->skb_queue) + |
| 1178 | skb_queue_len(&local->skb_queue_unreliable); | 1180 | skb_queue_len(&local->skb_queue_unreliable); |
| 1179 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 1181 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
| 1180 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1182 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
| 1181 | memcpy(&saved, skb->cb, sizeof(saved)); | ||
| 1182 | kfree(saved); | ||
| 1183 | dev_kfree_skb_irq(skb); | 1183 | dev_kfree_skb_irq(skb); |
| 1184 | tmp--; | 1184 | tmp--; |
| 1185 | I802_DEBUG_INC(local->tx_status_drop); | 1185 | I802_DEBUG_INC(local->tx_status_drop); |
| @@ -1193,7 +1193,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
| 1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
| 1194 | struct sk_buff *skb; | 1194 | struct sk_buff *skb; |
| 1195 | struct ieee80211_rx_status rx_status; | 1195 | struct ieee80211_rx_status rx_status; |
| 1196 | struct ieee80211_tx_status *tx_status; | ||
| 1197 | struct ieee80211_ra_tid *ra_tid; | 1196 | struct ieee80211_ra_tid *ra_tid; |
| 1198 | 1197 | ||
| 1199 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1198 | while ((skb = skb_dequeue(&local->skb_queue)) || |
| @@ -1208,12 +1207,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
| 1208 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 1207 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
| 1209 | break; | 1208 | break; |
| 1210 | case IEEE80211_TX_STATUS_MSG: | 1209 | case IEEE80211_TX_STATUS_MSG: |
| 1211 | /* get pointer to saved status out of skb->cb */ | ||
| 1212 | memcpy(&tx_status, skb->cb, sizeof(tx_status)); | ||
| 1213 | skb->pkt_type = 0; | 1210 | skb->pkt_type = 0; |
| 1214 | ieee80211_tx_status(local_to_hw(local), | 1211 | ieee80211_tx_status(local_to_hw(local), skb); |
| 1215 | skb, tx_status); | ||
| 1216 | kfree(tx_status); | ||
| 1217 | break; | 1212 | break; |
| 1218 | case IEEE80211_DELBA_MSG: | 1213 | case IEEE80211_DELBA_MSG: |
| 1219 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 1214 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
| @@ -1227,9 +1222,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
| 1227 | ra_tid->ra, ra_tid->tid); | 1222 | ra_tid->ra, ra_tid->tid); |
| 1228 | dev_kfree_skb(skb); | 1223 | dev_kfree_skb(skb); |
| 1229 | break ; | 1224 | break ; |
| 1230 | default: /* should never get here! */ | 1225 | default: |
| 1231 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1226 | WARN_ON(1); |
| 1232 | wiphy_name(local->hw.wiphy), skb->pkt_type); | ||
| 1233 | dev_kfree_skb(skb); | 1227 | dev_kfree_skb(skb); |
| 1234 | break; | 1228 | break; |
| 1235 | } | 1229 | } |
| @@ -1242,24 +1236,15 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
| 1242 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1236 | * Also, tx_packet_data in cb is restored from tx_control. */ |
| 1243 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
| 1244 | struct ieee80211_key *key, | 1238 | struct ieee80211_key *key, |
| 1245 | struct sk_buff *skb, | 1239 | struct sk_buff *skb) |
| 1246 | struct ieee80211_tx_control *control) | ||
| 1247 | { | 1240 | { |
| 1248 | int hdrlen, iv_len, mic_len; | 1241 | int hdrlen, iv_len, mic_len; |
| 1249 | struct ieee80211_tx_packet_data *pkt_data; | 1242 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1250 | 1243 | ||
| 1251 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1244 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | |
| 1252 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; | 1245 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | |
| 1253 | pkt_data->flags = 0; | 1246 | IEEE80211_TX_CTL_REQUEUE | |
| 1254 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 1247 | IEEE80211_TX_CTL_EAPOL_FRAME; |
| 1255 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
| 1256 | if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT) | ||
| 1257 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | ||
| 1258 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | ||
| 1259 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | ||
| 1260 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
| 1261 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
| 1262 | pkt_data->queue = control->queue; | ||
| 1263 | 1248 | ||
| 1264 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1249 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
| 1265 | 1250 | ||
| @@ -1306,9 +1291,10 @@ no_key: | |||
| 1306 | 1291 | ||
| 1307 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 1292 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
| 1308 | struct sta_info *sta, | 1293 | struct sta_info *sta, |
| 1309 | struct sk_buff *skb, | 1294 | struct sk_buff *skb) |
| 1310 | struct ieee80211_tx_status *status) | ||
| 1311 | { | 1295 | { |
| 1296 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 1297 | |||
| 1312 | sta->tx_filtered_count++; | 1298 | sta->tx_filtered_count++; |
| 1313 | 1299 | ||
| 1314 | /* | 1300 | /* |
| @@ -1316,7 +1302,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
| 1316 | * packet. If the STA went to power save mode, this will happen | 1302 | * packet. If the STA went to power save mode, this will happen |
| 1317 | * when it wakes up for the next time. | 1303 | * when it wakes up for the next time. |
| 1318 | */ | 1304 | */ |
| 1319 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1305 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
| 1320 | 1306 | ||
| 1321 | /* | 1307 | /* |
| 1322 | * This code races in the following way: | 1308 | * This code races in the following way: |
| @@ -1348,84 +1334,89 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
| 1348 | * can be unknown, for example with different interrupt status | 1334 | * can be unknown, for example with different interrupt status |
| 1349 | * bits. | 1335 | * bits. |
| 1350 | */ | 1336 | */ |
| 1351 | if (sta->flags & WLAN_STA_PS && | 1337 | if (test_sta_flags(sta, WLAN_STA_PS) && |
| 1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1338 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
| 1353 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1339 | ieee80211_remove_tx_extra(local, sta->key, skb); |
| 1354 | &status->control); | ||
| 1355 | skb_queue_tail(&sta->tx_filtered, skb); | 1340 | skb_queue_tail(&sta->tx_filtered, skb); |
| 1356 | return; | 1341 | return; |
| 1357 | } | 1342 | } |
| 1358 | 1343 | ||
| 1359 | if (!(sta->flags & WLAN_STA_PS) && | 1344 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
| 1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1345 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { |
| 1361 | /* Software retry the packet once */ | 1346 | /* Software retry the packet once */ |
| 1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1347 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
| 1363 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1348 | ieee80211_remove_tx_extra(local, sta->key, skb); |
| 1364 | &status->control); | ||
| 1365 | dev_queue_xmit(skb); | 1349 | dev_queue_xmit(skb); |
| 1366 | return; | 1350 | return; |
| 1367 | } | 1351 | } |
| 1368 | 1352 | ||
| 1353 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
| 1369 | if (net_ratelimit()) | 1354 | if (net_ratelimit()) |
| 1370 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 1355 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
| 1371 | "queue_len=%d PS=%d @%lu\n", | 1356 | "queue_len=%d PS=%d @%lu\n", |
| 1372 | wiphy_name(local->hw.wiphy), | 1357 | wiphy_name(local->hw.wiphy), |
| 1373 | skb_queue_len(&sta->tx_filtered), | 1358 | skb_queue_len(&sta->tx_filtered), |
| 1374 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1359 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
| 1360 | #endif | ||
| 1375 | dev_kfree_skb(skb); | 1361 | dev_kfree_skb(skb); |
| 1376 | } | 1362 | } |
| 1377 | 1363 | ||
| 1378 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1364 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
| 1379 | struct ieee80211_tx_status *status) | ||
| 1380 | { | 1365 | { |
| 1381 | struct sk_buff *skb2; | 1366 | struct sk_buff *skb2; |
| 1382 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1367 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 1383 | struct ieee80211_local *local = hw_to_local(hw); | 1368 | struct ieee80211_local *local = hw_to_local(hw); |
| 1369 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 1384 | u16 frag, type; | 1370 | u16 frag, type; |
| 1371 | __le16 fc; | ||
| 1385 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1372 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
| 1386 | struct ieee80211_sub_if_data *sdata; | 1373 | struct ieee80211_sub_if_data *sdata; |
| 1387 | struct net_device *prev_dev = NULL; | 1374 | struct net_device *prev_dev = NULL; |
| 1388 | 1375 | struct sta_info *sta; | |
| 1389 | if (!status) { | ||
| 1390 | printk(KERN_ERR | ||
| 1391 | "%s: ieee80211_tx_status called with NULL status\n", | ||
| 1392 | wiphy_name(local->hw.wiphy)); | ||
| 1393 | dev_kfree_skb(skb); | ||
| 1394 | return; | ||
| 1395 | } | ||
| 1396 | 1376 | ||
| 1397 | rcu_read_lock(); | 1377 | rcu_read_lock(); |
| 1398 | 1378 | ||
| 1399 | if (status->excessive_retries) { | 1379 | if (info->status.excessive_retries) { |
| 1400 | struct sta_info *sta; | ||
| 1401 | sta = sta_info_get(local, hdr->addr1); | 1380 | sta = sta_info_get(local, hdr->addr1); |
| 1402 | if (sta) { | 1381 | if (sta) { |
| 1403 | if (sta->flags & WLAN_STA_PS) { | 1382 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
| 1404 | /* | 1383 | /* |
| 1405 | * The STA is in power save mode, so assume | 1384 | * The STA is in power save mode, so assume |
| 1406 | * that this TX packet failed because of that. | 1385 | * that this TX packet failed because of that. |
| 1407 | */ | 1386 | */ |
| 1408 | status->excessive_retries = 0; | 1387 | ieee80211_handle_filtered_frame(local, sta, skb); |
| 1409 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | ||
| 1410 | ieee80211_handle_filtered_frame(local, sta, | ||
| 1411 | skb, status); | ||
| 1412 | rcu_read_unlock(); | 1388 | rcu_read_unlock(); |
| 1413 | return; | 1389 | return; |
| 1414 | } | 1390 | } |
| 1415 | } | 1391 | } |
| 1416 | } | 1392 | } |
| 1417 | 1393 | ||
| 1418 | if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { | 1394 | fc = hdr->frame_control; |
| 1419 | struct sta_info *sta; | 1395 | |
| 1396 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
| 1397 | (ieee80211_is_data_qos(fc))) { | ||
| 1398 | u16 tid, ssn; | ||
| 1399 | u8 *qc; | ||
| 1400 | sta = sta_info_get(local, hdr->addr1); | ||
| 1401 | if (sta) { | ||
| 1402 | qc = ieee80211_get_qos_ctl(hdr); | ||
| 1403 | tid = qc[0] & 0xf; | ||
| 1404 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | ||
| 1405 | & IEEE80211_SCTL_SEQ); | ||
| 1406 | ieee80211_send_bar(sta->sdata->dev, hdr->addr1, | ||
| 1407 | tid, ssn); | ||
| 1408 | } | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
| 1420 | sta = sta_info_get(local, hdr->addr1); | 1412 | sta = sta_info_get(local, hdr->addr1); |
| 1421 | if (sta) { | 1413 | if (sta) { |
| 1422 | ieee80211_handle_filtered_frame(local, sta, skb, | 1414 | ieee80211_handle_filtered_frame(local, sta, skb); |
| 1423 | status); | ||
| 1424 | rcu_read_unlock(); | 1415 | rcu_read_unlock(); |
| 1425 | return; | 1416 | return; |
| 1426 | } | 1417 | } |
| 1427 | } else | 1418 | } else |
| 1428 | rate_control_tx_status(local->mdev, skb, status); | 1419 | rate_control_tx_status(local->mdev, skb); |
| 1429 | 1420 | ||
| 1430 | rcu_read_unlock(); | 1421 | rcu_read_unlock(); |
| 1431 | 1422 | ||
| @@ -1439,14 +1430,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1439 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 1430 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
| 1440 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | 1431 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; |
| 1441 | 1432 | ||
| 1442 | if (status->flags & IEEE80211_TX_STATUS_ACK) { | 1433 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
| 1443 | if (frag == 0) { | 1434 | if (frag == 0) { |
| 1444 | local->dot11TransmittedFrameCount++; | 1435 | local->dot11TransmittedFrameCount++; |
| 1445 | if (is_multicast_ether_addr(hdr->addr1)) | 1436 | if (is_multicast_ether_addr(hdr->addr1)) |
| 1446 | local->dot11MulticastTransmittedFrameCount++; | 1437 | local->dot11MulticastTransmittedFrameCount++; |
| 1447 | if (status->retry_count > 0) | 1438 | if (info->status.retry_count > 0) |
| 1448 | local->dot11RetryCount++; | 1439 | local->dot11RetryCount++; |
| 1449 | if (status->retry_count > 1) | 1440 | if (info->status.retry_count > 1) |
| 1450 | local->dot11MultipleRetryCount++; | 1441 | local->dot11MultipleRetryCount++; |
| 1451 | } | 1442 | } |
| 1452 | 1443 | ||
| @@ -1483,7 +1474,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1483 | return; | 1474 | return; |
| 1484 | } | 1475 | } |
| 1485 | 1476 | ||
| 1486 | rthdr = (struct ieee80211_tx_status_rtap_hdr*) | 1477 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) |
| 1487 | skb_push(skb, sizeof(*rthdr)); | 1478 | skb_push(skb, sizeof(*rthdr)); |
| 1488 | 1479 | ||
| 1489 | memset(rthdr, 0, sizeof(*rthdr)); | 1480 | memset(rthdr, 0, sizeof(*rthdr)); |
| @@ -1492,17 +1483,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 1492 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 1483 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
| 1493 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 1484 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); |
| 1494 | 1485 | ||
| 1495 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | 1486 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
| 1496 | !is_multicast_ether_addr(hdr->addr1)) | 1487 | !is_multicast_ether_addr(hdr->addr1)) |
| 1497 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 1488 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
| 1498 | 1489 | ||
| 1499 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | 1490 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && |
| 1500 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | 1491 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) |
| 1501 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 1492 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
| 1502 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1493 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
| 1503 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 1494 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
| 1504 | 1495 | ||
| 1505 | rthdr->data_retries = status->retry_count; | 1496 | rthdr->data_retries = info->status.retry_count; |
| 1506 | 1497 | ||
| 1507 | /* XXX: is this sufficient for BPF? */ | 1498 | /* XXX: is this sufficient for BPF? */ |
| 1508 | skb_set_mac_header(skb, 0); | 1499 | skb_set_mac_header(skb, 0); |
| @@ -1628,7 +1619,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1628 | int result; | 1619 | int result; |
| 1629 | enum ieee80211_band band; | 1620 | enum ieee80211_band band; |
| 1630 | struct net_device *mdev; | 1621 | struct net_device *mdev; |
| 1631 | struct ieee80211_sub_if_data *sdata; | 1622 | struct wireless_dev *mwdev; |
| 1632 | 1623 | ||
| 1633 | /* | 1624 | /* |
| 1634 | * generic code guarantees at least one band, | 1625 | * generic code guarantees at least one band, |
| @@ -1652,19 +1643,30 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1652 | if (result < 0) | 1643 | if (result < 0) |
| 1653 | return result; | 1644 | return result; |
| 1654 | 1645 | ||
| 1655 | /* for now, mdev needs sub_if_data :/ */ | 1646 | /* |
| 1656 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | 1647 | * We use the number of queues for feature tests (QoS, HT) internally |
| 1657 | "wmaster%d", ether_setup); | 1648 | * so restrict them appropriately. |
| 1649 | */ | ||
| 1650 | if (hw->queues > IEEE80211_MAX_QUEUES) | ||
| 1651 | hw->queues = IEEE80211_MAX_QUEUES; | ||
| 1652 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) | ||
| 1653 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; | ||
| 1654 | if (hw->queues < 4) | ||
| 1655 | hw->ampdu_queues = 0; | ||
| 1656 | |||
| 1657 | mdev = alloc_netdev_mq(sizeof(struct wireless_dev), | ||
| 1658 | "wmaster%d", ether_setup, | ||
| 1659 | ieee80211_num_queues(hw)); | ||
| 1658 | if (!mdev) | 1660 | if (!mdev) |
| 1659 | goto fail_mdev_alloc; | 1661 | goto fail_mdev_alloc; |
| 1660 | 1662 | ||
| 1661 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | 1663 | mwdev = netdev_priv(mdev); |
| 1662 | mdev->ieee80211_ptr = &sdata->wdev; | 1664 | mdev->ieee80211_ptr = mwdev; |
| 1663 | sdata->wdev.wiphy = local->hw.wiphy; | 1665 | mwdev->wiphy = local->hw.wiphy; |
| 1664 | 1666 | ||
| 1665 | local->mdev = mdev; | 1667 | local->mdev = mdev; |
| 1666 | 1668 | ||
| 1667 | ieee80211_rx_bss_list_init(mdev); | 1669 | ieee80211_rx_bss_list_init(local); |
| 1668 | 1670 | ||
| 1669 | mdev->hard_start_xmit = ieee80211_master_start_xmit; | 1671 | mdev->hard_start_xmit = ieee80211_master_start_xmit; |
| 1670 | mdev->open = ieee80211_master_open; | 1672 | mdev->open = ieee80211_master_open; |
| @@ -1673,18 +1675,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1673 | mdev->header_ops = &ieee80211_header_ops; | 1675 | mdev->header_ops = &ieee80211_header_ops; |
| 1674 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 1676 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
| 1675 | 1677 | ||
| 1676 | sdata->vif.type = IEEE80211_IF_TYPE_AP; | ||
| 1677 | sdata->dev = mdev; | ||
| 1678 | sdata->local = local; | ||
| 1679 | sdata->u.ap.force_unicast_rateidx = -1; | ||
| 1680 | sdata->u.ap.max_ratectrl_rateidx = -1; | ||
| 1681 | ieee80211_if_sdata_init(sdata); | ||
| 1682 | |||
| 1683 | /* no RCU needed since we're still during init phase */ | ||
| 1684 | list_add_tail(&sdata->list, &local->interfaces); | ||
| 1685 | |||
| 1686 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1678 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
| 1687 | local->hw.workqueue = create_singlethread_workqueue(name); | 1679 | local->hw.workqueue = create_freezeable_workqueue(name); |
| 1688 | if (!local->hw.workqueue) { | 1680 | if (!local->hw.workqueue) { |
| 1689 | result = -ENOMEM; | 1681 | result = -ENOMEM; |
| 1690 | goto fail_workqueue; | 1682 | goto fail_workqueue; |
| @@ -1700,15 +1692,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1700 | 1692 | ||
| 1701 | debugfs_hw_add(local); | 1693 | debugfs_hw_add(local); |
| 1702 | 1694 | ||
| 1703 | local->hw.conf.beacon_int = 1000; | 1695 | if (local->hw.conf.beacon_int < 10) |
| 1696 | local->hw.conf.beacon_int = 100; | ||
| 1704 | 1697 | ||
| 1705 | local->wstats_flags |= local->hw.max_rssi ? | 1698 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
| 1706 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1699 | IEEE80211_HW_SIGNAL_DB | |
| 1707 | local->wstats_flags |= local->hw.max_signal ? | 1700 | IEEE80211_HW_SIGNAL_DBM) ? |
| 1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1701 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
| 1709 | local->wstats_flags |= local->hw.max_noise ? | 1702 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
| 1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1703 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
| 1711 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1704 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
| 1712 | local->wstats_flags |= IW_QUAL_DBM; | 1705 | local->wstats_flags |= IW_QUAL_DBM; |
| 1713 | 1706 | ||
| 1714 | result = sta_info_start(local); | 1707 | result = sta_info_start(local); |
| @@ -1727,9 +1720,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1727 | if (result < 0) | 1720 | if (result < 0) |
| 1728 | goto fail_dev; | 1721 | goto fail_dev; |
| 1729 | 1722 | ||
| 1730 | ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
| 1731 | ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); | ||
| 1732 | |||
| 1733 | result = ieee80211_init_rate_ctrl_alg(local, | 1723 | result = ieee80211_init_rate_ctrl_alg(local, |
| 1734 | hw->rate_control_algorithm); | 1724 | hw->rate_control_algorithm); |
| 1735 | if (result < 0) { | 1725 | if (result < 0) { |
| @@ -1746,16 +1736,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1746 | goto fail_wep; | 1736 | goto fail_wep; |
| 1747 | } | 1737 | } |
| 1748 | 1738 | ||
| 1749 | ieee80211_install_qdisc(local->mdev); | 1739 | local->mdev->select_queue = ieee80211_select_queue; |
| 1750 | 1740 | ||
| 1751 | /* add one default STA interface */ | 1741 | /* add one default STA interface */ |
| 1752 | result = ieee80211_if_add(local->mdev, "wlan%d", NULL, | 1742 | result = ieee80211_if_add(local, "wlan%d", NULL, |
| 1753 | IEEE80211_IF_TYPE_STA, NULL); | 1743 | IEEE80211_IF_TYPE_STA, NULL); |
| 1754 | if (result) | 1744 | if (result) |
| 1755 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 1745 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
| 1756 | wiphy_name(local->hw.wiphy)); | 1746 | wiphy_name(local->hw.wiphy)); |
| 1757 | 1747 | ||
| 1758 | local->reg_state = IEEE80211_DEV_REGISTERED; | ||
| 1759 | rtnl_unlock(); | 1748 | rtnl_unlock(); |
| 1760 | 1749 | ||
| 1761 | ieee80211_led_init(local); | 1750 | ieee80211_led_init(local); |
| @@ -1765,7 +1754,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
| 1765 | fail_wep: | 1754 | fail_wep: |
| 1766 | rate_control_deinitialize(local); | 1755 | rate_control_deinitialize(local); |
| 1767 | fail_rate: | 1756 | fail_rate: |
| 1768 | ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); | ||
| 1769 | unregister_netdevice(local->mdev); | 1757 | unregister_netdevice(local->mdev); |
| 1770 | local->mdev = NULL; | 1758 | local->mdev = NULL; |
| 1771 | fail_dev: | 1759 | fail_dev: |
| @@ -1775,10 +1763,8 @@ fail_sta_info: | |||
| 1775 | debugfs_hw_del(local); | 1763 | debugfs_hw_del(local); |
| 1776 | destroy_workqueue(local->hw.workqueue); | 1764 | destroy_workqueue(local->hw.workqueue); |
| 1777 | fail_workqueue: | 1765 | fail_workqueue: |
| 1778 | if (local->mdev != NULL) { | 1766 | if (local->mdev) |
| 1779 | ieee80211_if_free(local->mdev); | 1767 | free_netdev(local->mdev); |
| 1780 | local->mdev = NULL; | ||
| 1781 | } | ||
| 1782 | fail_mdev_alloc: | 1768 | fail_mdev_alloc: |
| 1783 | wiphy_unregister(local->hw.wiphy); | 1769 | wiphy_unregister(local->hw.wiphy); |
| 1784 | return result; | 1770 | return result; |
| @@ -1788,42 +1774,27 @@ EXPORT_SYMBOL(ieee80211_register_hw); | |||
| 1788 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) | 1774 | void ieee80211_unregister_hw(struct ieee80211_hw *hw) |
| 1789 | { | 1775 | { |
| 1790 | struct ieee80211_local *local = hw_to_local(hw); | 1776 | struct ieee80211_local *local = hw_to_local(hw); |
| 1791 | struct ieee80211_sub_if_data *sdata, *tmp; | ||
| 1792 | 1777 | ||
| 1793 | tasklet_kill(&local->tx_pending_tasklet); | 1778 | tasklet_kill(&local->tx_pending_tasklet); |
| 1794 | tasklet_kill(&local->tasklet); | 1779 | tasklet_kill(&local->tasklet); |
| 1795 | 1780 | ||
| 1796 | rtnl_lock(); | 1781 | rtnl_lock(); |
| 1797 | 1782 | ||
| 1798 | BUG_ON(local->reg_state != IEEE80211_DEV_REGISTERED); | ||
| 1799 | |||
| 1800 | local->reg_state = IEEE80211_DEV_UNREGISTERED; | ||
| 1801 | |||
| 1802 | /* | 1783 | /* |
| 1803 | * At this point, interface list manipulations are fine | 1784 | * At this point, interface list manipulations are fine |
| 1804 | * because the driver cannot be handing us frames any | 1785 | * because the driver cannot be handing us frames any |
| 1805 | * more and the tasklet is killed. | 1786 | * more and the tasklet is killed. |
| 1806 | */ | 1787 | */ |
| 1807 | 1788 | ||
| 1808 | /* | 1789 | /* First, we remove all virtual interfaces. */ |
| 1809 | * First, we remove all non-master interfaces. Do this because they | 1790 | ieee80211_remove_interfaces(local); |
| 1810 | * may have bss pointer dependency on the master, and when we free | ||
| 1811 | * the master these would be freed as well, breaking our list | ||
| 1812 | * iteration completely. | ||
| 1813 | */ | ||
| 1814 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | ||
| 1815 | if (sdata->dev == local->mdev) | ||
| 1816 | continue; | ||
| 1817 | list_del(&sdata->list); | ||
| 1818 | __ieee80211_if_del(local, sdata); | ||
| 1819 | } | ||
| 1820 | 1791 | ||
| 1821 | /* then, finally, remove the master interface */ | 1792 | /* then, finally, remove the master interface */ |
| 1822 | __ieee80211_if_del(local, IEEE80211_DEV_TO_SUB_IF(local->mdev)); | 1793 | unregister_netdevice(local->mdev); |
| 1823 | 1794 | ||
| 1824 | rtnl_unlock(); | 1795 | rtnl_unlock(); |
| 1825 | 1796 | ||
| 1826 | ieee80211_rx_bss_list_deinit(local->mdev); | 1797 | ieee80211_rx_bss_list_deinit(local); |
| 1827 | ieee80211_clear_tx_pending(local); | 1798 | ieee80211_clear_tx_pending(local); |
| 1828 | sta_info_stop(local); | 1799 | sta_info_stop(local); |
| 1829 | rate_control_deinitialize(local); | 1800 | rate_control_deinitialize(local); |
| @@ -1840,8 +1811,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
| 1840 | wiphy_unregister(local->hw.wiphy); | 1811 | wiphy_unregister(local->hw.wiphy); |
| 1841 | ieee80211_wep_free(local); | 1812 | ieee80211_wep_free(local); |
| 1842 | ieee80211_led_exit(local); | 1813 | ieee80211_led_exit(local); |
| 1843 | ieee80211_if_free(local->mdev); | 1814 | free_netdev(local->mdev); |
| 1844 | local->mdev = NULL; | ||
| 1845 | } | 1815 | } |
| 1846 | EXPORT_SYMBOL(ieee80211_unregister_hw); | 1816 | EXPORT_SYMBOL(ieee80211_unregister_hw); |
| 1847 | 1817 | ||
| @@ -1858,27 +1828,17 @@ static int __init ieee80211_init(void) | |||
| 1858 | struct sk_buff *skb; | 1828 | struct sk_buff *skb; |
| 1859 | int ret; | 1829 | int ret; |
| 1860 | 1830 | ||
| 1861 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1831 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
| 1832 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | ||
| 1833 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | ||
| 1862 | 1834 | ||
| 1863 | ret = rc80211_pid_init(); | 1835 | ret = rc80211_pid_init(); |
| 1864 | if (ret) | 1836 | if (ret) |
| 1865 | goto out; | 1837 | return ret; |
| 1866 | |||
| 1867 | ret = ieee80211_wme_register(); | ||
| 1868 | if (ret) { | ||
| 1869 | printk(KERN_DEBUG "ieee80211_init: failed to " | ||
| 1870 | "initialize WME (err=%d)\n", ret); | ||
| 1871 | goto out_cleanup_pid; | ||
| 1872 | } | ||
| 1873 | 1838 | ||
| 1874 | ieee80211_debugfs_netdev_init(); | 1839 | ieee80211_debugfs_netdev_init(); |
| 1875 | 1840 | ||
| 1876 | return 0; | 1841 | return 0; |
| 1877 | |||
| 1878 | out_cleanup_pid: | ||
| 1879 | rc80211_pid_exit(); | ||
| 1880 | out: | ||
| 1881 | return ret; | ||
| 1882 | } | 1842 | } |
| 1883 | 1843 | ||
| 1884 | static void __exit ieee80211_exit(void) | 1844 | static void __exit ieee80211_exit(void) |
| @@ -1894,7 +1854,6 @@ static void __exit ieee80211_exit(void) | |||
| 1894 | if (mesh_allocated) | 1854 | if (mesh_allocated) |
| 1895 | ieee80211s_stop(); | 1855 | ieee80211s_stop(); |
| 1896 | 1856 | ||
| 1897 | ieee80211_wme_unregister(); | ||
| 1898 | ieee80211_debugfs_netdev_exit(); | 1857 | ieee80211_debugfs_netdev_exit(); |
| 1899 | } | 1858 | } |
| 1900 | 1859 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 697ef67f96b6..b5933b271491 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
| @@ -315,6 +315,13 @@ struct mesh_table *mesh_table_alloc(int size_order) | |||
| 315 | return newtbl; | 315 | return newtbl; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | static void __mesh_table_free(struct mesh_table *tbl) | ||
| 319 | { | ||
| 320 | kfree(tbl->hash_buckets); | ||
| 321 | kfree(tbl->hashwlock); | ||
| 322 | kfree(tbl); | ||
| 323 | } | ||
| 324 | |||
| 318 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | 325 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) |
| 319 | { | 326 | { |
| 320 | struct hlist_head *mesh_hash; | 327 | struct hlist_head *mesh_hash; |
| @@ -330,9 +337,7 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
| 330 | } | 337 | } |
| 331 | spin_unlock(&tbl->hashwlock[i]); | 338 | spin_unlock(&tbl->hashwlock[i]); |
| 332 | } | 339 | } |
| 333 | kfree(tbl->hash_buckets); | 340 | __mesh_table_free(tbl); |
| 334 | kfree(tbl->hashwlock); | ||
| 335 | kfree(tbl); | ||
| 336 | } | 341 | } |
| 337 | 342 | ||
| 338 | static void ieee80211_mesh_path_timer(unsigned long data) | 343 | static void ieee80211_mesh_path_timer(unsigned long data) |
| @@ -349,21 +354,16 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | |||
| 349 | { | 354 | { |
| 350 | struct mesh_table *newtbl; | 355 | struct mesh_table *newtbl; |
| 351 | struct hlist_head *oldhash; | 356 | struct hlist_head *oldhash; |
| 352 | struct hlist_node *p; | 357 | struct hlist_node *p, *q; |
| 353 | int err = 0; | ||
| 354 | int i; | 358 | int i; |
| 355 | 359 | ||
| 356 | if (atomic_read(&tbl->entries) | 360 | if (atomic_read(&tbl->entries) |
| 357 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) { | 361 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) |
| 358 | err = -EPERM; | ||
| 359 | goto endgrow; | 362 | goto endgrow; |
| 360 | } | ||
| 361 | 363 | ||
| 362 | newtbl = mesh_table_alloc(tbl->size_order + 1); | 364 | newtbl = mesh_table_alloc(tbl->size_order + 1); |
| 363 | if (!newtbl) { | 365 | if (!newtbl) |
| 364 | err = -ENOMEM; | ||
| 365 | goto endgrow; | 366 | goto endgrow; |
| 366 | } | ||
| 367 | 367 | ||
| 368 | newtbl->free_node = tbl->free_node; | 368 | newtbl->free_node = tbl->free_node; |
| 369 | newtbl->mean_chain_len = tbl->mean_chain_len; | 369 | newtbl->mean_chain_len = tbl->mean_chain_len; |
| @@ -373,13 +373,19 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | |||
| 373 | oldhash = tbl->hash_buckets; | 373 | oldhash = tbl->hash_buckets; |
| 374 | for (i = 0; i <= tbl->hash_mask; i++) | 374 | for (i = 0; i <= tbl->hash_mask; i++) |
| 375 | hlist_for_each(p, &oldhash[i]) | 375 | hlist_for_each(p, &oldhash[i]) |
| 376 | tbl->copy_node(p, newtbl); | 376 | if (tbl->copy_node(p, newtbl) < 0) |
| 377 | goto errcopy; | ||
| 377 | 378 | ||
| 379 | return newtbl; | ||
| 380 | |||
| 381 | errcopy: | ||
| 382 | for (i = 0; i <= newtbl->hash_mask; i++) { | ||
| 383 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | ||
| 384 | tbl->free_node(p, 0); | ||
| 385 | } | ||
| 386 | __mesh_table_free(tbl); | ||
| 378 | endgrow: | 387 | endgrow: |
| 379 | if (err) | 388 | return NULL; |
| 380 | return NULL; | ||
| 381 | else | ||
| 382 | return newtbl; | ||
| 383 | } | 389 | } |
| 384 | 390 | ||
| 385 | /** | 391 | /** |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 2e161f6d8288..669eafafe497 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
| @@ -109,7 +109,7 @@ struct mesh_table { | |||
| 109 | __u32 hash_rnd; /* Used for hash generation */ | 109 | __u32 hash_rnd; /* Used for hash generation */ |
| 110 | atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ | 110 | atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ |
| 111 | void (*free_node) (struct hlist_node *p, bool free_leafs); | 111 | void (*free_node) (struct hlist_node *p, bool free_leafs); |
| 112 | void (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); | 112 | int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); |
| 113 | int size_order; | 113 | int size_order; |
| 114 | int mean_chain_len; | 114 | int mean_chain_len; |
| 115 | }; | 115 | }; |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index af0cd1e3e213..7fa149e230e6 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
| @@ -26,7 +26,7 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) | |||
| 26 | { | 26 | { |
| 27 | if (ae) | 27 | if (ae) |
| 28 | offset += 6; | 28 | offset += 6; |
| 29 | return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset))); | 29 | return get_unaligned_le32(preq_elem + offset); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | /* HWMP IE processing macros */ | 32 | /* HWMP IE processing macros */ |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 99c2d360888e..5f88a2e6ee50 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
| @@ -158,19 +158,14 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
| 158 | if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) | 158 | if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) |
| 159 | return -ENOSPC; | 159 | return -ENOSPC; |
| 160 | 160 | ||
| 161 | err = -ENOMEM; | ||
| 161 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); | 162 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); |
| 162 | if (!new_mpath) { | 163 | if (!new_mpath) |
| 163 | atomic_dec(&sdata->u.sta.mpaths); | 164 | goto err_path_alloc; |
| 164 | err = -ENOMEM; | 165 | |
| 165 | goto endadd2; | ||
| 166 | } | ||
| 167 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); | 166 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); |
| 168 | if (!new_node) { | 167 | if (!new_node) |
| 169 | kfree(new_mpath); | 168 | goto err_node_alloc; |
| 170 | atomic_dec(&sdata->u.sta.mpaths); | ||
| 171 | err = -ENOMEM; | ||
| 172 | goto endadd2; | ||
| 173 | } | ||
| 174 | 169 | ||
| 175 | read_lock(&pathtbl_resize_lock); | 170 | read_lock(&pathtbl_resize_lock); |
| 176 | memcpy(new_mpath->dst, dst, ETH_ALEN); | 171 | memcpy(new_mpath->dst, dst, ETH_ALEN); |
| @@ -189,16 +184,11 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
| 189 | 184 | ||
| 190 | spin_lock(&mesh_paths->hashwlock[hash_idx]); | 185 | spin_lock(&mesh_paths->hashwlock[hash_idx]); |
| 191 | 186 | ||
| 187 | err = -EEXIST; | ||
| 192 | hlist_for_each_entry(node, n, bucket, list) { | 188 | hlist_for_each_entry(node, n, bucket, list) { |
| 193 | mpath = node->mpath; | 189 | mpath = node->mpath; |
| 194 | if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) | 190 | if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) == 0) |
| 195 | == 0) { | 191 | goto err_exists; |
| 196 | err = -EEXIST; | ||
| 197 | atomic_dec(&sdata->u.sta.mpaths); | ||
| 198 | kfree(new_node); | ||
| 199 | kfree(new_mpath); | ||
| 200 | goto endadd; | ||
| 201 | } | ||
| 202 | } | 192 | } |
| 203 | 193 | ||
| 204 | hlist_add_head_rcu(&new_node->list, bucket); | 194 | hlist_add_head_rcu(&new_node->list, bucket); |
| @@ -206,10 +196,9 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
| 206 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) | 196 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) |
| 207 | grow = 1; | 197 | grow = 1; |
| 208 | 198 | ||
| 209 | endadd: | ||
| 210 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | 199 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); |
| 211 | read_unlock(&pathtbl_resize_lock); | 200 | read_unlock(&pathtbl_resize_lock); |
| 212 | if (!err && grow) { | 201 | if (grow) { |
| 213 | struct mesh_table *oldtbl, *newtbl; | 202 | struct mesh_table *oldtbl, *newtbl; |
| 214 | 203 | ||
| 215 | write_lock(&pathtbl_resize_lock); | 204 | write_lock(&pathtbl_resize_lock); |
| @@ -217,7 +206,7 @@ endadd: | |||
| 217 | newtbl = mesh_table_grow(mesh_paths); | 206 | newtbl = mesh_table_grow(mesh_paths); |
| 218 | if (!newtbl) { | 207 | if (!newtbl) { |
| 219 | write_unlock(&pathtbl_resize_lock); | 208 | write_unlock(&pathtbl_resize_lock); |
| 220 | return -ENOMEM; | 209 | return 0; |
| 221 | } | 210 | } |
| 222 | rcu_assign_pointer(mesh_paths, newtbl); | 211 | rcu_assign_pointer(mesh_paths, newtbl); |
| 223 | write_unlock(&pathtbl_resize_lock); | 212 | write_unlock(&pathtbl_resize_lock); |
| @@ -225,7 +214,16 @@ endadd: | |||
| 225 | synchronize_rcu(); | 214 | synchronize_rcu(); |
| 226 | mesh_table_free(oldtbl, false); | 215 | mesh_table_free(oldtbl, false); |
| 227 | } | 216 | } |
| 228 | endadd2: | 217 | return 0; |
| 218 | |||
| 219 | err_exists: | ||
| 220 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | ||
| 221 | read_unlock(&pathtbl_resize_lock); | ||
| 222 | kfree(new_node); | ||
| 223 | err_node_alloc: | ||
| 224 | kfree(new_mpath); | ||
| 225 | err_path_alloc: | ||
| 226 | atomic_dec(&sdata->u.sta.mpaths); | ||
| 229 | return err; | 227 | return err; |
| 230 | } | 228 | } |
| 231 | 229 | ||
| @@ -264,7 +262,6 @@ void mesh_plink_broken(struct sta_info *sta) | |||
| 264 | } | 262 | } |
| 265 | rcu_read_unlock(); | 263 | rcu_read_unlock(); |
| 266 | } | 264 | } |
| 267 | EXPORT_SYMBOL(mesh_plink_broken); | ||
| 268 | 265 | ||
| 269 | /** | 266 | /** |
| 270 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches | 267 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches |
| @@ -460,25 +457,28 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs) | |||
| 460 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); | 457 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); |
| 461 | mpath = node->mpath; | 458 | mpath = node->mpath; |
| 462 | hlist_del_rcu(p); | 459 | hlist_del_rcu(p); |
| 463 | synchronize_rcu(); | ||
| 464 | if (free_leafs) | 460 | if (free_leafs) |
| 465 | kfree(mpath); | 461 | kfree(mpath); |
| 466 | kfree(node); | 462 | kfree(node); |
| 467 | } | 463 | } |
| 468 | 464 | ||
| 469 | static void mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) | 465 | static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) |
| 470 | { | 466 | { |
| 471 | struct mesh_path *mpath; | 467 | struct mesh_path *mpath; |
| 472 | struct mpath_node *node, *new_node; | 468 | struct mpath_node *node, *new_node; |
| 473 | u32 hash_idx; | 469 | u32 hash_idx; |
| 474 | 470 | ||
| 471 | new_node = kmalloc(sizeof(struct mpath_node), GFP_ATOMIC); | ||
| 472 | if (new_node == NULL) | ||
| 473 | return -ENOMEM; | ||
| 474 | |||
| 475 | node = hlist_entry(p, struct mpath_node, list); | 475 | node = hlist_entry(p, struct mpath_node, list); |
| 476 | mpath = node->mpath; | 476 | mpath = node->mpath; |
| 477 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); | ||
| 478 | new_node->mpath = mpath; | 477 | new_node->mpath = mpath; |
| 479 | hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); | 478 | hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); |
| 480 | hlist_add_head(&new_node->list, | 479 | hlist_add_head(&new_node->list, |
| 481 | &newtbl->hash_buckets[hash_idx]); | 480 | &newtbl->hash_buckets[hash_idx]); |
| 481 | return 0; | ||
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | int mesh_pathtbl_init(void) | 484 | int mesh_pathtbl_init(void) |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 37f0c2b94ae7..9efeb1f07025 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
| @@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | |||
| 79 | * | 79 | * |
| 80 | * @sta: mes peer link to restart | 80 | * @sta: mes peer link to restart |
| 81 | * | 81 | * |
| 82 | * Locking: this function must be called holding sta->plink_lock | 82 | * Locking: this function must be called holding sta->lock |
| 83 | */ | 83 | */ |
| 84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) | 84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) |
| 85 | { | 85 | { |
| @@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 105 | if (!sta) | 105 | if (!sta) |
| 106 | return NULL; | 106 | return NULL; |
| 107 | 107 | ||
| 108 | sta->flags |= WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED; |
| 109 | sta->supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->supp_rates[local->hw.conf.channel->band] = rates; |
| 110 | 110 | ||
| 111 | return sta; | 111 | return sta; |
| @@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 118 | * | 118 | * |
| 119 | * All mesh paths with this peer as next hop will be flushed | 119 | * All mesh paths with this peer as next hop will be flushed |
| 120 | * | 120 | * |
| 121 | * Locking: the caller must hold sta->plink_lock | 121 | * Locking: the caller must hold sta->lock |
| 122 | */ | 122 | */ |
| 123 | static void __mesh_plink_deactivate(struct sta_info *sta) | 123 | static void __mesh_plink_deactivate(struct sta_info *sta) |
| 124 | { | 124 | { |
| @@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta) | |||
| 139 | */ | 139 | */ |
| 140 | void mesh_plink_deactivate(struct sta_info *sta) | 140 | void mesh_plink_deactivate(struct sta_info *sta) |
| 141 | { | 141 | { |
| 142 | spin_lock_bh(&sta->plink_lock); | 142 | spin_lock_bh(&sta->lock); |
| 143 | __mesh_plink_deactivate(sta); | 143 | __mesh_plink_deactivate(sta); |
| 144 | spin_unlock_bh(&sta->plink_lock); | 144 | spin_unlock_bh(&sta->lock); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static int mesh_plink_frame_tx(struct net_device *dev, | 147 | static int mesh_plink_frame_tx(struct net_device *dev, |
| @@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data) | |||
| 270 | */ | 270 | */ |
| 271 | sta = (struct sta_info *) data; | 271 | sta = (struct sta_info *) data; |
| 272 | 272 | ||
| 273 | spin_lock_bh(&sta->plink_lock); | 273 | spin_lock_bh(&sta->lock); |
| 274 | if (sta->ignore_plink_timer) { | 274 | if (sta->ignore_plink_timer) { |
| 275 | sta->ignore_plink_timer = false; | 275 | sta->ignore_plink_timer = false; |
| 276 | spin_unlock_bh(&sta->plink_lock); | 276 | spin_unlock_bh(&sta->lock); |
| 277 | return; | 277 | return; |
| 278 | } | 278 | } |
| 279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", | 279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", |
| @@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data) | |||
| 298 | rand % sta->plink_timeout; | 298 | rand % sta->plink_timeout; |
| 299 | ++sta->plink_retries; | 299 | ++sta->plink_retries; |
| 300 | mod_plink_timer(sta, sta->plink_timeout); | 300 | mod_plink_timer(sta, sta->plink_timeout); |
| 301 | spin_unlock_bh(&sta->plink_lock); | 301 | spin_unlock_bh(&sta->lock); |
| 302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
| 303 | 0, 0); | 303 | 0, 0); |
| 304 | break; | 304 | break; |
| @@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data) | |||
| 311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); | 311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); |
| 312 | sta->plink_state = PLINK_HOLDING; | 312 | sta->plink_state = PLINK_HOLDING; |
| 313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
| 314 | spin_unlock_bh(&sta->plink_lock); | 314 | spin_unlock_bh(&sta->lock); |
| 315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, | 315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, |
| 316 | reason); | 316 | reason); |
| 317 | break; | 317 | break; |
| @@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data) | |||
| 319 | /* holding timer */ | 319 | /* holding timer */ |
| 320 | del_timer(&sta->plink_timer); | 320 | del_timer(&sta->plink_timer); |
| 321 | mesh_plink_fsm_restart(sta); | 321 | mesh_plink_fsm_restart(sta); |
| 322 | spin_unlock_bh(&sta->plink_lock); | 322 | spin_unlock_bh(&sta->lock); |
| 323 | break; | 323 | break; |
| 324 | default: | 324 | default: |
| 325 | spin_unlock_bh(&sta->plink_lock); | 325 | spin_unlock_bh(&sta->lock); |
| 326 | break; | 326 | break; |
| 327 | } | 327 | } |
| 328 | } | 328 | } |
| @@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta) | |||
| 344 | DECLARE_MAC_BUF(mac); | 344 | DECLARE_MAC_BUF(mac); |
| 345 | #endif | 345 | #endif |
| 346 | 346 | ||
| 347 | spin_lock_bh(&sta->plink_lock); | 347 | spin_lock_bh(&sta->lock); |
| 348 | get_random_bytes(&llid, 2); | 348 | get_random_bytes(&llid, 2); |
| 349 | sta->llid = llid; | 349 | sta->llid = llid; |
| 350 | if (sta->plink_state != PLINK_LISTEN) { | 350 | if (sta->plink_state != PLINK_LISTEN) { |
| 351 | spin_unlock_bh(&sta->plink_lock); | 351 | spin_unlock_bh(&sta->lock); |
| 352 | return -EBUSY; | 352 | return -EBUSY; |
| 353 | } | 353 | } |
| 354 | sta->plink_state = PLINK_OPN_SNT; | 354 | sta->plink_state = PLINK_OPN_SNT; |
| 355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
| 356 | spin_unlock_bh(&sta->plink_lock); | 356 | spin_unlock_bh(&sta->lock); |
| 357 | mpl_dbg("Mesh plink: starting establishment with %s\n", | 357 | mpl_dbg("Mesh plink: starting establishment with %s\n", |
| 358 | print_mac(mac, sta->addr)); | 358 | print_mac(mac, sta->addr)); |
| 359 | 359 | ||
| @@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta) | |||
| 367 | DECLARE_MAC_BUF(mac); | 367 | DECLARE_MAC_BUF(mac); |
| 368 | #endif | 368 | #endif |
| 369 | 369 | ||
| 370 | spin_lock_bh(&sta->plink_lock); | 370 | spin_lock_bh(&sta->lock); |
| 371 | __mesh_plink_deactivate(sta); | 371 | __mesh_plink_deactivate(sta); |
| 372 | sta->plink_state = PLINK_BLOCKED; | 372 | sta->plink_state = PLINK_BLOCKED; |
| 373 | spin_unlock_bh(&sta->plink_lock); | 373 | spin_unlock_bh(&sta->lock); |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | int mesh_plink_close(struct sta_info *sta) | 376 | int mesh_plink_close(struct sta_info *sta) |
| @@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta) | |||
| 383 | 383 | ||
| 384 | mpl_dbg("Mesh plink: closing link with %s\n", | 384 | mpl_dbg("Mesh plink: closing link with %s\n", |
| 385 | print_mac(mac, sta->addr)); | 385 | print_mac(mac, sta->addr)); |
| 386 | spin_lock_bh(&sta->plink_lock); | 386 | spin_lock_bh(&sta->lock); |
| 387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); | 387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); |
| 388 | reason = sta->reason; | 388 | reason = sta->reason; |
| 389 | 389 | ||
| 390 | if (sta->plink_state == PLINK_LISTEN || | 390 | if (sta->plink_state == PLINK_LISTEN || |
| 391 | sta->plink_state == PLINK_BLOCKED) { | 391 | sta->plink_state == PLINK_BLOCKED) { |
| 392 | mesh_plink_fsm_restart(sta); | 392 | mesh_plink_fsm_restart(sta); |
| 393 | spin_unlock_bh(&sta->plink_lock); | 393 | spin_unlock_bh(&sta->lock); |
| 394 | return 0; | 394 | return 0; |
| 395 | } else if (sta->plink_state == PLINK_ESTAB) { | 395 | } else if (sta->plink_state == PLINK_ESTAB) { |
| 396 | __mesh_plink_deactivate(sta); | 396 | __mesh_plink_deactivate(sta); |
| @@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta) | |||
| 402 | sta->plink_state = PLINK_HOLDING; | 402 | sta->plink_state = PLINK_HOLDING; |
| 403 | llid = sta->llid; | 403 | llid = sta->llid; |
| 404 | plid = sta->plid; | 404 | plid = sta->plid; |
| 405 | spin_unlock_bh(&sta->plink_lock); | 405 | spin_unlock_bh(&sta->lock); |
| 406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, | 406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, |
| 407 | plid, reason); | 407 | plid, reason); |
| 408 | return 0; | 408 | return 0; |
| @@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 490 | /* avoid warning */ | 490 | /* avoid warning */ |
| 491 | break; | 491 | break; |
| 492 | } | 492 | } |
| 493 | spin_lock_bh(&sta->plink_lock); | 493 | spin_lock_bh(&sta->lock); |
| 494 | } else if (!sta) { | 494 | } else if (!sta) { |
| 495 | /* ftype == PLINK_OPEN */ | 495 | /* ftype == PLINK_OPEN */ |
| 496 | u64 rates; | 496 | u64 rates; |
| @@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 512 | return; | 512 | return; |
| 513 | } | 513 | } |
| 514 | event = OPN_ACPT; | 514 | event = OPN_ACPT; |
| 515 | spin_lock_bh(&sta->plink_lock); | 515 | spin_lock_bh(&sta->lock); |
| 516 | } else { | 516 | } else { |
| 517 | spin_lock_bh(&sta->plink_lock); | 517 | spin_lock_bh(&sta->lock); |
| 518 | switch (ftype) { | 518 | switch (ftype) { |
| 519 | case PLINK_OPEN: | 519 | case PLINK_OPEN: |
| 520 | if (!mesh_plink_free_count(sdata) || | 520 | if (!mesh_plink_free_count(sdata) || |
| @@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 551 | break; | 551 | break; |
| 552 | default: | 552 | default: |
| 553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); | 553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); |
| 554 | spin_unlock_bh(&sta->plink_lock); | 554 | spin_unlock_bh(&sta->lock); |
| 555 | rcu_read_unlock(); | 555 | rcu_read_unlock(); |
| 556 | return; | 556 | return; |
| 557 | } | 557 | } |
| @@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 568 | switch (event) { | 568 | switch (event) { |
| 569 | case CLS_ACPT: | 569 | case CLS_ACPT: |
| 570 | mesh_plink_fsm_restart(sta); | 570 | mesh_plink_fsm_restart(sta); |
| 571 | spin_unlock_bh(&sta->plink_lock); | 571 | spin_unlock_bh(&sta->lock); |
| 572 | break; | 572 | break; |
| 573 | case OPN_ACPT: | 573 | case OPN_ACPT: |
| 574 | sta->plink_state = PLINK_OPN_RCVD; | 574 | sta->plink_state = PLINK_OPN_RCVD; |
| @@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 576 | get_random_bytes(&llid, 2); | 576 | get_random_bytes(&llid, 2); |
| 577 | sta->llid = llid; | 577 | sta->llid = llid; |
| 578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
| 579 | spin_unlock_bh(&sta->plink_lock); | 579 | spin_unlock_bh(&sta->lock); |
| 580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
| 581 | 0, 0); | 581 | 0, 0); |
| 582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, | 582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, |
| 583 | llid, plid, 0); | 583 | llid, plid, 0); |
| 584 | break; | 584 | break; |
| 585 | default: | 585 | default: |
| 586 | spin_unlock_bh(&sta->plink_lock); | 586 | spin_unlock_bh(&sta->lock); |
| 587 | break; | 587 | break; |
| 588 | } | 588 | } |
| 589 | break; | 589 | break; |
| @@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 603 | sta->ignore_plink_timer = true; | 603 | sta->ignore_plink_timer = true; |
| 604 | 604 | ||
| 605 | llid = sta->llid; | 605 | llid = sta->llid; |
| 606 | spin_unlock_bh(&sta->plink_lock); | 606 | spin_unlock_bh(&sta->lock); |
| 607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
| 608 | plid, reason); | 608 | plid, reason); |
| 609 | break; | 609 | break; |
| @@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 612 | sta->plink_state = PLINK_OPN_RCVD; | 612 | sta->plink_state = PLINK_OPN_RCVD; |
| 613 | sta->plid = plid; | 613 | sta->plid = plid; |
| 614 | llid = sta->llid; | 614 | llid = sta->llid; |
| 615 | spin_unlock_bh(&sta->plink_lock); | 615 | spin_unlock_bh(&sta->lock); |
| 616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
| 617 | plid, 0); | 617 | plid, 0); |
| 618 | break; | 618 | break; |
| @@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 622 | dot11MeshConfirmTimeout(sdata))) | 622 | dot11MeshConfirmTimeout(sdata))) |
| 623 | sta->ignore_plink_timer = true; | 623 | sta->ignore_plink_timer = true; |
| 624 | 624 | ||
| 625 | spin_unlock_bh(&sta->plink_lock); | 625 | spin_unlock_bh(&sta->lock); |
| 626 | break; | 626 | break; |
| 627 | default: | 627 | default: |
| 628 | spin_unlock_bh(&sta->plink_lock); | 628 | spin_unlock_bh(&sta->lock); |
| 629 | break; | 629 | break; |
| 630 | } | 630 | } |
| 631 | break; | 631 | break; |
| @@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 645 | sta->ignore_plink_timer = true; | 645 | sta->ignore_plink_timer = true; |
| 646 | 646 | ||
| 647 | llid = sta->llid; | 647 | llid = sta->llid; |
| 648 | spin_unlock_bh(&sta->plink_lock); | 648 | spin_unlock_bh(&sta->lock); |
| 649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
| 650 | plid, reason); | 650 | plid, reason); |
| 651 | break; | 651 | break; |
| 652 | case OPN_ACPT: | 652 | case OPN_ACPT: |
| 653 | llid = sta->llid; | 653 | llid = sta->llid; |
| 654 | spin_unlock_bh(&sta->plink_lock); | 654 | spin_unlock_bh(&sta->lock); |
| 655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
| 656 | plid, 0); | 656 | plid, 0); |
| 657 | break; | 657 | break; |
| @@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 659 | del_timer(&sta->plink_timer); | 659 | del_timer(&sta->plink_timer); |
| 660 | sta->plink_state = PLINK_ESTAB; | 660 | sta->plink_state = PLINK_ESTAB; |
| 661 | mesh_plink_inc_estab_count(sdata); | 661 | mesh_plink_inc_estab_count(sdata); |
| 662 | spin_unlock_bh(&sta->plink_lock); | 662 | spin_unlock_bh(&sta->lock); |
| 663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
| 664 | print_mac(mac, sta->addr)); | 664 | print_mac(mac, sta->addr)); |
| 665 | break; | 665 | break; |
| 666 | default: | 666 | default: |
| 667 | spin_unlock_bh(&sta->plink_lock); | 667 | spin_unlock_bh(&sta->lock); |
| 668 | break; | 668 | break; |
| 669 | } | 669 | } |
| 670 | break; | 670 | break; |
| @@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 684 | sta->ignore_plink_timer = true; | 684 | sta->ignore_plink_timer = true; |
| 685 | 685 | ||
| 686 | llid = sta->llid; | 686 | llid = sta->llid; |
| 687 | spin_unlock_bh(&sta->plink_lock); | 687 | spin_unlock_bh(&sta->lock); |
| 688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
| 689 | plid, reason); | 689 | plid, reason); |
| 690 | break; | 690 | break; |
| @@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 692 | del_timer(&sta->plink_timer); | 692 | del_timer(&sta->plink_timer); |
| 693 | sta->plink_state = PLINK_ESTAB; | 693 | sta->plink_state = PLINK_ESTAB; |
| 694 | mesh_plink_inc_estab_count(sdata); | 694 | mesh_plink_inc_estab_count(sdata); |
| 695 | spin_unlock_bh(&sta->plink_lock); | 695 | spin_unlock_bh(&sta->lock); |
| 696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
| 697 | print_mac(mac, sta->addr)); | 697 | print_mac(mac, sta->addr)); |
| 698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
| 699 | plid, 0); | 699 | plid, 0); |
| 700 | break; | 700 | break; |
| 701 | default: | 701 | default: |
| 702 | spin_unlock_bh(&sta->plink_lock); | 702 | spin_unlock_bh(&sta->lock); |
| 703 | break; | 703 | break; |
| 704 | } | 704 | } |
| 705 | break; | 705 | break; |
| @@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 713 | sta->plink_state = PLINK_HOLDING; | 713 | sta->plink_state = PLINK_HOLDING; |
| 714 | llid = sta->llid; | 714 | llid = sta->llid; |
| 715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
| 716 | spin_unlock_bh(&sta->plink_lock); | 716 | spin_unlock_bh(&sta->lock); |
| 717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
| 718 | plid, reason); | 718 | plid, reason); |
| 719 | break; | 719 | break; |
| 720 | case OPN_ACPT: | 720 | case OPN_ACPT: |
| 721 | llid = sta->llid; | 721 | llid = sta->llid; |
| 722 | spin_unlock_bh(&sta->plink_lock); | 722 | spin_unlock_bh(&sta->lock); |
| 723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
| 724 | plid, 0); | 724 | plid, 0); |
| 725 | break; | 725 | break; |
| 726 | default: | 726 | default: |
| 727 | spin_unlock_bh(&sta->plink_lock); | 727 | spin_unlock_bh(&sta->lock); |
| 728 | break; | 728 | break; |
| 729 | } | 729 | } |
| 730 | break; | 730 | break; |
| @@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 734 | if (del_timer(&sta->plink_timer)) | 734 | if (del_timer(&sta->plink_timer)) |
| 735 | sta->ignore_plink_timer = 1; | 735 | sta->ignore_plink_timer = 1; |
| 736 | mesh_plink_fsm_restart(sta); | 736 | mesh_plink_fsm_restart(sta); |
| 737 | spin_unlock_bh(&sta->plink_lock); | 737 | spin_unlock_bh(&sta->lock); |
| 738 | break; | 738 | break; |
| 739 | case OPN_ACPT: | 739 | case OPN_ACPT: |
| 740 | case CNF_ACPT: | 740 | case CNF_ACPT: |
| @@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
| 742 | case CNF_RJCT: | 742 | case CNF_RJCT: |
| 743 | llid = sta->llid; | 743 | llid = sta->llid; |
| 744 | reason = sta->reason; | 744 | reason = sta->reason; |
| 745 | spin_unlock_bh(&sta->plink_lock); | 745 | spin_unlock_bh(&sta->lock); |
| 746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
| 747 | plid, reason); | 747 | plid, reason); |
| 748 | break; | 748 | break; |
| 749 | default: | 749 | default: |
| 750 | spin_unlock_bh(&sta->plink_lock); | 750 | spin_unlock_bh(&sta->lock); |
| 751 | } | 751 | } |
| 752 | break; | 752 | break; |
| 753 | default: | 753 | default: |
| 754 | /* should not get here, PLINK_BLOCKED is dealt with at the | 754 | /* should not get here, PLINK_BLOCKED is dealt with at the |
| 755 | * beggining of the function | 755 | * beggining of the function |
| 756 | */ | 756 | */ |
| 757 | spin_unlock_bh(&sta->plink_lock); | 757 | spin_unlock_bh(&sta->lock); |
| 758 | break; | 758 | break; |
| 759 | } | 759 | } |
| 760 | 760 | ||
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c index 0f844f7895f1..408649bd4702 100644 --- a/net/mac80211/michael.c +++ b/net/mac80211/michael.c | |||
| @@ -6,85 +6,68 @@ | |||
| 6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
| 7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
| 8 | */ | 8 | */ |
| 9 | |||
| 10 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| 10 | #include <linux/bitops.h> | ||
| 11 | #include <linux/ieee80211.h> | ||
| 12 | #include <asm/unaligned.h> | ||
| 11 | 13 | ||
| 12 | #include "michael.h" | 14 | #include "michael.h" |
| 13 | 15 | ||
| 14 | static inline u32 rotr(u32 val, int bits) | 16 | static void michael_block(struct michael_mic_ctx *mctx, u32 val) |
| 15 | { | ||
| 16 | return (val >> bits) | (val << (32 - bits)); | ||
| 17 | } | ||
| 18 | |||
| 19 | |||
| 20 | static inline u32 rotl(u32 val, int bits) | ||
| 21 | { | ||
| 22 | return (val << bits) | (val >> (32 - bits)); | ||
| 23 | } | ||
| 24 | |||
| 25 | |||
| 26 | static inline u32 xswap(u32 val) | ||
| 27 | { | ||
| 28 | return ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); | ||
| 29 | } | ||
| 30 | |||
| 31 | |||
| 32 | #define michael_block(l, r) \ | ||
| 33 | do { \ | ||
| 34 | r ^= rotl(l, 17); \ | ||
| 35 | l += r; \ | ||
| 36 | r ^= xswap(l); \ | ||
| 37 | l += r; \ | ||
| 38 | r ^= rotl(l, 3); \ | ||
| 39 | l += r; \ | ||
| 40 | r ^= rotr(l, 2); \ | ||
| 41 | l += r; \ | ||
| 42 | } while (0) | ||
| 43 | |||
| 44 | |||
| 45 | static inline u32 michael_get32(u8 *data) | ||
| 46 | { | 17 | { |
| 47 | return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | 18 | mctx->l ^= val; |
| 19 | mctx->r ^= rol32(mctx->l, 17); | ||
| 20 | mctx->l += mctx->r; | ||
| 21 | mctx->r ^= ((mctx->l & 0xff00ff00) >> 8) | | ||
| 22 | ((mctx->l & 0x00ff00ff) << 8); | ||
| 23 | mctx->l += mctx->r; | ||
| 24 | mctx->r ^= rol32(mctx->l, 3); | ||
| 25 | mctx->l += mctx->r; | ||
| 26 | mctx->r ^= ror32(mctx->l, 2); | ||
| 27 | mctx->l += mctx->r; | ||
| 48 | } | 28 | } |
| 49 | 29 | ||
| 50 | 30 | static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, | |
| 51 | static inline void michael_put32(u32 val, u8 *data) | 31 | struct ieee80211_hdr *hdr) |
| 52 | { | 32 | { |
| 53 | data[0] = val & 0xff; | 33 | u8 *da, *sa, tid; |
| 54 | data[1] = (val >> 8) & 0xff; | 34 | |
| 55 | data[2] = (val >> 16) & 0xff; | 35 | da = ieee80211_get_DA(hdr); |
| 56 | data[3] = (val >> 24) & 0xff; | 36 | sa = ieee80211_get_SA(hdr); |
| 37 | if (ieee80211_is_data_qos(hdr->frame_control)) | ||
| 38 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
| 39 | else | ||
| 40 | tid = 0; | ||
| 41 | |||
| 42 | mctx->l = get_unaligned_le32(key); | ||
| 43 | mctx->r = get_unaligned_le32(key + 4); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC | ||
| 47 | * calculation, but it is _not_ transmitted | ||
| 48 | */ | ||
| 49 | michael_block(mctx, get_unaligned_le32(da)); | ||
| 50 | michael_block(mctx, get_unaligned_le16(&da[4]) | | ||
| 51 | (get_unaligned_le16(sa) << 16)); | ||
| 52 | michael_block(mctx, get_unaligned_le32(&sa[2])); | ||
| 53 | michael_block(mctx, tid); | ||
| 57 | } | 54 | } |
| 58 | 55 | ||
| 59 | 56 | void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, | |
| 60 | void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | 57 | const u8 *data, size_t data_len, u8 *mic) |
| 61 | u8 *data, size_t data_len, u8 *mic) | ||
| 62 | { | 58 | { |
| 63 | u32 l, r, val; | 59 | u32 val; |
| 64 | size_t block, blocks, left; | 60 | size_t block, blocks, left; |
| 61 | struct michael_mic_ctx mctx; | ||
| 65 | 62 | ||
| 66 | l = michael_get32(key); | 63 | michael_mic_hdr(&mctx, key, hdr); |
| 67 | r = michael_get32(key + 4); | ||
| 68 | |||
| 69 | /* A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC | ||
| 70 | * calculation, but it is _not_ transmitted */ | ||
| 71 | l ^= michael_get32(da); | ||
| 72 | michael_block(l, r); | ||
| 73 | l ^= da[4] | (da[5] << 8) | (sa[0] << 16) | (sa[1] << 24); | ||
| 74 | michael_block(l, r); | ||
| 75 | l ^= michael_get32(&sa[2]); | ||
| 76 | michael_block(l, r); | ||
| 77 | l ^= priority; | ||
| 78 | michael_block(l, r); | ||
| 79 | 64 | ||
| 80 | /* Real data */ | 65 | /* Real data */ |
| 81 | blocks = data_len / 4; | 66 | blocks = data_len / 4; |
| 82 | left = data_len % 4; | 67 | left = data_len % 4; |
| 83 | 68 | ||
| 84 | for (block = 0; block < blocks; block++) { | 69 | for (block = 0; block < blocks; block++) |
| 85 | l ^= michael_get32(&data[block * 4]); | 70 | michael_block(&mctx, get_unaligned_le32(&data[block * 4])); |
| 86 | michael_block(l, r); | ||
| 87 | } | ||
| 88 | 71 | ||
| 89 | /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make | 72 | /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make |
| 90 | * total length a multiple of 4. */ | 73 | * total length a multiple of 4. */ |
| @@ -94,11 +77,10 @@ void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | |||
| 94 | left--; | 77 | left--; |
| 95 | val |= data[blocks * 4 + left]; | 78 | val |= data[blocks * 4 + left]; |
| 96 | } | 79 | } |
| 97 | l ^= val; | ||
| 98 | michael_block(l, r); | ||
| 99 | /* last block is zero, so l ^ 0 = l */ | ||
| 100 | michael_block(l, r); | ||
| 101 | 80 | ||
| 102 | michael_put32(l, mic); | 81 | michael_block(&mctx, val); |
| 103 | michael_put32(r, mic + 4); | 82 | michael_block(&mctx, 0); |
| 83 | |||
| 84 | put_unaligned_le32(mctx.l, mic); | ||
| 85 | put_unaligned_le32(mctx.r, mic + 4); | ||
| 104 | } | 86 | } |
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h index 2e6aebabeea1..3b848dad9587 100644 --- a/net/mac80211/michael.h +++ b/net/mac80211/michael.h | |||
| @@ -14,7 +14,11 @@ | |||
| 14 | 14 | ||
| 15 | #define MICHAEL_MIC_LEN 8 | 15 | #define MICHAEL_MIC_LEN 8 |
| 16 | 16 | ||
| 17 | void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | 17 | struct michael_mic_ctx { |
| 18 | u8 *data, size_t data_len, u8 *mic); | 18 | u32 l, r; |
| 19 | }; | ||
| 20 | |||
| 21 | void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, | ||
| 22 | const u8 *data, size_t data_len, u8 *mic); | ||
| 19 | 23 | ||
| 20 | #endif /* MICHAEL_H */ | 24 | #endif /* MICHAEL_H */ |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d2b582dd055..d7c371e36bf0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -78,7 +78,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, | |||
| 78 | static struct ieee80211_sta_bss * | 78 | static struct ieee80211_sta_bss * |
| 79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, | 79 | ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq, |
| 80 | u8 *ssid, u8 ssid_len); | 80 | u8 *ssid, u8 ssid_len); |
| 81 | static void ieee80211_rx_bss_put(struct net_device *dev, | 81 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
| 82 | struct ieee80211_sta_bss *bss); | 82 | struct ieee80211_sta_bss *bss); |
| 83 | static int ieee80211_sta_find_ibss(struct net_device *dev, | 83 | static int ieee80211_sta_find_ibss(struct net_device *dev, |
| 84 | struct ieee80211_if_sta *ifsta); | 84 | struct ieee80211_if_sta *ifsta); |
| @@ -87,6 +87,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
| 87 | u8 *ssid, size_t ssid_len); | 87 | u8 *ssid, size_t ssid_len); |
| 88 | static int ieee80211_sta_config_auth(struct net_device *dev, | 88 | static int ieee80211_sta_config_auth(struct net_device *dev, |
| 89 | struct ieee80211_if_sta *ifsta); | 89 | struct ieee80211_if_sta *ifsta); |
| 90 | static void sta_rx_agg_session_timer_expired(unsigned long data); | ||
| 90 | 91 | ||
| 91 | 92 | ||
| 92 | void ieee802_11_parse_elems(u8 *start, size_t len, | 93 | void ieee802_11_parse_elems(u8 *start, size_t len, |
| @@ -203,6 +204,25 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
| 203 | elems->perr = pos; | 204 | elems->perr = pos; |
| 204 | elems->perr_len = elen; | 205 | elems->perr_len = elen; |
| 205 | break; | 206 | break; |
| 207 | case WLAN_EID_CHANNEL_SWITCH: | ||
| 208 | elems->ch_switch_elem = pos; | ||
| 209 | elems->ch_switch_elem_len = elen; | ||
| 210 | break; | ||
| 211 | case WLAN_EID_QUIET: | ||
| 212 | if (!elems->quiet_elem) { | ||
| 213 | elems->quiet_elem = pos; | ||
| 214 | elems->quiet_elem_len = elen; | ||
| 215 | } | ||
| 216 | elems->num_of_quiet_elem++; | ||
| 217 | break; | ||
| 218 | case WLAN_EID_COUNTRY: | ||
| 219 | elems->country_elem = pos; | ||
| 220 | elems->country_elem_len = elen; | ||
| 221 | break; | ||
| 222 | case WLAN_EID_PWR_CONSTRAINT: | ||
| 223 | elems->pwr_constr_elem = pos; | ||
| 224 | elems->pwr_constr_elem_len = elen; | ||
| 225 | break; | ||
| 206 | default: | 226 | default: |
| 207 | break; | 227 | break; |
| 208 | } | 228 | } |
| @@ -256,19 +276,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev, | |||
| 256 | qparam.cw_max = 1023; | 276 | qparam.cw_max = 1023; |
| 257 | qparam.txop = 0; | 277 | qparam.txop = 0; |
| 258 | 278 | ||
| 259 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) | 279 | for (i = 0; i < local_to_hw(local)->queues; i++) |
| 260 | local->ops->conf_tx(local_to_hw(local), | 280 | local->ops->conf_tx(local_to_hw(local), i, &qparam); |
| 261 | i + IEEE80211_TX_QUEUE_DATA0, | ||
| 262 | &qparam); | ||
| 263 | |||
| 264 | if (ibss) { | ||
| 265 | /* IBSS uses different parameters for Beacon sending */ | ||
| 266 | qparam.cw_min++; | ||
| 267 | qparam.cw_min *= 2; | ||
| 268 | qparam.cw_min--; | ||
| 269 | local->ops->conf_tx(local_to_hw(local), | ||
| 270 | IEEE80211_TX_QUEUE_BEACON, &qparam); | ||
| 271 | } | ||
| 272 | } | 281 | } |
| 273 | } | 282 | } |
| 274 | 283 | ||
| @@ -282,6 +291,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
| 282 | int count; | 291 | int count; |
| 283 | u8 *pos; | 292 | u8 *pos; |
| 284 | 293 | ||
| 294 | if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
| 295 | return; | ||
| 296 | |||
| 297 | if (!wmm_param) | ||
| 298 | return; | ||
| 299 | |||
| 285 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 300 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
| 286 | return; | 301 | return; |
| 287 | count = wmm_param[6] & 0x0f; | 302 | count = wmm_param[6] & 0x0f; |
| @@ -305,37 +320,33 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
| 305 | 320 | ||
| 306 | switch (aci) { | 321 | switch (aci) { |
| 307 | case 1: | 322 | case 1: |
| 308 | queue = IEEE80211_TX_QUEUE_DATA3; | 323 | queue = 3; |
| 309 | if (acm) { | 324 | if (acm) |
| 310 | local->wmm_acm |= BIT(0) | BIT(3); | 325 | local->wmm_acm |= BIT(0) | BIT(3); |
| 311 | } | ||
| 312 | break; | 326 | break; |
| 313 | case 2: | 327 | case 2: |
| 314 | queue = IEEE80211_TX_QUEUE_DATA1; | 328 | queue = 1; |
| 315 | if (acm) { | 329 | if (acm) |
| 316 | local->wmm_acm |= BIT(4) | BIT(5); | 330 | local->wmm_acm |= BIT(4) | BIT(5); |
| 317 | } | ||
| 318 | break; | 331 | break; |
| 319 | case 3: | 332 | case 3: |
| 320 | queue = IEEE80211_TX_QUEUE_DATA0; | 333 | queue = 0; |
| 321 | if (acm) { | 334 | if (acm) |
| 322 | local->wmm_acm |= BIT(6) | BIT(7); | 335 | local->wmm_acm |= BIT(6) | BIT(7); |
| 323 | } | ||
| 324 | break; | 336 | break; |
| 325 | case 0: | 337 | case 0: |
| 326 | default: | 338 | default: |
| 327 | queue = IEEE80211_TX_QUEUE_DATA2; | 339 | queue = 2; |
| 328 | if (acm) { | 340 | if (acm) |
| 329 | local->wmm_acm |= BIT(1) | BIT(2); | 341 | local->wmm_acm |= BIT(1) | BIT(2); |
| 330 | } | ||
| 331 | break; | 342 | break; |
| 332 | } | 343 | } |
| 333 | 344 | ||
| 334 | params.aifs = pos[0] & 0x0f; | 345 | params.aifs = pos[0] & 0x0f; |
| 335 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
| 336 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 347 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
| 337 | params.txop = pos[2] | (pos[3] << 8); | 348 | params.txop = get_unaligned_le16(pos + 2); |
| 338 | #ifdef CONFIG_MAC80211_DEBUG | 349 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
| 339 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
| 340 | "cWmin=%d cWmax=%d txop=%d\n", | 351 | "cWmin=%d cWmax=%d txop=%d\n", |
| 341 | dev->name, queue, aci, acm, params.aifs, params.cw_min, | 352 | dev->name, queue, aci, acm, params.aifs, params.cw_min, |
| @@ -355,11 +366,14 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
| 355 | bool use_short_preamble) | 366 | bool use_short_preamble) |
| 356 | { | 367 | { |
| 357 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 368 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; |
| 369 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
| 358 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 370 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
| 359 | DECLARE_MAC_BUF(mac); | 371 | DECLARE_MAC_BUF(mac); |
| 372 | #endif | ||
| 360 | u32 changed = 0; | 373 | u32 changed = 0; |
| 361 | 374 | ||
| 362 | if (use_protection != bss_conf->use_cts_prot) { | 375 | if (use_protection != bss_conf->use_cts_prot) { |
| 376 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
| 363 | if (net_ratelimit()) { | 377 | if (net_ratelimit()) { |
| 364 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 378 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" |
| 365 | "%s)\n", | 379 | "%s)\n", |
| @@ -367,11 +381,13 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
| 367 | use_protection ? "enabled" : "disabled", | 381 | use_protection ? "enabled" : "disabled", |
| 368 | print_mac(mac, ifsta->bssid)); | 382 | print_mac(mac, ifsta->bssid)); |
| 369 | } | 383 | } |
| 384 | #endif | ||
| 370 | bss_conf->use_cts_prot = use_protection; | 385 | bss_conf->use_cts_prot = use_protection; |
| 371 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 386 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
| 372 | } | 387 | } |
| 373 | 388 | ||
| 374 | if (use_short_preamble != bss_conf->use_short_preamble) { | 389 | if (use_short_preamble != bss_conf->use_short_preamble) { |
| 390 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
| 375 | if (net_ratelimit()) { | 391 | if (net_ratelimit()) { |
| 376 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 392 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
| 377 | " (BSSID=%s)\n", | 393 | " (BSSID=%s)\n", |
| @@ -379,6 +395,7 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
| 379 | use_short_preamble ? "short" : "long", | 395 | use_short_preamble ? "short" : "long", |
| 380 | print_mac(mac, ifsta->bssid)); | 396 | print_mac(mac, ifsta->bssid)); |
| 381 | } | 397 | } |
| 398 | #endif | ||
| 382 | bss_conf->use_short_preamble = use_short_preamble; | 399 | bss_conf->use_short_preamble = use_short_preamble; |
| 383 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 400 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
| 384 | } | 401 | } |
| @@ -537,7 +554,7 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
| 537 | 554 | ||
| 538 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 555 | changed |= ieee80211_handle_bss_capability(sdata, bss); |
| 539 | 556 | ||
| 540 | ieee80211_rx_bss_put(dev, bss); | 557 | ieee80211_rx_bss_put(local, bss); |
| 541 | } | 558 | } |
| 542 | 559 | ||
| 543 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 560 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { |
| @@ -547,16 +564,15 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
| 547 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | 564 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; |
| 548 | } | 565 | } |
| 549 | 566 | ||
| 550 | netif_carrier_on(dev); | ||
| 551 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; | 567 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
| 552 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 568 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
| 553 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); | 569 | memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); |
| 554 | ieee80211_sta_send_associnfo(dev, ifsta); | 570 | ieee80211_sta_send_associnfo(dev, ifsta); |
| 555 | } else { | 571 | } else { |
| 572 | netif_carrier_off(dev); | ||
| 556 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); | 573 | ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); |
| 557 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 574 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
| 558 | netif_carrier_off(dev); | 575 | changed |= ieee80211_reset_erp_info(dev); |
| 559 | ieee80211_reset_erp_info(dev); | ||
| 560 | 576 | ||
| 561 | sdata->bss_conf.assoc_ht = 0; | 577 | sdata->bss_conf.assoc_ht = 0; |
| 562 | sdata->bss_conf.ht_conf = NULL; | 578 | sdata->bss_conf.ht_conf = NULL; |
| @@ -569,6 +585,10 @@ static void ieee80211_set_associated(struct net_device *dev, | |||
| 569 | 585 | ||
| 570 | sdata->bss_conf.assoc = assoc; | 586 | sdata->bss_conf.assoc = assoc; |
| 571 | ieee80211_bss_info_change_notify(sdata, changed); | 587 | ieee80211_bss_info_change_notify(sdata, changed); |
| 588 | |||
| 589 | if (assoc) | ||
| 590 | netif_carrier_on(dev); | ||
| 591 | |||
| 572 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 592 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
| 573 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 593 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
| 574 | } | 594 | } |
| @@ -586,7 +606,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
| 586 | int encrypt) | 606 | int encrypt) |
| 587 | { | 607 | { |
| 588 | struct ieee80211_sub_if_data *sdata; | 608 | struct ieee80211_sub_if_data *sdata; |
| 589 | struct ieee80211_tx_packet_data *pkt_data; | 609 | struct ieee80211_tx_info *info; |
| 590 | 610 | ||
| 591 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 611 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 592 | skb->dev = sdata->local->mdev; | 612 | skb->dev = sdata->local->mdev; |
| @@ -594,11 +614,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
| 594 | skb_set_network_header(skb, 0); | 614 | skb_set_network_header(skb, 0); |
| 595 | skb_set_transport_header(skb, 0); | 615 | skb_set_transport_header(skb, 0); |
| 596 | 616 | ||
| 597 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 617 | info = IEEE80211_SKB_CB(skb); |
| 598 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 618 | memset(info, 0, sizeof(struct ieee80211_tx_info)); |
| 599 | pkt_data->ifindex = sdata->dev->ifindex; | 619 | info->control.ifindex = sdata->dev->ifindex; |
| 600 | if (!encrypt) | 620 | if (!encrypt) |
| 601 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 621 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 602 | 622 | ||
| 603 | dev_queue_xmit(skb); | 623 | dev_queue_xmit(skb); |
| 604 | } | 624 | } |
| @@ -727,9 +747,8 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
| 727 | if (bss) { | 747 | if (bss) { |
| 728 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 748 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) |
| 729 | capab |= WLAN_CAPABILITY_PRIVACY; | 749 | capab |= WLAN_CAPABILITY_PRIVACY; |
| 730 | if (bss->wmm_ie) { | 750 | if (bss->wmm_ie) |
| 731 | wmm = 1; | 751 | wmm = 1; |
| 732 | } | ||
| 733 | 752 | ||
| 734 | /* get all rates supported by the device and the AP as | 753 | /* get all rates supported by the device and the AP as |
| 735 | * some APs don't like getting a superset of their rates | 754 | * some APs don't like getting a superset of their rates |
| @@ -737,7 +756,11 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
| 737 | * b-only mode) */ | 756 | * b-only mode) */ |
| 738 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | 757 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); |
| 739 | 758 | ||
| 740 | ieee80211_rx_bss_put(dev, bss); | 759 | if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && |
| 760 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | ||
| 761 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | ||
| 762 | |||
| 763 | ieee80211_rx_bss_put(local, bss); | ||
| 741 | } else { | 764 | } else { |
| 742 | rates = ~0; | 765 | rates = ~0; |
| 743 | rates_len = sband->n_bitrates; | 766 | rates_len = sband->n_bitrates; |
| @@ -804,6 +827,26 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
| 804 | } | 827 | } |
| 805 | } | 828 | } |
| 806 | 829 | ||
| 830 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { | ||
| 831 | /* 1. power capabilities */ | ||
| 832 | pos = skb_put(skb, 4); | ||
| 833 | *pos++ = WLAN_EID_PWR_CAPABILITY; | ||
| 834 | *pos++ = 2; | ||
| 835 | *pos++ = 0; /* min tx power */ | ||
| 836 | *pos++ = local->hw.conf.channel->max_power; /* max tx power */ | ||
| 837 | |||
| 838 | /* 2. supported channels */ | ||
| 839 | /* TODO: get this in reg domain format */ | ||
| 840 | pos = skb_put(skb, 2 * sband->n_channels + 2); | ||
| 841 | *pos++ = WLAN_EID_SUPPORTED_CHANNELS; | ||
| 842 | *pos++ = 2 * sband->n_channels; | ||
| 843 | for (i = 0; i < sband->n_channels; i++) { | ||
| 844 | *pos++ = ieee80211_frequency_to_channel( | ||
| 845 | sband->channels[i].center_freq); | ||
| 846 | *pos++ = 1; /* one channel in the subband*/ | ||
| 847 | } | ||
| 848 | } | ||
| 849 | |||
| 807 | if (ifsta->extra_ie) { | 850 | if (ifsta->extra_ie) { |
| 808 | pos = skb_put(skb, ifsta->extra_ie_len); | 851 | pos = skb_put(skb, ifsta->extra_ie_len); |
| 809 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); | 852 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); |
| @@ -821,9 +864,32 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
| 821 | *pos++ = 1; /* WME ver */ | 864 | *pos++ = 1; /* WME ver */ |
| 822 | *pos++ = 0; | 865 | *pos++ = 0; |
| 823 | } | 866 | } |
| 867 | |||
| 824 | /* wmm support is a must to HT */ | 868 | /* wmm support is a must to HT */ |
| 825 | if (wmm && sband->ht_info.ht_supported) { | 869 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
| 826 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 870 | sband->ht_info.ht_supported && bss->ht_add_ie) { |
| 871 | struct ieee80211_ht_addt_info *ht_add_info = | ||
| 872 | (struct ieee80211_ht_addt_info *)bss->ht_add_ie; | ||
| 873 | u16 cap = sband->ht_info.cap; | ||
| 874 | __le16 tmp; | ||
| 875 | u32 flags = local->hw.conf.channel->flags; | ||
| 876 | |||
| 877 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | ||
| 878 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | ||
| 879 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | ||
| 880 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
| 881 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
| 882 | } | ||
| 883 | break; | ||
| 884 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | ||
| 885 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | ||
| 886 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
| 887 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
| 888 | } | ||
| 889 | break; | ||
| 890 | } | ||
| 891 | |||
| 892 | tmp = cpu_to_le16(cap); | ||
| 827 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 893 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
| 828 | *pos++ = WLAN_EID_HT_CAPABILITY; | 894 | *pos++ = WLAN_EID_HT_CAPABILITY; |
| 829 | *pos++ = sizeof(struct ieee80211_ht_cap); | 895 | *pos++ = sizeof(struct ieee80211_ht_cap); |
| @@ -926,7 +992,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, | |||
| 926 | wep_privacy = !!ieee80211_sta_wep_configured(dev); | 992 | wep_privacy = !!ieee80211_sta_wep_configured(dev); |
| 927 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); | 993 | privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); |
| 928 | 994 | ||
| 929 | ieee80211_rx_bss_put(dev, bss); | 995 | ieee80211_rx_bss_put(local, bss); |
| 930 | 996 | ||
| 931 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) | 997 | if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) |
| 932 | return 0; | 998 | return 0; |
| @@ -1118,14 +1184,10 @@ static void ieee80211_auth_challenge(struct net_device *dev, | |||
| 1118 | u8 *pos; | 1184 | u8 *pos; |
| 1119 | struct ieee802_11_elems elems; | 1185 | struct ieee802_11_elems elems; |
| 1120 | 1186 | ||
| 1121 | printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); | ||
| 1122 | pos = mgmt->u.auth.variable; | 1187 | pos = mgmt->u.auth.variable; |
| 1123 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 1188 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
| 1124 | if (!elems.challenge) { | 1189 | if (!elems.challenge) |
| 1125 | printk(KERN_DEBUG "%s: no challenge IE in shared key auth " | ||
| 1126 | "frame\n", dev->name); | ||
| 1127 | return; | 1190 | return; |
| 1128 | } | ||
| 1129 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, | 1191 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, |
| 1130 | elems.challenge_len + 2, 1); | 1192 | elems.challenge_len + 2, 1); |
| 1131 | } | 1193 | } |
| @@ -1141,8 +1203,8 @@ static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid, | |||
| 1141 | struct ieee80211_mgmt *mgmt; | 1203 | struct ieee80211_mgmt *mgmt; |
| 1142 | u16 capab; | 1204 | u16 capab; |
| 1143 | 1205 | ||
| 1144 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1206 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
| 1145 | sizeof(mgmt->u.action.u.addba_resp)); | 1207 | |
| 1146 | if (!skb) { | 1208 | if (!skb) { |
| 1147 | printk(KERN_DEBUG "%s: failed to allocate buffer " | 1209 | printk(KERN_DEBUG "%s: failed to allocate buffer " |
| 1148 | "for addba resp frame\n", dev->name); | 1210 | "for addba resp frame\n", dev->name); |
| @@ -1190,9 +1252,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, | |||
| 1190 | struct ieee80211_mgmt *mgmt; | 1252 | struct ieee80211_mgmt *mgmt; |
| 1191 | u16 capab; | 1253 | u16 capab; |
| 1192 | 1254 | ||
| 1193 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1255 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
| 1194 | sizeof(mgmt->u.action.u.addba_req)); | ||
| 1195 | |||
| 1196 | 1256 | ||
| 1197 | if (!skb) { | 1257 | if (!skb) { |
| 1198 | printk(KERN_ERR "%s: failed to allocate buffer " | 1258 | printk(KERN_ERR "%s: failed to allocate buffer " |
| @@ -1293,7 +1353,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
| 1293 | 1353 | ||
| 1294 | 1354 | ||
| 1295 | /* examine state machine */ | 1355 | /* examine state machine */ |
| 1296 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1356 | spin_lock_bh(&sta->lock); |
| 1297 | 1357 | ||
| 1298 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 1358 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { |
| 1299 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1359 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| @@ -1309,9 +1369,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
| 1309 | sta->ampdu_mlme.tid_rx[tid] = | 1369 | sta->ampdu_mlme.tid_rx[tid] = |
| 1310 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); | 1370 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); |
| 1311 | if (!sta->ampdu_mlme.tid_rx[tid]) { | 1371 | if (!sta->ampdu_mlme.tid_rx[tid]) { |
| 1372 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 1312 | if (net_ratelimit()) | 1373 | if (net_ratelimit()) |
| 1313 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", | 1374 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", |
| 1314 | tid); | 1375 | tid); |
| 1376 | #endif | ||
| 1315 | goto end; | 1377 | goto end; |
| 1316 | } | 1378 | } |
| 1317 | /* rx timer */ | 1379 | /* rx timer */ |
| @@ -1327,9 +1389,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
| 1327 | tid_agg_rx->reorder_buf = | 1389 | tid_agg_rx->reorder_buf = |
| 1328 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); | 1390 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); |
| 1329 | if (!tid_agg_rx->reorder_buf) { | 1391 | if (!tid_agg_rx->reorder_buf) { |
| 1392 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 1330 | if (net_ratelimit()) | 1393 | if (net_ratelimit()) |
| 1331 | printk(KERN_ERR "can not allocate reordering buffer " | 1394 | printk(KERN_ERR "can not allocate reordering buffer " |
| 1332 | "to tid %d\n", tid); | 1395 | "to tid %d\n", tid); |
| 1396 | #endif | ||
| 1333 | kfree(sta->ampdu_mlme.tid_rx[tid]); | 1397 | kfree(sta->ampdu_mlme.tid_rx[tid]); |
| 1334 | goto end; | 1398 | goto end; |
| 1335 | } | 1399 | } |
| @@ -1360,7 +1424,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
| 1360 | tid_agg_rx->stored_mpdu_num = 0; | 1424 | tid_agg_rx->stored_mpdu_num = 0; |
| 1361 | status = WLAN_STATUS_SUCCESS; | 1425 | status = WLAN_STATUS_SUCCESS; |
| 1362 | end: | 1426 | end: |
| 1363 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1427 | spin_unlock_bh(&sta->lock); |
| 1364 | 1428 | ||
| 1365 | end_no_lock: | 1429 | end_no_lock: |
| 1366 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, | 1430 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, |
| @@ -1392,18 +1456,16 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
| 1392 | 1456 | ||
| 1393 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1457 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 1394 | 1458 | ||
| 1395 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1459 | spin_lock_bh(&sta->lock); |
| 1396 | 1460 | ||
| 1397 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1461 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
| 1398 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1462 | spin_unlock_bh(&sta->lock); |
| 1399 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | ||
| 1400 | "%d\n", *state); | ||
| 1401 | goto addba_resp_exit; | 1463 | goto addba_resp_exit; |
| 1402 | } | 1464 | } |
| 1403 | 1465 | ||
| 1404 | if (mgmt->u.action.u.addba_resp.dialog_token != | 1466 | if (mgmt->u.action.u.addba_resp.dialog_token != |
| 1405 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 1467 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
| 1406 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1468 | spin_unlock_bh(&sta->lock); |
| 1407 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1469 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 1408 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 1470 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
| 1409 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1471 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| @@ -1416,26 +1478,18 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
| 1416 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1478 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 1417 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 1479 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
| 1418 | == WLAN_STATUS_SUCCESS) { | 1480 | == WLAN_STATUS_SUCCESS) { |
| 1419 | if (*state & HT_ADDBA_RECEIVED_MSK) | ||
| 1420 | printk(KERN_DEBUG "double addBA response\n"); | ||
| 1421 | |||
| 1422 | *state |= HT_ADDBA_RECEIVED_MSK; | 1481 | *state |= HT_ADDBA_RECEIVED_MSK; |
| 1423 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 1482 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
| 1424 | 1483 | ||
| 1425 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 1484 | if (*state == HT_AGG_STATE_OPERATIONAL) |
| 1426 | printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); | ||
| 1427 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1485 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
| 1428 | } | ||
| 1429 | 1486 | ||
| 1430 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1487 | spin_unlock_bh(&sta->lock); |
| 1431 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | ||
| 1432 | } else { | 1488 | } else { |
| 1433 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | ||
| 1434 | |||
| 1435 | sta->ampdu_mlme.addba_req_num[tid]++; | 1489 | sta->ampdu_mlme.addba_req_num[tid]++; |
| 1436 | /* this will allow the state check in stop_BA_session */ | 1490 | /* this will allow the state check in stop_BA_session */ |
| 1437 | *state = HT_AGG_STATE_OPERATIONAL; | 1491 | *state = HT_AGG_STATE_OPERATIONAL; |
| 1438 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1492 | spin_unlock_bh(&sta->lock); |
| 1439 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, | 1493 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, |
| 1440 | WLAN_BACK_INITIATOR); | 1494 | WLAN_BACK_INITIATOR); |
| 1441 | } | 1495 | } |
| @@ -1454,8 +1508,7 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | |||
| 1454 | struct ieee80211_mgmt *mgmt; | 1508 | struct ieee80211_mgmt *mgmt; |
| 1455 | u16 params; | 1509 | u16 params; |
| 1456 | 1510 | ||
| 1457 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1511 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
| 1458 | sizeof(mgmt->u.action.u.delba)); | ||
| 1459 | 1512 | ||
| 1460 | if (!skb) { | 1513 | if (!skb) { |
| 1461 | printk(KERN_ERR "%s: failed to allocate buffer " | 1514 | printk(KERN_ERR "%s: failed to allocate buffer " |
| @@ -1488,6 +1541,35 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | |||
| 1488 | ieee80211_sta_tx(dev, skb, 0); | 1541 | ieee80211_sta_tx(dev, skb, 0); |
| 1489 | } | 1542 | } |
| 1490 | 1543 | ||
| 1544 | void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn) | ||
| 1545 | { | ||
| 1546 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1547 | struct sk_buff *skb; | ||
| 1548 | struct ieee80211_bar *bar; | ||
| 1549 | u16 bar_control = 0; | ||
| 1550 | |||
| 1551 | skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); | ||
| 1552 | if (!skb) { | ||
| 1553 | printk(KERN_ERR "%s: failed to allocate buffer for " | ||
| 1554 | "bar frame\n", dev->name); | ||
| 1555 | return; | ||
| 1556 | } | ||
| 1557 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
| 1558 | bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar)); | ||
| 1559 | memset(bar, 0, sizeof(*bar)); | ||
| 1560 | bar->frame_control = IEEE80211_FC(IEEE80211_FTYPE_CTL, | ||
| 1561 | IEEE80211_STYPE_BACK_REQ); | ||
| 1562 | memcpy(bar->ra, ra, ETH_ALEN); | ||
| 1563 | memcpy(bar->ta, dev->dev_addr, ETH_ALEN); | ||
| 1564 | bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL; | ||
| 1565 | bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA; | ||
| 1566 | bar_control |= (u16)(tid << 12); | ||
| 1567 | bar->control = cpu_to_le16(bar_control); | ||
| 1568 | bar->start_seq_num = cpu_to_le16(ssn); | ||
| 1569 | |||
| 1570 | ieee80211_sta_tx(dev, skb, 0); | ||
| 1571 | } | ||
| 1572 | |||
| 1491 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | 1573 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, |
| 1492 | u16 initiator, u16 reason) | 1574 | u16 initiator, u16 reason) |
| 1493 | { | 1575 | { |
| @@ -1506,17 +1588,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
| 1506 | } | 1588 | } |
| 1507 | 1589 | ||
| 1508 | /* check if TID is in operational state */ | 1590 | /* check if TID is in operational state */ |
| 1509 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1591 | spin_lock_bh(&sta->lock); |
| 1510 | if (sta->ampdu_mlme.tid_state_rx[tid] | 1592 | if (sta->ampdu_mlme.tid_state_rx[tid] |
| 1511 | != HT_AGG_STATE_OPERATIONAL) { | 1593 | != HT_AGG_STATE_OPERATIONAL) { |
| 1512 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1594 | spin_unlock_bh(&sta->lock); |
| 1513 | rcu_read_unlock(); | 1595 | rcu_read_unlock(); |
| 1514 | return; | 1596 | return; |
| 1515 | } | 1597 | } |
| 1516 | sta->ampdu_mlme.tid_state_rx[tid] = | 1598 | sta->ampdu_mlme.tid_state_rx[tid] = |
| 1517 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 1599 | HT_AGG_STATE_REQ_STOP_BA_MSK | |
| 1518 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 1600 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
| 1519 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1601 | spin_unlock_bh(&sta->lock); |
| 1520 | 1602 | ||
| 1521 | /* stop HW Rx aggregation. ampdu_action existence | 1603 | /* stop HW Rx aggregation. ampdu_action existence |
| 1522 | * already verified in session init so we add the BUG_ON */ | 1604 | * already verified in session init so we add the BUG_ON */ |
| @@ -1531,7 +1613,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
| 1531 | ra, tid, NULL); | 1613 | ra, tid, NULL); |
| 1532 | if (ret) | 1614 | if (ret) |
| 1533 | printk(KERN_DEBUG "HW problem - can not stop rx " | 1615 | printk(KERN_DEBUG "HW problem - can not stop rx " |
| 1534 | "aggergation for tid %d\n", tid); | 1616 | "aggregation for tid %d\n", tid); |
| 1535 | 1617 | ||
| 1536 | /* shutdown timer has not expired */ | 1618 | /* shutdown timer has not expired */ |
| 1537 | if (initiator != WLAN_BACK_TIMER) | 1619 | if (initiator != WLAN_BACK_TIMER) |
| @@ -1593,10 +1675,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev, | |||
| 1593 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, | 1675 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, |
| 1594 | WLAN_BACK_INITIATOR, 0); | 1676 | WLAN_BACK_INITIATOR, 0); |
| 1595 | else { /* WLAN_BACK_RECIPIENT */ | 1677 | else { /* WLAN_BACK_RECIPIENT */ |
| 1596 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1678 | spin_lock_bh(&sta->lock); |
| 1597 | sta->ampdu_mlme.tid_state_tx[tid] = | 1679 | sta->ampdu_mlme.tid_state_tx[tid] = |
| 1598 | HT_AGG_STATE_OPERATIONAL; | 1680 | HT_AGG_STATE_OPERATIONAL; |
| 1599 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1681 | spin_unlock_bh(&sta->lock); |
| 1600 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, | 1682 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, |
| 1601 | WLAN_BACK_RECIPIENT); | 1683 | WLAN_BACK_RECIPIENT); |
| 1602 | } | 1684 | } |
| @@ -1633,20 +1715,24 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
| 1633 | 1715 | ||
| 1634 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1716 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 1635 | /* check if the TID waits for addBA response */ | 1717 | /* check if the TID waits for addBA response */ |
| 1636 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1718 | spin_lock_bh(&sta->lock); |
| 1637 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1719 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
| 1638 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1720 | spin_unlock_bh(&sta->lock); |
| 1639 | *state = HT_AGG_STATE_IDLE; | 1721 | *state = HT_AGG_STATE_IDLE; |
| 1722 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 1640 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 1723 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
| 1641 | "expecting addBA response there", tid); | 1724 | "expecting addBA response there", tid); |
| 1725 | #endif | ||
| 1642 | goto timer_expired_exit; | 1726 | goto timer_expired_exit; |
| 1643 | } | 1727 | } |
| 1644 | 1728 | ||
| 1729 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 1645 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | 1730 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); |
| 1731 | #endif | ||
| 1646 | 1732 | ||
| 1647 | /* go through the state check in stop_BA_session */ | 1733 | /* go through the state check in stop_BA_session */ |
| 1648 | *state = HT_AGG_STATE_OPERATIONAL; | 1734 | *state = HT_AGG_STATE_OPERATIONAL; |
| 1649 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1735 | spin_unlock_bh(&sta->lock); |
| 1650 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, | 1736 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, |
| 1651 | WLAN_BACK_INITIATOR); | 1737 | WLAN_BACK_INITIATOR); |
| 1652 | 1738 | ||
| @@ -1659,7 +1745,7 @@ timer_expired_exit: | |||
| 1659 | * resetting it after each frame that arrives from the originator. | 1745 | * resetting it after each frame that arrives from the originator. |
| 1660 | * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. | 1746 | * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. |
| 1661 | */ | 1747 | */ |
| 1662 | void sta_rx_agg_session_timer_expired(unsigned long data) | 1748 | static void sta_rx_agg_session_timer_expired(unsigned long data) |
| 1663 | { | 1749 | { |
| 1664 | /* not an elegant detour, but there is no choice as the timer passes | 1750 | /* not an elegant detour, but there is no choice as the timer passes |
| 1665 | * only one argument, and various sta_info are needed here, so init | 1751 | * only one argument, and various sta_info are needed here, so init |
| @@ -1670,7 +1756,9 @@ void sta_rx_agg_session_timer_expired(unsigned long data) | |||
| 1670 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, | 1756 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, |
| 1671 | timer_to_tid[0]); | 1757 | timer_to_tid[0]); |
| 1672 | 1758 | ||
| 1759 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
| 1673 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 1760 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
| 1761 | #endif | ||
| 1674 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, | 1762 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, |
| 1675 | (u16)*ptid, WLAN_BACK_TIMER, | 1763 | (u16)*ptid, WLAN_BACK_TIMER, |
| 1676 | WLAN_REASON_QSTA_TIMEOUT); | 1764 | WLAN_REASON_QSTA_TIMEOUT); |
| @@ -1690,6 +1778,71 @@ void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr) | |||
| 1690 | } | 1778 | } |
| 1691 | } | 1779 | } |
| 1692 | 1780 | ||
| 1781 | static void ieee80211_send_refuse_measurement_request(struct net_device *dev, | ||
| 1782 | struct ieee80211_msrment_ie *request_ie, | ||
| 1783 | const u8 *da, const u8 *bssid, | ||
| 1784 | u8 dialog_token) | ||
| 1785 | { | ||
| 1786 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1787 | struct sk_buff *skb; | ||
| 1788 | struct ieee80211_mgmt *msr_report; | ||
| 1789 | |||
| 1790 | skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + | ||
| 1791 | sizeof(struct ieee80211_msrment_ie)); | ||
| 1792 | |||
| 1793 | if (!skb) { | ||
| 1794 | printk(KERN_ERR "%s: failed to allocate buffer for " | ||
| 1795 | "measurement report frame\n", dev->name); | ||
| 1796 | return; | ||
| 1797 | } | ||
| 1798 | |||
| 1799 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
| 1800 | msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); | ||
| 1801 | memset(msr_report, 0, 24); | ||
| 1802 | memcpy(msr_report->da, da, ETH_ALEN); | ||
| 1803 | memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN); | ||
| 1804 | memcpy(msr_report->bssid, bssid, ETH_ALEN); | ||
| 1805 | msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
| 1806 | IEEE80211_STYPE_ACTION); | ||
| 1807 | |||
| 1808 | skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); | ||
| 1809 | msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
| 1810 | msr_report->u.action.u.measurement.action_code = | ||
| 1811 | WLAN_ACTION_SPCT_MSR_RPRT; | ||
| 1812 | msr_report->u.action.u.measurement.dialog_token = dialog_token; | ||
| 1813 | |||
| 1814 | msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; | ||
| 1815 | msr_report->u.action.u.measurement.length = | ||
| 1816 | sizeof(struct ieee80211_msrment_ie); | ||
| 1817 | |||
| 1818 | memset(&msr_report->u.action.u.measurement.msr_elem, 0, | ||
| 1819 | sizeof(struct ieee80211_msrment_ie)); | ||
| 1820 | msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; | ||
| 1821 | msr_report->u.action.u.measurement.msr_elem.mode |= | ||
| 1822 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | ||
| 1823 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | ||
| 1824 | |||
| 1825 | ieee80211_sta_tx(dev, skb, 0); | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | static void ieee80211_sta_process_measurement_req(struct net_device *dev, | ||
| 1829 | struct ieee80211_mgmt *mgmt, | ||
| 1830 | size_t len) | ||
| 1831 | { | ||
| 1832 | /* | ||
| 1833 | * Ignoring measurement request is spec violation. | ||
| 1834 | * Mandatory measurements must be reported optional | ||
| 1835 | * measurements might be refused or reported incapable | ||
| 1836 | * For now just refuse | ||
| 1837 | * TODO: Answer basic measurement as unmeasured | ||
| 1838 | */ | ||
| 1839 | ieee80211_send_refuse_measurement_request(dev, | ||
| 1840 | &mgmt->u.action.u.measurement.msr_elem, | ||
| 1841 | mgmt->sa, mgmt->bssid, | ||
| 1842 | mgmt->u.action.u.measurement.dialog_token); | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | |||
| 1693 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, | 1846 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, |
| 1694 | struct ieee80211_if_sta *ifsta, | 1847 | struct ieee80211_if_sta *ifsta, |
| 1695 | struct ieee80211_mgmt *mgmt, | 1848 | struct ieee80211_mgmt *mgmt, |
| @@ -1700,73 +1853,41 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
| 1700 | DECLARE_MAC_BUF(mac); | 1853 | DECLARE_MAC_BUF(mac); |
| 1701 | 1854 | ||
| 1702 | if (ifsta->state != IEEE80211_AUTHENTICATE && | 1855 | if (ifsta->state != IEEE80211_AUTHENTICATE && |
| 1703 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1856 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
| 1704 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
| 1705 | "%s, but not in authenticate state - ignored\n", | ||
| 1706 | dev->name, print_mac(mac, mgmt->sa)); | ||
| 1707 | return; | 1857 | return; |
| 1708 | } | ||
| 1709 | 1858 | ||
| 1710 | if (len < 24 + 6) { | 1859 | if (len < 24 + 6) |
| 1711 | printk(KERN_DEBUG "%s: too short (%zd) authentication frame " | ||
| 1712 | "received from %s - ignored\n", | ||
| 1713 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
| 1714 | return; | 1860 | return; |
| 1715 | } | ||
| 1716 | 1861 | ||
| 1717 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1862 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
| 1718 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1863 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
| 1719 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
| 1720 | "unknown AP (SA=%s BSSID=%s) - " | ||
| 1721 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
| 1722 | print_mac(mac, mgmt->bssid)); | ||
| 1723 | return; | 1864 | return; |
| 1724 | } | ||
| 1725 | 1865 | ||
| 1726 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1866 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
| 1727 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) { | 1867 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
| 1728 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
| 1729 | "unknown BSSID (SA=%s BSSID=%s) - " | ||
| 1730 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
| 1731 | print_mac(mac, mgmt->bssid)); | ||
| 1732 | return; | 1868 | return; |
| 1733 | } | ||
| 1734 | 1869 | ||
| 1735 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1870 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
| 1736 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 1871 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
| 1737 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | 1872 | status_code = le16_to_cpu(mgmt->u.auth.status_code); |
| 1738 | 1873 | ||
| 1739 | printk(KERN_DEBUG "%s: RX authentication from %s (alg=%d " | ||
| 1740 | "transaction=%d status=%d)\n", | ||
| 1741 | dev->name, print_mac(mac, mgmt->sa), auth_alg, | ||
| 1742 | auth_transaction, status_code); | ||
| 1743 | |||
| 1744 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 1874 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
| 1745 | /* IEEE 802.11 standard does not require authentication in IBSS | 1875 | /* |
| 1876 | * IEEE 802.11 standard does not require authentication in IBSS | ||
| 1746 | * networks and most implementations do not seem to use it. | 1877 | * networks and most implementations do not seem to use it. |
| 1747 | * However, try to reply to authentication attempts if someone | 1878 | * However, try to reply to authentication attempts if someone |
| 1748 | * has actually implemented this. | 1879 | * has actually implemented this. |
| 1749 | * TODO: Could implement shared key authentication. */ | 1880 | */ |
| 1750 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { | 1881 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
| 1751 | printk(KERN_DEBUG "%s: unexpected IBSS authentication " | ||
| 1752 | "frame (alg=%d transaction=%d)\n", | ||
| 1753 | dev->name, auth_alg, auth_transaction); | ||
| 1754 | return; | 1882 | return; |
| 1755 | } | ||
| 1756 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); | 1883 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); |
| 1757 | } | 1884 | } |
| 1758 | 1885 | ||
| 1759 | if (auth_alg != ifsta->auth_alg || | 1886 | if (auth_alg != ifsta->auth_alg || |
| 1760 | auth_transaction != ifsta->auth_transaction) { | 1887 | auth_transaction != ifsta->auth_transaction) |
| 1761 | printk(KERN_DEBUG "%s: unexpected authentication frame " | ||
| 1762 | "(alg=%d transaction=%d)\n", | ||
| 1763 | dev->name, auth_alg, auth_transaction); | ||
| 1764 | return; | 1888 | return; |
| 1765 | } | ||
| 1766 | 1889 | ||
| 1767 | if (status_code != WLAN_STATUS_SUCCESS) { | 1890 | if (status_code != WLAN_STATUS_SUCCESS) { |
| 1768 | printk(KERN_DEBUG "%s: AP denied authentication (auth_alg=%d " | ||
| 1769 | "code=%d)\n", dev->name, ifsta->auth_alg, status_code); | ||
| 1770 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { | 1891 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { |
| 1771 | u8 algs[3]; | 1892 | u8 algs[3]; |
| 1772 | const int num_algs = ARRAY_SIZE(algs); | 1893 | const int num_algs = ARRAY_SIZE(algs); |
| @@ -1795,9 +1916,6 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
| 1795 | !ieee80211_sta_wep_configured(dev)) | 1916 | !ieee80211_sta_wep_configured(dev)) |
| 1796 | continue; | 1917 | continue; |
| 1797 | ifsta->auth_alg = algs[pos]; | 1918 | ifsta->auth_alg = algs[pos]; |
| 1798 | printk(KERN_DEBUG "%s: set auth_alg=%d for " | ||
| 1799 | "next try\n", | ||
| 1800 | dev->name, ifsta->auth_alg); | ||
| 1801 | break; | 1919 | break; |
| 1802 | } | 1920 | } |
| 1803 | } | 1921 | } |
| @@ -1827,30 +1945,16 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev, | |||
| 1827 | u16 reason_code; | 1945 | u16 reason_code; |
| 1828 | DECLARE_MAC_BUF(mac); | 1946 | DECLARE_MAC_BUF(mac); |
| 1829 | 1947 | ||
| 1830 | if (len < 24 + 2) { | 1948 | if (len < 24 + 2) |
| 1831 | printk(KERN_DEBUG "%s: too short (%zd) deauthentication frame " | ||
| 1832 | "received from %s - ignored\n", | ||
| 1833 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
| 1834 | return; | 1949 | return; |
| 1835 | } | ||
| 1836 | 1950 | ||
| 1837 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1951 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
| 1838 | printk(KERN_DEBUG "%s: deauthentication frame received from " | ||
| 1839 | "unknown AP (SA=%s BSSID=%s) - " | ||
| 1840 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
| 1841 | print_mac(mac, mgmt->bssid)); | ||
| 1842 | return; | 1952 | return; |
| 1843 | } | ||
| 1844 | 1953 | ||
| 1845 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1954 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
| 1846 | 1955 | ||
| 1847 | printk(KERN_DEBUG "%s: RX deauthentication from %s" | 1956 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
| 1848 | " (reason=%d)\n", | ||
| 1849 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
| 1850 | |||
| 1851 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) { | ||
| 1852 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); | 1957 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); |
| 1853 | } | ||
| 1854 | 1958 | ||
| 1855 | if (ifsta->state == IEEE80211_AUTHENTICATE || | 1959 | if (ifsta->state == IEEE80211_AUTHENTICATE || |
| 1856 | ifsta->state == IEEE80211_ASSOCIATE || | 1960 | ifsta->state == IEEE80211_ASSOCIATE || |
| @@ -1873,27 +1977,14 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, | |||
| 1873 | u16 reason_code; | 1977 | u16 reason_code; |
| 1874 | DECLARE_MAC_BUF(mac); | 1978 | DECLARE_MAC_BUF(mac); |
| 1875 | 1979 | ||
| 1876 | if (len < 24 + 2) { | 1980 | if (len < 24 + 2) |
| 1877 | printk(KERN_DEBUG "%s: too short (%zd) disassociation frame " | ||
| 1878 | "received from %s - ignored\n", | ||
| 1879 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
| 1880 | return; | 1981 | return; |
| 1881 | } | ||
| 1882 | 1982 | ||
| 1883 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1983 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
| 1884 | printk(KERN_DEBUG "%s: disassociation frame received from " | ||
| 1885 | "unknown AP (SA=%s BSSID=%s) - " | ||
| 1886 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
| 1887 | print_mac(mac, mgmt->bssid)); | ||
| 1888 | return; | 1984 | return; |
| 1889 | } | ||
| 1890 | 1985 | ||
| 1891 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1986 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
| 1892 | 1987 | ||
| 1893 | printk(KERN_DEBUG "%s: RX disassociation from %s" | ||
| 1894 | " (reason=%d)\n", | ||
| 1895 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
| 1896 | |||
| 1897 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1988 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
| 1898 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); | 1989 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); |
| 1899 | 1990 | ||
| @@ -1929,27 +2020,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 1929 | /* AssocResp and ReassocResp have identical structure, so process both | 2020 | /* AssocResp and ReassocResp have identical structure, so process both |
| 1930 | * of them in this function. */ | 2021 | * of them in this function. */ |
| 1931 | 2022 | ||
| 1932 | if (ifsta->state != IEEE80211_ASSOCIATE) { | 2023 | if (ifsta->state != IEEE80211_ASSOCIATE) |
| 1933 | printk(KERN_DEBUG "%s: association frame received from " | ||
| 1934 | "%s, but not in associate state - ignored\n", | ||
| 1935 | dev->name, print_mac(mac, mgmt->sa)); | ||
| 1936 | return; | 2024 | return; |
| 1937 | } | ||
| 1938 | 2025 | ||
| 1939 | if (len < 24 + 6) { | 2026 | if (len < 24 + 6) |
| 1940 | printk(KERN_DEBUG "%s: too short (%zd) association frame " | ||
| 1941 | "received from %s - ignored\n", | ||
| 1942 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
| 1943 | return; | 2027 | return; |
| 1944 | } | ||
| 1945 | 2028 | ||
| 1946 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 2029 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
| 1947 | printk(KERN_DEBUG "%s: association frame received from " | ||
| 1948 | "unknown AP (SA=%s BSSID=%s) - " | ||
| 1949 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
| 1950 | print_mac(mac, mgmt->bssid)); | ||
| 1951 | return; | 2030 | return; |
| 1952 | } | ||
| 1953 | 2031 | ||
| 1954 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 2032 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
| 1955 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 2033 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
| @@ -2013,10 +2091,10 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2013 | local->hw.conf.channel->center_freq, | 2091 | local->hw.conf.channel->center_freq, |
| 2014 | ifsta->ssid, ifsta->ssid_len); | 2092 | ifsta->ssid, ifsta->ssid_len); |
| 2015 | if (bss) { | 2093 | if (bss) { |
| 2016 | sta->last_rssi = bss->rssi; | ||
| 2017 | sta->last_signal = bss->signal; | 2094 | sta->last_signal = bss->signal; |
| 2095 | sta->last_qual = bss->qual; | ||
| 2018 | sta->last_noise = bss->noise; | 2096 | sta->last_noise = bss->noise; |
| 2019 | ieee80211_rx_bss_put(dev, bss); | 2097 | ieee80211_rx_bss_put(local, bss); |
| 2020 | } | 2098 | } |
| 2021 | 2099 | ||
| 2022 | err = sta_info_insert(sta); | 2100 | err = sta_info_insert(sta); |
| @@ -2038,8 +2116,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2038 | * to between the sta_info_alloc() and sta_info_insert() above. | 2116 | * to between the sta_info_alloc() and sta_info_insert() above. |
| 2039 | */ | 2117 | */ |
| 2040 | 2118 | ||
| 2041 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | | 2119 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
| 2042 | WLAN_STA_AUTHORIZED; | 2120 | WLAN_STA_AUTHORIZED); |
| 2043 | 2121 | ||
| 2044 | rates = 0; | 2122 | rates = 0; |
| 2045 | basic_rates = 0; | 2123 | basic_rates = 0; |
| @@ -2083,7 +2161,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2083 | else | 2161 | else |
| 2084 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 2162 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
| 2085 | 2163 | ||
| 2086 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | 2164 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
| 2165 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
| 2087 | struct ieee80211_ht_bss_info bss_info; | 2166 | struct ieee80211_ht_bss_info bss_info; |
| 2088 | ieee80211_ht_cap_ie_to_ht_info( | 2167 | ieee80211_ht_cap_ie_to_ht_info( |
| 2089 | (struct ieee80211_ht_cap *) | 2168 | (struct ieee80211_ht_cap *) |
| @@ -2096,8 +2175,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
| 2096 | 2175 | ||
| 2097 | rate_control_rate_init(sta, local); | 2176 | rate_control_rate_init(sta, local); |
| 2098 | 2177 | ||
| 2099 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2178 | if (elems.wmm_param) { |
| 2100 | sta->flags |= WLAN_STA_WME; | 2179 | set_sta_flags(sta, WLAN_STA_WME); |
| 2101 | rcu_read_unlock(); | 2180 | rcu_read_unlock(); |
| 2102 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2181 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
| 2103 | elems.wmm_param_len); | 2182 | elems.wmm_param_len); |
| @@ -2133,10 +2212,9 @@ static void __ieee80211_rx_bss_hash_add(struct net_device *dev, | |||
| 2133 | 2212 | ||
| 2134 | 2213 | ||
| 2135 | /* Caller must hold local->sta_bss_lock */ | 2214 | /* Caller must hold local->sta_bss_lock */ |
| 2136 | static void __ieee80211_rx_bss_hash_del(struct net_device *dev, | 2215 | static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local, |
| 2137 | struct ieee80211_sta_bss *bss) | 2216 | struct ieee80211_sta_bss *bss) |
| 2138 | { | 2217 | { |
| 2139 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 2140 | struct ieee80211_sta_bss *b, *prev = NULL; | 2218 | struct ieee80211_sta_bss *b, *prev = NULL; |
| 2141 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; | 2219 | b = local->sta_bss_hash[STA_HASH(bss->bssid)]; |
| 2142 | while (b) { | 2220 | while (b) { |
| @@ -2281,45 +2359,42 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
| 2281 | kfree(bss->rsn_ie); | 2359 | kfree(bss->rsn_ie); |
| 2282 | kfree(bss->wmm_ie); | 2360 | kfree(bss->wmm_ie); |
| 2283 | kfree(bss->ht_ie); | 2361 | kfree(bss->ht_ie); |
| 2362 | kfree(bss->ht_add_ie); | ||
| 2284 | kfree(bss_mesh_id(bss)); | 2363 | kfree(bss_mesh_id(bss)); |
| 2285 | kfree(bss_mesh_cfg(bss)); | 2364 | kfree(bss_mesh_cfg(bss)); |
| 2286 | kfree(bss); | 2365 | kfree(bss); |
| 2287 | } | 2366 | } |
| 2288 | 2367 | ||
| 2289 | 2368 | ||
| 2290 | static void ieee80211_rx_bss_put(struct net_device *dev, | 2369 | static void ieee80211_rx_bss_put(struct ieee80211_local *local, |
| 2291 | struct ieee80211_sta_bss *bss) | 2370 | struct ieee80211_sta_bss *bss) |
| 2292 | { | 2371 | { |
| 2293 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 2294 | |||
| 2295 | local_bh_disable(); | 2372 | local_bh_disable(); |
| 2296 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { | 2373 | if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) { |
| 2297 | local_bh_enable(); | 2374 | local_bh_enable(); |
| 2298 | return; | 2375 | return; |
| 2299 | } | 2376 | } |
| 2300 | 2377 | ||
| 2301 | __ieee80211_rx_bss_hash_del(dev, bss); | 2378 | __ieee80211_rx_bss_hash_del(local, bss); |
| 2302 | list_del(&bss->list); | 2379 | list_del(&bss->list); |
| 2303 | spin_unlock_bh(&local->sta_bss_lock); | 2380 | spin_unlock_bh(&local->sta_bss_lock); |
| 2304 | ieee80211_rx_bss_free(bss); | 2381 | ieee80211_rx_bss_free(bss); |
| 2305 | } | 2382 | } |
| 2306 | 2383 | ||
| 2307 | 2384 | ||
| 2308 | void ieee80211_rx_bss_list_init(struct net_device *dev) | 2385 | void ieee80211_rx_bss_list_init(struct ieee80211_local *local) |
| 2309 | { | 2386 | { |
| 2310 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 2311 | spin_lock_init(&local->sta_bss_lock); | 2387 | spin_lock_init(&local->sta_bss_lock); |
| 2312 | INIT_LIST_HEAD(&local->sta_bss_list); | 2388 | INIT_LIST_HEAD(&local->sta_bss_list); |
| 2313 | } | 2389 | } |
| 2314 | 2390 | ||
| 2315 | 2391 | ||
| 2316 | void ieee80211_rx_bss_list_deinit(struct net_device *dev) | 2392 | void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local) |
| 2317 | { | 2393 | { |
| 2318 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 2319 | struct ieee80211_sta_bss *bss, *tmp; | 2394 | struct ieee80211_sta_bss *bss, *tmp; |
| 2320 | 2395 | ||
| 2321 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) | 2396 | list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list) |
| 2322 | ieee80211_rx_bss_put(dev, bss); | 2397 | ieee80211_rx_bss_put(local, bss); |
| 2323 | } | 2398 | } |
| 2324 | 2399 | ||
| 2325 | 2400 | ||
| @@ -2331,8 +2406,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
| 2331 | int res, rates, i, j; | 2406 | int res, rates, i, j; |
| 2332 | struct sk_buff *skb; | 2407 | struct sk_buff *skb; |
| 2333 | struct ieee80211_mgmt *mgmt; | 2408 | struct ieee80211_mgmt *mgmt; |
| 2334 | struct ieee80211_tx_control control; | ||
| 2335 | struct rate_selection ratesel; | ||
| 2336 | u8 *pos; | 2409 | u8 *pos; |
| 2337 | struct ieee80211_sub_if_data *sdata; | 2410 | struct ieee80211_sub_if_data *sdata; |
| 2338 | struct ieee80211_supported_band *sband; | 2411 | struct ieee80211_supported_band *sband; |
| @@ -2350,7 +2423,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
| 2350 | local->ops->reset_tsf(local_to_hw(local)); | 2423 | local->ops->reset_tsf(local_to_hw(local)); |
| 2351 | } | 2424 | } |
| 2352 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); | 2425 | memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); |
| 2353 | res = ieee80211_if_config(dev); | 2426 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); |
| 2354 | if (res) | 2427 | if (res) |
| 2355 | return res; | 2428 | return res; |
| 2356 | 2429 | ||
| @@ -2364,24 +2437,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
| 2364 | if (res) | 2437 | if (res) |
| 2365 | return res; | 2438 | return res; |
| 2366 | 2439 | ||
| 2367 | /* Set beacon template */ | 2440 | /* Build IBSS probe response */ |
| 2368 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 2441 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
| 2369 | do { | 2442 | if (skb) { |
| 2370 | if (!skb) | ||
| 2371 | break; | ||
| 2372 | |||
| 2373 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2443 | skb_reserve(skb, local->hw.extra_tx_headroom); |
| 2374 | 2444 | ||
| 2375 | mgmt = (struct ieee80211_mgmt *) | 2445 | mgmt = (struct ieee80211_mgmt *) |
| 2376 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 2446 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
| 2377 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 2447 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
| 2378 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 2448 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, |
| 2379 | IEEE80211_STYPE_BEACON); | 2449 | IEEE80211_STYPE_PROBE_RESP); |
| 2380 | memset(mgmt->da, 0xff, ETH_ALEN); | 2450 | memset(mgmt->da, 0xff, ETH_ALEN); |
| 2381 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | 2451 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); |
| 2382 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | 2452 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); |
| 2383 | mgmt->u.beacon.beacon_int = | 2453 | mgmt->u.beacon.beacon_int = |
| 2384 | cpu_to_le16(local->hw.conf.beacon_int); | 2454 | cpu_to_le16(local->hw.conf.beacon_int); |
| 2455 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
| 2385 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | 2456 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); |
| 2386 | 2457 | ||
| 2387 | pos = skb_put(skb, 2 + ifsta->ssid_len); | 2458 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
| @@ -2419,60 +2490,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
| 2419 | memcpy(pos, &bss->supp_rates[8], rates); | 2490 | memcpy(pos, &bss->supp_rates[8], rates); |
| 2420 | } | 2491 | } |
| 2421 | 2492 | ||
| 2422 | memset(&control, 0, sizeof(control)); | 2493 | ifsta->probe_resp = skb; |
| 2423 | rate_control_get_rate(dev, sband, skb, &ratesel); | ||
| 2424 | if (!ratesel.rate) { | ||
| 2425 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | ||
| 2426 | "for IBSS beacon\n", dev->name); | ||
| 2427 | break; | ||
| 2428 | } | ||
| 2429 | control.vif = &sdata->vif; | ||
| 2430 | control.tx_rate = ratesel.rate; | ||
| 2431 | if (sdata->bss_conf.use_short_preamble && | ||
| 2432 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
| 2433 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | ||
| 2434 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
| 2435 | control.flags |= IEEE80211_TXCTL_NO_ACK; | ||
| 2436 | control.retry_limit = 1; | ||
| 2437 | |||
| 2438 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | ||
| 2439 | if (ifsta->probe_resp) { | ||
| 2440 | mgmt = (struct ieee80211_mgmt *) | ||
| 2441 | ifsta->probe_resp->data; | ||
| 2442 | mgmt->frame_control = | ||
| 2443 | IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
| 2444 | IEEE80211_STYPE_PROBE_RESP); | ||
| 2445 | } else { | ||
| 2446 | printk(KERN_DEBUG "%s: Could not allocate ProbeResp " | ||
| 2447 | "template for IBSS\n", dev->name); | ||
| 2448 | } | ||
| 2449 | |||
| 2450 | if (local->ops->beacon_update && | ||
| 2451 | local->ops->beacon_update(local_to_hw(local), | ||
| 2452 | skb, &control) == 0) { | ||
| 2453 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | ||
| 2454 | "template\n", dev->name); | ||
| 2455 | skb = NULL; | ||
| 2456 | } | ||
| 2457 | |||
| 2458 | rates = 0; | ||
| 2459 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
| 2460 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
| 2461 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; | ||
| 2462 | for (j = 0; j < sband->n_bitrates; j++) | ||
| 2463 | if (sband->bitrates[j].bitrate == bitrate) | ||
| 2464 | rates |= BIT(j); | ||
| 2465 | } | ||
| 2466 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
| 2467 | 2494 | ||
| 2468 | ieee80211_sta_def_wmm_params(dev, bss, 1); | 2495 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
| 2469 | } while (0); | 2496 | } |
| 2470 | 2497 | ||
| 2471 | if (skb) { | 2498 | rates = 0; |
| 2472 | printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " | 2499 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
| 2473 | "template\n", dev->name); | 2500 | for (i = 0; i < bss->supp_rates_len; i++) { |
| 2474 | dev_kfree_skb(skb); | 2501 | int bitrate = (bss->supp_rates[i] & 0x7f) * 5; |
| 2502 | for (j = 0; j < sband->n_bitrates; j++) | ||
| 2503 | if (sband->bitrates[j].bitrate == bitrate) | ||
| 2504 | rates |= BIT(j); | ||
| 2475 | } | 2505 | } |
| 2506 | ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; | ||
| 2507 | |||
| 2508 | ieee80211_sta_def_wmm_params(dev, bss, 1); | ||
| 2476 | 2509 | ||
| 2477 | ifsta->state = IEEE80211_IBSS_JOINED; | 2510 | ifsta->state = IEEE80211_IBSS_JOINED; |
| 2478 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); | 2511 | mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); |
| @@ -2525,11 +2558,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2525 | struct ieee80211_mgmt *mgmt, | 2558 | struct ieee80211_mgmt *mgmt, |
| 2526 | size_t len, | 2559 | size_t len, |
| 2527 | struct ieee80211_rx_status *rx_status, | 2560 | struct ieee80211_rx_status *rx_status, |
| 2561 | struct ieee802_11_elems *elems, | ||
| 2528 | int beacon) | 2562 | int beacon) |
| 2529 | { | 2563 | { |
| 2530 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2564 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 2531 | struct ieee802_11_elems elems; | ||
| 2532 | size_t baselen; | ||
| 2533 | int freq, clen; | 2565 | int freq, clen; |
| 2534 | struct ieee80211_sta_bss *bss; | 2566 | struct ieee80211_sta_bss *bss; |
| 2535 | struct sta_info *sta; | 2567 | struct sta_info *sta; |
| @@ -2542,35 +2574,24 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2542 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) | 2574 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) |
| 2543 | return; /* ignore ProbeResp to foreign address */ | 2575 | return; /* ignore ProbeResp to foreign address */ |
| 2544 | 2576 | ||
| 2545 | #if 0 | ||
| 2546 | printk(KERN_DEBUG "%s: RX %s from %s to %s\n", | ||
| 2547 | dev->name, beacon ? "Beacon" : "Probe Response", | ||
| 2548 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); | ||
| 2549 | #endif | ||
| 2550 | |||
| 2551 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
| 2552 | if (baselen > len) | ||
| 2553 | return; | ||
| 2554 | |||
| 2555 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2577 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
| 2556 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
| 2557 | 2578 | ||
| 2558 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && | 2579 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && |
| 2559 | elems.mesh_config && mesh_matches_local(&elems, dev)) { | 2580 | elems->mesh_config && mesh_matches_local(elems, dev)) { |
| 2560 | u64 rates = ieee80211_sta_get_rates(local, &elems, | 2581 | u64 rates = ieee80211_sta_get_rates(local, elems, |
| 2561 | rx_status->band); | 2582 | rx_status->band); |
| 2562 | 2583 | ||
| 2563 | mesh_neighbour_update(mgmt->sa, rates, dev, | 2584 | mesh_neighbour_update(mgmt->sa, rates, dev, |
| 2564 | mesh_peer_accepts_plinks(&elems, dev)); | 2585 | mesh_peer_accepts_plinks(elems, dev)); |
| 2565 | } | 2586 | } |
| 2566 | 2587 | ||
| 2567 | rcu_read_lock(); | 2588 | rcu_read_lock(); |
| 2568 | 2589 | ||
| 2569 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2590 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && |
| 2570 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2591 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
| 2571 | (sta = sta_info_get(local, mgmt->sa))) { | 2592 | (sta = sta_info_get(local, mgmt->sa))) { |
| 2572 | u64 prev_rates; | 2593 | u64 prev_rates; |
| 2573 | u64 supp_rates = ieee80211_sta_get_rates(local, &elems, | 2594 | u64 supp_rates = ieee80211_sta_get_rates(local, elems, |
| 2574 | rx_status->band); | 2595 | rx_status->band); |
| 2575 | 2596 | ||
| 2576 | prev_rates = sta->supp_rates[rx_status->band]; | 2597 | prev_rates = sta->supp_rates[rx_status->band]; |
| @@ -2582,21 +2603,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2582 | sta->supp_rates[rx_status->band] = | 2603 | sta->supp_rates[rx_status->band] = |
| 2583 | sdata->u.sta.supp_rates_bits[rx_status->band]; | 2604 | sdata->u.sta.supp_rates_bits[rx_status->band]; |
| 2584 | } | 2605 | } |
| 2585 | if (sta->supp_rates[rx_status->band] != prev_rates) { | ||
| 2586 | printk(KERN_DEBUG "%s: updated supp_rates set for " | ||
| 2587 | "%s based on beacon info (0x%llx & 0x%llx -> " | ||
| 2588 | "0x%llx)\n", | ||
| 2589 | dev->name, print_mac(mac, sta->addr), | ||
| 2590 | (unsigned long long) prev_rates, | ||
| 2591 | (unsigned long long) supp_rates, | ||
| 2592 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
| 2593 | } | ||
| 2594 | } | 2606 | } |
| 2595 | 2607 | ||
| 2596 | rcu_read_unlock(); | 2608 | rcu_read_unlock(); |
| 2597 | 2609 | ||
| 2598 | if (elems.ds_params && elems.ds_params_len == 1) | 2610 | if (elems->ds_params && elems->ds_params_len == 1) |
| 2599 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | 2611 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
| 2600 | else | 2612 | else |
| 2601 | freq = rx_status->freq; | 2613 | freq = rx_status->freq; |
| 2602 | 2614 | ||
| @@ -2606,23 +2618,23 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2606 | return; | 2618 | return; |
| 2607 | 2619 | ||
| 2608 | #ifdef CONFIG_MAC80211_MESH | 2620 | #ifdef CONFIG_MAC80211_MESH |
| 2609 | if (elems.mesh_config) | 2621 | if (elems->mesh_config) |
| 2610 | bss = ieee80211_rx_mesh_bss_get(dev, elems.mesh_id, | 2622 | bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, |
| 2611 | elems.mesh_id_len, elems.mesh_config, freq); | 2623 | elems->mesh_id_len, elems->mesh_config, freq); |
| 2612 | else | 2624 | else |
| 2613 | #endif | 2625 | #endif |
| 2614 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, | 2626 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
| 2615 | elems.ssid, elems.ssid_len); | 2627 | elems->ssid, elems->ssid_len); |
| 2616 | if (!bss) { | 2628 | if (!bss) { |
| 2617 | #ifdef CONFIG_MAC80211_MESH | 2629 | #ifdef CONFIG_MAC80211_MESH |
| 2618 | if (elems.mesh_config) | 2630 | if (elems->mesh_config) |
| 2619 | bss = ieee80211_rx_mesh_bss_add(dev, elems.mesh_id, | 2631 | bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id, |
| 2620 | elems.mesh_id_len, elems.mesh_config, | 2632 | elems->mesh_id_len, elems->mesh_config, |
| 2621 | elems.mesh_config_len, freq); | 2633 | elems->mesh_config_len, freq); |
| 2622 | else | 2634 | else |
| 2623 | #endif | 2635 | #endif |
| 2624 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, | 2636 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
| 2625 | elems.ssid, elems.ssid_len); | 2637 | elems->ssid, elems->ssid_len); |
| 2626 | if (!bss) | 2638 | if (!bss) |
| 2627 | return; | 2639 | return; |
| 2628 | } else { | 2640 | } else { |
| @@ -2635,46 +2647,66 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2635 | } | 2647 | } |
| 2636 | 2648 | ||
| 2637 | /* save the ERP value so that it is available at association time */ | 2649 | /* save the ERP value so that it is available at association time */ |
| 2638 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2650 | if (elems->erp_info && elems->erp_info_len >= 1) { |
| 2639 | bss->erp_value = elems.erp_info[0]; | 2651 | bss->erp_value = elems->erp_info[0]; |
| 2640 | bss->has_erp_value = 1; | 2652 | bss->has_erp_value = 1; |
| 2641 | } | 2653 | } |
| 2642 | 2654 | ||
| 2643 | if (elems.ht_cap_elem && | 2655 | if (elems->ht_cap_elem && |
| 2644 | (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len || | 2656 | (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || |
| 2645 | memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) { | 2657 | memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { |
| 2646 | kfree(bss->ht_ie); | 2658 | kfree(bss->ht_ie); |
| 2647 | bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC); | 2659 | bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC); |
| 2648 | if (bss->ht_ie) { | 2660 | if (bss->ht_ie) { |
| 2649 | memcpy(bss->ht_ie, elems.ht_cap_elem - 2, | 2661 | memcpy(bss->ht_ie, elems->ht_cap_elem - 2, |
| 2650 | elems.ht_cap_elem_len + 2); | 2662 | elems->ht_cap_elem_len + 2); |
| 2651 | bss->ht_ie_len = elems.ht_cap_elem_len + 2; | 2663 | bss->ht_ie_len = elems->ht_cap_elem_len + 2; |
| 2652 | } else | 2664 | } else |
| 2653 | bss->ht_ie_len = 0; | 2665 | bss->ht_ie_len = 0; |
| 2654 | } else if (!elems.ht_cap_elem && bss->ht_ie) { | 2666 | } else if (!elems->ht_cap_elem && bss->ht_ie) { |
| 2655 | kfree(bss->ht_ie); | 2667 | kfree(bss->ht_ie); |
| 2656 | bss->ht_ie = NULL; | 2668 | bss->ht_ie = NULL; |
| 2657 | bss->ht_ie_len = 0; | 2669 | bss->ht_ie_len = 0; |
| 2658 | } | 2670 | } |
| 2659 | 2671 | ||
| 2672 | if (elems->ht_info_elem && | ||
| 2673 | (!bss->ht_add_ie || | ||
| 2674 | bss->ht_add_ie_len != elems->ht_info_elem_len || | ||
| 2675 | memcmp(bss->ht_add_ie, elems->ht_info_elem, | ||
| 2676 | elems->ht_info_elem_len))) { | ||
| 2677 | kfree(bss->ht_add_ie); | ||
| 2678 | bss->ht_add_ie = | ||
| 2679 | kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC); | ||
| 2680 | if (bss->ht_add_ie) { | ||
| 2681 | memcpy(bss->ht_add_ie, elems->ht_info_elem - 2, | ||
| 2682 | elems->ht_info_elem_len + 2); | ||
| 2683 | bss->ht_add_ie_len = elems->ht_info_elem_len + 2; | ||
| 2684 | } else | ||
| 2685 | bss->ht_add_ie_len = 0; | ||
| 2686 | } else if (!elems->ht_info_elem && bss->ht_add_ie) { | ||
| 2687 | kfree(bss->ht_add_ie); | ||
| 2688 | bss->ht_add_ie = NULL; | ||
| 2689 | bss->ht_add_ie_len = 0; | ||
| 2690 | } | ||
| 2691 | |||
| 2660 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | 2692 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); |
| 2661 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2693 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
| 2662 | 2694 | ||
| 2663 | bss->supp_rates_len = 0; | 2695 | bss->supp_rates_len = 0; |
| 2664 | if (elems.supp_rates) { | 2696 | if (elems->supp_rates) { |
| 2665 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2697 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
| 2666 | if (clen > elems.supp_rates_len) | 2698 | if (clen > elems->supp_rates_len) |
| 2667 | clen = elems.supp_rates_len; | 2699 | clen = elems->supp_rates_len; |
| 2668 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, | 2700 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, |
| 2669 | clen); | 2701 | clen); |
| 2670 | bss->supp_rates_len += clen; | 2702 | bss->supp_rates_len += clen; |
| 2671 | } | 2703 | } |
| 2672 | if (elems.ext_supp_rates) { | 2704 | if (elems->ext_supp_rates) { |
| 2673 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2705 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
| 2674 | if (clen > elems.ext_supp_rates_len) | 2706 | if (clen > elems->ext_supp_rates_len) |
| 2675 | clen = elems.ext_supp_rates_len; | 2707 | clen = elems->ext_supp_rates_len; |
| 2676 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 2708 | memcpy(&bss->supp_rates[bss->supp_rates_len], |
| 2677 | elems.ext_supp_rates, clen); | 2709 | elems->ext_supp_rates, clen); |
| 2678 | bss->supp_rates_len += clen; | 2710 | bss->supp_rates_len += clen; |
| 2679 | } | 2711 | } |
| 2680 | 2712 | ||
| @@ -2682,9 +2714,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2682 | 2714 | ||
| 2683 | bss->timestamp = beacon_timestamp; | 2715 | bss->timestamp = beacon_timestamp; |
| 2684 | bss->last_update = jiffies; | 2716 | bss->last_update = jiffies; |
| 2685 | bss->rssi = rx_status->ssi; | ||
| 2686 | bss->signal = rx_status->signal; | 2717 | bss->signal = rx_status->signal; |
| 2687 | bss->noise = rx_status->noise; | 2718 | bss->noise = rx_status->noise; |
| 2719 | bss->qual = rx_status->qual; | ||
| 2688 | if (!beacon && !bss->probe_resp) | 2720 | if (!beacon && !bss->probe_resp) |
| 2689 | bss->probe_resp = true; | 2721 | bss->probe_resp = true; |
| 2690 | 2722 | ||
| @@ -2694,37 +2726,37 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2694 | */ | 2726 | */ |
| 2695 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 2727 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
| 2696 | bss->probe_resp && beacon) { | 2728 | bss->probe_resp && beacon) { |
| 2697 | ieee80211_rx_bss_put(dev, bss); | 2729 | ieee80211_rx_bss_put(local, bss); |
| 2698 | return; | 2730 | return; |
| 2699 | } | 2731 | } |
| 2700 | 2732 | ||
| 2701 | if (elems.wpa && | 2733 | if (elems->wpa && |
| 2702 | (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || | 2734 | (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || |
| 2703 | memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { | 2735 | memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { |
| 2704 | kfree(bss->wpa_ie); | 2736 | kfree(bss->wpa_ie); |
| 2705 | bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); | 2737 | bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC); |
| 2706 | if (bss->wpa_ie) { | 2738 | if (bss->wpa_ie) { |
| 2707 | memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); | 2739 | memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2); |
| 2708 | bss->wpa_ie_len = elems.wpa_len + 2; | 2740 | bss->wpa_ie_len = elems->wpa_len + 2; |
| 2709 | } else | 2741 | } else |
| 2710 | bss->wpa_ie_len = 0; | 2742 | bss->wpa_ie_len = 0; |
| 2711 | } else if (!elems.wpa && bss->wpa_ie) { | 2743 | } else if (!elems->wpa && bss->wpa_ie) { |
| 2712 | kfree(bss->wpa_ie); | 2744 | kfree(bss->wpa_ie); |
| 2713 | bss->wpa_ie = NULL; | 2745 | bss->wpa_ie = NULL; |
| 2714 | bss->wpa_ie_len = 0; | 2746 | bss->wpa_ie_len = 0; |
| 2715 | } | 2747 | } |
| 2716 | 2748 | ||
| 2717 | if (elems.rsn && | 2749 | if (elems->rsn && |
| 2718 | (!bss->rsn_ie || bss->rsn_ie_len != elems.rsn_len || | 2750 | (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len || |
| 2719 | memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { | 2751 | memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) { |
| 2720 | kfree(bss->rsn_ie); | 2752 | kfree(bss->rsn_ie); |
| 2721 | bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); | 2753 | bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC); |
| 2722 | if (bss->rsn_ie) { | 2754 | if (bss->rsn_ie) { |
| 2723 | memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); | 2755 | memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2); |
| 2724 | bss->rsn_ie_len = elems.rsn_len + 2; | 2756 | bss->rsn_ie_len = elems->rsn_len + 2; |
| 2725 | } else | 2757 | } else |
| 2726 | bss->rsn_ie_len = 0; | 2758 | bss->rsn_ie_len = 0; |
| 2727 | } else if (!elems.rsn && bss->rsn_ie) { | 2759 | } else if (!elems->rsn && bss->rsn_ie) { |
| 2728 | kfree(bss->rsn_ie); | 2760 | kfree(bss->rsn_ie); |
| 2729 | bss->rsn_ie = NULL; | 2761 | bss->rsn_ie = NULL; |
| 2730 | bss->rsn_ie_len = 0; | 2762 | bss->rsn_ie_len = 0; |
| @@ -2744,20 +2776,21 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2744 | * inclusion of the WMM Parameters in beacons, however, is optional. | 2776 | * inclusion of the WMM Parameters in beacons, however, is optional. |
| 2745 | */ | 2777 | */ |
| 2746 | 2778 | ||
| 2747 | if (elems.wmm_param && | 2779 | if (elems->wmm_param && |
| 2748 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || | 2780 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len || |
| 2749 | memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { | 2781 | memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) { |
| 2750 | kfree(bss->wmm_ie); | 2782 | kfree(bss->wmm_ie); |
| 2751 | bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); | 2783 | bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC); |
| 2752 | if (bss->wmm_ie) { | 2784 | if (bss->wmm_ie) { |
| 2753 | memcpy(bss->wmm_ie, elems.wmm_param - 2, | 2785 | memcpy(bss->wmm_ie, elems->wmm_param - 2, |
| 2754 | elems.wmm_param_len + 2); | 2786 | elems->wmm_param_len + 2); |
| 2755 | bss->wmm_ie_len = elems.wmm_param_len + 2; | 2787 | bss->wmm_ie_len = elems->wmm_param_len + 2; |
| 2756 | } else | 2788 | } else |
| 2757 | bss->wmm_ie_len = 0; | 2789 | bss->wmm_ie_len = 0; |
| 2758 | } else if (elems.wmm_info && | 2790 | } else if (elems->wmm_info && |
| 2759 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || | 2791 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len || |
| 2760 | memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { | 2792 | memcmp(bss->wmm_ie, elems->wmm_info, |
| 2793 | elems->wmm_info_len))) { | ||
| 2761 | /* As for certain AP's Fifth bit is not set in WMM IE in | 2794 | /* As for certain AP's Fifth bit is not set in WMM IE in |
| 2762 | * beacon frames.So while parsing the beacon frame the | 2795 | * beacon frames.So while parsing the beacon frame the |
| 2763 | * wmm_info structure is used instead of wmm_param. | 2796 | * wmm_info structure is used instead of wmm_param. |
| @@ -2767,14 +2800,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2767 | * n-band association. | 2800 | * n-band association. |
| 2768 | */ | 2801 | */ |
| 2769 | kfree(bss->wmm_ie); | 2802 | kfree(bss->wmm_ie); |
| 2770 | bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); | 2803 | bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC); |
| 2771 | if (bss->wmm_ie) { | 2804 | if (bss->wmm_ie) { |
| 2772 | memcpy(bss->wmm_ie, elems.wmm_info - 2, | 2805 | memcpy(bss->wmm_ie, elems->wmm_info - 2, |
| 2773 | elems.wmm_info_len + 2); | 2806 | elems->wmm_info_len + 2); |
| 2774 | bss->wmm_ie_len = elems.wmm_info_len + 2; | 2807 | bss->wmm_ie_len = elems->wmm_info_len + 2; |
| 2775 | } else | 2808 | } else |
| 2776 | bss->wmm_ie_len = 0; | 2809 | bss->wmm_ie_len = 0; |
| 2777 | } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { | 2810 | } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) { |
| 2778 | kfree(bss->wmm_ie); | 2811 | kfree(bss->wmm_ie); |
| 2779 | bss->wmm_ie = NULL; | 2812 | bss->wmm_ie = NULL; |
| 2780 | bss->wmm_ie_len = 0; | 2813 | bss->wmm_ie_len = 0; |
| @@ -2785,8 +2818,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2785 | !local->sta_sw_scanning && !local->sta_hw_scanning && | 2818 | !local->sta_sw_scanning && !local->sta_hw_scanning && |
| 2786 | bss->capability & WLAN_CAPABILITY_IBSS && | 2819 | bss->capability & WLAN_CAPABILITY_IBSS && |
| 2787 | bss->freq == local->oper_channel->center_freq && | 2820 | bss->freq == local->oper_channel->center_freq && |
| 2788 | elems.ssid_len == sdata->u.sta.ssid_len && | 2821 | elems->ssid_len == sdata->u.sta.ssid_len && |
| 2789 | memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { | 2822 | memcmp(elems->ssid, sdata->u.sta.ssid, |
| 2823 | sdata->u.sta.ssid_len) == 0) { | ||
| 2790 | if (rx_status->flag & RX_FLAG_TSFT) { | 2824 | if (rx_status->flag & RX_FLAG_TSFT) { |
| 2791 | /* in order for correct IBSS merging we need mactime | 2825 | /* in order for correct IBSS merging we need mactime |
| 2792 | * | 2826 | * |
| @@ -2824,18 +2858,18 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
| 2824 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2858 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
| 2825 | if (beacon_timestamp > rx_timestamp) { | 2859 | if (beacon_timestamp > rx_timestamp) { |
| 2826 | #ifndef CONFIG_MAC80211_IBSS_DEBUG | 2860 | #ifndef CONFIG_MAC80211_IBSS_DEBUG |
| 2827 | if (net_ratelimit()) | 2861 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
| 2862 | "local TSF - IBSS merge with BSSID %s\n", | ||
| 2863 | dev->name, print_mac(mac, mgmt->bssid)); | ||
| 2828 | #endif | 2864 | #endif |
| 2829 | printk(KERN_DEBUG "%s: beacon TSF higher than " | ||
| 2830 | "local TSF - IBSS merge with BSSID %s\n", | ||
| 2831 | dev->name, print_mac(mac, mgmt->bssid)); | ||
| 2832 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | 2865 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); |
| 2833 | ieee80211_ibss_add_sta(dev, NULL, | 2866 | ieee80211_ibss_add_sta(dev, NULL, |
| 2834 | mgmt->bssid, mgmt->sa); | 2867 | mgmt->bssid, mgmt->sa, |
| 2868 | BIT(rx_status->rate_idx)); | ||
| 2835 | } | 2869 | } |
| 2836 | } | 2870 | } |
| 2837 | 2871 | ||
| 2838 | ieee80211_rx_bss_put(dev, bss); | 2872 | ieee80211_rx_bss_put(local, bss); |
| 2839 | } | 2873 | } |
| 2840 | 2874 | ||
| 2841 | 2875 | ||
| @@ -2844,7 +2878,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, | |||
| 2844 | size_t len, | 2878 | size_t len, |
| 2845 | struct ieee80211_rx_status *rx_status) | 2879 | struct ieee80211_rx_status *rx_status) |
| 2846 | { | 2880 | { |
| 2847 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); | 2881 | size_t baselen; |
| 2882 | struct ieee802_11_elems elems; | ||
| 2883 | |||
| 2884 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | ||
| 2885 | if (baselen > len) | ||
| 2886 | return; | ||
| 2887 | |||
| 2888 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | ||
| 2889 | &elems); | ||
| 2890 | |||
| 2891 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); | ||
| 2848 | } | 2892 | } |
| 2849 | 2893 | ||
| 2850 | 2894 | ||
| @@ -2861,7 +2905,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
| 2861 | struct ieee80211_conf *conf = &local->hw.conf; | 2905 | struct ieee80211_conf *conf = &local->hw.conf; |
| 2862 | u32 changed = 0; | 2906 | u32 changed = 0; |
| 2863 | 2907 | ||
| 2864 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); | 2908 | /* Process beacon from the current BSS */ |
| 2909 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
| 2910 | if (baselen > len) | ||
| 2911 | return; | ||
| 2912 | |||
| 2913 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
| 2914 | |||
| 2915 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); | ||
| 2865 | 2916 | ||
| 2866 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2917 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 2867 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 2918 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
| @@ -2872,17 +2923,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
| 2872 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) | 2923 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
| 2873 | return; | 2924 | return; |
| 2874 | 2925 | ||
| 2875 | /* Process beacon from the current BSS */ | 2926 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
| 2876 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 2927 | elems.wmm_param_len); |
| 2877 | if (baselen > len) | ||
| 2878 | return; | ||
| 2879 | |||
| 2880 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
| 2881 | |||
| 2882 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
| 2883 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | ||
| 2884 | elems.wmm_param_len); | ||
| 2885 | } | ||
| 2886 | 2928 | ||
| 2887 | /* Do not send changes to driver if we are scanning. This removes | 2929 | /* Do not send changes to driver if we are scanning. This removes |
| 2888 | * requirement that driver's bss_info_changed function needs to be | 2930 | * requirement that driver's bss_info_changed function needs to be |
| @@ -2959,11 +3001,11 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, | |||
| 2959 | pos = mgmt->u.probe_req.variable; | 3001 | pos = mgmt->u.probe_req.variable; |
| 2960 | if (pos[0] != WLAN_EID_SSID || | 3002 | if (pos[0] != WLAN_EID_SSID || |
| 2961 | pos + 2 + pos[1] > end) { | 3003 | pos + 2 + pos[1] > end) { |
| 2962 | if (net_ratelimit()) { | 3004 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 2963 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 3005 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
| 2964 | "from %s\n", | 3006 | "from %s\n", |
| 2965 | dev->name, print_mac(mac, mgmt->sa)); | 3007 | dev->name, print_mac(mac, mgmt->sa)); |
| 2966 | } | 3008 | #endif |
| 2967 | return; | 3009 | return; |
| 2968 | } | 3010 | } |
| 2969 | if (pos[1] != 0 && | 3011 | if (pos[1] != 0 && |
| @@ -2994,11 +3036,24 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
| 2994 | struct ieee80211_rx_status *rx_status) | 3036 | struct ieee80211_rx_status *rx_status) |
| 2995 | { | 3037 | { |
| 2996 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3038 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 3039 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 2997 | 3040 | ||
| 2998 | if (len < IEEE80211_MIN_ACTION_SIZE) | 3041 | if (len < IEEE80211_MIN_ACTION_SIZE) |
| 2999 | return; | 3042 | return; |
| 3000 | 3043 | ||
| 3001 | switch (mgmt->u.action.category) { | 3044 | switch (mgmt->u.action.category) { |
| 3045 | case WLAN_CATEGORY_SPECTRUM_MGMT: | ||
| 3046 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) | ||
| 3047 | break; | ||
| 3048 | switch (mgmt->u.action.u.chan_switch.action_code) { | ||
| 3049 | case WLAN_ACTION_SPCT_MSR_REQ: | ||
| 3050 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
| 3051 | sizeof(mgmt->u.action.u.measurement))) | ||
| 3052 | break; | ||
| 3053 | ieee80211_sta_process_measurement_req(dev, mgmt, len); | ||
| 3054 | break; | ||
| 3055 | } | ||
| 3056 | break; | ||
| 3002 | case WLAN_CATEGORY_BACK: | 3057 | case WLAN_CATEGORY_BACK: |
| 3003 | switch (mgmt->u.action.u.addba_req.action_code) { | 3058 | switch (mgmt->u.action.u.addba_req.action_code) { |
| 3004 | case WLAN_ACTION_ADDBA_REQ: | 3059 | case WLAN_ACTION_ADDBA_REQ: |
| @@ -3019,11 +3074,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
| 3019 | break; | 3074 | break; |
| 3020 | ieee80211_sta_process_delba(dev, mgmt, len); | 3075 | ieee80211_sta_process_delba(dev, mgmt, len); |
| 3021 | break; | 3076 | break; |
| 3022 | default: | ||
| 3023 | if (net_ratelimit()) | ||
| 3024 | printk(KERN_DEBUG "%s: Rx unknown A-MPDU action\n", | ||
| 3025 | dev->name); | ||
| 3026 | break; | ||
| 3027 | } | 3077 | } |
| 3028 | break; | 3078 | break; |
| 3029 | case PLINK_CATEGORY: | 3079 | case PLINK_CATEGORY: |
| @@ -3034,11 +3084,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
| 3034 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 3084 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
| 3035 | mesh_rx_path_sel_frame(dev, mgmt, len); | 3085 | mesh_rx_path_sel_frame(dev, mgmt, len); |
| 3036 | break; | 3086 | break; |
| 3037 | default: | ||
| 3038 | if (net_ratelimit()) | ||
| 3039 | printk(KERN_DEBUG "%s: Rx unknown action frame - " | ||
| 3040 | "category=%d\n", dev->name, mgmt->u.action.category); | ||
| 3041 | break; | ||
| 3042 | } | 3087 | } |
| 3043 | } | 3088 | } |
| 3044 | 3089 | ||
| @@ -3074,11 +3119,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, | |||
| 3074 | skb_queue_tail(&ifsta->skb_queue, skb); | 3119 | skb_queue_tail(&ifsta->skb_queue, skb); |
| 3075 | queue_work(local->hw.workqueue, &ifsta->work); | 3120 | queue_work(local->hw.workqueue, &ifsta->work); |
| 3076 | return; | 3121 | return; |
| 3077 | default: | ||
| 3078 | printk(KERN_DEBUG "%s: received unknown management frame - " | ||
| 3079 | "stype=%d\n", dev->name, | ||
| 3080 | (fc & IEEE80211_FCTL_STYPE) >> 4); | ||
| 3081 | break; | ||
| 3082 | } | 3122 | } |
| 3083 | 3123 | ||
| 3084 | fail: | 3124 | fail: |
| @@ -3142,33 +3182,32 @@ ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, | |||
| 3142 | struct ieee80211_rx_status *rx_status) | 3182 | struct ieee80211_rx_status *rx_status) |
| 3143 | { | 3183 | { |
| 3144 | struct ieee80211_mgmt *mgmt; | 3184 | struct ieee80211_mgmt *mgmt; |
| 3145 | u16 fc; | 3185 | __le16 fc; |
| 3146 | 3186 | ||
| 3147 | if (skb->len < 2) | 3187 | if (skb->len < 2) |
| 3148 | return RX_DROP_UNUSABLE; | 3188 | return RX_DROP_UNUSABLE; |
| 3149 | 3189 | ||
| 3150 | mgmt = (struct ieee80211_mgmt *) skb->data; | 3190 | mgmt = (struct ieee80211_mgmt *) skb->data; |
| 3151 | fc = le16_to_cpu(mgmt->frame_control); | 3191 | fc = mgmt->frame_control; |
| 3152 | 3192 | ||
| 3153 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) | 3193 | if (ieee80211_is_ctl(fc)) |
| 3154 | return RX_CONTINUE; | 3194 | return RX_CONTINUE; |
| 3155 | 3195 | ||
| 3156 | if (skb->len < 24) | 3196 | if (skb->len < 24) |
| 3157 | return RX_DROP_MONITOR; | 3197 | return RX_DROP_MONITOR; |
| 3158 | 3198 | ||
| 3159 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 3199 | if (ieee80211_is_probe_resp(fc)) { |
| 3160 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { | 3200 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); |
| 3161 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, | 3201 | dev_kfree_skb(skb); |
| 3162 | skb->len, rx_status); | 3202 | return RX_QUEUED; |
| 3163 | dev_kfree_skb(skb); | 3203 | } |
| 3164 | return RX_QUEUED; | 3204 | |
| 3165 | } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { | 3205 | if (ieee80211_is_beacon(fc)) { |
| 3166 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, | 3206 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); |
| 3167 | rx_status); | 3207 | dev_kfree_skb(skb); |
| 3168 | dev_kfree_skb(skb); | 3208 | return RX_QUEUED; |
| 3169 | return RX_QUEUED; | ||
| 3170 | } | ||
| 3171 | } | 3209 | } |
| 3210 | |||
| 3172 | return RX_CONTINUE; | 3211 | return RX_CONTINUE; |
| 3173 | } | 3212 | } |
| 3174 | 3213 | ||
| @@ -3208,8 +3247,10 @@ static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time) | |||
| 3208 | spin_lock_irqsave(&local->sta_lock, flags); | 3247 | spin_lock_irqsave(&local->sta_lock, flags); |
| 3209 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) | 3248 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) |
| 3210 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 3249 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
| 3250 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
| 3211 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", | 3251 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", |
| 3212 | dev->name, print_mac(mac, sta->addr)); | 3252 | dev->name, print_mac(mac, sta->addr)); |
| 3253 | #endif | ||
| 3213 | __sta_info_unlink(&sta); | 3254 | __sta_info_unlink(&sta); |
| 3214 | if (sta) | 3255 | if (sta) |
| 3215 | list_add(&sta->list, &tmp_list); | 3256 | list_add(&sta->list, &tmp_list); |
| @@ -3248,7 +3289,7 @@ static void ieee80211_mesh_housekeeping(struct net_device *dev, | |||
| 3248 | 3289 | ||
| 3249 | free_plinks = mesh_plink_availables(sdata); | 3290 | free_plinks = mesh_plink_availables(sdata); |
| 3250 | if (free_plinks != sdata->u.sta.accepting_plinks) | 3291 | if (free_plinks != sdata->u.sta.accepting_plinks) |
| 3251 | ieee80211_if_config_beacon(dev); | 3292 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); |
| 3252 | 3293 | ||
| 3253 | mod_timer(&ifsta->timer, jiffies + | 3294 | mod_timer(&ifsta->timer, jiffies + |
| 3254 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); | 3295 | IEEE80211_MESH_HOUSEKEEPING_INTERVAL); |
| @@ -3292,13 +3333,10 @@ void ieee80211_sta_work(struct work_struct *work) | |||
| 3292 | if (local->sta_sw_scanning || local->sta_hw_scanning) | 3333 | if (local->sta_sw_scanning || local->sta_hw_scanning) |
| 3293 | return; | 3334 | return; |
| 3294 | 3335 | ||
| 3295 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 3336 | if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA && |
| 3296 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 3337 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
| 3297 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) { | 3338 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
| 3298 | printk(KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " | ||
| 3299 | "(type=%d)\n", dev->name, sdata->vif.type); | ||
| 3300 | return; | 3339 | return; |
| 3301 | } | ||
| 3302 | ifsta = &sdata->u.sta; | 3340 | ifsta = &sdata->u.sta; |
| 3303 | 3341 | ||
| 3304 | while ((skb = skb_dequeue(&ifsta->skb_queue))) | 3342 | while ((skb = skb_dequeue(&ifsta->skb_queue))) |
| @@ -3352,8 +3390,7 @@ void ieee80211_sta_work(struct work_struct *work) | |||
| 3352 | break; | 3390 | break; |
| 3353 | #endif | 3391 | #endif |
| 3354 | default: | 3392 | default: |
| 3355 | printk(KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n", | 3393 | WARN_ON(1); |
| 3356 | ifsta->state); | ||
| 3357 | break; | 3394 | break; |
| 3358 | } | 3395 | } |
| 3359 | 3396 | ||
| @@ -3388,8 +3425,6 @@ static void ieee80211_sta_reset_auth(struct net_device *dev, | |||
| 3388 | ifsta->auth_alg = WLAN_AUTH_LEAP; | 3425 | ifsta->auth_alg = WLAN_AUTH_LEAP; |
| 3389 | else | 3426 | else |
| 3390 | ifsta->auth_alg = WLAN_AUTH_OPEN; | 3427 | ifsta->auth_alg = WLAN_AUTH_OPEN; |
| 3391 | printk(KERN_DEBUG "%s: Initial auth_alg=%d\n", dev->name, | ||
| 3392 | ifsta->auth_alg); | ||
| 3393 | ifsta->auth_transaction = -1; | 3428 | ifsta->auth_transaction = -1; |
| 3394 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 3429 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
| 3395 | ifsta->auth_tries = ifsta->assoc_tries = 0; | 3430 | ifsta->auth_tries = ifsta->assoc_tries = 0; |
| @@ -3478,9 +3513,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
| 3478 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) | 3513 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) |
| 3479 | continue; | 3514 | continue; |
| 3480 | 3515 | ||
| 3481 | if (!selected || top_rssi < bss->rssi) { | 3516 | if (!selected || top_rssi < bss->signal) { |
| 3482 | selected = bss; | 3517 | selected = bss; |
| 3483 | top_rssi = bss->rssi; | 3518 | top_rssi = bss->signal; |
| 3484 | } | 3519 | } |
| 3485 | } | 3520 | } |
| 3486 | if (selected) | 3521 | if (selected) |
| @@ -3494,7 +3529,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
| 3494 | selected->ssid_len); | 3529 | selected->ssid_len); |
| 3495 | ieee80211_sta_set_bssid(dev, selected->bssid); | 3530 | ieee80211_sta_set_bssid(dev, selected->bssid); |
| 3496 | ieee80211_sta_def_wmm_params(dev, selected, 0); | 3531 | ieee80211_sta_def_wmm_params(dev, selected, 0); |
| 3497 | ieee80211_rx_bss_put(dev, selected); | 3532 | ieee80211_rx_bss_put(local, selected); |
| 3498 | ifsta->state = IEEE80211_AUTHENTICATE; | 3533 | ifsta->state = IEEE80211_AUTHENTICATE; |
| 3499 | ieee80211_sta_reset_auth(dev, ifsta); | 3534 | ieee80211_sta_reset_auth(dev, ifsta); |
| 3500 | return 0; | 3535 | return 0; |
| @@ -3553,14 +3588,16 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
| 3553 | sband = local->hw.wiphy->bands[bss->band]; | 3588 | sband = local->hw.wiphy->bands[bss->band]; |
| 3554 | 3589 | ||
| 3555 | if (local->hw.conf.beacon_int == 0) | 3590 | if (local->hw.conf.beacon_int == 0) |
| 3556 | local->hw.conf.beacon_int = 10000; | 3591 | local->hw.conf.beacon_int = 100; |
| 3557 | bss->beacon_int = local->hw.conf.beacon_int; | 3592 | bss->beacon_int = local->hw.conf.beacon_int; |
| 3558 | bss->last_update = jiffies; | 3593 | bss->last_update = jiffies; |
| 3559 | bss->capability = WLAN_CAPABILITY_IBSS; | 3594 | bss->capability = WLAN_CAPABILITY_IBSS; |
| 3560 | if (sdata->default_key) { | 3595 | |
| 3596 | if (sdata->default_key) | ||
| 3561 | bss->capability |= WLAN_CAPABILITY_PRIVACY; | 3597 | bss->capability |= WLAN_CAPABILITY_PRIVACY; |
| 3562 | } else | 3598 | else |
| 3563 | sdata->drop_unencrypted = 0; | 3599 | sdata->drop_unencrypted = 0; |
| 3600 | |||
| 3564 | bss->supp_rates_len = sband->n_bitrates; | 3601 | bss->supp_rates_len = sband->n_bitrates; |
| 3565 | pos = bss->supp_rates; | 3602 | pos = bss->supp_rates; |
| 3566 | for (i = 0; i < sband->n_bitrates; i++) { | 3603 | for (i = 0; i < sband->n_bitrates; i++) { |
| @@ -3569,7 +3606,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
| 3569 | } | 3606 | } |
| 3570 | 3607 | ||
| 3571 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3608 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
| 3572 | ieee80211_rx_bss_put(dev, bss); | 3609 | ieee80211_rx_bss_put(local, bss); |
| 3573 | return ret; | 3610 | return ret; |
| 3574 | } | 3611 | } |
| 3575 | 3612 | ||
| @@ -3611,8 +3648,10 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
| 3611 | spin_unlock_bh(&local->sta_bss_lock); | 3648 | spin_unlock_bh(&local->sta_bss_lock); |
| 3612 | 3649 | ||
| 3613 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3650 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| 3614 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 3651 | if (found) |
| 3615 | "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); | 3652 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " |
| 3653 | "%s\n", print_mac(mac, bssid), | ||
| 3654 | print_mac(mac2, ifsta->bssid)); | ||
| 3616 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 3655 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
| 3617 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && | 3656 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && |
| 3618 | (bss = ieee80211_rx_bss_get(dev, bssid, | 3657 | (bss = ieee80211_rx_bss_get(dev, bssid, |
| @@ -3623,7 +3662,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, | |||
| 3623 | " based on configured SSID\n", | 3662 | " based on configured SSID\n", |
| 3624 | dev->name, print_mac(mac, bssid)); | 3663 | dev->name, print_mac(mac, bssid)); |
| 3625 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); | 3664 | ret = ieee80211_sta_join_ibss(dev, ifsta, bss); |
| 3626 | ieee80211_rx_bss_put(dev, bss); | 3665 | ieee80211_rx_bss_put(local, bss); |
| 3627 | return ret; | 3666 | return ret; |
| 3628 | } | 3667 | } |
| 3629 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 3668 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
| @@ -3674,28 +3713,45 @@ int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) | |||
| 3674 | { | 3713 | { |
| 3675 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3714 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 3676 | struct ieee80211_if_sta *ifsta; | 3715 | struct ieee80211_if_sta *ifsta; |
| 3716 | int res; | ||
| 3677 | 3717 | ||
| 3678 | if (len > IEEE80211_MAX_SSID_LEN) | 3718 | if (len > IEEE80211_MAX_SSID_LEN) |
| 3679 | return -EINVAL; | 3719 | return -EINVAL; |
| 3680 | 3720 | ||
| 3681 | ifsta = &sdata->u.sta; | 3721 | ifsta = &sdata->u.sta; |
| 3682 | 3722 | ||
| 3683 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) | 3723 | if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) { |
| 3724 | memset(ifsta->ssid, 0, sizeof(ifsta->ssid)); | ||
| 3725 | memcpy(ifsta->ssid, ssid, len); | ||
| 3726 | ifsta->ssid_len = len; | ||
| 3684 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 3727 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
| 3685 | memcpy(ifsta->ssid, ssid, len); | 3728 | |
| 3686 | memset(ifsta->ssid + len, 0, IEEE80211_MAX_SSID_LEN - len); | 3729 | res = 0; |
| 3687 | ifsta->ssid_len = len; | 3730 | /* |
| 3731 | * Hack! MLME code needs to be cleaned up to have different | ||
| 3732 | * entry points for configuration and internal selection change | ||
| 3733 | */ | ||
| 3734 | if (netif_running(sdata->dev)) | ||
| 3735 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
| 3736 | if (res) { | ||
| 3737 | printk(KERN_DEBUG "%s: Failed to config new SSID to " | ||
| 3738 | "the low-level driver\n", dev->name); | ||
| 3739 | return res; | ||
| 3740 | } | ||
| 3741 | } | ||
| 3688 | 3742 | ||
| 3689 | if (len) | 3743 | if (len) |
| 3690 | ifsta->flags |= IEEE80211_STA_SSID_SET; | 3744 | ifsta->flags |= IEEE80211_STA_SSID_SET; |
| 3691 | else | 3745 | else |
| 3692 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; | 3746 | ifsta->flags &= ~IEEE80211_STA_SSID_SET; |
| 3747 | |||
| 3693 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && | 3748 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && |
| 3694 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { | 3749 | !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { |
| 3695 | ifsta->ibss_join_req = jiffies; | 3750 | ifsta->ibss_join_req = jiffies; |
| 3696 | ifsta->state = IEEE80211_IBSS_SEARCH; | 3751 | ifsta->state = IEEE80211_IBSS_SEARCH; |
| 3697 | return ieee80211_sta_find_ibss(dev, ifsta); | 3752 | return ieee80211_sta_find_ibss(dev, ifsta); |
| 3698 | } | 3753 | } |
| 3754 | |||
| 3699 | return 0; | 3755 | return 0; |
| 3700 | } | 3756 | } |
| 3701 | 3757 | ||
| @@ -3721,7 +3777,12 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) | |||
| 3721 | 3777 | ||
| 3722 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 3778 | if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
| 3723 | memcpy(ifsta->bssid, bssid, ETH_ALEN); | 3779 | memcpy(ifsta->bssid, bssid, ETH_ALEN); |
| 3724 | res = ieee80211_if_config(dev); | 3780 | res = 0; |
| 3781 | /* | ||
| 3782 | * Hack! See also ieee80211_sta_set_ssid. | ||
| 3783 | */ | ||
| 3784 | if (netif_running(sdata->dev)) | ||
| 3785 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID); | ||
| 3725 | if (res) { | 3786 | if (res) { |
| 3726 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " | 3787 | printk(KERN_DEBUG "%s: Failed to config new BSSID to " |
| 3727 | "the low-level driver\n", dev->name); | 3788 | "the low-level driver\n", dev->name); |
| @@ -3744,7 +3805,7 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
| 3744 | { | 3805 | { |
| 3745 | struct sk_buff *skb; | 3806 | struct sk_buff *skb; |
| 3746 | struct ieee80211_hdr *nullfunc; | 3807 | struct ieee80211_hdr *nullfunc; |
| 3747 | u16 fc; | 3808 | __le16 fc; |
| 3748 | 3809 | ||
| 3749 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); | 3810 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); |
| 3750 | if (!skb) { | 3811 | if (!skb) { |
| @@ -3756,11 +3817,11 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
| 3756 | 3817 | ||
| 3757 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); | 3818 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); |
| 3758 | memset(nullfunc, 0, 24); | 3819 | memset(nullfunc, 0, 24); |
| 3759 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | | 3820 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | |
| 3760 | IEEE80211_FCTL_TODS; | 3821 | IEEE80211_FCTL_TODS); |
| 3761 | if (powersave) | 3822 | if (powersave) |
| 3762 | fc |= IEEE80211_FCTL_PM; | 3823 | fc |= cpu_to_le16(IEEE80211_FCTL_PM); |
| 3763 | nullfunc->frame_control = cpu_to_le16(fc); | 3824 | nullfunc->frame_control = fc; |
| 3764 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); | 3825 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); |
| 3765 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); | 3826 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); |
| 3766 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); | 3827 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); |
| @@ -3808,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
| 3808 | 3869 | ||
| 3809 | 3870 | ||
| 3810 | netif_tx_lock_bh(local->mdev); | 3871 | netif_tx_lock_bh(local->mdev); |
| 3872 | netif_addr_lock(local->mdev); | ||
| 3811 | local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; | 3873 | local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; |
| 3812 | local->ops->configure_filter(local_to_hw(local), | 3874 | local->ops->configure_filter(local_to_hw(local), |
| 3813 | FIF_BCN_PRBRESP_PROMISC, | 3875 | FIF_BCN_PRBRESP_PROMISC, |
| @@ -3815,15 +3877,11 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw) | |||
| 3815 | local->mdev->mc_count, | 3877 | local->mdev->mc_count, |
| 3816 | local->mdev->mc_list); | 3878 | local->mdev->mc_list); |
| 3817 | 3879 | ||
| 3880 | netif_addr_unlock(local->mdev); | ||
| 3818 | netif_tx_unlock_bh(local->mdev); | 3881 | netif_tx_unlock_bh(local->mdev); |
| 3819 | 3882 | ||
| 3820 | rcu_read_lock(); | 3883 | rcu_read_lock(); |
| 3821 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 3884 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
| 3822 | |||
| 3823 | /* No need to wake the master device. */ | ||
| 3824 | if (sdata->dev == local->mdev) | ||
| 3825 | continue; | ||
| 3826 | |||
| 3827 | /* Tell AP we're back */ | 3885 | /* Tell AP we're back */ |
| 3828 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 3886 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
| 3829 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) | 3887 | sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) |
| @@ -3989,12 +4047,6 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
| 3989 | 4047 | ||
| 3990 | rcu_read_lock(); | 4048 | rcu_read_lock(); |
| 3991 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4049 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
| 3992 | |||
| 3993 | /* Don't stop the master interface, otherwise we can't transmit | ||
| 3994 | * probes! */ | ||
| 3995 | if (sdata->dev == local->mdev) | ||
| 3996 | continue; | ||
| 3997 | |||
| 3998 | netif_stop_queue(sdata->dev); | 4050 | netif_stop_queue(sdata->dev); |
| 3999 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && | 4051 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA && |
| 4000 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) | 4052 | (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) |
| @@ -4012,14 +4064,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
| 4012 | local->scan_band = IEEE80211_BAND_2GHZ; | 4064 | local->scan_band = IEEE80211_BAND_2GHZ; |
| 4013 | local->scan_dev = dev; | 4065 | local->scan_dev = dev; |
| 4014 | 4066 | ||
| 4015 | netif_tx_lock_bh(local->mdev); | 4067 | netif_addr_lock_bh(local->mdev); |
| 4016 | local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; | 4068 | local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; |
| 4017 | local->ops->configure_filter(local_to_hw(local), | 4069 | local->ops->configure_filter(local_to_hw(local), |
| 4018 | FIF_BCN_PRBRESP_PROMISC, | 4070 | FIF_BCN_PRBRESP_PROMISC, |
| 4019 | &local->filter_flags, | 4071 | &local->filter_flags, |
| 4020 | local->mdev->mc_count, | 4072 | local->mdev->mc_count, |
| 4021 | local->mdev->mc_list); | 4073 | local->mdev->mc_list); |
| 4022 | netif_tx_unlock_bh(local->mdev); | 4074 | netif_addr_unlock_bh(local->mdev); |
| 4023 | 4075 | ||
| 4024 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ | 4076 | /* TODO: start scan as soon as all nullfunc frames are ACKed */ |
| 4025 | queue_delayed_work(local->hw.workqueue, &local->scan_work, | 4077 | queue_delayed_work(local->hw.workqueue, &local->scan_work, |
| @@ -4054,6 +4106,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) | |||
| 4054 | 4106 | ||
| 4055 | static char * | 4107 | static char * |
| 4056 | ieee80211_sta_scan_result(struct net_device *dev, | 4108 | ieee80211_sta_scan_result(struct net_device *dev, |
| 4109 | struct iw_request_info *info, | ||
| 4057 | struct ieee80211_sta_bss *bss, | 4110 | struct ieee80211_sta_bss *bss, |
| 4058 | char *current_ev, char *end_buf) | 4111 | char *current_ev, char *end_buf) |
| 4059 | { | 4112 | { |
| @@ -4068,7 +4121,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4068 | iwe.cmd = SIOCGIWAP; | 4121 | iwe.cmd = SIOCGIWAP; |
| 4069 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 4122 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
| 4070 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); | 4123 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); |
| 4071 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4124 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
| 4072 | IW_EV_ADDR_LEN); | 4125 | IW_EV_ADDR_LEN); |
| 4073 | 4126 | ||
| 4074 | memset(&iwe, 0, sizeof(iwe)); | 4127 | memset(&iwe, 0, sizeof(iwe)); |
| @@ -4076,13 +4129,13 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4076 | if (bss_mesh_cfg(bss)) { | 4129 | if (bss_mesh_cfg(bss)) { |
| 4077 | iwe.u.data.length = bss_mesh_id_len(bss); | 4130 | iwe.u.data.length = bss_mesh_id_len(bss); |
| 4078 | iwe.u.data.flags = 1; | 4131 | iwe.u.data.flags = 1; |
| 4079 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4132 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
| 4080 | bss_mesh_id(bss)); | 4133 | &iwe, bss_mesh_id(bss)); |
| 4081 | } else { | 4134 | } else { |
| 4082 | iwe.u.data.length = bss->ssid_len; | 4135 | iwe.u.data.length = bss->ssid_len; |
| 4083 | iwe.u.data.flags = 1; | 4136 | iwe.u.data.flags = 1; |
| 4084 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4137 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
| 4085 | bss->ssid); | 4138 | &iwe, bss->ssid); |
| 4086 | } | 4139 | } |
| 4087 | 4140 | ||
| 4088 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) | 4141 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) |
| @@ -4095,30 +4148,30 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4095 | iwe.u.mode = IW_MODE_MASTER; | 4148 | iwe.u.mode = IW_MODE_MASTER; |
| 4096 | else | 4149 | else |
| 4097 | iwe.u.mode = IW_MODE_ADHOC; | 4150 | iwe.u.mode = IW_MODE_ADHOC; |
| 4098 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4151 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
| 4099 | IW_EV_UINT_LEN); | 4152 | &iwe, IW_EV_UINT_LEN); |
| 4100 | } | 4153 | } |
| 4101 | 4154 | ||
| 4102 | memset(&iwe, 0, sizeof(iwe)); | 4155 | memset(&iwe, 0, sizeof(iwe)); |
| 4103 | iwe.cmd = SIOCGIWFREQ; | 4156 | iwe.cmd = SIOCGIWFREQ; |
| 4104 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | 4157 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); |
| 4105 | iwe.u.freq.e = 0; | 4158 | iwe.u.freq.e = 0; |
| 4106 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4159 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
| 4107 | IW_EV_FREQ_LEN); | 4160 | IW_EV_FREQ_LEN); |
| 4108 | 4161 | ||
| 4109 | memset(&iwe, 0, sizeof(iwe)); | 4162 | memset(&iwe, 0, sizeof(iwe)); |
| 4110 | iwe.cmd = SIOCGIWFREQ; | 4163 | iwe.cmd = SIOCGIWFREQ; |
| 4111 | iwe.u.freq.m = bss->freq; | 4164 | iwe.u.freq.m = bss->freq; |
| 4112 | iwe.u.freq.e = 6; | 4165 | iwe.u.freq.e = 6; |
| 4113 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4166 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
| 4114 | IW_EV_FREQ_LEN); | 4167 | IW_EV_FREQ_LEN); |
| 4115 | memset(&iwe, 0, sizeof(iwe)); | 4168 | memset(&iwe, 0, sizeof(iwe)); |
| 4116 | iwe.cmd = IWEVQUAL; | 4169 | iwe.cmd = IWEVQUAL; |
| 4117 | iwe.u.qual.qual = bss->signal; | 4170 | iwe.u.qual.qual = bss->qual; |
| 4118 | iwe.u.qual.level = bss->rssi; | 4171 | iwe.u.qual.level = bss->signal; |
| 4119 | iwe.u.qual.noise = bss->noise; | 4172 | iwe.u.qual.noise = bss->noise; |
| 4120 | iwe.u.qual.updated = local->wstats_flags; | 4173 | iwe.u.qual.updated = local->wstats_flags; |
| 4121 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4174 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
| 4122 | IW_EV_QUAL_LEN); | 4175 | IW_EV_QUAL_LEN); |
| 4123 | 4176 | ||
| 4124 | memset(&iwe, 0, sizeof(iwe)); | 4177 | memset(&iwe, 0, sizeof(iwe)); |
| @@ -4128,27 +4181,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4128 | else | 4181 | else |
| 4129 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 4182 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
| 4130 | iwe.u.data.length = 0; | 4183 | iwe.u.data.length = 0; |
| 4131 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); | 4184 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
| 4185 | &iwe, ""); | ||
| 4132 | 4186 | ||
| 4133 | if (bss && bss->wpa_ie) { | 4187 | if (bss && bss->wpa_ie) { |
| 4134 | memset(&iwe, 0, sizeof(iwe)); | 4188 | memset(&iwe, 0, sizeof(iwe)); |
| 4135 | iwe.cmd = IWEVGENIE; | 4189 | iwe.cmd = IWEVGENIE; |
| 4136 | iwe.u.data.length = bss->wpa_ie_len; | 4190 | iwe.u.data.length = bss->wpa_ie_len; |
| 4137 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4191 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
| 4138 | bss->wpa_ie); | 4192 | &iwe, bss->wpa_ie); |
| 4139 | } | 4193 | } |
| 4140 | 4194 | ||
| 4141 | if (bss && bss->rsn_ie) { | 4195 | if (bss && bss->rsn_ie) { |
| 4142 | memset(&iwe, 0, sizeof(iwe)); | 4196 | memset(&iwe, 0, sizeof(iwe)); |
| 4143 | iwe.cmd = IWEVGENIE; | 4197 | iwe.cmd = IWEVGENIE; |
| 4144 | iwe.u.data.length = bss->rsn_ie_len; | 4198 | iwe.u.data.length = bss->rsn_ie_len; |
| 4145 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4199 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
| 4146 | bss->rsn_ie); | 4200 | &iwe, bss->rsn_ie); |
| 4201 | } | ||
| 4202 | |||
| 4203 | if (bss && bss->ht_ie) { | ||
| 4204 | memset(&iwe, 0, sizeof(iwe)); | ||
| 4205 | iwe.cmd = IWEVGENIE; | ||
| 4206 | iwe.u.data.length = bss->ht_ie_len; | ||
| 4207 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | ||
| 4208 | &iwe, bss->ht_ie); | ||
| 4147 | } | 4209 | } |
| 4148 | 4210 | ||
| 4149 | if (bss && bss->supp_rates_len > 0) { | 4211 | if (bss && bss->supp_rates_len > 0) { |
| 4150 | /* display all supported rates in readable format */ | 4212 | /* display all supported rates in readable format */ |
| 4151 | char *p = current_ev + IW_EV_LCP_LEN; | 4213 | char *p = current_ev + iwe_stream_lcp_len(info); |
| 4152 | int i; | 4214 | int i; |
| 4153 | 4215 | ||
| 4154 | memset(&iwe, 0, sizeof(iwe)); | 4216 | memset(&iwe, 0, sizeof(iwe)); |
| @@ -4159,7 +4221,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4159 | for (i = 0; i < bss->supp_rates_len; i++) { | 4221 | for (i = 0; i < bss->supp_rates_len; i++) { |
| 4160 | iwe.u.bitrate.value = ((bss->supp_rates[i] & | 4222 | iwe.u.bitrate.value = ((bss->supp_rates[i] & |
| 4161 | 0x7f) * 500000); | 4223 | 0x7f) * 500000); |
| 4162 | p = iwe_stream_add_value(current_ev, p, | 4224 | p = iwe_stream_add_value(info, current_ev, p, |
| 4163 | end_buf, &iwe, IW_EV_PARAM_LEN); | 4225 | end_buf, &iwe, IW_EV_PARAM_LEN); |
| 4164 | } | 4226 | } |
| 4165 | current_ev = p; | 4227 | current_ev = p; |
| @@ -4173,8 +4235,16 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4173 | iwe.cmd = IWEVCUSTOM; | 4235 | iwe.cmd = IWEVCUSTOM; |
| 4174 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); | 4236 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); |
| 4175 | iwe.u.data.length = strlen(buf); | 4237 | iwe.u.data.length = strlen(buf); |
| 4176 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4238 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4239 | end_buf, | ||
| 4177 | &iwe, buf); | 4240 | &iwe, buf); |
| 4241 | memset(&iwe, 0, sizeof(iwe)); | ||
| 4242 | iwe.cmd = IWEVCUSTOM; | ||
| 4243 | sprintf(buf, " Last beacon: %dms ago", | ||
| 4244 | jiffies_to_msecs(jiffies - bss->last_update)); | ||
| 4245 | iwe.u.data.length = strlen(buf); | ||
| 4246 | current_ev = iwe_stream_add_point(info, current_ev, | ||
| 4247 | end_buf, &iwe, buf); | ||
| 4178 | kfree(buf); | 4248 | kfree(buf); |
| 4179 | } | 4249 | } |
| 4180 | } | 4250 | } |
| @@ -4188,31 +4258,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4188 | iwe.cmd = IWEVCUSTOM; | 4258 | iwe.cmd = IWEVCUSTOM; |
| 4189 | sprintf(buf, "Mesh network (version %d)", cfg[0]); | 4259 | sprintf(buf, "Mesh network (version %d)", cfg[0]); |
| 4190 | iwe.u.data.length = strlen(buf); | 4260 | iwe.u.data.length = strlen(buf); |
| 4191 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4261 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4262 | end_buf, | ||
| 4192 | &iwe, buf); | 4263 | &iwe, buf); |
| 4193 | sprintf(buf, "Path Selection Protocol ID: " | 4264 | sprintf(buf, "Path Selection Protocol ID: " |
| 4194 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], | 4265 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], |
| 4195 | cfg[4]); | 4266 | cfg[4]); |
| 4196 | iwe.u.data.length = strlen(buf); | 4267 | iwe.u.data.length = strlen(buf); |
| 4197 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4268 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4269 | end_buf, | ||
| 4198 | &iwe, buf); | 4270 | &iwe, buf); |
| 4199 | sprintf(buf, "Path Selection Metric ID: " | 4271 | sprintf(buf, "Path Selection Metric ID: " |
| 4200 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], | 4272 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], |
| 4201 | cfg[8]); | 4273 | cfg[8]); |
| 4202 | iwe.u.data.length = strlen(buf); | 4274 | iwe.u.data.length = strlen(buf); |
| 4203 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4275 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4276 | end_buf, | ||
| 4204 | &iwe, buf); | 4277 | &iwe, buf); |
| 4205 | sprintf(buf, "Congestion Control Mode ID: " | 4278 | sprintf(buf, "Congestion Control Mode ID: " |
| 4206 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], | 4279 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], |
| 4207 | cfg[11], cfg[12]); | 4280 | cfg[11], cfg[12]); |
| 4208 | iwe.u.data.length = strlen(buf); | 4281 | iwe.u.data.length = strlen(buf); |
| 4209 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4282 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4283 | end_buf, | ||
| 4210 | &iwe, buf); | 4284 | &iwe, buf); |
| 4211 | sprintf(buf, "Channel Precedence: " | 4285 | sprintf(buf, "Channel Precedence: " |
| 4212 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], | 4286 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], |
| 4213 | cfg[15], cfg[16]); | 4287 | cfg[15], cfg[16]); |
| 4214 | iwe.u.data.length = strlen(buf); | 4288 | iwe.u.data.length = strlen(buf); |
| 4215 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4289 | current_ev = iwe_stream_add_point(info, current_ev, |
| 4290 | end_buf, | ||
| 4216 | &iwe, buf); | 4291 | &iwe, buf); |
| 4217 | kfree(buf); | 4292 | kfree(buf); |
| 4218 | } | 4293 | } |
| @@ -4222,7 +4297,9 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
| 4222 | } | 4297 | } |
| 4223 | 4298 | ||
| 4224 | 4299 | ||
| 4225 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | 4300 | int ieee80211_sta_scan_results(struct net_device *dev, |
| 4301 | struct iw_request_info *info, | ||
| 4302 | char *buf, size_t len) | ||
| 4226 | { | 4303 | { |
| 4227 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4304 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 4228 | char *current_ev = buf; | 4305 | char *current_ev = buf; |
| @@ -4235,8 +4312,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | |||
| 4235 | spin_unlock_bh(&local->sta_bss_lock); | 4312 | spin_unlock_bh(&local->sta_bss_lock); |
| 4236 | return -E2BIG; | 4313 | return -E2BIG; |
| 4237 | } | 4314 | } |
| 4238 | current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, | 4315 | current_ev = ieee80211_sta_scan_result(dev, info, bss, |
| 4239 | end_buf); | 4316 | current_ev, end_buf); |
| 4240 | } | 4317 | } |
| 4241 | spin_unlock_bh(&local->sta_bss_lock); | 4318 | spin_unlock_bh(&local->sta_bss_lock); |
| 4242 | return current_ev - buf; | 4319 | return current_ev - buf; |
| @@ -4247,6 +4324,7 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
| 4247 | { | 4324 | { |
| 4248 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4325 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 4249 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4326 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
| 4327 | |||
| 4250 | kfree(ifsta->extra_ie); | 4328 | kfree(ifsta->extra_ie); |
| 4251 | if (len == 0) { | 4329 | if (len == 0) { |
| 4252 | ifsta->extra_ie = NULL; | 4330 | ifsta->extra_ie = NULL; |
| @@ -4264,14 +4342,15 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
| 4264 | } | 4342 | } |
| 4265 | 4343 | ||
| 4266 | 4344 | ||
| 4267 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | 4345 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
| 4268 | struct sk_buff *skb, u8 *bssid, | 4346 | struct sk_buff *skb, u8 *bssid, |
| 4269 | u8 *addr) | 4347 | u8 *addr, u64 supp_rates) |
| 4270 | { | 4348 | { |
| 4271 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4349 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 4272 | struct sta_info *sta; | 4350 | struct sta_info *sta; |
| 4273 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4351 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 4274 | DECLARE_MAC_BUF(mac); | 4352 | DECLARE_MAC_BUF(mac); |
| 4353 | int band = local->hw.conf.channel->band; | ||
| 4275 | 4354 | ||
| 4276 | /* TODO: Could consider removing the least recently used entry and | 4355 | /* TODO: Could consider removing the least recently used entry and |
| 4277 | * allow new one to be added. */ | 4356 | * allow new one to be added. */ |
| @@ -4283,17 +4362,24 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
| 4283 | return NULL; | 4362 | return NULL; |
| 4284 | } | 4363 | } |
| 4285 | 4364 | ||
| 4365 | if (compare_ether_addr(bssid, sdata->u.sta.bssid)) | ||
| 4366 | return NULL; | ||
| 4367 | |||
| 4368 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
| 4286 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 4369 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", |
| 4287 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 4370 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
| 4371 | #endif | ||
| 4288 | 4372 | ||
| 4289 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 4373 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
| 4290 | if (!sta) | 4374 | if (!sta) |
| 4291 | return NULL; | 4375 | return NULL; |
| 4292 | 4376 | ||
| 4293 | sta->flags |= WLAN_STA_AUTHORIZED; | 4377 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
| 4294 | 4378 | ||
| 4295 | sta->supp_rates[local->hw.conf.channel->band] = | 4379 | if (supp_rates) |
| 4296 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | 4380 | sta->supp_rates[band] = supp_rates; |
| 4381 | else | ||
| 4382 | sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band]; | ||
| 4297 | 4383 | ||
| 4298 | rate_control_rate_init(sta, local); | 4384 | rate_control_rate_init(sta, local); |
| 4299 | 4385 | ||
| @@ -4309,7 +4395,7 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason) | |||
| 4309 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4395 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 4310 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4396 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
| 4311 | 4397 | ||
| 4312 | printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n", | 4398 | printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", |
| 4313 | dev->name, reason); | 4399 | dev->name, reason); |
| 4314 | 4400 | ||
| 4315 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 4401 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && |
| @@ -4327,7 +4413,7 @@ int ieee80211_sta_disassociate(struct net_device *dev, u16 reason) | |||
| 4327 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4413 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 4328 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4414 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
| 4329 | 4415 | ||
| 4330 | printk(KERN_DEBUG "%s: disassociate(reason=%d)\n", | 4416 | printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", |
| 4331 | dev->name, reason); | 4417 | dev->name, reason); |
| 4332 | 4418 | ||
| 4333 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 4419 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
| @@ -4351,12 +4437,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw, | |||
| 4351 | case IEEE80211_NOTIFY_RE_ASSOC: | 4437 | case IEEE80211_NOTIFY_RE_ASSOC: |
| 4352 | rcu_read_lock(); | 4438 | rcu_read_lock(); |
| 4353 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 4439 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
| 4440 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | ||
| 4441 | continue; | ||
| 4354 | 4442 | ||
| 4355 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 4443 | ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); |
| 4356 | ieee80211_sta_req_auth(sdata->dev, | ||
| 4357 | &sdata->u.sta); | ||
| 4358 | } | ||
| 4359 | |||
| 4360 | } | 4444 | } |
| 4361 | rcu_read_unlock(); | 4445 | rcu_read_unlock(); |
| 4362 | break; | 4446 | break; |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 841df93807fc..0388c090dfe9 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
| @@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev, | |||
| 176 | rcu_read_lock(); | 176 | rcu_read_lock(); |
| 177 | sta = sta_info_get(local, hdr->addr1); | 177 | sta = sta_info_get(local, hdr->addr1); |
| 178 | 178 | ||
| 179 | memset(sel, 0, sizeof(struct rate_selection)); | 179 | sel->rate_idx = -1; |
| 180 | sel->nonerp_idx = -1; | ||
| 181 | sel->probe_idx = -1; | ||
| 180 | 182 | ||
| 181 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); | 183 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); |
| 182 | 184 | ||
| 185 | BUG_ON(sel->rate_idx < 0); | ||
| 186 | |||
| 183 | /* Select a non-ERP backup rate. */ | 187 | /* Select a non-ERP backup rate. */ |
| 184 | if (!sel->nonerp) { | 188 | if (sel->nonerp_idx < 0) { |
| 185 | for (i = 0; i < sband->n_bitrates; i++) { | 189 | for (i = 0; i < sband->n_bitrates; i++) { |
| 186 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 190 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
| 187 | if (sel->rate->bitrate < rate->bitrate) | 191 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) |
| 188 | break; | 192 | break; |
| 189 | 193 | ||
| 190 | if (rate_supported(sta, sband->band, i) && | 194 | if (rate_supported(sta, sband->band, i) && |
| 191 | !(rate->flags & IEEE80211_RATE_ERP_G)) | 195 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
| 192 | sel->nonerp = rate; | 196 | sel->nonerp_idx = i; |
| 193 | } | 197 | } |
| 194 | } | 198 | } |
| 195 | 199 | ||
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 5b45f33cb766..ede7ab56f65b 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
| @@ -19,22 +19,22 @@ | |||
| 19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
| 20 | #include "sta_info.h" | 20 | #include "sta_info.h" |
| 21 | 21 | ||
| 22 | /* TODO: kdoc */ | 22 | /** |
| 23 | * struct rate_selection - rate selection for rate control algos | ||
| 24 | * @rate: selected transmission rate index | ||
| 25 | * @nonerp: Non-ERP rate to use instead if ERP cannot be used | ||
| 26 | * @probe: rate for probing (or -1) | ||
| 27 | * | ||
| 28 | */ | ||
| 23 | struct rate_selection { | 29 | struct rate_selection { |
| 24 | /* Selected transmission rate */ | 30 | s8 rate_idx, nonerp_idx, probe_idx; |
| 25 | struct ieee80211_rate *rate; | ||
| 26 | /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */ | ||
| 27 | struct ieee80211_rate *nonerp; | ||
| 28 | /* probe with this rate, or NULL for no probing */ | ||
| 29 | struct ieee80211_rate *probe; | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | struct rate_control_ops { | 33 | struct rate_control_ops { |
| 33 | struct module *module; | 34 | struct module *module; |
| 34 | const char *name; | 35 | const char *name; |
| 35 | void (*tx_status)(void *priv, struct net_device *dev, | 36 | void (*tx_status)(void *priv, struct net_device *dev, |
| 36 | struct sk_buff *skb, | 37 | struct sk_buff *skb); |
| 37 | struct ieee80211_tx_status *status); | ||
| 38 | void (*get_rate)(void *priv, struct net_device *dev, | 38 | void (*get_rate)(void *priv, struct net_device *dev, |
| 39 | struct ieee80211_supported_band *band, | 39 | struct ieee80211_supported_band *band, |
| 40 | struct sk_buff *skb, | 40 | struct sk_buff *skb, |
| @@ -76,13 +76,12 @@ struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | |||
| 76 | void rate_control_put(struct rate_control_ref *ref); | 76 | void rate_control_put(struct rate_control_ref *ref); |
| 77 | 77 | ||
| 78 | static inline void rate_control_tx_status(struct net_device *dev, | 78 | static inline void rate_control_tx_status(struct net_device *dev, |
| 79 | struct sk_buff *skb, | 79 | struct sk_buff *skb) |
| 80 | struct ieee80211_tx_status *status) | ||
| 81 | { | 80 | { |
| 82 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 81 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 83 | struct rate_control_ref *ref = local->rate_ctrl; | 82 | struct rate_control_ref *ref = local->rate_ctrl; |
| 84 | 83 | ||
| 85 | ref->ops->tx_status(ref->priv, dev, skb, status); | 84 | ref->ops->tx_status(ref->priv, dev, skb); |
| 86 | } | 85 | } |
| 87 | 86 | ||
| 88 | 87 | ||
| @@ -138,7 +137,7 @@ static inline int rate_supported(struct sta_info *sta, | |||
| 138 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); | 137 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); |
| 139 | } | 138 | } |
| 140 | 139 | ||
| 141 | static inline int | 140 | static inline s8 |
| 142 | rate_lowest_index(struct ieee80211_local *local, | 141 | rate_lowest_index(struct ieee80211_local *local, |
| 143 | struct ieee80211_supported_band *sband, | 142 | struct ieee80211_supported_band *sband, |
| 144 | struct sta_info *sta) | 143 | struct sta_info *sta) |
| @@ -155,14 +154,6 @@ rate_lowest_index(struct ieee80211_local *local, | |||
| 155 | return 0; | 154 | return 0; |
| 156 | } | 155 | } |
| 157 | 156 | ||
| 158 | static inline struct ieee80211_rate * | ||
| 159 | rate_lowest(struct ieee80211_local *local, | ||
| 160 | struct ieee80211_supported_band *sband, | ||
| 161 | struct sta_info *sta) | ||
| 162 | { | ||
| 163 | return &sband->bitrates[rate_lowest_index(local, sband, sta)]; | ||
| 164 | } | ||
| 165 | |||
| 166 | 157 | ||
| 167 | /* functions for rate control related to a device */ | 158 | /* functions for rate control related to a device */ |
| 168 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | 159 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, |
| @@ -171,9 +162,7 @@ void rate_control_deinitialize(struct ieee80211_local *local); | |||
| 171 | 162 | ||
| 172 | 163 | ||
| 173 | /* Rate control algorithms */ | 164 | /* Rate control algorithms */ |
| 174 | #if defined(RC80211_PID_COMPILE) || \ | 165 | #ifdef CONFIG_MAC80211_RC_PID |
| 175 | (defined(CONFIG_MAC80211_RC_PID) && \ | ||
| 176 | !defined(CONFIG_MAC80211_RC_PID_MODULE)) | ||
| 177 | extern int rc80211_pid_init(void); | 166 | extern int rc80211_pid_init(void); |
| 178 | extern void rc80211_pid_exit(void); | 167 | extern void rc80211_pid_exit(void); |
| 179 | #else | 168 | #else |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 04afc13ed825..0a9135b974b5 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
| @@ -61,7 +61,7 @@ enum rc_pid_event_type { | |||
| 61 | union rc_pid_event_data { | 61 | union rc_pid_event_data { |
| 62 | /* RC_PID_EVENT_TX_STATUS */ | 62 | /* RC_PID_EVENT_TX_STATUS */ |
| 63 | struct { | 63 | struct { |
| 64 | struct ieee80211_tx_status tx_status; | 64 | struct ieee80211_tx_info tx_status; |
| 65 | }; | 65 | }; |
| 66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ | 66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ |
| 67 | /* RC_PID_EVENT_TYPE_TX_RATE */ | 67 | /* RC_PID_EVENT_TYPE_TX_RATE */ |
| @@ -141,7 +141,6 @@ struct rc_pid_events_file_info { | |||
| 141 | * rate behaviour values (lower means we should trust more what we learnt | 141 | * rate behaviour values (lower means we should trust more what we learnt |
| 142 | * about behaviour of rates, higher means we should trust more the natural | 142 | * about behaviour of rates, higher means we should trust more the natural |
| 143 | * ordering of rates) | 143 | * ordering of rates) |
| 144 | * @fast_start: if Y, push high rates right after initialization | ||
| 145 | */ | 144 | */ |
| 146 | struct rc_pid_debugfs_entries { | 145 | struct rc_pid_debugfs_entries { |
| 147 | struct dentry *dir; | 146 | struct dentry *dir; |
| @@ -154,11 +153,10 @@ struct rc_pid_debugfs_entries { | |||
| 154 | struct dentry *sharpen_factor; | 153 | struct dentry *sharpen_factor; |
| 155 | struct dentry *sharpen_duration; | 154 | struct dentry *sharpen_duration; |
| 156 | struct dentry *norm_offset; | 155 | struct dentry *norm_offset; |
| 157 | struct dentry *fast_start; | ||
| 158 | }; | 156 | }; |
| 159 | 157 | ||
| 160 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 158 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
| 161 | struct ieee80211_tx_status *stat); | 159 | struct ieee80211_tx_info *stat); |
| 162 | 160 | ||
| 163 | void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf, | 161 | void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf, |
| 164 | int index, int rate); | 162 | int index, int rate); |
| @@ -267,9 +265,6 @@ struct rc_pid_info { | |||
| 267 | /* Normalization offset. */ | 265 | /* Normalization offset. */ |
| 268 | unsigned int norm_offset; | 266 | unsigned int norm_offset; |
| 269 | 267 | ||
| 270 | /* Fast starst parameter. */ | ||
| 271 | unsigned int fast_start; | ||
| 272 | |||
| 273 | /* Rates information. */ | 268 | /* Rates information. */ |
| 274 | struct rc_pid_rateinfo *rinfo; | 269 | struct rc_pid_rateinfo *rinfo; |
| 275 | 270 | ||
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index a849b745bdb5..a914ba73ccf5 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
| @@ -237,8 +237,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | 239 | static void rate_control_pid_tx_status(void *priv, struct net_device *dev, |
| 240 | struct sk_buff *skb, | 240 | struct sk_buff *skb) |
| 241 | struct ieee80211_tx_status *status) | ||
| 242 | { | 241 | { |
| 243 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 242 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 244 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 243 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| @@ -248,6 +247,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
| 248 | struct rc_pid_sta_info *spinfo; | 247 | struct rc_pid_sta_info *spinfo; |
| 249 | unsigned long period; | 248 | unsigned long period; |
| 250 | struct ieee80211_supported_band *sband; | 249 | struct ieee80211_supported_band *sband; |
| 250 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 251 | 251 | ||
| 252 | rcu_read_lock(); | 252 | rcu_read_lock(); |
| 253 | 253 | ||
| @@ -259,35 +259,35 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
| 259 | 259 | ||
| 260 | /* Don't update the state if we're not controlling the rate. */ | 260 | /* Don't update the state if we're not controlling the rate. */ |
| 261 | sdata = sta->sdata; | 261 | sdata = sta->sdata; |
| 262 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { | 262 | if (sdata->force_unicast_rateidx > -1) { |
| 263 | sta->txrate_idx = sdata->bss->max_ratectrl_rateidx; | 263 | sta->txrate_idx = sdata->max_ratectrl_rateidx; |
| 264 | goto unlock; | 264 | goto unlock; |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | /* Ignore all frames that were sent with a different rate than the rate | 267 | /* Ignore all frames that were sent with a different rate than the rate |
| 268 | * we currently advise mac80211 to use. */ | 268 | * we currently advise mac80211 to use. */ |
| 269 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) | 269 | if (info->tx_rate_idx != sta->txrate_idx) |
| 270 | goto unlock; | 270 | goto unlock; |
| 271 | 271 | ||
| 272 | spinfo = sta->rate_ctrl_priv; | 272 | spinfo = sta->rate_ctrl_priv; |
| 273 | spinfo->tx_num_xmit++; | 273 | spinfo->tx_num_xmit++; |
| 274 | 274 | ||
| 275 | #ifdef CONFIG_MAC80211_DEBUGFS | 275 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 276 | rate_control_pid_event_tx_status(&spinfo->events, status); | 276 | rate_control_pid_event_tx_status(&spinfo->events, info); |
| 277 | #endif | 277 | #endif |
| 278 | 278 | ||
| 279 | /* We count frames that totally failed to be transmitted as two bad | 279 | /* We count frames that totally failed to be transmitted as two bad |
| 280 | * frames, those that made it out but had some retries as one good and | 280 | * frames, those that made it out but had some retries as one good and |
| 281 | * one bad frame. */ | 281 | * one bad frame. */ |
| 282 | if (status->excessive_retries) { | 282 | if (info->status.excessive_retries) { |
| 283 | spinfo->tx_num_failed += 2; | 283 | spinfo->tx_num_failed += 2; |
| 284 | spinfo->tx_num_xmit++; | 284 | spinfo->tx_num_xmit++; |
| 285 | } else if (status->retry_count) { | 285 | } else if (info->status.retry_count) { |
| 286 | spinfo->tx_num_failed++; | 286 | spinfo->tx_num_failed++; |
| 287 | spinfo->tx_num_xmit++; | 287 | spinfo->tx_num_xmit++; |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | if (status->excessive_retries) { | 290 | if (info->status.excessive_retries) { |
| 291 | sta->tx_retry_failed++; | 291 | sta->tx_retry_failed++; |
| 292 | sta->tx_num_consecutive_failures++; | 292 | sta->tx_num_consecutive_failures++; |
| 293 | sta->tx_num_mpdu_fail++; | 293 | sta->tx_num_mpdu_fail++; |
| @@ -295,8 +295,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
| 295 | sta->tx_num_consecutive_failures = 0; | 295 | sta->tx_num_consecutive_failures = 0; |
| 296 | sta->tx_num_mpdu_ok++; | 296 | sta->tx_num_mpdu_ok++; |
| 297 | } | 297 | } |
| 298 | sta->tx_retry_count += status->retry_count; | 298 | sta->tx_retry_count += info->status.retry_count; |
| 299 | sta->tx_num_mpdu_fail += status->retry_count; | 299 | sta->tx_num_mpdu_fail += info->status.retry_count; |
| 300 | 300 | ||
| 301 | /* Update PID controller state. */ | 301 | /* Update PID controller state. */ |
| 302 | period = (HZ * pinfo->sampling_period + 500) / 1000; | 302 | period = (HZ * pinfo->sampling_period + 500) / 1000; |
| @@ -330,15 +330,15 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
| 330 | fc = le16_to_cpu(hdr->frame_control); | 330 | fc = le16_to_cpu(hdr->frame_control); |
| 331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
| 332 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 332 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
| 333 | sel->rate = rate_lowest(local, sband, sta); | 333 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
| 334 | rcu_read_unlock(); | 334 | rcu_read_unlock(); |
| 335 | return; | 335 | return; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | /* If a forced rate is in effect, select it. */ | 338 | /* If a forced rate is in effect, select it. */ |
| 339 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 339 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 340 | if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) | 340 | if (sdata->force_unicast_rateidx > -1) |
| 341 | sta->txrate_idx = sdata->bss->force_unicast_rateidx; | 341 | sta->txrate_idx = sdata->force_unicast_rateidx; |
| 342 | 342 | ||
| 343 | rateidx = sta->txrate_idx; | 343 | rateidx = sta->txrate_idx; |
| 344 | 344 | ||
| @@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
| 349 | 349 | ||
| 350 | rcu_read_unlock(); | 350 | rcu_read_unlock(); |
| 351 | 351 | ||
| 352 | sel->rate = &sband->bitrates[rateidx]; | 352 | sel->rate_idx = rateidx; |
| 353 | 353 | ||
| 354 | #ifdef CONFIG_MAC80211_DEBUGFS | 354 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 355 | rate_control_pid_event_tx_rate( | 355 | rate_control_pid_event_tx_rate( |
| @@ -398,13 +398,25 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 398 | return NULL; | 398 | return NULL; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | pinfo->target = RC_PID_TARGET_PF; | ||
| 402 | pinfo->sampling_period = RC_PID_INTERVAL; | ||
| 403 | pinfo->coeff_p = RC_PID_COEFF_P; | ||
| 404 | pinfo->coeff_i = RC_PID_COEFF_I; | ||
| 405 | pinfo->coeff_d = RC_PID_COEFF_D; | ||
| 406 | pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; | ||
| 407 | pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; | ||
| 408 | pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; | ||
| 409 | pinfo->norm_offset = RC_PID_NORM_OFFSET; | ||
| 410 | pinfo->rinfo = rinfo; | ||
| 411 | pinfo->oldrate = 0; | ||
| 412 | |||
| 401 | /* Sort the rates. This is optimized for the most common case (i.e. | 413 | /* Sort the rates. This is optimized for the most common case (i.e. |
| 402 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed | 414 | * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed |
| 403 | * mapping too. */ | 415 | * mapping too. */ |
| 404 | for (i = 0; i < sband->n_bitrates; i++) { | 416 | for (i = 0; i < sband->n_bitrates; i++) { |
| 405 | rinfo[i].index = i; | 417 | rinfo[i].index = i; |
| 406 | rinfo[i].rev_index = i; | 418 | rinfo[i].rev_index = i; |
| 407 | if (pinfo->fast_start) | 419 | if (RC_PID_FAST_START) |
| 408 | rinfo[i].diff = 0; | 420 | rinfo[i].diff = 0; |
| 409 | else | 421 | else |
| 410 | rinfo[i].diff = i * pinfo->norm_offset; | 422 | rinfo[i].diff = i * pinfo->norm_offset; |
| @@ -425,19 +437,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 425 | break; | 437 | break; |
| 426 | } | 438 | } |
| 427 | 439 | ||
| 428 | pinfo->target = RC_PID_TARGET_PF; | ||
| 429 | pinfo->sampling_period = RC_PID_INTERVAL; | ||
| 430 | pinfo->coeff_p = RC_PID_COEFF_P; | ||
| 431 | pinfo->coeff_i = RC_PID_COEFF_I; | ||
| 432 | pinfo->coeff_d = RC_PID_COEFF_D; | ||
| 433 | pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT; | ||
| 434 | pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR; | ||
| 435 | pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION; | ||
| 436 | pinfo->norm_offset = RC_PID_NORM_OFFSET; | ||
| 437 | pinfo->fast_start = RC_PID_FAST_START; | ||
| 438 | pinfo->rinfo = rinfo; | ||
| 439 | pinfo->oldrate = 0; | ||
| 440 | |||
| 441 | #ifdef CONFIG_MAC80211_DEBUGFS | 440 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 442 | de = &pinfo->dentries; | 441 | de = &pinfo->dentries; |
| 443 | de->dir = debugfs_create_dir("rc80211_pid", | 442 | de->dir = debugfs_create_dir("rc80211_pid", |
| @@ -465,9 +464,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local) | |||
| 465 | de->norm_offset = debugfs_create_u32("norm_offset", | 464 | de->norm_offset = debugfs_create_u32("norm_offset", |
| 466 | S_IRUSR | S_IWUSR, de->dir, | 465 | S_IRUSR | S_IWUSR, de->dir, |
| 467 | &pinfo->norm_offset); | 466 | &pinfo->norm_offset); |
| 468 | de->fast_start = debugfs_create_bool("fast_start", | ||
| 469 | S_IRUSR | S_IWUSR, de->dir, | ||
| 470 | &pinfo->fast_start); | ||
| 471 | #endif | 467 | #endif |
| 472 | 468 | ||
| 473 | return pinfo; | 469 | return pinfo; |
| @@ -479,7 +475,6 @@ static void rate_control_pid_free(void *priv) | |||
| 479 | #ifdef CONFIG_MAC80211_DEBUGFS | 475 | #ifdef CONFIG_MAC80211_DEBUGFS |
| 480 | struct rc_pid_debugfs_entries *de = &pinfo->dentries; | 476 | struct rc_pid_debugfs_entries *de = &pinfo->dentries; |
| 481 | 477 | ||
| 482 | debugfs_remove(de->fast_start); | ||
| 483 | debugfs_remove(de->norm_offset); | 478 | debugfs_remove(de->norm_offset); |
| 484 | debugfs_remove(de->sharpen_duration); | 479 | debugfs_remove(de->sharpen_duration); |
| 485 | debugfs_remove(de->sharpen_factor); | 480 | debugfs_remove(de->sharpen_factor); |
| @@ -540,11 +535,6 @@ static struct rate_control_ops mac80211_rcpid = { | |||
| 540 | #endif | 535 | #endif |
| 541 | }; | 536 | }; |
| 542 | 537 | ||
| 543 | MODULE_DESCRIPTION("PID controller based rate control algorithm"); | ||
| 544 | MODULE_AUTHOR("Stefano Brivio"); | ||
| 545 | MODULE_AUTHOR("Mattias Nissler"); | ||
| 546 | MODULE_LICENSE("GPL"); | ||
| 547 | |||
| 548 | int __init rc80211_pid_init(void) | 538 | int __init rc80211_pid_init(void) |
| 549 | { | 539 | { |
| 550 | return ieee80211_rate_control_register(&mac80211_rcpid); | 540 | return ieee80211_rate_control_register(&mac80211_rcpid); |
| @@ -554,8 +544,3 @@ void rc80211_pid_exit(void) | |||
| 554 | { | 544 | { |
| 555 | ieee80211_rate_control_unregister(&mac80211_rcpid); | 545 | ieee80211_rate_control_unregister(&mac80211_rcpid); |
| 556 | } | 546 | } |
| 557 | |||
| 558 | #ifdef CONFIG_MAC80211_RC_PID_MODULE | ||
| 559 | module_init(rc80211_pid_init); | ||
| 560 | module_exit(rc80211_pid_exit); | ||
| 561 | #endif | ||
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index ff5c380f3c13..8121d3bc6835 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
| @@ -39,11 +39,11 @@ static void rate_control_pid_event(struct rc_pid_event_buffer *buf, | |||
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 41 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
| 42 | struct ieee80211_tx_status *stat) | 42 | struct ieee80211_tx_info *stat) |
| 43 | { | 43 | { |
| 44 | union rc_pid_event_data evd; | 44 | union rc_pid_event_data evd; |
| 45 | 45 | ||
| 46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_status)); | 46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); |
| 47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); | 47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| @@ -167,8 +167,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
| 167 | switch (ev->type) { | 167 | switch (ev->type) { |
| 168 | case RC_PID_EVENT_TYPE_TX_STATUS: | 168 | case RC_PID_EVENT_TYPE_TX_STATUS: |
| 169 | p += snprintf(pb + p, length - p, "tx_status %u %u", | 169 | p += snprintf(pb + p, length - p, "tx_status %u %u", |
| 170 | ev->data.tx_status.excessive_retries, | 170 | ev->data.tx_status.status.excessive_retries, |
| 171 | ev->data.tx_status.retry_count); | 171 | ev->data.tx_status.status.retry_count); |
| 172 | break; | 172 | break; |
| 173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: | 173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: |
| 174 | p += snprintf(pb + p, length - p, "rate_change %d %d", | 174 | p += snprintf(pb + p, length - p, "rate_change %d %d", |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0941e5d6a522..6d9ae67c27ca 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -61,22 +61,147 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, | |||
| 61 | int present_fcs_len, | 61 | int present_fcs_len, |
| 62 | int radiotap_len) | 62 | int radiotap_len) |
| 63 | { | 63 | { |
| 64 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 64 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 65 | 65 | ||
| 66 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | 66 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) |
| 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 | } |
| 79 | 76 | ||
| 77 | static int | ||
| 78 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, | ||
| 79 | struct ieee80211_rx_status *status) | ||
| 80 | { | ||
| 81 | int len; | ||
| 82 | |||
| 83 | /* always present fields */ | ||
| 84 | len = sizeof(struct ieee80211_radiotap_header) + 9; | ||
| 85 | |||
| 86 | if (status->flag & RX_FLAG_TSFT) | ||
| 87 | len += 8; | ||
| 88 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB || | ||
| 89 | local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
| 90 | len += 1; | ||
| 91 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
| 92 | len += 1; | ||
| 93 | |||
| 94 | if (len & 1) /* padding for RX_FLAGS if necessary */ | ||
| 95 | len++; | ||
| 96 | |||
| 97 | /* make sure radiotap starts at a naturally aligned address */ | ||
| 98 | if (len % 8) | ||
| 99 | len = roundup(len, 8); | ||
| 100 | |||
| 101 | return len; | ||
| 102 | } | ||
| 103 | |||
| 104 | /** | ||
| 105 | * ieee80211_add_rx_radiotap_header - add radiotap header | ||
| 106 | * | ||
| 107 | * add a radiotap header containing all the fields which the hardware provided. | ||
| 108 | */ | ||
| 109 | static void | ||
| 110 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | ||
| 111 | struct sk_buff *skb, | ||
| 112 | struct ieee80211_rx_status *status, | ||
| 113 | struct ieee80211_rate *rate, | ||
| 114 | int rtap_len) | ||
| 115 | { | ||
| 116 | struct ieee80211_radiotap_header *rthdr; | ||
| 117 | unsigned char *pos; | ||
| 118 | |||
| 119 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | ||
| 120 | memset(rthdr, 0, rtap_len); | ||
| 121 | |||
| 122 | /* radiotap header, set always present flags */ | ||
| 123 | rthdr->it_present = | ||
| 124 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
| 125 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
| 126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
| 127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | ||
| 128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
| 129 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
| 130 | |||
| 131 | pos = (unsigned char *)(rthdr+1); | ||
| 132 | |||
| 133 | /* the order of the following fields is important */ | ||
| 134 | |||
| 135 | /* IEEE80211_RADIOTAP_TSFT */ | ||
| 136 | if (status->flag & RX_FLAG_TSFT) { | ||
| 137 | *(__le64 *)pos = cpu_to_le64(status->mactime); | ||
| 138 | rthdr->it_present |= | ||
| 139 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
| 140 | pos += 8; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* IEEE80211_RADIOTAP_FLAGS */ | ||
| 144 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
| 145 | *pos |= IEEE80211_RADIOTAP_F_FCS; | ||
| 146 | pos++; | ||
| 147 | |||
| 148 | /* IEEE80211_RADIOTAP_RATE */ | ||
| 149 | *pos = rate->bitrate / 5; | ||
| 150 | pos++; | ||
| 151 | |||
| 152 | /* IEEE80211_RADIOTAP_CHANNEL */ | ||
| 153 | *(__le16 *)pos = cpu_to_le16(status->freq); | ||
| 154 | pos += 2; | ||
| 155 | if (status->band == IEEE80211_BAND_5GHZ) | ||
| 156 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
| 157 | IEEE80211_CHAN_5GHZ); | ||
| 158 | else | ||
| 159 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
| 160 | IEEE80211_CHAN_2GHZ); | ||
| 161 | pos += 2; | ||
| 162 | |||
| 163 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | ||
| 164 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
| 165 | *pos = status->signal; | ||
| 166 | rthdr->it_present |= | ||
| 167 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | ||
| 168 | pos++; | ||
| 169 | } | ||
| 170 | |||
| 171 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ | ||
| 172 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | ||
| 173 | *pos = status->noise; | ||
| 174 | rthdr->it_present |= | ||
| 175 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); | ||
| 176 | pos++; | ||
| 177 | } | ||
| 178 | |||
| 179 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ | ||
| 180 | |||
| 181 | /* IEEE80211_RADIOTAP_ANTENNA */ | ||
| 182 | *pos = status->antenna; | ||
| 183 | pos++; | ||
| 184 | |||
| 185 | /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */ | ||
| 186 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB) { | ||
| 187 | *pos = status->signal; | ||
| 188 | rthdr->it_present |= | ||
| 189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL); | ||
| 190 | pos++; | ||
| 191 | } | ||
| 192 | |||
| 193 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ | ||
| 194 | |||
| 195 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | ||
| 196 | /* ensure 2 byte alignment for the 2 byte field as required */ | ||
| 197 | if ((pos - (unsigned char *)rthdr) & 1) | ||
| 198 | pos++; | ||
| 199 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
| 200 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
| 201 | *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
| 202 | pos += 2; | ||
| 203 | } | ||
| 204 | |||
| 80 | /* | 205 | /* |
| 81 | * This function copies a received frame to all monitor interfaces and | 206 | * This function copies a received frame to all monitor interfaces and |
| 82 | * returns a cleaned-up SKB that no longer includes the FCS nor the | 207 | * returns a cleaned-up SKB that no longer includes the FCS nor the |
| @@ -89,17 +214,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
| 89 | { | 214 | { |
| 90 | struct ieee80211_sub_if_data *sdata; | 215 | struct ieee80211_sub_if_data *sdata; |
| 91 | int needed_headroom = 0; | 216 | int needed_headroom = 0; |
| 92 | struct ieee80211_radiotap_header *rthdr; | ||
| 93 | __le64 *rttsft = NULL; | ||
| 94 | struct ieee80211_rtap_fixed_data { | ||
| 95 | u8 flags; | ||
| 96 | u8 rate; | ||
| 97 | __le16 chan_freq; | ||
| 98 | __le16 chan_flags; | ||
| 99 | u8 antsignal; | ||
| 100 | u8 padding_for_rxflags; | ||
| 101 | __le16 rx_flags; | ||
| 102 | } __attribute__ ((packed)) *rtfixed; | ||
| 103 | struct sk_buff *skb, *skb2; | 217 | struct sk_buff *skb, *skb2; |
| 104 | struct net_device *prev_dev = NULL; | 218 | struct net_device *prev_dev = NULL; |
| 105 | int present_fcs_len = 0; | 219 | int present_fcs_len = 0; |
| @@ -116,8 +230,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
| 116 | if (status->flag & RX_FLAG_RADIOTAP) | 230 | if (status->flag & RX_FLAG_RADIOTAP) |
| 117 | rtap_len = ieee80211_get_radiotap_len(origskb->data); | 231 | rtap_len = ieee80211_get_radiotap_len(origskb->data); |
| 118 | else | 232 | else |
| 119 | /* room for radiotap header, always present fields and TSFT */ | 233 | /* room for the radiotap header based on driver features */ |
| 120 | needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8; | 234 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
| 121 | 235 | ||
| 122 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 236 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
| 123 | present_fcs_len = FCS_LEN; | 237 | present_fcs_len = FCS_LEN; |
| @@ -163,55 +277,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
| 163 | } | 277 | } |
| 164 | 278 | ||
| 165 | /* if necessary, prepend radiotap information */ | 279 | /* if necessary, prepend radiotap information */ |
| 166 | if (!(status->flag & RX_FLAG_RADIOTAP)) { | 280 | if (!(status->flag & RX_FLAG_RADIOTAP)) |
| 167 | rtfixed = (void *) skb_push(skb, sizeof(*rtfixed)); | 281 | ieee80211_add_rx_radiotap_header(local, skb, status, rate, |
| 168 | rtap_len = sizeof(*rthdr) + sizeof(*rtfixed); | 282 | needed_headroom); |
| 169 | if (status->flag & RX_FLAG_TSFT) { | ||
| 170 | rttsft = (void *) skb_push(skb, sizeof(*rttsft)); | ||
| 171 | rtap_len += 8; | ||
| 172 | } | ||
| 173 | rthdr = (void *) skb_push(skb, sizeof(*rthdr)); | ||
| 174 | memset(rthdr, 0, sizeof(*rthdr)); | ||
| 175 | memset(rtfixed, 0, sizeof(*rtfixed)); | ||
| 176 | rthdr->it_present = | ||
| 177 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
| 178 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
| 179 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
| 180 | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | | ||
| 181 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
| 182 | rtfixed->flags = 0; | ||
| 183 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
| 184 | rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS; | ||
| 185 | |||
| 186 | if (rttsft) { | ||
| 187 | *rttsft = cpu_to_le64(status->mactime); | ||
| 188 | rthdr->it_present |= | ||
| 189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
| 190 | } | ||
| 191 | |||
| 192 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
| 193 | rtfixed->rx_flags = 0; | ||
| 194 | if (status->flag & | ||
| 195 | (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
| 196 | rtfixed->rx_flags |= | ||
| 197 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
| 198 | |||
| 199 | rtfixed->rate = rate->bitrate / 5; | ||
| 200 | |||
| 201 | rtfixed->chan_freq = cpu_to_le16(status->freq); | ||
| 202 | |||
| 203 | if (status->band == IEEE80211_BAND_5GHZ) | ||
| 204 | rtfixed->chan_flags = | ||
| 205 | cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
| 206 | IEEE80211_CHAN_5GHZ); | ||
| 207 | else | ||
| 208 | rtfixed->chan_flags = | ||
| 209 | cpu_to_le16(IEEE80211_CHAN_DYN | | ||
| 210 | IEEE80211_CHAN_2GHZ); | ||
| 211 | |||
| 212 | rtfixed->antsignal = status->ssi; | ||
| 213 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
| 214 | } | ||
| 215 | 283 | ||
| 216 | skb_reset_mac_header(skb); | 284 | skb_reset_mac_header(skb); |
| 217 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 285 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
| @@ -253,33 +321,33 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
| 253 | 321 | ||
| 254 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | 322 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) |
| 255 | { | 323 | { |
| 256 | u8 *data = rx->skb->data; | 324 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 257 | int tid; | 325 | int tid; |
| 258 | 326 | ||
| 259 | /* does the frame have a qos control field? */ | 327 | /* does the frame have a qos control field? */ |
| 260 | if (WLAN_FC_IS_QOS_DATA(rx->fc)) { | 328 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
| 261 | u8 *qc = data + ieee80211_get_hdrlen(rx->fc) - QOS_CONTROL_LEN; | 329 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
| 262 | /* frame has qos control */ | 330 | /* frame has qos control */ |
| 263 | tid = qc[0] & QOS_CONTROL_TID_MASK; | 331 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
| 264 | if (qc[0] & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | 332 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) |
| 265 | rx->flags |= IEEE80211_RX_AMSDU; | 333 | rx->flags |= IEEE80211_RX_AMSDU; |
| 266 | else | 334 | else |
| 267 | rx->flags &= ~IEEE80211_RX_AMSDU; | 335 | rx->flags &= ~IEEE80211_RX_AMSDU; |
| 268 | } else { | 336 | } else { |
| 269 | if (unlikely((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)) { | 337 | /* |
| 270 | /* Separate TID for management frames */ | 338 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
| 271 | tid = NUM_RX_DATA_QUEUES - 1; | 339 | * |
| 272 | } else { | 340 | * Sequence numbers for management frames, QoS data |
| 273 | /* no qos control present */ | 341 | * frames with a broadcast/multicast address in the |
| 274 | tid = 0; /* 802.1d - Best Effort */ | 342 | * Address 1 field, and all non-QoS data frames sent |
| 275 | } | 343 | * by QoS STAs are assigned using an additional single |
| 344 | * modulo-4096 counter, [...] | ||
| 345 | * | ||
| 346 | * We also use that counter for non-QoS STAs. | ||
| 347 | */ | ||
| 348 | tid = NUM_RX_DATA_QUEUES - 1; | ||
| 276 | } | 349 | } |
| 277 | 350 | ||
| 278 | I802_DEBUG_INC(rx->local->wme_rx_queue[tid]); | ||
| 279 | /* only a debug counter, sta might not be assigned properly yet */ | ||
| 280 | if (rx->sta) | ||
| 281 | I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]); | ||
| 282 | |||
| 283 | rx->queue = tid; | 351 | rx->queue = tid; |
| 284 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. | 352 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. |
| 285 | * For now, set skb->priority to 0 for other cases. */ | 353 | * For now, set skb->priority to 0 for other cases. */ |
| @@ -289,9 +357,10 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
| 289 | static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | 357 | static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) |
| 290 | { | 358 | { |
| 291 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT | 359 | #ifdef CONFIG_MAC80211_DEBUG_PACKET_ALIGNMENT |
| 360 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | ||
| 292 | int hdrlen; | 361 | int hdrlen; |
| 293 | 362 | ||
| 294 | if (!WLAN_FC_DATA_PRESENT(rx->fc)) | 363 | if (!ieee80211_is_data_present(hdr->frame_control)) |
| 295 | return; | 364 | return; |
| 296 | 365 | ||
| 297 | /* | 366 | /* |
| @@ -313,7 +382,7 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
| 313 | * header and the payload is not supported, the driver is required | 382 | * header and the payload is not supported, the driver is required |
| 314 | * to move the 802.11 header further back in that case. | 383 | * to move the 802.11 header further back in that case. |
| 315 | */ | 384 | */ |
| 316 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 385 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 317 | if (rx->flags & IEEE80211_RX_AMSDU) | 386 | if (rx->flags & IEEE80211_RX_AMSDU) |
| 318 | hdrlen += ETH_HLEN; | 387 | hdrlen += ETH_HLEN; |
| 319 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); | 388 | WARN_ON_ONCE(((unsigned long)(rx->skb->data + hdrlen)) & 3); |
| @@ -321,51 +390,9 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
| 321 | } | 390 | } |
| 322 | 391 | ||
| 323 | 392 | ||
| 324 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | ||
| 325 | struct sk_buff *skb, | ||
| 326 | struct ieee80211_rx_status *status, | ||
| 327 | struct ieee80211_rate *rate) | ||
| 328 | { | ||
| 329 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 330 | u32 load = 0, hdrtime; | ||
| 331 | |||
| 332 | /* Estimate total channel use caused by this frame */ | ||
| 333 | |||
| 334 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | ||
| 335 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
| 336 | |||
| 337 | if (status->band == IEEE80211_BAND_5GHZ || | ||
| 338 | (status->band == IEEE80211_BAND_5GHZ && | ||
| 339 | rate->flags & IEEE80211_RATE_ERP_G)) | ||
| 340 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
| 341 | else | ||
| 342 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
| 343 | |||
| 344 | load = hdrtime; | ||
| 345 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
| 346 | load += hdrtime; | ||
| 347 | |||
| 348 | /* TODO: optimise again */ | ||
| 349 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
| 350 | |||
| 351 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
| 352 | load >>= CHAN_UTIL_SHIFT; | ||
| 353 | |||
| 354 | return load; | ||
| 355 | } | ||
| 356 | |||
| 357 | /* rx handlers */ | 393 | /* rx handlers */ |
| 358 | 394 | ||
| 359 | static ieee80211_rx_result | 395 | static ieee80211_rx_result debug_noinline |
| 360 | ieee80211_rx_h_if_stats(struct ieee80211_rx_data *rx) | ||
| 361 | { | ||
| 362 | if (rx->sta) | ||
| 363 | rx->sta->channel_use_raw += rx->load; | ||
| 364 | rx->sdata->channel_use_raw += rx->load; | ||
| 365 | return RX_CONTINUE; | ||
| 366 | } | ||
| 367 | |||
| 368 | static ieee80211_rx_result | ||
| 369 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 396 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
| 370 | { | 397 | { |
| 371 | struct ieee80211_local *local = rx->local; | 398 | struct ieee80211_local *local = rx->local; |
| @@ -394,14 +421,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | |||
| 394 | static ieee80211_rx_result | 421 | static ieee80211_rx_result |
| 395 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | 422 | ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) |
| 396 | { | 423 | { |
| 397 | int hdrlen = ieee80211_get_hdrlen(rx->fc); | 424 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 398 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 425 | unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 399 | 426 | ||
| 400 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) | 427 | if (ieee80211_is_data(hdr->frame_control)) { |
| 401 | 428 | if (!ieee80211_has_a4(hdr->frame_control)) | |
| 402 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { | ||
| 403 | if (!((rx->fc & IEEE80211_FCTL_FROMDS) && | ||
| 404 | (rx->fc & IEEE80211_FCTL_TODS))) | ||
| 405 | return RX_DROP_MONITOR; | 429 | return RX_DROP_MONITOR; |
| 406 | if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0) | 430 | if (memcmp(hdr->addr4, rx->dev->dev_addr, ETH_ALEN) == 0) |
| 407 | return RX_DROP_MONITOR; | 431 | return RX_DROP_MONITOR; |
| @@ -414,27 +438,30 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
| 414 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { | 438 | if (!rx->sta || sta_plink_state(rx->sta) != PLINK_ESTAB) { |
| 415 | struct ieee80211_mgmt *mgmt; | 439 | struct ieee80211_mgmt *mgmt; |
| 416 | 440 | ||
| 417 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) | 441 | if (!ieee80211_is_mgmt(hdr->frame_control)) |
| 418 | return RX_DROP_MONITOR; | 442 | return RX_DROP_MONITOR; |
| 419 | 443 | ||
| 420 | switch (rx->fc & IEEE80211_FCTL_STYPE) { | 444 | if (ieee80211_is_action(hdr->frame_control)) { |
| 421 | case IEEE80211_STYPE_ACTION: | ||
| 422 | mgmt = (struct ieee80211_mgmt *)hdr; | 445 | mgmt = (struct ieee80211_mgmt *)hdr; |
| 423 | if (mgmt->u.action.category != PLINK_CATEGORY) | 446 | if (mgmt->u.action.category != PLINK_CATEGORY) |
| 424 | return RX_DROP_MONITOR; | 447 | return RX_DROP_MONITOR; |
| 425 | /* fall through on else */ | ||
| 426 | case IEEE80211_STYPE_PROBE_REQ: | ||
| 427 | case IEEE80211_STYPE_PROBE_RESP: | ||
| 428 | case IEEE80211_STYPE_BEACON: | ||
| 429 | return RX_CONTINUE; | 448 | return RX_CONTINUE; |
| 430 | break; | ||
| 431 | default: | ||
| 432 | return RX_DROP_MONITOR; | ||
| 433 | } | 449 | } |
| 434 | 450 | ||
| 435 | } else if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 451 | if (ieee80211_is_probe_req(hdr->frame_control) || |
| 436 | is_multicast_ether_addr(hdr->addr1) && | 452 | ieee80211_is_probe_resp(hdr->frame_control) || |
| 437 | mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) | 453 | ieee80211_is_beacon(hdr->frame_control)) |
| 454 | return RX_CONTINUE; | ||
| 455 | |||
| 456 | return RX_DROP_MONITOR; | ||
| 457 | |||
| 458 | } | ||
| 459 | |||
| 460 | #define msh_h_get(h, l) ((struct ieee80211s_hdr *) ((u8 *)h + l)) | ||
| 461 | |||
| 462 | if (ieee80211_is_data(hdr->frame_control) && | ||
| 463 | is_multicast_ether_addr(hdr->addr1) && | ||
| 464 | mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) | ||
| 438 | return RX_DROP_MONITOR; | 465 | return RX_DROP_MONITOR; |
| 439 | #undef msh_h_get | 466 | #undef msh_h_get |
| 440 | 467 | ||
| @@ -442,16 +469,14 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
| 442 | } | 469 | } |
| 443 | 470 | ||
| 444 | 471 | ||
| 445 | static ieee80211_rx_result | 472 | static ieee80211_rx_result debug_noinline |
| 446 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 473 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
| 447 | { | 474 | { |
| 448 | struct ieee80211_hdr *hdr; | 475 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 449 | |||
| 450 | hdr = (struct ieee80211_hdr *) rx->skb->data; | ||
| 451 | 476 | ||
| 452 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 477 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
| 453 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 478 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
| 454 | if (unlikely(rx->fc & IEEE80211_FCTL_RETRY && | 479 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
| 455 | rx->sta->last_seq_ctrl[rx->queue] == | 480 | rx->sta->last_seq_ctrl[rx->queue] == |
| 456 | hdr->seq_ctrl)) { | 481 | hdr->seq_ctrl)) { |
| 457 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 482 | if (rx->flags & IEEE80211_RX_RA_MATCH) { |
| @@ -480,15 +505,14 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
| 480 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) | 505 | if (ieee80211_vif_is_mesh(&rx->sdata->vif)) |
| 481 | return ieee80211_rx_mesh_check(rx); | 506 | return ieee80211_rx_mesh_check(rx); |
| 482 | 507 | ||
| 483 | if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA || | 508 | if (unlikely((ieee80211_is_data(hdr->frame_control) || |
| 484 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 509 | ieee80211_is_pspoll(hdr->frame_control)) && |
| 485 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && | ||
| 486 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 510 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
| 487 | (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { | 511 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
| 488 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && | 512 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
| 489 | !(rx->fc & IEEE80211_FCTL_TODS) && | 513 | !ieee80211_has_tods(hdr->frame_control) && |
| 490 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) | 514 | ieee80211_is_data(hdr->frame_control)) || |
| 491 | || !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 515 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { |
| 492 | /* Drop IBSS frames and frames for other hosts | 516 | /* Drop IBSS frames and frames for other hosts |
| 493 | * silently. */ | 517 | * silently. */ |
| 494 | return RX_DROP_MONITOR; | 518 | return RX_DROP_MONITOR; |
| @@ -501,10 +525,10 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
| 501 | } | 525 | } |
| 502 | 526 | ||
| 503 | 527 | ||
| 504 | static ieee80211_rx_result | 528 | static ieee80211_rx_result debug_noinline |
| 505 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 529 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
| 506 | { | 530 | { |
| 507 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 508 | int keyidx; | 532 | int keyidx; |
| 509 | int hdrlen; | 533 | int hdrlen; |
| 510 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 534 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
| @@ -536,7 +560,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
| 536 | * possible. | 560 | * possible. |
| 537 | */ | 561 | */ |
| 538 | 562 | ||
| 539 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) | 563 | if (!ieee80211_has_protected(hdr->frame_control)) |
| 540 | return RX_CONTINUE; | 564 | return RX_CONTINUE; |
| 541 | 565 | ||
| 542 | /* | 566 | /* |
| @@ -565,7 +589,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
| 565 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) | 589 | (rx->status->flag & RX_FLAG_IV_STRIPPED)) |
| 566 | return RX_CONTINUE; | 590 | return RX_CONTINUE; |
| 567 | 591 | ||
| 568 | hdrlen = ieee80211_get_hdrlen(rx->fc); | 592 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 569 | 593 | ||
| 570 | if (rx->skb->len < 8 + hdrlen) | 594 | if (rx->skb->len < 8 + hdrlen) |
| 571 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | 595 | return RX_DROP_UNUSABLE; /* TODO: count this? */ |
| @@ -592,17 +616,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
| 592 | rx->key->tx_rx_count++; | 616 | rx->key->tx_rx_count++; |
| 593 | /* TODO: add threshold stuff again */ | 617 | /* TODO: add threshold stuff again */ |
| 594 | } else { | 618 | } else { |
| 595 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 596 | if (net_ratelimit()) | ||
| 597 | printk(KERN_DEBUG "%s: RX protected frame," | ||
| 598 | " but have no key\n", rx->dev->name); | ||
| 599 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 600 | return RX_DROP_MONITOR; | 619 | return RX_DROP_MONITOR; |
| 601 | } | 620 | } |
| 602 | 621 | ||
| 603 | /* Check for weak IVs if possible */ | 622 | /* Check for weak IVs if possible */ |
| 604 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | 623 | if (rx->sta && rx->key->conf.alg == ALG_WEP && |
| 605 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 624 | ieee80211_is_data(hdr->frame_control) && |
| 606 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || | 625 | (!(rx->status->flag & RX_FLAG_IV_STRIPPED) || |
| 607 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && | 626 | !(rx->status->flag & RX_FLAG_DECRYPTED)) && |
| 608 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 627 | ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
| @@ -633,10 +652,8 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
| 633 | 652 | ||
| 634 | sdata = sta->sdata; | 653 | sdata = sta->sdata; |
| 635 | 654 | ||
| 636 | if (sdata->bss) | 655 | atomic_inc(&sdata->bss->num_sta_ps); |
| 637 | atomic_inc(&sdata->bss->num_sta_ps); | 656 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
| 638 | sta->flags |= WLAN_STA_PS; | ||
| 639 | sta->flags &= ~WLAN_STA_PSPOLL; | ||
| 640 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 657 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| 641 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 658 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
| 642 | dev->name, print_mac(mac, sta->addr), sta->aid); | 659 | dev->name, print_mac(mac, sta->addr), sta->aid); |
| @@ -649,15 +666,14 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
| 649 | struct sk_buff *skb; | 666 | struct sk_buff *skb; |
| 650 | int sent = 0; | 667 | int sent = 0; |
| 651 | struct ieee80211_sub_if_data *sdata; | 668 | struct ieee80211_sub_if_data *sdata; |
| 652 | struct ieee80211_tx_packet_data *pkt_data; | 669 | struct ieee80211_tx_info *info; |
| 653 | DECLARE_MAC_BUF(mac); | 670 | DECLARE_MAC_BUF(mac); |
| 654 | 671 | ||
| 655 | sdata = sta->sdata; | 672 | sdata = sta->sdata; |
| 656 | 673 | ||
| 657 | if (sdata->bss) | 674 | atomic_dec(&sdata->bss->num_sta_ps); |
| 658 | atomic_dec(&sdata->bss->num_sta_ps); | ||
| 659 | 675 | ||
| 660 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); | 676 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
| 661 | 677 | ||
| 662 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 678 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
| 663 | sta_info_clear_tim_bit(sta); | 679 | sta_info_clear_tim_bit(sta); |
| @@ -669,13 +685,13 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
| 669 | 685 | ||
| 670 | /* Send all buffered frames to the station */ | 686 | /* Send all buffered frames to the station */ |
| 671 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 687 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
| 672 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 688 | info = IEEE80211_SKB_CB(skb); |
| 673 | sent++; | 689 | sent++; |
| 674 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | 690 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
| 675 | dev_queue_xmit(skb); | 691 | dev_queue_xmit(skb); |
| 676 | } | 692 | } |
| 677 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 693 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
| 678 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 694 | info = IEEE80211_SKB_CB(skb); |
| 679 | local->total_ps_buffered--; | 695 | local->total_ps_buffered--; |
| 680 | sent++; | 696 | sent++; |
| 681 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 697 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| @@ -683,19 +699,19 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
| 683 | "since STA not sleeping anymore\n", dev->name, | 699 | "since STA not sleeping anymore\n", dev->name, |
| 684 | print_mac(mac, sta->addr), sta->aid); | 700 | print_mac(mac, sta->addr), sta->aid); |
| 685 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 701 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
| 686 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | 702 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
| 687 | dev_queue_xmit(skb); | 703 | dev_queue_xmit(skb); |
| 688 | } | 704 | } |
| 689 | 705 | ||
| 690 | return sent; | 706 | return sent; |
| 691 | } | 707 | } |
| 692 | 708 | ||
| 693 | static ieee80211_rx_result | 709 | static ieee80211_rx_result debug_noinline |
| 694 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 710 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
| 695 | { | 711 | { |
| 696 | struct sta_info *sta = rx->sta; | 712 | struct sta_info *sta = rx->sta; |
| 697 | struct net_device *dev = rx->dev; | 713 | struct net_device *dev = rx->dev; |
| 698 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 714 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 699 | 715 | ||
| 700 | if (!sta) | 716 | if (!sta) |
| 701 | return RX_CONTINUE; | 717 | return RX_CONTINUE; |
| @@ -725,24 +741,26 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
| 725 | 741 | ||
| 726 | sta->rx_fragments++; | 742 | sta->rx_fragments++; |
| 727 | sta->rx_bytes += rx->skb->len; | 743 | sta->rx_bytes += rx->skb->len; |
| 728 | sta->last_rssi = rx->status->ssi; | ||
| 729 | sta->last_signal = rx->status->signal; | 744 | sta->last_signal = rx->status->signal; |
| 745 | sta->last_qual = rx->status->qual; | ||
| 730 | sta->last_noise = rx->status->noise; | 746 | sta->last_noise = rx->status->noise; |
| 731 | 747 | ||
| 732 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { | 748 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
| 749 | (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP || | ||
| 750 | rx->sdata->vif.type == IEEE80211_IF_TYPE_VLAN)) { | ||
| 733 | /* Change STA power saving mode only in the end of a frame | 751 | /* Change STA power saving mode only in the end of a frame |
| 734 | * exchange sequence */ | 752 | * exchange sequence */ |
| 735 | if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) | 753 | if (test_sta_flags(sta, WLAN_STA_PS) && |
| 754 | !ieee80211_has_pm(hdr->frame_control)) | ||
| 736 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); | 755 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); |
| 737 | else if (!(sta->flags & WLAN_STA_PS) && | 756 | else if (!test_sta_flags(sta, WLAN_STA_PS) && |
| 738 | (rx->fc & IEEE80211_FCTL_PM)) | 757 | ieee80211_has_pm(hdr->frame_control)) |
| 739 | ap_sta_ps_start(dev, sta); | 758 | ap_sta_ps_start(dev, sta); |
| 740 | } | 759 | } |
| 741 | 760 | ||
| 742 | /* Drop data::nullfunc frames silently, since they are used only to | 761 | /* Drop data::nullfunc frames silently, since they are used only to |
| 743 | * control station power saving mode. */ | 762 | * control station power saving mode. */ |
| 744 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 763 | if (ieee80211_is_nullfunc(hdr->frame_control)) { |
| 745 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_NULLFUNC) { | ||
| 746 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); | 764 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); |
| 747 | /* Update counter and free packet here to avoid counting this | 765 | /* Update counter and free packet here to avoid counting this |
| 748 | * as a dropped packed. */ | 766 | * as a dropped packed. */ |
| @@ -768,7 +786,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
| 768 | sdata->fragment_next = 0; | 786 | sdata->fragment_next = 0; |
| 769 | 787 | ||
| 770 | if (!skb_queue_empty(&entry->skb_list)) { | 788 | if (!skb_queue_empty(&entry->skb_list)) { |
| 771 | #ifdef CONFIG_MAC80211_DEBUG | 789 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
| 772 | struct ieee80211_hdr *hdr = | 790 | struct ieee80211_hdr *hdr = |
| 773 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 791 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
| 774 | DECLARE_MAC_BUF(mac); | 792 | DECLARE_MAC_BUF(mac); |
| @@ -780,7 +798,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
| 780 | jiffies - entry->first_frag_time, entry->seq, | 798 | jiffies - entry->first_frag_time, entry->seq, |
| 781 | entry->last_frag, print_mac(mac, hdr->addr1), | 799 | entry->last_frag, print_mac(mac, hdr->addr1), |
| 782 | print_mac(mac2, hdr->addr2)); | 800 | print_mac(mac2, hdr->addr2)); |
| 783 | #endif /* CONFIG_MAC80211_DEBUG */ | 801 | #endif |
| 784 | __skb_queue_purge(&entry->skb_list); | 802 | __skb_queue_purge(&entry->skb_list); |
| 785 | } | 803 | } |
| 786 | 804 | ||
| @@ -837,7 +855,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
| 837 | return NULL; | 855 | return NULL; |
| 838 | } | 856 | } |
| 839 | 857 | ||
| 840 | static ieee80211_rx_result | 858 | static ieee80211_rx_result debug_noinline |
| 841 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | 859 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |
| 842 | { | 860 | { |
| 843 | struct ieee80211_hdr *hdr; | 861 | struct ieee80211_hdr *hdr; |
| @@ -901,18 +919,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
| 901 | break; | 919 | break; |
| 902 | } | 920 | } |
| 903 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; | 921 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; |
| 904 | if (memcmp(pn, rpn, CCMP_PN_LEN) != 0) { | 922 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
| 905 | if (net_ratelimit()) | ||
| 906 | printk(KERN_DEBUG "%s: defrag: CCMP PN not " | ||
| 907 | "sequential A2=%s" | ||
| 908 | " PN=%02x%02x%02x%02x%02x%02x " | ||
| 909 | "(expected %02x%02x%02x%02x%02x%02x)\n", | ||
| 910 | rx->dev->name, print_mac(mac, hdr->addr2), | ||
| 911 | rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], | ||
| 912 | rpn[5], pn[0], pn[1], pn[2], pn[3], | ||
| 913 | pn[4], pn[5]); | ||
| 914 | return RX_DROP_UNUSABLE; | 923 | return RX_DROP_UNUSABLE; |
| 915 | } | ||
| 916 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 924 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
| 917 | } | 925 | } |
| 918 | 926 | ||
| @@ -953,7 +961,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
| 953 | return RX_CONTINUE; | 961 | return RX_CONTINUE; |
| 954 | } | 962 | } |
| 955 | 963 | ||
| 956 | static ieee80211_rx_result | 964 | static ieee80211_rx_result debug_noinline |
| 957 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 965 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
| 958 | { | 966 | { |
| 959 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 967 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
| @@ -988,7 +996,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
| 988 | * Tell TX path to send one frame even though the STA may | 996 | * Tell TX path to send one frame even though the STA may |
| 989 | * still remain is PS mode after this frame exchange. | 997 | * still remain is PS mode after this frame exchange. |
| 990 | */ | 998 | */ |
| 991 | rx->sta->flags |= WLAN_STA_PSPOLL; | 999 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
| 992 | 1000 | ||
| 993 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1001 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| 994 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1002 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", |
| @@ -1016,7 +1024,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
| 1016 | * have nothing buffered for it? | 1024 | * have nothing buffered for it? |
| 1017 | */ | 1025 | */ |
| 1018 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1026 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " |
| 1019 | "though there is no buffered frames for it\n", | 1027 | "though there are no buffered frames for it\n", |
| 1020 | rx->dev->name, print_mac(mac, rx->sta->addr)); | 1028 | rx->dev->name, print_mac(mac, rx->sta->addr)); |
| 1021 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1029 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
| 1022 | } | 1030 | } |
| @@ -1028,22 +1036,22 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
| 1028 | return RX_QUEUED; | 1036 | return RX_QUEUED; |
| 1029 | } | 1037 | } |
| 1030 | 1038 | ||
| 1031 | static ieee80211_rx_result | 1039 | static ieee80211_rx_result debug_noinline |
| 1032 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1040 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
| 1033 | { | 1041 | { |
| 1034 | u16 fc = rx->fc; | ||
| 1035 | u8 *data = rx->skb->data; | 1042 | u8 *data = rx->skb->data; |
| 1036 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data; | 1043 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data; |
| 1037 | 1044 | ||
| 1038 | if (!WLAN_FC_IS_QOS_DATA(fc)) | 1045 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
| 1039 | return RX_CONTINUE; | 1046 | return RX_CONTINUE; |
| 1040 | 1047 | ||
| 1041 | /* remove the qos control field, update frame type and meta-data */ | 1048 | /* remove the qos control field, update frame type and meta-data */ |
| 1042 | memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2); | 1049 | memmove(data + IEEE80211_QOS_CTL_LEN, data, |
| 1043 | hdr = (struct ieee80211_hdr *) skb_pull(rx->skb, 2); | 1050 | ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN); |
| 1051 | hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN); | ||
| 1044 | /* change frame type to non QOS */ | 1052 | /* change frame type to non QOS */ |
| 1045 | rx->fc = fc &= ~IEEE80211_STYPE_QOS_DATA; | 1053 | rx->fc &= ~IEEE80211_STYPE_QOS_DATA; |
| 1046 | hdr->frame_control = cpu_to_le16(fc); | 1054 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); |
| 1047 | 1055 | ||
| 1048 | return RX_CONTINUE; | 1056 | return RX_CONTINUE; |
| 1049 | } | 1057 | } |
| @@ -1051,14 +1059,9 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | |||
| 1051 | static int | 1059 | static int |
| 1052 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1060 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
| 1053 | { | 1061 | { |
| 1054 | if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { | 1062 | if (unlikely(!rx->sta || |
| 1055 | #ifdef CONFIG_MAC80211_DEBUG | 1063 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) |
| 1056 | if (net_ratelimit()) | ||
| 1057 | printk(KERN_DEBUG "%s: dropped frame " | ||
| 1058 | "(unauthorized port)\n", rx->dev->name); | ||
| 1059 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 1060 | return -EACCES; | 1064 | return -EACCES; |
| 1061 | } | ||
| 1062 | 1065 | ||
| 1063 | return 0; | 1066 | return 0; |
| 1064 | } | 1067 | } |
| @@ -1138,16 +1141,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
| 1138 | memcpy(src, hdr->addr2, ETH_ALEN); | 1141 | memcpy(src, hdr->addr2, ETH_ALEN); |
| 1139 | 1142 | ||
| 1140 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && | 1143 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && |
| 1141 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) { | 1144 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) |
| 1142 | if (net_ratelimit()) | ||
| 1143 | printk(KERN_DEBUG "%s: dropped ToDS frame " | ||
| 1144 | "(BSSID=%s SA=%s DA=%s)\n", | ||
| 1145 | dev->name, | ||
| 1146 | print_mac(mac, hdr->addr1), | ||
| 1147 | print_mac(mac2, hdr->addr2), | ||
| 1148 | print_mac(mac3, hdr->addr3)); | ||
| 1149 | return -1; | 1145 | return -1; |
| 1150 | } | ||
| 1151 | break; | 1146 | break; |
| 1152 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | 1147 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): |
| 1153 | /* RA TA DA SA */ | 1148 | /* RA TA DA SA */ |
| @@ -1155,17 +1150,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
| 1155 | memcpy(src, hdr->addr4, ETH_ALEN); | 1150 | memcpy(src, hdr->addr4, ETH_ALEN); |
| 1156 | 1151 | ||
| 1157 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && | 1152 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && |
| 1158 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) { | 1153 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
| 1159 | if (net_ratelimit()) | ||
| 1160 | printk(KERN_DEBUG "%s: dropped FromDS&ToDS " | ||
| 1161 | "frame (RA=%s TA=%s DA=%s SA=%s)\n", | ||
| 1162 | rx->dev->name, | ||
| 1163 | print_mac(mac, hdr->addr1), | ||
| 1164 | print_mac(mac2, hdr->addr2), | ||
| 1165 | print_mac(mac3, hdr->addr3), | ||
| 1166 | print_mac(mac4, hdr->addr4)); | ||
| 1167 | return -1; | 1154 | return -1; |
| 1168 | } | ||
| 1169 | break; | 1155 | break; |
| 1170 | case IEEE80211_FCTL_FROMDS: | 1156 | case IEEE80211_FCTL_FROMDS: |
| 1171 | /* DA BSSID SA */ | 1157 | /* DA BSSID SA */ |
| @@ -1182,27 +1168,13 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
| 1182 | memcpy(dst, hdr->addr1, ETH_ALEN); | 1168 | memcpy(dst, hdr->addr1, ETH_ALEN); |
| 1183 | memcpy(src, hdr->addr2, ETH_ALEN); | 1169 | memcpy(src, hdr->addr2, ETH_ALEN); |
| 1184 | 1170 | ||
| 1185 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1171 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
| 1186 | if (net_ratelimit()) { | ||
| 1187 | printk(KERN_DEBUG "%s: dropped IBSS frame " | ||
| 1188 | "(DA=%s SA=%s BSSID=%s)\n", | ||
| 1189 | dev->name, | ||
| 1190 | print_mac(mac, hdr->addr1), | ||
| 1191 | print_mac(mac2, hdr->addr2), | ||
| 1192 | print_mac(mac3, hdr->addr3)); | ||
| 1193 | } | ||
| 1194 | return -1; | 1172 | return -1; |
| 1195 | } | ||
| 1196 | break; | 1173 | break; |
| 1197 | } | 1174 | } |
| 1198 | 1175 | ||
| 1199 | if (unlikely(skb->len - hdrlen < 8)) { | 1176 | if (unlikely(skb->len - hdrlen < 8)) |
| 1200 | if (net_ratelimit()) { | ||
| 1201 | printk(KERN_DEBUG "%s: RX too short data frame " | ||
| 1202 | "payload\n", dev->name); | ||
| 1203 | } | ||
| 1204 | return -1; | 1177 | return -1; |
| 1205 | } | ||
| 1206 | 1178 | ||
| 1207 | payload = skb->data + hdrlen; | 1179 | payload = skb->data + hdrlen; |
| 1208 | ethertype = (payload[6] << 8) | payload[7]; | 1180 | ethertype = (payload[6] << 8) | payload[7]; |
| @@ -1345,7 +1317,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
| 1345 | } | 1317 | } |
| 1346 | } | 1318 | } |
| 1347 | 1319 | ||
| 1348 | static ieee80211_rx_result | 1320 | static ieee80211_rx_result debug_noinline |
| 1349 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1321 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
| 1350 | { | 1322 | { |
| 1351 | struct net_device *dev = rx->dev; | 1323 | struct net_device *dev = rx->dev; |
| @@ -1394,10 +1366,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
| 1394 | 1366 | ||
| 1395 | padding = ((4 - subframe_len) & 0x3); | 1367 | padding = ((4 - subframe_len) & 0x3); |
| 1396 | /* the last MSDU has no padding */ | 1368 | /* the last MSDU has no padding */ |
| 1397 | if (subframe_len > remaining) { | 1369 | if (subframe_len > remaining) |
| 1398 | printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name); | ||
| 1399 | return RX_DROP_UNUSABLE; | 1370 | return RX_DROP_UNUSABLE; |
| 1400 | } | ||
| 1401 | 1371 | ||
| 1402 | skb_pull(skb, sizeof(struct ethhdr)); | 1372 | skb_pull(skb, sizeof(struct ethhdr)); |
| 1403 | /* if last subframe reuse skb */ | 1373 | /* if last subframe reuse skb */ |
| @@ -1418,8 +1388,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
| 1418 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + | 1388 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + |
| 1419 | padding); | 1389 | padding); |
| 1420 | if (!eth) { | 1390 | if (!eth) { |
| 1421 | printk(KERN_DEBUG "%s: wrong buffer size\n", | ||
| 1422 | dev->name); | ||
| 1423 | dev_kfree_skb(frame); | 1391 | dev_kfree_skb(frame); |
| 1424 | return RX_DROP_UNUSABLE; | 1392 | return RX_DROP_UNUSABLE; |
| 1425 | } | 1393 | } |
| @@ -1462,7 +1430,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
| 1462 | return RX_QUEUED; | 1430 | return RX_QUEUED; |
| 1463 | } | 1431 | } |
| 1464 | 1432 | ||
| 1465 | static ieee80211_rx_result | 1433 | static ieee80211_rx_result debug_noinline |
| 1466 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1434 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
| 1467 | { | 1435 | { |
| 1468 | struct net_device *dev = rx->dev; | 1436 | struct net_device *dev = rx->dev; |
| @@ -1493,21 +1461,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
| 1493 | return RX_QUEUED; | 1461 | return RX_QUEUED; |
| 1494 | } | 1462 | } |
| 1495 | 1463 | ||
| 1496 | static ieee80211_rx_result | 1464 | static ieee80211_rx_result debug_noinline |
| 1497 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 1465 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
| 1498 | { | 1466 | { |
| 1499 | struct ieee80211_local *local = rx->local; | 1467 | struct ieee80211_local *local = rx->local; |
| 1500 | struct ieee80211_hw *hw = &local->hw; | 1468 | struct ieee80211_hw *hw = &local->hw; |
| 1501 | struct sk_buff *skb = rx->skb; | 1469 | struct sk_buff *skb = rx->skb; |
| 1502 | struct ieee80211_bar *bar = (struct ieee80211_bar *) skb->data; | 1470 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
| 1503 | struct tid_ampdu_rx *tid_agg_rx; | 1471 | struct tid_ampdu_rx *tid_agg_rx; |
| 1504 | u16 start_seq_num; | 1472 | u16 start_seq_num; |
| 1505 | u16 tid; | 1473 | u16 tid; |
| 1506 | 1474 | ||
| 1507 | if (likely((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL)) | 1475 | if (likely(!ieee80211_is_ctl(bar->frame_control))) |
| 1508 | return RX_CONTINUE; | 1476 | return RX_CONTINUE; |
| 1509 | 1477 | ||
| 1510 | if ((rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ) { | 1478 | if (ieee80211_is_back_req(bar->frame_control)) { |
| 1511 | if (!rx->sta) | 1479 | if (!rx->sta) |
| 1512 | return RX_CONTINUE; | 1480 | return RX_CONTINUE; |
| 1513 | tid = le16_to_cpu(bar->control) >> 12; | 1481 | tid = le16_to_cpu(bar->control) >> 12; |
| @@ -1537,7 +1505,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
| 1537 | return RX_CONTINUE; | 1505 | return RX_CONTINUE; |
| 1538 | } | 1506 | } |
| 1539 | 1507 | ||
| 1540 | static ieee80211_rx_result | 1508 | static ieee80211_rx_result debug_noinline |
| 1541 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1509 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
| 1542 | { | 1510 | { |
| 1543 | struct ieee80211_sub_if_data *sdata; | 1511 | struct ieee80211_sub_if_data *sdata; |
| @@ -1561,41 +1529,27 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
| 1561 | struct ieee80211_hdr *hdr, | 1529 | struct ieee80211_hdr *hdr, |
| 1562 | struct ieee80211_rx_data *rx) | 1530 | struct ieee80211_rx_data *rx) |
| 1563 | { | 1531 | { |
| 1564 | int keyidx, hdrlen; | 1532 | int keyidx; |
| 1533 | unsigned int hdrlen; | ||
| 1565 | DECLARE_MAC_BUF(mac); | 1534 | DECLARE_MAC_BUF(mac); |
| 1566 | DECLARE_MAC_BUF(mac2); | 1535 | DECLARE_MAC_BUF(mac2); |
| 1567 | 1536 | ||
| 1568 | hdrlen = ieee80211_get_hdrlen_from_skb(rx->skb); | 1537 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 1569 | if (rx->skb->len >= hdrlen + 4) | 1538 | if (rx->skb->len >= hdrlen + 4) |
| 1570 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | 1539 | keyidx = rx->skb->data[hdrlen + 3] >> 6; |
| 1571 | else | 1540 | else |
| 1572 | keyidx = -1; | 1541 | keyidx = -1; |
| 1573 | 1542 | ||
| 1574 | if (net_ratelimit()) | ||
| 1575 | printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC " | ||
| 1576 | "failure from %s to %s keyidx=%d\n", | ||
| 1577 | dev->name, print_mac(mac, hdr->addr2), | ||
| 1578 | print_mac(mac2, hdr->addr1), keyidx); | ||
| 1579 | |||
| 1580 | if (!rx->sta) { | 1543 | if (!rx->sta) { |
| 1581 | /* | 1544 | /* |
| 1582 | * Some hardware seem to generate incorrect Michael MIC | 1545 | * Some hardware seem to generate incorrect Michael MIC |
| 1583 | * reports; ignore them to avoid triggering countermeasures. | 1546 | * reports; ignore them to avoid triggering countermeasures. |
| 1584 | */ | 1547 | */ |
| 1585 | if (net_ratelimit()) | ||
| 1586 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
| 1587 | "error for unknown address %s\n", | ||
| 1588 | dev->name, print_mac(mac, hdr->addr2)); | ||
| 1589 | goto ignore; | 1548 | goto ignore; |
| 1590 | } | 1549 | } |
| 1591 | 1550 | ||
| 1592 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) { | 1551 | if (!ieee80211_has_protected(hdr->frame_control)) |
| 1593 | if (net_ratelimit()) | ||
| 1594 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
| 1595 | "error for a frame with no PROTECTED flag (src " | ||
| 1596 | "%s)\n", dev->name, print_mac(mac, hdr->addr2)); | ||
| 1597 | goto ignore; | 1552 | goto ignore; |
| 1598 | } | ||
| 1599 | 1553 | ||
| 1600 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { | 1554 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { |
| 1601 | /* | 1555 | /* |
| @@ -1604,24 +1558,12 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
| 1604 | * group keys and only the AP is sending real multicast | 1558 | * group keys and only the AP is sending real multicast |
| 1605 | * frames in the BSS. | 1559 | * frames in the BSS. |
| 1606 | */ | 1560 | */ |
| 1607 | if (net_ratelimit()) | ||
| 1608 | printk(KERN_DEBUG "%s: ignored Michael MIC error for " | ||
| 1609 | "a frame with non-zero keyidx (%d)" | ||
| 1610 | " (src %s)\n", dev->name, keyidx, | ||
| 1611 | print_mac(mac, hdr->addr2)); | ||
| 1612 | goto ignore; | 1561 | goto ignore; |
| 1613 | } | 1562 | } |
| 1614 | 1563 | ||
| 1615 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 1564 | if (!ieee80211_is_data(hdr->frame_control) && |
| 1616 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 1565 | !ieee80211_is_auth(hdr->frame_control)) |
| 1617 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) { | ||
| 1618 | if (net_ratelimit()) | ||
| 1619 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
| 1620 | "error for a frame that cannot be encrypted " | ||
| 1621 | "(fc=0x%04x) (src %s)\n", | ||
| 1622 | dev->name, rx->fc, print_mac(mac, hdr->addr2)); | ||
| 1623 | goto ignore; | 1566 | goto ignore; |
| 1624 | } | ||
| 1625 | 1567 | ||
| 1626 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); | 1568 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); |
| 1627 | ignore: | 1569 | ignore: |
| @@ -1710,67 +1652,57 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
| 1710 | dev_kfree_skb(skb); | 1652 | dev_kfree_skb(skb); |
| 1711 | } | 1653 | } |
| 1712 | 1654 | ||
| 1713 | typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *); | ||
| 1714 | static ieee80211_rx_handler ieee80211_rx_handlers[] = | ||
| 1715 | { | ||
| 1716 | ieee80211_rx_h_if_stats, | ||
| 1717 | ieee80211_rx_h_passive_scan, | ||
| 1718 | ieee80211_rx_h_check, | ||
| 1719 | ieee80211_rx_h_decrypt, | ||
| 1720 | ieee80211_rx_h_sta_process, | ||
| 1721 | ieee80211_rx_h_defragment, | ||
| 1722 | ieee80211_rx_h_ps_poll, | ||
| 1723 | ieee80211_rx_h_michael_mic_verify, | ||
| 1724 | /* this must be after decryption - so header is counted in MPDU mic | ||
| 1725 | * must be before pae and data, so QOS_DATA format frames | ||
| 1726 | * are not passed to user space by these functions | ||
| 1727 | */ | ||
| 1728 | ieee80211_rx_h_remove_qos_control, | ||
| 1729 | ieee80211_rx_h_amsdu, | ||
| 1730 | ieee80211_rx_h_data, | ||
| 1731 | ieee80211_rx_h_ctrl, | ||
| 1732 | ieee80211_rx_h_mgmt, | ||
| 1733 | NULL | ||
| 1734 | }; | ||
| 1735 | 1655 | ||
| 1736 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1656 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
| 1737 | struct ieee80211_rx_data *rx, | 1657 | struct ieee80211_rx_data *rx, |
| 1738 | struct sk_buff *skb) | 1658 | struct sk_buff *skb) |
| 1739 | { | 1659 | { |
| 1740 | ieee80211_rx_handler *handler; | ||
| 1741 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1660 | ieee80211_rx_result res = RX_DROP_MONITOR; |
| 1742 | 1661 | ||
| 1743 | rx->skb = skb; | 1662 | rx->skb = skb; |
| 1744 | rx->sdata = sdata; | 1663 | rx->sdata = sdata; |
| 1745 | rx->dev = sdata->dev; | 1664 | rx->dev = sdata->dev; |
| 1746 | 1665 | ||
| 1747 | for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { | 1666 | #define CALL_RXH(rxh) \ |
| 1748 | res = (*handler)(rx); | 1667 | res = rxh(rx); \ |
| 1749 | 1668 | if (res != RX_CONTINUE) \ | |
| 1750 | switch (res) { | 1669 | goto rxh_done; |
| 1751 | case RX_CONTINUE: | 1670 | |
| 1752 | continue; | 1671 | CALL_RXH(ieee80211_rx_h_passive_scan) |
| 1753 | case RX_DROP_UNUSABLE: | 1672 | CALL_RXH(ieee80211_rx_h_check) |
| 1754 | case RX_DROP_MONITOR: | 1673 | CALL_RXH(ieee80211_rx_h_decrypt) |
| 1755 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1674 | CALL_RXH(ieee80211_rx_h_sta_process) |
| 1756 | if (rx->sta) | 1675 | CALL_RXH(ieee80211_rx_h_defragment) |
| 1757 | rx->sta->rx_dropped++; | 1676 | CALL_RXH(ieee80211_rx_h_ps_poll) |
| 1758 | break; | 1677 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
| 1759 | case RX_QUEUED: | 1678 | /* must be after MMIC verify so header is counted in MPDU mic */ |
| 1760 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 1679 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
| 1761 | break; | 1680 | CALL_RXH(ieee80211_rx_h_amsdu) |
| 1762 | } | 1681 | CALL_RXH(ieee80211_rx_h_data) |
| 1763 | break; | 1682 | CALL_RXH(ieee80211_rx_h_ctrl) |
| 1764 | } | 1683 | CALL_RXH(ieee80211_rx_h_mgmt) |
| 1765 | 1684 | ||
| 1685 | #undef CALL_RXH | ||
| 1686 | |||
| 1687 | rxh_done: | ||
| 1766 | switch (res) { | 1688 | switch (res) { |
| 1767 | case RX_CONTINUE: | ||
| 1768 | case RX_DROP_MONITOR: | 1689 | case RX_DROP_MONITOR: |
| 1690 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
| 1691 | if (rx->sta) | ||
| 1692 | rx->sta->rx_dropped++; | ||
| 1693 | /* fall through */ | ||
| 1694 | case RX_CONTINUE: | ||
| 1769 | ieee80211_rx_cooked_monitor(rx); | 1695 | ieee80211_rx_cooked_monitor(rx); |
| 1770 | break; | 1696 | break; |
| 1771 | case RX_DROP_UNUSABLE: | 1697 | case RX_DROP_UNUSABLE: |
| 1698 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
| 1699 | if (rx->sta) | ||
| 1700 | rx->sta->rx_dropped++; | ||
| 1772 | dev_kfree_skb(rx->skb); | 1701 | dev_kfree_skb(rx->skb); |
| 1773 | break; | 1702 | break; |
| 1703 | case RX_QUEUED: | ||
| 1704 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | ||
| 1705 | break; | ||
| 1774 | } | 1706 | } |
| 1775 | } | 1707 | } |
| 1776 | 1708 | ||
| @@ -1801,9 +1733,13 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
| 1801 | case IEEE80211_IF_TYPE_IBSS: | 1733 | case IEEE80211_IF_TYPE_IBSS: |
| 1802 | if (!bssid) | 1734 | if (!bssid) |
| 1803 | return 0; | 1735 | return 0; |
| 1804 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && | 1736 | if (ieee80211_is_beacon(hdr->frame_control)) { |
| 1805 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) | 1737 | if (!rx->sta) |
| 1738 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, | ||
| 1739 | rx->skb, bssid, hdr->addr2, | ||
| 1740 | BIT(rx->status->rate_idx)); | ||
| 1806 | return 1; | 1741 | return 1; |
| 1742 | } | ||
| 1807 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | 1743 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { |
| 1808 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 1744 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) |
| 1809 | return 0; | 1745 | return 0; |
| @@ -1816,7 +1752,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
| 1816 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1752 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
| 1817 | } else if (!rx->sta) | 1753 | } else if (!rx->sta) |
| 1818 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, | 1754 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, |
| 1819 | bssid, hdr->addr2); | 1755 | bssid, hdr->addr2, |
| 1756 | BIT(rx->status->rate_idx)); | ||
| 1820 | break; | 1757 | break; |
| 1821 | case IEEE80211_IF_TYPE_MESH_POINT: | 1758 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 1822 | if (!multicast && | 1759 | if (!multicast && |
| @@ -1840,15 +1777,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
| 1840 | return 0; | 1777 | return 0; |
| 1841 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1778 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
| 1842 | } | 1779 | } |
| 1843 | if (sdata->dev == sdata->local->mdev && | ||
| 1844 | !(rx->flags & IEEE80211_RX_IN_SCAN)) | ||
| 1845 | /* do not receive anything via | ||
| 1846 | * master device when not scanning */ | ||
| 1847 | return 0; | ||
| 1848 | break; | 1780 | break; |
| 1849 | case IEEE80211_IF_TYPE_WDS: | 1781 | case IEEE80211_IF_TYPE_WDS: |
| 1850 | if (bssid || | 1782 | if (bssid || !ieee80211_is_data(hdr->frame_control)) |
| 1851 | (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | ||
| 1852 | return 0; | 1783 | return 0; |
| 1853 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) | 1784 | if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) |
| 1854 | return 0; | 1785 | return 0; |
| @@ -1872,7 +1803,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
| 1872 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 1803 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
| 1873 | struct sk_buff *skb, | 1804 | struct sk_buff *skb, |
| 1874 | struct ieee80211_rx_status *status, | 1805 | struct ieee80211_rx_status *status, |
| 1875 | u32 load, | ||
| 1876 | struct ieee80211_rate *rate) | 1806 | struct ieee80211_rate *rate) |
| 1877 | { | 1807 | { |
| 1878 | struct ieee80211_local *local = hw_to_local(hw); | 1808 | struct ieee80211_local *local = hw_to_local(hw); |
| @@ -1891,7 +1821,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
| 1891 | rx.local = local; | 1821 | rx.local = local; |
| 1892 | 1822 | ||
| 1893 | rx.status = status; | 1823 | rx.status = status; |
| 1894 | rx.load = load; | ||
| 1895 | rx.rate = rate; | 1824 | rx.rate = rate; |
| 1896 | rx.fc = le16_to_cpu(hdr->frame_control); | 1825 | rx.fc = le16_to_cpu(hdr->frame_control); |
| 1897 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1826 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
| @@ -2000,7 +1929,6 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
| 2000 | struct ieee80211_rx_status status; | 1929 | struct ieee80211_rx_status status; |
| 2001 | u16 head_seq_num, buf_size; | 1930 | u16 head_seq_num, buf_size; |
| 2002 | int index; | 1931 | int index; |
| 2003 | u32 pkt_load; | ||
| 2004 | struct ieee80211_supported_band *sband; | 1932 | struct ieee80211_supported_band *sband; |
| 2005 | struct ieee80211_rate *rate; | 1933 | struct ieee80211_rate *rate; |
| 2006 | 1934 | ||
| @@ -2035,12 +1963,9 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
| 2035 | sizeof(status)); | 1963 | sizeof(status)); |
| 2036 | sband = local->hw.wiphy->bands[status.band]; | 1964 | sband = local->hw.wiphy->bands[status.band]; |
| 2037 | rate = &sband->bitrates[status.rate_idx]; | 1965 | rate = &sband->bitrates[status.rate_idx]; |
| 2038 | pkt_load = ieee80211_rx_load_stats(local, | ||
| 2039 | tid_agg_rx->reorder_buf[index], | ||
| 2040 | &status, rate); | ||
| 2041 | __ieee80211_rx_handle_packet(hw, | 1966 | __ieee80211_rx_handle_packet(hw, |
| 2042 | tid_agg_rx->reorder_buf[index], | 1967 | tid_agg_rx->reorder_buf[index], |
| 2043 | &status, pkt_load, rate); | 1968 | &status, rate); |
| 2044 | tid_agg_rx->stored_mpdu_num--; | 1969 | tid_agg_rx->stored_mpdu_num--; |
| 2045 | tid_agg_rx->reorder_buf[index] = NULL; | 1970 | tid_agg_rx->reorder_buf[index] = NULL; |
| 2046 | } | 1971 | } |
| @@ -2082,11 +2007,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
| 2082 | sizeof(status)); | 2007 | sizeof(status)); |
| 2083 | sband = local->hw.wiphy->bands[status.band]; | 2008 | sband = local->hw.wiphy->bands[status.band]; |
| 2084 | rate = &sband->bitrates[status.rate_idx]; | 2009 | rate = &sband->bitrates[status.rate_idx]; |
| 2085 | pkt_load = ieee80211_rx_load_stats(local, | ||
| 2086 | tid_agg_rx->reorder_buf[index], | ||
| 2087 | &status, rate); | ||
| 2088 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 2010 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
| 2089 | &status, pkt_load, rate); | 2011 | &status, rate); |
| 2090 | tid_agg_rx->stored_mpdu_num--; | 2012 | tid_agg_rx->stored_mpdu_num--; |
| 2091 | tid_agg_rx->reorder_buf[index] = NULL; | 2013 | tid_agg_rx->reorder_buf[index] = NULL; |
| 2092 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 2014 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
| @@ -2103,32 +2025,29 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
| 2103 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2025 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 2104 | struct sta_info *sta; | 2026 | struct sta_info *sta; |
| 2105 | struct tid_ampdu_rx *tid_agg_rx; | 2027 | struct tid_ampdu_rx *tid_agg_rx; |
| 2106 | u16 fc, sc; | 2028 | u16 sc; |
| 2107 | u16 mpdu_seq_num; | 2029 | u16 mpdu_seq_num; |
| 2108 | u8 ret = 0, *qc; | 2030 | u8 ret = 0; |
| 2109 | int tid; | 2031 | int tid; |
| 2110 | 2032 | ||
| 2111 | sta = sta_info_get(local, hdr->addr2); | 2033 | sta = sta_info_get(local, hdr->addr2); |
| 2112 | if (!sta) | 2034 | if (!sta) |
| 2113 | return ret; | 2035 | return ret; |
| 2114 | 2036 | ||
| 2115 | fc = le16_to_cpu(hdr->frame_control); | ||
| 2116 | |||
| 2117 | /* filter the QoS data rx stream according to | 2037 | /* filter the QoS data rx stream according to |
| 2118 | * STA/TID and check if this STA/TID is on aggregation */ | 2038 | * STA/TID and check if this STA/TID is on aggregation */ |
| 2119 | if (!WLAN_FC_IS_QOS_DATA(fc)) | 2039 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
| 2120 | goto end_reorder; | 2040 | goto end_reorder; |
| 2121 | 2041 | ||
| 2122 | qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN; | 2042 | tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; |
| 2123 | tid = qc[0] & QOS_CONTROL_TID_MASK; | ||
| 2124 | 2043 | ||
| 2125 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) | 2044 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) |
| 2126 | goto end_reorder; | 2045 | goto end_reorder; |
| 2127 | 2046 | ||
| 2128 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 2047 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
| 2129 | 2048 | ||
| 2130 | /* null data frames are excluded */ | 2049 | /* qos null data frames are excluded */ |
| 2131 | if (unlikely(fc & IEEE80211_STYPE_NULLFUNC)) | 2050 | if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) |
| 2132 | goto end_reorder; | 2051 | goto end_reorder; |
| 2133 | 2052 | ||
| 2134 | /* new un-ordered ampdu frame - process it */ | 2053 | /* new un-ordered ampdu frame - process it */ |
| @@ -2165,7 +2084,6 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2165 | struct ieee80211_rx_status *status) | 2084 | struct ieee80211_rx_status *status) |
| 2166 | { | 2085 | { |
| 2167 | struct ieee80211_local *local = hw_to_local(hw); | 2086 | struct ieee80211_local *local = hw_to_local(hw); |
| 2168 | u32 pkt_load; | ||
| 2169 | struct ieee80211_rate *rate = NULL; | 2087 | struct ieee80211_rate *rate = NULL; |
| 2170 | struct ieee80211_supported_band *sband; | 2088 | struct ieee80211_supported_band *sband; |
| 2171 | 2089 | ||
| @@ -2205,11 +2123,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
| 2205 | return; | 2123 | return; |
| 2206 | } | 2124 | } |
| 2207 | 2125 | ||
| 2208 | pkt_load = ieee80211_rx_load_stats(local, skb, status, rate); | ||
| 2209 | local->channel_use_raw += pkt_load; | ||
| 2210 | |||
| 2211 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2126 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
| 2212 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); | 2127 | __ieee80211_rx_handle_packet(hw, skb, status, rate); |
| 2213 | 2128 | ||
| 2214 | rcu_read_unlock(); | 2129 | rcu_read_unlock(); |
| 2215 | } | 2130 | } |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 7d4fe4a52929..f2ba653b9d69 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -135,6 +135,7 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, | |||
| 135 | /** | 135 | /** |
| 136 | * __sta_info_free - internal STA free helper | 136 | * __sta_info_free - internal STA free helper |
| 137 | * | 137 | * |
| 138 | * @local: pointer to the global information | ||
| 138 | * @sta: STA info to free | 139 | * @sta: STA info to free |
| 139 | * | 140 | * |
| 140 | * This function must undo everything done by sta_info_alloc() | 141 | * This function must undo everything done by sta_info_alloc() |
| @@ -202,14 +203,12 @@ void sta_info_destroy(struct sta_info *sta) | |||
| 202 | dev_kfree_skb_any(skb); | 203 | dev_kfree_skb_any(skb); |
| 203 | 204 | ||
| 204 | for (i = 0; i < STA_TID_NUM; i++) { | 205 | for (i = 0; i < STA_TID_NUM; i++) { |
| 205 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 206 | spin_lock_bh(&sta->lock); |
| 206 | if (sta->ampdu_mlme.tid_rx[i]) | 207 | if (sta->ampdu_mlme.tid_rx[i]) |
| 207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); | 208 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); |
| 208 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | ||
| 209 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
| 210 | if (sta->ampdu_mlme.tid_tx[i]) | 209 | if (sta->ampdu_mlme.tid_tx[i]) |
| 211 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); | 210 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); |
| 212 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 211 | spin_unlock_bh(&sta->lock); |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | __sta_info_free(local, sta); | 214 | __sta_info_free(local, sta); |
| @@ -236,6 +235,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 236 | if (!sta) | 235 | if (!sta) |
| 237 | return NULL; | 236 | return NULL; |
| 238 | 237 | ||
| 238 | spin_lock_init(&sta->lock); | ||
| 239 | spin_lock_init(&sta->flaglock); | ||
| 240 | |||
| 239 | memcpy(sta->addr, addr, ETH_ALEN); | 241 | memcpy(sta->addr, addr, ETH_ALEN); |
| 240 | sta->local = local; | 242 | sta->local = local; |
| 241 | sta->sdata = sdata; | 243 | sta->sdata = sdata; |
| @@ -249,15 +251,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 249 | return NULL; | 251 | return NULL; |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | ||
| 253 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
| 254 | for (i = 0; i < STA_TID_NUM; i++) { | 254 | for (i = 0; i < STA_TID_NUM; i++) { |
| 255 | /* timer_to_tid must be initialized with identity mapping to | 255 | /* timer_to_tid must be initialized with identity mapping to |
| 256 | * enable session_timer's data differentiation. refer to | 256 | * enable session_timer's data differentiation. refer to |
| 257 | * sta_rx_agg_session_timer_expired for useage */ | 257 | * sta_rx_agg_session_timer_expired for useage */ |
| 258 | sta->timer_to_tid[i] = i; | 258 | sta->timer_to_tid[i] = i; |
| 259 | /* tid to tx queue: initialize according to HW (0 is valid) */ | 259 | /* tid to tx queue: initialize according to HW (0 is valid) */ |
| 260 | sta->tid_to_tx_q[i] = local->hw.queues; | 260 | sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw); |
| 261 | /* rx */ | 261 | /* rx */ |
| 262 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; | 262 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; |
| 263 | sta->ampdu_mlme.tid_rx[i] = NULL; | 263 | sta->ampdu_mlme.tid_rx[i] = NULL; |
| @@ -276,7 +276,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 276 | 276 | ||
| 277 | #ifdef CONFIG_MAC80211_MESH | 277 | #ifdef CONFIG_MAC80211_MESH |
| 278 | sta->plink_state = PLINK_LISTEN; | 278 | sta->plink_state = PLINK_LISTEN; |
| 279 | spin_lock_init(&sta->plink_lock); | ||
| 280 | init_timer(&sta->plink_timer); | 279 | init_timer(&sta->plink_timer); |
| 281 | #endif | 280 | #endif |
| 282 | 281 | ||
| @@ -321,7 +320,9 @@ int sta_info_insert(struct sta_info *sta) | |||
| 321 | /* notify driver */ | 320 | /* notify driver */ |
| 322 | if (local->ops->sta_notify) { | 321 | if (local->ops->sta_notify) { |
| 323 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 322 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
| 324 | sdata = sdata->u.vlan.ap; | 323 | sdata = container_of(sdata->bss, |
| 324 | struct ieee80211_sub_if_data, | ||
| 325 | u.ap); | ||
| 325 | 326 | ||
| 326 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 327 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
| 327 | STA_NOTIFY_ADD, sta->addr); | 328 | STA_NOTIFY_ADD, sta->addr); |
| @@ -376,8 +377,10 @@ static inline void __bss_tim_clear(struct ieee80211_if_ap *bss, u16 aid) | |||
| 376 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, | 377 | static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss, |
| 377 | struct sta_info *sta) | 378 | struct sta_info *sta) |
| 378 | { | 379 | { |
| 379 | if (bss) | 380 | BUG_ON(!bss); |
| 380 | __bss_tim_set(bss, sta->aid); | 381 | |
| 382 | __bss_tim_set(bss, sta->aid); | ||
| 383 | |||
| 381 | if (sta->local->ops->set_tim) { | 384 | if (sta->local->ops->set_tim) { |
| 382 | sta->local->tim_in_locked_section = true; | 385 | sta->local->tim_in_locked_section = true; |
| 383 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); | 386 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); |
| @@ -389,6 +392,8 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
| 389 | { | 392 | { |
| 390 | unsigned long flags; | 393 | unsigned long flags; |
| 391 | 394 | ||
| 395 | BUG_ON(!sta->sdata->bss); | ||
| 396 | |||
| 392 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 397 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
| 393 | __sta_info_set_tim_bit(sta->sdata->bss, sta); | 398 | __sta_info_set_tim_bit(sta->sdata->bss, sta); |
| 394 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 399 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
| @@ -397,8 +402,10 @@ void sta_info_set_tim_bit(struct sta_info *sta) | |||
| 397 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, | 402 | static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss, |
| 398 | struct sta_info *sta) | 403 | struct sta_info *sta) |
| 399 | { | 404 | { |
| 400 | if (bss) | 405 | BUG_ON(!bss); |
| 401 | __bss_tim_clear(bss, sta->aid); | 406 | |
| 407 | __bss_tim_clear(bss, sta->aid); | ||
| 408 | |||
| 402 | if (sta->local->ops->set_tim) { | 409 | if (sta->local->ops->set_tim) { |
| 403 | sta->local->tim_in_locked_section = true; | 410 | sta->local->tim_in_locked_section = true; |
| 404 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); | 411 | sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); |
| @@ -410,6 +417,8 @@ void sta_info_clear_tim_bit(struct sta_info *sta) | |||
| 410 | { | 417 | { |
| 411 | unsigned long flags; | 418 | unsigned long flags; |
| 412 | 419 | ||
| 420 | BUG_ON(!sta->sdata->bss); | ||
| 421 | |||
| 413 | spin_lock_irqsave(&sta->local->sta_lock, flags); | 422 | spin_lock_irqsave(&sta->local->sta_lock, flags); |
| 414 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); | 423 | __sta_info_clear_tim_bit(sta->sdata->bss, sta); |
| 415 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); | 424 | spin_unlock_irqrestore(&sta->local->sta_lock, flags); |
| @@ -437,10 +446,10 @@ void __sta_info_unlink(struct sta_info **sta) | |||
| 437 | 446 | ||
| 438 | list_del(&(*sta)->list); | 447 | list_del(&(*sta)->list); |
| 439 | 448 | ||
| 440 | if ((*sta)->flags & WLAN_STA_PS) { | 449 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
| 441 | (*sta)->flags &= ~WLAN_STA_PS; | 450 | BUG_ON(!sdata->bss); |
| 442 | if (sdata->bss) | 451 | |
| 443 | atomic_dec(&sdata->bss->num_sta_ps); | 452 | atomic_dec(&sdata->bss->num_sta_ps); |
| 444 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 453 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
| 445 | } | 454 | } |
| 446 | 455 | ||
| @@ -448,7 +457,9 @@ void __sta_info_unlink(struct sta_info **sta) | |||
| 448 | 457 | ||
| 449 | if (local->ops->sta_notify) { | 458 | if (local->ops->sta_notify) { |
| 450 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) | 459 | if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) |
| 451 | sdata = sdata->u.vlan.ap; | 460 | sdata = container_of(sdata->bss, |
| 461 | struct ieee80211_sub_if_data, | ||
| 462 | u.ap); | ||
| 452 | 463 | ||
| 453 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, | 464 | local->ops->sta_notify(local_to_hw(local), &sdata->vif, |
| 454 | STA_NOTIFY_REMOVE, (*sta)->addr); | 465 | STA_NOTIFY_REMOVE, (*sta)->addr); |
| @@ -515,20 +526,20 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local, | |||
| 515 | struct sta_info *sta, | 526 | struct sta_info *sta, |
| 516 | struct sk_buff *skb) | 527 | struct sk_buff *skb) |
| 517 | { | 528 | { |
| 518 | struct ieee80211_tx_packet_data *pkt_data; | 529 | struct ieee80211_tx_info *info; |
| 519 | int timeout; | 530 | int timeout; |
| 520 | 531 | ||
| 521 | if (!skb) | 532 | if (!skb) |
| 522 | return 0; | 533 | return 0; |
| 523 | 534 | ||
| 524 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 535 | info = IEEE80211_SKB_CB(skb); |
| 525 | 536 | ||
| 526 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ | 537 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ |
| 527 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / | 538 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / |
| 528 | 15625) * HZ; | 539 | 15625) * HZ; |
| 529 | if (timeout < STA_TX_BUFFER_EXPIRE) | 540 | if (timeout < STA_TX_BUFFER_EXPIRE) |
| 530 | timeout = STA_TX_BUFFER_EXPIRE; | 541 | timeout = STA_TX_BUFFER_EXPIRE; |
| 531 | return time_after(jiffies, pkt_data->jiffies + timeout); | 542 | return time_after(jiffies, info->control.jiffies + timeout); |
| 532 | } | 543 | } |
| 533 | 544 | ||
| 534 | 545 | ||
| @@ -557,8 +568,10 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
| 557 | 568 | ||
| 558 | sdata = sta->sdata; | 569 | sdata = sta->sdata; |
| 559 | local->total_ps_buffered--; | 570 | local->total_ps_buffered--; |
| 571 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
| 560 | printk(KERN_DEBUG "Buffered frame expired (STA " | 572 | printk(KERN_DEBUG "Buffered frame expired (STA " |
| 561 | "%s)\n", print_mac(mac, sta->addr)); | 573 | "%s)\n", print_mac(mac, sta->addr)); |
| 574 | #endif | ||
| 562 | dev_kfree_skb(skb); | 575 | dev_kfree_skb(skb); |
| 563 | 576 | ||
| 564 | if (skb_queue_empty(&sta->ps_tx_buf)) | 577 | if (skb_queue_empty(&sta->ps_tx_buf)) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index f8c95bc9659c..109db787ccb7 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | * @WLAN_STA_WDS: Station is one of our WDS peers. | 32 | * @WLAN_STA_WDS: Station is one of our WDS peers. |
| 33 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. | 33 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. |
| 34 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the | 34 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the |
| 35 | * IEEE80211_TXCTL_CLEAR_PS_FILT control flag) when the next | 35 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next |
| 36 | * frame to this station is transmitted. | 36 | * frame to this station is transmitted. |
| 37 | */ | 37 | */ |
| 38 | enum ieee80211_sta_info_flags { | 38 | enum ieee80211_sta_info_flags { |
| @@ -129,23 +129,19 @@ enum plink_state { | |||
| 129 | * | 129 | * |
| 130 | * @tid_state_rx: TID's state in Rx session state machine. | 130 | * @tid_state_rx: TID's state in Rx session state machine. |
| 131 | * @tid_rx: aggregation info for Rx per TID | 131 | * @tid_rx: aggregation info for Rx per TID |
| 132 | * @ampdu_rx: for locking sections in aggregation Rx flow | ||
| 133 | * @tid_state_tx: TID's state in Tx session state machine. | 132 | * @tid_state_tx: TID's state in Tx session state machine. |
| 134 | * @tid_tx: aggregation info for Tx per TID | 133 | * @tid_tx: aggregation info for Tx per TID |
| 135 | * @addba_req_num: number of times addBA request has been sent. | 134 | * @addba_req_num: number of times addBA request has been sent. |
| 136 | * @ampdu_tx: for locking sectionsi in aggregation Tx flow | ||
| 137 | * @dialog_token_allocator: dialog token enumerator for each new session; | 135 | * @dialog_token_allocator: dialog token enumerator for each new session; |
| 138 | */ | 136 | */ |
| 139 | struct sta_ampdu_mlme { | 137 | struct sta_ampdu_mlme { |
| 140 | /* rx */ | 138 | /* rx */ |
| 141 | u8 tid_state_rx[STA_TID_NUM]; | 139 | u8 tid_state_rx[STA_TID_NUM]; |
| 142 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 140 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
| 143 | spinlock_t ampdu_rx; | ||
| 144 | /* tx */ | 141 | /* tx */ |
| 145 | u8 tid_state_tx[STA_TID_NUM]; | 142 | u8 tid_state_tx[STA_TID_NUM]; |
| 146 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | 143 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; |
| 147 | u8 addba_req_num[STA_TID_NUM]; | 144 | u8 addba_req_num[STA_TID_NUM]; |
| 148 | spinlock_t ampdu_tx; | ||
| 149 | u8 dialog_token_allocator; | 145 | u8 dialog_token_allocator; |
| 150 | }; | 146 | }; |
| 151 | 147 | ||
| @@ -164,9 +160,20 @@ struct sta_ampdu_mlme { | |||
| 164 | * @list: global linked list entry | 160 | * @list: global linked list entry |
| 165 | * @hnext: hash table linked list pointer | 161 | * @hnext: hash table linked list pointer |
| 166 | * @local: pointer to the global information | 162 | * @local: pointer to the global information |
| 163 | * @sdata: TBD | ||
| 164 | * @key: TBD | ||
| 165 | * @rate_ctrl: TBD | ||
| 166 | * @rate_ctrl_priv: TBD | ||
| 167 | * @lock: used for locking all fields that require locking, see comments | ||
| 168 | * in the header file. | ||
| 169 | * @flaglock: spinlock for flags accesses | ||
| 170 | * @ht_info: HT capabilities of this STA | ||
| 171 | * @supp_rates: Bitmap of supported rates (per band) | ||
| 167 | * @addr: MAC address of this STA | 172 | * @addr: MAC address of this STA |
| 168 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), | 173 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), |
| 169 | * only used in AP (and IBSS?) mode | 174 | * only used in AP (and IBSS?) mode |
| 175 | * @listen_interval: TBD | ||
| 176 | * @pin_status: TBD | ||
| 170 | * @flags: STA flags, see &enum ieee80211_sta_info_flags | 177 | * @flags: STA flags, see &enum ieee80211_sta_info_flags |
| 171 | * @ps_tx_buf: buffer of frames to transmit to this station | 178 | * @ps_tx_buf: buffer of frames to transmit to this station |
| 172 | * when it leaves power saving state | 179 | * when it leaves power saving state |
| @@ -175,8 +182,41 @@ struct sta_ampdu_mlme { | |||
| 175 | * power saving state | 182 | * power saving state |
| 176 | * @rx_packets: Number of MSDUs received from this STA | 183 | * @rx_packets: Number of MSDUs received from this STA |
| 177 | * @rx_bytes: Number of bytes received from this STA | 184 | * @rx_bytes: Number of bytes received from this STA |
| 178 | * @supp_rates: Bitmap of supported rates (per band) | 185 | * @wep_weak_iv_count: TBD |
| 179 | * @ht_info: HT capabilities of this STA | 186 | * @last_rx: TBD |
| 187 | * @num_duplicates: number of duplicate frames received from this STA | ||
| 188 | * @rx_fragments: number of received MPDUs | ||
| 189 | * @rx_dropped: number of dropped MPDUs from this STA | ||
| 190 | * @last_signal: signal of last received frame from this STA | ||
| 191 | * @last_qual: qual of last received frame from this STA | ||
| 192 | * @last_noise: noise of last received frame from this STA | ||
| 193 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) | ||
| 194 | * @wme_rx_queue: TBD | ||
| 195 | * @tx_filtered_count: TBD | ||
| 196 | * @tx_retry_failed: TBD | ||
| 197 | * @tx_retry_count: TBD | ||
| 198 | * @tx_num_consecutive_failures: TBD | ||
| 199 | * @tx_num_mpdu_ok: TBD | ||
| 200 | * @tx_num_mpdu_fail: TBD | ||
| 201 | * @fail_avg: moving percentage of failed MSDUs | ||
| 202 | * @tx_packets: number of RX/TX MSDUs | ||
| 203 | * @tx_bytes: TBD | ||
| 204 | * @tx_fragments: number of transmitted MPDUs | ||
| 205 | * @txrate_idx: TBD | ||
| 206 | * @last_txrate_idx: TBD | ||
| 207 | * @wme_tx_queue: TBD | ||
| 208 | * @ampdu_mlme: TBD | ||
| 209 | * @timer_to_tid: identity mapping to ID timers | ||
| 210 | * @tid_to_tx_q: map tid to tx queue | ||
| 211 | * @llid: Local link ID | ||
| 212 | * @plid: Peer link ID | ||
| 213 | * @reason: Cancel reason on PLINK_HOLDING state | ||
| 214 | * @plink_retries: Retries in establishment | ||
| 215 | * @ignore_plink_timer: TBD | ||
| 216 | * @plink_state plink_state: TBD | ||
| 217 | * @plink_timeout: TBD | ||
| 218 | * @plink_timer: TBD | ||
| 219 | * @debugfs: debug filesystem info | ||
| 180 | */ | 220 | */ |
| 181 | struct sta_info { | 221 | struct sta_info { |
| 182 | /* General information, mostly static */ | 222 | /* General information, mostly static */ |
| @@ -187,6 +227,8 @@ struct sta_info { | |||
| 187 | struct ieee80211_key *key; | 227 | struct ieee80211_key *key; |
| 188 | struct rate_control_ref *rate_ctrl; | 228 | struct rate_control_ref *rate_ctrl; |
| 189 | void *rate_ctrl_priv; | 229 | void *rate_ctrl_priv; |
| 230 | spinlock_t lock; | ||
| 231 | spinlock_t flaglock; | ||
| 190 | struct ieee80211_ht_info ht_info; | 232 | struct ieee80211_ht_info ht_info; |
| 191 | u64 supp_rates[IEEE80211_NUM_BANDS]; | 233 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
| 192 | u8 addr[ETH_ALEN]; | 234 | u8 addr[ETH_ALEN]; |
| @@ -199,7 +241,10 @@ struct sta_info { | |||
| 199 | */ | 241 | */ |
| 200 | u8 pin_status; | 242 | u8 pin_status; |
| 201 | 243 | ||
| 202 | /* frequently updated information, needs locking? */ | 244 | /* |
| 245 | * frequently updated, locked with own spinlock (flaglock), | ||
| 246 | * use the accessors defined below | ||
| 247 | */ | ||
| 203 | u32 flags; | 248 | u32 flags; |
| 204 | 249 | ||
| 205 | /* | 250 | /* |
| @@ -213,14 +258,12 @@ struct sta_info { | |||
| 213 | unsigned long rx_packets, rx_bytes; | 258 | unsigned long rx_packets, rx_bytes; |
| 214 | unsigned long wep_weak_iv_count; | 259 | unsigned long wep_weak_iv_count; |
| 215 | unsigned long last_rx; | 260 | unsigned long last_rx; |
| 216 | unsigned long num_duplicates; /* number of duplicate frames received | 261 | unsigned long num_duplicates; |
| 217 | * from this STA */ | 262 | unsigned long rx_fragments; |
| 218 | unsigned long rx_fragments; /* number of received MPDUs */ | 263 | unsigned long rx_dropped; |
| 219 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ | 264 | int last_signal; |
| 220 | int last_rssi; /* RSSI of last received frame from this STA */ | 265 | int last_qual; |
| 221 | int last_signal; /* signal of last received frame from this STA */ | 266 | int last_noise; |
| 222 | int last_noise; /* noise of last received frame from this STA */ | ||
| 223 | /* last received seq/frag number from this STA (per RX queue) */ | ||
| 224 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 267 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; |
| 225 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 268 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
| 226 | unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; | 269 | unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; |
| @@ -237,42 +280,36 @@ struct sta_info { | |||
| 237 | unsigned int fail_avg; | 280 | unsigned int fail_avg; |
| 238 | 281 | ||
| 239 | /* Updated from TX path only, no locking requirements */ | 282 | /* Updated from TX path only, no locking requirements */ |
| 240 | unsigned long tx_packets; /* number of RX/TX MSDUs */ | 283 | unsigned long tx_packets; |
| 241 | unsigned long tx_bytes; | 284 | unsigned long tx_bytes; |
| 242 | unsigned long tx_fragments; /* number of transmitted MPDUs */ | 285 | unsigned long tx_fragments; |
| 243 | int txrate_idx; | 286 | int txrate_idx; |
| 244 | int last_txrate_idx; | 287 | int last_txrate_idx; |
| 288 | u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; | ||
| 245 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 289 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
| 246 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; | 290 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; |
| 247 | #endif | 291 | #endif |
| 248 | 292 | ||
| 249 | /* Debug counters, no locking doesn't matter */ | ||
| 250 | int channel_use; | ||
| 251 | int channel_use_raw; | ||
| 252 | |||
| 253 | /* | 293 | /* |
| 254 | * Aggregation information, comes with own locking. | 294 | * Aggregation information, locked with lock. |
| 255 | */ | 295 | */ |
| 256 | struct sta_ampdu_mlme ampdu_mlme; | 296 | struct sta_ampdu_mlme ampdu_mlme; |
| 257 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ | 297 | u8 timer_to_tid[STA_TID_NUM]; |
| 258 | u8 tid_to_tx_q[STA_TID_NUM]; /* map tid to tx queue */ | 298 | u8 tid_to_tx_q[STA_TID_NUM]; |
| 259 | 299 | ||
| 260 | #ifdef CONFIG_MAC80211_MESH | 300 | #ifdef CONFIG_MAC80211_MESH |
| 261 | /* | 301 | /* |
| 262 | * Mesh peer link attributes | 302 | * Mesh peer link attributes |
| 263 | * TODO: move to a sub-structure that is referenced with pointer? | 303 | * TODO: move to a sub-structure that is referenced with pointer? |
| 264 | */ | 304 | */ |
| 265 | __le16 llid; /* Local link ID */ | 305 | __le16 llid; |
| 266 | __le16 plid; /* Peer link ID */ | 306 | __le16 plid; |
| 267 | __le16 reason; /* Cancel reason on PLINK_HOLDING state */ | 307 | __le16 reason; |
| 268 | u8 plink_retries; /* Retries in establishment */ | 308 | u8 plink_retries; |
| 269 | bool ignore_plink_timer; | 309 | bool ignore_plink_timer; |
| 270 | enum plink_state plink_state; | 310 | enum plink_state plink_state; |
| 271 | u32 plink_timeout; | 311 | u32 plink_timeout; |
| 272 | struct timer_list plink_timer; | 312 | struct timer_list plink_timer; |
| 273 | spinlock_t plink_lock; /* For peer_state reads / updates and other | ||
| 274 | updates in the structure. Ensures robust | ||
| 275 | transitions for the peerlink FSM */ | ||
| 276 | #endif | 313 | #endif |
| 277 | 314 | ||
| 278 | #ifdef CONFIG_MAC80211_DEBUGFS | 315 | #ifdef CONFIG_MAC80211_DEBUGFS |
| @@ -299,6 +336,73 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta) | |||
| 299 | return PLINK_LISTEN; | 336 | return PLINK_LISTEN; |
| 300 | } | 337 | } |
| 301 | 338 | ||
| 339 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | ||
| 340 | { | ||
| 341 | unsigned long irqfl; | ||
| 342 | |||
| 343 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 344 | sta->flags |= flags; | ||
| 345 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 346 | } | ||
| 347 | |||
| 348 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | ||
| 349 | { | ||
| 350 | unsigned long irqfl; | ||
| 351 | |||
| 352 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 353 | sta->flags &= ~flags; | ||
| 354 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 355 | } | ||
| 356 | |||
| 357 | static inline void set_and_clear_sta_flags(struct sta_info *sta, | ||
| 358 | const u32 set, const u32 clear) | ||
| 359 | { | ||
| 360 | unsigned long irqfl; | ||
| 361 | |||
| 362 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 363 | sta->flags |= set; | ||
| 364 | sta->flags &= ~clear; | ||
| 365 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 366 | } | ||
| 367 | |||
| 368 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | ||
| 369 | { | ||
| 370 | u32 ret; | ||
| 371 | unsigned long irqfl; | ||
| 372 | |||
| 373 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 374 | ret = sta->flags & flags; | ||
| 375 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 376 | |||
| 377 | return ret; | ||
| 378 | } | ||
| 379 | |||
| 380 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | ||
| 381 | const u32 flags) | ||
| 382 | { | ||
| 383 | u32 ret; | ||
| 384 | unsigned long irqfl; | ||
| 385 | |||
| 386 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 387 | ret = sta->flags & flags; | ||
| 388 | sta->flags &= ~flags; | ||
| 389 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 390 | |||
| 391 | return ret; | ||
| 392 | } | ||
| 393 | |||
| 394 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
| 395 | { | ||
| 396 | u32 ret; | ||
| 397 | unsigned long irqfl; | ||
| 398 | |||
| 399 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
| 400 | ret = sta->flags; | ||
| 401 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
| 402 | |||
| 403 | return ret; | ||
| 404 | } | ||
| 405 | |||
| 302 | 406 | ||
| 303 | /* Maximum number of concurrently registered stations */ | 407 | /* Maximum number of concurrently registered stations */ |
| 304 | #define MAX_STA_COUNT 2007 | 408 | #define MAX_STA_COUNT 2007 |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 09093da24af6..995f7af3d25e 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
| @@ -6,25 +6,23 @@ | |||
| 6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
| 7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
| 8 | */ | 8 | */ |
| 9 | |||
| 10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 10 | #include <linux/bitops.h> | ||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
| 13 | #include <asm/unaligned.h> | ||
| 13 | 14 | ||
| 14 | #include <net/mac80211.h> | 15 | #include <net/mac80211.h> |
| 15 | #include "key.h" | 16 | #include "key.h" |
| 16 | #include "tkip.h" | 17 | #include "tkip.h" |
| 17 | #include "wep.h" | 18 | #include "wep.h" |
| 18 | 19 | ||
| 19 | |||
| 20 | /* TKIP key mixing functions */ | ||
| 21 | |||
| 22 | |||
| 23 | #define PHASE1_LOOP_COUNT 8 | 20 | #define PHASE1_LOOP_COUNT 8 |
| 24 | 21 | ||
| 25 | 22 | /* | |
| 26 | /* 2-byte by 2-byte subset of the full AES S-box table; second part of this | 23 | * 2-byte by 2-byte subset of the full AES S-box table; second part of this |
| 27 | * table is identical to first part but byte-swapped */ | 24 | * table is identical to first part but byte-swapped |
| 25 | */ | ||
| 28 | static const u16 tkip_sbox[256] = | 26 | static const u16 tkip_sbox[256] = |
| 29 | { | 27 | { |
| 30 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | 28 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, |
| @@ -61,84 +59,54 @@ static const u16 tkip_sbox[256] = | |||
| 61 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | 59 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, |
| 62 | }; | 60 | }; |
| 63 | 61 | ||
| 64 | 62 | static u16 tkipS(u16 val) | |
| 65 | static inline u16 Mk16(u8 x, u8 y) | ||
| 66 | { | 63 | { |
| 67 | return ((u16) x << 8) | (u16) y; | 64 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
| 68 | } | 65 | } |
| 69 | 66 | ||
| 70 | 67 | static u8 *write_tkip_iv(u8 *pos, u16 iv16) | |
| 71 | static inline u8 Hi8(u16 v) | ||
| 72 | { | ||
| 73 | return v >> 8; | ||
| 74 | } | ||
| 75 | |||
| 76 | |||
| 77 | static inline u8 Lo8(u16 v) | ||
| 78 | { | ||
| 79 | return v & 0xff; | ||
| 80 | } | ||
| 81 | |||
| 82 | |||
| 83 | static inline u16 Hi16(u32 v) | ||
| 84 | { | ||
| 85 | return v >> 16; | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | static inline u16 Lo16(u32 v) | ||
| 90 | { | ||
| 91 | return v & 0xffff; | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | static inline u16 RotR1(u16 v) | ||
| 96 | { | ||
| 97 | return (v >> 1) | ((v & 0x0001) << 15); | ||
| 98 | } | ||
| 99 | |||
| 100 | |||
| 101 | static inline u16 tkip_S(u16 val) | ||
| 102 | { | 68 | { |
| 103 | u16 a = tkip_sbox[Hi8(val)]; | 69 | *pos++ = iv16 >> 8; |
| 104 | 70 | *pos++ = ((iv16 >> 8) | 0x20) & 0x7f; | |
| 105 | return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); | 71 | *pos++ = iv16 & 0xFF; |
| 72 | return pos; | ||
| 106 | } | 73 | } |
| 107 | 74 | ||
| 108 | 75 | /* | |
| 109 | 76 | * P1K := Phase1(TA, TK, TSC) | |
| 110 | /* P1K := Phase1(TA, TK, TSC) | ||
| 111 | * TA = transmitter address (48 bits) | 77 | * TA = transmitter address (48 bits) |
| 112 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) | 78 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) |
| 113 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 79 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
| 114 | * P1K: 80 bits | 80 | * P1K: 80 bits |
| 115 | */ | 81 | */ |
| 116 | static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | 82 | static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, |
| 117 | u16 *p1k) | 83 | const u8 *ta, u32 tsc_IV32) |
| 118 | { | 84 | { |
| 119 | int i, j; | 85 | int i, j; |
| 86 | u16 *p1k = ctx->p1k; | ||
| 120 | 87 | ||
| 121 | p1k[0] = Lo16(tsc_IV32); | 88 | p1k[0] = tsc_IV32 & 0xFFFF; |
| 122 | p1k[1] = Hi16(tsc_IV32); | 89 | p1k[1] = tsc_IV32 >> 16; |
| 123 | p1k[2] = Mk16(ta[1], ta[0]); | 90 | p1k[2] = get_unaligned_le16(ta + 0); |
| 124 | p1k[3] = Mk16(ta[3], ta[2]); | 91 | p1k[3] = get_unaligned_le16(ta + 2); |
| 125 | p1k[4] = Mk16(ta[5], ta[4]); | 92 | p1k[4] = get_unaligned_le16(ta + 4); |
| 126 | 93 | ||
| 127 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | 94 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { |
| 128 | j = 2 * (i & 1); | 95 | j = 2 * (i & 1); |
| 129 | p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); | 96 | p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j)); |
| 130 | p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); | 97 | p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j)); |
| 131 | p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); | 98 | p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j)); |
| 132 | p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); | 99 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
| 133 | p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; | 100 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
| 134 | } | 101 | } |
| 102 | ctx->initialized = 1; | ||
| 135 | } | 103 | } |
| 136 | 104 | ||
| 137 | 105 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | |
| 138 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 106 | u16 tsc_IV16, u8 *rc4key) |
| 139 | u8 *rc4key) | ||
| 140 | { | 107 | { |
| 141 | u16 ppk[6]; | 108 | u16 ppk[6]; |
| 109 | const u16 *p1k = ctx->p1k; | ||
| 142 | int i; | 110 | int i; |
| 143 | 111 | ||
| 144 | ppk[0] = p1k[0]; | 112 | ppk[0] = p1k[0]; |
| @@ -148,70 +116,35 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
| 148 | ppk[4] = p1k[4]; | 116 | ppk[4] = p1k[4]; |
| 149 | ppk[5] = p1k[4] + tsc_IV16; | 117 | ppk[5] = p1k[4] + tsc_IV16; |
| 150 | 118 | ||
| 151 | ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); | 119 | ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0)); |
| 152 | ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); | 120 | ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2)); |
| 153 | ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); | 121 | ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4)); |
| 154 | ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); | 122 | ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6)); |
| 155 | ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); | 123 | ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8)); |
| 156 | ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); | 124 | ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10)); |
| 157 | ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); | 125 | ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1); |
| 158 | ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); | 126 | ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1); |
| 159 | ppk[2] += RotR1(ppk[1]); | 127 | ppk[2] += ror16(ppk[1], 1); |
| 160 | ppk[3] += RotR1(ppk[2]); | 128 | ppk[3] += ror16(ppk[2], 1); |
| 161 | ppk[4] += RotR1(ppk[3]); | 129 | ppk[4] += ror16(ppk[3], 1); |
| 162 | ppk[5] += RotR1(ppk[4]); | 130 | ppk[5] += ror16(ppk[4], 1); |
| 163 | 131 | ||
| 164 | rc4key[0] = Hi8(tsc_IV16); | 132 | rc4key = write_tkip_iv(rc4key, tsc_IV16); |
| 165 | rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; | 133 | *rc4key++ = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
| 166 | rc4key[2] = Lo8(tsc_IV16); | 134 | |
| 167 | rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); | 135 | for (i = 0; i < 6; i++) |
| 168 | 136 | put_unaligned_le16(ppk[i], rc4key + 2 * i); | |
| 169 | for (i = 0; i < 6; i++) { | ||
| 170 | rc4key[4 + 2 * i] = Lo8(ppk[i]); | ||
| 171 | rc4key[5 + 2 * i] = Hi8(ppk[i]); | ||
| 172 | } | ||
| 173 | } | 137 | } |
| 174 | 138 | ||
| 175 | |||
| 176 | /* 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 |
| 177 | * 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 |
| 178 | * the packet payload). */ | 141 | * the packet payload). */ |
| 179 | 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) |
| 180 | u8 iv0, u8 iv1, u8 iv2) | ||
| 181 | { | 143 | { |
| 182 | *pos++ = iv0; | 144 | pos = write_tkip_iv(pos, iv16); |
| 183 | *pos++ = iv1; | ||
| 184 | *pos++ = iv2; | ||
| 185 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 145 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
| 186 | *pos++ = key->u.tkip.iv32 & 0xff; | 146 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
| 187 | *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; | 147 | return pos + 4; |
| 188 | *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; | ||
| 189 | *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; | ||
| 190 | return pos; | ||
| 191 | } | ||
| 192 | |||
| 193 | |||
| 194 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | ||
| 195 | u16 *phase1key) | ||
| 196 | { | ||
| 197 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
| 198 | key->u.tkip.iv32, phase1key); | ||
| 199 | } | ||
| 200 | |||
| 201 | void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
| 202 | u8 *rc4key) | ||
| 203 | { | ||
| 204 | /* Calculate per-packet key */ | ||
| 205 | if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { | ||
| 206 | /* IV16 wrapped around - perform TKIP phase 1 */ | ||
| 207 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
| 208 | key->u.tkip.iv32, key->u.tkip.p1k); | ||
| 209 | key->u.tkip.tx_initialized = 1; | ||
| 210 | } | ||
| 211 | |||
| 212 | tkip_mixing_phase2(key->u.tkip.p1k, | ||
| 213 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
| 214 | key->u.tkip.iv16, rc4key); | ||
| 215 | } | 148 | } |
| 216 | 149 | ||
| 217 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 150 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, |
| @@ -220,48 +153,44 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
| 220 | { | 153 | { |
| 221 | struct ieee80211_key *key = (struct ieee80211_key *) | 154 | struct ieee80211_key *key = (struct ieee80211_key *) |
| 222 | container_of(keyconf, struct ieee80211_key, conf); | 155 | container_of(keyconf, struct ieee80211_key, conf); |
| 223 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 156 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 224 | u8 *data = (u8 *) hdr; | 157 | u8 *data; |
| 225 | u16 fc = le16_to_cpu(hdr->frame_control); | 158 | const u8 *tk; |
| 226 | int hdr_len = ieee80211_get_hdrlen(fc); | 159 | struct tkip_ctx *ctx; |
| 227 | u8 *ta = hdr->addr2; | ||
| 228 | u16 iv16; | 160 | u16 iv16; |
| 229 | u32 iv32; | 161 | u32 iv32; |
| 230 | 162 | ||
| 231 | iv16 = data[hdr_len] << 8; | 163 | data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); |
| 232 | iv16 += data[hdr_len + 2]; | 164 | iv16 = data[2] | (data[0] << 8); |
| 233 | iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | | 165 | iv32 = get_unaligned_le32(&data[4]); |
| 234 | (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); | 166 | |
| 167 | tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
| 168 | ctx = &key->u.tkip.tx; | ||
| 235 | 169 | ||
| 236 | #ifdef CONFIG_TKIP_DEBUG | 170 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
| 237 | 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", |
| 238 | iv16, iv32); | 172 | iv16, iv32); |
| 239 | 173 | ||
| 240 | if (iv32 != key->u.tkip.iv32) { | 174 | if (iv32 != ctx->iv32) { |
| 241 | 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", |
| 242 | iv32, key->u.tkip.iv32); | 176 | iv32, ctx->iv32); |
| 243 | 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 " |
| 244 | "fragmented packet\n"); | 178 | "fragmented packet\n"); |
| 245 | } | 179 | } |
| 246 | #endif /* CONFIG_TKIP_DEBUG */ | 180 | #endif |
| 247 | 181 | ||
| 248 | /* 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 |
| 249 | * 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 |
| 250 | * fragmented packets. */ | 184 | * fragmented packets. */ |
| 251 | if (iv16 == 0 || !key->u.tkip.tx_initialized) { | 185 | if (iv16 == 0 || !ctx->initialized) |
| 252 | /* IV16 wrapped around - perform TKIP phase 1 */ | 186 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); |
| 253 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
| 254 | iv32, key->u.tkip.p1k); | ||
| 255 | key->u.tkip.tx_initialized = 1; | ||
| 256 | } | ||
| 257 | 187 | ||
| 258 | if (type == IEEE80211_TKIP_P1_KEY) { | 188 | if (type == IEEE80211_TKIP_P1_KEY) { |
| 259 | memcpy(outkey, key->u.tkip.p1k, sizeof(u16) * 5); | 189 | memcpy(outkey, ctx->p1k, sizeof(u16) * 5); |
| 260 | return; | 190 | return; |
| 261 | } | 191 | } |
| 262 | 192 | ||
| 263 | tkip_mixing_phase2(key->u.tkip.p1k, | 193 | tkip_mixing_phase2(tk, ctx, iv16, outkey); |
| 264 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], iv16, outkey); | ||
| 265 | } | 194 | } |
| 266 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 195 | EXPORT_SYMBOL(ieee80211_get_tkip_key); |
| 267 | 196 | ||
| @@ -275,13 +204,19 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
| 275 | u8 *pos, size_t payload_len, u8 *ta) | 204 | u8 *pos, size_t payload_len, u8 *ta) |
| 276 | { | 205 | { |
| 277 | u8 rc4key[16]; | 206 | u8 rc4key[16]; |
| 207 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
| 208 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
| 209 | |||
| 210 | /* Calculate per-packet key */ | ||
| 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); | ||
| 278 | 215 | ||
| 279 | ieee80211_tkip_gen_rc4key(key, ta, rc4key); | 216 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
| 280 | pos = ieee80211_tkip_add_iv(pos, key, rc4key[0], rc4key[1], rc4key[2]); | ||
| 281 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 217 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
| 282 | } | 218 | } |
| 283 | 219 | ||
| 284 | |||
| 285 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 220 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
| 286 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., | 221 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., |
| 287 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the | 222 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the |
| @@ -296,15 +231,16 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 296 | u32 iv16; | 231 | u32 iv16; |
| 297 | u8 rc4key[16], keyid, *pos = payload; | 232 | u8 rc4key[16], keyid, *pos = payload; |
| 298 | int res; | 233 | int res; |
| 234 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
| 299 | 235 | ||
| 300 | if (payload_len < 12) | 236 | if (payload_len < 12) |
| 301 | return -1; | 237 | return -1; |
| 302 | 238 | ||
| 303 | iv16 = (pos[0] << 8) | pos[2]; | 239 | iv16 = (pos[0] << 8) | pos[2]; |
| 304 | keyid = pos[3]; | 240 | keyid = pos[3]; |
| 305 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | 241 | iv32 = get_unaligned_le32(pos + 4); |
| 306 | pos += 8; | 242 | pos += 8; |
| 307 | #ifdef CONFIG_TKIP_DEBUG | 243 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
| 308 | { | 244 | { |
| 309 | int i; | 245 | int i; |
| 310 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); | 246 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); |
| @@ -314,7 +250,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 314 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", | 250 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", |
| 315 | iv16, iv32); | 251 | iv16, iv32); |
| 316 | } | 252 | } |
| 317 | #endif /* CONFIG_TKIP_DEBUG */ | 253 | #endif |
| 318 | 254 | ||
| 319 | if (!(keyid & (1 << 5))) | 255 | if (!(keyid & (1 << 5))) |
| 320 | return TKIP_DECRYPT_NO_EXT_IV; | 256 | return TKIP_DECRYPT_NO_EXT_IV; |
| @@ -322,50 +258,48 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 322 | if ((keyid >> 6) != key->conf.keyidx) | 258 | if ((keyid >> 6) != key->conf.keyidx) |
| 323 | return TKIP_DECRYPT_INVALID_KEYIDX; | 259 | return TKIP_DECRYPT_INVALID_KEYIDX; |
| 324 | 260 | ||
| 325 | if (key->u.tkip.rx_initialized[queue] && | 261 | if (key->u.tkip.rx[queue].initialized && |
| 326 | (iv32 < key->u.tkip.iv32_rx[queue] || | 262 | (iv32 < key->u.tkip.rx[queue].iv32 || |
| 327 | (iv32 == key->u.tkip.iv32_rx[queue] && | 263 | (iv32 == key->u.tkip.rx[queue].iv32 && |
| 328 | iv16 <= key->u.tkip.iv16_rx[queue]))) { | 264 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
| 329 | #ifdef CONFIG_TKIP_DEBUG | 265 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
| 330 | DECLARE_MAC_BUF(mac); | 266 | DECLARE_MAC_BUF(mac); |
| 331 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | 267 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " |
| 332 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | 268 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", |
| 333 | print_mac(mac, ta), | 269 | print_mac(mac, ta), |
| 334 | iv32, iv16, key->u.tkip.iv32_rx[queue], | 270 | iv32, iv16, key->u.tkip.rx[queue].iv32, |
| 335 | key->u.tkip.iv16_rx[queue]); | 271 | key->u.tkip.rx[queue].iv16); |
| 336 | #endif /* CONFIG_TKIP_DEBUG */ | 272 | #endif |
| 337 | return TKIP_DECRYPT_REPLAY; | 273 | return TKIP_DECRYPT_REPLAY; |
| 338 | } | 274 | } |
| 339 | 275 | ||
| 340 | if (only_iv) { | 276 | if (only_iv) { |
| 341 | res = TKIP_DECRYPT_OK; | 277 | res = TKIP_DECRYPT_OK; |
| 342 | key->u.tkip.rx_initialized[queue] = 1; | 278 | key->u.tkip.rx[queue].initialized = 1; |
| 343 | goto done; | 279 | goto done; |
| 344 | } | 280 | } |
| 345 | 281 | ||
| 346 | if (!key->u.tkip.rx_initialized[queue] || | 282 | if (!key->u.tkip.rx[queue].initialized || |
| 347 | key->u.tkip.iv32_rx[queue] != iv32) { | 283 | key->u.tkip.rx[queue].iv32 != iv32) { |
| 348 | key->u.tkip.rx_initialized[queue] = 1; | ||
| 349 | /* IV16 wrapped around - perform TKIP phase 1 */ | 284 | /* IV16 wrapped around - perform TKIP phase 1 */ |
| 350 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | 285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); |
| 351 | iv32, key->u.tkip.p1k_rx[queue]); | 286 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
| 352 | #ifdef CONFIG_TKIP_DEBUG | ||
| 353 | { | 287 | { |
| 354 | int i; | 288 | int i; |
| 289 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; | ||
| 355 | DECLARE_MAC_BUF(mac); | 290 | DECLARE_MAC_BUF(mac); |
| 356 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" | 291 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" |
| 357 | " TK=", print_mac(mac, ta)); | 292 | " TK=", print_mac(mac, ta)); |
| 358 | for (i = 0; i < 16; i++) | 293 | for (i = 0; i < 16; i++) |
| 359 | printk("%02x ", | 294 | printk("%02x ", |
| 360 | key->conf.key[ | 295 | key->conf.key[key_offset + i]); |
| 361 | ALG_TKIP_TEMP_ENCR_KEY + i]); | ||
| 362 | printk("\n"); | 296 | printk("\n"); |
| 363 | printk(KERN_DEBUG "TKIP decrypt: P1K="); | 297 | printk(KERN_DEBUG "TKIP decrypt: P1K="); |
| 364 | for (i = 0; i < 5; i++) | 298 | for (i = 0; i < 5; i++) |
| 365 | printk("%04x ", key->u.tkip.p1k_rx[queue][i]); | 299 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); |
| 366 | printk("\n"); | 300 | printk("\n"); |
| 367 | } | 301 | } |
| 368 | #endif /* CONFIG_TKIP_DEBUG */ | 302 | #endif |
| 369 | if (key->local->ops->update_tkip_key && | 303 | if (key->local->ops->update_tkip_key && |
| 370 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 304 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
| 371 | u8 bcast[ETH_ALEN] = | 305 | u8 bcast[ETH_ALEN] = |
| @@ -377,14 +311,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 377 | 311 | ||
| 378 | key->local->ops->update_tkip_key( | 312 | key->local->ops->update_tkip_key( |
| 379 | local_to_hw(key->local), &key->conf, | 313 | local_to_hw(key->local), &key->conf, |
| 380 | sta_addr, iv32, key->u.tkip.p1k_rx[queue]); | 314 | sta_addr, iv32, key->u.tkip.rx[queue].p1k); |
| 381 | } | 315 | } |
| 382 | } | 316 | } |
| 383 | 317 | ||
| 384 | tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], | 318 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); |
| 385 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | 319 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
| 386 | iv16, rc4key); | ||
| 387 | #ifdef CONFIG_TKIP_DEBUG | ||
| 388 | { | 320 | { |
| 389 | int i; | 321 | int i; |
| 390 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); | 322 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); |
| @@ -392,7 +324,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 392 | printk("%02x ", rc4key[i]); | 324 | printk("%02x ", rc4key[i]); |
| 393 | printk("\n"); | 325 | printk("\n"); |
| 394 | } | 326 | } |
| 395 | #endif /* CONFIG_TKIP_DEBUG */ | 327 | #endif |
| 396 | 328 | ||
| 397 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); | 329 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); |
| 398 | done: | 330 | done: |
| @@ -409,5 +341,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
| 409 | 341 | ||
| 410 | return res; | 342 | return res; |
| 411 | } | 343 | } |
| 412 | |||
| 413 | |||
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index b7c2ee763d9d..d4714383f5fc 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
| @@ -13,12 +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_gen_phase1key(struct ieee80211_key *key, u8 *ta, | ||
| 19 | u16 *phase1key); | ||
| 20 | void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
| 21 | u8 *rc4key); | ||
| 22 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | 18 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, |
| 23 | struct ieee80211_key *key, | 19 | struct ieee80211_key *key, |
| 24 | 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 c80d5899f279..0fbadd8b983c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -38,23 +38,12 @@ | |||
| 38 | 38 | ||
| 39 | /* misc utils */ | 39 | /* misc utils */ |
| 40 | 40 | ||
| 41 | static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata, | ||
| 42 | struct ieee80211_hdr *hdr) | ||
| 43 | { | ||
| 44 | /* Set the sequence number for this frame. */ | ||
| 45 | hdr->seq_ctrl = cpu_to_le16(sdata->sequence); | ||
| 46 | |||
| 47 | /* Increase the sequence number. */ | ||
| 48 | sdata->sequence = (sdata->sequence + 0x10) & IEEE80211_SCTL_SEQ; | ||
| 49 | } | ||
| 50 | |||
| 51 | #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP | 41 | #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP |
| 52 | static void ieee80211_dump_frame(const char *ifname, const char *title, | 42 | static void ieee80211_dump_frame(const char *ifname, const char *title, |
| 53 | const struct sk_buff *skb) | 43 | const struct sk_buff *skb) |
| 54 | { | 44 | { |
| 55 | const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 45 | const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 56 | u16 fc; | 46 | unsigned int hdrlen; |
| 57 | int hdrlen; | ||
| 58 | DECLARE_MAC_BUF(mac); | 47 | DECLARE_MAC_BUF(mac); |
| 59 | 48 | ||
| 60 | printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); | 49 | printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); |
| @@ -63,13 +52,12 @@ static void ieee80211_dump_frame(const char *ifname, const char *title, | |||
| 63 | return; | 52 | return; |
| 64 | } | 53 | } |
| 65 | 54 | ||
| 66 | fc = le16_to_cpu(hdr->frame_control); | 55 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 67 | hdrlen = ieee80211_get_hdrlen(fc); | ||
| 68 | if (hdrlen > skb->len) | 56 | if (hdrlen > skb->len) |
| 69 | hdrlen = skb->len; | 57 | hdrlen = skb->len; |
| 70 | if (hdrlen >= 4) | 58 | if (hdrlen >= 4) |
| 71 | printk(" FC=0x%04x DUR=0x%04x", | 59 | printk(" FC=0x%04x DUR=0x%04x", |
| 72 | fc, le16_to_cpu(hdr->duration_id)); | 60 | le16_to_cpu(hdr->frame_control), le16_to_cpu(hdr->duration_id)); |
| 73 | if (hdrlen >= 10) | 61 | if (hdrlen >= 10) |
| 74 | printk(" A1=%s", print_mac(mac, hdr->addr1)); | 62 | printk(" A1=%s", print_mac(mac, hdr->addr1)); |
| 75 | if (hdrlen >= 16) | 63 | if (hdrlen >= 16) |
| @@ -87,15 +75,16 @@ static inline void ieee80211_dump_frame(const char *ifname, const char *title, | |||
| 87 | } | 75 | } |
| 88 | #endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ | 76 | #endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ |
| 89 | 77 | ||
| 90 | static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | 78 | static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, |
| 91 | int next_frag_len) | 79 | int next_frag_len) |
| 92 | { | 80 | { |
| 93 | int rate, mrate, erp, dur, i; | 81 | int rate, mrate, erp, dur, i; |
| 94 | struct ieee80211_rate *txrate = tx->rate; | 82 | struct ieee80211_rate *txrate; |
| 95 | struct ieee80211_local *local = tx->local; | 83 | struct ieee80211_local *local = tx->local; |
| 96 | struct ieee80211_supported_band *sband; | 84 | struct ieee80211_supported_band *sband; |
| 97 | 85 | ||
| 98 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 86 | sband = local->hw.wiphy->bands[tx->channel->band]; |
| 87 | txrate = &sband->bitrates[tx->rate_idx]; | ||
| 99 | 88 | ||
| 100 | erp = 0; | 89 | erp = 0; |
| 101 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 90 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
| @@ -139,7 +128,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
| 139 | 128 | ||
| 140 | /* data/mgmt */ | 129 | /* data/mgmt */ |
| 141 | if (0 /* FIX: data/mgmt during CFP */) | 130 | if (0 /* FIX: data/mgmt during CFP */) |
| 142 | return 32768; | 131 | return cpu_to_le16(32768); |
| 143 | 132 | ||
| 144 | if (group_addr) /* Group address as the destination - no ACK */ | 133 | if (group_addr) /* Group address as the destination - no ACK */ |
| 145 | return 0; | 134 | return 0; |
| @@ -209,19 +198,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
| 209 | tx->sdata->bss_conf.use_short_preamble); | 198 | tx->sdata->bss_conf.use_short_preamble); |
| 210 | } | 199 | } |
| 211 | 200 | ||
| 212 | return dur; | 201 | return cpu_to_le16(dur); |
| 213 | } | ||
| 214 | |||
| 215 | static inline int __ieee80211_queue_stopped(const struct ieee80211_local *local, | ||
| 216 | int queue) | ||
| 217 | { | ||
| 218 | return test_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); | ||
| 219 | } | ||
| 220 | |||
| 221 | static inline int __ieee80211_queue_pending(const struct ieee80211_local *local, | ||
| 222 | int queue) | ||
| 223 | { | ||
| 224 | return test_bit(IEEE80211_LINK_STATE_PENDING, &local->state[queue]); | ||
| 225 | } | 202 | } |
| 226 | 203 | ||
| 227 | static int inline is_ieee80211_device(struct net_device *dev, | 204 | static int inline is_ieee80211_device(struct net_device *dev, |
| @@ -233,16 +210,16 @@ static int inline is_ieee80211_device(struct net_device *dev, | |||
| 233 | 210 | ||
| 234 | /* tx handlers */ | 211 | /* tx handlers */ |
| 235 | 212 | ||
| 236 | static ieee80211_tx_result | 213 | static ieee80211_tx_result debug_noinline |
| 237 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | 214 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) |
| 238 | { | 215 | { |
| 239 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 216 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
| 240 | struct sk_buff *skb = tx->skb; | 217 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
| 241 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 242 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 218 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
| 219 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 243 | u32 sta_flags; | 220 | u32 sta_flags; |
| 244 | 221 | ||
| 245 | if (unlikely(tx->flags & IEEE80211_TX_INJECTED)) | 222 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) |
| 246 | return TX_CONTINUE; | 223 | return TX_CONTINUE; |
| 247 | 224 | ||
| 248 | if (unlikely(tx->local->sta_sw_scanning) && | 225 | if (unlikely(tx->local->sta_sw_scanning) && |
| @@ -256,7 +233,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
| 256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 233 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
| 257 | return TX_CONTINUE; | 234 | return TX_CONTINUE; |
| 258 | 235 | ||
| 259 | sta_flags = tx->sta ? tx->sta->flags : 0; | 236 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; |
| 260 | 237 | ||
| 261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 238 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
| 262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 239 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && |
| @@ -287,17 +264,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
| 287 | return TX_CONTINUE; | 264 | return TX_CONTINUE; |
| 288 | } | 265 | } |
| 289 | 266 | ||
| 290 | static ieee80211_tx_result | ||
| 291 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | ||
| 292 | { | ||
| 293 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
| 294 | |||
| 295 | if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) | ||
| 296 | ieee80211_include_sequence(tx->sdata, hdr); | ||
| 297 | |||
| 298 | return TX_CONTINUE; | ||
| 299 | } | ||
| 300 | |||
| 301 | /* This function is called whenever the AP is about to exceed the maximum limit | 267 | /* This function is called whenever the AP is about to exceed the maximum limit |
| 302 | * of buffered frames for power saving STAs. This situation should not really | 268 | * of buffered frames for power saving STAs. This situation should not really |
| 303 | * happen often during normal operation, so dropping the oldest buffered packet | 269 | * happen often during normal operation, so dropping the oldest buffered packet |
| @@ -316,8 +282,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
| 316 | 282 | ||
| 317 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 283 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
| 318 | struct ieee80211_if_ap *ap; | 284 | struct ieee80211_if_ap *ap; |
| 319 | if (sdata->dev == local->mdev || | 285 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP) |
| 320 | sdata->vif.type != IEEE80211_IF_TYPE_AP) | ||
| 321 | continue; | 286 | continue; |
| 322 | ap = &sdata->u.ap; | 287 | ap = &sdata->u.ap; |
| 323 | skb = skb_dequeue(&ap->ps_bc_buf); | 288 | skb = skb_dequeue(&ap->ps_bc_buf); |
| @@ -340,13 +305,17 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
| 340 | rcu_read_unlock(); | 305 | rcu_read_unlock(); |
| 341 | 306 | ||
| 342 | local->total_ps_buffered = total; | 307 | local->total_ps_buffered = total; |
| 308 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
| 343 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 309 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", |
| 344 | wiphy_name(local->hw.wiphy), purged); | 310 | wiphy_name(local->hw.wiphy), purged); |
| 311 | #endif | ||
| 345 | } | 312 | } |
| 346 | 313 | ||
| 347 | static ieee80211_tx_result | 314 | static ieee80211_tx_result |
| 348 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | 315 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) |
| 349 | { | 316 | { |
| 317 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 318 | |||
| 350 | /* | 319 | /* |
| 351 | * broadcast/multicast frame | 320 | * broadcast/multicast frame |
| 352 | * | 321 | * |
| @@ -355,8 +324,12 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 355 | * This is done either by the hardware or us. | 324 | * This is done either by the hardware or us. |
| 356 | */ | 325 | */ |
| 357 | 326 | ||
| 358 | /* not AP/IBSS or ordered frame */ | 327 | /* powersaving STAs only in AP/VLAN mode */ |
| 359 | if (!tx->sdata->bss || (tx->fc & IEEE80211_FCTL_ORDER)) | 328 | if (!tx->sdata->bss) |
| 329 | return TX_CONTINUE; | ||
| 330 | |||
| 331 | /* no buffering for ordered frames */ | ||
| 332 | if (tx->fc & IEEE80211_FCTL_ORDER) | ||
| 360 | return TX_CONTINUE; | 333 | return TX_CONTINUE; |
| 361 | 334 | ||
| 362 | /* no stations in PS mode */ | 335 | /* no stations in PS mode */ |
| @@ -369,11 +342,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 369 | purge_old_ps_buffers(tx->local); | 342 | purge_old_ps_buffers(tx->local); |
| 370 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= | 343 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= |
| 371 | AP_MAX_BC_BUFFER) { | 344 | AP_MAX_BC_BUFFER) { |
| 345 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
| 372 | if (net_ratelimit()) { | 346 | if (net_ratelimit()) { |
| 373 | printk(KERN_DEBUG "%s: BC TX buffer full - " | 347 | printk(KERN_DEBUG "%s: BC TX buffer full - " |
| 374 | "dropping the oldest frame\n", | 348 | "dropping the oldest frame\n", |
| 375 | tx->dev->name); | 349 | tx->dev->name); |
| 376 | } | 350 | } |
| 351 | #endif | ||
| 377 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 352 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); |
| 378 | } else | 353 | } else |
| 379 | tx->local->total_ps_buffered++; | 354 | tx->local->total_ps_buffered++; |
| @@ -382,7 +357,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 382 | } | 357 | } |
| 383 | 358 | ||
| 384 | /* buffered in hardware */ | 359 | /* buffered in hardware */ |
| 385 | tx->control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM; | 360 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
| 386 | 361 | ||
| 387 | return TX_CONTINUE; | 362 | return TX_CONTINUE; |
| 388 | } | 363 | } |
| @@ -391,6 +366,8 @@ static ieee80211_tx_result | |||
| 391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | 366 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) |
| 392 | { | 367 | { |
| 393 | struct sta_info *sta = tx->sta; | 368 | struct sta_info *sta = tx->sta; |
| 369 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 370 | u32 staflags; | ||
| 394 | DECLARE_MAC_BUF(mac); | 371 | DECLARE_MAC_BUF(mac); |
| 395 | 372 | ||
| 396 | if (unlikely(!sta || | 373 | if (unlikely(!sta || |
| @@ -398,9 +375,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 398 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) | 375 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) |
| 399 | return TX_CONTINUE; | 376 | return TX_CONTINUE; |
| 400 | 377 | ||
| 401 | if (unlikely((sta->flags & WLAN_STA_PS) && | 378 | staflags = get_sta_flags(sta); |
| 402 | !(sta->flags & WLAN_STA_PSPOLL))) { | 379 | |
| 403 | struct ieee80211_tx_packet_data *pkt_data; | 380 | if (unlikely((staflags & WLAN_STA_PS) && |
| 381 | !(staflags & WLAN_STA_PSPOLL))) { | ||
| 404 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 382 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| 405 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 383 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " |
| 406 | "before %d)\n", | 384 | "before %d)\n", |
| @@ -411,11 +389,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 411 | purge_old_ps_buffers(tx->local); | 389 | purge_old_ps_buffers(tx->local); |
| 412 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 390 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { |
| 413 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 391 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); |
| 392 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
| 414 | if (net_ratelimit()) { | 393 | if (net_ratelimit()) { |
| 415 | printk(KERN_DEBUG "%s: STA %s TX " | 394 | printk(KERN_DEBUG "%s: STA %s TX " |
| 416 | "buffer full - dropping oldest frame\n", | 395 | "buffer full - dropping oldest frame\n", |
| 417 | tx->dev->name, print_mac(mac, sta->addr)); | 396 | tx->dev->name, print_mac(mac, sta->addr)); |
| 418 | } | 397 | } |
| 398 | #endif | ||
| 419 | dev_kfree_skb(old); | 399 | dev_kfree_skb(old); |
| 420 | } else | 400 | } else |
| 421 | tx->local->total_ps_buffered++; | 401 | tx->local->total_ps_buffered++; |
| @@ -424,24 +404,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 424 | if (skb_queue_empty(&sta->ps_tx_buf)) | 404 | if (skb_queue_empty(&sta->ps_tx_buf)) |
| 425 | sta_info_set_tim_bit(sta); | 405 | sta_info_set_tim_bit(sta); |
| 426 | 406 | ||
| 427 | pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; | 407 | info->control.jiffies = jiffies; |
| 428 | pkt_data->jiffies = jiffies; | ||
| 429 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 408 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
| 430 | return TX_QUEUED; | 409 | return TX_QUEUED; |
| 431 | } | 410 | } |
| 432 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 411 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| 433 | else if (unlikely(sta->flags & WLAN_STA_PS)) { | 412 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { |
| 434 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " | 413 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " |
| 435 | "set -> send frame\n", tx->dev->name, | 414 | "set -> send frame\n", tx->dev->name, |
| 436 | print_mac(mac, sta->addr)); | 415 | print_mac(mac, sta->addr)); |
| 437 | } | 416 | } |
| 438 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 417 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
| 439 | sta->flags &= ~WLAN_STA_PSPOLL; | 418 | clear_sta_flags(sta, WLAN_STA_PSPOLL); |
| 440 | 419 | ||
| 441 | return TX_CONTINUE; | 420 | return TX_CONTINUE; |
| 442 | } | 421 | } |
| 443 | 422 | ||
| 444 | static ieee80211_tx_result | 423 | static ieee80211_tx_result debug_noinline |
| 445 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | 424 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) |
| 446 | { | 425 | { |
| 447 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) | 426 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) |
| @@ -453,21 +432,22 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
| 453 | return ieee80211_tx_h_multicast_ps_buf(tx); | 432 | return ieee80211_tx_h_multicast_ps_buf(tx); |
| 454 | } | 433 | } |
| 455 | 434 | ||
| 456 | static ieee80211_tx_result | 435 | static ieee80211_tx_result debug_noinline |
| 457 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 436 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
| 458 | { | 437 | { |
| 459 | struct ieee80211_key *key; | 438 | struct ieee80211_key *key; |
| 439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 460 | u16 fc = tx->fc; | 440 | u16 fc = tx->fc; |
| 461 | 441 | ||
| 462 | if (unlikely(tx->control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 442 | if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) |
| 463 | tx->key = NULL; | 443 | tx->key = NULL; |
| 464 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) | 444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
| 465 | tx->key = key; | 445 | tx->key = key; |
| 466 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 446 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
| 467 | tx->key = key; | 447 | tx->key = key; |
| 468 | else if (tx->sdata->drop_unencrypted && | 448 | else if (tx->sdata->drop_unencrypted && |
| 469 | !(tx->control->flags & IEEE80211_TXCTL_EAPOL_FRAME) && | 449 | !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) && |
| 470 | !(tx->flags & IEEE80211_TX_INJECTED)) { | 450 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
| 471 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
| 472 | return TX_DROP; | 452 | return TX_DROP; |
| 473 | } else | 453 | } else |
| @@ -496,15 +476,197 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
| 496 | } | 476 | } |
| 497 | 477 | ||
| 498 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
| 499 | tx->control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 479 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 500 | 480 | ||
| 501 | return TX_CONTINUE; | 481 | return TX_CONTINUE; |
| 502 | } | 482 | } |
| 503 | 483 | ||
| 504 | static ieee80211_tx_result | 484 | static ieee80211_tx_result debug_noinline |
| 485 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | ||
| 486 | { | ||
| 487 | struct rate_selection rsel; | ||
| 488 | struct ieee80211_supported_band *sband; | ||
| 489 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 490 | |||
| 491 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
| 492 | |||
| 493 | if (likely(tx->rate_idx < 0)) { | ||
| 494 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); | ||
| 495 | tx->rate_idx = rsel.rate_idx; | ||
| 496 | if (unlikely(rsel.probe_idx >= 0)) { | ||
| 497 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
| 498 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 499 | info->control.alt_retry_rate_idx = tx->rate_idx; | ||
| 500 | tx->rate_idx = rsel.probe_idx; | ||
| 501 | } else | ||
| 502 | info->control.alt_retry_rate_idx = -1; | ||
| 503 | |||
| 504 | if (unlikely(tx->rate_idx < 0)) | ||
| 505 | return TX_DROP; | ||
| 506 | } else | ||
| 507 | info->control.alt_retry_rate_idx = -1; | ||
| 508 | |||
| 509 | if (tx->sdata->bss_conf.use_cts_prot && | ||
| 510 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | ||
| 511 | tx->last_frag_rate_idx = tx->rate_idx; | ||
| 512 | if (rsel.probe_idx >= 0) | ||
| 513 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 514 | else | ||
| 515 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 516 | tx->rate_idx = rsel.nonerp_idx; | ||
| 517 | info->tx_rate_idx = rsel.nonerp_idx; | ||
| 518 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
| 519 | } else { | ||
| 520 | tx->last_frag_rate_idx = tx->rate_idx; | ||
| 521 | info->tx_rate_idx = tx->rate_idx; | ||
| 522 | } | ||
| 523 | info->tx_rate_idx = tx->rate_idx; | ||
| 524 | |||
| 525 | return TX_CONTINUE; | ||
| 526 | } | ||
| 527 | |||
| 528 | static ieee80211_tx_result debug_noinline | ||
| 529 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
| 530 | { | ||
| 531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
| 532 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 533 | struct ieee80211_supported_band *sband; | ||
| 534 | |||
| 535 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
| 536 | |||
| 537 | if (tx->sta) | ||
| 538 | info->control.aid = tx->sta->aid; | ||
| 539 | |||
| 540 | if (!info->control.retry_limit) { | ||
| 541 | if (!is_multicast_ether_addr(hdr->addr1)) { | ||
| 542 | int len = min_t(int, tx->skb->len + FCS_LEN, | ||
| 543 | tx->local->fragmentation_threshold); | ||
| 544 | if (len > tx->local->rts_threshold | ||
| 545 | && tx->local->rts_threshold < | ||
| 546 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
| 547 | info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS; | ||
| 548 | info->flags |= | ||
| 549 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT; | ||
| 550 | info->control.retry_limit = | ||
| 551 | tx->local->long_retry_limit; | ||
| 552 | } else { | ||
| 553 | info->control.retry_limit = | ||
| 554 | tx->local->short_retry_limit; | ||
| 555 | } | ||
| 556 | } else { | ||
| 557 | info->control.retry_limit = 1; | ||
| 558 | } | ||
| 559 | } | ||
| 560 | |||
| 561 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | ||
| 562 | /* Do not use multiple retry rates when sending fragmented | ||
| 563 | * frames. | ||
| 564 | * TODO: The last fragment could still use multiple retry | ||
| 565 | * rates. */ | ||
| 566 | info->control.alt_retry_rate_idx = -1; | ||
| 567 | } | ||
| 568 | |||
| 569 | /* Use CTS protection for unicast frames sent using extended rates if | ||
| 570 | * there are associated non-ERP stations and RTS/CTS is not configured | ||
| 571 | * for the frame. */ | ||
| 572 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | ||
| 573 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && | ||
| 574 | (tx->flags & IEEE80211_TX_UNICAST) && | ||
| 575 | tx->sdata->bss_conf.use_cts_prot && | ||
| 576 | !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)) | ||
| 577 | info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT; | ||
| 578 | |||
| 579 | /* Transmit data frames using short preambles if the driver supports | ||
| 580 | * short preambles at the selected rate and short preambles are | ||
| 581 | * available on the network at the current point in time. */ | ||
| 582 | if (ieee80211_is_data(hdr->frame_control) && | ||
| 583 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | ||
| 584 | tx->sdata->bss_conf.use_short_preamble && | ||
| 585 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | ||
| 586 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
| 587 | } | ||
| 588 | |||
| 589 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
| 590 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | ||
| 591 | struct ieee80211_rate *rate; | ||
| 592 | s8 baserate = -1; | ||
| 593 | int idx; | ||
| 594 | |||
| 595 | /* Do not use multiple retry rates when using RTS/CTS */ | ||
| 596 | info->control.alt_retry_rate_idx = -1; | ||
| 597 | |||
| 598 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | ||
| 599 | rate = &sband->bitrates[tx->rate_idx]; | ||
| 600 | |||
| 601 | for (idx = 0; idx < sband->n_bitrates; idx++) { | ||
| 602 | if (sband->bitrates[idx].bitrate > rate->bitrate) | ||
| 603 | continue; | ||
| 604 | if (tx->sdata->basic_rates & BIT(idx) && | ||
| 605 | (baserate < 0 || | ||
| 606 | (sband->bitrates[baserate].bitrate | ||
| 607 | < sband->bitrates[idx].bitrate))) | ||
| 608 | baserate = idx; | ||
| 609 | } | ||
| 610 | |||
| 611 | if (baserate >= 0) | ||
| 612 | info->control.rts_cts_rate_idx = baserate; | ||
| 613 | else | ||
| 614 | info->control.rts_cts_rate_idx = 0; | ||
| 615 | } | ||
| 616 | |||
| 617 | if (tx->sta) | ||
| 618 | info->control.aid = tx->sta->aid; | ||
| 619 | |||
| 620 | return TX_CONTINUE; | ||
| 621 | } | ||
| 622 | |||
| 623 | static ieee80211_tx_result debug_noinline | ||
| 624 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | ||
| 625 | { | ||
| 626 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
| 627 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
| 628 | u16 *seq; | ||
| 629 | u8 *qc; | ||
| 630 | int tid; | ||
| 631 | |||
| 632 | /* only for injected frames */ | ||
| 633 | if (unlikely(ieee80211_is_ctl(hdr->frame_control))) | ||
| 634 | return TX_CONTINUE; | ||
| 635 | |||
| 636 | if (ieee80211_hdrlen(hdr->frame_control) < 24) | ||
| 637 | return TX_CONTINUE; | ||
| 638 | |||
| 639 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | ||
| 640 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | ||
| 641 | return TX_CONTINUE; | ||
| 642 | } | ||
| 643 | |||
| 644 | /* | ||
| 645 | * This should be true for injected/management frames only, for | ||
| 646 | * management frames we have set the IEEE80211_TX_CTL_ASSIGN_SEQ | ||
| 647 | * above since they are not QoS-data frames. | ||
| 648 | */ | ||
| 649 | if (!tx->sta) | ||
| 650 | return TX_CONTINUE; | ||
| 651 | |||
| 652 | /* include per-STA, per-TID sequence counter */ | ||
| 653 | |||
| 654 | qc = ieee80211_get_qos_ctl(hdr); | ||
| 655 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | ||
| 656 | seq = &tx->sta->tid_seq[tid]; | ||
| 657 | |||
| 658 | hdr->seq_ctrl = cpu_to_le16(*seq); | ||
| 659 | |||
| 660 | /* Increase the sequence number. */ | ||
| 661 | *seq = (*seq + 0x10) & IEEE80211_SCTL_SEQ; | ||
| 662 | |||
| 663 | return TX_CONTINUE; | ||
| 664 | } | ||
| 665 | |||
| 666 | static ieee80211_tx_result debug_noinline | ||
| 505 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 667 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
| 506 | { | 668 | { |
| 507 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 669 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
| 508 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; | 670 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; |
| 509 | struct sk_buff **frags, *first, *frag; | 671 | struct sk_buff **frags, *first, *frag; |
| 510 | int i; | 672 | int i; |
| @@ -515,9 +677,19 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
| 515 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) | 677 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) |
| 516 | return TX_CONTINUE; | 678 | return TX_CONTINUE; |
| 517 | 679 | ||
| 680 | /* | ||
| 681 | * Warn when submitting a fragmented A-MPDU frame and drop it. | ||
| 682 | * This scenario is handled in __ieee80211_tx_prepare but extra | ||
| 683 | * caution taken here as fragmented ampdu may cause Tx stop. | ||
| 684 | */ | ||
| 685 | if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || | ||
| 686 | skb_get_queue_mapping(tx->skb) >= | ||
| 687 | ieee80211_num_regular_queues(&tx->local->hw))) | ||
| 688 | return TX_DROP; | ||
| 689 | |||
| 518 | first = tx->skb; | 690 | first = tx->skb; |
| 519 | 691 | ||
| 520 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 692 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 521 | payload_len = first->len - hdrlen; | 693 | payload_len = first->len - hdrlen; |
| 522 | per_fragm = frag_threshold - hdrlen - FCS_LEN; | 694 | per_fragm = frag_threshold - hdrlen - FCS_LEN; |
| 523 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); | 695 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); |
| @@ -558,6 +730,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
| 558 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 730 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
| 559 | copylen = left > per_fragm ? per_fragm : left; | 731 | copylen = left > per_fragm ? per_fragm : left; |
| 560 | memcpy(skb_put(frag, copylen), pos, copylen); | 732 | memcpy(skb_put(frag, copylen), pos, copylen); |
| 733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | ||
| 734 | skb_copy_queue_mapping(frag, first); | ||
| 561 | 735 | ||
| 562 | pos += copylen; | 736 | pos += copylen; |
| 563 | left -= copylen; | 737 | left -= copylen; |
| @@ -570,7 +744,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
| 570 | return TX_CONTINUE; | 744 | return TX_CONTINUE; |
| 571 | 745 | ||
| 572 | fail: | 746 | fail: |
| 573 | printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); | ||
| 574 | if (frags) { | 747 | if (frags) { |
| 575 | for (i = 0; i < num_fragm - 1; i++) | 748 | for (i = 0; i < num_fragm - 1; i++) |
| 576 | if (frags[i]) | 749 | if (frags[i]) |
| @@ -581,7 +754,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
| 581 | return TX_DROP; | 754 | return TX_DROP; |
| 582 | } | 755 | } |
| 583 | 756 | ||
| 584 | static ieee80211_tx_result | 757 | static ieee80211_tx_result debug_noinline |
| 585 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | 758 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) |
| 586 | { | 759 | { |
| 587 | if (!tx->key) | 760 | if (!tx->key) |
| @@ -601,236 +774,57 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | |||
| 601 | return TX_DROP; | 774 | return TX_DROP; |
| 602 | } | 775 | } |
| 603 | 776 | ||
| 604 | static ieee80211_tx_result | 777 | static ieee80211_tx_result debug_noinline |
| 605 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 778 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) |
| 606 | { | 779 | { |
| 607 | struct rate_selection rsel; | 780 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
| 608 | struct ieee80211_supported_band *sband; | 781 | int next_len, i; |
| 609 | 782 | int group_addr = is_multicast_ether_addr(hdr->addr1); | |
| 610 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
| 611 | |||
| 612 | if (likely(!tx->rate)) { | ||
| 613 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); | ||
| 614 | tx->rate = rsel.rate; | ||
| 615 | if (unlikely(rsel.probe)) { | ||
| 616 | tx->control->flags |= | ||
| 617 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | ||
| 618 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 619 | tx->control->alt_retry_rate = tx->rate; | ||
| 620 | tx->rate = rsel.probe; | ||
| 621 | } else | ||
| 622 | tx->control->alt_retry_rate = NULL; | ||
| 623 | |||
| 624 | if (!tx->rate) | ||
| 625 | return TX_DROP; | ||
| 626 | } else | ||
| 627 | tx->control->alt_retry_rate = NULL; | ||
| 628 | 783 | ||
| 629 | if (tx->sdata->bss_conf.use_cts_prot && | 784 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) { |
| 630 | (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) { | 785 | hdr->duration_id = ieee80211_duration(tx, group_addr, 0); |
| 631 | tx->last_frag_rate = tx->rate; | 786 | return TX_CONTINUE; |
| 632 | if (rsel.probe) | ||
| 633 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 634 | else | ||
| 635 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
| 636 | tx->rate = rsel.nonerp; | ||
| 637 | tx->control->tx_rate = rsel.nonerp; | ||
| 638 | tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | ||
| 639 | } else { | ||
| 640 | tx->last_frag_rate = tx->rate; | ||
| 641 | tx->control->tx_rate = tx->rate; | ||
| 642 | } | 787 | } |
| 643 | tx->control->tx_rate = tx->rate; | ||
| 644 | |||
| 645 | return TX_CONTINUE; | ||
| 646 | } | ||
| 647 | 788 | ||
| 648 | static ieee80211_tx_result | 789 | hdr->duration_id = ieee80211_duration(tx, group_addr, |
| 649 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | 790 | tx->extra_frag[0]->len); |
| 650 | { | ||
| 651 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | ||
| 652 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
| 653 | u16 dur; | ||
| 654 | struct ieee80211_tx_control *control = tx->control; | ||
| 655 | 791 | ||
| 656 | if (!control->retry_limit) { | 792 | for (i = 0; i < tx->num_extra_frag; i++) { |
| 657 | if (!is_multicast_ether_addr(hdr->addr1)) { | 793 | if (i + 1 < tx->num_extra_frag) { |
| 658 | if (tx->skb->len + FCS_LEN > tx->local->rts_threshold | 794 | next_len = tx->extra_frag[i + 1]->len; |
| 659 | && tx->local->rts_threshold < | ||
| 660 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
| 661 | control->flags |= | ||
| 662 | IEEE80211_TXCTL_USE_RTS_CTS; | ||
| 663 | control->flags |= | ||
| 664 | IEEE80211_TXCTL_LONG_RETRY_LIMIT; | ||
| 665 | control->retry_limit = | ||
| 666 | tx->local->long_retry_limit; | ||
| 667 | } else { | ||
| 668 | control->retry_limit = | ||
| 669 | tx->local->short_retry_limit; | ||
| 670 | } | ||
| 671 | } else { | 795 | } else { |
| 672 | control->retry_limit = 1; | 796 | next_len = 0; |
| 673 | } | 797 | tx->rate_idx = tx->last_frag_rate_idx; |
| 674 | } | ||
| 675 | |||
| 676 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | ||
| 677 | /* Do not use multiple retry rates when sending fragmented | ||
| 678 | * frames. | ||
| 679 | * TODO: The last fragment could still use multiple retry | ||
| 680 | * rates. */ | ||
| 681 | control->alt_retry_rate = NULL; | ||
| 682 | } | ||
| 683 | |||
| 684 | /* Use CTS protection for unicast frames sent using extended rates if | ||
| 685 | * there are associated non-ERP stations and RTS/CTS is not configured | ||
| 686 | * for the frame. */ | ||
| 687 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | ||
| 688 | (tx->rate->flags & IEEE80211_RATE_ERP_G) && | ||
| 689 | (tx->flags & IEEE80211_TX_UNICAST) && | ||
| 690 | tx->sdata->bss_conf.use_cts_prot && | ||
| 691 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | ||
| 692 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; | ||
| 693 | |||
| 694 | /* Transmit data frames using short preambles if the driver supports | ||
| 695 | * short preambles at the selected rate and short preambles are | ||
| 696 | * available on the network at the current point in time. */ | ||
| 697 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | ||
| 698 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | ||
| 699 | tx->sdata->bss_conf.use_short_preamble && | ||
| 700 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | ||
| 701 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | ||
| 702 | } | ||
| 703 | |||
| 704 | /* Setup duration field for the first fragment of the frame. Duration | ||
| 705 | * for remaining fragments will be updated when they are being sent | ||
| 706 | * to low-level driver in ieee80211_tx(). */ | ||
| 707 | dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1), | ||
| 708 | (tx->flags & IEEE80211_TX_FRAGMENTED) ? | ||
| 709 | tx->extra_frag[0]->len : 0); | ||
| 710 | hdr->duration_id = cpu_to_le16(dur); | ||
| 711 | |||
| 712 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || | ||
| 713 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { | ||
| 714 | struct ieee80211_supported_band *sband; | ||
| 715 | struct ieee80211_rate *rate, *baserate; | ||
| 716 | int idx; | ||
| 717 | |||
| 718 | sband = tx->local->hw.wiphy->bands[ | ||
| 719 | tx->local->hw.conf.channel->band]; | ||
| 720 | |||
| 721 | /* Do not use multiple retry rates when using RTS/CTS */ | ||
| 722 | control->alt_retry_rate = NULL; | ||
| 723 | |||
| 724 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | ||
| 725 | rate = tx->rate; | ||
| 726 | baserate = NULL; | ||
| 727 | |||
| 728 | for (idx = 0; idx < sband->n_bitrates; idx++) { | ||
| 729 | if (sband->bitrates[idx].bitrate > rate->bitrate) | ||
| 730 | continue; | ||
| 731 | if (tx->sdata->basic_rates & BIT(idx) && | ||
| 732 | (!baserate || | ||
| 733 | (baserate->bitrate < sband->bitrates[idx].bitrate))) | ||
| 734 | baserate = &sband->bitrates[idx]; | ||
| 735 | } | 798 | } |
| 736 | 799 | ||
| 737 | if (baserate) | 800 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; |
| 738 | control->rts_cts_rate = baserate; | 801 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); |
| 739 | else | ||
| 740 | control->rts_cts_rate = &sband->bitrates[0]; | ||
| 741 | } | ||
| 742 | |||
| 743 | if (tx->sta) { | ||
| 744 | control->aid = tx->sta->aid; | ||
| 745 | tx->sta->tx_packets++; | ||
| 746 | tx->sta->tx_fragments++; | ||
| 747 | tx->sta->tx_bytes += tx->skb->len; | ||
| 748 | if (tx->extra_frag) { | ||
| 749 | int i; | ||
| 750 | tx->sta->tx_fragments += tx->num_extra_frag; | ||
| 751 | for (i = 0; i < tx->num_extra_frag; i++) { | ||
| 752 | tx->sta->tx_bytes += | ||
| 753 | tx->extra_frag[i]->len; | ||
| 754 | } | ||
| 755 | } | ||
| 756 | } | 802 | } |
| 757 | 803 | ||
| 758 | return TX_CONTINUE; | 804 | return TX_CONTINUE; |
| 759 | } | 805 | } |
| 760 | 806 | ||
| 761 | static ieee80211_tx_result | 807 | static ieee80211_tx_result debug_noinline |
| 762 | ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx) | 808 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) |
| 763 | { | 809 | { |
| 764 | struct ieee80211_local *local = tx->local; | 810 | int i; |
| 765 | struct sk_buff *skb = tx->skb; | ||
| 766 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
| 767 | u32 load = 0, hdrtime; | ||
| 768 | struct ieee80211_rate *rate = tx->rate; | ||
| 769 | |||
| 770 | /* TODO: this could be part of tx_status handling, so that the number | ||
| 771 | * of retries would be known; TX rate should in that case be stored | ||
| 772 | * somewhere with the packet */ | ||
| 773 | |||
| 774 | /* Estimate total channel use caused by this frame */ | ||
| 775 | |||
| 776 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | ||
| 777 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
| 778 | |||
| 779 | if (tx->channel->band == IEEE80211_BAND_5GHZ || | ||
| 780 | (tx->channel->band == IEEE80211_BAND_2GHZ && | ||
| 781 | rate->flags & IEEE80211_RATE_ERP_G)) | ||
| 782 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
| 783 | else | ||
| 784 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
| 785 | |||
| 786 | load = hdrtime; | ||
| 787 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
| 788 | load += hdrtime; | ||
| 789 | |||
| 790 | if (tx->control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | ||
| 791 | load += 2 * hdrtime; | ||
| 792 | else if (tx->control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | ||
| 793 | load += hdrtime; | ||
| 794 | 811 | ||
| 795 | /* TODO: optimise again */ | 812 | if (!tx->sta) |
| 796 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | 813 | return TX_CONTINUE; |
| 797 | 814 | ||
| 815 | tx->sta->tx_packets++; | ||
| 816 | tx->sta->tx_fragments++; | ||
| 817 | tx->sta->tx_bytes += tx->skb->len; | ||
| 798 | if (tx->extra_frag) { | 818 | if (tx->extra_frag) { |
| 799 | int i; | 819 | tx->sta->tx_fragments += tx->num_extra_frag; |
| 800 | for (i = 0; i < tx->num_extra_frag; i++) { | 820 | for (i = 0; i < tx->num_extra_frag; i++) |
| 801 | load += 2 * hdrtime; | 821 | tx->sta->tx_bytes += tx->extra_frag[i]->len; |
| 802 | load += tx->extra_frag[i]->len * | ||
| 803 | tx->rate->bitrate; | ||
| 804 | } | ||
| 805 | } | 822 | } |
| 806 | 823 | ||
| 807 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
| 808 | load >>= CHAN_UTIL_SHIFT; | ||
| 809 | local->channel_use_raw += load; | ||
| 810 | if (tx->sta) | ||
| 811 | tx->sta->channel_use_raw += load; | ||
| 812 | tx->sdata->channel_use_raw += load; | ||
| 813 | |||
| 814 | return TX_CONTINUE; | 824 | return TX_CONTINUE; |
| 815 | } | 825 | } |
| 816 | 826 | ||
| 817 | 827 | ||
| 818 | typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_tx_data *); | ||
| 819 | static ieee80211_tx_handler ieee80211_tx_handlers[] = | ||
| 820 | { | ||
| 821 | ieee80211_tx_h_check_assoc, | ||
| 822 | ieee80211_tx_h_sequence, | ||
| 823 | ieee80211_tx_h_ps_buf, | ||
| 824 | ieee80211_tx_h_select_key, | ||
| 825 | ieee80211_tx_h_michael_mic_add, | ||
| 826 | ieee80211_tx_h_fragment, | ||
| 827 | ieee80211_tx_h_encrypt, | ||
| 828 | ieee80211_tx_h_rate_ctrl, | ||
| 829 | ieee80211_tx_h_misc, | ||
| 830 | ieee80211_tx_h_load_stats, | ||
| 831 | NULL | ||
| 832 | }; | ||
| 833 | |||
| 834 | /* actual transmit path */ | 828 | /* actual transmit path */ |
| 835 | 829 | ||
| 836 | /* | 830 | /* |
| @@ -854,12 +848,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 854 | (struct ieee80211_radiotap_header *) skb->data; | 848 | (struct ieee80211_radiotap_header *) skb->data; |
| 855 | struct ieee80211_supported_band *sband; | 849 | struct ieee80211_supported_band *sband; |
| 856 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 850 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
| 857 | struct ieee80211_tx_control *control = tx->control; | 851 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 858 | 852 | ||
| 859 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | 853 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
| 860 | 854 | ||
| 861 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 855 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 862 | tx->flags |= IEEE80211_TX_INJECTED; | 856 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
| 863 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 857 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
| 864 | 858 | ||
| 865 | /* | 859 | /* |
| @@ -896,7 +890,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 896 | r = &sband->bitrates[i]; | 890 | r = &sband->bitrates[i]; |
| 897 | 891 | ||
| 898 | if (r->bitrate == target_rate) { | 892 | if (r->bitrate == target_rate) { |
| 899 | tx->rate = r; | 893 | tx->rate_idx = i; |
| 900 | break; | 894 | break; |
| 901 | } | 895 | } |
| 902 | } | 896 | } |
| @@ -907,7 +901,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 907 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | 901 | * radiotap uses 0 for 1st ant, mac80211 is 1 for |
| 908 | * 1st ant | 902 | * 1st ant |
| 909 | */ | 903 | */ |
| 910 | control->antenna_sel_tx = (*iterator.this_arg) + 1; | 904 | info->antenna_sel_tx = (*iterator.this_arg) + 1; |
| 911 | break; | 905 | break; |
| 912 | 906 | ||
| 913 | #if 0 | 907 | #if 0 |
| @@ -931,8 +925,8 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 931 | skb_trim(skb, skb->len - FCS_LEN); | 925 | skb_trim(skb, skb->len - FCS_LEN); |
| 932 | } | 926 | } |
| 933 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 927 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
| 934 | control->flags &= | 928 | info->flags &= |
| 935 | ~IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 929 | ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 936 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
| 937 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 931 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
| 938 | break; | 932 | break; |
| @@ -967,12 +961,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 967 | static ieee80211_tx_result | 961 | static ieee80211_tx_result |
| 968 | __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | 962 | __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, |
| 969 | struct sk_buff *skb, | 963 | struct sk_buff *skb, |
| 970 | struct net_device *dev, | 964 | struct net_device *dev) |
| 971 | struct ieee80211_tx_control *control) | ||
| 972 | { | 965 | { |
| 973 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 966 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 974 | struct ieee80211_hdr *hdr; | 967 | struct ieee80211_hdr *hdr; |
| 975 | struct ieee80211_sub_if_data *sdata; | 968 | struct ieee80211_sub_if_data *sdata; |
| 969 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 976 | 970 | ||
| 977 | int hdrlen; | 971 | int hdrlen; |
| 978 | 972 | ||
| @@ -981,7 +975,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 981 | tx->dev = dev; /* use original interface */ | 975 | tx->dev = dev; /* use original interface */ |
| 982 | tx->local = local; | 976 | tx->local = local; |
| 983 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 977 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 984 | tx->control = control; | 978 | tx->channel = local->hw.conf.channel; |
| 979 | tx->rate_idx = -1; | ||
| 980 | tx->last_frag_rate_idx = -1; | ||
| 985 | /* | 981 | /* |
| 986 | * Set this flag (used below to indicate "automatic fragmentation"), | 982 | * Set this flag (used below to indicate "automatic fragmentation"), |
| 987 | * it will be cleared/left by radiotap as desired. | 983 | * it will be cleared/left by radiotap as desired. |
| @@ -1008,34 +1004,33 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 1008 | 1004 | ||
| 1009 | if (is_multicast_ether_addr(hdr->addr1)) { | 1005 | if (is_multicast_ether_addr(hdr->addr1)) { |
| 1010 | tx->flags &= ~IEEE80211_TX_UNICAST; | 1006 | tx->flags &= ~IEEE80211_TX_UNICAST; |
| 1011 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 1007 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
| 1012 | } else { | 1008 | } else { |
| 1013 | tx->flags |= IEEE80211_TX_UNICAST; | 1009 | tx->flags |= IEEE80211_TX_UNICAST; |
| 1014 | control->flags &= ~IEEE80211_TXCTL_NO_ACK; | 1010 | info->flags &= ~IEEE80211_TX_CTL_NO_ACK; |
| 1015 | } | 1011 | } |
| 1016 | 1012 | ||
| 1017 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 1013 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
| 1018 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 1014 | if ((tx->flags & IEEE80211_TX_UNICAST) && |
| 1019 | skb->len + FCS_LEN > local->fragmentation_threshold && | 1015 | skb->len + FCS_LEN > local->fragmentation_threshold && |
| 1020 | !local->ops->set_frag_threshold) | 1016 | !local->ops->set_frag_threshold && |
| 1017 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | ||
| 1021 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1018 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
| 1022 | else | 1019 | else |
| 1023 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 1020 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
| 1024 | } | 1021 | } |
| 1025 | 1022 | ||
| 1026 | if (!tx->sta) | 1023 | if (!tx->sta) |
| 1027 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1024 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
| 1028 | else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { | 1025 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
| 1029 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1026 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
| 1030 | tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT; | ||
| 1031 | } | ||
| 1032 | 1027 | ||
| 1033 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1028 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
| 1034 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { | 1029 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { |
| 1035 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; | 1030 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; |
| 1036 | tx->ethertype = (pos[0] << 8) | pos[1]; | 1031 | tx->ethertype = (pos[0] << 8) | pos[1]; |
| 1037 | } | 1032 | } |
| 1038 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; | 1033 | info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT; |
| 1039 | 1034 | ||
| 1040 | return TX_CONTINUE; | 1035 | return TX_CONTINUE; |
| 1041 | } | 1036 | } |
| @@ -1045,14 +1040,12 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 1045 | */ | 1040 | */ |
| 1046 | static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | 1041 | static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, |
| 1047 | struct sk_buff *skb, | 1042 | struct sk_buff *skb, |
| 1048 | struct net_device *mdev, | 1043 | struct net_device *mdev) |
| 1049 | struct ieee80211_tx_control *control) | ||
| 1050 | { | 1044 | { |
| 1051 | struct ieee80211_tx_packet_data *pkt_data; | 1045 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1052 | struct net_device *dev; | 1046 | struct net_device *dev; |
| 1053 | 1047 | ||
| 1054 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1048 | dev = dev_get_by_index(&init_net, info->control.ifindex); |
| 1055 | dev = dev_get_by_index(&init_net, pkt_data->ifindex); | ||
| 1056 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { | 1049 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { |
| 1057 | dev_put(dev); | 1050 | dev_put(dev); |
| 1058 | dev = NULL; | 1051 | dev = NULL; |
| @@ -1060,7 +1053,7 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 1060 | if (unlikely(!dev)) | 1053 | if (unlikely(!dev)) |
| 1061 | return -ENODEV; | 1054 | return -ENODEV; |
| 1062 | /* initialises tx with control */ | 1055 | /* initialises tx with control */ |
| 1063 | __ieee80211_tx_prepare(tx, skb, dev, control); | 1056 | __ieee80211_tx_prepare(tx, skb, dev); |
| 1064 | dev_put(dev); | 1057 | dev_put(dev); |
| 1065 | return 0; | 1058 | return 0; |
| 1066 | } | 1059 | } |
| @@ -1068,50 +1061,49 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 1068 | static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | 1061 | static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, |
| 1069 | struct ieee80211_tx_data *tx) | 1062 | struct ieee80211_tx_data *tx) |
| 1070 | { | 1063 | { |
| 1071 | struct ieee80211_tx_control *control = tx->control; | 1064 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1072 | int ret, i; | 1065 | int ret, i; |
| 1073 | 1066 | ||
| 1074 | if (!ieee80211_qdisc_installed(local->mdev) && | 1067 | if (netif_subqueue_stopped(local->mdev, skb)) |
| 1075 | __ieee80211_queue_stopped(local, 0)) { | ||
| 1076 | netif_stop_queue(local->mdev); | ||
| 1077 | return IEEE80211_TX_AGAIN; | 1068 | return IEEE80211_TX_AGAIN; |
| 1078 | } | 1069 | |
| 1079 | if (skb) { | 1070 | if (skb) { |
| 1080 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), | 1071 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), |
| 1081 | "TX to low-level driver", skb); | 1072 | "TX to low-level driver", skb); |
| 1082 | ret = local->ops->tx(local_to_hw(local), skb, control); | 1073 | ret = local->ops->tx(local_to_hw(local), skb); |
| 1083 | if (ret) | 1074 | if (ret) |
| 1084 | return IEEE80211_TX_AGAIN; | 1075 | return IEEE80211_TX_AGAIN; |
| 1085 | local->mdev->trans_start = jiffies; | 1076 | local->mdev->trans_start = jiffies; |
| 1086 | ieee80211_led_tx(local, 1); | 1077 | ieee80211_led_tx(local, 1); |
| 1087 | } | 1078 | } |
| 1088 | if (tx->extra_frag) { | 1079 | if (tx->extra_frag) { |
| 1089 | control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | | ||
| 1090 | IEEE80211_TXCTL_USE_CTS_PROTECT | | ||
| 1091 | IEEE80211_TXCTL_CLEAR_PS_FILT | | ||
| 1092 | IEEE80211_TXCTL_FIRST_FRAGMENT); | ||
| 1093 | for (i = 0; i < tx->num_extra_frag; i++) { | 1080 | for (i = 0; i < tx->num_extra_frag; i++) { |
| 1094 | if (!tx->extra_frag[i]) | 1081 | if (!tx->extra_frag[i]) |
| 1095 | continue; | 1082 | continue; |
| 1096 | if (__ieee80211_queue_stopped(local, control->queue)) | 1083 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
| 1084 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | ||
| 1085 | IEEE80211_TX_CTL_USE_CTS_PROTECT | | ||
| 1086 | IEEE80211_TX_CTL_CLEAR_PS_FILT | | ||
| 1087 | IEEE80211_TX_CTL_FIRST_FRAGMENT); | ||
| 1088 | if (netif_subqueue_stopped(local->mdev, | ||
| 1089 | tx->extra_frag[i])) | ||
| 1097 | return IEEE80211_TX_FRAG_AGAIN; | 1090 | return IEEE80211_TX_FRAG_AGAIN; |
| 1098 | if (i == tx->num_extra_frag) { | 1091 | if (i == tx->num_extra_frag) { |
| 1099 | control->tx_rate = tx->last_frag_rate; | 1092 | info->tx_rate_idx = tx->last_frag_rate_idx; |
| 1100 | 1093 | ||
| 1101 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | 1094 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) |
| 1102 | control->flags |= | 1095 | info->flags |= |
| 1103 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1096 | IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
| 1104 | else | 1097 | else |
| 1105 | control->flags &= | 1098 | info->flags &= |
| 1106 | ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1099 | ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
| 1107 | } | 1100 | } |
| 1108 | 1101 | ||
| 1109 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), | 1102 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), |
| 1110 | "TX to low-level driver", | 1103 | "TX to low-level driver", |
| 1111 | tx->extra_frag[i]); | 1104 | tx->extra_frag[i]); |
| 1112 | ret = local->ops->tx(local_to_hw(local), | 1105 | ret = local->ops->tx(local_to_hw(local), |
| 1113 | tx->extra_frag[i], | 1106 | tx->extra_frag[i]); |
| 1114 | control); | ||
| 1115 | if (ret) | 1107 | if (ret) |
| 1116 | return IEEE80211_TX_FRAG_AGAIN; | 1108 | return IEEE80211_TX_FRAG_AGAIN; |
| 1117 | local->mdev->trans_start = jiffies; | 1109 | local->mdev->trans_start = jiffies; |
| @@ -1124,17 +1116,65 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 1124 | return IEEE80211_TX_OK; | 1116 | return IEEE80211_TX_OK; |
| 1125 | } | 1117 | } |
| 1126 | 1118 | ||
| 1127 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | 1119 | /* |
| 1128 | struct ieee80211_tx_control *control) | 1120 | * Invoke TX handlers, return 0 on success and non-zero if the |
| 1121 | * frame was dropped or queued. | ||
| 1122 | */ | ||
| 1123 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | ||
| 1124 | { | ||
| 1125 | struct sk_buff *skb = tx->skb; | ||
| 1126 | ieee80211_tx_result res = TX_DROP; | ||
| 1127 | int i; | ||
| 1128 | |||
| 1129 | #define CALL_TXH(txh) \ | ||
| 1130 | res = txh(tx); \ | ||
| 1131 | if (res != TX_CONTINUE) \ | ||
| 1132 | goto txh_done; | ||
| 1133 | |||
| 1134 | CALL_TXH(ieee80211_tx_h_check_assoc) | ||
| 1135 | CALL_TXH(ieee80211_tx_h_ps_buf) | ||
| 1136 | CALL_TXH(ieee80211_tx_h_select_key) | ||
| 1137 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | ||
| 1138 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | ||
| 1139 | CALL_TXH(ieee80211_tx_h_misc) | ||
| 1140 | CALL_TXH(ieee80211_tx_h_sequence) | ||
| 1141 | CALL_TXH(ieee80211_tx_h_fragment) | ||
| 1142 | /* handlers after fragment must be aware of tx info fragmentation! */ | ||
| 1143 | CALL_TXH(ieee80211_tx_h_encrypt) | ||
| 1144 | CALL_TXH(ieee80211_tx_h_calculate_duration) | ||
| 1145 | CALL_TXH(ieee80211_tx_h_stats) | ||
| 1146 | #undef CALL_TXH | ||
| 1147 | |||
| 1148 | txh_done: | ||
| 1149 | if (unlikely(res == TX_DROP)) { | ||
| 1150 | I802_DEBUG_INC(tx->local->tx_handlers_drop); | ||
| 1151 | dev_kfree_skb(skb); | ||
| 1152 | for (i = 0; i < tx->num_extra_frag; i++) | ||
| 1153 | if (tx->extra_frag[i]) | ||
| 1154 | dev_kfree_skb(tx->extra_frag[i]); | ||
| 1155 | kfree(tx->extra_frag); | ||
| 1156 | return -1; | ||
| 1157 | } else if (unlikely(res == TX_QUEUED)) { | ||
| 1158 | I802_DEBUG_INC(tx->local->tx_handlers_queued); | ||
| 1159 | return -1; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | return 0; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) | ||
| 1129 | { | 1166 | { |
| 1130 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1167 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 1131 | struct sta_info *sta; | 1168 | struct sta_info *sta; |
| 1132 | ieee80211_tx_handler *handler; | ||
| 1133 | struct ieee80211_tx_data tx; | 1169 | struct ieee80211_tx_data tx; |
| 1134 | ieee80211_tx_result res = TX_DROP, res_prepare; | 1170 | ieee80211_tx_result res_prepare; |
| 1135 | int ret, i, retries = 0; | 1171 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1172 | int ret, i; | ||
| 1173 | u16 queue; | ||
| 1174 | |||
| 1175 | queue = skb_get_queue_mapping(skb); | ||
| 1136 | 1176 | ||
| 1137 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); | 1177 | WARN_ON(test_bit(queue, local->queues_pending)); |
| 1138 | 1178 | ||
| 1139 | if (unlikely(skb->len < 10)) { | 1179 | if (unlikely(skb->len < 10)) { |
| 1140 | dev_kfree_skb(skb); | 1180 | dev_kfree_skb(skb); |
| @@ -1144,7 +1184,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
| 1144 | rcu_read_lock(); | 1184 | rcu_read_lock(); |
| 1145 | 1185 | ||
| 1146 | /* initialises tx */ | 1186 | /* initialises tx */ |
| 1147 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); | 1187 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev); |
| 1148 | 1188 | ||
| 1149 | if (res_prepare == TX_DROP) { | 1189 | if (res_prepare == TX_DROP) { |
| 1150 | dev_kfree_skb(skb); | 1190 | dev_kfree_skb(skb); |
| @@ -1154,86 +1194,53 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
| 1154 | 1194 | ||
| 1155 | sta = tx.sta; | 1195 | sta = tx.sta; |
| 1156 | tx.channel = local->hw.conf.channel; | 1196 | tx.channel = local->hw.conf.channel; |
| 1197 | info->band = tx.channel->band; | ||
| 1157 | 1198 | ||
| 1158 | for (handler = ieee80211_tx_handlers; *handler != NULL; | 1199 | if (invoke_tx_handlers(&tx)) |
| 1159 | handler++) { | 1200 | goto out; |
| 1160 | res = (*handler)(&tx); | ||
| 1161 | if (res != TX_CONTINUE) | ||
| 1162 | break; | ||
| 1163 | } | ||
| 1164 | |||
| 1165 | skb = tx.skb; /* handlers are allowed to change skb */ | ||
| 1166 | |||
| 1167 | if (unlikely(res == TX_DROP)) { | ||
| 1168 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
| 1169 | goto drop; | ||
| 1170 | } | ||
| 1171 | |||
| 1172 | if (unlikely(res == TX_QUEUED)) { | ||
| 1173 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
| 1174 | rcu_read_unlock(); | ||
| 1175 | return 0; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | if (tx.extra_frag) { | ||
| 1179 | for (i = 0; i < tx.num_extra_frag; i++) { | ||
| 1180 | int next_len, dur; | ||
| 1181 | struct ieee80211_hdr *hdr = | ||
| 1182 | (struct ieee80211_hdr *) | ||
| 1183 | tx.extra_frag[i]->data; | ||
| 1184 | |||
| 1185 | if (i + 1 < tx.num_extra_frag) { | ||
| 1186 | next_len = tx.extra_frag[i + 1]->len; | ||
| 1187 | } else { | ||
| 1188 | next_len = 0; | ||
| 1189 | tx.rate = tx.last_frag_rate; | ||
| 1190 | } | ||
| 1191 | dur = ieee80211_duration(&tx, 0, next_len); | ||
| 1192 | hdr->duration_id = cpu_to_le16(dur); | ||
| 1193 | } | ||
| 1194 | } | ||
| 1195 | 1201 | ||
| 1196 | retry: | 1202 | retry: |
| 1197 | ret = __ieee80211_tx(local, skb, &tx); | 1203 | ret = __ieee80211_tx(local, skb, &tx); |
| 1198 | if (ret) { | 1204 | if (ret) { |
| 1199 | struct ieee80211_tx_stored_packet *store = | 1205 | struct ieee80211_tx_stored_packet *store; |
| 1200 | &local->pending_packet[control->queue]; | 1206 | |
| 1207 | /* | ||
| 1208 | * Since there are no fragmented frames on A-MPDU | ||
| 1209 | * queues, there's no reason for a driver to reject | ||
| 1210 | * a frame there, warn and drop it. | ||
| 1211 | */ | ||
| 1212 | if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw))) | ||
| 1213 | goto drop; | ||
| 1214 | |||
| 1215 | store = &local->pending_packet[queue]; | ||
| 1201 | 1216 | ||
| 1202 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1217 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
| 1203 | skb = NULL; | 1218 | skb = NULL; |
| 1204 | set_bit(IEEE80211_LINK_STATE_PENDING, | 1219 | set_bit(queue, local->queues_pending); |
| 1205 | &local->state[control->queue]); | ||
| 1206 | smp_mb(); | 1220 | smp_mb(); |
| 1207 | /* When the driver gets out of buffers during sending of | 1221 | /* |
| 1208 | * fragments and calls ieee80211_stop_queue, there is | 1222 | * When the driver gets out of buffers during sending of |
| 1209 | * a small window between IEEE80211_LINK_STATE_XOFF and | 1223 | * fragments and calls ieee80211_stop_queue, the netif |
| 1210 | * IEEE80211_LINK_STATE_PENDING flags are set. If a buffer | 1224 | * subqueue is stopped. There is, however, a small window |
| 1225 | * in which the PENDING bit is not yet set. If a buffer | ||
| 1211 | * gets available in that window (i.e. driver calls | 1226 | * gets available in that window (i.e. driver calls |
| 1212 | * ieee80211_wake_queue), we would end up with ieee80211_tx | 1227 | * ieee80211_wake_queue), we would end up with ieee80211_tx |
| 1213 | * called with IEEE80211_LINK_STATE_PENDING. Prevent this by | 1228 | * called with the PENDING bit still set. Prevent this by |
| 1214 | * continuing transmitting here when that situation is | 1229 | * continuing transmitting here when that situation is |
| 1215 | * possible to have happened. */ | 1230 | * possible to have happened. |
| 1216 | if (!__ieee80211_queue_stopped(local, control->queue)) { | 1231 | */ |
| 1217 | clear_bit(IEEE80211_LINK_STATE_PENDING, | 1232 | if (!__netif_subqueue_stopped(local->mdev, queue)) { |
| 1218 | &local->state[control->queue]); | 1233 | clear_bit(queue, local->queues_pending); |
| 1219 | retries++; | ||
| 1220 | /* | ||
| 1221 | * Driver bug, it's rejecting packets but | ||
| 1222 | * not stopping queues. | ||
| 1223 | */ | ||
| 1224 | if (WARN_ON_ONCE(retries > 5)) | ||
| 1225 | goto drop; | ||
| 1226 | goto retry; | 1234 | goto retry; |
| 1227 | } | 1235 | } |
| 1228 | memcpy(&store->control, control, | ||
| 1229 | sizeof(struct ieee80211_tx_control)); | ||
| 1230 | store->skb = skb; | 1236 | store->skb = skb; |
| 1231 | store->extra_frag = tx.extra_frag; | 1237 | store->extra_frag = tx.extra_frag; |
| 1232 | store->num_extra_frag = tx.num_extra_frag; | 1238 | store->num_extra_frag = tx.num_extra_frag; |
| 1233 | store->last_frag_rate = tx.last_frag_rate; | 1239 | store->last_frag_rate_idx = tx.last_frag_rate_idx; |
| 1234 | store->last_frag_rate_ctrl_probe = | 1240 | store->last_frag_rate_ctrl_probe = |
| 1235 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | 1241 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); |
| 1236 | } | 1242 | } |
| 1243 | out: | ||
| 1237 | rcu_read_unlock(); | 1244 | rcu_read_unlock(); |
| 1238 | return 0; | 1245 | return 0; |
| 1239 | 1246 | ||
| @@ -1250,24 +1257,57 @@ retry: | |||
| 1250 | 1257 | ||
| 1251 | /* device xmit handlers */ | 1258 | /* device xmit handlers */ |
| 1252 | 1259 | ||
| 1260 | static int ieee80211_skb_resize(struct ieee80211_local *local, | ||
| 1261 | struct sk_buff *skb, | ||
| 1262 | int head_need, bool may_encrypt) | ||
| 1263 | { | ||
| 1264 | int tail_need = 0; | ||
| 1265 | |||
| 1266 | /* | ||
| 1267 | * This could be optimised, devices that do full hardware | ||
| 1268 | * crypto (including TKIP MMIC) need no tailroom... But we | ||
| 1269 | * have no drivers for such devices currently. | ||
| 1270 | */ | ||
| 1271 | if (may_encrypt) { | ||
| 1272 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | ||
| 1273 | tail_need -= skb_tailroom(skb); | ||
| 1274 | tail_need = max_t(int, tail_need, 0); | ||
| 1275 | } | ||
| 1276 | |||
| 1277 | if (head_need || tail_need) { | ||
| 1278 | /* Sorry. Can't account for this any more */ | ||
| 1279 | skb_orphan(skb); | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | if (skb_header_cloned(skb)) | ||
| 1283 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | ||
| 1284 | else | ||
| 1285 | I802_DEBUG_INC(local->tx_expand_skb_head); | ||
| 1286 | |||
| 1287 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { | ||
| 1288 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", | ||
| 1289 | wiphy_name(local->hw.wiphy)); | ||
| 1290 | return -ENOMEM; | ||
| 1291 | } | ||
| 1292 | |||
| 1293 | /* update truesize too */ | ||
| 1294 | skb->truesize += head_need + tail_need; | ||
| 1295 | |||
| 1296 | return 0; | ||
| 1297 | } | ||
| 1298 | |||
| 1253 | int ieee80211_master_start_xmit(struct sk_buff *skb, | 1299 | int ieee80211_master_start_xmit(struct sk_buff *skb, |
| 1254 | struct net_device *dev) | 1300 | struct net_device *dev) |
| 1255 | { | 1301 | { |
| 1256 | struct ieee80211_tx_control control; | 1302 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1257 | struct ieee80211_tx_packet_data *pkt_data; | ||
| 1258 | struct net_device *odev = NULL; | 1303 | struct net_device *odev = NULL; |
| 1259 | struct ieee80211_sub_if_data *osdata; | 1304 | struct ieee80211_sub_if_data *osdata; |
| 1260 | int headroom; | 1305 | int headroom; |
| 1306 | bool may_encrypt; | ||
| 1261 | int ret; | 1307 | int ret; |
| 1262 | 1308 | ||
| 1263 | /* | 1309 | if (info->control.ifindex) |
| 1264 | * copy control out of the skb so other people can use skb->cb | 1310 | odev = dev_get_by_index(&init_net, info->control.ifindex); |
| 1265 | */ | ||
| 1266 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | ||
| 1267 | memset(&control, 0, sizeof(struct ieee80211_tx_control)); | ||
| 1268 | |||
| 1269 | if (pkt_data->ifindex) | ||
| 1270 | odev = dev_get_by_index(&init_net, pkt_data->ifindex); | ||
| 1271 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { | 1311 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { |
| 1272 | dev_put(odev); | 1312 | dev_put(odev); |
| 1273 | odev = NULL; | 1313 | odev = NULL; |
| @@ -1280,32 +1320,25 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
| 1280 | dev_kfree_skb(skb); | 1320 | dev_kfree_skb(skb); |
| 1281 | return 0; | 1321 | return 0; |
| 1282 | } | 1322 | } |
| 1323 | |||
| 1283 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); | 1324 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); |
| 1284 | 1325 | ||
| 1285 | headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM; | 1326 | may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT); |
| 1286 | if (skb_headroom(skb) < headroom) { | 1327 | |
| 1287 | if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { | 1328 | headroom = osdata->local->tx_headroom; |
| 1288 | dev_kfree_skb(skb); | 1329 | if (may_encrypt) |
| 1289 | dev_put(odev); | 1330 | headroom += IEEE80211_ENCRYPT_HEADROOM; |
| 1290 | return 0; | 1331 | headroom -= skb_headroom(skb); |
| 1291 | } | 1332 | headroom = max_t(int, 0, headroom); |
| 1333 | |||
| 1334 | if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) { | ||
| 1335 | dev_kfree_skb(skb); | ||
| 1336 | dev_put(odev); | ||
| 1337 | return 0; | ||
| 1292 | } | 1338 | } |
| 1293 | 1339 | ||
| 1294 | control.vif = &osdata->vif; | 1340 | info->control.vif = &osdata->vif; |
| 1295 | control.type = osdata->vif.type; | 1341 | ret = ieee80211_tx(odev, skb); |
| 1296 | if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS) | ||
| 1297 | control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS; | ||
| 1298 | if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT) | ||
| 1299 | control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
| 1300 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) | ||
| 1301 | control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
| 1302 | if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME) | ||
| 1303 | control.flags |= IEEE80211_TXCTL_EAPOL_FRAME; | ||
| 1304 | if (pkt_data->flags & IEEE80211_TXPD_AMPDU) | ||
| 1305 | control.flags |= IEEE80211_TXCTL_AMPDU; | ||
| 1306 | control.queue = pkt_data->queue; | ||
| 1307 | |||
| 1308 | ret = ieee80211_tx(odev, skb, &control); | ||
| 1309 | dev_put(odev); | 1342 | dev_put(odev); |
| 1310 | 1343 | ||
| 1311 | return ret; | 1344 | return ret; |
| @@ -1315,7 +1348,7 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
| 1315 | struct net_device *dev) | 1348 | struct net_device *dev) |
| 1316 | { | 1349 | { |
| 1317 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1350 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 1318 | struct ieee80211_tx_packet_data *pkt_data; | 1351 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 1319 | struct ieee80211_radiotap_header *prthdr = | 1352 | struct ieee80211_radiotap_header *prthdr = |
| 1320 | (struct ieee80211_radiotap_header *)skb->data; | 1353 | (struct ieee80211_radiotap_header *)skb->data; |
| 1321 | u16 len_rthdr; | 1354 | u16 len_rthdr; |
| @@ -1337,12 +1370,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
| 1337 | 1370 | ||
| 1338 | skb->dev = local->mdev; | 1371 | skb->dev = local->mdev; |
| 1339 | 1372 | ||
| 1340 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | ||
| 1341 | memset(pkt_data, 0, sizeof(*pkt_data)); | ||
| 1342 | /* needed because we set skb device to master */ | 1373 | /* needed because we set skb device to master */ |
| 1343 | pkt_data->ifindex = dev->ifindex; | 1374 | info->control.ifindex = dev->ifindex; |
| 1344 | 1375 | ||
| 1345 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 1376 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 1377 | /* Interfaces should always request a status report */ | ||
| 1378 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
| 1346 | 1379 | ||
| 1347 | /* | 1380 | /* |
| 1348 | * fix up the pointers accounting for the radiotap | 1381 | * fix up the pointers accounting for the radiotap |
| @@ -1386,10 +1419,11 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1386 | struct net_device *dev) | 1419 | struct net_device *dev) |
| 1387 | { | 1420 | { |
| 1388 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1421 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 1389 | struct ieee80211_tx_packet_data *pkt_data; | 1422 | struct ieee80211_tx_info *info; |
| 1390 | struct ieee80211_sub_if_data *sdata; | 1423 | struct ieee80211_sub_if_data *sdata; |
| 1391 | int ret = 1, head_need; | 1424 | int ret = 1, head_need; |
| 1392 | u16 ethertype, hdrlen, meshhdrlen = 0, fc; | 1425 | u16 ethertype, hdrlen, meshhdrlen = 0; |
| 1426 | __le16 fc; | ||
| 1393 | struct ieee80211_hdr hdr; | 1427 | struct ieee80211_hdr hdr; |
| 1394 | struct ieee80211s_hdr mesh_hdr; | 1428 | struct ieee80211s_hdr mesh_hdr; |
| 1395 | const u8 *encaps_data; | 1429 | const u8 *encaps_data; |
| @@ -1400,8 +1434,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1400 | 1434 | ||
| 1401 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1435 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1402 | if (unlikely(skb->len < ETH_HLEN)) { | 1436 | if (unlikely(skb->len < ETH_HLEN)) { |
| 1403 | printk(KERN_DEBUG "%s: short skb (len=%d)\n", | ||
| 1404 | dev->name, skb->len); | ||
| 1405 | ret = 0; | 1437 | ret = 0; |
| 1406 | goto fail; | 1438 | goto fail; |
| 1407 | } | 1439 | } |
| @@ -1412,12 +1444,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1412 | /* convert Ethernet header to proper 802.11 header (based on | 1444 | /* convert Ethernet header to proper 802.11 header (based on |
| 1413 | * operation mode) */ | 1445 | * operation mode) */ |
| 1414 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1446 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
| 1415 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; | 1447 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
| 1416 | 1448 | ||
| 1417 | switch (sdata->vif.type) { | 1449 | switch (sdata->vif.type) { |
| 1418 | case IEEE80211_IF_TYPE_AP: | 1450 | case IEEE80211_IF_TYPE_AP: |
| 1419 | case IEEE80211_IF_TYPE_VLAN: | 1451 | case IEEE80211_IF_TYPE_VLAN: |
| 1420 | fc |= IEEE80211_FCTL_FROMDS; | 1452 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
| 1421 | /* DA BSSID SA */ | 1453 | /* DA BSSID SA */ |
| 1422 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1454 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
| 1423 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1455 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
| @@ -1425,7 +1457,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1425 | hdrlen = 24; | 1457 | hdrlen = 24; |
| 1426 | break; | 1458 | break; |
| 1427 | case IEEE80211_IF_TYPE_WDS: | 1459 | case IEEE80211_IF_TYPE_WDS: |
| 1428 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1460 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
| 1429 | /* RA TA DA SA */ | 1461 | /* RA TA DA SA */ |
| 1430 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); | 1462 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); |
| 1431 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1463 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
| @@ -1435,7 +1467,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1435 | break; | 1467 | break; |
| 1436 | #ifdef CONFIG_MAC80211_MESH | 1468 | #ifdef CONFIG_MAC80211_MESH |
| 1437 | case IEEE80211_IF_TYPE_MESH_POINT: | 1469 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 1438 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1470 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
| 1439 | /* RA TA DA SA */ | 1471 | /* RA TA DA SA */ |
| 1440 | if (is_multicast_ether_addr(skb->data)) | 1472 | if (is_multicast_ether_addr(skb->data)) |
| 1441 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1473 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
| @@ -1465,7 +1497,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1465 | break; | 1497 | break; |
| 1466 | #endif | 1498 | #endif |
| 1467 | case IEEE80211_IF_TYPE_STA: | 1499 | case IEEE80211_IF_TYPE_STA: |
| 1468 | fc |= IEEE80211_FCTL_TODS; | 1500 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
| 1469 | /* BSSID SA DA */ | 1501 | /* BSSID SA DA */ |
| 1470 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); | 1502 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); |
| 1471 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1503 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
| @@ -1493,13 +1525,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1493 | rcu_read_lock(); | 1525 | rcu_read_lock(); |
| 1494 | sta = sta_info_get(local, hdr.addr1); | 1526 | sta = sta_info_get(local, hdr.addr1); |
| 1495 | if (sta) | 1527 | if (sta) |
| 1496 | sta_flags = sta->flags; | 1528 | sta_flags = get_sta_flags(sta); |
| 1497 | rcu_read_unlock(); | 1529 | rcu_read_unlock(); |
| 1498 | } | 1530 | } |
| 1499 | 1531 | ||
| 1500 | /* receiver is QoS enabled, use a QoS type frame */ | 1532 | /* receiver and we are QoS enabled, use a QoS type frame */ |
| 1501 | if (sta_flags & WLAN_STA_WME) { | 1533 | if (sta_flags & WLAN_STA_WME && |
| 1502 | fc |= IEEE80211_STYPE_QOS_DATA; | 1534 | ieee80211_num_regular_queues(&local->hw) >= 4) { |
| 1535 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
| 1503 | hdrlen += 2; | 1536 | hdrlen += 2; |
| 1504 | } | 1537 | } |
| 1505 | 1538 | ||
| @@ -1527,7 +1560,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1527 | goto fail; | 1560 | goto fail; |
| 1528 | } | 1561 | } |
| 1529 | 1562 | ||
| 1530 | hdr.frame_control = cpu_to_le16(fc); | 1563 | hdr.frame_control = fc; |
| 1531 | hdr.duration_id = 0; | 1564 | hdr.duration_id = 0; |
| 1532 | hdr.seq_ctrl = 0; | 1565 | hdr.seq_ctrl = 0; |
| 1533 | 1566 | ||
| @@ -1562,32 +1595,26 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1562 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and | 1595 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and |
| 1563 | * alloc_skb() (net/core/skbuff.c) | 1596 | * alloc_skb() (net/core/skbuff.c) |
| 1564 | */ | 1597 | */ |
| 1565 | head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom; | 1598 | head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); |
| 1566 | head_need -= skb_headroom(skb); | ||
| 1567 | 1599 | ||
| 1568 | /* We are going to modify skb data, so make a copy of it if happens to | 1600 | /* |
| 1569 | * be cloned. This could happen, e.g., with Linux bridge code passing | 1601 | * So we need to modify the skb header and hence need a copy of |
| 1570 | * us broadcast frames. */ | 1602 | * that. The head_need variable above doesn't, so far, include |
| 1603 | * the needed header space that we don't need right away. If we | ||
| 1604 | * can, then we don't reallocate right now but only after the | ||
| 1605 | * frame arrives at the master device (if it does...) | ||
| 1606 | * | ||
| 1607 | * If we cannot, however, then we will reallocate to include all | ||
| 1608 | * the ever needed space. Also, if we need to reallocate it anyway, | ||
| 1609 | * make it big enough for everything we may ever need. | ||
| 1610 | */ | ||
| 1571 | 1611 | ||
| 1572 | if (head_need > 0 || skb_cloned(skb)) { | 1612 | if (head_need > 0 || skb_cloned(skb)) { |
| 1573 | #if 0 | 1613 | head_need += IEEE80211_ENCRYPT_HEADROOM; |
| 1574 | printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " | 1614 | head_need += local->tx_headroom; |
| 1575 | "of headroom\n", dev->name, head_need); | 1615 | head_need = max_t(int, 0, head_need); |
| 1576 | #endif | 1616 | if (ieee80211_skb_resize(local, skb, head_need, true)) |
| 1577 | |||
| 1578 | if (skb_cloned(skb)) | ||
| 1579 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | ||
| 1580 | else | ||
| 1581 | I802_DEBUG_INC(local->tx_expand_skb_head); | ||
| 1582 | /* Since we have to reallocate the buffer, make sure that there | ||
| 1583 | * is enough room for possible WEP IV/ICV and TKIP (8 bytes | ||
| 1584 | * before payload and 12 after). */ | ||
| 1585 | if (pskb_expand_head(skb, (head_need > 0 ? head_need + 8 : 8), | ||
| 1586 | 12, GFP_ATOMIC)) { | ||
| 1587 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer" | ||
| 1588 | "\n", dev->name); | ||
| 1589 | goto fail; | 1617 | goto fail; |
| 1590 | } | ||
| 1591 | } | 1618 | } |
| 1592 | 1619 | ||
| 1593 | if (encaps_data) { | 1620 | if (encaps_data) { |
| @@ -1602,7 +1629,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1602 | h_pos += meshhdrlen; | 1629 | h_pos += meshhdrlen; |
| 1603 | } | 1630 | } |
| 1604 | 1631 | ||
| 1605 | if (fc & IEEE80211_STYPE_QOS_DATA) { | 1632 | if (ieee80211_is_data_qos(fc)) { |
| 1606 | __le16 *qos_control; | 1633 | __le16 *qos_control; |
| 1607 | 1634 | ||
| 1608 | qos_control = (__le16*) skb_push(skb, 2); | 1635 | qos_control = (__le16*) skb_push(skb, 2); |
| @@ -1618,11 +1645,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1618 | nh_pos += hdrlen; | 1645 | nh_pos += hdrlen; |
| 1619 | h_pos += hdrlen; | 1646 | h_pos += hdrlen; |
| 1620 | 1647 | ||
| 1621 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1648 | info = IEEE80211_SKB_CB(skb); |
| 1622 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 1649 | memset(info, 0, sizeof(*info)); |
| 1623 | pkt_data->ifindex = dev->ifindex; | 1650 | info->control.ifindex = dev->ifindex; |
| 1624 | if (ethertype == ETH_P_PAE) | 1651 | if (ethertype == ETH_P_PAE) |
| 1625 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | 1652 | info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME; |
| 1653 | |||
| 1654 | /* Interfaces should always request a status report */ | ||
| 1655 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
| 1626 | 1656 | ||
| 1627 | skb->dev = local->mdev; | 1657 | skb->dev = local->mdev; |
| 1628 | dev->stats.tx_packets++; | 1658 | dev->stats.tx_packets++; |
| @@ -1647,46 +1677,55 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
| 1647 | return ret; | 1677 | return ret; |
| 1648 | } | 1678 | } |
| 1649 | 1679 | ||
| 1650 | /* helper functions for pending packets for when queues are stopped */ | ||
| 1651 | 1680 | ||
| 1681 | /* | ||
| 1682 | * ieee80211_clear_tx_pending may not be called in a context where | ||
| 1683 | * it is possible that it packets could come in again. | ||
| 1684 | */ | ||
| 1652 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) | 1685 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) |
| 1653 | { | 1686 | { |
| 1654 | int i, j; | 1687 | int i, j; |
| 1655 | struct ieee80211_tx_stored_packet *store; | 1688 | struct ieee80211_tx_stored_packet *store; |
| 1656 | 1689 | ||
| 1657 | for (i = 0; i < local->hw.queues; i++) { | 1690 | for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { |
| 1658 | if (!__ieee80211_queue_pending(local, i)) | 1691 | if (!test_bit(i, local->queues_pending)) |
| 1659 | continue; | 1692 | continue; |
| 1660 | store = &local->pending_packet[i]; | 1693 | store = &local->pending_packet[i]; |
| 1661 | kfree_skb(store->skb); | 1694 | kfree_skb(store->skb); |
| 1662 | for (j = 0; j < store->num_extra_frag; j++) | 1695 | for (j = 0; j < store->num_extra_frag; j++) |
| 1663 | kfree_skb(store->extra_frag[j]); | 1696 | kfree_skb(store->extra_frag[j]); |
| 1664 | kfree(store->extra_frag); | 1697 | kfree(store->extra_frag); |
| 1665 | clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[i]); | 1698 | clear_bit(i, local->queues_pending); |
| 1666 | } | 1699 | } |
| 1667 | } | 1700 | } |
| 1668 | 1701 | ||
| 1702 | /* | ||
| 1703 | * Transmit all pending packets. Called from tasklet, locks master device | ||
| 1704 | * TX lock so that no new packets can come in. | ||
| 1705 | */ | ||
| 1669 | void ieee80211_tx_pending(unsigned long data) | 1706 | void ieee80211_tx_pending(unsigned long data) |
| 1670 | { | 1707 | { |
| 1671 | struct ieee80211_local *local = (struct ieee80211_local *)data; | 1708 | struct ieee80211_local *local = (struct ieee80211_local *)data; |
| 1672 | struct net_device *dev = local->mdev; | 1709 | struct net_device *dev = local->mdev; |
| 1673 | struct ieee80211_tx_stored_packet *store; | 1710 | struct ieee80211_tx_stored_packet *store; |
| 1674 | struct ieee80211_tx_data tx; | 1711 | struct ieee80211_tx_data tx; |
| 1675 | int i, ret, reschedule = 0; | 1712 | int i, ret; |
| 1676 | 1713 | ||
| 1677 | netif_tx_lock_bh(dev); | 1714 | netif_tx_lock_bh(dev); |
| 1678 | for (i = 0; i < local->hw.queues; i++) { | 1715 | for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { |
| 1679 | if (__ieee80211_queue_stopped(local, i)) | 1716 | /* Check that this queue is ok */ |
| 1717 | if (__netif_subqueue_stopped(local->mdev, i)) | ||
| 1680 | continue; | 1718 | continue; |
| 1681 | if (!__ieee80211_queue_pending(local, i)) { | 1719 | |
| 1682 | reschedule = 1; | 1720 | if (!test_bit(i, local->queues_pending)) { |
| 1721 | ieee80211_wake_queue(&local->hw, i); | ||
| 1683 | continue; | 1722 | continue; |
| 1684 | } | 1723 | } |
| 1724 | |||
| 1685 | store = &local->pending_packet[i]; | 1725 | store = &local->pending_packet[i]; |
| 1686 | tx.control = &store->control; | ||
| 1687 | tx.extra_frag = store->extra_frag; | 1726 | tx.extra_frag = store->extra_frag; |
| 1688 | tx.num_extra_frag = store->num_extra_frag; | 1727 | tx.num_extra_frag = store->num_extra_frag; |
| 1689 | tx.last_frag_rate = store->last_frag_rate; | 1728 | tx.last_frag_rate_idx = store->last_frag_rate_idx; |
| 1690 | tx.flags = 0; | 1729 | tx.flags = 0; |
| 1691 | if (store->last_frag_rate_ctrl_probe) | 1730 | if (store->last_frag_rate_ctrl_probe) |
| 1692 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 1731 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
| @@ -1695,19 +1734,11 @@ void ieee80211_tx_pending(unsigned long data) | |||
| 1695 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1734 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
| 1696 | store->skb = NULL; | 1735 | store->skb = NULL; |
| 1697 | } else { | 1736 | } else { |
| 1698 | clear_bit(IEEE80211_LINK_STATE_PENDING, | 1737 | clear_bit(i, local->queues_pending); |
| 1699 | &local->state[i]); | 1738 | ieee80211_wake_queue(&local->hw, i); |
| 1700 | reschedule = 1; | ||
| 1701 | } | 1739 | } |
| 1702 | } | 1740 | } |
| 1703 | netif_tx_unlock_bh(dev); | 1741 | netif_tx_unlock_bh(dev); |
| 1704 | if (reschedule) { | ||
| 1705 | if (!ieee80211_qdisc_installed(dev)) { | ||
| 1706 | if (!__ieee80211_queue_stopped(local, 0)) | ||
| 1707 | netif_wake_queue(dev); | ||
| 1708 | } else | ||
| 1709 | netif_schedule(dev); | ||
| 1710 | } | ||
| 1711 | } | 1742 | } |
| 1712 | 1743 | ||
| 1713 | /* functions for drivers to get certain frames */ | 1744 | /* functions for drivers to get certain frames */ |
| @@ -1776,23 +1807,24 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local, | |||
| 1776 | } | 1807 | } |
| 1777 | 1808 | ||
| 1778 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 1809 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, |
| 1779 | struct ieee80211_vif *vif, | 1810 | struct ieee80211_vif *vif) |
| 1780 | struct ieee80211_tx_control *control) | ||
| 1781 | { | 1811 | { |
| 1782 | struct ieee80211_local *local = hw_to_local(hw); | 1812 | struct ieee80211_local *local = hw_to_local(hw); |
| 1783 | struct sk_buff *skb; | 1813 | struct sk_buff *skb = NULL; |
| 1814 | struct ieee80211_tx_info *info; | ||
| 1784 | struct net_device *bdev; | 1815 | struct net_device *bdev; |
| 1785 | struct ieee80211_sub_if_data *sdata = NULL; | 1816 | struct ieee80211_sub_if_data *sdata = NULL; |
| 1786 | struct ieee80211_if_ap *ap = NULL; | 1817 | struct ieee80211_if_ap *ap = NULL; |
| 1818 | struct ieee80211_if_sta *ifsta = NULL; | ||
| 1787 | struct rate_selection rsel; | 1819 | struct rate_selection rsel; |
| 1788 | struct beacon_data *beacon; | 1820 | struct beacon_data *beacon; |
| 1789 | struct ieee80211_supported_band *sband; | 1821 | struct ieee80211_supported_band *sband; |
| 1790 | struct ieee80211_mgmt *mgmt; | 1822 | struct ieee80211_mgmt *mgmt; |
| 1791 | int *num_beacons; | 1823 | int *num_beacons; |
| 1792 | bool err = true; | 1824 | enum ieee80211_band band = local->hw.conf.channel->band; |
| 1793 | u8 *pos; | 1825 | u8 *pos; |
| 1794 | 1826 | ||
| 1795 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1827 | sband = local->hw.wiphy->bands[band]; |
| 1796 | 1828 | ||
| 1797 | rcu_read_lock(); | 1829 | rcu_read_lock(); |
| 1798 | 1830 | ||
| @@ -1817,9 +1849,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
| 1817 | memcpy(skb_put(skb, beacon->head_len), beacon->head, | 1849 | memcpy(skb_put(skb, beacon->head_len), beacon->head, |
| 1818 | beacon->head_len); | 1850 | beacon->head_len); |
| 1819 | 1851 | ||
| 1820 | ieee80211_include_sequence(sdata, | ||
| 1821 | (struct ieee80211_hdr *)skb->data); | ||
| 1822 | |||
| 1823 | /* | 1852 | /* |
| 1824 | * Not very nice, but we want to allow the driver to call | 1853 | * Not very nice, but we want to allow the driver to call |
| 1825 | * ieee80211_beacon_get() as a response to the set_tim() | 1854 | * ieee80211_beacon_get() as a response to the set_tim() |
| @@ -1842,9 +1871,24 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
| 1842 | beacon->tail, beacon->tail_len); | 1871 | beacon->tail, beacon->tail_len); |
| 1843 | 1872 | ||
| 1844 | num_beacons = &ap->num_beacons; | 1873 | num_beacons = &ap->num_beacons; |
| 1874 | } else | ||
| 1875 | goto out; | ||
| 1876 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | ||
| 1877 | struct ieee80211_hdr *hdr; | ||
| 1878 | ifsta = &sdata->u.sta; | ||
| 1845 | 1879 | ||
| 1846 | err = false; | 1880 | if (!ifsta->probe_resp) |
| 1847 | } | 1881 | goto out; |
| 1882 | |||
| 1883 | skb = skb_copy(ifsta->probe_resp, GFP_ATOMIC); | ||
| 1884 | if (!skb) | ||
| 1885 | goto out; | ||
| 1886 | |||
| 1887 | hdr = (struct ieee80211_hdr *) skb->data; | ||
| 1888 | hdr->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
| 1889 | IEEE80211_STYPE_BEACON); | ||
| 1890 | |||
| 1891 | num_beacons = &ifsta->num_beacons; | ||
| 1848 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1892 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
| 1849 | /* headroom, head length, tail length and maximum TIM length */ | 1893 | /* headroom, head length, tail length and maximum TIM length */ |
| 1850 | skb = dev_alloc_skb(local->tx_headroom + 400); | 1894 | skb = dev_alloc_skb(local->tx_headroom + 400); |
| @@ -1855,8 +1899,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
| 1855 | mgmt = (struct ieee80211_mgmt *) | 1899 | mgmt = (struct ieee80211_mgmt *) |
| 1856 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 1900 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
| 1857 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 1901 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
| 1858 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 1902 | mgmt->frame_control = |
| 1859 | IEEE80211_STYPE_BEACON); | 1903 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
| 1860 | memset(mgmt->da, 0xff, ETH_ALEN); | 1904 | memset(mgmt->da, 0xff, ETH_ALEN); |
| 1861 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | 1905 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); |
| 1862 | /* BSSID is left zeroed, wildcard value */ | 1906 | /* BSSID is left zeroed, wildcard value */ |
| @@ -1871,44 +1915,41 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
| 1871 | mesh_mgmt_ies_add(skb, sdata->dev); | 1915 | mesh_mgmt_ies_add(skb, sdata->dev); |
| 1872 | 1916 | ||
| 1873 | num_beacons = &sdata->u.sta.num_beacons; | 1917 | num_beacons = &sdata->u.sta.num_beacons; |
| 1874 | 1918 | } else { | |
| 1875 | err = false; | 1919 | WARN_ON(1); |
| 1920 | goto out; | ||
| 1876 | } | 1921 | } |
| 1877 | 1922 | ||
| 1878 | if (err) { | 1923 | info = IEEE80211_SKB_CB(skb); |
| 1879 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1924 | |
| 1880 | if (net_ratelimit()) | 1925 | info->band = band; |
| 1881 | printk(KERN_DEBUG "no beacon data avail for %s\n", | 1926 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
| 1882 | bdev->name); | 1927 | |
| 1883 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 1928 | if (unlikely(rsel.rate_idx < 0)) { |
| 1929 | if (net_ratelimit()) { | ||
| 1930 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | ||
| 1931 | "no rate found\n", | ||
| 1932 | wiphy_name(local->hw.wiphy)); | ||
| 1933 | } | ||
| 1934 | dev_kfree_skb(skb); | ||
| 1884 | skb = NULL; | 1935 | skb = NULL; |
| 1885 | goto out; | 1936 | goto out; |
| 1886 | } | 1937 | } |
| 1887 | 1938 | ||
| 1888 | if (control) { | 1939 | info->control.vif = vif; |
| 1889 | rate_control_get_rate(local->mdev, sband, skb, &rsel); | 1940 | info->tx_rate_idx = rsel.rate_idx; |
| 1890 | if (!rsel.rate) { | 1941 | |
| 1891 | if (net_ratelimit()) { | 1942 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
| 1892 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | 1943 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
| 1893 | "no rate found\n", | 1944 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
| 1894 | wiphy_name(local->hw.wiphy)); | 1945 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
| 1895 | } | 1946 | if (sdata->bss_conf.use_short_preamble && |
| 1896 | dev_kfree_skb(skb); | 1947 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
| 1897 | skb = NULL; | 1948 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
| 1898 | goto out; | 1949 | |
| 1899 | } | 1950 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
| 1951 | info->control.retry_limit = 1; | ||
| 1900 | 1952 | ||
| 1901 | control->vif = vif; | ||
| 1902 | control->tx_rate = rsel.rate; | ||
| 1903 | if (sdata->bss_conf.use_short_preamble && | ||
| 1904 | rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
| 1905 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | ||
| 1906 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
| 1907 | control->flags |= IEEE80211_TXCTL_NO_ACK; | ||
| 1908 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
| 1909 | control->retry_limit = 1; | ||
| 1910 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | ||
| 1911 | } | ||
| 1912 | (*num_beacons)++; | 1953 | (*num_beacons)++; |
| 1913 | out: | 1954 | out: |
| 1914 | rcu_read_unlock(); | 1955 | rcu_read_unlock(); |
| @@ -1918,14 +1959,13 @@ EXPORT_SYMBOL(ieee80211_beacon_get); | |||
| 1918 | 1959 | ||
| 1919 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1960 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 1920 | const void *frame, size_t frame_len, | 1961 | const void *frame, size_t frame_len, |
| 1921 | const struct ieee80211_tx_control *frame_txctl, | 1962 | const struct ieee80211_tx_info *frame_txctl, |
| 1922 | struct ieee80211_rts *rts) | 1963 | struct ieee80211_rts *rts) |
| 1923 | { | 1964 | { |
| 1924 | const struct ieee80211_hdr *hdr = frame; | 1965 | const struct ieee80211_hdr *hdr = frame; |
| 1925 | u16 fctl; | ||
| 1926 | 1966 | ||
| 1927 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS; | 1967 | rts->frame_control = |
| 1928 | rts->frame_control = cpu_to_le16(fctl); | 1968 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); |
| 1929 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, | 1969 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, |
| 1930 | frame_txctl); | 1970 | frame_txctl); |
| 1931 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); | 1971 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); |
| @@ -1935,14 +1975,13 @@ EXPORT_SYMBOL(ieee80211_rts_get); | |||
| 1935 | 1975 | ||
| 1936 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1976 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 1937 | const void *frame, size_t frame_len, | 1977 | const void *frame, size_t frame_len, |
| 1938 | const struct ieee80211_tx_control *frame_txctl, | 1978 | const struct ieee80211_tx_info *frame_txctl, |
| 1939 | struct ieee80211_cts *cts) | 1979 | struct ieee80211_cts *cts) |
| 1940 | { | 1980 | { |
| 1941 | const struct ieee80211_hdr *hdr = frame; | 1981 | const struct ieee80211_hdr *hdr = frame; |
| 1942 | u16 fctl; | ||
| 1943 | 1982 | ||
| 1944 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS; | 1983 | cts->frame_control = |
| 1945 | cts->frame_control = cpu_to_le16(fctl); | 1984 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); |
| 1946 | cts->duration = ieee80211_ctstoself_duration(hw, vif, | 1985 | cts->duration = ieee80211_ctstoself_duration(hw, vif, |
| 1947 | frame_len, frame_txctl); | 1986 | frame_len, frame_txctl); |
| 1948 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); | 1987 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); |
| @@ -1951,23 +1990,21 @@ EXPORT_SYMBOL(ieee80211_ctstoself_get); | |||
| 1951 | 1990 | ||
| 1952 | struct sk_buff * | 1991 | struct sk_buff * |
| 1953 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | 1992 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, |
| 1954 | struct ieee80211_vif *vif, | 1993 | struct ieee80211_vif *vif) |
| 1955 | struct ieee80211_tx_control *control) | ||
| 1956 | { | 1994 | { |
| 1957 | struct ieee80211_local *local = hw_to_local(hw); | 1995 | struct ieee80211_local *local = hw_to_local(hw); |
| 1958 | struct sk_buff *skb; | 1996 | struct sk_buff *skb = NULL; |
| 1959 | struct sta_info *sta; | 1997 | struct sta_info *sta; |
| 1960 | ieee80211_tx_handler *handler; | ||
| 1961 | struct ieee80211_tx_data tx; | 1998 | struct ieee80211_tx_data tx; |
| 1962 | ieee80211_tx_result res = TX_DROP; | ||
| 1963 | struct net_device *bdev; | 1999 | struct net_device *bdev; |
| 1964 | struct ieee80211_sub_if_data *sdata; | 2000 | struct ieee80211_sub_if_data *sdata; |
| 1965 | struct ieee80211_if_ap *bss = NULL; | 2001 | struct ieee80211_if_ap *bss = NULL; |
| 1966 | struct beacon_data *beacon; | 2002 | struct beacon_data *beacon; |
| 2003 | struct ieee80211_tx_info *info; | ||
| 1967 | 2004 | ||
| 1968 | sdata = vif_to_sdata(vif); | 2005 | sdata = vif_to_sdata(vif); |
| 1969 | bdev = sdata->dev; | 2006 | bdev = sdata->dev; |
| 1970 | 2007 | bss = &sdata->u.ap; | |
| 1971 | 2008 | ||
| 1972 | if (!bss) | 2009 | if (!bss) |
| 1973 | return NULL; | 2010 | return NULL; |
| @@ -1975,19 +2012,16 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
| 1975 | rcu_read_lock(); | 2012 | rcu_read_lock(); |
| 1976 | beacon = rcu_dereference(bss->beacon); | 2013 | beacon = rcu_dereference(bss->beacon); |
| 1977 | 2014 | ||
| 1978 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || | 2015 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) |
| 1979 | !beacon->head) { | 2016 | goto out; |
| 1980 | rcu_read_unlock(); | ||
| 1981 | return NULL; | ||
| 1982 | } | ||
| 1983 | 2017 | ||
| 1984 | if (bss->dtim_count != 0) | 2018 | if (bss->dtim_count != 0) |
| 1985 | return NULL; /* send buffered bc/mc only after DTIM beacon */ | 2019 | goto out; /* send buffered bc/mc only after DTIM beacon */ |
| 1986 | memset(control, 0, sizeof(*control)); | 2020 | |
| 1987 | while (1) { | 2021 | while (1) { |
| 1988 | skb = skb_dequeue(&bss->ps_bc_buf); | 2022 | skb = skb_dequeue(&bss->ps_bc_buf); |
| 1989 | if (!skb) | 2023 | if (!skb) |
| 1990 | return NULL; | 2024 | goto out; |
| 1991 | local->total_ps_buffered--; | 2025 | local->total_ps_buffered--; |
| 1992 | 2026 | ||
| 1993 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { | 2027 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { |
| @@ -2000,30 +2034,21 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
| 2000 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 2034 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
| 2001 | } | 2035 | } |
| 2002 | 2036 | ||
| 2003 | if (!ieee80211_tx_prepare(&tx, skb, local->mdev, control)) | 2037 | if (!ieee80211_tx_prepare(&tx, skb, local->mdev)) |
| 2004 | break; | 2038 | break; |
| 2005 | dev_kfree_skb_any(skb); | 2039 | dev_kfree_skb_any(skb); |
| 2006 | } | 2040 | } |
| 2041 | |||
| 2042 | info = IEEE80211_SKB_CB(skb); | ||
| 2043 | |||
| 2007 | sta = tx.sta; | 2044 | sta = tx.sta; |
| 2008 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2045 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
| 2009 | tx.channel = local->hw.conf.channel; | 2046 | tx.channel = local->hw.conf.channel; |
| 2047 | info->band = tx.channel->band; | ||
| 2010 | 2048 | ||
| 2011 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | 2049 | if (invoke_tx_handlers(&tx)) |
| 2012 | res = (*handler)(&tx); | ||
| 2013 | if (res == TX_DROP || res == TX_QUEUED) | ||
| 2014 | break; | ||
| 2015 | } | ||
| 2016 | skb = tx.skb; /* handlers are allowed to change skb */ | ||
| 2017 | |||
| 2018 | if (res == TX_DROP) { | ||
| 2019 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
| 2020 | dev_kfree_skb(skb); | ||
| 2021 | skb = NULL; | ||
| 2022 | } else if (res == TX_QUEUED) { | ||
| 2023 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
| 2024 | skb = NULL; | 2050 | skb = NULL; |
| 2025 | } | 2051 | out: |
| 2026 | |||
| 2027 | rcu_read_unlock(); | 2052 | rcu_read_unlock(); |
| 2028 | 2053 | ||
| 2029 | return skb; | 2054 | return skb; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4e97b266f907..19f85e1b3695 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) |
| 137 | { | 134 | { |
| 138 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data; | 135 | unsigned int hdrlen = 24; |
| 139 | int hdrlen; | 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) | ||
| 166 | { | ||
| 167 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; | ||
| 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; |
| @@ -258,7 +287,7 @@ EXPORT_SYMBOL(ieee80211_generic_frame_duration); | |||
| 258 | 287 | ||
| 259 | __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | 288 | __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, |
| 260 | struct ieee80211_vif *vif, size_t frame_len, | 289 | struct ieee80211_vif *vif, size_t frame_len, |
| 261 | const struct ieee80211_tx_control *frame_txctl) | 290 | const struct ieee80211_tx_info *frame_txctl) |
| 262 | { | 291 | { |
| 263 | struct ieee80211_local *local = hw_to_local(hw); | 292 | struct ieee80211_local *local = hw_to_local(hw); |
| 264 | struct ieee80211_rate *rate; | 293 | struct ieee80211_rate *rate; |
| @@ -266,10 +295,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
| 266 | bool short_preamble; | 295 | bool short_preamble; |
| 267 | int erp; | 296 | int erp; |
| 268 | u16 dur; | 297 | u16 dur; |
| 298 | struct ieee80211_supported_band *sband; | ||
| 299 | |||
| 300 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
| 269 | 301 | ||
| 270 | short_preamble = sdata->bss_conf.use_short_preamble; | 302 | short_preamble = sdata->bss_conf.use_short_preamble; |
| 271 | 303 | ||
| 272 | rate = frame_txctl->rts_cts_rate; | 304 | rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; |
| 273 | 305 | ||
| 274 | erp = 0; | 306 | erp = 0; |
| 275 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 307 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
| @@ -292,7 +324,7 @@ EXPORT_SYMBOL(ieee80211_rts_duration); | |||
| 292 | __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | 324 | __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, |
| 293 | struct ieee80211_vif *vif, | 325 | struct ieee80211_vif *vif, |
| 294 | size_t frame_len, | 326 | size_t frame_len, |
| 295 | const struct ieee80211_tx_control *frame_txctl) | 327 | const struct ieee80211_tx_info *frame_txctl) |
| 296 | { | 328 | { |
| 297 | struct ieee80211_local *local = hw_to_local(hw); | 329 | struct ieee80211_local *local = hw_to_local(hw); |
| 298 | struct ieee80211_rate *rate; | 330 | struct ieee80211_rate *rate; |
| @@ -300,10 +332,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
| 300 | bool short_preamble; | 332 | bool short_preamble; |
| 301 | int erp; | 333 | int erp; |
| 302 | u16 dur; | 334 | u16 dur; |
| 335 | struct ieee80211_supported_band *sband; | ||
| 336 | |||
| 337 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
| 303 | 338 | ||
| 304 | short_preamble = sdata->bss_conf.use_short_preamble; | 339 | short_preamble = sdata->bss_conf.use_short_preamble; |
| 305 | 340 | ||
| 306 | rate = frame_txctl->rts_cts_rate; | 341 | rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; |
| 307 | erp = 0; | 342 | erp = 0; |
| 308 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 343 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
| 309 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 344 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
| @@ -311,7 +346,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
| 311 | /* Data frame duration */ | 346 | /* Data frame duration */ |
| 312 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, | 347 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, |
| 313 | erp, short_preamble); | 348 | erp, short_preamble); |
| 314 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { | 349 | if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { |
| 315 | /* ACK duration */ | 350 | /* ACK duration */ |
| 316 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, | 351 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
| 317 | erp, short_preamble); | 352 | erp, short_preamble); |
| @@ -325,17 +360,10 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | |||
| 325 | { | 360 | { |
| 326 | struct ieee80211_local *local = hw_to_local(hw); | 361 | struct ieee80211_local *local = hw_to_local(hw); |
| 327 | 362 | ||
| 328 | if (test_and_clear_bit(IEEE80211_LINK_STATE_XOFF, | 363 | if (test_bit(queue, local->queues_pending)) { |
| 329 | &local->state[queue])) { | 364 | tasklet_schedule(&local->tx_pending_tasklet); |
| 330 | if (test_bit(IEEE80211_LINK_STATE_PENDING, | 365 | } else { |
| 331 | &local->state[queue])) | 366 | netif_wake_subqueue(local->mdev, queue); |
| 332 | tasklet_schedule(&local->tx_pending_tasklet); | ||
| 333 | else | ||
| 334 | if (!ieee80211_qdisc_installed(local->mdev)) { | ||
| 335 | if (queue == 0) | ||
| 336 | netif_wake_queue(local->mdev); | ||
| 337 | } else | ||
| 338 | __netif_schedule(local->mdev); | ||
| 339 | } | 367 | } |
| 340 | } | 368 | } |
| 341 | EXPORT_SYMBOL(ieee80211_wake_queue); | 369 | EXPORT_SYMBOL(ieee80211_wake_queue); |
| @@ -344,29 +372,15 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | |||
| 344 | { | 372 | { |
| 345 | struct ieee80211_local *local = hw_to_local(hw); | 373 | struct ieee80211_local *local = hw_to_local(hw); |
| 346 | 374 | ||
| 347 | if (!ieee80211_qdisc_installed(local->mdev) && queue == 0) | 375 | netif_stop_subqueue(local->mdev, queue); |
| 348 | netif_stop_queue(local->mdev); | ||
| 349 | set_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); | ||
| 350 | } | 376 | } |
| 351 | EXPORT_SYMBOL(ieee80211_stop_queue); | 377 | EXPORT_SYMBOL(ieee80211_stop_queue); |
| 352 | 378 | ||
| 353 | void ieee80211_start_queues(struct ieee80211_hw *hw) | ||
| 354 | { | ||
| 355 | struct ieee80211_local *local = hw_to_local(hw); | ||
| 356 | int i; | ||
| 357 | |||
| 358 | for (i = 0; i < local->hw.queues; i++) | ||
| 359 | clear_bit(IEEE80211_LINK_STATE_XOFF, &local->state[i]); | ||
| 360 | if (!ieee80211_qdisc_installed(local->mdev)) | ||
| 361 | netif_start_queue(local->mdev); | ||
| 362 | } | ||
| 363 | EXPORT_SYMBOL(ieee80211_start_queues); | ||
| 364 | |||
| 365 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | 379 | void ieee80211_stop_queues(struct ieee80211_hw *hw) |
| 366 | { | 380 | { |
| 367 | int i; | 381 | int i; |
| 368 | 382 | ||
| 369 | for (i = 0; i < hw->queues; i++) | 383 | for (i = 0; i < ieee80211_num_queues(hw); i++) |
| 370 | ieee80211_stop_queue(hw, i); | 384 | ieee80211_stop_queue(hw, i); |
| 371 | } | 385 | } |
| 372 | EXPORT_SYMBOL(ieee80211_stop_queues); | 386 | EXPORT_SYMBOL(ieee80211_stop_queues); |
| @@ -375,7 +389,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw) | |||
| 375 | { | 389 | { |
| 376 | int i; | 390 | int i; |
| 377 | 391 | ||
| 378 | for (i = 0; i < hw->queues; i++) | 392 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) |
| 379 | ieee80211_wake_queue(hw, i); | 393 | ieee80211_wake_queue(hw, i); |
| 380 | } | 394 | } |
| 381 | EXPORT_SYMBOL(ieee80211_wake_queues); | 395 | EXPORT_SYMBOL(ieee80211_wake_queues); |
| @@ -404,8 +418,6 @@ void ieee80211_iterate_active_interfaces( | |||
| 404 | case IEEE80211_IF_TYPE_MESH_POINT: | 418 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 405 | break; | 419 | break; |
| 406 | } | 420 | } |
| 407 | if (sdata->dev == local->mdev) | ||
| 408 | continue; | ||
| 409 | if (netif_running(sdata->dev)) | 421 | if (netif_running(sdata->dev)) |
| 410 | iterator(data, sdata->dev->dev_addr, | 422 | iterator(data, sdata->dev->dev_addr, |
| 411 | &sdata->vif); | 423 | &sdata->vif); |
| @@ -439,8 +451,6 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
| 439 | case IEEE80211_IF_TYPE_MESH_POINT: | 451 | case IEEE80211_IF_TYPE_MESH_POINT: |
| 440 | break; | 452 | break; |
| 441 | } | 453 | } |
| 442 | if (sdata->dev == local->mdev) | ||
| 443 | continue; | ||
| 444 | if (netif_running(sdata->dev)) | 454 | if (netif_running(sdata->dev)) |
| 445 | iterator(data, sdata->dev->dev_addr, | 455 | iterator(data, sdata->dev->dev_addr, |
| 446 | &sdata->vif); | 456 | &sdata->vif); |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index affcecd78c10..872d2fcd1a5b 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
| @@ -84,24 +84,17 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, | |||
| 84 | struct sk_buff *skb, | 84 | struct sk_buff *skb, |
| 85 | struct ieee80211_key *key) | 85 | struct ieee80211_key *key) |
| 86 | { | 86 | { |
| 87 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 87 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 88 | u16 fc; | 88 | unsigned int hdrlen; |
| 89 | int hdrlen; | ||
| 90 | u8 *newhdr; | 89 | u8 *newhdr; |
| 91 | 90 | ||
| 92 | fc = le16_to_cpu(hdr->frame_control); | 91 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
| 93 | fc |= IEEE80211_FCTL_PROTECTED; | ||
| 94 | hdr->frame_control = cpu_to_le16(fc); | ||
| 95 | 92 | ||
| 96 | if ((skb_headroom(skb) < WEP_IV_LEN || | 93 | if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || |
| 97 | skb_tailroom(skb) < WEP_ICV_LEN)) { | 94 | skb_headroom(skb) < WEP_IV_LEN)) |
| 98 | I802_DEBUG_INC(local->tx_expand_skb_head); | 95 | return NULL; |
| 99 | if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN, | ||
| 100 | GFP_ATOMIC))) | ||
| 101 | return NULL; | ||
| 102 | } | ||
| 103 | 96 | ||
| 104 | hdrlen = ieee80211_get_hdrlen(fc); | 97 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 105 | newhdr = skb_push(skb, WEP_IV_LEN); | 98 | newhdr = skb_push(skb, WEP_IV_LEN); |
| 106 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); | 99 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); |
| 107 | ieee80211_wep_get_iv(local, key, newhdr + hdrlen); | 100 | ieee80211_wep_get_iv(local, key, newhdr + hdrlen); |
| @@ -113,12 +106,10 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, | |||
| 113 | struct sk_buff *skb, | 106 | struct sk_buff *skb, |
| 114 | struct ieee80211_key *key) | 107 | struct ieee80211_key *key) |
| 115 | { | 108 | { |
| 116 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 109 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 117 | u16 fc; | 110 | unsigned int hdrlen; |
| 118 | int hdrlen; | ||
| 119 | 111 | ||
| 120 | fc = le16_to_cpu(hdr->frame_control); | 112 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 121 | hdrlen = ieee80211_get_hdrlen(fc); | ||
| 122 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 113 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); |
| 123 | skb_pull(skb, WEP_IV_LEN); | 114 | skb_pull(skb, WEP_IV_LEN); |
| 124 | } | 115 | } |
| @@ -228,17 +219,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 228 | u32 klen; | 219 | u32 klen; |
| 229 | u8 *rc4key; | 220 | u8 *rc4key; |
| 230 | u8 keyidx; | 221 | u8 keyidx; |
| 231 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 222 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 232 | u16 fc; | 223 | unsigned int hdrlen; |
| 233 | int hdrlen; | ||
| 234 | size_t len; | 224 | size_t len; |
| 235 | int ret = 0; | 225 | int ret = 0; |
| 236 | 226 | ||
| 237 | fc = le16_to_cpu(hdr->frame_control); | 227 | if (!ieee80211_has_protected(hdr->frame_control)) |
| 238 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
| 239 | return -1; | 228 | return -1; |
| 240 | 229 | ||
| 241 | hdrlen = ieee80211_get_hdrlen(fc); | 230 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 242 | 231 | ||
| 243 | if (skb->len < 8 + hdrlen) | 232 | if (skb->len < 8 + hdrlen) |
| 244 | return -1; | 233 | return -1; |
| @@ -264,11 +253,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 264 | 253 | ||
| 265 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, | 254 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
| 266 | skb->data + hdrlen + WEP_IV_LEN, | 255 | skb->data + hdrlen + WEP_IV_LEN, |
| 267 | len)) { | 256 | len)) |
| 268 | if (net_ratelimit()) | ||
| 269 | printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); | ||
| 270 | ret = -1; | 257 | ret = -1; |
| 271 | } | ||
| 272 | 258 | ||
| 273 | kfree(rc4key); | 259 | kfree(rc4key); |
| 274 | 260 | ||
| @@ -285,17 +271,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 285 | 271 | ||
| 286 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 272 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) |
| 287 | { | 273 | { |
| 288 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 274 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 289 | u16 fc; | 275 | unsigned int hdrlen; |
| 290 | int hdrlen; | ||
| 291 | u8 *ivpos; | 276 | u8 *ivpos; |
| 292 | u32 iv; | 277 | u32 iv; |
| 293 | 278 | ||
| 294 | fc = le16_to_cpu(hdr->frame_control); | 279 | if (!ieee80211_has_protected(hdr->frame_control)) |
| 295 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
| 296 | return NULL; | 280 | return NULL; |
| 297 | 281 | ||
| 298 | hdrlen = ieee80211_get_hdrlen(fc); | 282 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 299 | ivpos = skb->data + hdrlen; | 283 | ivpos = skb->data + hdrlen; |
| 300 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 284 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
| 301 | 285 | ||
| @@ -314,14 +298,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
| 314 | return RX_CONTINUE; | 298 | return RX_CONTINUE; |
| 315 | 299 | ||
| 316 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 300 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { |
| 317 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 301 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
| 318 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 319 | if (net_ratelimit()) | ||
| 320 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | ||
| 321 | "failed\n", rx->dev->name); | ||
| 322 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 323 | return RX_DROP_UNUSABLE; | 302 | return RX_DROP_UNUSABLE; |
| 324 | } | ||
| 325 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { | 303 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { |
| 326 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 304 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
| 327 | /* remove ICV */ | 305 | /* remove ICV */ |
| @@ -333,11 +311,16 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
| 333 | 311 | ||
| 334 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 312 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
| 335 | { | 313 | { |
| 314 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 315 | |||
| 316 | info->control.iv_len = WEP_IV_LEN; | ||
| 317 | info->control.icv_len = WEP_ICV_LEN; | ||
| 318 | |||
| 336 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 319 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { |
| 337 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) | 320 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) |
| 338 | return -1; | 321 | return -1; |
| 339 | } else { | 322 | } else { |
| 340 | tx->control->key_idx = tx->key->conf.hw_key_idx; | 323 | info->control.hw_key = &tx->key->conf; |
| 341 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { | 324 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { |
| 342 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) | 325 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) |
| 343 | return -1; | 326 | return -1; |
| @@ -349,8 +332,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
| 349 | ieee80211_tx_result | 332 | ieee80211_tx_result |
| 350 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 333 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) |
| 351 | { | 334 | { |
| 352 | tx->control->iv_len = WEP_IV_LEN; | ||
| 353 | tx->control->icv_len = WEP_ICV_LEN; | ||
| 354 | ieee80211_tx_set_protected(tx); | 335 | ieee80211_tx_set_protected(tx); |
| 355 | 336 | ||
| 356 | if (wep_encrypt_skb(tx, tx->skb) < 0) { | 337 | if (wep_encrypt_skb(tx, tx->skb) < 0) { |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 363779c50658..e587172115b8 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
| @@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
| 26 | struct ieee80211_key *key); | 26 | struct ieee80211_key *key); |
| 27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | 27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, |
| 28 | struct ieee80211_key *key); | 28 | struct ieee80211_key *key); |
| 29 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 29 | u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
| 30 | 30 | ||
| 31 | ieee80211_rx_result | 31 | ieee80211_rx_result |
| 32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); | 32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 6106cb79060c..34fa8ed1e784 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
| @@ -95,6 +95,13 @@ static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, | |||
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | if (alg == ALG_WEP && | ||
| 99 | key_len != LEN_WEP40 && key_len != LEN_WEP104) { | ||
| 100 | ieee80211_key_free(key); | ||
| 101 | err = -EINVAL; | ||
| 102 | goto out_unlock; | ||
| 103 | } | ||
| 104 | |||
| 98 | ieee80211_key_link(key, sdata, sta); | 105 | ieee80211_key_link(key, sdata, sta); |
| 99 | 106 | ||
| 100 | if (set_tx_key || (!sta && !sdata->default_key && key)) | 107 | if (set_tx_key || (!sta && !sdata->default_key && key)) |
| @@ -135,7 +142,39 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
| 135 | struct iw_request_info *info, | 142 | struct iw_request_info *info, |
| 136 | char *name, char *extra) | 143 | char *name, char *extra) |
| 137 | { | 144 | { |
| 145 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 146 | struct ieee80211_supported_band *sband; | ||
| 147 | u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0; | ||
| 148 | |||
| 149 | |||
| 150 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; | ||
| 151 | if (sband) { | ||
| 152 | is_a = 1; | ||
| 153 | is_ht |= sband->ht_info.ht_supported; | ||
| 154 | } | ||
| 155 | |||
| 156 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
| 157 | if (sband) { | ||
| 158 | int i; | ||
| 159 | /* Check for mandatory rates */ | ||
| 160 | for (i = 0; i < sband->n_bitrates; i++) { | ||
| 161 | if (sband->bitrates[i].bitrate == 10) | ||
| 162 | is_b = 1; | ||
| 163 | if (sband->bitrates[i].bitrate == 60) | ||
| 164 | is_g = 1; | ||
| 165 | } | ||
| 166 | is_ht |= sband->ht_info.ht_supported; | ||
| 167 | } | ||
| 168 | |||
| 138 | strcpy(name, "IEEE 802.11"); | 169 | strcpy(name, "IEEE 802.11"); |
| 170 | if (is_a) | ||
| 171 | strcat(name, "a"); | ||
| 172 | if (is_b) | ||
| 173 | strcat(name, "b"); | ||
| 174 | if (is_g) | ||
| 175 | strcat(name, "g"); | ||
| 176 | if (is_ht) | ||
| 177 | strcat(name, "n"); | ||
| 139 | 178 | ||
| 140 | return 0; | 179 | return 0; |
| 141 | } | 180 | } |
| @@ -169,14 +208,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
| 169 | range->num_encoding_sizes = 2; | 208 | range->num_encoding_sizes = 2; |
| 170 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; | 209 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; |
| 171 | 210 | ||
| 172 | range->max_qual.qual = local->hw.max_signal; | 211 | if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC || |
| 173 | range->max_qual.level = local->hw.max_rssi; | 212 | local->hw.flags & IEEE80211_HW_SIGNAL_DB) |
| 174 | range->max_qual.noise = local->hw.max_noise; | 213 | range->max_qual.level = local->hw.max_signal; |
| 214 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
| 215 | range->max_qual.level = -110; | ||
| 216 | else | ||
| 217 | range->max_qual.level = 0; | ||
| 218 | |||
| 219 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
| 220 | range->max_qual.noise = -110; | ||
| 221 | else | ||
| 222 | range->max_qual.noise = 0; | ||
| 223 | |||
| 224 | range->max_qual.qual = 100; | ||
| 175 | range->max_qual.updated = local->wstats_flags; | 225 | range->max_qual.updated = local->wstats_flags; |
| 176 | 226 | ||
| 177 | range->avg_qual.qual = local->hw.max_signal/2; | 227 | range->avg_qual.qual = 50; |
| 178 | range->avg_qual.level = 0; | 228 | /* not always true but better than nothing */ |
| 179 | range->avg_qual.noise = 0; | 229 | range->avg_qual.level = range->max_qual.level / 2; |
| 230 | range->avg_qual.noise = range->max_qual.noise / 2; | ||
| 180 | range->avg_qual.updated = local->wstats_flags; | 231 | range->avg_qual.updated = local->wstats_flags; |
| 181 | 232 | ||
| 182 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 233 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
| @@ -245,15 +296,7 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev, | |||
| 245 | return -EINVAL; | 296 | return -EINVAL; |
| 246 | } | 297 | } |
| 247 | 298 | ||
| 248 | if (type == sdata->vif.type) | 299 | return ieee80211_if_change_type(sdata, type); |
| 249 | return 0; | ||
| 250 | if (netif_running(dev)) | ||
| 251 | return -EBUSY; | ||
| 252 | |||
| 253 | ieee80211_if_reinit(dev); | ||
| 254 | ieee80211_if_set_type(dev, type); | ||
| 255 | |||
| 256 | return 0; | ||
| 257 | } | 300 | } |
| 258 | 301 | ||
| 259 | 302 | ||
| @@ -401,7 +444,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev, | |||
| 401 | memset(sdata->u.ap.ssid + len, 0, | 444 | memset(sdata->u.ap.ssid + len, 0, |
| 402 | IEEE80211_MAX_SSID_LEN - len); | 445 | IEEE80211_MAX_SSID_LEN - len); |
| 403 | sdata->u.ap.ssid_len = len; | 446 | sdata->u.ap.ssid_len = len; |
| 404 | return ieee80211_if_config(dev); | 447 | return ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); |
| 405 | } | 448 | } |
| 406 | return -EOPNOTSUPP; | 449 | return -EOPNOTSUPP; |
| 407 | } | 450 | } |
| @@ -555,7 +598,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev, | |||
| 555 | if (local->sta_sw_scanning || local->sta_hw_scanning) | 598 | if (local->sta_sw_scanning || local->sta_hw_scanning) |
| 556 | return -EAGAIN; | 599 | return -EAGAIN; |
| 557 | 600 | ||
| 558 | res = ieee80211_sta_scan_results(dev, extra, data->length); | 601 | res = ieee80211_sta_scan_results(dev, info, extra, data->length); |
| 559 | if (res >= 0) { | 602 | if (res >= 0) { |
| 560 | data->length = res; | 603 | data->length = res; |
| 561 | return 0; | 604 | return 0; |
| @@ -576,16 +619,14 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
| 576 | struct ieee80211_supported_band *sband; | 619 | struct ieee80211_supported_band *sband; |
| 577 | 620 | ||
| 578 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 621 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 579 | if (!sdata->bss) | ||
| 580 | return -ENODEV; | ||
| 581 | 622 | ||
| 582 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 623 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
| 583 | 624 | ||
| 584 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates | 625 | /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates |
| 585 | * target_rate = X, rate->fixed = 1 means only rate X | 626 | * target_rate = X, rate->fixed = 1 means only rate X |
| 586 | * target_rate = X, rate->fixed = 0 means all rates <= X */ | 627 | * target_rate = X, rate->fixed = 0 means all rates <= X */ |
| 587 | sdata->bss->max_ratectrl_rateidx = -1; | 628 | sdata->max_ratectrl_rateidx = -1; |
| 588 | sdata->bss->force_unicast_rateidx = -1; | 629 | sdata->force_unicast_rateidx = -1; |
| 589 | if (rate->value < 0) | 630 | if (rate->value < 0) |
| 590 | return 0; | 631 | return 0; |
| 591 | 632 | ||
| @@ -594,9 +635,9 @@ static int ieee80211_ioctl_siwrate(struct net_device *dev, | |||
| 594 | int this_rate = brate->bitrate; | 635 | int this_rate = brate->bitrate; |
| 595 | 636 | ||
| 596 | if (target_rate == this_rate) { | 637 | if (target_rate == this_rate) { |
| 597 | sdata->bss->max_ratectrl_rateidx = i; | 638 | sdata->max_ratectrl_rateidx = i; |
| 598 | if (rate->fixed) | 639 | if (rate->fixed) |
| 599 | sdata->bss->force_unicast_rateidx = i; | 640 | sdata->force_unicast_rateidx = i; |
| 600 | err = 0; | 641 | err = 0; |
| 601 | break; | 642 | break; |
| 602 | } | 643 | } |
| @@ -709,6 +750,9 @@ static int ieee80211_ioctl_siwrts(struct net_device *dev, | |||
| 709 | 750 | ||
| 710 | if (rts->disabled) | 751 | if (rts->disabled) |
| 711 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 752 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
| 753 | else if (!rts->fixed) | ||
| 754 | /* if the rts value is not fixed, then take default */ | ||
| 755 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | ||
| 712 | else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) | 756 | else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) |
| 713 | return -EINVAL; | 757 | return -EINVAL; |
| 714 | else | 758 | else |
| @@ -746,6 +790,8 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev, | |||
| 746 | 790 | ||
| 747 | if (frag->disabled) | 791 | if (frag->disabled) |
| 748 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 792 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
| 793 | else if (!frag->fixed) | ||
| 794 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | ||
| 749 | else if (frag->value < 256 || | 795 | else if (frag->value < 256 || |
| 750 | frag->value > IEEE80211_MAX_FRAG_THRESHOLD) | 796 | frag->value > IEEE80211_MAX_FRAG_THRESHOLD) |
| 751 | return -EINVAL; | 797 | return -EINVAL; |
| @@ -937,6 +983,58 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev, | |||
| 937 | erq->length = sdata->keys[idx]->conf.keylen; | 983 | erq->length = sdata->keys[idx]->conf.keylen; |
| 938 | erq->flags |= IW_ENCODE_ENABLED; | 984 | erq->flags |= IW_ENCODE_ENABLED; |
| 939 | 985 | ||
| 986 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | ||
| 987 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
| 988 | switch (ifsta->auth_alg) { | ||
| 989 | case WLAN_AUTH_OPEN: | ||
| 990 | case WLAN_AUTH_LEAP: | ||
| 991 | erq->flags |= IW_ENCODE_OPEN; | ||
| 992 | break; | ||
| 993 | case WLAN_AUTH_SHARED_KEY: | ||
| 994 | erq->flags |= IW_ENCODE_RESTRICTED; | ||
| 995 | break; | ||
| 996 | } | ||
| 997 | } | ||
| 998 | |||
| 999 | return 0; | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | static int ieee80211_ioctl_siwpower(struct net_device *dev, | ||
| 1003 | struct iw_request_info *info, | ||
| 1004 | struct iw_param *wrq, | ||
| 1005 | char *extra) | ||
| 1006 | { | ||
| 1007 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1008 | struct ieee80211_conf *conf = &local->hw.conf; | ||
| 1009 | |||
| 1010 | if (wrq->disabled) { | ||
| 1011 | conf->flags &= ~IEEE80211_CONF_PS; | ||
| 1012 | return ieee80211_hw_config(local); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | switch (wrq->flags & IW_POWER_MODE) { | ||
| 1016 | case IW_POWER_ON: /* If not specified */ | ||
| 1017 | case IW_POWER_MODE: /* If set all mask */ | ||
| 1018 | case IW_POWER_ALL_R: /* If explicitely state all */ | ||
| 1019 | conf->flags |= IEEE80211_CONF_PS; | ||
| 1020 | break; | ||
| 1021 | default: /* Otherwise we don't support it */ | ||
| 1022 | return -EINVAL; | ||
| 1023 | } | ||
| 1024 | |||
| 1025 | return ieee80211_hw_config(local); | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | ||
| 1029 | struct iw_request_info *info, | ||
| 1030 | union iwreq_data *wrqu, | ||
| 1031 | char *extra) | ||
| 1032 | { | ||
| 1033 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 1034 | struct ieee80211_conf *conf = &local->hw.conf; | ||
| 1035 | |||
| 1036 | wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS); | ||
| 1037 | |||
| 940 | return 0; | 1038 | return 0; |
| 941 | } | 1039 | } |
| 942 | 1040 | ||
| @@ -1008,8 +1106,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev | |||
| 1008 | wstats->qual.noise = 0; | 1106 | wstats->qual.noise = 0; |
| 1009 | wstats->qual.updated = IW_QUAL_ALL_INVALID; | 1107 | wstats->qual.updated = IW_QUAL_ALL_INVALID; |
| 1010 | } else { | 1108 | } else { |
| 1011 | wstats->qual.level = sta->last_rssi; | 1109 | wstats->qual.level = sta->last_signal; |
| 1012 | wstats->qual.qual = sta->last_signal; | 1110 | wstats->qual.qual = sta->last_qual; |
| 1013 | wstats->qual.noise = sta->last_noise; | 1111 | wstats->qual.noise = sta->last_noise; |
| 1014 | wstats->qual.updated = local->wstats_flags; | 1112 | wstats->qual.updated = local->wstats_flags; |
| 1015 | } | 1113 | } |
| @@ -1142,8 +1240,8 @@ static const iw_handler ieee80211_handler[] = | |||
| 1142 | (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ | 1240 | (iw_handler) ieee80211_ioctl_giwretry, /* SIOCGIWRETRY */ |
| 1143 | (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ | 1241 | (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ |
| 1144 | (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ | 1242 | (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ |
| 1145 | (iw_handler) NULL, /* SIOCSIWPOWER */ | 1243 | (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ |
| 1146 | (iw_handler) NULL, /* SIOCGIWPOWER */ | 1244 | (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ |
| 1147 | (iw_handler) NULL, /* -- hole -- */ | 1245 | (iw_handler) NULL, /* -- hole -- */ |
| 1148 | (iw_handler) NULL, /* -- hole -- */ | 1246 | (iw_handler) NULL, /* -- hole -- */ |
| 1149 | (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ | 1247 | (iw_handler) ieee80211_ioctl_siwgenie, /* SIOCSIWGENIE */ |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 635b996c8c35..07edda0b8a5c 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -18,61 +18,42 @@ | |||
| 18 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
| 19 | #include "wme.h" | 19 | #include "wme.h" |
| 20 | 20 | ||
| 21 | /* maximum number of hardware queues we support. */ | 21 | /* Default mapping in classifier to work with default |
| 22 | #define TC_80211_MAX_QUEUES 16 | 22 | * queue setup. |
| 23 | 23 | */ | |
| 24 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | 24 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; |
| 25 | 25 | ||
| 26 | struct ieee80211_sched_data | ||
| 27 | { | ||
| 28 | unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)]; | ||
| 29 | struct tcf_proto *filter_list; | ||
| 30 | struct Qdisc *queues[TC_80211_MAX_QUEUES]; | ||
| 31 | struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; | ||
| 32 | }; | ||
| 33 | |||
| 34 | static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0}; | 26 | static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0}; |
| 35 | 27 | ||
| 36 | /* given a data frame determine the 802.1p/1d tag to use */ | 28 | /* Given a data frame determine the 802.1p/1d tag to use. */ |
| 37 | static inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd) | 29 | static unsigned int classify_1d(struct sk_buff *skb) |
| 38 | { | 30 | { |
| 39 | struct iphdr *ip; | 31 | unsigned int dscp; |
| 40 | int dscp; | ||
| 41 | int offset; | ||
| 42 | |||
| 43 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 44 | struct tcf_result res = { -1, 0 }; | ||
| 45 | |||
| 46 | /* if there is a user set filter list, call out to that */ | ||
| 47 | if (q->filter_list) { | ||
| 48 | tc_classify(skb, q->filter_list, &res); | ||
| 49 | if (res.class != -1) | ||
| 50 | return res.class; | ||
| 51 | } | ||
| 52 | 32 | ||
| 53 | /* skb->priority values from 256->263 are magic values to | 33 | /* skb->priority values from 256->263 are magic values to |
| 54 | * directly indicate a specific 802.1d priority. | 34 | * directly indicate a specific 802.1d priority. This is used |
| 55 | * This is used to allow 802.1d priority to be passed directly in | 35 | * to allow 802.1d priority to be passed directly in from VLAN |
| 56 | * from VLAN tags, etc. */ | 36 | * tags, etc. |
| 37 | */ | ||
| 57 | if (skb->priority >= 256 && skb->priority <= 263) | 38 | if (skb->priority >= 256 && skb->priority <= 263) |
| 58 | return skb->priority - 256; | 39 | return skb->priority - 256; |
| 59 | 40 | ||
| 60 | /* check there is a valid IP header present */ | 41 | switch (skb->protocol) { |
| 61 | offset = ieee80211_get_hdrlen_from_skb(skb); | 42 | case __constant_htons(ETH_P_IP): |
| 62 | if (skb->len < offset + sizeof(llc_ip_hdr) + sizeof(*ip) || | 43 | dscp = ip_hdr(skb)->tos & 0xfc; |
| 63 | memcmp(skb->data + offset, llc_ip_hdr, sizeof(llc_ip_hdr))) | 44 | break; |
| 64 | return 0; | ||
| 65 | 45 | ||
| 66 | ip = (struct iphdr *) (skb->data + offset + sizeof(llc_ip_hdr)); | 46 | default: |
| 47 | return 0; | ||
| 48 | } | ||
| 67 | 49 | ||
| 68 | dscp = ip->tos & 0xfc; | ||
| 69 | if (dscp & 0x1c) | 50 | if (dscp & 0x1c) |
| 70 | return 0; | 51 | return 0; |
| 71 | return dscp >> 5; | 52 | return dscp >> 5; |
| 72 | } | 53 | } |
| 73 | 54 | ||
| 74 | 55 | ||
| 75 | static inline int wme_downgrade_ac(struct sk_buff *skb) | 56 | static int wme_downgrade_ac(struct sk_buff *skb) |
| 76 | { | 57 | { |
| 77 | switch (skb->priority) { | 58 | switch (skb->priority) { |
| 78 | case 6: | 59 | case 6: |
| @@ -93,43 +74,38 @@ static inline int wme_downgrade_ac(struct sk_buff *skb) | |||
| 93 | } | 74 | } |
| 94 | 75 | ||
| 95 | 76 | ||
| 96 | /* positive return value indicates which queue to use | 77 | /* Indicate which queue to use. */ |
| 97 | * negative return value indicates to drop the frame */ | 78 | static u16 classify80211(struct sk_buff *skb, struct net_device *dev) |
| 98 | static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) | ||
| 99 | { | 79 | { |
| 100 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 80 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 101 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 81 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 102 | unsigned short fc = le16_to_cpu(hdr->frame_control); | ||
| 103 | int qos; | ||
| 104 | 82 | ||
| 105 | /* see if frame is data or non data frame */ | 83 | if (!ieee80211_is_data(hdr->frame_control)) { |
| 106 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { | ||
| 107 | /* management frames go on AC_VO queue, but are sent | 84 | /* management frames go on AC_VO queue, but are sent |
| 108 | * without QoS control fields */ | 85 | * without QoS control fields */ |
| 109 | return IEEE80211_TX_QUEUE_DATA0; | 86 | return 0; |
| 110 | } | 87 | } |
| 111 | 88 | ||
| 112 | if (0 /* injected */) { | 89 | if (0 /* injected */) { |
| 113 | /* use AC from radiotap */ | 90 | /* use AC from radiotap */ |
| 114 | } | 91 | } |
| 115 | 92 | ||
| 116 | /* is this a QoS frame? */ | 93 | if (!ieee80211_is_data_qos(hdr->frame_control)) { |
| 117 | qos = fc & IEEE80211_STYPE_QOS_DATA; | ||
| 118 | |||
| 119 | if (!qos) { | ||
| 120 | skb->priority = 0; /* required for correct WPA/11i MIC */ | 94 | skb->priority = 0; /* required for correct WPA/11i MIC */ |
| 121 | return ieee802_1d_to_ac[skb->priority]; | 95 | return ieee802_1d_to_ac[skb->priority]; |
| 122 | } | 96 | } |
| 123 | 97 | ||
| 124 | /* use the data classifier to determine what 802.1d tag the | 98 | /* use the data classifier to determine what 802.1d tag the |
| 125 | * data frame has */ | 99 | * data frame has */ |
| 126 | skb->priority = classify_1d(skb, qd); | 100 | skb->priority = classify_1d(skb); |
| 127 | 101 | ||
| 128 | /* in case we are a client verify acm is not set for this ac */ | 102 | /* in case we are a client verify acm is not set for this ac */ |
| 129 | while (unlikely(local->wmm_acm & BIT(skb->priority))) { | 103 | while (unlikely(local->wmm_acm & BIT(skb->priority))) { |
| 130 | if (wme_downgrade_ac(skb)) { | 104 | if (wme_downgrade_ac(skb)) { |
| 131 | /* No AC with lower priority has acm=0, drop packet. */ | 105 | /* The old code would drop the packet in this |
| 132 | return -1; | 106 | * case. |
| 107 | */ | ||
| 108 | return 0; | ||
| 133 | } | 109 | } |
| 134 | } | 110 | } |
| 135 | 111 | ||
| @@ -137,55 +113,52 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) | |||
| 137 | return ieee802_1d_to_ac[skb->priority]; | 113 | return ieee802_1d_to_ac[skb->priority]; |
| 138 | } | 114 | } |
| 139 | 115 | ||
| 140 | 116 | u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |
| 141 | static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | ||
| 142 | { | 117 | { |
| 143 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 144 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 145 | struct ieee80211_tx_packet_data *pkt_data = | ||
| 146 | (struct ieee80211_tx_packet_data *) skb->cb; | ||
| 147 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 118 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 148 | unsigned short fc = le16_to_cpu(hdr->frame_control); | 119 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
| 149 | struct Qdisc *qdisc; | 120 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 150 | int err, queue; | ||
| 151 | struct sta_info *sta; | 121 | struct sta_info *sta; |
| 122 | u16 queue; | ||
| 152 | u8 tid; | 123 | u8 tid; |
| 153 | 124 | ||
| 154 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { | 125 | queue = classify80211(skb, dev); |
| 155 | queue = pkt_data->queue; | 126 | if (unlikely(queue >= local->hw.queues)) |
| 127 | queue = local->hw.queues - 1; | ||
| 128 | |||
| 129 | if (info->flags & IEEE80211_TX_CTL_REQUEUE) { | ||
| 156 | rcu_read_lock(); | 130 | rcu_read_lock(); |
| 157 | sta = sta_info_get(local, hdr->addr1); | 131 | sta = sta_info_get(local, hdr->addr1); |
| 158 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 132 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
| 159 | if (sta) { | 133 | if (sta) { |
| 134 | struct ieee80211_hw *hw = &local->hw; | ||
| 160 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 135 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
| 161 | if ((ampdu_queue < local->hw.queues) && | 136 | |
| 162 | test_bit(ampdu_queue, q->qdisc_pool)) { | 137 | if ((ampdu_queue < ieee80211_num_queues(hw)) && |
| 138 | test_bit(ampdu_queue, local->queue_pool)) { | ||
| 163 | queue = ampdu_queue; | 139 | queue = ampdu_queue; |
| 164 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | 140 | info->flags |= IEEE80211_TX_CTL_AMPDU; |
| 165 | } else { | 141 | } else { |
| 166 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | 142 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
| 167 | } | 143 | } |
| 168 | } | 144 | } |
| 169 | rcu_read_unlock(); | 145 | rcu_read_unlock(); |
| 170 | skb_queue_tail(&q->requeued[queue], skb); | ||
| 171 | qd->q.qlen++; | ||
| 172 | return 0; | ||
| 173 | } | ||
| 174 | 146 | ||
| 175 | queue = classify80211(skb, qd); | 147 | return queue; |
| 148 | } | ||
| 176 | 149 | ||
| 177 | /* now we know the 1d priority, fill in the QoS header if there is one | 150 | /* Now we know the 1d priority, fill in the QoS header if |
| 151 | * there is one. | ||
| 178 | */ | 152 | */ |
| 179 | if (WLAN_FC_IS_QOS_DATA(fc)) { | 153 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
| 180 | u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; | 154 | u8 *p = ieee80211_get_qos_ctl(hdr); |
| 181 | u8 ack_policy = 0; | 155 | u8 ack_policy = 0; |
| 182 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 156 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
| 183 | if (local->wifi_wme_noack_test) | 157 | if (local->wifi_wme_noack_test) |
| 184 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << | 158 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << |
| 185 | QOS_CONTROL_ACK_POLICY_SHIFT; | 159 | QOS_CONTROL_ACK_POLICY_SHIFT; |
| 186 | /* qos header is 2 bytes, second reserved */ | 160 | /* qos header is 2 bytes, second reserved */ |
| 187 | *p = ack_policy | tid; | 161 | *p++ = ack_policy | tid; |
| 188 | p++; | ||
| 189 | *p = 0; | 162 | *p = 0; |
| 190 | 163 | ||
| 191 | rcu_read_lock(); | 164 | rcu_read_lock(); |
| @@ -193,476 +166,37 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
| 193 | sta = sta_info_get(local, hdr->addr1); | 166 | sta = sta_info_get(local, hdr->addr1); |
| 194 | if (sta) { | 167 | if (sta) { |
| 195 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 168 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
| 196 | if ((ampdu_queue < local->hw.queues) && | 169 | struct ieee80211_hw *hw = &local->hw; |
| 197 | test_bit(ampdu_queue, q->qdisc_pool)) { | 170 | |
| 171 | if ((ampdu_queue < ieee80211_num_queues(hw)) && | ||
| 172 | test_bit(ampdu_queue, local->queue_pool)) { | ||
| 198 | queue = ampdu_queue; | 173 | queue = ampdu_queue; |
| 199 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | 174 | info->flags |= IEEE80211_TX_CTL_AMPDU; |
| 200 | } else { | 175 | } else { |
| 201 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | 176 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
| 202 | } | 177 | } |
| 203 | } | 178 | } |
| 204 | 179 | ||
| 205 | rcu_read_unlock(); | 180 | rcu_read_unlock(); |
| 206 | } | 181 | } |
| 207 | 182 | ||
| 208 | if (unlikely(queue >= local->hw.queues)) { | ||
| 209 | #if 0 | ||
| 210 | if (net_ratelimit()) { | ||
| 211 | printk(KERN_DEBUG "%s - queue=%d (hw does not " | ||
| 212 | "support) -> %d\n", | ||
| 213 | __func__, queue, local->hw.queues - 1); | ||
| 214 | } | ||
| 215 | #endif | ||
| 216 | queue = local->hw.queues - 1; | ||
| 217 | } | ||
| 218 | |||
| 219 | if (unlikely(queue < 0)) { | ||
| 220 | kfree_skb(skb); | ||
| 221 | err = NET_XMIT_DROP; | ||
| 222 | } else { | ||
| 223 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | ||
| 224 | pkt_data->queue = (unsigned int) queue; | ||
| 225 | qdisc = q->queues[queue]; | ||
| 226 | err = qdisc->enqueue(skb, qdisc); | ||
| 227 | if (err == NET_XMIT_SUCCESS) { | ||
| 228 | qd->q.qlen++; | ||
| 229 | qd->bstats.bytes += skb->len; | ||
| 230 | qd->bstats.packets++; | ||
| 231 | return NET_XMIT_SUCCESS; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | qd->qstats.drops++; | ||
| 235 | return err; | ||
| 236 | } | ||
| 237 | |||
| 238 | |||
| 239 | /* TODO: clean up the cases where master_hard_start_xmit | ||
| 240 | * returns non 0 - it shouldn't ever do that. Once done we | ||
| 241 | * can remove this function */ | ||
| 242 | static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) | ||
| 243 | { | ||
| 244 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 245 | struct ieee80211_tx_packet_data *pkt_data = | ||
| 246 | (struct ieee80211_tx_packet_data *) skb->cb; | ||
| 247 | struct Qdisc *qdisc; | ||
| 248 | int err; | ||
| 249 | |||
| 250 | /* we recorded which queue to use earlier! */ | ||
| 251 | qdisc = q->queues[pkt_data->queue]; | ||
| 252 | |||
| 253 | if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { | ||
| 254 | qd->q.qlen++; | ||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | qd->qstats.drops++; | ||
| 258 | return err; | ||
| 259 | } | ||
| 260 | |||
| 261 | |||
| 262 | static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd) | ||
| 263 | { | ||
| 264 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 265 | struct net_device *dev = qd->dev; | ||
| 266 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
| 267 | struct ieee80211_hw *hw = &local->hw; | ||
| 268 | struct sk_buff *skb; | ||
| 269 | struct Qdisc *qdisc; | ||
| 270 | int queue; | ||
| 271 | |||
| 272 | /* check all the h/w queues in numeric/priority order */ | ||
| 273 | for (queue = 0; queue < hw->queues; queue++) { | ||
| 274 | /* see if there is room in this hardware queue */ | ||
| 275 | if ((test_bit(IEEE80211_LINK_STATE_XOFF, | ||
| 276 | &local->state[queue])) || | ||
| 277 | (test_bit(IEEE80211_LINK_STATE_PENDING, | ||
| 278 | &local->state[queue])) || | ||
| 279 | (!test_bit(queue, q->qdisc_pool))) | ||
| 280 | continue; | ||
| 281 | |||
| 282 | /* there is space - try and get a frame */ | ||
| 283 | skb = skb_dequeue(&q->requeued[queue]); | ||
| 284 | if (skb) { | ||
| 285 | qd->q.qlen--; | ||
| 286 | return skb; | ||
| 287 | } | ||
| 288 | |||
| 289 | qdisc = q->queues[queue]; | ||
| 290 | skb = qdisc->dequeue(qdisc); | ||
| 291 | if (skb) { | ||
| 292 | qd->q.qlen--; | ||
| 293 | return skb; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | /* returning a NULL here when all the h/w queues are full means we | ||
| 297 | * never need to call netif_stop_queue in the driver */ | ||
| 298 | return NULL; | ||
| 299 | } | ||
| 300 | |||
| 301 | |||
| 302 | static void wme_qdiscop_reset(struct Qdisc* qd) | ||
| 303 | { | ||
| 304 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 305 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 306 | struct ieee80211_hw *hw = &local->hw; | ||
| 307 | int queue; | ||
| 308 | |||
| 309 | /* QUESTION: should we have some hardware flush functionality here? */ | ||
| 310 | |||
| 311 | for (queue = 0; queue < hw->queues; queue++) { | ||
| 312 | skb_queue_purge(&q->requeued[queue]); | ||
| 313 | qdisc_reset(q->queues[queue]); | ||
| 314 | } | ||
| 315 | qd->q.qlen = 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | |||
| 319 | static void wme_qdiscop_destroy(struct Qdisc* qd) | ||
| 320 | { | ||
| 321 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 322 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 323 | struct ieee80211_hw *hw = &local->hw; | ||
| 324 | int queue; | ||
| 325 | |||
| 326 | tcf_destroy_chain(q->filter_list); | ||
| 327 | q->filter_list = NULL; | ||
| 328 | |||
| 329 | for (queue=0; queue < hw->queues; queue++) { | ||
| 330 | skb_queue_purge(&q->requeued[queue]); | ||
| 331 | qdisc_destroy(q->queues[queue]); | ||
| 332 | q->queues[queue] = &noop_qdisc; | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | |||
| 337 | /* called whenever parameters are updated on existing qdisc */ | ||
| 338 | static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) | ||
| 339 | { | ||
| 340 | /* struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 341 | */ | ||
| 342 | /* check our options block is the right size */ | ||
| 343 | /* copy any options to our local structure */ | ||
| 344 | /* Ignore options block for now - always use static mapping | ||
| 345 | struct tc_ieee80211_qopt *qopt = nla_data(opt); | ||
| 346 | |||
| 347 | if (opt->nla_len < nla_attr_size(sizeof(*qopt))) | ||
| 348 | return -EINVAL; | ||
| 349 | memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue)); | ||
| 350 | */ | ||
| 351 | return 0; | ||
| 352 | } | ||
| 353 | |||
| 354 | |||
| 355 | /* called during initial creation of qdisc on device */ | ||
| 356 | static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | ||
| 357 | { | ||
| 358 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 359 | struct net_device *dev = qd->dev; | ||
| 360 | struct ieee80211_local *local; | ||
| 361 | int queues; | ||
| 362 | int err = 0, i; | ||
| 363 | |||
| 364 | /* check that device is a mac80211 device */ | ||
| 365 | if (!dev->ieee80211_ptr || | ||
| 366 | dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) | ||
| 367 | return -EINVAL; | ||
| 368 | |||
| 369 | /* check this device is an ieee80211 master type device */ | ||
| 370 | if (dev->type != ARPHRD_IEEE80211) | ||
| 371 | return -EINVAL; | ||
| 372 | |||
| 373 | /* check that there is no qdisc currently attached to device | ||
| 374 | * this ensures that we will be the root qdisc. (I can't find a better | ||
| 375 | * way to test this explicitly) */ | ||
| 376 | if (dev->qdisc_sleeping != &noop_qdisc) | ||
| 377 | return -EINVAL; | ||
| 378 | |||
| 379 | if (qd->flags & TCQ_F_INGRESS) | ||
| 380 | return -EINVAL; | ||
| 381 | |||
| 382 | local = wdev_priv(dev->ieee80211_ptr); | ||
| 383 | queues = local->hw.queues; | ||
| 384 | |||
| 385 | /* if options were passed in, set them */ | ||
| 386 | if (opt) { | ||
| 387 | err = wme_qdiscop_tune(qd, opt); | ||
| 388 | } | ||
| 389 | |||
| 390 | /* create child queues */ | ||
| 391 | for (i = 0; i < queues; i++) { | ||
| 392 | skb_queue_head_init(&q->requeued[i]); | ||
| 393 | q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, | ||
| 394 | qd->handle); | ||
| 395 | if (!q->queues[i]) { | ||
| 396 | q->queues[i] = &noop_qdisc; | ||
| 397 | printk(KERN_ERR "%s child qdisc %i creation failed\n", | ||
| 398 | dev->name, i); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | /* reserve all legacy QoS queues */ | ||
| 403 | for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++) | ||
| 404 | set_bit(i, q->qdisc_pool); | ||
| 405 | |||
| 406 | return err; | ||
| 407 | } | ||
| 408 | |||
| 409 | static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) | ||
| 410 | { | ||
| 411 | /* struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 412 | unsigned char *p = skb->tail; | ||
| 413 | struct tc_ieee80211_qopt opt; | ||
| 414 | |||
| 415 | memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1); | ||
| 416 | NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); | ||
| 417 | */ return skb->len; | ||
| 418 | /* | ||
| 419 | nla_put_failure: | ||
| 420 | skb_trim(skb, p - skb->data);*/ | ||
| 421 | return -1; | ||
| 422 | } | ||
| 423 | |||
| 424 | |||
| 425 | static int wme_classop_graft(struct Qdisc *qd, unsigned long arg, | ||
| 426 | struct Qdisc *new, struct Qdisc **old) | ||
| 427 | { | ||
| 428 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 429 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 430 | struct ieee80211_hw *hw = &local->hw; | ||
| 431 | unsigned long queue = arg - 1; | ||
| 432 | |||
| 433 | if (queue >= hw->queues) | ||
| 434 | return -EINVAL; | ||
| 435 | |||
| 436 | if (!new) | ||
| 437 | new = &noop_qdisc; | ||
| 438 | |||
| 439 | sch_tree_lock(qd); | ||
| 440 | *old = q->queues[queue]; | ||
| 441 | q->queues[queue] = new; | ||
| 442 | qdisc_reset(*old); | ||
| 443 | sch_tree_unlock(qd); | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | static struct Qdisc * | ||
| 450 | wme_classop_leaf(struct Qdisc *qd, unsigned long arg) | ||
| 451 | { | ||
| 452 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 453 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 454 | struct ieee80211_hw *hw = &local->hw; | ||
| 455 | unsigned long queue = arg - 1; | ||
| 456 | |||
| 457 | if (queue >= hw->queues) | ||
| 458 | return NULL; | ||
| 459 | |||
| 460 | return q->queues[queue]; | ||
| 461 | } | ||
| 462 | |||
| 463 | |||
| 464 | static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid) | ||
| 465 | { | ||
| 466 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 467 | struct ieee80211_hw *hw = &local->hw; | ||
| 468 | unsigned long queue = TC_H_MIN(classid); | ||
| 469 | |||
| 470 | if (queue - 1 >= hw->queues) | ||
| 471 | return 0; | ||
| 472 | |||
| 473 | return queue; | 183 | return queue; |
| 474 | } | 184 | } |
| 475 | 185 | ||
| 476 | |||
| 477 | static unsigned long wme_classop_bind(struct Qdisc *qd, unsigned long parent, | ||
| 478 | u32 classid) | ||
| 479 | { | ||
| 480 | return wme_classop_get(qd, classid); | ||
| 481 | } | ||
| 482 | |||
| 483 | |||
| 484 | static void wme_classop_put(struct Qdisc *q, unsigned long cl) | ||
| 485 | { | ||
| 486 | } | ||
| 487 | |||
| 488 | |||
| 489 | static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent, | ||
| 490 | struct nlattr **tca, unsigned long *arg) | ||
| 491 | { | ||
| 492 | unsigned long cl = *arg; | ||
| 493 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 494 | struct ieee80211_hw *hw = &local->hw; | ||
| 495 | |||
| 496 | if (cl - 1 > hw->queues) | ||
| 497 | return -ENOENT; | ||
| 498 | |||
| 499 | /* TODO: put code to program hardware queue parameters here, | ||
| 500 | * to allow programming from tc command line */ | ||
| 501 | |||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | |||
| 505 | |||
| 506 | /* we don't support deleting hardware queues | ||
| 507 | * when we add WMM-SA support - TSPECs may be deleted here */ | ||
| 508 | static int wme_classop_delete(struct Qdisc *qd, unsigned long cl) | ||
| 509 | { | ||
| 510 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 511 | struct ieee80211_hw *hw = &local->hw; | ||
| 512 | |||
| 513 | if (cl - 1 > hw->queues) | ||
| 514 | return -ENOENT; | ||
| 515 | return 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | |||
| 519 | static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl, | ||
| 520 | struct sk_buff *skb, struct tcmsg *tcm) | ||
| 521 | { | ||
| 522 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 523 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 524 | struct ieee80211_hw *hw = &local->hw; | ||
| 525 | |||
| 526 | if (cl - 1 > hw->queues) | ||
| 527 | return -ENOENT; | ||
| 528 | tcm->tcm_handle = TC_H_MIN(cl); | ||
| 529 | tcm->tcm_parent = qd->handle; | ||
| 530 | tcm->tcm_info = q->queues[cl-1]->handle; /* do we need this? */ | ||
| 531 | return 0; | ||
| 532 | } | ||
| 533 | |||
| 534 | |||
| 535 | static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg) | ||
| 536 | { | ||
| 537 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | ||
| 538 | struct ieee80211_hw *hw = &local->hw; | ||
| 539 | int queue; | ||
| 540 | |||
| 541 | if (arg->stop) | ||
| 542 | return; | ||
| 543 | |||
| 544 | for (queue = 0; queue < hw->queues; queue++) { | ||
| 545 | if (arg->count < arg->skip) { | ||
| 546 | arg->count++; | ||
| 547 | continue; | ||
| 548 | } | ||
| 549 | /* we should return classids for our internal queues here | ||
| 550 | * as well as the external ones */ | ||
| 551 | if (arg->fn(qd, queue+1, arg) < 0) { | ||
| 552 | arg->stop = 1; | ||
| 553 | break; | ||
| 554 | } | ||
| 555 | arg->count++; | ||
| 556 | } | ||
| 557 | } | ||
| 558 | |||
| 559 | |||
| 560 | static struct tcf_proto ** wme_classop_find_tcf(struct Qdisc *qd, | ||
| 561 | unsigned long cl) | ||
| 562 | { | ||
| 563 | struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
| 564 | |||
| 565 | if (cl) | ||
| 566 | return NULL; | ||
| 567 | |||
| 568 | return &q->filter_list; | ||
| 569 | } | ||
| 570 | |||
| 571 | |||
| 572 | /* this qdisc is classful (i.e. has classes, some of which may have leaf qdiscs attached) | ||
| 573 | * - these are the operations on the classes */ | ||
| 574 | static const struct Qdisc_class_ops class_ops = | ||
| 575 | { | ||
| 576 | .graft = wme_classop_graft, | ||
| 577 | .leaf = wme_classop_leaf, | ||
| 578 | |||
| 579 | .get = wme_classop_get, | ||
| 580 | .put = wme_classop_put, | ||
| 581 | .change = wme_classop_change, | ||
| 582 | .delete = wme_classop_delete, | ||
| 583 | .walk = wme_classop_walk, | ||
| 584 | |||
| 585 | .tcf_chain = wme_classop_find_tcf, | ||
| 586 | .bind_tcf = wme_classop_bind, | ||
| 587 | .unbind_tcf = wme_classop_put, | ||
| 588 | |||
| 589 | .dump = wme_classop_dump_class, | ||
| 590 | }; | ||
| 591 | |||
| 592 | |||
| 593 | /* queueing discipline operations */ | ||
| 594 | static struct Qdisc_ops wme_qdisc_ops __read_mostly = | ||
| 595 | { | ||
| 596 | .next = NULL, | ||
| 597 | .cl_ops = &class_ops, | ||
| 598 | .id = "ieee80211", | ||
| 599 | .priv_size = sizeof(struct ieee80211_sched_data), | ||
| 600 | |||
| 601 | .enqueue = wme_qdiscop_enqueue, | ||
| 602 | .dequeue = wme_qdiscop_dequeue, | ||
| 603 | .requeue = wme_qdiscop_requeue, | ||
| 604 | .drop = NULL, /* drop not needed since we are always the root qdisc */ | ||
| 605 | |||
| 606 | .init = wme_qdiscop_init, | ||
| 607 | .reset = wme_qdiscop_reset, | ||
| 608 | .destroy = wme_qdiscop_destroy, | ||
| 609 | .change = wme_qdiscop_tune, | ||
| 610 | |||
| 611 | .dump = wme_qdiscop_dump, | ||
| 612 | }; | ||
| 613 | |||
| 614 | |||
| 615 | void ieee80211_install_qdisc(struct net_device *dev) | ||
| 616 | { | ||
| 617 | struct Qdisc *qdisc; | ||
| 618 | |||
| 619 | qdisc = qdisc_create_dflt(dev, &wme_qdisc_ops, TC_H_ROOT); | ||
| 620 | if (!qdisc) { | ||
| 621 | printk(KERN_ERR "%s: qdisc installation failed\n", dev->name); | ||
| 622 | return; | ||
| 623 | } | ||
| 624 | |||
| 625 | /* same handle as would be allocated by qdisc_alloc_handle() */ | ||
| 626 | qdisc->handle = 0x80010000; | ||
| 627 | |||
| 628 | qdisc_lock_tree(dev); | ||
| 629 | list_add_tail(&qdisc->list, &dev->qdisc_list); | ||
| 630 | dev->qdisc_sleeping = qdisc; | ||
| 631 | qdisc_unlock_tree(dev); | ||
| 632 | } | ||
| 633 | |||
| 634 | |||
| 635 | int ieee80211_qdisc_installed(struct net_device *dev) | ||
| 636 | { | ||
| 637 | return dev->qdisc_sleeping->ops == &wme_qdisc_ops; | ||
| 638 | } | ||
| 639 | |||
| 640 | |||
| 641 | int ieee80211_wme_register(void) | ||
| 642 | { | ||
| 643 | return register_qdisc(&wme_qdisc_ops); | ||
| 644 | } | ||
| 645 | |||
| 646 | |||
| 647 | void ieee80211_wme_unregister(void) | ||
| 648 | { | ||
| 649 | unregister_qdisc(&wme_qdisc_ops); | ||
| 650 | } | ||
| 651 | |||
| 652 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | 186 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, |
| 653 | struct sta_info *sta, u16 tid) | 187 | struct sta_info *sta, u16 tid) |
| 654 | { | 188 | { |
| 655 | int i; | 189 | int i; |
| 656 | struct ieee80211_sched_data *q = | ||
| 657 | qdisc_priv(local->mdev->qdisc_sleeping); | ||
| 658 | DECLARE_MAC_BUF(mac); | ||
| 659 | 190 | ||
| 660 | /* prepare the filter and save it for the SW queue | 191 | /* prepare the filter and save it for the SW queue |
| 661 | * matching the recieved HW queue */ | 192 | * matching the received HW queue */ |
| 193 | |||
| 194 | if (!local->hw.ampdu_queues) | ||
| 195 | return -EPERM; | ||
| 662 | 196 | ||
| 663 | /* try to get a Qdisc from the pool */ | 197 | /* try to get a Qdisc from the pool */ |
| 664 | for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++) | 198 | for (i = local->hw.queues; i < ieee80211_num_queues(&local->hw); i++) |
| 665 | if (!test_and_set_bit(i, q->qdisc_pool)) { | 199 | if (!test_and_set_bit(i, local->queue_pool)) { |
| 666 | ieee80211_stop_queue(local_to_hw(local), i); | 200 | ieee80211_stop_queue(local_to_hw(local), i); |
| 667 | sta->tid_to_tx_q[tid] = i; | 201 | sta->tid_to_tx_q[tid] = i; |
| 668 | 202 | ||
| @@ -671,11 +205,13 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
| 671 | * on the previous queue | 205 | * on the previous queue |
| 672 | * since HT is strict in order */ | 206 | * since HT is strict in order */ |
| 673 | #ifdef CONFIG_MAC80211_HT_DEBUG | 207 | #ifdef CONFIG_MAC80211_HT_DEBUG |
| 674 | if (net_ratelimit()) | 208 | if (net_ratelimit()) { |
| 209 | DECLARE_MAC_BUF(mac); | ||
| 675 | printk(KERN_DEBUG "allocated aggregation queue" | 210 | printk(KERN_DEBUG "allocated aggregation queue" |
| 676 | " %d tid %d addr %s pool=0x%lX\n", | 211 | " %d tid %d addr %s pool=0x%lX\n", |
| 677 | i, tid, print_mac(mac, sta->addr), | 212 | i, tid, print_mac(mac, sta->addr), |
| 678 | q->qdisc_pool[0]); | 213 | local->queue_pool[0]); |
| 214 | } | ||
| 679 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 215 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
| 680 | return 0; | 216 | return 0; |
| 681 | } | 217 | } |
| @@ -684,44 +220,79 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
| 684 | } | 220 | } |
| 685 | 221 | ||
| 686 | /** | 222 | /** |
| 687 | * the caller needs to hold local->mdev->queue_lock | 223 | * the caller needs to hold netdev_get_tx_queue(local->mdev, X)->lock |
| 688 | */ | 224 | */ |
| 689 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | 225 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, |
| 690 | struct sta_info *sta, u16 tid, | 226 | struct sta_info *sta, u16 tid, |
| 691 | u8 requeue) | 227 | u8 requeue) |
| 692 | { | 228 | { |
| 693 | struct ieee80211_sched_data *q = | ||
| 694 | qdisc_priv(local->mdev->qdisc_sleeping); | ||
| 695 | int agg_queue = sta->tid_to_tx_q[tid]; | 229 | int agg_queue = sta->tid_to_tx_q[tid]; |
| 230 | struct ieee80211_hw *hw = &local->hw; | ||
| 696 | 231 | ||
| 697 | /* return the qdisc to the pool */ | 232 | /* return the qdisc to the pool */ |
| 698 | clear_bit(agg_queue, q->qdisc_pool); | 233 | clear_bit(agg_queue, local->queue_pool); |
| 699 | sta->tid_to_tx_q[tid] = local->hw.queues; | 234 | sta->tid_to_tx_q[tid] = ieee80211_num_queues(hw); |
| 700 | 235 | ||
| 701 | if (requeue) | 236 | if (requeue) { |
| 702 | ieee80211_requeue(local, agg_queue); | 237 | ieee80211_requeue(local, agg_queue); |
| 703 | else | 238 | } else { |
| 704 | q->queues[agg_queue]->ops->reset(q->queues[agg_queue]); | 239 | struct netdev_queue *txq; |
| 240 | spinlock_t *root_lock; | ||
| 241 | |||
| 242 | txq = netdev_get_tx_queue(local->mdev, agg_queue); | ||
| 243 | root_lock = qdisc_root_lock(txq->qdisc); | ||
| 244 | |||
| 245 | spin_lock_bh(root_lock); | ||
| 246 | qdisc_reset(txq->qdisc); | ||
| 247 | spin_unlock_bh(root_lock); | ||
| 248 | } | ||
| 705 | } | 249 | } |
| 706 | 250 | ||
| 707 | void ieee80211_requeue(struct ieee80211_local *local, int queue) | 251 | void ieee80211_requeue(struct ieee80211_local *local, int queue) |
| 708 | { | 252 | { |
| 709 | struct Qdisc *root_qd = local->mdev->qdisc_sleeping; | 253 | struct netdev_queue *txq = netdev_get_tx_queue(local->mdev, queue); |
| 710 | struct ieee80211_sched_data *q = qdisc_priv(root_qd); | 254 | struct sk_buff_head list; |
| 711 | struct Qdisc *qdisc = q->queues[queue]; | 255 | spinlock_t *root_lock; |
| 712 | struct sk_buff *skb = NULL; | 256 | struct Qdisc *qdisc; |
| 713 | u32 len; | 257 | u32 len; |
| 714 | 258 | ||
| 259 | rcu_read_lock_bh(); | ||
| 260 | |||
| 261 | qdisc = rcu_dereference(txq->qdisc); | ||
| 715 | if (!qdisc || !qdisc->dequeue) | 262 | if (!qdisc || !qdisc->dequeue) |
| 716 | return; | 263 | goto out_unlock; |
| 264 | |||
| 265 | skb_queue_head_init(&list); | ||
| 717 | 266 | ||
| 718 | printk(KERN_DEBUG "requeue: qlen = %d\n", qdisc->q.qlen); | 267 | root_lock = qdisc_root_lock(qdisc); |
| 268 | spin_lock(root_lock); | ||
| 719 | for (len = qdisc->q.qlen; len > 0; len--) { | 269 | for (len = qdisc->q.qlen; len > 0; len--) { |
| 720 | skb = qdisc->dequeue(qdisc); | 270 | struct sk_buff *skb = qdisc->dequeue(qdisc); |
| 721 | root_qd->q.qlen--; | 271 | |
| 722 | /* packet will be classified again and */ | ||
| 723 | /* skb->packet_data->queue will be overridden if needed */ | ||
| 724 | if (skb) | 272 | if (skb) |
| 725 | wme_qdiscop_enqueue(skb, root_qd); | 273 | __skb_queue_tail(&list, skb); |
| 274 | } | ||
| 275 | spin_unlock(root_lock); | ||
| 276 | |||
| 277 | for (len = list.qlen; len > 0; len--) { | ||
| 278 | struct sk_buff *skb = __skb_dequeue(&list); | ||
| 279 | u16 new_queue; | ||
| 280 | |||
| 281 | BUG_ON(!skb); | ||
| 282 | new_queue = ieee80211_select_queue(local->mdev, skb); | ||
| 283 | skb_set_queue_mapping(skb, new_queue); | ||
| 284 | |||
| 285 | txq = netdev_get_tx_queue(local->mdev, new_queue); | ||
| 286 | |||
| 287 | |||
| 288 | qdisc = rcu_dereference(txq->qdisc); | ||
| 289 | root_lock = qdisc_root_lock(qdisc); | ||
| 290 | |||
| 291 | spin_lock(root_lock); | ||
| 292 | qdisc_enqueue_root(skb, qdisc); | ||
| 293 | spin_unlock(root_lock); | ||
| 726 | } | 294 | } |
| 295 | |||
| 296 | out_unlock: | ||
| 297 | rcu_read_unlock_bh(); | ||
| 727 | } | 298 | } |
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index fcc6b05508cc..04de28c071a6 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h | |||
| @@ -19,57 +19,16 @@ | |||
| 19 | #define QOS_CONTROL_ACK_POLICY_NORMAL 0 | 19 | #define QOS_CONTROL_ACK_POLICY_NORMAL 0 |
| 20 | #define QOS_CONTROL_ACK_POLICY_NOACK 1 | 20 | #define QOS_CONTROL_ACK_POLICY_NOACK 1 |
| 21 | 21 | ||
| 22 | #define QOS_CONTROL_TID_MASK 0x0f | ||
| 23 | #define QOS_CONTROL_ACK_POLICY_SHIFT 5 | 22 | #define QOS_CONTROL_ACK_POLICY_SHIFT 5 |
| 24 | 23 | ||
| 25 | #define QOS_CONTROL_TAG1D_MASK 0x07 | ||
| 26 | |||
| 27 | extern const int ieee802_1d_to_ac[8]; | 24 | extern const int ieee802_1d_to_ac[8]; |
| 28 | 25 | ||
| 29 | static inline int WLAN_FC_IS_QOS_DATA(u16 fc) | 26 | u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb); |
| 30 | { | ||
| 31 | return (fc & 0x8C) == 0x88; | ||
| 32 | } | ||
| 33 | |||
| 34 | #ifdef CONFIG_NET_SCHED | ||
| 35 | void ieee80211_install_qdisc(struct net_device *dev); | ||
| 36 | int ieee80211_qdisc_installed(struct net_device *dev); | ||
| 37 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | 27 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, |
| 38 | struct sta_info *sta, u16 tid); | 28 | struct sta_info *sta, u16 tid); |
| 39 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | 29 | void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, |
| 40 | struct sta_info *sta, u16 tid, | 30 | struct sta_info *sta, u16 tid, |
| 41 | u8 requeue); | 31 | u8 requeue); |
| 42 | void ieee80211_requeue(struct ieee80211_local *local, int queue); | 32 | void ieee80211_requeue(struct ieee80211_local *local, int queue); |
| 43 | int ieee80211_wme_register(void); | ||
| 44 | void ieee80211_wme_unregister(void); | ||
| 45 | #else | ||
| 46 | static inline void ieee80211_install_qdisc(struct net_device *dev) | ||
| 47 | { | ||
| 48 | } | ||
| 49 | static inline int ieee80211_qdisc_installed(struct net_device *dev) | ||
| 50 | { | ||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | static inline int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | ||
| 54 | struct sta_info *sta, u16 tid) | ||
| 55 | { | ||
| 56 | return -EAGAIN; | ||
| 57 | } | ||
| 58 | static inline void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | ||
| 59 | struct sta_info *sta, u16 tid, | ||
| 60 | u8 requeue) | ||
| 61 | { | ||
| 62 | } | ||
| 63 | static inline void ieee80211_requeue(struct ieee80211_local *local, int queue) | ||
| 64 | { | ||
| 65 | } | ||
| 66 | static inline int ieee80211_wme_register(void) | ||
| 67 | { | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | static inline void ieee80211_wme_unregister(void) | ||
| 71 | { | ||
| 72 | } | ||
| 73 | #endif /* CONFIG_NET_SCHED */ | ||
| 74 | 33 | ||
| 75 | #endif /* _WME_H */ | 34 | #endif /* _WME_H */ |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 45709ada8fee..2f33df0dcccf 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
| @@ -11,6 +11,8 @@ | |||
| 11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
| 12 | #include <linux/skbuff.h> | 12 | #include <linux/skbuff.h> |
| 13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
| 14 | #include <linux/ieee80211.h> | ||
| 15 | #include <asm/unaligned.h> | ||
| 14 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
| 15 | 17 | ||
| 16 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
| @@ -19,76 +21,30 @@ | |||
| 19 | #include "aes_ccm.h" | 21 | #include "aes_ccm.h" |
| 20 | #include "wpa.h" | 22 | #include "wpa.h" |
| 21 | 23 | ||
| 22 | static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | ||
| 23 | u8 *qos_tid, u8 **data, size_t *data_len) | ||
| 24 | { | ||
| 25 | struct ieee80211_hdr *hdr; | ||
| 26 | size_t hdrlen; | ||
| 27 | u16 fc; | ||
| 28 | int a4_included; | ||
| 29 | u8 *pos; | ||
| 30 | |||
| 31 | hdr = (struct ieee80211_hdr *) skb->data; | ||
| 32 | fc = le16_to_cpu(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 | |||
| 51 | if (fc & 0x80) | ||
| 52 | hdrlen += 2; | ||
| 53 | |||
| 54 | *data = skb->data + hdrlen; | ||
| 55 | *data_len = skb->len - hdrlen; | ||
| 56 | |||
| 57 | a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | ||
| 58 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
| 59 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | ||
| 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; | ||
| 68 | |||
| 69 | return skb->len < hdrlen ? -1 : 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | ieee80211_tx_result | 24 | ieee80211_tx_result |
| 74 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | 25 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) |
| 75 | { | 26 | { |
| 76 | u8 *data, *sa, *da, *key, *mic, qos_tid; | 27 | u8 *data, *key, *mic, key_offset; |
| 77 | size_t data_len; | 28 | size_t data_len; |
| 78 | u16 fc; | 29 | unsigned int hdrlen; |
| 30 | struct ieee80211_hdr *hdr; | ||
| 79 | struct sk_buff *skb = tx->skb; | 31 | struct sk_buff *skb = tx->skb; |
| 80 | int authenticator; | 32 | int authenticator; |
| 81 | int wpa_test = 0; | 33 | int wpa_test = 0; |
| 34 | int tail; | ||
| 82 | 35 | ||
| 83 | fc = tx->fc; | 36 | hdr = (struct ieee80211_hdr *)skb->data; |
| 84 | |||
| 85 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || | 37 | if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || |
| 86 | !WLAN_FC_DATA_PRESENT(fc)) | 38 | !ieee80211_is_data_present(hdr->frame_control)) |
| 87 | return TX_CONTINUE; | 39 | return TX_CONTINUE; |
| 88 | 40 | ||
| 89 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) | 41 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 42 | if (skb->len < hdrlen) | ||
| 90 | return TX_DROP; | 43 | return TX_DROP; |
| 91 | 44 | ||
| 45 | data = skb->data + hdrlen; | ||
| 46 | data_len = skb->len - hdrlen; | ||
| 47 | |||
| 92 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 48 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
| 93 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && | 49 | !(tx->flags & IEEE80211_TX_FRAGMENTED) && |
| 94 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && | 50 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) && |
| @@ -98,26 +54,27 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
| 98 | return TX_CONTINUE; | 54 | return TX_CONTINUE; |
| 99 | } | 55 | } |
| 100 | 56 | ||
| 101 | if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { | 57 | tail = MICHAEL_MIC_LEN; |
| 102 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 58 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
| 103 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, | 59 | tail += TKIP_ICV_LEN; |
| 104 | MICHAEL_MIC_LEN + TKIP_ICV_LEN, | 60 | |
| 105 | GFP_ATOMIC))) { | 61 | if (WARN_ON(skb_tailroom(skb) < tail || |
| 106 | printk(KERN_DEBUG "%s: failed to allocate more memory " | 62 | skb_headroom(skb) < TKIP_IV_LEN)) |
| 107 | "for Michael MIC\n", tx->dev->name); | 63 | return TX_DROP; |
| 108 | return TX_DROP; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | 64 | ||
| 112 | #if 0 | 65 | #if 0 |
| 113 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ | 66 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ |
| 114 | #else | 67 | #else |
| 115 | authenticator = 1; | 68 | authenticator = 1; |
| 116 | #endif | 69 | #endif |
| 117 | key = &tx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY : | 70 | /* At this point we know we're using ALG_TKIP. To get the MIC key |
| 118 | ALG_TKIP_TEMP_AUTH_RX_MIC_KEY]; | 71 | * we now will rely on the offset from the ieee80211_key_conf::key */ |
| 72 | key_offset = authenticator ? | ||
| 73 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY : | ||
| 74 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | ||
| 75 | key = &tx->key->conf.key[key_offset]; | ||
| 119 | mic = skb_put(skb, MICHAEL_MIC_LEN); | 76 | mic = skb_put(skb, MICHAEL_MIC_LEN); |
| 120 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 77 | michael_mic(key, hdr, data, data_len, mic); |
| 121 | 78 | ||
| 122 | return TX_CONTINUE; | 79 | return TX_CONTINUE; |
| 123 | } | 80 | } |
| @@ -126,47 +83,50 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
| 126 | ieee80211_rx_result | 83 | ieee80211_rx_result |
| 127 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | 84 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) |
| 128 | { | 85 | { |
| 129 | u8 *data, *sa, *da, *key = NULL, qos_tid; | 86 | u8 *data, *key = NULL, key_offset; |
| 130 | size_t data_len; | 87 | size_t data_len; |
| 131 | u16 fc; | 88 | unsigned int hdrlen; |
| 89 | struct ieee80211_hdr *hdr; | ||
| 132 | u8 mic[MICHAEL_MIC_LEN]; | 90 | u8 mic[MICHAEL_MIC_LEN]; |
| 133 | struct sk_buff *skb = rx->skb; | 91 | struct sk_buff *skb = rx->skb; |
| 134 | int authenticator = 1, wpa_test = 0; | 92 | int authenticator = 1, wpa_test = 0; |
| 135 | DECLARE_MAC_BUF(mac); | 93 | DECLARE_MAC_BUF(mac); |
| 136 | 94 | ||
| 137 | fc = rx->fc; | ||
| 138 | |||
| 139 | /* | 95 | /* |
| 140 | * No way to verify the MIC if the hardware stripped it | 96 | * No way to verify the MIC if the hardware stripped it |
| 141 | */ | 97 | */ |
| 142 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) | 98 | if (rx->status->flag & RX_FLAG_MMIC_STRIPPED) |
| 143 | return RX_CONTINUE; | 99 | return RX_CONTINUE; |
| 144 | 100 | ||
| 101 | hdr = (struct ieee80211_hdr *)skb->data; | ||
| 145 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || | 102 | if (!rx->key || rx->key->conf.alg != ALG_TKIP || |
| 146 | !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) | 103 | !ieee80211_has_protected(hdr->frame_control) || |
| 104 | !ieee80211_is_data_present(hdr->frame_control)) | ||
| 147 | return RX_CONTINUE; | 105 | return RX_CONTINUE; |
| 148 | 106 | ||
| 149 | if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) | 107 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 150 | || data_len < MICHAEL_MIC_LEN) | 108 | if (skb->len < hdrlen + MICHAEL_MIC_LEN) |
| 151 | return RX_DROP_UNUSABLE; | 109 | return RX_DROP_UNUSABLE; |
| 152 | 110 | ||
| 153 | data_len -= MICHAEL_MIC_LEN; | 111 | data = skb->data + hdrlen; |
| 112 | data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; | ||
| 154 | 113 | ||
| 155 | #if 0 | 114 | #if 0 |
| 156 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ | 115 | authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ |
| 157 | #else | 116 | #else |
| 158 | authenticator = 1; | 117 | authenticator = 1; |
| 159 | #endif | 118 | #endif |
| 160 | key = &rx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY : | 119 | /* At this point we know we're using ALG_TKIP. To get the MIC key |
| 161 | ALG_TKIP_TEMP_AUTH_TX_MIC_KEY]; | 120 | * we now will rely on the offset from the ieee80211_key_conf::key */ |
| 162 | michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); | 121 | key_offset = authenticator ? |
| 122 | NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : | ||
| 123 | NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | ||
| 124 | key = &rx->key->conf.key[key_offset]; | ||
| 125 | michael_mic(key, hdr, data, data_len, mic); | ||
| 163 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 126 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
| 164 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 127 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
| 165 | return RX_DROP_UNUSABLE; | 128 | return RX_DROP_UNUSABLE; |
| 166 | 129 | ||
| 167 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " | ||
| 168 | "%s\n", rx->dev->name, print_mac(mac, sa)); | ||
| 169 | |||
| 170 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, | 130 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, |
| 171 | (void *) skb->data); | 131 | (void *) skb->data); |
| 172 | return RX_DROP_UNUSABLE; | 132 | return RX_DROP_UNUSABLE; |
| @@ -176,59 +136,58 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
| 176 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 136 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
| 177 | 137 | ||
| 178 | /* update IV in key information to be able to detect replays */ | 138 | /* update IV in key information to be able to detect replays */ |
| 179 | rx->key->u.tkip.iv32_rx[rx->queue] = rx->tkip_iv32; | 139 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; |
| 180 | rx->key->u.tkip.iv16_rx[rx->queue] = rx->tkip_iv16; | 140 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; |
| 181 | 141 | ||
| 182 | return RX_CONTINUE; | 142 | return RX_CONTINUE; |
| 183 | } | 143 | } |
| 184 | 144 | ||
| 185 | 145 | ||
| 186 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, | 146 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
| 187 | struct sk_buff *skb, int test) | ||
| 188 | { | 147 | { |
| 189 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 148 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 190 | struct ieee80211_key *key = tx->key; | 149 | struct ieee80211_key *key = tx->key; |
| 191 | int hdrlen, len, tailneed; | 150 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 192 | u16 fc; | 151 | unsigned int hdrlen; |
| 152 | int len, tail; | ||
| 193 | u8 *pos; | 153 | u8 *pos; |
| 194 | 154 | ||
| 195 | fc = le16_to_cpu(hdr->frame_control); | 155 | info->control.icv_len = TKIP_ICV_LEN; |
| 196 | hdrlen = ieee80211_get_hdrlen(fc); | 156 | info->control.iv_len = TKIP_IV_LEN; |
| 157 | |||
| 158 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | ||
| 159 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
| 160 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
| 161 | info->control.hw_key = &tx->key->conf; | ||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 165 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
| 197 | len = skb->len - hdrlen; | 166 | len = skb->len - hdrlen; |
| 198 | 167 | ||
| 199 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 168 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
| 200 | tailneed = 0; | 169 | tail = 0; |
| 201 | else | 170 | else |
| 202 | tailneed = TKIP_ICV_LEN; | 171 | tail = TKIP_ICV_LEN; |
| 203 | 172 | ||
| 204 | if ((skb_headroom(skb) < TKIP_IV_LEN || | 173 | if (WARN_ON(skb_tailroom(skb) < tail || |
| 205 | skb_tailroom(skb) < tailneed)) { | 174 | skb_headroom(skb) < TKIP_IV_LEN)) |
| 206 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 175 | return -1; |
| 207 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed, | ||
| 208 | GFP_ATOMIC))) | ||
| 209 | return -1; | ||
| 210 | } | ||
| 211 | 176 | ||
| 212 | pos = skb_push(skb, TKIP_IV_LEN); | 177 | pos = skb_push(skb, TKIP_IV_LEN); |
| 213 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); | 178 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); |
| 214 | pos += hdrlen; | 179 | pos += hdrlen; |
| 215 | 180 | ||
| 216 | /* Increase IV for the frame */ | 181 | /* Increase IV for the frame */ |
| 217 | key->u.tkip.iv16++; | 182 | key->u.tkip.tx.iv16++; |
| 218 | if (key->u.tkip.iv16 == 0) | 183 | if (key->u.tkip.tx.iv16 == 0) |
| 219 | key->u.tkip.iv32++; | 184 | key->u.tkip.tx.iv32++; |
| 220 | 185 | ||
| 221 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 186 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
| 222 | hdr = (struct ieee80211_hdr *)skb->data; | ||
| 223 | |||
| 224 | /* hwaccel - with preallocated room for IV */ | 187 | /* hwaccel - with preallocated room for IV */ |
| 225 | ieee80211_tkip_add_iv(pos, key, | 188 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
| 226 | (u8) (key->u.tkip.iv16 >> 8), | ||
| 227 | (u8) (((key->u.tkip.iv16 >> 8) | 0x20) & | ||
| 228 | 0x7f), | ||
| 229 | (u8) key->u.tkip.iv16); | ||
| 230 | 189 | ||
| 231 | tx->control->key_idx = tx->key->conf.hw_key_idx; | 190 | info->control.hw_key = &tx->key->conf; |
| 232 | return 0; | 191 | return 0; |
| 233 | } | 192 | } |
| 234 | 193 | ||
| @@ -246,28 +205,16 @@ ieee80211_tx_result | |||
| 246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | 205 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) |
| 247 | { | 206 | { |
| 248 | struct sk_buff *skb = tx->skb; | 207 | struct sk_buff *skb = tx->skb; |
| 249 | int wpa_test = 0, test = 0; | ||
| 250 | 208 | ||
| 251 | tx->control->icv_len = TKIP_ICV_LEN; | ||
| 252 | tx->control->iv_len = TKIP_IV_LEN; | ||
| 253 | ieee80211_tx_set_protected(tx); | 209 | ieee80211_tx_set_protected(tx); |
| 254 | 210 | ||
| 255 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 211 | if (tkip_encrypt_skb(tx, skb) < 0) |
| 256 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | ||
| 257 | !wpa_test) { | ||
| 258 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
| 259 | tx->control->key_idx = tx->key->conf.hw_key_idx; | ||
| 260 | return TX_CONTINUE; | ||
| 261 | } | ||
| 262 | |||
| 263 | if (tkip_encrypt_skb(tx, skb, test) < 0) | ||
| 264 | return TX_DROP; | 212 | return TX_DROP; |
| 265 | 213 | ||
| 266 | if (tx->extra_frag) { | 214 | if (tx->extra_frag) { |
| 267 | int i; | 215 | int i; |
| 268 | for (i = 0; i < tx->num_extra_frag; i++) { | 216 | for (i = 0; i < tx->num_extra_frag; i++) { |
| 269 | if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) | 217 | if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
| 270 | < 0) | ||
| 271 | return TX_DROP; | 218 | return TX_DROP; |
| 272 | } | 219 | } |
| 273 | } | 220 | } |
| @@ -280,16 +227,14 @@ ieee80211_rx_result | |||
| 280 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | 227 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) |
| 281 | { | 228 | { |
| 282 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 229 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
| 283 | u16 fc; | ||
| 284 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 230 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
| 285 | struct ieee80211_key *key = rx->key; | 231 | struct ieee80211_key *key = rx->key; |
| 286 | struct sk_buff *skb = rx->skb; | 232 | struct sk_buff *skb = rx->skb; |
| 287 | DECLARE_MAC_BUF(mac); | 233 | DECLARE_MAC_BUF(mac); |
| 288 | 234 | ||
| 289 | fc = le16_to_cpu(hdr->frame_control); | 235 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 290 | hdrlen = ieee80211_get_hdrlen(fc); | ||
| 291 | 236 | ||
| 292 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 237 | if (!ieee80211_is_data(hdr->frame_control)) |
| 293 | return RX_CONTINUE; | 238 | return RX_CONTINUE; |
| 294 | 239 | ||
| 295 | if (!rx->sta || skb->len - hdrlen < 12) | 240 | if (!rx->sta || skb->len - hdrlen < 12) |
| @@ -315,15 +260,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
| 315 | hdr->addr1, hwaccel, rx->queue, | 260 | hdr->addr1, hwaccel, rx->queue, |
| 316 | &rx->tkip_iv32, | 261 | &rx->tkip_iv32, |
| 317 | &rx->tkip_iv16); | 262 | &rx->tkip_iv16); |
| 318 | if (res != TKIP_DECRYPT_OK || wpa_test) { | 263 | if (res != TKIP_DECRYPT_OK || wpa_test) |
| 319 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 320 | if (net_ratelimit()) | ||
| 321 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX " | ||
| 322 | "frame from %s (res=%d)\n", rx->dev->name, | ||
| 323 | print_mac(mac, rx->sta->addr), res); | ||
| 324 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 325 | return RX_DROP_UNUSABLE; | 264 | return RX_DROP_UNUSABLE; |
| 326 | } | ||
| 327 | 265 | ||
| 328 | /* Trim ICV */ | 266 | /* Trim ICV */ |
| 329 | skb_trim(skb, skb->len - TKIP_ICV_LEN); | 267 | skb_trim(skb, skb->len - TKIP_ICV_LEN); |
| @@ -336,70 +274,68 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
| 336 | } | 274 | } |
| 337 | 275 | ||
| 338 | 276 | ||
| 339 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, | 277 | static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, |
| 340 | int encrypted) | 278 | int encrypted) |
| 341 | { | 279 | { |
| 342 | u16 fc; | 280 | __le16 mask_fc; |
| 343 | int a4_included, qos_included; | 281 | int a4_included; |
| 344 | u8 qos_tid, *fc_pos, *data, *sa, *da; | 282 | u8 qos_tid; |
| 345 | int len_a; | 283 | u8 *b_0, *aad; |
| 346 | size_t data_len; | 284 | u16 data_len, len_a; |
| 347 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 285 | unsigned int hdrlen; |
| 286 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
| 348 | 287 | ||
| 349 | fc_pos = (u8 *) &hdr->frame_control; | 288 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
| 350 | fc = fc_pos[0] ^ (fc_pos[1] << 8); | 289 | aad = scratch + 4 * AES_BLOCK_LEN; |
| 351 | a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 290 | |
| 352 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 291 | /* |
| 353 | 292 | * Mask FC: zero subtype b4 b5 b6 | |
| 354 | ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len); | 293 | * Retry, PwrMgt, MoreData; set Protected |
| 355 | data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0); | 294 | */ |
| 356 | if (qos_tid & 0x80) { | 295 | mask_fc = hdr->frame_control; |
| 357 | qos_included = 1; | 296 | mask_fc &= ~cpu_to_le16(0x0070 | IEEE80211_FCTL_RETRY | |
| 358 | qos_tid &= 0x0f; | 297 | IEEE80211_FCTL_PM | IEEE80211_FCTL_MOREDATA); |
| 359 | } else | 298 | mask_fc |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
| 360 | qos_included = 0; | 299 | |
| 361 | /* First block, b_0 */ | 300 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 301 | len_a = hdrlen - 2; | ||
| 302 | a4_included = ieee80211_has_a4(hdr->frame_control); | ||
| 303 | |||
| 304 | if (ieee80211_is_data_qos(hdr->frame_control)) | ||
| 305 | qos_tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; | ||
| 306 | else | ||
| 307 | qos_tid = 0; | ||
| 308 | |||
| 309 | data_len = skb->len - hdrlen - CCMP_HDR_LEN; | ||
| 310 | if (encrypted) | ||
| 311 | data_len -= CCMP_MIC_LEN; | ||
| 362 | 312 | ||
| 313 | /* First block, b_0 */ | ||
| 363 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ | 314 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ |
| 364 | /* Nonce: QoS Priority | A2 | PN */ | 315 | /* Nonce: QoS Priority | A2 | PN */ |
| 365 | b_0[1] = qos_tid; | 316 | b_0[1] = qos_tid; |
| 366 | memcpy(&b_0[2], hdr->addr2, 6); | 317 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
| 367 | memcpy(&b_0[8], pn, CCMP_PN_LEN); | 318 | memcpy(&b_0[8], pn, CCMP_PN_LEN); |
| 368 | /* l(m) */ | 319 | /* l(m) */ |
| 369 | b_0[14] = (data_len >> 8) & 0xff; | 320 | put_unaligned_be16(data_len, &b_0[14]); |
| 370 | b_0[15] = data_len & 0xff; | ||
| 371 | |||
| 372 | 321 | ||
| 373 | /* AAD (extra authenticate-only data) / masked 802.11 header | 322 | /* AAD (extra authenticate-only data) / masked 802.11 header |
| 374 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ | 323 | * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ |
| 375 | 324 | put_unaligned_be16(len_a, &aad[0]); | |
| 376 | len_a = a4_included ? 28 : 22; | 325 | put_unaligned(mask_fc, (__le16 *)&aad[2]); |
| 377 | if (qos_included) | 326 | memcpy(&aad[4], &hdr->addr1, 3 * ETH_ALEN); |
| 378 | len_a += 2; | ||
| 379 | |||
| 380 | aad[0] = 0; /* (len_a >> 8) & 0xff; */ | ||
| 381 | aad[1] = len_a & 0xff; | ||
| 382 | /* Mask FC: zero subtype b4 b5 b6 */ | ||
| 383 | aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6)); | ||
| 384 | /* Retry, PwrMgt, MoreData; set Protected */ | ||
| 385 | aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6); | ||
| 386 | memcpy(&aad[4], &hdr->addr1, 18); | ||
| 387 | 327 | ||
| 388 | /* Mask Seq#, leave Frag# */ | 328 | /* Mask Seq#, leave Frag# */ |
| 389 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; | 329 | aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; |
| 390 | aad[23] = 0; | 330 | aad[23] = 0; |
| 331 | |||
| 391 | if (a4_included) { | 332 | if (a4_included) { |
| 392 | memcpy(&aad[24], hdr->addr4, 6); | 333 | memcpy(&aad[24], hdr->addr4, ETH_ALEN); |
| 393 | aad[30] = 0; | 334 | aad[30] = qos_tid; |
| 394 | aad[31] = 0; | 335 | aad[31] = 0; |
| 395 | } else | 336 | } else { |
| 396 | memset(&aad[24], 0, 8); | 337 | memset(&aad[24], 0, ETH_ALEN + IEEE80211_QOS_CTL_LEN); |
| 397 | if (qos_included) { | 338 | aad[24] = qos_tid; |
| 398 | u8 *dpos = &aad[a4_included ? 30 : 24]; | ||
| 399 | |||
| 400 | /* Mask QoS Control field */ | ||
| 401 | dpos[0] = qos_tid; | ||
| 402 | dpos[1] = 0; | ||
| 403 | } | 339 | } |
| 404 | } | 340 | } |
| 405 | 341 | ||
| @@ -429,36 +365,37 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) | |||
| 429 | } | 365 | } |
| 430 | 366 | ||
| 431 | 367 | ||
| 432 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | 368 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
| 433 | struct sk_buff *skb, int test) | ||
| 434 | { | 369 | { |
| 435 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 370 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 436 | struct ieee80211_key *key = tx->key; | 371 | struct ieee80211_key *key = tx->key; |
| 437 | int hdrlen, len, tailneed; | 372 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 438 | u16 fc; | 373 | int hdrlen, len, tail; |
| 439 | u8 *pos, *pn, *b_0, *aad, *scratch; | 374 | u8 *pos, *pn; |
| 440 | int i; | 375 | int i; |
| 441 | 376 | ||
| 442 | scratch = key->u.ccmp.tx_crypto_buf; | 377 | info->control.icv_len = CCMP_MIC_LEN; |
| 443 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 378 | info->control.iv_len = CCMP_HDR_LEN; |
| 444 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
| 445 | 379 | ||
| 446 | fc = le16_to_cpu(hdr->frame_control); | 380 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && |
| 447 | hdrlen = ieee80211_get_hdrlen(fc); | 381 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
| 382 | /* hwaccel - with no need for preallocated room for CCMP " | ||
| 383 | * header or MIC fields */ | ||
| 384 | info->control.hw_key = &tx->key->conf; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
| 448 | len = skb->len - hdrlen; | 389 | len = skb->len - hdrlen; |
| 449 | 390 | ||
| 450 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 391 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
| 451 | tailneed = 0; | 392 | tail = 0; |
| 452 | else | 393 | else |
| 453 | tailneed = CCMP_MIC_LEN; | 394 | tail = CCMP_MIC_LEN; |
| 454 | 395 | ||
| 455 | if ((skb_headroom(skb) < CCMP_HDR_LEN || | 396 | if (WARN_ON(skb_tailroom(skb) < tail || |
| 456 | skb_tailroom(skb) < tailneed)) { | 397 | skb_headroom(skb) < CCMP_HDR_LEN)) |
| 457 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 398 | return -1; |
| 458 | if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed, | ||
| 459 | GFP_ATOMIC))) | ||
| 460 | return -1; | ||
| 461 | } | ||
| 462 | 399 | ||
| 463 | pos = skb_push(skb, CCMP_HDR_LEN); | 400 | pos = skb_push(skb, CCMP_HDR_LEN); |
| 464 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 401 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |
| @@ -478,13 +415,13 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | |||
| 478 | 415 | ||
| 479 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 416 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
| 480 | /* hwaccel - with preallocated room for CCMP header */ | 417 | /* hwaccel - with preallocated room for CCMP header */ |
| 481 | tx->control->key_idx = key->conf.hw_key_idx; | 418 | info->control.hw_key = &tx->key->conf; |
| 482 | return 0; | 419 | return 0; |
| 483 | } | 420 | } |
| 484 | 421 | ||
| 485 | pos += CCMP_HDR_LEN; | 422 | pos += CCMP_HDR_LEN; |
| 486 | ccmp_special_blocks(skb, pn, b_0, aad, 0); | 423 | ccmp_special_blocks(skb, pn, key->u.ccmp.tx_crypto_buf, 0); |
| 487 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, b_0, aad, pos, len, | 424 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, key->u.ccmp.tx_crypto_buf, pos, len, |
| 488 | pos, skb_put(skb, CCMP_MIC_LEN)); | 425 | pos, skb_put(skb, CCMP_MIC_LEN)); |
| 489 | 426 | ||
| 490 | return 0; | 427 | return 0; |
| @@ -495,28 +432,16 @@ ieee80211_tx_result | |||
| 495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 432 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) |
| 496 | { | 433 | { |
| 497 | struct sk_buff *skb = tx->skb; | 434 | struct sk_buff *skb = tx->skb; |
| 498 | int test = 0; | ||
| 499 | 435 | ||
| 500 | tx->control->icv_len = CCMP_MIC_LEN; | ||
| 501 | tx->control->iv_len = CCMP_HDR_LEN; | ||
| 502 | ieee80211_tx_set_protected(tx); | 436 | ieee80211_tx_set_protected(tx); |
| 503 | 437 | ||
| 504 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 438 | if (ccmp_encrypt_skb(tx, skb) < 0) |
| 505 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
| 506 | /* hwaccel - with no need for preallocated room for CCMP " | ||
| 507 | * header or MIC fields */ | ||
| 508 | tx->control->key_idx = tx->key->conf.hw_key_idx; | ||
| 509 | return TX_CONTINUE; | ||
| 510 | } | ||
| 511 | |||
| 512 | if (ccmp_encrypt_skb(tx, skb, test) < 0) | ||
| 513 | return TX_DROP; | 439 | return TX_DROP; |
| 514 | 440 | ||
| 515 | if (tx->extra_frag) { | 441 | if (tx->extra_frag) { |
| 516 | int i; | 442 | int i; |
| 517 | for (i = 0; i < tx->num_extra_frag; i++) { | 443 | for (i = 0; i < tx->num_extra_frag; i++) { |
| 518 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test) | 444 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
| 519 | < 0) | ||
| 520 | return TX_DROP; | 445 | return TX_DROP; |
| 521 | } | 446 | } |
| 522 | } | 447 | } |
| @@ -528,8 +453,7 @@ ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | |||
| 528 | ieee80211_rx_result | 453 | ieee80211_rx_result |
| 529 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | 454 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) |
| 530 | { | 455 | { |
| 531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 456 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
| 532 | u16 fc; | ||
| 533 | int hdrlen; | 457 | int hdrlen; |
| 534 | struct ieee80211_key *key = rx->key; | 458 | struct ieee80211_key *key = rx->key; |
| 535 | struct sk_buff *skb = rx->skb; | 459 | struct sk_buff *skb = rx->skb; |
| @@ -537,10 +461,9 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
| 537 | int data_len; | 461 | int data_len; |
| 538 | DECLARE_MAC_BUF(mac); | 462 | DECLARE_MAC_BUF(mac); |
| 539 | 463 | ||
| 540 | fc = le16_to_cpu(hdr->frame_control); | 464 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 541 | hdrlen = ieee80211_get_hdrlen(fc); | ||
| 542 | 465 | ||
| 543 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 466 | if (!ieee80211_is_data(hdr->frame_control)) |
| 544 | return RX_CONTINUE; | 467 | return RX_CONTINUE; |
| 545 | 468 | ||
| 546 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; | 469 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; |
| @@ -554,41 +477,19 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
| 554 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 477 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); |
| 555 | 478 | ||
| 556 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { | 479 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { |
| 557 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 558 | u8 *ppn = key->u.ccmp.rx_pn[rx->queue]; | ||
| 559 | |||
| 560 | printk(KERN_DEBUG "%s: CCMP replay detected for RX frame from " | ||
| 561 | "%s (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " | ||
| 562 | "%02x%02x%02x%02x%02x%02x)\n", rx->dev->name, | ||
| 563 | print_mac(mac, rx->sta->addr), | ||
| 564 | pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], | ||
| 565 | ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); | ||
| 566 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 567 | key->u.ccmp.replays++; | 480 | key->u.ccmp.replays++; |
| 568 | return RX_DROP_UNUSABLE; | 481 | return RX_DROP_UNUSABLE; |
| 569 | } | 482 | } |
| 570 | 483 | ||
| 571 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 484 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { |
| 572 | /* hardware didn't decrypt/verify MIC */ | 485 | /* hardware didn't decrypt/verify MIC */ |
| 573 | u8 *scratch, *b_0, *aad; | 486 | ccmp_special_blocks(skb, pn, key->u.ccmp.rx_crypto_buf, 1); |
| 574 | |||
| 575 | scratch = key->u.ccmp.rx_crypto_buf; | ||
| 576 | b_0 = scratch + 3 * AES_BLOCK_LEN; | ||
| 577 | aad = scratch + 4 * AES_BLOCK_LEN; | ||
| 578 | |||
| 579 | ccmp_special_blocks(skb, pn, b_0, aad, 1); | ||
| 580 | 487 | ||
| 581 | if (ieee80211_aes_ccm_decrypt( | 488 | if (ieee80211_aes_ccm_decrypt( |
| 582 | key->u.ccmp.tfm, scratch, b_0, aad, | 489 | key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf, |
| 583 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 490 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
| 584 | skb->data + skb->len - CCMP_MIC_LEN, | 491 | skb->data + skb->len - CCMP_MIC_LEN, |
| 585 | skb->data + hdrlen + CCMP_HDR_LEN)) { | 492 | skb->data + hdrlen + CCMP_HDR_LEN)) { |
| 586 | #ifdef CONFIG_MAC80211_DEBUG | ||
| 587 | if (net_ratelimit()) | ||
| 588 | printk(KERN_DEBUG "%s: CCMP decrypt failed " | ||
| 589 | "for RX frame from %s\n", rx->dev->name, | ||
| 590 | print_mac(mac, rx->sta->addr)); | ||
| 591 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
| 592 | return RX_DROP_UNUSABLE; | 493 | return RX_DROP_UNUSABLE; |
| 593 | } | 494 | } |
| 594 | } | 495 | } |
