diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 67 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800pci.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800usb.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 42 |
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, ®); | 307 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
308 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
309 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 308 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
310 | rt2x00_set_field32(®, 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(®, CSR14_TSF_COUNT, 1); | ||
1187 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1188 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1184 | rt2x00_set_field32(®, 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, ®); | 313 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
314 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
315 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | 314 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
316 | rt2x00_set_field32(®, 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(®, CSR14_TSF_COUNT, 1); | ||
1341 | rt2x00_set_field32(®, CSR14_TBCN, 1); | ||
1342 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 1); | 1338 | rt2x00_set_field32(®, 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, ®); | 480 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); |
481 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
482 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | 481 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); |
483 | rt2x00_set_field16(®, 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(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
822 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
823 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 821 | rt2x00_set_field32(®, 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 | } |
832 | EXPORT_SYMBOL_GPL(rt2800_write_beacon); | 830 | EXPORT_SYMBOL_GPL(rt2800_write_beacon); |
833 | 831 | ||
834 | static inline void rt2800_clear_beacon(struct rt2x00_dev *rt2x00dev, | 832 | static 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 | ||
846 | void 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, ®); | ||
856 | rt2x00_set_field32(®, 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(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
869 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
870 | } | ||
871 | EXPORT_SYMBOL_GPL(rt2800_clear_beacon); | ||
872 | |||
848 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 873 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
849 | const struct rt2x00debug rt2800_rt2x00debug = { | 874 | const 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, ®); | 1185 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
1166 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
1167 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); | 1186 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_SYNC, conf->sync); |
1168 | rt2x00_set_field32(®, 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, ®); | ||
1177 | rt2x00_set_field32(®, 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, ®); | 2207 | rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); |
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); | |||
156 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status); | 156 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status); |
157 | 157 | ||
158 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); | 158 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); |
159 | void rt2800_clear_beacon(struct queue_entry *entry); | ||
159 | 160 | ||
160 | extern const struct rt2x00debug rt2800_rt2x00debug; | 161 | extern 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(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | 205 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); |
206 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | 206 | rt2x00_set_field32(®, 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, ®); | ||
210 | rt2x00_set_field32(®, 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(®, BCN_TIME_CFG_TBTT_ENABLE, 0); | 254 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); |
251 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 255 | rt2x00_set_field32(®, 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, ®); | ||
259 | rt2x00_set_field32(®, 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 | ||
127 | static void rt2x00lib_intf_scheduled(struct work_struct *work) | 127 | static 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 | ||
180 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 180 | void 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 | */ |
165 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | 164 | int 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 | */ | ||
172 | int 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 | ||
569 | int 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 | |||
569 | int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | 596 | int 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, ®); | 560 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
571 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
572 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 561 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
573 | rt2x00_set_field32(®, 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(®, TXRX_CSR9_TSF_TICKING, 1); | ||
2006 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
2007 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1993 | rt2x00_set_field32(®, 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 | ||
2003 | static 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, ®); | ||
2013 | rt2x00_set_field32(®, 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(®, 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, ®); | 511 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
522 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
523 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | 512 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); |
524 | rt2x00_set_field32(®, 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(®, TXRX_CSR9_TSF_TICKING, 1); | ||
1594 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1); | ||
1595 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 1); | 1581 | rt2x00_set_field32(®, 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 | ||
1591 | static 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, ®); | ||
1602 | rt2x00_set_field32(®, 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(®, TXRX_CSR9_BEACON_GEN, 1); | ||
1615 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1616 | } | ||
1617 | |||
1605 | static int rt73usb_get_tx_data_len(struct queue_entry *entry) | 1618 | static 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, |