aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-10-10 04:12:58 -0400
committerLuciano Coelho <coelho@ti.com>2011-10-11 08:04:23 -0400
commit48e93e402ad19f570bae323b07911bdf6562af8e (patch)
treee472d28864aede3c878886941b338bdb64947a54 /drivers
parent4b730b6a814fe52425d90ff3db3d8deefb22fb24 (diff)
wl12xx: move tx_security_seq into wlvif
The last security seq num has to be saved across reconfigs. Add a new "persistent" struct into wlvif, which won't get deleted on wl12xx_init_vif_data() Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c1
-rw-r--r--drivers/net/wireless/wl12xx/main.c32
-rw-r--r--drivers/net/wireless/wl12xx/tx.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h30
4 files changed, 45 insertions, 30 deletions
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index bbc8004edf40..669b081848e8 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -346,7 +346,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
346 DRIVER_STATE_PRINT_INT(tx_results_count); 346 DRIVER_STATE_PRINT_INT(tx_results_count);
347 DRIVER_STATE_PRINT_LHEX(flags); 347 DRIVER_STATE_PRINT_LHEX(flags);
348 DRIVER_STATE_PRINT_INT(tx_blocks_freed); 348 DRIVER_STATE_PRINT_INT(tx_blocks_freed);
349 DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb);
350 DRIVER_STATE_PRINT_INT(rx_counter); 349 DRIVER_STATE_PRINT_INT(rx_counter);
351 DRIVER_STATE_PRINT_INT(state); 350 DRIVER_STATE_PRINT_INT(state);
352 DRIVER_STATE_PRINT_INT(channel); 351 DRIVER_STATE_PRINT_INT(channel);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index b52deac368f4..8d87df53bbec 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1206,6 +1206,7 @@ static void wl1271_recovery_work(struct work_struct *work)
1206{ 1206{
1207 struct wl1271 *wl = 1207 struct wl1271 *wl =
1208 container_of(work, struct wl1271, recovery_work); 1208 container_of(work, struct wl1271, recovery_work);
1209 struct wl12xx_vif *wlvif;
1209 1210
1210 mutex_lock(&wl->mutex); 1211 mutex_lock(&wl->mutex);
1211 1212
@@ -1227,9 +1228,12 @@ static void wl1271_recovery_work(struct work_struct *work)
1227 * in the firmware during recovery. This doens't hurt if the network is 1228 * in the firmware during recovery. This doens't hurt if the network is
1228 * not encrypted. 1229 * not encrypted.
1229 */ 1230 */
1230 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) || 1231 wl12xx_for_each_wlvif(wl, wlvif) {
1231 test_bit(WL1271_FLAG_AP_STARTED, &wl->flags)) 1232 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags) ||
1232 wl->tx_security_seq += WL1271_TX_SQN_POST_RECOVERY_PADDING; 1233 test_bit(WL1271_FLAG_AP_STARTED, &wl->flags))
1234 wlvif->tx_security_seq +=
1235 WL1271_TX_SQN_POST_RECOVERY_PADDING;
1236 }
1233 1237
1234 /* Prevent spurious TX during FW restart */ 1238 /* Prevent spurious TX during FW restart */
1235 ieee80211_stop_queues(wl->hw); 1239 ieee80211_stop_queues(wl->hw);
@@ -1910,8 +1914,8 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
1910{ 1914{
1911 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 1915 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
1912 1916
1913 /* make sure wlvif is zeroed */ 1917 /* clear everything but the persistent data */
1914 memset(wlvif, 0, sizeof(*wlvif)); 1918 memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent));
1915 1919
1916 switch (ieee80211_vif_type_p2p(vif)) { 1920 switch (ieee80211_vif_type_p2p(vif)) {
1917 case NL80211_IFTYPE_P2P_CLIENT: 1921 case NL80211_IFTYPE_P2P_CLIENT:
@@ -2297,8 +2301,8 @@ static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2297 goto out; 2301 goto out;
2298 2302
2299 /* reset TX security counters on a clean disconnect */ 2303 /* reset TX security counters on a clean disconnect */
2300 wl->tx_security_last_seq_lsb = 0; 2304 wlvif->tx_security_last_seq_lsb = 0;
2301 wl->tx_security_seq = 0; 2305 wlvif->tx_security_seq = 0;
2302 2306
2303out: 2307out:
2304 return ret; 2308 return ret;
@@ -2870,20 +2874,20 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2870 key_type = KEY_TKIP; 2874 key_type = KEY_TKIP;
2871 2875
2872 key_conf->hw_key_idx = key_conf->keyidx; 2876 key_conf->hw_key_idx = key_conf->keyidx;
2873 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); 2877 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
2874 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); 2878 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
2875 break; 2879 break;
2876 case WLAN_CIPHER_SUITE_CCMP: 2880 case WLAN_CIPHER_SUITE_CCMP:
2877 key_type = KEY_AES; 2881 key_type = KEY_AES;
2878 2882
2879 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 2883 key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
2880 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); 2884 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
2881 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); 2885 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
2882 break; 2886 break;
2883 case WL1271_CIPHER_SUITE_GEM: 2887 case WL1271_CIPHER_SUITE_GEM:
2884 key_type = KEY_GEM; 2888 key_type = KEY_GEM;
2885 tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); 2889 tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
2886 tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); 2890 tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
2887 break; 2891 break;
2888 default: 2892 default:
2889 wl1271_error("Unknown key algo 0x%x", key_conf->cipher); 2893 wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
@@ -4923,8 +4927,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4923 wl->quirks = 0; 4927 wl->quirks = 0;
4924 wl->platform_quirks = 0; 4928 wl->platform_quirks = 0;
4925 wl->sched_scanning = false; 4929 wl->sched_scanning = false;
4926 wl->tx_security_seq = 0;
4927 wl->tx_security_last_seq_lsb = 0;
4928 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT; 4930 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
4929 wl->system_hlid = WL12XX_SYSTEM_HLID; 4931 wl->system_hlid = WL12XX_SYSTEM_HLID;
4930 wl->active_sta_count = 0; 4932 wl->active_sta_count = 0;
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index c7be15186c4a..8c35d37ba600 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -755,6 +755,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
755 struct wl1271_tx_hw_res_descr *result) 755 struct wl1271_tx_hw_res_descr *result)
756{ 756{
757 struct ieee80211_tx_info *info; 757 struct ieee80211_tx_info *info;
758 struct ieee80211_vif *vif;
759 struct wl12xx_vif *wlvif;
758 struct sk_buff *skb; 760 struct sk_buff *skb;
759 int id = result->id; 761 int id = result->id;
760 int rate = -1; 762 int rate = -1;
@@ -774,6 +776,10 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
774 return; 776 return;
775 } 777 }
776 778
779 /* info->control is valid as long as we don't update info->status */
780 vif = info->control.vif;
781 wlvif = wl12xx_vif_to_data(vif);
782
777 /* update the TX status info */ 783 /* update the TX status info */
778 if (result->status == TX_SUCCESS) { 784 if (result->status == TX_SUCCESS) {
779 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 785 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -801,14 +807,14 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
801 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP || 807 info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP ||
802 info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) { 808 info->control.hw_key->cipher == WL1271_CIPHER_SUITE_GEM)) {
803 u8 fw_lsb = result->tx_security_sequence_number_lsb; 809 u8 fw_lsb = result->tx_security_sequence_number_lsb;
804 u8 cur_lsb = wl->tx_security_last_seq_lsb; 810 u8 cur_lsb = wlvif->tx_security_last_seq_lsb;
805 811
806 /* 812 /*
807 * update security sequence number, taking care of potential 813 * update security sequence number, taking care of potential
808 * wrap-around 814 * wrap-around
809 */ 815 */
810 wl->tx_security_seq += (fw_lsb - cur_lsb + 256) % 256; 816 wlvif->tx_security_seq += (fw_lsb - cur_lsb) & 0xff;
811 wl->tx_security_last_seq_lsb = fw_lsb; 817 wlvif->tx_security_last_seq_lsb = fw_lsb;
812 } 818 }
813 819
814 /* remove private header from packet */ 820 /* remove private header from packet */
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index de9a2b639403..d58488598d11 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -437,17 +437,6 @@ struct wl1271 {
437 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS]; 437 struct sk_buff *tx_frames[ACX_TX_DESCRIPTORS];
438 int tx_frames_cnt; 438 int tx_frames_cnt;
439 439
440 /*
441 * Security sequence number
442 * bits 0-15: lower 16 bits part of sequence number
443 * bits 16-47: higher 32 bits part of sequence number
444 * bits 48-63: not in use
445 */
446 u64 tx_security_seq;
447
448 /* 8 bits of the last sequence number in use */
449 u8 tx_security_last_seq_lsb;
450
451 /* FW Rx counter */ 440 /* FW Rx counter */
452 u32 rx_counter; 441 u32 rx_counter;
453 442
@@ -645,6 +634,25 @@ struct wl12xx_vif {
645 /* RX BA constraint value */ 634 /* RX BA constraint value */
646 bool ba_support; 635 bool ba_support;
647 bool ba_allowed; 636 bool ba_allowed;
637
638 /*
639 * This struct must be last!
640 * data that has to be saved acrossed reconfigs (e.g. recovery)
641 * should be declared in this struct.
642 */
643 struct {
644 u8 persistent[0];
645 /*
646 * Security sequence number
647 * bits 0-15: lower 16 bits part of sequence number
648 * bits 16-47: higher 32 bits part of sequence number
649 * bits 48-63: not in use
650 */
651 u64 tx_security_seq;
652
653 /* 8 bits of the last sequence number in use */
654 u8 tx_security_last_seq_lsb;
655 };
648}; 656};
649 657
650static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif) 658static inline struct wl12xx_vif *wl12xx_vif_to_data(struct ieee80211_vif *vif)