aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c4
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c2
-rw-r--r--drivers/net/wireless/wl12xx/main.c18
-rw-r--r--drivers/net/wireless/wl12xx/tx.c22
-rw-r--r--drivers/net/wireless/wl12xx/tx.h2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h14
6 files changed, 47 insertions, 15 deletions
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index c9a1fa523274..a712a0f7b370 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -400,10 +400,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
400 400
401 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; 401 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
402 402
403 /* reset TX security counters */
404 wl->tx_security_last_seq = 0;
405 wl->tx_security_seq = 0;
406
407 wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x", 403 wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
408 join->basic_rate_set, join->supported_rate_set); 404 join->basic_rate_set, join->supported_rate_set);
409 405
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index da2127018300..3f6314143ef8 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -349,7 +349,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
349 DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]); 349 DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
350 DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]); 350 DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
351 DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]); 351 DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
352 DRIVER_STATE_PRINT_INT(tx_security_last_seq); 352 DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb);
353 DRIVER_STATE_PRINT_INT(rx_counter); 353 DRIVER_STATE_PRINT_INT(rx_counter);
354 DRIVER_STATE_PRINT_INT(session_counter); 354 DRIVER_STATE_PRINT_INT(session_counter);
355 DRIVER_STATE_PRINT_INT(state); 355 DRIVER_STATE_PRINT_INT(state);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index a3734bdf5119..b896f5956d9e 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1227,6 +1227,15 @@ static void wl1271_recovery_work(struct work_struct *work)
1227 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x", 1227 wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
1228 wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4)); 1228 wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
1229 1229
1230 /*
1231 * Advance security sequence number to overcome potential progress
1232 * in the firmware during recovery. This doens't hurt if the network is
1233 * not encrypted.
1234 */
1235 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
1236 test_bit(WL1271_FLAG_AP_STARTED, &wl->flags))
1237 wl->tx_security_seq += WL1271_TX_SQN_POST_RECOVERY_PADDING;
1238
1230 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) 1239 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
1231 ieee80211_connection_loss(wl->vif); 1240 ieee80211_connection_loss(wl->vif);
1232 1241
@@ -1980,8 +1989,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
1980 wl->tx_allocated_blocks = 0; 1989 wl->tx_allocated_blocks = 0;
1981 wl->tx_results_count = 0; 1990 wl->tx_results_count = 0;
1982 wl->tx_packets_count = 0; 1991 wl->tx_packets_count = 0;
1983 wl->tx_security_last_seq = 0;
1984 wl->tx_security_seq = 0;
1985 wl->time_offset = 0; 1992 wl->time_offset = 0;
1986 wl->session_counter = 0; 1993 wl->session_counter = 0;
1987 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1994 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
@@ -2154,6 +2161,10 @@ static int wl1271_unjoin(struct wl1271 *wl)
2154 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 2161 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
2155 memset(wl->bssid, 0, ETH_ALEN); 2162 memset(wl->bssid, 0, ETH_ALEN);
2156 2163
2164 /* reset TX security counters on a clean disconnect */
2165 wl->tx_security_last_seq_lsb = 0;
2166 wl->tx_security_seq = 0;
2167
2157 /* stop filtering packets based on bssid */ 2168 /* stop filtering packets based on bssid */
2158 wl1271_configure_filters(wl, FIF_OTHER_BSS); 2169 wl1271_configure_filters(wl, FIF_OTHER_BSS);
2159 2170
@@ -4327,6 +4338,9 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4327 wl->quirks = 0; 4338 wl->quirks = 0;
4328 wl->platform_quirks = 0; 4339 wl->platform_quirks = 0;
4329 wl->sched_scanning = false; 4340 wl->sched_scanning = false;
4341 wl->tx_security_seq = 0;
4342 wl->tx_security_last_seq_lsb = 0;
4343
4330 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer, 4344 setup_timer(&wl->rx_streaming_timer, wl1271_rx_streaming_timer,
4331 (unsigned long) wl); 4345 (unsigned long) wl);
4332 wl->fwlog_size = 0; 4346 wl->fwlog_size = 0;
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 200590c0d9e3..003f9e08691b 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -704,10 +704,24 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
704 704
705 wl->stats.retry_count += result->ack_failures; 705 wl->stats.retry_count += result->ack_failures;
706 706
707 /* update security sequence number */ 707 /*
708 wl->tx_security_seq += (result->lsb_security_sequence_number - 708 * update sequence number only when relevant, i.e. only in
709 wl->tx_security_last_seq); 709 * sessions of TKIP, AES and GEM (not in open or WEP sessions)
710 wl->tx_security_last_seq = result->lsb_security_sequence_number; 710 */
711 if (info->control.hw_key &&
712 (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP ||
713 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
714 info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
715 u8 fw_lsb = result->tx_security_sequence_number_lsb;
716 u8 cur_lsb = wl->tx_security_last_seq_lsb;
717
718 /*
719 * update security sequence number, taking care of potential
720 * wrap-around
721 */
722 wl->tx_security_seq += (fw_lsb - cur_lsb + 256) % 256;
723 wl->tx_security_last_seq_lsb = fw_lsb;
724 }
711 725
712 /* remove private header from packet */ 726 /* remove private header from packet */
713 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); 727 skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index 832f9258d675..7ed3c01f3651 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -150,7 +150,7 @@ struct wl1271_tx_hw_res_descr {
150 (from 1st EDCA AIFS counter until TX Complete). */ 150 (from 1st EDCA AIFS counter until TX Complete). */
151 __le32 medium_delay; 151 __le32 medium_delay;
152 /* LS-byte of last TKIP seq-num (saved per AC for recovery). */ 152 /* LS-byte of last TKIP seq-num (saved per AC for recovery). */
153 u8 lsb_security_sequence_number; 153 u8 tx_security_sequence_number_lsb;
154 /* Retry count - number of transmissions without successful ACK.*/ 154 /* Retry count - number of transmissions without successful ACK.*/
155 u8 ack_failures; 155 u8 ack_failures;
156 /* The rate that succeeded getting ACK 156 /* The rate that succeeded getting ACK
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index d7db6e77047a..002d9c53e373 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -144,6 +144,7 @@ extern u32 wl12xx_debug_level;
144 144
145#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) 145#define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
146#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) 146#define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
147#define WL1271_TX_SQN_POST_RECOVERY_PADDING 0xff
147 148
148#define WL1271_CIPHER_SUITE_GEM 0x00147201 149#define WL1271_CIPHER_SUITE_GEM 0x00147201
149 150
@@ -454,9 +455,16 @@ struct wl1271 {
454 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; 455 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
455 int tx_frames_cnt; 456 int tx_frames_cnt;
456 457
457 /* Security sequence number counters */ 458 /*
458 u8 tx_security_last_seq; 459 * Security sequence number
459 s64 tx_security_seq; 460 * bits 0-15: lower 16 bits part of sequence number
461 * bits 16-47: higher 32 bits part of sequence number
462 * bits 48-63: not in use
463 */
464 u64 tx_security_seq;
465
466 /* 8 bits of the last sequence number in use */
467 u8 tx_security_last_seq_lsb;
460 468
461 /* FW Rx counter */ 469 /* FW Rx counter */
462 u32 rx_counter; 470 u32 rx_counter;