diff options
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 84 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 98 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 207 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 113 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00config.c | 119 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 154 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00lib.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 152 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 169 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 179 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.h | 17 |
15 files changed, 826 insertions, 530 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index fc161084a8d3..61766ed800e3 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -246,50 +246,50 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
246 | /* | 246 | /* |
247 | * Configuration handlers. | 247 | * Configuration handlers. |
248 | */ | 248 | */ |
249 | static void rt2400pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | 249 | static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, |
250 | __le32 *mac) | 250 | struct rt2x00_intf *intf, |
251 | struct rt2x00intf_conf *conf, | ||
252 | const unsigned int flags) | ||
251 | { | 253 | { |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 254 | unsigned int bcn_preload; |
253 | (2 * sizeof(__le32))); | 255 | u32 reg; |
254 | } | ||
255 | 256 | ||
256 | static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, | 257 | if (flags & CONFIG_UPDATE_TYPE) { |
257 | __le32 *bssid) | 258 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); |
258 | { | ||
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | ||
260 | (2 * sizeof(__le32))); | ||
261 | } | ||
262 | 259 | ||
263 | static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 260 | /* |
264 | const int tsf_sync) | 261 | * Enable beacon config |
265 | { | 262 | */ |
266 | u32 reg; | 263 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
264 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
265 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | ||
266 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
267 | 267 | ||
268 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 268 | /* |
269 | * Enable synchronisation. | ||
270 | */ | ||
271 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
272 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
273 | rt2x00_set_field32(®, CSR14_TBCN, | ||
274 | (conf->sync == TSF_SYNC_BEACON)); | ||
275 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
276 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); | ||
277 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
278 | } | ||
269 | 279 | ||
270 | /* | 280 | if (flags & CONFIG_UPDATE_MAC) |
271 | * Enable beacon config | 281 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, |
272 | */ | 282 | conf->mac, sizeof(conf->mac)); |
273 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | ||
274 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | ||
275 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | ||
276 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | ||
277 | 283 | ||
278 | /* | 284 | if (flags & CONFIG_UPDATE_BSSID) |
279 | * Enable synchronisation. | 285 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, |
280 | */ | 286 | conf->bssid, sizeof(conf->bssid)); |
281 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | ||
282 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | ||
283 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | ||
284 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | ||
285 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | ||
286 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
287 | } | 287 | } |
288 | 288 | ||
289 | static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 289 | static int rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
290 | const int short_preamble, | 290 | const int short_preamble, |
291 | const int ack_timeout, | 291 | const int ack_timeout, |
292 | const int ack_consume_time) | 292 | const int ack_consume_time) |
293 | { | 293 | { |
294 | int preamble_mask; | 294 | int preamble_mask; |
295 | u32 reg; | 295 | u32 reg; |
@@ -327,6 +327,8 @@ static void rt2400pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
327 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 327 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
328 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 328 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
329 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 329 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
330 | |||
331 | return 0; | ||
330 | } | 332 | } |
331 | 333 | ||
332 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 334 | static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -481,8 +483,8 @@ static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
481 | } | 483 | } |
482 | 484 | ||
483 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, | 485 | static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, |
484 | const unsigned int flags, | 486 | struct rt2x00lib_conf *libconf, |
485 | struct rt2x00lib_conf *libconf) | 487 | const unsigned int flags) |
486 | { | 488 | { |
487 | if (flags & CONFIG_UPDATE_PHYMODE) | 489 | if (flags & CONFIG_UPDATE_PHYMODE) |
488 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); | 490 | rt2400pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -1553,9 +1555,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1553 | .write_tx_data = rt2x00pci_write_tx_data, | 1555 | .write_tx_data = rt2x00pci_write_tx_data, |
1554 | .kick_tx_queue = rt2400pci_kick_tx_queue, | 1556 | .kick_tx_queue = rt2400pci_kick_tx_queue, |
1555 | .fill_rxdone = rt2400pci_fill_rxdone, | 1557 | .fill_rxdone = rt2400pci_fill_rxdone, |
1556 | .config_mac_addr = rt2400pci_config_mac_addr, | 1558 | .config_intf = rt2400pci_config_intf, |
1557 | .config_bssid = rt2400pci_config_bssid, | ||
1558 | .config_type = rt2400pci_config_type, | ||
1559 | .config_preamble = rt2400pci_config_preamble, | 1559 | .config_preamble = rt2400pci_config_preamble, |
1560 | .config = rt2400pci_config, | 1560 | .config = rt2400pci_config, |
1561 | }; | 1561 | }; |
@@ -1590,6 +1590,8 @@ static const struct data_queue_desc rt2400pci_queue_atim = { | |||
1590 | 1590 | ||
1591 | static const struct rt2x00_ops rt2400pci_ops = { | 1591 | static const struct rt2x00_ops rt2400pci_ops = { |
1592 | .name = KBUILD_MODNAME, | 1592 | .name = KBUILD_MODNAME, |
1593 | .max_sta_intf = 1, | ||
1594 | .max_ap_intf = 1, | ||
1593 | .eeprom_size = EEPROM_SIZE, | 1595 | .eeprom_size = EEPROM_SIZE, |
1594 | .rf_size = RF_SIZE, | 1596 | .rf_size = RF_SIZE, |
1595 | .rx = &rt2400pci_queue_rx, | 1597 | .rx = &rt2400pci_queue_rx, |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 0a54b6512207..6a558bf74f11 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -246,53 +246,53 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
246 | /* | 246 | /* |
247 | * Configuration handlers. | 247 | * Configuration handlers. |
248 | */ | 248 | */ |
249 | static void rt2500pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, | 249 | static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, |
250 | __le32 *mac) | 250 | struct rt2x00_intf *intf, |
251 | { | 251 | struct rt2x00intf_conf *conf, |
252 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, mac, | 252 | const unsigned int flags) |
253 | (2 * sizeof(__le32))); | ||
254 | } | ||
255 | |||
256 | static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, | ||
257 | __le32 *bssid) | ||
258 | { | ||
259 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, bssid, | ||
260 | (2 * sizeof(__le32))); | ||
261 | } | ||
262 | |||
263 | static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | ||
264 | const int tsf_sync) | ||
265 | { | 253 | { |
266 | struct data_queue *queue = | 254 | struct data_queue *queue = |
267 | rt2x00queue_get_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 255 | rt2x00queue_get_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); |
256 | unsigned int bcn_preload; | ||
268 | u32 reg; | 257 | u32 reg; |
269 | 258 | ||
270 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | 259 | if (flags & CONFIG_UPDATE_TYPE) { |
260 | rt2x00pci_register_write(rt2x00dev, CSR14, 0); | ||
271 | 261 | ||
272 | /* | 262 | /* |
273 | * Enable beacon config | 263 | * Enable beacon config |
274 | */ | 264 | */ |
275 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 265 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
276 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, | 266 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
277 | PREAMBLE + get_duration(IEEE80211_HEADER, 20)); | 267 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
278 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); | 268 | rt2x00_set_field32(®, BCNCSR1_BEACON_CWMIN, queue->cw_min); |
279 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 269 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
280 | 270 | ||
281 | /* | 271 | /* |
282 | * Enable synchronisation. | 272 | * Enable synchronisation. |
283 | */ | 273 | */ |
284 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); | 274 | rt2x00pci_register_read(rt2x00dev, CSR14, ®); |
285 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); | 275 | rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); |
286 | rt2x00_set_field32(®, CSR14_TBCN, (tsf_sync == TSF_SYNC_BEACON)); | 276 | rt2x00_set_field32(®, CSR14_TBCN, |
287 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); | 277 | (conf->sync == TSF_SYNC_BEACON)); |
288 | rt2x00_set_field32(®, CSR14_TSF_SYNC, tsf_sync); | 278 | rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); |
289 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | 279 | rt2x00_set_field32(®, CSR14_TSF_SYNC, conf->sync); |
280 | rt2x00pci_register_write(rt2x00dev, CSR14, reg); | ||
281 | } | ||
282 | |||
283 | if (flags & CONFIG_UPDATE_MAC) | ||
284 | rt2x00pci_register_multiwrite(rt2x00dev, CSR3, | ||
285 | conf->mac, sizeof(conf->mac)); | ||
286 | |||
287 | if (flags & CONFIG_UPDATE_BSSID) | ||
288 | rt2x00pci_register_multiwrite(rt2x00dev, CSR5, | ||
289 | conf->bssid, sizeof(conf->bssid)); | ||
290 | } | 290 | } |
291 | 291 | ||
292 | static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 292 | static int rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
293 | const int short_preamble, | 293 | const int short_preamble, |
294 | const int ack_timeout, | 294 | const int ack_timeout, |
295 | const int ack_consume_time) | 295 | const int ack_consume_time) |
296 | { | 296 | { |
297 | int preamble_mask; | 297 | int preamble_mask; |
298 | u32 reg; | 298 | u32 reg; |
@@ -330,6 +330,8 @@ static void rt2500pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
330 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 330 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
331 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 331 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); |
332 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 332 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
333 | |||
334 | return 0; | ||
333 | } | 335 | } |
334 | 336 | ||
335 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 337 | static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -529,8 +531,8 @@ static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
529 | } | 531 | } |
530 | 532 | ||
531 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, | 533 | static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, |
532 | const unsigned int flags, | 534 | struct rt2x00lib_conf *libconf, |
533 | struct rt2x00lib_conf *libconf) | 535 | const unsigned int flags) |
534 | { | 536 | { |
535 | if (flags & CONFIG_UPDATE_PHYMODE) | 537 | if (flags & CONFIG_UPDATE_PHYMODE) |
536 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); | 538 | rt2500pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -609,9 +611,10 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
609 | /* | 611 | /* |
610 | * To prevent collisions with MAC ASIC on chipsets | 612 | * To prevent collisions with MAC ASIC on chipsets |
611 | * up to version C the link tuning should halt after 20 | 613 | * up to version C the link tuning should halt after 20 |
612 | * seconds. | 614 | * seconds while being associated. |
613 | */ | 615 | */ |
614 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 616 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
617 | rt2x00dev->intf_associated && | ||
615 | rt2x00dev->link.count > 20) | 618 | rt2x00dev->link.count > 20) |
616 | return; | 619 | return; |
617 | 620 | ||
@@ -619,9 +622,12 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
619 | 622 | ||
620 | /* | 623 | /* |
621 | * Chipset versions C and lower should directly continue | 624 | * Chipset versions C and lower should directly continue |
622 | * to the dynamic CCA tuning. | 625 | * to the dynamic CCA tuning. Chipset version D and higher |
626 | * should go straight to dynamic CCA tuning when they | ||
627 | * are not associated. | ||
623 | */ | 628 | */ |
624 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D) | 629 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D || |
630 | !rt2x00dev->intf_associated) | ||
625 | goto dynamic_cca_tune; | 631 | goto dynamic_cca_tune; |
626 | 632 | ||
627 | /* | 633 | /* |
@@ -1861,9 +1867,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { | |||
1861 | .write_tx_data = rt2x00pci_write_tx_data, | 1867 | .write_tx_data = rt2x00pci_write_tx_data, |
1862 | .kick_tx_queue = rt2500pci_kick_tx_queue, | 1868 | .kick_tx_queue = rt2500pci_kick_tx_queue, |
1863 | .fill_rxdone = rt2500pci_fill_rxdone, | 1869 | .fill_rxdone = rt2500pci_fill_rxdone, |
1864 | .config_mac_addr = rt2500pci_config_mac_addr, | 1870 | .config_intf = rt2500pci_config_intf, |
1865 | .config_bssid = rt2500pci_config_bssid, | ||
1866 | .config_type = rt2500pci_config_type, | ||
1867 | .config_preamble = rt2500pci_config_preamble, | 1871 | .config_preamble = rt2500pci_config_preamble, |
1868 | .config = rt2500pci_config, | 1872 | .config = rt2500pci_config, |
1869 | }; | 1873 | }; |
@@ -1898,6 +1902,8 @@ static const struct data_queue_desc rt2500pci_queue_atim = { | |||
1898 | 1902 | ||
1899 | static const struct rt2x00_ops rt2500pci_ops = { | 1903 | static const struct rt2x00_ops rt2500pci_ops = { |
1900 | .name = KBUILD_MODNAME, | 1904 | .name = KBUILD_MODNAME, |
1905 | .max_sta_intf = 1, | ||
1906 | .max_ap_intf = 1, | ||
1901 | .eeprom_size = EEPROM_SIZE, | 1907 | .eeprom_size = EEPROM_SIZE, |
1902 | .rf_size = RF_SIZE, | 1908 | .rf_size = RF_SIZE, |
1903 | .rx = &rt2500pci_queue_rx, | 1909 | .rx = &rt2500pci_queue_rx, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index edc16a5fc754..31258ee24ee3 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -285,70 +285,65 @@ static const struct rt2x00debug rt2500usb_rt2x00debug = { | |||
285 | /* | 285 | /* |
286 | * Configuration handlers. | 286 | * Configuration handlers. |
287 | */ | 287 | */ |
288 | static void rt2500usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, | 288 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, |
289 | __le32 *mac) | 289 | struct rt2x00_intf *intf, |
290 | { | 290 | struct rt2x00intf_conf *conf, |
291 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | 291 | const unsigned int flags) |
292 | (3 * sizeof(__le16))); | ||
293 | } | ||
294 | |||
295 | static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, | ||
296 | __le32 *bssid) | ||
297 | { | ||
298 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, bssid, | ||
299 | (3 * sizeof(__le16))); | ||
300 | } | ||
301 | |||
302 | static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | ||
303 | const int tsf_sync) | ||
304 | { | 292 | { |
293 | unsigned int bcn_preload; | ||
305 | u16 reg; | 294 | u16 reg; |
306 | 295 | ||
307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | 296 | if (flags & CONFIG_UPDATE_TYPE) { |
297 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0); | ||
308 | 298 | ||
309 | /* | 299 | /* |
310 | * Enable beacon config | 300 | * Enable beacon config |
311 | */ | 301 | */ |
312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); | 302 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); |
313 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, | 303 | rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®); |
314 | (PREAMBLE + get_duration(IEEE80211_HEADER, 20)) >> 6); | 304 | rt2x00_set_field16(®, TXRX_CSR20_OFFSET, bcn_preload >> 6); |
315 | if (type == IEEE80211_IF_TYPE_STA) | 305 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, |
316 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0); | 306 | 2 * (conf->type != IEEE80211_IF_TYPE_STA)); |
317 | else | 307 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); |
318 | rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2); | ||
319 | rt2500usb_register_write(rt2x00dev, TXRX_CSR20, reg); | ||
320 | 308 | ||
321 | /* | 309 | /* |
322 | * Enable synchronisation. | 310 | * Enable synchronisation. |
323 | */ | 311 | */ |
324 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); | 312 | rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); |
325 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); | 313 | rt2x00_set_field16(®, TXRX_CSR18_OFFSET, 0); |
326 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); | 314 | rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); |
315 | |||
316 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | ||
317 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | ||
318 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | ||
319 | (conf->sync == TSF_SYNC_BEACON)); | ||
320 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | ||
321 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, conf->sync); | ||
322 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | ||
323 | } | ||
327 | 324 | ||
328 | rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); | 325 | if (flags & CONFIG_UPDATE_MAC) |
329 | rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1); | 326 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR2, conf->mac, |
330 | rt2x00_set_field16(®, TXRX_CSR19_TBCN, | 327 | (3 * sizeof(__le16))); |
331 | (tsf_sync == TSF_SYNC_BEACON)); | 328 | |
332 | rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0); | 329 | if (flags & CONFIG_UPDATE_BSSID) |
333 | rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, tsf_sync); | 330 | rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, conf->bssid, |
334 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 331 | (3 * sizeof(__le16))); |
335 | } | 332 | } |
336 | 333 | ||
337 | static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 334 | static int rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 335 | const int short_preamble, |
339 | const int ack_timeout, | 336 | const int ack_timeout, |
340 | const int ack_consume_time) | 337 | const int ack_consume_time) |
341 | { | 338 | { |
342 | u16 reg; | 339 | u16 reg; |
343 | 340 | ||
344 | /* | 341 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 342 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 343 | * try this configuration again later. |
347 | */ | 344 | */ |
348 | if (in_atomic()) { | 345 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 346 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 347 | ||
353 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 348 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
354 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); | 349 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, ack_timeout); |
@@ -358,6 +353,8 @@ static void rt2500usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 353 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 354 | !!short_preamble); |
360 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 355 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
356 | |||
357 | return 0; | ||
361 | } | 358 | } |
362 | 359 | ||
363 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 360 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -518,8 +515,8 @@ static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
518 | } | 515 | } |
519 | 516 | ||
520 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, | 517 | static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, |
521 | const unsigned int flags, | 518 | struct rt2x00lib_conf *libconf, |
522 | struct rt2x00lib_conf *libconf) | 519 | const unsigned int flags) |
523 | { | 520 | { |
524 | if (flags & CONFIG_UPDATE_PHYMODE) | 521 | if (flags & CONFIG_UPDATE_PHYMODE) |
525 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, | 522 | rt2500usb_config_phymode(rt2x00dev, libconf->phymode, |
@@ -626,6 +623,24 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | u8 low_bound; | 623 | u8 low_bound; |
627 | 624 | ||
628 | /* | 625 | /* |
626 | * Read current r17 value, as well as the sensitivity values | ||
627 | * for the r17 register. | ||
628 | */ | ||
629 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
630 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
631 | |||
632 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
633 | up_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
634 | low_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCLOWER); | ||
635 | |||
636 | /* | ||
637 | * If we are not associated, we should go straight to the | ||
638 | * dynamic CCA tuning. | ||
639 | */ | ||
640 | if (!rt2x00dev->intf_associated) | ||
641 | goto dynamic_cca_tune; | ||
642 | |||
643 | /* | ||
629 | * Determine the BBP tuning threshold and correctly | 644 | * Determine the BBP tuning threshold and correctly |
630 | * set BBP 24, 25 and 61. | 645 | * set BBP 24, 25 and 61. |
631 | */ | 646 | */ |
@@ -651,13 +666,6 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
651 | rt2500usb_bbp_write(rt2x00dev, 61, r61); | 666 | rt2500usb_bbp_write(rt2x00dev, 61, r61); |
652 | 667 | ||
653 | /* | 668 | /* |
654 | * Read current r17 value, as well as the sensitivity values | ||
655 | * for the r17 register. | ||
656 | */ | ||
657 | rt2500usb_bbp_read(rt2x00dev, 17, &r17); | ||
658 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &r17_sens); | ||
659 | |||
660 | /* | ||
661 | * A too low RSSI will cause too much false CCA which will | 669 | * A too low RSSI will cause too much false CCA which will |
662 | * then corrupt the R17 tuning. To remidy this the tuning should | 670 | * then corrupt the R17 tuning. To remidy this the tuning should |
663 | * be stopped (While making sure the R17 value will not exceed limits) | 671 | * be stopped (While making sure the R17 value will not exceed limits) |
@@ -692,14 +700,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
692 | * Leave short or middle distance condition, restore r17 | 700 | * Leave short or middle distance condition, restore r17 |
693 | * to the dynamic tuning range. | 701 | * to the dynamic tuning range. |
694 | */ | 702 | */ |
695 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &vgc_bound); | ||
696 | vgc_bound = rt2x00_get_field16(vgc_bound, EEPROM_BBPTUNE_VGCUPPER); | ||
697 | |||
698 | low_bound = 0x32; | 703 | low_bound = 0x32; |
699 | if (rssi >= -77) | 704 | if (rssi < -77) |
700 | up_bound = vgc_bound; | 705 | up_bound -= (-77 - rssi); |
701 | else | ||
702 | up_bound = vgc_bound - (-77 - rssi); | ||
703 | 706 | ||
704 | if (up_bound < low_bound) | 707 | if (up_bound < low_bound) |
705 | up_bound = low_bound; | 708 | up_bound = low_bound; |
@@ -707,7 +710,16 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | if (r17 > up_bound) { | 710 | if (r17 > up_bound) { |
708 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); | 711 | rt2500usb_bbp_write(rt2x00dev, 17, up_bound); |
709 | rt2x00dev->link.vgc_level = up_bound; | 712 | rt2x00dev->link.vgc_level = up_bound; |
710 | } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | 713 | return; |
714 | } | ||
715 | |||
716 | dynamic_cca_tune: | ||
717 | |||
718 | /* | ||
719 | * R17 is inside the dynamic tuning range, | ||
720 | * start tuning the link based on the false cca counter. | ||
721 | */ | ||
722 | if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { | ||
711 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); | 723 | rt2500usb_bbp_write(rt2x00dev, 17, ++r17); |
712 | rt2x00dev->link.vgc_level = r17; | 724 | rt2x00dev->link.vgc_level = r17; |
713 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { | 725 | } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { |
@@ -1203,6 +1215,7 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1203 | { | 1215 | { |
1204 | u16 word; | 1216 | u16 word; |
1205 | u8 *mac; | 1217 | u8 *mac; |
1218 | u8 bbp; | ||
1206 | 1219 | ||
1207 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); | 1220 | rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE); |
1208 | 1221 | ||
@@ -1257,9 +1270,17 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1257 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); | 1270 | EEPROM(rt2x00dev, "BBPtune: 0x%04x\n", word); |
1258 | } | 1271 | } |
1259 | 1272 | ||
1273 | /* | ||
1274 | * Switch lower vgc bound to current BBP R17 value, | ||
1275 | * lower the value a bit for better quality. | ||
1276 | */ | ||
1277 | rt2500usb_bbp_read(rt2x00dev, 17, &bbp); | ||
1278 | bbp -= 6; | ||
1279 | |||
1260 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); | 1280 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_VGC, &word); |
1261 | if (word == 0xffff) { | 1281 | if (word == 0xffff) { |
1262 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); | 1282 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCUPPER, 0x40); |
1283 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1263 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | 1284 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); |
1264 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); | 1285 | EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word); |
1265 | } | 1286 | } |
@@ -1270,6 +1291,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1270 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); | 1291 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41); |
1271 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); | 1292 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word); |
1272 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); | 1293 | EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word); |
1294 | } else { | ||
1295 | rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp); | ||
1296 | rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word); | ||
1273 | } | 1297 | } |
1274 | 1298 | ||
1275 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); | 1299 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word); |
@@ -1705,40 +1729,40 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1705 | { | 1729 | { |
1706 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1730 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1707 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 1731 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); |
1732 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1708 | struct queue_entry_priv_usb_bcn *priv_bcn; | 1733 | struct queue_entry_priv_usb_bcn *priv_bcn; |
1709 | struct skb_frame_desc *skbdesc; | 1734 | struct skb_frame_desc *skbdesc; |
1710 | struct data_queue *queue; | ||
1711 | struct queue_entry *entry; | ||
1712 | int pipe = usb_sndbulkpipe(usb_dev, 1); | 1735 | int pipe = usb_sndbulkpipe(usb_dev, 1); |
1713 | int length; | 1736 | int length; |
1714 | 1737 | ||
1715 | /* | 1738 | if (unlikely(!intf->beacon)) |
1716 | * Just in case the ieee80211 doesn't set this, | 1739 | return -ENOBUFS; |
1717 | * but we need this queue set for the descriptor | 1740 | |
1718 | * initialization. | 1741 | priv_bcn = intf->beacon->priv_data; |
1719 | */ | ||
1720 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1721 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
1722 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
1723 | priv_bcn = entry->priv_data; | ||
1724 | 1742 | ||
1725 | /* | 1743 | /* |
1726 | * Add the descriptor in front of the skb. | 1744 | * Add the descriptor in front of the skb. |
1727 | */ | 1745 | */ |
1728 | skb_push(skb, queue->desc_size); | 1746 | skb_push(skb, intf->beacon->queue->desc_size); |
1729 | memset(skb->data, 0, queue->desc_size); | 1747 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
1730 | 1748 | ||
1731 | /* | 1749 | /* |
1732 | * Fill in skb descriptor | 1750 | * Fill in skb descriptor |
1733 | */ | 1751 | */ |
1734 | skbdesc = get_skb_frame_desc(skb); | 1752 | skbdesc = get_skb_frame_desc(skb); |
1735 | memset(skbdesc, 0, sizeof(*skbdesc)); | 1753 | memset(skbdesc, 0, sizeof(*skbdesc)); |
1736 | skbdesc->data = skb->data + queue->desc_size; | 1754 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
1737 | skbdesc->data_len = queue->data_size; | 1755 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
1738 | skbdesc->desc = skb->data; | 1756 | skbdesc->desc = skb->data; |
1739 | skbdesc->desc_len = queue->desc_size; | 1757 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
1740 | skbdesc->entry = entry; | 1758 | skbdesc->entry = intf->beacon; |
1741 | 1759 | ||
1760 | /* | ||
1761 | * Just in case mac80211 doesn't set this correctly, | ||
1762 | * but we need this queue set for the descriptor | ||
1763 | * initialization. | ||
1764 | */ | ||
1765 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
1742 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 1766 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
1743 | 1767 | ||
1744 | /* | 1768 | /* |
@@ -1749,7 +1773,8 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1749 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); | 1773 | length = rt2500usb_get_tx_data_len(rt2x00dev, skb); |
1750 | 1774 | ||
1751 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, | 1775 | usb_fill_bulk_urb(priv_bcn->urb, usb_dev, pipe, |
1752 | skb->data, length, rt2500usb_beacondone, entry); | 1776 | skb->data, length, rt2500usb_beacondone, |
1777 | intf->beacon); | ||
1753 | 1778 | ||
1754 | /* | 1779 | /* |
1755 | * Second we need to create the guardian byte. | 1780 | * Second we need to create the guardian byte. |
@@ -1759,7 +1784,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1759 | priv_bcn->guardian_data = 0; | 1784 | priv_bcn->guardian_data = 0; |
1760 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, | 1785 | usb_fill_bulk_urb(priv_bcn->guardian_urb, usb_dev, pipe, |
1761 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, | 1786 | &priv_bcn->guardian_data, 1, rt2500usb_beacondone, |
1762 | entry); | 1787 | intf->beacon); |
1763 | 1788 | ||
1764 | /* | 1789 | /* |
1765 | * Send out the guardian byte. | 1790 | * Send out the guardian byte. |
@@ -1769,7 +1794,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | |||
1769 | /* | 1794 | /* |
1770 | * Enable beacon generation. | 1795 | * Enable beacon generation. |
1771 | */ | 1796 | */ |
1772 | rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 1797 | rt2500usb_kick_tx_queue(rt2x00dev, control->queue); |
1773 | 1798 | ||
1774 | return 0; | 1799 | return 0; |
1775 | } | 1800 | } |
@@ -1805,9 +1830,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1805 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1830 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1806 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1831 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1807 | .fill_rxdone = rt2500usb_fill_rxdone, | 1832 | .fill_rxdone = rt2500usb_fill_rxdone, |
1808 | .config_mac_addr = rt2500usb_config_mac_addr, | 1833 | .config_intf = rt2500usb_config_intf, |
1809 | .config_bssid = rt2500usb_config_bssid, | ||
1810 | .config_type = rt2500usb_config_type, | ||
1811 | .config_preamble = rt2500usb_config_preamble, | 1834 | .config_preamble = rt2500usb_config_preamble, |
1812 | .config = rt2500usb_config, | 1835 | .config = rt2500usb_config, |
1813 | }; | 1836 | }; |
@@ -1842,6 +1865,8 @@ static const struct data_queue_desc rt2500usb_queue_atim = { | |||
1842 | 1865 | ||
1843 | static const struct rt2x00_ops rt2500usb_ops = { | 1866 | static const struct rt2x00_ops rt2500usb_ops = { |
1844 | .name = KBUILD_MODNAME, | 1867 | .name = KBUILD_MODNAME, |
1868 | .max_sta_intf = 1, | ||
1869 | .max_ap_intf = 1, | ||
1845 | .eeprom_size = EEPROM_SIZE, | 1870 | .eeprom_size = EEPROM_SIZE, |
1846 | .rf_size = RF_SIZE, | 1871 | .rf_size = RF_SIZE, |
1847 | .rx = &rt2500usb_queue_rx, | 1872 | .rx = &rt2500usb_queue_rx, |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index e9f2cd90da58..23ba0c15741f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -686,6 +686,7 @@ | |||
686 | */ | 686 | */ |
687 | #define EEPROM_BBPTUNE_VGC 0x0034 | 687 | #define EEPROM_BBPTUNE_VGC 0x0034 |
688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) | 688 | #define EEPROM_BBPTUNE_VGCUPPER FIELD16(0x00ff) |
689 | #define EEPROM_BBPTUNE_VGCLOWER FIELD16(0xff00) | ||
689 | 690 | ||
690 | /* | 691 | /* |
691 | * EEPROM BBP R17 Tuning. | 692 | * EEPROM BBP R17 Tuning. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6a25195816db..2363ca4903cc 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -343,20 +343,22 @@ static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) | |||
343 | 343 | ||
344 | /* | 344 | /* |
345 | * Interface structure | 345 | * Interface structure |
346 | * Configuration details about the current interface. | 346 | * Per interface configuration details, this structure |
347 | * is allocated as the private data for ieee80211_vif. | ||
347 | */ | 348 | */ |
348 | struct interface { | 349 | struct rt2x00_intf { |
349 | /* | 350 | /* |
350 | * Interface identification. The value is assigned | 351 | * All fields within the rt2x00_intf structure |
351 | * to us by the 80211 stack, and is used to request | 352 | * must be protected with a spinlock. |
352 | * new beacons. | ||
353 | */ | 353 | */ |
354 | struct ieee80211_vif *id; | 354 | spinlock_t lock; |
355 | 355 | ||
356 | /* | 356 | /* |
357 | * Current working type (IEEE80211_IF_TYPE_*). | 357 | * BSS configuration. Copied from the structure |
358 | * passed to us through the bss_info_changed() | ||
359 | * callback funtion. | ||
358 | */ | 360 | */ |
359 | int type; | 361 | struct ieee80211_bss_conf conf; |
360 | 362 | ||
361 | /* | 363 | /* |
362 | * MAC of the device. | 364 | * MAC of the device. |
@@ -367,16 +369,25 @@ struct interface { | |||
367 | * BBSID of the AP to associate with. | 369 | * BBSID of the AP to associate with. |
368 | */ | 370 | */ |
369 | u8 bssid[ETH_ALEN]; | 371 | u8 bssid[ETH_ALEN]; |
370 | }; | ||
371 | 372 | ||
372 | static inline int is_interface_present(struct interface *intf) | 373 | /* |
373 | { | 374 | * Entry in the beacon queue which belongs to |
374 | return !!intf->id; | 375 | * this interface. Each interface has its own |
375 | } | 376 | * dedicated beacon entry. |
377 | */ | ||
378 | struct queue_entry *beacon; | ||
376 | 379 | ||
377 | static inline int is_interface_type(struct interface *intf, int type) | 380 | /* |
381 | * Actions that needed rescheduling. | ||
382 | */ | ||
383 | unsigned int delayed_flags; | ||
384 | #define DELAYED_UPDATE_BEACON 0x00000001 | ||
385 | #define DELAYED_CONFIG_PREAMBLE 0x00000002 | ||
386 | }; | ||
387 | |||
388 | static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif) | ||
378 | { | 389 | { |
379 | return intf->type == type; | 390 | return (struct rt2x00_intf *)vif->drv_priv; |
380 | } | 391 | } |
381 | 392 | ||
382 | /* | 393 | /* |
@@ -430,6 +441,37 @@ struct rt2x00lib_conf { | |||
430 | }; | 441 | }; |
431 | 442 | ||
432 | /* | 443 | /* |
444 | * Configuration structure wrapper around the | ||
445 | * rt2x00 interface configuration handler. | ||
446 | */ | ||
447 | struct rt2x00intf_conf { | ||
448 | /* | ||
449 | * Interface type | ||
450 | */ | ||
451 | enum ieee80211_if_types type; | ||
452 | |||
453 | /* | ||
454 | * TSF sync value, this is dependant on the operation type. | ||
455 | */ | ||
456 | enum tsf_sync sync; | ||
457 | |||
458 | /* | ||
459 | * The MAC and BSSID addressess are simple array of bytes, | ||
460 | * these arrays are little endian, so when sending the addressess | ||
461 | * to the drivers, copy the it into a endian-signed variable. | ||
462 | * | ||
463 | * Note that all devices (except rt2500usb) have 32 bits | ||
464 | * register word sizes. This means that whatever variable we | ||
465 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
466 | * might not accept what we are sending to it. | ||
467 | * This will also make it easier for the driver to write | ||
468 | * the data to the device. | ||
469 | */ | ||
470 | __le32 mac[2]; | ||
471 | __le32 bssid[2]; | ||
472 | }; | ||
473 | |||
474 | /* | ||
433 | * rt2x00lib callback functions. | 475 | * rt2x00lib callback functions. |
434 | */ | 476 | */ |
435 | struct rt2x00lib_ops { | 477 | struct rt2x00lib_ops { |
@@ -495,16 +537,21 @@ struct rt2x00lib_ops { | |||
495 | /* | 537 | /* |
496 | * Configuration handlers. | 538 | * Configuration handlers. |
497 | */ | 539 | */ |
498 | void (*config_mac_addr) (struct rt2x00_dev *rt2x00dev, __le32 *mac); | 540 | void (*config_intf) (struct rt2x00_dev *rt2x00dev, |
499 | void (*config_bssid) (struct rt2x00_dev *rt2x00dev, __le32 *bssid); | 541 | struct rt2x00_intf *intf, |
500 | void (*config_type) (struct rt2x00_dev *rt2x00dev, const int type, | 542 | struct rt2x00intf_conf *conf, |
501 | const int tsf_sync); | 543 | const unsigned int flags); |
502 | void (*config_preamble) (struct rt2x00_dev *rt2x00dev, | 544 | #define CONFIG_UPDATE_TYPE ( 1 << 1 ) |
503 | const int short_preamble, | 545 | #define CONFIG_UPDATE_MAC ( 1 << 2 ) |
504 | const int ack_timeout, | 546 | #define CONFIG_UPDATE_BSSID ( 1 << 3 ) |
505 | const int ack_consume_time); | 547 | |
506 | void (*config) (struct rt2x00_dev *rt2x00dev, const unsigned int flags, | 548 | int (*config_preamble) (struct rt2x00_dev *rt2x00dev, |
507 | struct rt2x00lib_conf *libconf); | 549 | const int short_preamble, |
550 | const int ack_timeout, | ||
551 | const int ack_consume_time); | ||
552 | void (*config) (struct rt2x00_dev *rt2x00dev, | ||
553 | struct rt2x00lib_conf *libconf, | ||
554 | const unsigned int flags); | ||
508 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) | 555 | #define CONFIG_UPDATE_PHYMODE ( 1 << 1 ) |
509 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) | 556 | #define CONFIG_UPDATE_CHANNEL ( 1 << 2 ) |
510 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) | 557 | #define CONFIG_UPDATE_TXPOWER ( 1 << 3 ) |
@@ -519,6 +566,8 @@ struct rt2x00lib_ops { | |||
519 | */ | 566 | */ |
520 | struct rt2x00_ops { | 567 | struct rt2x00_ops { |
521 | const char *name; | 568 | const char *name; |
569 | const unsigned int max_sta_intf; | ||
570 | const unsigned int max_ap_intf; | ||
522 | const unsigned int eeprom_size; | 571 | const unsigned int eeprom_size; |
523 | const unsigned int rf_size; | 572 | const unsigned int rf_size; |
524 | const struct data_queue_desc *rx; | 573 | const struct data_queue_desc *rx; |
@@ -550,6 +599,7 @@ enum rt2x00_flags { | |||
550 | /* | 599 | /* |
551 | * Driver features | 600 | * Driver features |
552 | */ | 601 | */ |
602 | DRIVER_SUPPORT_MIXED_INTERFACES, | ||
553 | DRIVER_REQUIRE_FIRMWARE, | 603 | DRIVER_REQUIRE_FIRMWARE, |
554 | DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, | 604 | DRIVER_REQUIRE_FIRMWARE_CRC_ITU_T, |
555 | DRIVER_REQUIRE_FIRMWARE_CCITT, | 605 | DRIVER_REQUIRE_FIRMWARE_CCITT, |
@@ -566,7 +616,6 @@ enum rt2x00_flags { | |||
566 | CONFIG_EXTERNAL_LNA_BG, | 616 | CONFIG_EXTERNAL_LNA_BG, |
567 | CONFIG_DOUBLE_ANTENNA, | 617 | CONFIG_DOUBLE_ANTENNA, |
568 | CONFIG_DISABLE_LINK_TUNING, | 618 | CONFIG_DISABLE_LINK_TUNING, |
569 | CONFIG_SHORT_PREAMBLE, | ||
570 | }; | 619 | }; |
571 | 620 | ||
572 | /* | 621 | /* |
@@ -670,9 +719,14 @@ struct rt2x00_dev { | |||
670 | unsigned int packet_filter; | 719 | unsigned int packet_filter; |
671 | 720 | ||
672 | /* | 721 | /* |
673 | * Interface configuration. | 722 | * Interface details: |
723 | * - Open ap interface count. | ||
724 | * - Open sta interface count. | ||
725 | * - Association count. | ||
674 | */ | 726 | */ |
675 | struct interface interface; | 727 | unsigned int intf_ap_count; |
728 | unsigned int intf_sta_count; | ||
729 | unsigned int intf_associated; | ||
676 | 730 | ||
677 | /* | 731 | /* |
678 | * Link quality | 732 | * Link quality |
@@ -738,9 +792,8 @@ struct rt2x00_dev { | |||
738 | /* | 792 | /* |
739 | * Scheduled work. | 793 | * Scheduled work. |
740 | */ | 794 | */ |
741 | struct work_struct beacon_work; | 795 | struct work_struct intf_work; |
742 | struct work_struct filter_work; | 796 | struct work_struct filter_work; |
743 | struct work_struct config_work; | ||
744 | 797 | ||
745 | /* | 798 | /* |
746 | * Data queue arrays for RX, TX and Beacon. | 799 | * Data queue arrays for RX, TX and Beacon. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index c247ee77b3a3..20231e0c53fa 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -29,64 +29,89 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | 32 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, | |
33 | /* | 33 | struct rt2x00_intf *intf, |
34 | * The MAC and BSSID addressess are simple array of bytes, | 34 | enum ieee80211_if_types type, |
35 | * these arrays are little endian, so when sending the addressess | 35 | u8 *mac, u8 *bssid) |
36 | * to the drivers, copy the it into a endian-signed variable. | ||
37 | * | ||
38 | * Note that all devices (except rt2500usb) have 32 bits | ||
39 | * register word sizes. This means that whatever variable we | ||
40 | * pass _must_ be a multiple of 32 bits. Otherwise the device | ||
41 | * might not accept what we are sending to it. | ||
42 | * This will also make it easier for the driver to write | ||
43 | * the data to the device. | ||
44 | * | ||
45 | * Also note that when NULL is passed as address the | ||
46 | * we will send 00:00:00:00:00 to the device to clear the address. | ||
47 | * This will prevent the device being confused when it wants | ||
48 | * to ACK frames or consideres itself associated. | ||
49 | */ | ||
50 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac) | ||
51 | { | 36 | { |
52 | __le32 reg[2]; | 37 | struct rt2x00intf_conf conf; |
53 | 38 | unsigned int flags = 0; | |
54 | memset(®, 0, sizeof(reg)); | ||
55 | if (mac) | ||
56 | memcpy(®, mac, ETH_ALEN); | ||
57 | |||
58 | rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, ®[0]); | ||
59 | } | ||
60 | 39 | ||
61 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) | 40 | conf.type = type; |
62 | { | ||
63 | __le32 reg[2]; | ||
64 | |||
65 | memset(®, 0, sizeof(reg)); | ||
66 | if (bssid) | ||
67 | memcpy(®, bssid, ETH_ALEN); | ||
68 | |||
69 | rt2x00dev->ops->lib->config_bssid(rt2x00dev, ®[0]); | ||
70 | } | ||
71 | |||
72 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) | ||
73 | { | ||
74 | int tsf_sync; | ||
75 | 41 | ||
76 | switch (type) { | 42 | switch (type) { |
77 | case IEEE80211_IF_TYPE_IBSS: | 43 | case IEEE80211_IF_TYPE_IBSS: |
78 | case IEEE80211_IF_TYPE_AP: | 44 | case IEEE80211_IF_TYPE_AP: |
79 | tsf_sync = TSF_SYNC_BEACON; | 45 | conf.sync = TSF_SYNC_BEACON; |
80 | break; | 46 | break; |
81 | case IEEE80211_IF_TYPE_STA: | 47 | case IEEE80211_IF_TYPE_STA: |
82 | tsf_sync = TSF_SYNC_INFRA; | 48 | conf.sync = TSF_SYNC_INFRA; |
83 | break; | 49 | break; |
84 | default: | 50 | default: |
85 | tsf_sync = TSF_SYNC_NONE; | 51 | conf.sync = TSF_SYNC_NONE; |
86 | break; | 52 | break; |
87 | } | 53 | } |
88 | 54 | ||
89 | rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); | 55 | /* |
56 | * Note that when NULL is passed as address we will send | ||
57 | * 00:00:00:00:00 to the device to clear the address. | ||
58 | * This will prevent the device being confused when it wants | ||
59 | * to ACK frames or consideres itself associated. | ||
60 | */ | ||
61 | memset(&conf.mac, 0, sizeof(conf.mac)); | ||
62 | if (mac) | ||
63 | memcpy(&conf.mac, mac, ETH_ALEN); | ||
64 | |||
65 | memset(&conf.bssid, 0, sizeof(conf.bssid)); | ||
66 | if (bssid) | ||
67 | memcpy(&conf.bssid, bssid, ETH_ALEN); | ||
68 | |||
69 | flags |= CONFIG_UPDATE_TYPE; | ||
70 | if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
71 | flags |= CONFIG_UPDATE_MAC; | ||
72 | if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count)) | ||
73 | flags |= CONFIG_UPDATE_BSSID; | ||
74 | |||
75 | rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags); | ||
76 | } | ||
77 | |||
78 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
79 | struct rt2x00_intf *intf, | ||
80 | const unsigned int short_preamble) | ||
81 | { | ||
82 | int retval; | ||
83 | int ack_timeout; | ||
84 | int ack_consume_time; | ||
85 | |||
86 | ack_timeout = PLCP + get_duration(ACK_SIZE, 10); | ||
87 | ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10); | ||
88 | |||
89 | if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) | ||
90 | ack_timeout += SHORT_DIFS; | ||
91 | else | ||
92 | ack_timeout += DIFS; | ||
93 | |||
94 | if (short_preamble) { | ||
95 | ack_timeout += SHORT_PREAMBLE; | ||
96 | ack_consume_time += SHORT_PREAMBLE; | ||
97 | } else { | ||
98 | ack_timeout += PREAMBLE; | ||
99 | ack_consume_time += PREAMBLE; | ||
100 | } | ||
101 | |||
102 | retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev, | ||
103 | short_preamble, | ||
104 | ack_timeout, | ||
105 | ack_consume_time); | ||
106 | |||
107 | spin_lock(&intf->lock); | ||
108 | |||
109 | if (retval) { | ||
110 | intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE; | ||
111 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
112 | } | ||
113 | |||
114 | spin_unlock(&intf->lock); | ||
90 | } | 115 | } |
91 | 116 | ||
92 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 117 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
@@ -113,7 +138,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
113 | * The latter is required since we need to recalibrate the | 138 | * The latter is required since we need to recalibrate the |
114 | * noise-sensitivity ratio for the new setup. | 139 | * noise-sensitivity ratio for the new setup. |
115 | */ | 140 | */ |
116 | rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); | 141 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
117 | rt2x00lib_reset_link_tuner(rt2x00dev); | 142 | rt2x00lib_reset_link_tuner(rt2x00dev); |
118 | 143 | ||
119 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 144 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
@@ -266,7 +291,7 @@ config: | |||
266 | /* | 291 | /* |
267 | * Start configuration. | 292 | * Start configuration. |
268 | */ | 293 | */ |
269 | rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); | 294 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags); |
270 | 295 | ||
271 | /* | 296 | /* |
272 | * Some configuration changes affect the link quality | 297 | * Some configuration changes affect the link quality |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index bc07c56f89b3..014c307c270c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -136,12 +136,10 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
136 | /* | 136 | /* |
137 | * Stop all scheduled work. | 137 | * Stop all scheduled work. |
138 | */ | 138 | */ |
139 | if (work_pending(&rt2x00dev->beacon_work)) | 139 | if (work_pending(&rt2x00dev->intf_work)) |
140 | cancel_work_sync(&rt2x00dev->beacon_work); | 140 | cancel_work_sync(&rt2x00dev->intf_work); |
141 | if (work_pending(&rt2x00dev->filter_work)) | 141 | if (work_pending(&rt2x00dev->filter_work)) |
142 | cancel_work_sync(&rt2x00dev->filter_work); | 142 | cancel_work_sync(&rt2x00dev->filter_work); |
143 | if (work_pending(&rt2x00dev->config_work)) | ||
144 | cancel_work_sync(&rt2x00dev->config_work); | ||
145 | 143 | ||
146 | /* | 144 | /* |
147 | * Stop the TX queues. | 145 | * Stop the TX queues. |
@@ -173,7 +171,7 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
173 | * When we are enabling the RX, we should also start the link tuner. | 171 | * When we are enabling the RX, we should also start the link tuner. |
174 | */ | 172 | */ |
175 | if (state == STATE_RADIO_RX_ON && | 173 | if (state == STATE_RADIO_RX_ON && |
176 | is_interface_present(&rt2x00dev->interface)) | 174 | (rt2x00dev->intf_ap_count || rt2x00dev->intf_sta_count)) |
177 | rt2x00lib_start_link_tuner(rt2x00dev); | 175 | rt2x00lib_start_link_tuner(rt2x00dev); |
178 | } | 176 | } |
179 | 177 | ||
@@ -401,10 +399,10 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
401 | unsigned int filter = rt2x00dev->packet_filter; | 399 | unsigned int filter = rt2x00dev->packet_filter; |
402 | 400 | ||
403 | /* | 401 | /* |
404 | * Since we had stored the filter inside interface.filter, | 402 | * Since we had stored the filter inside rt2x00dev->packet_filter, |
405 | * we should now clear that field. Otherwise the driver will | 403 | * we should now clear that field. Otherwise the driver will |
406 | * assume nothing has changed (*total_flags will be compared | 404 | * assume nothing has changed (*total_flags will be compared |
407 | * to interface.filter to determine if any action is required). | 405 | * to rt2x00dev->packet_filter to determine if any action is required). |
408 | */ | 406 | */ |
409 | rt2x00dev->packet_filter = 0; | 407 | rt2x00dev->packet_filter = 0; |
410 | 408 | ||
@@ -412,41 +410,72 @@ static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | |||
412 | filter, &filter, 0, NULL); | 410 | filter, &filter, 0, NULL); |
413 | } | 411 | } |
414 | 412 | ||
415 | static void rt2x00lib_configuration_scheduled(struct work_struct *work) | 413 | static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, |
414 | struct ieee80211_vif *vif) | ||
416 | { | 415 | { |
417 | struct rt2x00_dev *rt2x00dev = | 416 | struct rt2x00_dev *rt2x00dev = data; |
418 | container_of(work, struct rt2x00_dev, config_work); | 417 | struct rt2x00_intf *intf = vif_to_intf(vif); |
419 | struct ieee80211_bss_conf bss_conf; | 418 | struct sk_buff *skb; |
419 | struct ieee80211_tx_control control; | ||
420 | struct ieee80211_bss_conf conf; | ||
421 | int delayed_flags; | ||
422 | |||
423 | /* | ||
424 | * Copy all data we need during this action under the protection | ||
425 | * of a spinlock. Otherwise race conditions might occur which results | ||
426 | * into an invalid configuration. | ||
427 | */ | ||
428 | spin_lock(&intf->lock); | ||
429 | |||
430 | memcpy(&conf, &intf->conf, sizeof(conf)); | ||
431 | delayed_flags = intf->delayed_flags; | ||
432 | intf->delayed_flags = 0; | ||
433 | |||
434 | spin_unlock(&intf->lock); | ||
435 | |||
436 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | ||
437 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | ||
438 | if (skb) { | ||
439 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, | ||
440 | &control); | ||
441 | dev_kfree_skb(skb); | ||
442 | } | ||
443 | } | ||
444 | |||
445 | if (delayed_flags & DELAYED_CONFIG_PREAMBLE) | ||
446 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
447 | intf->conf.use_short_preamble); | ||
448 | } | ||
420 | 449 | ||
421 | bss_conf.use_short_preamble = | 450 | static void rt2x00lib_intf_scheduled(struct work_struct *work) |
422 | test_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 451 | { |
452 | struct rt2x00_dev *rt2x00dev = | ||
453 | container_of(work, struct rt2x00_dev, intf_work); | ||
423 | 454 | ||
424 | /* | 455 | /* |
425 | * FIXME: shouldn't invoke it this way because all other contents | 456 | * Iterate over each interface and perform the |
426 | * of bss_conf is invalid. | 457 | * requested configurations. |
427 | */ | 458 | */ |
428 | rt2x00mac_bss_info_changed(rt2x00dev->hw, rt2x00dev->interface.id, | 459 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
429 | &bss_conf, BSS_CHANGED_ERP_PREAMBLE); | 460 | rt2x00lib_intf_scheduled_iter, |
461 | rt2x00dev); | ||
430 | } | 462 | } |
431 | 463 | ||
432 | /* | 464 | /* |
433 | * Interrupt context handlers. | 465 | * Interrupt context handlers. |
434 | */ | 466 | */ |
435 | static void rt2x00lib_beacondone_scheduled(struct work_struct *work) | 467 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
468 | struct ieee80211_vif *vif) | ||
436 | { | 469 | { |
437 | struct rt2x00_dev *rt2x00dev = | 470 | struct rt2x00_intf *intf = vif_to_intf(vif); |
438 | container_of(work, struct rt2x00_dev, beacon_work); | ||
439 | struct ieee80211_tx_control control; | ||
440 | struct sk_buff *skb; | ||
441 | 471 | ||
442 | skb = ieee80211_beacon_get(rt2x00dev->hw, | 472 | if (vif->type != IEEE80211_IF_TYPE_AP && |
443 | rt2x00dev->interface.id, &control); | 473 | vif->type != IEEE80211_IF_TYPE_IBSS) |
444 | if (!skb) | ||
445 | return; | 474 | return; |
446 | 475 | ||
447 | rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, skb, &control); | 476 | spin_lock(&intf->lock); |
448 | 477 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | |
449 | dev_kfree_skb(skb); | 478 | spin_unlock(&intf->lock); |
450 | } | 479 | } |
451 | 480 | ||
452 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | 481 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) |
@@ -454,7 +483,11 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
454 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
455 | return; | 484 | return; |
456 | 485 | ||
457 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->beacon_work); | 486 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
487 | rt2x00lib_beacondone_iter, | ||
488 | rt2x00dev); | ||
489 | |||
490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | ||
458 | } | 491 | } |
459 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 492 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
460 | 493 | ||
@@ -1037,6 +1070,10 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) | |||
1037 | return retval; | 1070 | return retval; |
1038 | } | 1071 | } |
1039 | 1072 | ||
1073 | rt2x00dev->intf_ap_count = 0; | ||
1074 | rt2x00dev->intf_sta_count = 0; | ||
1075 | rt2x00dev->intf_associated = 0; | ||
1076 | |||
1040 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1077 | __set_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1041 | 1078 | ||
1042 | return 0; | 1079 | return 0; |
@@ -1053,6 +1090,10 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) | |||
1053 | */ | 1090 | */ |
1054 | rt2x00lib_disable_radio(rt2x00dev); | 1091 | rt2x00lib_disable_radio(rt2x00dev); |
1055 | 1092 | ||
1093 | rt2x00dev->intf_ap_count = 0; | ||
1094 | rt2x00dev->intf_sta_count = 0; | ||
1095 | rt2x00dev->intf_associated = 0; | ||
1096 | |||
1056 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); | 1097 | __clear_bit(DEVICE_STARTED, &rt2x00dev->flags); |
1057 | } | 1098 | } |
1058 | 1099 | ||
@@ -1064,6 +1105,12 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1064 | int retval = -ENOMEM; | 1105 | int retval = -ENOMEM; |
1065 | 1106 | ||
1066 | /* | 1107 | /* |
1108 | * Make room for rt2x00_intf inside the per-interface | ||
1109 | * structure ieee80211_vif. | ||
1110 | */ | ||
1111 | rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); | ||
1112 | |||
1113 | /* | ||
1067 | * Let the driver probe the device to detect the capabilities. | 1114 | * Let the driver probe the device to detect the capabilities. |
1068 | */ | 1115 | */ |
1069 | retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); | 1116 | retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); |
@@ -1075,17 +1122,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1075 | /* | 1122 | /* |
1076 | * Initialize configuration work. | 1123 | * Initialize configuration work. |
1077 | */ | 1124 | */ |
1078 | INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled); | 1125 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1079 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1126 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1080 | INIT_WORK(&rt2x00dev->config_work, rt2x00lib_configuration_scheduled); | ||
1081 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1127 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
1082 | 1128 | ||
1083 | /* | 1129 | /* |
1084 | * Reset current working type. | ||
1085 | */ | ||
1086 | rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; | ||
1087 | |||
1088 | /* | ||
1089 | * Allocate queue array. | 1130 | * Allocate queue array. |
1090 | */ | 1131 | */ |
1091 | retval = rt2x00queue_allocate(rt2x00dev); | 1132 | retval = rt2x00queue_allocate(rt2x00dev); |
@@ -1203,9 +1244,30 @@ exit: | |||
1203 | } | 1244 | } |
1204 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); | 1245 | EXPORT_SYMBOL_GPL(rt2x00lib_suspend); |
1205 | 1246 | ||
1247 | static void rt2x00lib_resume_intf(void *data, u8 *mac, | ||
1248 | struct ieee80211_vif *vif) | ||
1249 | { | ||
1250 | struct rt2x00_dev *rt2x00dev = data; | ||
1251 | struct rt2x00_intf *intf = vif_to_intf(vif); | ||
1252 | |||
1253 | spin_lock(&intf->lock); | ||
1254 | |||
1255 | rt2x00lib_config_intf(rt2x00dev, intf, | ||
1256 | vif->type, intf->mac, intf->bssid); | ||
1257 | |||
1258 | |||
1259 | /* | ||
1260 | * Master or Ad-hoc mode require a new beacon update. | ||
1261 | */ | ||
1262 | if (vif->type == IEEE80211_IF_TYPE_AP || | ||
1263 | vif->type == IEEE80211_IF_TYPE_IBSS) | ||
1264 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | ||
1265 | |||
1266 | spin_unlock(&intf->lock); | ||
1267 | } | ||
1268 | |||
1206 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | 1269 | int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) |
1207 | { | 1270 | { |
1208 | struct interface *intf = &rt2x00dev->interface; | ||
1209 | int retval; | 1271 | int retval; |
1210 | 1272 | ||
1211 | NOTICE(rt2x00dev, "Waking up.\n"); | 1273 | NOTICE(rt2x00dev, "Waking up.\n"); |
@@ -1235,9 +1297,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1235 | if (!rt2x00dev->hw->conf.radio_enabled) | 1297 | if (!rt2x00dev->hw->conf.radio_enabled) |
1236 | rt2x00lib_disable_radio(rt2x00dev); | 1298 | rt2x00lib_disable_radio(rt2x00dev); |
1237 | 1299 | ||
1238 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 1300 | /* |
1239 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 1301 | * Iterator over each active interface to |
1240 | rt2x00lib_config_type(rt2x00dev, intf->type); | 1302 | * reconfigure the hardware. |
1303 | */ | ||
1304 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | ||
1305 | rt2x00lib_resume_intf, rt2x00dev); | ||
1241 | 1306 | ||
1242 | /* | 1307 | /* |
1243 | * We are ready again to receive requests from mac80211. | 1308 | * We are ready again to receive requests from mac80211. |
@@ -1253,12 +1318,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) | |||
1253 | ieee80211_start_queues(rt2x00dev->hw); | 1318 | ieee80211_start_queues(rt2x00dev->hw); |
1254 | 1319 | ||
1255 | /* | 1320 | /* |
1256 | * When in Master or Ad-hoc mode, | 1321 | * During interface iteration we might have changed the |
1257 | * restart Beacon transmitting by faking a beacondone event. | 1322 | * delayed_flags, time to handles the event by calling |
1323 | * the work handler directly. | ||
1258 | */ | 1324 | */ |
1259 | if (intf->type == IEEE80211_IF_TYPE_AP || | 1325 | rt2x00lib_intf_scheduled(&rt2x00dev->intf_work); |
1260 | intf->type == IEEE80211_IF_TYPE_IBSS) | ||
1261 | rt2x00lib_beacondone(rt2x00dev); | ||
1262 | 1326 | ||
1263 | return 0; | 1327 | return 0; |
1264 | 1328 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 5c835f42a455..f6789fdaaf6e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -50,9 +50,13 @@ void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev); | |||
50 | /* | 50 | /* |
51 | * Configuration handlers. | 51 | * Configuration handlers. |
52 | */ | 52 | */ |
53 | void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); | 53 | void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, |
54 | void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); | 54 | struct rt2x00_intf *intf, |
55 | void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type); | 55 | enum ieee80211_if_types type, |
56 | u8 *mac, u8 *bssid); | ||
57 | void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev, | ||
58 | struct rt2x00_intf *intf, | ||
59 | const unsigned int short_preamble); | ||
56 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 60 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
57 | enum antenna rx, enum antenna tx); | 61 | enum antenna rx, enum antenna tx); |
58 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 62 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index f08c151ee4ba..65a2bcd18aa1 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -52,11 +52,11 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, | |||
52 | skb_put(skb, size); | 52 | skb_put(skb, size); |
53 | 53 | ||
54 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | 54 | if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
55 | ieee80211_ctstoself_get(rt2x00dev->hw, rt2x00dev->interface.id, | 55 | ieee80211_ctstoself_get(rt2x00dev->hw, control->vif, |
56 | frag_skb->data, frag_skb->len, control, | 56 | frag_skb->data, frag_skb->len, control, |
57 | (struct ieee80211_cts *)(skb->data)); | 57 | (struct ieee80211_cts *)(skb->data)); |
58 | else | 58 | else |
59 | ieee80211_rts_get(rt2x00dev->hw, rt2x00dev->interface.id, | 59 | ieee80211_rts_get(rt2x00dev->hw, control->vif, |
60 | frag_skb->data, frag_skb->len, control, | 60 | frag_skb->data, frag_skb->len, control, |
61 | (struct ieee80211_rts *)(skb->data)); | 61 | (struct ieee80211_rts *)(skb->data)); |
62 | 62 | ||
@@ -162,19 +162,67 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
162 | struct ieee80211_if_init_conf *conf) | 162 | struct ieee80211_if_init_conf *conf) |
163 | { | 163 | { |
164 | struct rt2x00_dev *rt2x00dev = hw->priv; | 164 | struct rt2x00_dev *rt2x00dev = hw->priv; |
165 | struct interface *intf = &rt2x00dev->interface; | 165 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
166 | struct data_queue *queue = | ||
167 | rt2x00queue_get_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | ||
168 | struct queue_entry *entry = NULL; | ||
169 | unsigned int i; | ||
166 | 170 | ||
167 | /* | 171 | /* |
168 | * Don't allow interfaces to be added while | 172 | * Don't allow interfaces to be added |
169 | * either the device has disappeared or when | 173 | * the device has disappeared. |
170 | * another interface is already present. | ||
171 | */ | 174 | */ |
172 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 175 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
173 | is_interface_present(intf)) | 176 | !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) |
177 | return -ENODEV; | ||
178 | |||
179 | /* | ||
180 | * When we don't support mixed interfaces (a combination | ||
181 | * of sta and ap virtual interfaces) then we can only | ||
182 | * add this interface when the rival interface count is 0. | ||
183 | */ | ||
184 | if (!test_bit(DRIVER_SUPPORT_MIXED_INTERFACES, &rt2x00dev->flags) && | ||
185 | ((conf->type == IEEE80211_IF_TYPE_AP && rt2x00dev->intf_sta_count) || | ||
186 | (conf->type != IEEE80211_IF_TYPE_AP && rt2x00dev->intf_ap_count))) | ||
187 | return -ENOBUFS; | ||
188 | |||
189 | /* | ||
190 | * Check if we exceeded the maximum amount of supported interfaces. | ||
191 | */ | ||
192 | if ((conf->type == IEEE80211_IF_TYPE_AP && | ||
193 | rt2x00dev->intf_ap_count >= rt2x00dev->ops->max_ap_intf) || | ||
194 | (conf->type != IEEE80211_IF_TYPE_AP && | ||
195 | rt2x00dev->intf_sta_count >= rt2x00dev->ops->max_sta_intf)) | ||
196 | return -ENOBUFS; | ||
197 | |||
198 | /* | ||
199 | * Loop through all beacon queues to find a free | ||
200 | * entry. Since there are as much beacon entries | ||
201 | * as the maximum interfaces, this search shouldn't | ||
202 | * fail. | ||
203 | */ | ||
204 | for (i = 0; i < queue->limit; i++) { | ||
205 | entry = &queue->entries[i]; | ||
206 | if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) | ||
207 | break; | ||
208 | } | ||
209 | |||
210 | if (unlikely(i == queue->limit)) | ||
174 | return -ENOBUFS; | 211 | return -ENOBUFS; |
175 | 212 | ||
176 | intf->id = conf->vif; | 213 | /* |
177 | intf->type = conf->type; | 214 | * We are now absolutely sure the interface can be created, |
215 | * increase interface count and start initialization. | ||
216 | */ | ||
217 | |||
218 | if (conf->type == IEEE80211_IF_TYPE_AP) | ||
219 | rt2x00dev->intf_ap_count++; | ||
220 | else | ||
221 | rt2x00dev->intf_sta_count++; | ||
222 | |||
223 | spin_lock_init(&intf->lock); | ||
224 | intf->beacon = entry; | ||
225 | |||
178 | if (conf->type == IEEE80211_IF_TYPE_AP) | 226 | if (conf->type == IEEE80211_IF_TYPE_AP) |
179 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); | 227 | memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN); |
180 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); | 228 | memcpy(&intf->mac, conf->mac_addr, ETH_ALEN); |
@@ -184,8 +232,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, | |||
184 | * has been initialized. Otherwise the device can reset | 232 | * has been initialized. Otherwise the device can reset |
185 | * the MAC registers. | 233 | * the MAC registers. |
186 | */ | 234 | */ |
187 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 235 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, intf->mac, NULL); |
188 | rt2x00lib_config_type(rt2x00dev, conf->type); | ||
189 | 236 | ||
190 | return 0; | 237 | return 0; |
191 | } | 238 | } |
@@ -195,7 +242,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
195 | struct ieee80211_if_init_conf *conf) | 242 | struct ieee80211_if_init_conf *conf) |
196 | { | 243 | { |
197 | struct rt2x00_dev *rt2x00dev = hw->priv; | 244 | struct rt2x00_dev *rt2x00dev = hw->priv; |
198 | struct interface *intf = &rt2x00dev->interface; | 245 | struct rt2x00_intf *intf = vif_to_intf(conf->vif); |
199 | 246 | ||
200 | /* | 247 | /* |
201 | * Don't allow interfaces to be remove while | 248 | * Don't allow interfaces to be remove while |
@@ -203,21 +250,27 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, | |||
203 | * no interface is present. | 250 | * no interface is present. |
204 | */ | 251 | */ |
205 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || | 252 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || |
206 | !is_interface_present(intf)) | 253 | (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || |
254 | (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) | ||
207 | return; | 255 | return; |
208 | 256 | ||
209 | intf->id = NULL; | 257 | if (conf->type == IEEE80211_IF_TYPE_AP) |
210 | intf->type = IEEE80211_IF_TYPE_INVALID; | 258 | rt2x00dev->intf_ap_count--; |
211 | memset(&intf->bssid, 0x00, ETH_ALEN); | 259 | else |
212 | memset(&intf->mac, 0x00, ETH_ALEN); | 260 | rt2x00dev->intf_sta_count--; |
261 | |||
262 | /* | ||
263 | * Release beacon entry so it is available for | ||
264 | * new interfaces again. | ||
265 | */ | ||
266 | __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); | ||
213 | 267 | ||
214 | /* | 268 | /* |
215 | * Make sure the bssid and mac address registers | 269 | * Make sure the bssid and mac address registers |
216 | * are cleared to prevent false ACKing of frames. | 270 | * are cleared to prevent false ACKing of frames. |
217 | */ | 271 | */ |
218 | rt2x00lib_config_mac_addr(rt2x00dev, intf->mac); | 272 | rt2x00lib_config_intf(rt2x00dev, intf, |
219 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 273 | IEEE80211_IF_TYPE_INVALID, NULL, NULL); |
220 | rt2x00lib_config_type(rt2x00dev, intf->type); | ||
221 | } | 274 | } |
222 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); | 275 | EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface); |
223 | 276 | ||
@@ -262,7 +315,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
262 | struct ieee80211_if_conf *conf) | 315 | struct ieee80211_if_conf *conf) |
263 | { | 316 | { |
264 | struct rt2x00_dev *rt2x00dev = hw->priv; | 317 | struct rt2x00_dev *rt2x00dev = hw->priv; |
265 | struct interface *intf = &rt2x00dev->interface; | 318 | struct rt2x00_intf *intf = vif_to_intf(vif); |
266 | int status; | 319 | int status; |
267 | 320 | ||
268 | /* | 321 | /* |
@@ -272,12 +325,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
272 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) | 325 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) |
273 | return 0; | 326 | return 0; |
274 | 327 | ||
275 | /* | 328 | spin_lock(&intf->lock); |
276 | * If the given type does not match the configured type, | ||
277 | * there has been a problem. | ||
278 | */ | ||
279 | if (conf->type != intf->type) | ||
280 | return -EINVAL; | ||
281 | 329 | ||
282 | /* | 330 | /* |
283 | * If the interface does not work in master mode, | 331 | * If the interface does not work in master mode, |
@@ -286,7 +334,9 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, | |||
286 | */ | 334 | */ |
287 | if (conf->type != IEEE80211_IF_TYPE_AP) | 335 | if (conf->type != IEEE80211_IF_TYPE_AP) |
288 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); | 336 | memcpy(&intf->bssid, conf->bssid, ETH_ALEN); |
289 | rt2x00lib_config_bssid(rt2x00dev, intf->bssid); | 337 | rt2x00lib_config_intf(rt2x00dev, intf, conf->type, NULL, intf->bssid); |
338 | |||
339 | spin_unlock(&intf->lock); | ||
290 | 340 | ||
291 | /* | 341 | /* |
292 | * We only need to initialize the beacon when master mode is enabled. | 342 | * We only need to initialize the beacon when master mode is enabled. |
@@ -342,35 +392,35 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
342 | u32 changes) | 392 | u32 changes) |
343 | { | 393 | { |
344 | struct rt2x00_dev *rt2x00dev = hw->priv; | 394 | struct rt2x00_dev *rt2x00dev = hw->priv; |
345 | int short_preamble; | 395 | struct rt2x00_intf *intf = vif_to_intf(vif); |
346 | int ack_timeout; | ||
347 | int ack_consume_time; | ||
348 | int difs; | ||
349 | int preamble; | ||
350 | 396 | ||
351 | /* | 397 | /* |
352 | * We only support changing preamble mode. | 398 | * When the association status has changed we must reset the link |
399 | * tuner counter. This is because some drivers determine if they | ||
400 | * should perform link tuning based on the number of seconds | ||
401 | * while associated or not associated. | ||
353 | */ | 402 | */ |
354 | if (!(changes & BSS_CHANGED_ERP_PREAMBLE)) | 403 | if (changes & BSS_CHANGED_ASSOC) { |
355 | return; | 404 | rt2x00dev->link.count = 0; |
356 | |||
357 | short_preamble = bss_conf->use_short_preamble; | ||
358 | preamble = bss_conf->use_short_preamble ? | ||
359 | SHORT_PREAMBLE : PREAMBLE; | ||
360 | 405 | ||
361 | difs = (hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME) ? | 406 | if (bss_conf->assoc) |
362 | SHORT_DIFS : DIFS; | 407 | rt2x00dev->intf_associated++; |
363 | ack_timeout = difs + PLCP + preamble + get_duration(ACK_SIZE, 10); | 408 | else |
364 | 409 | rt2x00dev->intf_associated--; | |
365 | ack_consume_time = SIFS + PLCP + preamble + get_duration(ACK_SIZE, 10); | 410 | } |
366 | 411 | ||
367 | if (short_preamble) | 412 | /* |
368 | __set_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 413 | * When the preamble mode has changed, we should perform additional |
369 | else | 414 | * configuration steps. For all other changes we are already done. |
370 | __clear_bit(CONFIG_SHORT_PREAMBLE, &rt2x00dev->flags); | 415 | */ |
416 | if (changes & BSS_CHANGED_ERP_PREAMBLE) { | ||
417 | rt2x00lib_config_preamble(rt2x00dev, intf, | ||
418 | bss_conf->use_short_preamble); | ||
371 | 419 | ||
372 | rt2x00dev->ops->lib->config_preamble(rt2x00dev, short_preamble, | 420 | spin_lock(&intf->lock); |
373 | ack_timeout, ack_consume_time); | 421 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
422 | spin_unlock(&intf->lock); | ||
423 | } | ||
374 | } | 424 | } |
375 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); | 425 | EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); |
376 | 426 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 63cfe33e95da..764147dd5aea 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -38,20 +38,14 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
38 | struct ieee80211_tx_control *control) | 38 | struct ieee80211_tx_control *control) |
39 | { | 39 | { |
40 | struct rt2x00_dev *rt2x00dev = hw->priv; | 40 | struct rt2x00_dev *rt2x00dev = hw->priv; |
41 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
41 | struct queue_entry_priv_pci_tx *priv_tx; | 42 | struct queue_entry_priv_pci_tx *priv_tx; |
42 | struct skb_frame_desc *skbdesc; | 43 | struct skb_frame_desc *skbdesc; |
43 | struct data_queue *queue; | ||
44 | struct queue_entry *entry; | ||
45 | 44 | ||
46 | /* | 45 | if (unlikely(!intf->beacon)) |
47 | * Just in case mac80211 doesn't set this correctly, | 46 | return -ENOBUFS; |
48 | * but we need this queue set for the descriptor | 47 | |
49 | * initialization. | 48 | priv_tx = intf->beacon->priv_data; |
50 | */ | ||
51 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
52 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
53 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
54 | priv_tx = entry->priv_data; | ||
55 | 49 | ||
56 | /* | 50 | /* |
57 | * Fill in skb descriptor | 51 | * Fill in skb descriptor |
@@ -59,17 +53,25 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
59 | skbdesc = get_skb_frame_desc(skb); | 53 | skbdesc = get_skb_frame_desc(skb); |
60 | memset(skbdesc, 0, sizeof(*skbdesc)); | 54 | memset(skbdesc, 0, sizeof(*skbdesc)); |
61 | skbdesc->data = skb->data; | 55 | skbdesc->data = skb->data; |
62 | skbdesc->data_len = queue->data_size; | 56 | skbdesc->data_len = skb->len; |
63 | skbdesc->desc = priv_tx->desc; | 57 | skbdesc->desc = priv_tx->desc; |
64 | skbdesc->desc_len = queue->desc_size; | 58 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
65 | skbdesc->entry = entry; | 59 | skbdesc->entry = intf->beacon; |
66 | 60 | ||
67 | memcpy(priv_tx->data, skb->data, skb->len); | 61 | /* |
62 | * Just in case mac80211 doesn't set this correctly, | ||
63 | * but we need this queue set for the descriptor | ||
64 | * initialization. | ||
65 | */ | ||
66 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
68 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 67 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
69 | 68 | ||
70 | /* | 69 | /* |
71 | * Enable beacon generation. | 70 | * Enable beacon generation. |
71 | * Write entire beacon with descriptor to register, | ||
72 | * and kick the beacon generator. | ||
72 | */ | 73 | */ |
74 | memcpy(priv_tx->data, skb->data, skb->len); | ||
73 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); | 75 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue); |
74 | 76 | ||
75 | return 0; | 77 | return 0; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 507116c6c9fe..75af48eddc25 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -46,9 +46,6 @@ | |||
46 | * queue would be sufficient. Although this is almost one third of | 46 | * queue would be sufficient. Although this is almost one third of |
47 | * the amount the legacy driver allocated, the queues aren't getting | 47 | * the amount the legacy driver allocated, the queues aren't getting |
48 | * filled to the maximum even when working with the maximum rate. | 48 | * filled to the maximum even when working with the maximum rate. |
49 | * | ||
50 | * FIXME: For virtual interfaces we need a different number | ||
51 | * of beacons, since more interfaces require more beacons. | ||
52 | */ | 49 | */ |
53 | #define RX_ENTRIES 12 | 50 | #define RX_ENTRIES 12 |
54 | #define TX_ENTRIES 12 | 51 | #define TX_ENTRIES 12 |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index b5ab771bbac2..b432cc21d248 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -271,63 +271,60 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
271 | /* | 271 | /* |
272 | * Configuration handlers. | 272 | * Configuration handlers. |
273 | */ | 273 | */ |
274 | static void rt61pci_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 274 | static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, |
275 | struct rt2x00_intf *intf, | ||
276 | struct rt2x00intf_conf *conf, | ||
277 | const unsigned int flags) | ||
275 | { | 278 | { |
276 | u32 tmp; | 279 | unsigned int beacon_base; |
277 | 280 | u32 reg; | |
278 | tmp = le32_to_cpu(mac[1]); | ||
279 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
280 | mac[1] = cpu_to_le32(tmp); | ||
281 | |||
282 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | ||
283 | (2 * sizeof(__le32))); | ||
284 | } | ||
285 | 281 | ||
286 | static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 282 | if (flags & CONFIG_UPDATE_TYPE) { |
287 | { | 283 | /* |
288 | u32 tmp; | 284 | * Clear current synchronisation setup. |
285 | * For the Beacon base registers we only need to clear | ||
286 | * the first byte since that byte contains the VALID and OWNER | ||
287 | * bits which (when set to 0) will invalidate the entire beacon. | ||
288 | */ | ||
289 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
290 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
291 | rt2x00pci_register_write(rt2x00dev, beacon_base, 0); | ||
289 | 292 | ||
290 | tmp = le32_to_cpu(bssid[1]); | 293 | /* |
291 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 294 | * Enable synchronisation. |
292 | bssid[1] = cpu_to_le32(tmp); | 295 | */ |
296 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
297 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
298 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
299 | (conf->sync == TSF_SYNC_BEACON)); | ||
300 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
301 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
302 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
303 | } | ||
293 | 304 | ||
294 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 305 | if (flags & CONFIG_UPDATE_MAC) { |
295 | (2 * sizeof(__le32))); | 306 | reg = le32_to_cpu(conf->mac[1]); |
296 | } | 307 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
308 | conf->mac[1] = cpu_to_le32(reg); | ||
297 | 309 | ||
298 | static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 310 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR2, |
299 | const int tsf_sync) | 311 | conf->mac, sizeof(conf->mac)); |
300 | { | 312 | } |
301 | u32 reg; | ||
302 | 313 | ||
303 | /* | 314 | if (flags & CONFIG_UPDATE_BSSID) { |
304 | * Clear current synchronisation setup. | 315 | reg = le32_to_cpu(conf->bssid[1]); |
305 | * For the Beacon base registers we only need to clear | 316 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
306 | * the first byte since that byte contains the VALID and OWNER | 317 | conf->bssid[1] = cpu_to_le32(reg); |
307 | * bits which (when set to 0) will invalidate the entire beacon. | ||
308 | */ | ||
309 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
310 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
311 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
312 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
313 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
314 | 318 | ||
315 | /* | 319 | rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, |
316 | * Enable synchronisation. | 320 | conf->bssid, sizeof(conf->bssid)); |
317 | */ | 321 | } |
318 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
319 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
320 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
321 | (tsf_sync == TSF_SYNC_BEACON)); | ||
322 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
323 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
324 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
325 | } | 322 | } |
326 | 323 | ||
327 | static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | 324 | static int rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, |
328 | const int short_preamble, | 325 | const int short_preamble, |
329 | const int ack_timeout, | 326 | const int ack_timeout, |
330 | const int ack_consume_time) | 327 | const int ack_consume_time) |
331 | { | 328 | { |
332 | u32 reg; | 329 | u32 reg; |
333 | 330 | ||
@@ -339,6 +336,8 @@ static void rt61pci_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
339 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 336 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
340 | !!short_preamble); | 337 | !!short_preamble); |
341 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); | 338 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); |
339 | |||
340 | return 0; | ||
342 | } | 341 | } |
343 | 342 | ||
344 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, | 343 | static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -667,8 +666,8 @@ static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev, | |||
667 | } | 666 | } |
668 | 667 | ||
669 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, | 668 | static void rt61pci_config(struct rt2x00_dev *rt2x00dev, |
670 | const unsigned int flags, | 669 | struct rt2x00lib_conf *libconf, |
671 | struct rt2x00lib_conf *libconf) | 670 | const unsigned int flags) |
672 | { | 671 | { |
673 | if (flags & CONFIG_UPDATE_PHYMODE) | 672 | if (flags & CONFIG_UPDATE_PHYMODE) |
674 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); | 673 | rt61pci_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -816,6 +815,13 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
816 | } | 815 | } |
817 | 816 | ||
818 | /* | 817 | /* |
818 | * If we are not associated, we should go straight to the | ||
819 | * dynamic CCA tuning. | ||
820 | */ | ||
821 | if (!rt2x00dev->intf_associated) | ||
822 | goto dynamic_cca_tune; | ||
823 | |||
824 | /* | ||
819 | * Special big-R17 for very short distance | 825 | * Special big-R17 for very short distance |
820 | */ | 826 | */ |
821 | if (rssi >= -35) { | 827 | if (rssi >= -35) { |
@@ -866,6 +872,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
866 | return; | 872 | return; |
867 | } | 873 | } |
868 | 874 | ||
875 | dynamic_cca_tune: | ||
876 | |||
869 | /* | 877 | /* |
870 | * r17 does not yet exceed upper limit, continue and base | 878 | * r17 does not yet exceed upper limit, continue and base |
871 | * the r17 tuning on the false CCA count. | 879 | * the r17 tuning on the false CCA count. |
@@ -1215,6 +1223,17 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1215 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); | 1223 | rt2x00pci_register_write(rt2x00dev, AC_TXOP_CSR1, reg); |
1216 | 1224 | ||
1217 | /* | 1225 | /* |
1226 | * Clear all beacons | ||
1227 | * For the Beacon base registers we only need to clear | ||
1228 | * the first byte since that byte contains the VALID and OWNER | ||
1229 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1230 | */ | ||
1231 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1232 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1233 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1234 | rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1235 | |||
1236 | /* | ||
1218 | * We must clear the error counters. | 1237 | * We must clear the error counters. |
1219 | * These registers are cleared on read, | 1238 | * These registers are cleared on read, |
1220 | * so we may pass a useless variable to store the value. | 1239 | * so we may pass a useless variable to store the value. |
@@ -2378,25 +2397,20 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2378 | struct ieee80211_tx_control *control) | 2397 | struct ieee80211_tx_control *control) |
2379 | { | 2398 | { |
2380 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2399 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2400 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
2381 | struct skb_frame_desc *skbdesc; | 2401 | struct skb_frame_desc *skbdesc; |
2382 | struct data_queue *queue; | 2402 | unsigned int beacon_base; |
2383 | struct queue_entry *entry; | ||
2384 | 2403 | ||
2385 | /* | 2404 | if (unlikely(!intf->beacon)) |
2386 | * Just in case the ieee80211 doesn't set this, | 2405 | return -ENOBUFS; |
2387 | * but we need this queue set for the descriptor | ||
2388 | * initialization. | ||
2389 | */ | ||
2390 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2391 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
2392 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
2393 | 2406 | ||
2394 | /* | 2407 | /* |
2395 | * We need to append the descriptor in front of the | 2408 | * We need to append the descriptor in front of the |
2396 | * beacon frame. | 2409 | * beacon frame. |
2397 | */ | 2410 | */ |
2398 | if (skb_headroom(skb) < queue->desc_size) { | 2411 | if (skb_headroom(skb) < intf->beacon->queue->desc_size) { |
2399 | if (pskb_expand_head(skb, queue->desc_size, 0, GFP_ATOMIC)) { | 2412 | if (pskb_expand_head(skb, intf->beacon->queue->desc_size, |
2413 | 0, GFP_ATOMIC)) { | ||
2400 | dev_kfree_skb(skb); | 2414 | dev_kfree_skb(skb); |
2401 | return -ENOMEM; | 2415 | return -ENOMEM; |
2402 | } | 2416 | } |
@@ -2405,29 +2419,36 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2405 | /* | 2419 | /* |
2406 | * Add the descriptor in front of the skb. | 2420 | * Add the descriptor in front of the skb. |
2407 | */ | 2421 | */ |
2408 | skb_push(skb, queue->desc_size); | 2422 | skb_push(skb, intf->beacon->queue->desc_size); |
2409 | memset(skb->data, 0, queue->desc_size); | 2423 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2410 | 2424 | ||
2411 | /* | 2425 | /* |
2412 | * Fill in skb descriptor | 2426 | * Fill in skb descriptor |
2413 | */ | 2427 | */ |
2414 | skbdesc = get_skb_frame_desc(skb); | 2428 | skbdesc = get_skb_frame_desc(skb); |
2415 | memset(skbdesc, 0, sizeof(*skbdesc)); | 2429 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2416 | skbdesc->data = skb->data + queue->desc_size; | 2430 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2417 | skbdesc->data_len = queue->data_size; | 2431 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2418 | skbdesc->desc = skb->data; | 2432 | skbdesc->desc = skb->data; |
2419 | skbdesc->desc_len = queue->desc_size; | 2433 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2420 | skbdesc->entry = entry; | 2434 | skbdesc->entry = intf->beacon; |
2421 | 2435 | ||
2436 | /* | ||
2437 | * Just in case the ieee80211 doesn't set this, | ||
2438 | * but we need this queue set for the descriptor | ||
2439 | * initialization. | ||
2440 | */ | ||
2441 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2422 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2442 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2423 | 2443 | ||
2424 | /* | 2444 | /* |
2425 | * Write entire beacon with descriptor to register, | 2445 | * Write entire beacon with descriptor to register, |
2426 | * and kick the beacon generator. | 2446 | * and kick the beacon generator. |
2427 | */ | 2447 | */ |
2428 | rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, | 2448 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); |
2449 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2429 | skb->data, skb->len); | 2450 | skb->data, skb->len); |
2430 | rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2451 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); |
2431 | 2452 | ||
2432 | return 0; | 2453 | return 0; |
2433 | } | 2454 | } |
@@ -2469,9 +2490,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2469 | .write_tx_data = rt2x00pci_write_tx_data, | 2490 | .write_tx_data = rt2x00pci_write_tx_data, |
2470 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2491 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2471 | .fill_rxdone = rt61pci_fill_rxdone, | 2492 | .fill_rxdone = rt61pci_fill_rxdone, |
2472 | .config_mac_addr = rt61pci_config_mac_addr, | 2493 | .config_intf = rt61pci_config_intf, |
2473 | .config_bssid = rt61pci_config_bssid, | ||
2474 | .config_type = rt61pci_config_type, | ||
2475 | .config_preamble = rt61pci_config_preamble, | 2494 | .config_preamble = rt61pci_config_preamble, |
2476 | .config = rt61pci_config, | 2495 | .config = rt61pci_config, |
2477 | }; | 2496 | }; |
@@ -2491,7 +2510,7 @@ static const struct data_queue_desc rt61pci_queue_tx = { | |||
2491 | }; | 2510 | }; |
2492 | 2511 | ||
2493 | static const struct data_queue_desc rt61pci_queue_bcn = { | 2512 | static const struct data_queue_desc rt61pci_queue_bcn = { |
2494 | .entry_num = BEACON_ENTRIES, | 2513 | .entry_num = 4 * BEACON_ENTRIES, |
2495 | .data_size = MGMT_FRAME_SIZE, | 2514 | .data_size = MGMT_FRAME_SIZE, |
2496 | .desc_size = TXINFO_SIZE, | 2515 | .desc_size = TXINFO_SIZE, |
2497 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | 2516 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), |
@@ -2499,6 +2518,8 @@ static const struct data_queue_desc rt61pci_queue_bcn = { | |||
2499 | 2518 | ||
2500 | static const struct rt2x00_ops rt61pci_ops = { | 2519 | static const struct rt2x00_ops rt61pci_ops = { |
2501 | .name = KBUILD_MODNAME, | 2520 | .name = KBUILD_MODNAME, |
2521 | .max_sta_intf = 1, | ||
2522 | .max_ap_intf = 4, | ||
2502 | .eeprom_size = EEPROM_SIZE, | 2523 | .eeprom_size = EEPROM_SIZE, |
2503 | .rf_size = RF_SIZE, | 2524 | .rf_size = RF_SIZE, |
2504 | .rx = &rt61pci_queue_rx, | 2525 | .rx = &rt61pci_queue_rx, |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 10519f8c5783..d291c0fe405c 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -161,7 +161,9 @@ struct hw_pairwise_ta_entry { | |||
161 | #define HW_BEACON_BASE1 0x2d00 | 161 | #define HW_BEACON_BASE1 0x2d00 |
162 | #define HW_BEACON_BASE2 0x2e00 | 162 | #define HW_BEACON_BASE2 0x2e00 |
163 | #define HW_BEACON_BASE3 0x2f00 | 163 | #define HW_BEACON_BASE3 0x2f00 |
164 | #define HW_BEACON_OFFSET 0x0100 | 164 | |
165 | #define HW_BEACON_OFFSET(__index) \ | ||
166 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
165 | 167 | ||
166 | /* | 168 | /* |
167 | * HOST-MCU shared memory. | 169 | * HOST-MCU shared memory. |
@@ -234,6 +236,11 @@ struct hw_pairwise_ta_entry { | |||
234 | 236 | ||
235 | /* | 237 | /* |
236 | * MAC_CSR3: STA MAC register 1. | 238 | * MAC_CSR3: STA MAC register 1. |
239 | * UNICAST_TO_ME_MASK: | ||
240 | * Used to mask off bits from byte 5 of the MAC address | ||
241 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
242 | * The full mask is complemented by BSS_ID_MASK: | ||
243 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
237 | */ | 244 | */ |
238 | #define MAC_CSR3 0x300c | 245 | #define MAC_CSR3 0x300c |
239 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 246 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -251,7 +258,14 @@ struct hw_pairwise_ta_entry { | |||
251 | 258 | ||
252 | /* | 259 | /* |
253 | * MAC_CSR5: BSSID register 1. | 260 | * MAC_CSR5: BSSID register 1. |
254 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 261 | * BSS_ID_MASK: |
262 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
263 | * BSSID. This will make sure that those bits will be ignored | ||
264 | * when determining the MY_BSS of RX frames. | ||
265 | * 0: 1-BSSID mode (BSS index = 0) | ||
266 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
267 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
268 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
255 | */ | 269 | */ |
256 | #define MAC_CSR5 0x3014 | 270 | #define MAC_CSR5 0x3014 |
257 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 271 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 8ebf3fed9815..7907fd0d4aa5 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -281,74 +281,69 @@ static const struct rt2x00debug rt73usb_rt2x00debug = { | |||
281 | /* | 281 | /* |
282 | * Configuration handlers. | 282 | * Configuration handlers. |
283 | */ | 283 | */ |
284 | static void rt73usb_config_mac_addr(struct rt2x00_dev *rt2x00dev, __le32 *mac) | 284 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, |
285 | struct rt2x00_intf *intf, | ||
286 | struct rt2x00intf_conf *conf, | ||
287 | const unsigned int flags) | ||
285 | { | 288 | { |
286 | u32 tmp; | 289 | unsigned int beacon_base; |
287 | 290 | u32 reg; | |
288 | tmp = le32_to_cpu(mac[1]); | ||
289 | rt2x00_set_field32(&tmp, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); | ||
290 | mac[1] = cpu_to_le32(tmp); | ||
291 | |||
292 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, mac, | ||
293 | (2 * sizeof(__le32))); | ||
294 | } | ||
295 | 291 | ||
296 | static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, __le32 *bssid) | 292 | if (flags & CONFIG_UPDATE_TYPE) { |
297 | { | 293 | /* |
298 | u32 tmp; | 294 | * Clear current synchronisation setup. |
295 | * For the Beacon base registers we only need to clear | ||
296 | * the first byte since that byte contains the VALID and OWNER | ||
297 | * bits which (when set to 0) will invalidate the entire beacon. | ||
298 | */ | ||
299 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
300 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
301 | rt73usb_register_write(rt2x00dev, beacon_base, 0); | ||
299 | 302 | ||
300 | tmp = le32_to_cpu(bssid[1]); | 303 | /* |
301 | rt2x00_set_field32(&tmp, MAC_CSR5_BSS_ID_MASK, 3); | 304 | * Enable synchronisation. |
302 | bssid[1] = cpu_to_le32(tmp); | 305 | */ |
306 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
307 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
308 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
309 | (conf->sync == TSF_SYNC_BEACON)); | ||
310 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
311 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, conf->sync); | ||
312 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
313 | } | ||
303 | 314 | ||
304 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, bssid, | 315 | if (flags & CONFIG_UPDATE_MAC) { |
305 | (2 * sizeof(__le32))); | 316 | reg = le32_to_cpu(conf->mac[1]); |
306 | } | 317 | rt2x00_set_field32(®, MAC_CSR3_UNICAST_TO_ME_MASK, 0xff); |
318 | conf->mac[1] = cpu_to_le32(reg); | ||
307 | 319 | ||
308 | static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type, | 320 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR2, |
309 | const int tsf_sync) | 321 | conf->mac, sizeof(conf->mac)); |
310 | { | 322 | } |
311 | u32 reg; | ||
312 | 323 | ||
313 | /* | 324 | if (flags & CONFIG_UPDATE_BSSID) { |
314 | * Clear current synchronisation setup. | 325 | reg = le32_to_cpu(conf->bssid[1]); |
315 | * For the Beacon base registers we only need to clear | 326 | rt2x00_set_field32(®, MAC_CSR5_BSS_ID_MASK, 3); |
316 | * the first byte since that byte contains the VALID and OWNER | 327 | conf->bssid[1] = cpu_to_le32(reg); |
317 | * bits which (when set to 0) will invalidate the entire beacon. | ||
318 | */ | ||
319 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0); | ||
320 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
321 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
322 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
323 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
324 | 328 | ||
325 | /* | 329 | rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, |
326 | * Enable synchronisation. | 330 | conf->bssid, sizeof(conf->bssid)); |
327 | */ | 331 | } |
328 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
329 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1); | ||
330 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, | ||
331 | (tsf_sync == TSF_SYNC_BEACON)); | ||
332 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
333 | rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, tsf_sync); | ||
334 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
335 | } | 332 | } |
336 | 333 | ||
337 | static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | 334 | static int rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, |
338 | const int short_preamble, | 335 | const int short_preamble, |
339 | const int ack_timeout, | 336 | const int ack_timeout, |
340 | const int ack_consume_time) | 337 | const int ack_consume_time) |
341 | { | 338 | { |
342 | u32 reg; | 339 | u32 reg; |
343 | 340 | ||
344 | /* | 341 | /* |
345 | * When in atomic context, reschedule and let rt2x00lib | 342 | * When in atomic context, we should let rt2x00lib |
346 | * call this function again. | 343 | * try this configuration again later. |
347 | */ | 344 | */ |
348 | if (in_atomic()) { | 345 | if (in_atomic()) |
349 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->config_work); | 346 | return -EAGAIN; |
350 | return; | ||
351 | } | ||
352 | 347 | ||
353 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 348 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
354 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); | 349 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, ack_timeout); |
@@ -358,6 +353,8 @@ static void rt73usb_config_preamble(struct rt2x00_dev *rt2x00dev, | |||
358 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 353 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
359 | !!short_preamble); | 354 | !!short_preamble); |
360 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 355 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
356 | |||
357 | return 0; | ||
361 | } | 358 | } |
362 | 359 | ||
363 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 360 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -617,8 +614,8 @@ static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, | |||
617 | } | 614 | } |
618 | 615 | ||
619 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, | 616 | static void rt73usb_config(struct rt2x00_dev *rt2x00dev, |
620 | const unsigned int flags, | 617 | struct rt2x00lib_conf *libconf, |
621 | struct rt2x00lib_conf *libconf) | 618 | const unsigned int flags) |
622 | { | 619 | { |
623 | if (flags & CONFIG_UPDATE_PHYMODE) | 620 | if (flags & CONFIG_UPDATE_PHYMODE) |
624 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); | 621 | rt73usb_config_phymode(rt2x00dev, libconf->basic_rates); |
@@ -766,6 +763,13 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
766 | } | 763 | } |
767 | 764 | ||
768 | /* | 765 | /* |
766 | * If we are not associated, we should go straight to the | ||
767 | * dynamic CCA tuning. | ||
768 | */ | ||
769 | if (!rt2x00dev->intf_associated) | ||
770 | goto dynamic_cca_tune; | ||
771 | |||
772 | /* | ||
769 | * Special big-R17 for very short distance | 773 | * Special big-R17 for very short distance |
770 | */ | 774 | */ |
771 | if (rssi > -35) { | 775 | if (rssi > -35) { |
@@ -815,6 +819,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
815 | return; | 819 | return; |
816 | } | 820 | } |
817 | 821 | ||
822 | dynamic_cca_tune: | ||
823 | |||
818 | /* | 824 | /* |
819 | * r17 does not yet exceed upper limit, continue and base | 825 | * r17 does not yet exceed upper limit, continue and base |
820 | * the r17 tuning on the false CCA count. | 826 | * the r17 tuning on the false CCA count. |
@@ -1021,6 +1027,17 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1021 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); | 1027 | rt73usb_register_write(rt2x00dev, MAC_CSR9, reg); |
1022 | 1028 | ||
1023 | /* | 1029 | /* |
1030 | * Clear all beacons | ||
1031 | * For the Beacon base registers we only need to clear | ||
1032 | * the first byte since that byte contains the VALID and OWNER | ||
1033 | * bits which (when set to 0) will invalidate the entire beacon. | ||
1034 | */ | ||
1035 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0); | ||
1036 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0); | ||
1037 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0); | ||
1038 | rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0); | ||
1039 | |||
1040 | /* | ||
1024 | * We must clear the error counters. | 1041 | * We must clear the error counters. |
1025 | * These registers are cleared on read, | 1042 | * These registers are cleared on read, |
1026 | * so we may pass a useless variable to store the value. | 1043 | * so we may pass a useless variable to store the value. |
@@ -1985,52 +2002,52 @@ static void rt73usb_reset_tsf(struct ieee80211_hw *hw) | |||
1985 | } | 2002 | } |
1986 | 2003 | ||
1987 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | 2004 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, |
1988 | struct ieee80211_tx_control *control) | 2005 | struct ieee80211_tx_control *control) |
1989 | { | 2006 | { |
1990 | struct rt2x00_dev *rt2x00dev = hw->priv; | 2007 | struct rt2x00_dev *rt2x00dev = hw->priv; |
2008 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1991 | struct skb_frame_desc *skbdesc; | 2009 | struct skb_frame_desc *skbdesc; |
1992 | struct data_queue *queue; | 2010 | unsigned int beacon_base; |
1993 | struct queue_entry *entry; | 2011 | unsigned int timeout; |
1994 | int timeout; | ||
1995 | 2012 | ||
1996 | /* | 2013 | if (unlikely(!intf->beacon)) |
1997 | * Just in case the ieee80211 doesn't set this, | 2014 | return -ENOBUFS; |
1998 | * but we need this queue set for the descriptor | ||
1999 | * initialization. | ||
2000 | */ | ||
2001 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2002 | queue = rt2x00queue_get_queue(rt2x00dev, control->queue); | ||
2003 | entry = rt2x00queue_get_entry(queue, Q_INDEX); | ||
2004 | 2015 | ||
2005 | /* | 2016 | /* |
2006 | * Add the descriptor in front of the skb. | 2017 | * Add the descriptor in front of the skb. |
2007 | */ | 2018 | */ |
2008 | skb_push(skb, queue->desc_size); | 2019 | skb_push(skb, intf->beacon->queue->desc_size); |
2009 | memset(skb->data, 0, queue->desc_size); | 2020 | memset(skb->data, 0, intf->beacon->queue->desc_size); |
2010 | 2021 | ||
2011 | /* | 2022 | /* |
2012 | * Fill in skb descriptor | 2023 | * Fill in skb descriptor |
2013 | */ | 2024 | */ |
2014 | skbdesc = get_skb_frame_desc(skb); | 2025 | skbdesc = get_skb_frame_desc(skb); |
2015 | memset(skbdesc, 0, sizeof(*skbdesc)); | 2026 | memset(skbdesc, 0, sizeof(*skbdesc)); |
2016 | skbdesc->data = skb->data + queue->desc_size; | 2027 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; |
2017 | skbdesc->data_len = queue->data_size; | 2028 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; |
2018 | skbdesc->desc = skb->data; | 2029 | skbdesc->desc = skb->data; |
2019 | skbdesc->desc_len = queue->desc_size; | 2030 | skbdesc->desc_len = intf->beacon->queue->desc_size; |
2020 | skbdesc->entry = entry; | 2031 | skbdesc->entry = intf->beacon; |
2021 | 2032 | ||
2033 | /* | ||
2034 | * Just in case the ieee80211 doesn't set this, | ||
2035 | * but we need this queue set for the descriptor | ||
2036 | * initialization. | ||
2037 | */ | ||
2038 | control->queue = IEEE80211_TX_QUEUE_BEACON; | ||
2022 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | 2039 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); |
2023 | 2040 | ||
2024 | /* | 2041 | /* |
2025 | * Write entire beacon with descriptor to register, | 2042 | * Write entire beacon with descriptor to register, |
2026 | * and kick the beacon generator. | 2043 | * and kick the beacon generator. |
2027 | */ | 2044 | */ |
2045 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2028 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | 2046 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); |
2029 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 2047 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
2030 | USB_VENDOR_REQUEST_OUT, | 2048 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, |
2031 | HW_BEACON_BASE0, 0x0000, | ||
2032 | skb->data, skb->len, timeout); | 2049 | skb->data, skb->len, timeout); |
2033 | rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); | 2050 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); |
2034 | 2051 | ||
2035 | return 0; | 2052 | return 0; |
2036 | } | 2053 | } |
@@ -2071,9 +2088,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2071 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2088 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2072 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2089 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2073 | .fill_rxdone = rt73usb_fill_rxdone, | 2090 | .fill_rxdone = rt73usb_fill_rxdone, |
2074 | .config_mac_addr = rt73usb_config_mac_addr, | 2091 | .config_intf = rt73usb_config_intf, |
2075 | .config_bssid = rt73usb_config_bssid, | ||
2076 | .config_type = rt73usb_config_type, | ||
2077 | .config_preamble = rt73usb_config_preamble, | 2092 | .config_preamble = rt73usb_config_preamble, |
2078 | .config = rt73usb_config, | 2093 | .config = rt73usb_config, |
2079 | }; | 2094 | }; |
@@ -2093,7 +2108,7 @@ static const struct data_queue_desc rt73usb_queue_tx = { | |||
2093 | }; | 2108 | }; |
2094 | 2109 | ||
2095 | static const struct data_queue_desc rt73usb_queue_bcn = { | 2110 | static const struct data_queue_desc rt73usb_queue_bcn = { |
2096 | .entry_num = BEACON_ENTRIES, | 2111 | .entry_num = 4 * BEACON_ENTRIES, |
2097 | .data_size = MGMT_FRAME_SIZE, | 2112 | .data_size = MGMT_FRAME_SIZE, |
2098 | .desc_size = TXINFO_SIZE, | 2113 | .desc_size = TXINFO_SIZE, |
2099 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2114 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), |
@@ -2101,6 +2116,8 @@ static const struct data_queue_desc rt73usb_queue_bcn = { | |||
2101 | 2116 | ||
2102 | static const struct rt2x00_ops rt73usb_ops = { | 2117 | static const struct rt2x00_ops rt73usb_ops = { |
2103 | .name = KBUILD_MODNAME, | 2118 | .name = KBUILD_MODNAME, |
2119 | .max_sta_intf = 1, | ||
2120 | .max_ap_intf = 4, | ||
2104 | .eeprom_size = EEPROM_SIZE, | 2121 | .eeprom_size = EEPROM_SIZE, |
2105 | .rf_size = RF_SIZE, | 2122 | .rf_size = RF_SIZE, |
2106 | .rx = &rt73usb_queue_rx, | 2123 | .rx = &rt73usb_queue_rx, |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index da62b4f091a7..3f9675655eb9 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -114,6 +114,9 @@ struct hw_pairwise_ta_entry { | |||
114 | #define HW_BEACON_BASE2 0x2600 | 114 | #define HW_BEACON_BASE2 0x2600 |
115 | #define HW_BEACON_BASE3 0x2700 | 115 | #define HW_BEACON_BASE3 0x2700 |
116 | 116 | ||
117 | #define HW_BEACON_OFFSET(__index) \ | ||
118 | ( HW_BEACON_BASE0 + (__index * 0x0100) ) | ||
119 | |||
117 | /* | 120 | /* |
118 | * MAC Control/Status Registers(CSR). | 121 | * MAC Control/Status Registers(CSR). |
119 | * Some values are set in TU, whereas 1 TU == 1024 us. | 122 | * Some values are set in TU, whereas 1 TU == 1024 us. |
@@ -146,6 +149,11 @@ struct hw_pairwise_ta_entry { | |||
146 | 149 | ||
147 | /* | 150 | /* |
148 | * MAC_CSR3: STA MAC register 1. | 151 | * MAC_CSR3: STA MAC register 1. |
152 | * UNICAST_TO_ME_MASK: | ||
153 | * Used to mask off bits from byte 5 of the MAC address | ||
154 | * to determine the UNICAST_TO_ME bit for RX frames. | ||
155 | * The full mask is complemented by BSS_ID_MASK: | ||
156 | * MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK | ||
149 | */ | 157 | */ |
150 | #define MAC_CSR3 0x300c | 158 | #define MAC_CSR3 0x300c |
151 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) | 159 | #define MAC_CSR3_BYTE4 FIELD32(0x000000ff) |
@@ -163,7 +171,14 @@ struct hw_pairwise_ta_entry { | |||
163 | 171 | ||
164 | /* | 172 | /* |
165 | * MAC_CSR5: BSSID register 1. | 173 | * MAC_CSR5: BSSID register 1. |
166 | * BSS_ID_MASK: 3: one BSSID, 0: 4 BSSID, 2 or 1: 2 BSSID. | 174 | * BSS_ID_MASK: |
175 | * This mask is used to mask off bits 0 and 1 of byte 5 of the | ||
176 | * BSSID. This will make sure that those bits will be ignored | ||
177 | * when determining the MY_BSS of RX frames. | ||
178 | * 0: 1-BSSID mode (BSS index = 0) | ||
179 | * 1: 2-BSSID mode (BSS index: Byte5, bit 0) | ||
180 | * 2: 2-BSSID mode (BSS index: byte5, bit 1) | ||
181 | * 3: 4-BSSID mode (BSS index: byte5, bit 0 - 1) | ||
167 | */ | 182 | */ |
168 | #define MAC_CSR5 0x3014 | 183 | #define MAC_CSR5 0x3014 |
169 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) | 184 | #define MAC_CSR5_BYTE4 FIELD32(0x000000ff) |