aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c67
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c41
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c41
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c42
14 files changed, 185 insertions, 85 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 54ca49ad3472..cb28e1b2f1e2 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -305,9 +305,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
305 * Enable synchronisation. 305 * Enable synchronisation.
306 */ 306 */
307 rt2x00pci_register_read(rt2x00dev, CSR14, &reg); 307 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
308 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
309 rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync); 308 rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
310 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
311 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 309 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
312 } 310 }
313 311
@@ -1183,8 +1181,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry,
1183 /* 1181 /*
1184 * Enable beaconing again. 1182 * Enable beaconing again.
1185 */ 1183 */
1186 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1187 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1188 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1); 1184 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1189 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1185 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1190} 1186}
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index a9ff26a27724..5225ae1899fe 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -311,9 +311,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
311 * Enable synchronisation. 311 * Enable synchronisation.
312 */ 312 */
313 rt2x00pci_register_read(rt2x00dev, CSR14, &reg); 313 rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
314 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
315 rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync); 314 rt2x00_set_field32(&reg, CSR14_TSF_SYNC, conf->sync);
316 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
317 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 315 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
318 } 316 }
319 317
@@ -1337,8 +1335,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry,
1337 /* 1335 /*
1338 * Enable beaconing again. 1336 * Enable beaconing again.
1339 */ 1337 */
1340 rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 1);
1341 rt2x00_set_field32(&reg, CSR14_TBCN, 1);
1342 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1); 1338 rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 1);
1343 rt2x00pci_register_write(rt2x00dev, CSR14, reg); 1339 rt2x00pci_register_write(rt2x00dev, CSR14, reg);
1344} 1340}
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 6b3b1de46792..157516e0aab7 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -478,9 +478,7 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
478 rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); 478 rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
479 479
480 rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg); 480 rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
481 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 1);
482 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_SYNC, conf->sync); 481 rt2x00_set_field16(&reg, TXRX_CSR19_TSF_SYNC, conf->sync);
483 rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 1);
484 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); 482 rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
485 } 483 }
486 484
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index f8ba01cbc6dd..4753fb1b0aaf 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -818,8 +818,6 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
818 /* 818 /*
819 * Enable beaconing again. 819 * Enable beaconing again.
820 */ 820 */
821 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
822 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
823 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1); 821 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
824 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 822 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
825 823
@@ -831,8 +829,8 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
831} 829}
832EXPORT_SYMBOL_GPL(rt2800_write_beacon); 830EXPORT_SYMBOL_GPL(rt2800_write_beacon);
833 831
834static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, 832static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
835 unsigned int beacon_base) 833 unsigned int beacon_base)
836{ 834{
837 int i; 835 int i;
838 836
@@ -845,6 +843,33 @@ static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev,
845 rt2800_register_write(rt2x00dev, beacon_base + i, 0); 843 rt2800_register_write(rt2x00dev, beacon_base + i, 0);
846} 844}
847 845
846void rt2800_clear_beacon(struct queue_entry *entry)
847{
848 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
849 u32 reg;
850
851 /*
852 * Disable beaconing while we are reloading the beacon data,
853 * otherwise we might be sending out invalid data.
854 */
855 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
856 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
857 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
858
859 /*
860 * Clear beacon.
861 */
862 rt2800_clear_beacon_register(rt2x00dev,
863 HW_BEACON_OFFSET(entry->entry_idx));
864
865 /*
866 * Enabled beaconing again.
867 */
868 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
869 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
870}
871EXPORT_SYMBOL_GPL(rt2800_clear_beacon);
872
848#ifdef CONFIG_RT2X00_LIB_DEBUGFS 873#ifdef CONFIG_RT2X00_LIB_DEBUGFS
849const struct rt2x00debug rt2800_rt2x00debug = { 874const struct rt2x00debug rt2800_rt2x00debug = {
850 .owner = THIS_MODULE, 875 .owner = THIS_MODULE,
@@ -1155,29 +1180,11 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1155 1180
1156 if (flags & CONFIG_UPDATE_TYPE) { 1181 if (flags & CONFIG_UPDATE_TYPE) {
1157 /* 1182 /*
1158 * Clear current synchronisation setup.
1159 */
1160 rt2800_clear_beacon(rt2x00dev,
1161 HW_BEACON_OFFSET(intf->beacon->entry_idx));
1162 /*
1163 * Enable synchronisation. 1183 * Enable synchronisation.
1164 */ 1184 */
1165 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg); 1185 rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
1166 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
1167 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync); 1186 rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
1168 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE,
1169 (conf->sync == TSF_SYNC_ADHOC ||
1170 conf->sync == TSF_SYNC_AP_NONE));
1171 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 1187 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
1172
1173 /*
1174 * Enable pre tbtt interrupt for beaconing modes
1175 */
1176 rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
1177 rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER,
1178 (conf->sync == TSF_SYNC_AP_NONE));
1179 rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
1180
1181 } 1188 }
1182 1189
1183 if (flags & CONFIG_UPDATE_MAC) { 1190 if (flags & CONFIG_UPDATE_MAC) {
@@ -2187,14 +2194,14 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
2187 /* 2194 /*
2188 * Clear all beacons 2195 * Clear all beacons
2189 */ 2196 */
2190 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE0); 2197 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE0);
2191 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE1); 2198 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE1);
2192 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE2); 2199 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE2);
2193 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE3); 2200 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE3);
2194 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE4); 2201 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE4);
2195 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE5); 2202 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE5);
2196 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE6); 2203 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE6);
2197 rt2800_clear_beacon(rt2x00dev, HW_BEACON_BASE7); 2204 rt2800_clear_beacon_register(rt2x00dev, HW_BEACON_BASE7);
2198 2205
2199 if (rt2x00_is_usb(rt2x00dev)) { 2206 if (rt2x00_is_usb(rt2x00dev)) {
2200 rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg); 2207 rt2800_register_read(rt2x00dev, US_CYC_CNT, &reg);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 3efafb78ff77..0c92d86a36f4 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -156,6 +156,7 @@ void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
156void rt2800_txdone_entry(struct queue_entry *entry, u32 status); 156void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
157 157
158void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); 158void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
159void rt2800_clear_beacon(struct queue_entry *entry);
159 160
160extern const struct rt2x00debug rt2800_rt2x00debug; 161extern const struct rt2x00debug rt2800_rt2x00debug;
161 162
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index bfc2fc5c1c22..54e37e08c114 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -205,6 +205,10 @@ static void rt2800pci_start_queue(struct data_queue *queue)
205 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1); 205 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
206 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1); 206 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
207 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 207 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
208
209 rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
210 rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
211 rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
208 break; 212 break;
209 default: 213 default:
210 break; 214 break;
@@ -250,6 +254,10 @@ static void rt2800pci_stop_queue(struct data_queue *queue)
250 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0); 254 rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
251 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0); 255 rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
252 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); 256 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
257
258 rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
259 rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
260 rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
253 break; 261 break;
254 default: 262 default:
255 break; 263 break;
@@ -974,6 +982,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
974 .write_tx_desc = rt2800pci_write_tx_desc, 982 .write_tx_desc = rt2800pci_write_tx_desc,
975 .write_tx_data = rt2800_write_tx_data, 983 .write_tx_data = rt2800_write_tx_data,
976 .write_beacon = rt2800_write_beacon, 984 .write_beacon = rt2800_write_beacon,
985 .clear_beacon = rt2800_clear_beacon,
977 .fill_rxdone = rt2800pci_fill_rxdone, 986 .fill_rxdone = rt2800pci_fill_rxdone,
978 .config_shared_key = rt2800_config_shared_key, 987 .config_shared_key = rt2800_config_shared_key,
979 .config_pairwise_key = rt2800_config_pairwise_key, 988 .config_pairwise_key = rt2800_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index b97a4a54ff4c..3ebe473f8551 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -633,6 +633,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
633 .write_tx_desc = rt2800usb_write_tx_desc, 633 .write_tx_desc = rt2800usb_write_tx_desc,
634 .write_tx_data = rt2800usb_write_tx_data, 634 .write_tx_data = rt2800usb_write_tx_data,
635 .write_beacon = rt2800_write_beacon, 635 .write_beacon = rt2800_write_beacon,
636 .clear_beacon = rt2800_clear_beacon,
636 .get_tx_data_len = rt2800usb_get_tx_data_len, 637 .get_tx_data_len = rt2800usb_get_tx_data_len,
637 .fill_rxdone = rt2800usb_fill_rxdone, 638 .fill_rxdone = rt2800usb_fill_rxdone,
638 .config_shared_key = rt2800_config_shared_key, 639 .config_shared_key = rt2800_config_shared_key,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 84aaf393da43..985982bb65e2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -368,6 +368,7 @@ struct rt2x00_intf {
368 * dedicated beacon entry. 368 * dedicated beacon entry.
369 */ 369 */
370 struct queue_entry *beacon; 370 struct queue_entry *beacon;
371 bool enable_beacon;
371 372
372 /* 373 /*
373 * Actions that needed rescheduling. 374 * Actions that needed rescheduling.
@@ -573,6 +574,7 @@ struct rt2x00lib_ops {
573 struct txentry_desc *txdesc); 574 struct txentry_desc *txdesc);
574 void (*write_beacon) (struct queue_entry *entry, 575 void (*write_beacon) (struct queue_entry *entry,
575 struct txentry_desc *txdesc); 576 struct txentry_desc *txdesc);
577 void (*clear_beacon) (struct queue_entry *entry);
576 int (*get_tx_data_len) (struct queue_entry *entry); 578 int (*get_tx_data_len) (struct queue_entry *entry);
577 579
578 /* 580 /*
@@ -788,10 +790,12 @@ struct rt2x00_dev {
788 * - Open ap interface count. 790 * - Open ap interface count.
789 * - Open sta interface count. 791 * - Open sta interface count.
790 * - Association count. 792 * - Association count.
793 * - Beaconing enabled count.
791 */ 794 */
792 unsigned int intf_ap_count; 795 unsigned int intf_ap_count;
793 unsigned int intf_sta_count; 796 unsigned int intf_sta_count;
794 unsigned int intf_associated; 797 unsigned int intf_associated;
798 unsigned int intf_beaconing;
795 799
796 /* 800 /*
797 * Link quality 801 * Link quality
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 31b7db05abd9..2c6503878059 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -121,7 +121,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
121 return; 121 return;
122 122
123 if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) 123 if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
124 rt2x00queue_update_beacon(rt2x00dev, vif, true); 124 rt2x00queue_update_beacon(rt2x00dev, vif);
125} 125}
126 126
127static void rt2x00lib_intf_scheduled(struct work_struct *work) 127static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -174,7 +174,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
174 vif->type != NL80211_IFTYPE_WDS) 174 vif->type != NL80211_IFTYPE_WDS)
175 return; 175 return;
176 176
177 rt2x00queue_update_beacon(rt2x00dev, vif, true); 177 rt2x00queue_update_beacon(rt2x00dev, vif);
178} 178}
179 179
180void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) 180void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index a105c500627b..6c6a8f15870e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -160,11 +160,17 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
160 * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware 160 * rt2x00queue_update_beacon - Send new beacon from mac80211 to hardware
161 * @rt2x00dev: Pointer to &struct rt2x00_dev. 161 * @rt2x00dev: Pointer to &struct rt2x00_dev.
162 * @vif: Interface for which the beacon should be updated. 162 * @vif: Interface for which the beacon should be updated.
163 * @enable_beacon: Enable beaconing
164 */ 163 */
165int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, 164int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
166 struct ieee80211_vif *vif, 165 struct ieee80211_vif *vif);
167 const bool enable_beacon); 166
167/**
168 * rt2x00queue_clear_beacon - Clear beacon in hardware
169 * @rt2x00dev: Pointer to &struct rt2x00_dev.
170 * @vif: Interface for which the beacon should be updated.
171 */
172int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
173 struct ieee80211_vif *vif);
168 174
169/** 175/**
170 * rt2x00queue_index_inc - Index incrementation function 176 * rt2x00queue_index_inc - Index incrementation function
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index f3da051df39e..7d3316724bb4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -619,9 +619,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
619 /* 619 /*
620 * Update the beacon. 620 * Update the beacon.
621 */ 621 */
622 if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) 622 if (changes & BSS_CHANGED_BEACON)
623 rt2x00queue_update_beacon(rt2x00dev, vif, 623 rt2x00queue_update_beacon(rt2x00dev, vif);
624 bss_conf->enable_beacon); 624
625 /*
626 * Start/stop beaconing.
627 */
628 if (changes & BSS_CHANGED_BEACON_ENABLED) {
629 if (!bss_conf->enable_beacon && intf->enable_beacon) {
630 rt2x00queue_clear_beacon(rt2x00dev, vif);
631 rt2x00dev->intf_beaconing--;
632 intf->enable_beacon = false;
633
634 if (rt2x00dev->intf_beaconing == 0) {
635 /*
636 * Last beaconing interface disabled
637 * -> stop beacon queue.
638 */
639 mutex_lock(&intf->beacon_skb_mutex);
640 rt2x00queue_stop_queue(rt2x00dev->bcn);
641 mutex_unlock(&intf->beacon_skb_mutex);
642 }
643
644
645 } else if (bss_conf->enable_beacon && !intf->enable_beacon) {
646 rt2x00dev->intf_beaconing++;
647 intf->enable_beacon = true;
648
649 if (rt2x00dev->intf_beaconing == 1) {
650 /*
651 * First beaconing interface enabled
652 * -> start beacon queue.
653 */
654 mutex_lock(&intf->beacon_skb_mutex);
655 rt2x00queue_start_queue(rt2x00dev->bcn);
656 mutex_unlock(&intf->beacon_skb_mutex);
657 }
658 }
659 }
625 660
626 /* 661 /*
627 * When the association status has changed we must reset the link 662 * When the association status has changed we must reset the link
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index ca82b3a91697..24bcdb47a465 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -566,9 +566,35 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
566 return 0; 566 return 0;
567} 567}
568 568
569int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
570 struct ieee80211_vif *vif)
571{
572 struct rt2x00_intf *intf = vif_to_intf(vif);
573
574 if (unlikely(!intf->beacon))
575 return -ENOBUFS;
576
577 mutex_lock(&intf->beacon_skb_mutex);
578
579 /*
580 * Clean up the beacon skb.
581 */
582 rt2x00queue_free_skb(intf->beacon);
583
584 /*
585 * Clear beacon (single bssid devices don't need to clear the beacon
586 * since the beacon queue will get stopped anyway).
587 */
588 if (rt2x00dev->ops->lib->clear_beacon)
589 rt2x00dev->ops->lib->clear_beacon(intf->beacon);
590
591 mutex_unlock(&intf->beacon_skb_mutex);
592
593 return 0;
594}
595
569int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, 596int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
570 struct ieee80211_vif *vif, 597 struct ieee80211_vif *vif)
571 const bool enable_beacon)
572{ 598{
573 struct rt2x00_intf *intf = vif_to_intf(vif); 599 struct rt2x00_intf *intf = vif_to_intf(vif);
574 struct skb_frame_desc *skbdesc; 600 struct skb_frame_desc *skbdesc;
@@ -584,12 +610,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
584 */ 610 */
585 rt2x00queue_free_skb(intf->beacon); 611 rt2x00queue_free_skb(intf->beacon);
586 612
587 if (!enable_beacon) {
588 rt2x00queue_stop_queue(intf->beacon->queue);
589 mutex_unlock(&intf->beacon_skb_mutex);
590 return 0;
591 }
592
593 intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif); 613 intf->beacon->skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
594 if (!intf->beacon->skb) { 614 if (!intf->beacon->skb) {
595 mutex_unlock(&intf->beacon_skb_mutex); 615 mutex_unlock(&intf->beacon_skb_mutex);
@@ -611,7 +631,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
611 skbdesc->entry = intf->beacon; 631 skbdesc->entry = intf->beacon;
612 632
613 /* 633 /*
614 * Send beacon to hardware and enable beacon genaration.. 634 * Send beacon to hardware.
615 */ 635 */
616 rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); 636 rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc);
617 637
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 8de44dd401e0..f14cc452eb0c 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -551,26 +551,14 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
551 struct rt2x00intf_conf *conf, 551 struct rt2x00intf_conf *conf,
552 const unsigned int flags) 552 const unsigned int flags)
553{ 553{
554 unsigned int beacon_base;
555 u32 reg; 554 u32 reg;
556 555
557 if (flags & CONFIG_UPDATE_TYPE) { 556 if (flags & CONFIG_UPDATE_TYPE) {
558 /* 557 /*
559 * Clear current synchronisation setup.
560 * For the Beacon base registers, we only need to clear
561 * the first byte since that byte contains the VALID and OWNER
562 * bits which (when set to 0) will invalidate the entire beacon.
563 */
564 beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
565 rt2x00pci_register_write(rt2x00dev, beacon_base, 0);
566
567 /*
568 * Enable synchronisation. 558 * Enable synchronisation.
569 */ 559 */
570 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg); 560 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
571 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
572 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync); 561 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
573 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
574 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); 562 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
575 } 563 }
576 564
@@ -2002,8 +1990,6 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
2002 */ 1990 */
2003 rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); 1991 rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
2004 1992
2005 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
2006 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
2007 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1); 1993 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
2008 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); 1994 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
2009 1995
@@ -2014,6 +2000,32 @@ static void rt61pci_write_beacon(struct queue_entry *entry,
2014 entry->skb = NULL; 2000 entry->skb = NULL;
2015} 2001}
2016 2002
2003static void rt61pci_clear_beacon(struct queue_entry *entry)
2004{
2005 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
2006 u32 reg;
2007
2008 /*
2009 * Disable beaconing while we are reloading the beacon data,
2010 * otherwise we might be sending out invalid data.
2011 */
2012 rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
2013 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
2014 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
2015
2016 /*
2017 * Clear beacon.
2018 */
2019 rt2x00pci_register_write(rt2x00dev,
2020 HW_BEACON_OFFSET(entry->entry_idx), 0);
2021
2022 /*
2023 * Enable beaconing again.
2024 */
2025 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
2026 rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
2027}
2028
2017/* 2029/*
2018 * RX control handlers 2030 * RX control handlers
2019 */ 2031 */
@@ -2903,6 +2915,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2903 .stop_queue = rt61pci_stop_queue, 2915 .stop_queue = rt61pci_stop_queue,
2904 .write_tx_desc = rt61pci_write_tx_desc, 2916 .write_tx_desc = rt61pci_write_tx_desc,
2905 .write_beacon = rt61pci_write_beacon, 2917 .write_beacon = rt61pci_write_beacon,
2918 .clear_beacon = rt61pci_clear_beacon,
2906 .fill_rxdone = rt61pci_fill_rxdone, 2919 .fill_rxdone = rt61pci_fill_rxdone,
2907 .config_shared_key = rt61pci_config_shared_key, 2920 .config_shared_key = rt61pci_config_shared_key,
2908 .config_pairwise_key = rt61pci_config_pairwise_key, 2921 .config_pairwise_key = rt61pci_config_pairwise_key,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 029be3c6c030..330353ec5c96 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -502,26 +502,14 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
502 struct rt2x00intf_conf *conf, 502 struct rt2x00intf_conf *conf,
503 const unsigned int flags) 503 const unsigned int flags)
504{ 504{
505 unsigned int beacon_base;
506 u32 reg; 505 u32 reg;
507 506
508 if (flags & CONFIG_UPDATE_TYPE) { 507 if (flags & CONFIG_UPDATE_TYPE) {
509 /* 508 /*
510 * Clear current synchronisation setup.
511 * For the Beacon base registers we only need to clear
512 * the first byte since that byte contains the VALID and OWNER
513 * bits which (when set to 0) will invalidate the entire beacon.
514 */
515 beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
516 rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
517
518 /*
519 * Enable synchronisation. 509 * Enable synchronisation.
520 */ 510 */
521 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg); 511 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
522 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
523 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync); 512 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, conf->sync);
524 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
525 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 513 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
526 } 514 }
527 515
@@ -1590,8 +1578,6 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1590 */ 1578 */
1591 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008); 1579 rt2x00usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
1592 1580
1593 rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 1);
1594 rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 1);
1595 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1); 1581 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1596 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); 1582 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1597 1583
@@ -1602,6 +1588,33 @@ static void rt73usb_write_beacon(struct queue_entry *entry,
1602 entry->skb = NULL; 1588 entry->skb = NULL;
1603} 1589}
1604 1590
1591static void rt73usb_clear_beacon(struct queue_entry *entry)
1592{
1593 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
1594 unsigned int beacon_base;
1595 u32 reg;
1596
1597 /*
1598 * Disable beaconing while we are reloading the beacon data,
1599 * otherwise we might be sending out invalid data.
1600 */
1601 rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
1602 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
1603 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1604
1605 /*
1606 * Clear beacon.
1607 */
1608 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
1609 rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
1610
1611 /*
1612 * Enable beaconing again.
1613 */
1614 rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
1615 rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
1616}
1617
1605static int rt73usb_get_tx_data_len(struct queue_entry *entry) 1618static int rt73usb_get_tx_data_len(struct queue_entry *entry)
1606{ 1619{
1607 int length; 1620 int length;
@@ -2313,6 +2326,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2313 .flush_queue = rt2x00usb_flush_queue, 2326 .flush_queue = rt2x00usb_flush_queue,
2314 .write_tx_desc = rt73usb_write_tx_desc, 2327 .write_tx_desc = rt73usb_write_tx_desc,
2315 .write_beacon = rt73usb_write_beacon, 2328 .write_beacon = rt73usb_write_beacon,
2329 .clear_beacon = rt73usb_clear_beacon,
2316 .get_tx_data_len = rt73usb_get_tx_data_len, 2330 .get_tx_data_len = rt73usb_get_tx_data_len,
2317 .fill_rxdone = rt73usb_fill_rxdone, 2331 .fill_rxdone = rt73usb_fill_rxdone,
2318 .config_shared_key = rt73usb_config_shared_key, 2332 .config_shared_key = rt73usb_config_shared_key,