aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2400pci.c
diff options
context:
space:
mode:
authorHelmut Schaa <helmut.schaa@googlemail.com>2010-09-08 14:56:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-09-14 16:03:43 -0400
commit0204464329c17ba6d293e1899f71223599a0e582 (patch)
tree368b9617c1ad770b77fd22612edbb49300d0f500 /drivers/net/wireless/rt2x00/rt2400pci.c
parent47ee3eb1359a5444efd9f529e3d28c02e8e405e7 (diff)
rt2x00: Check for specific changed flags when updating the erp config
Previously rt2x00 was always updating all erp related config variables even though mac80211 might only have changed one. Hence, pass the changed flags to the config_erp driver callback so that the driver can limit the changes to the correct values. This fixes an issue in AP mode where the beacon interval is not initialized (and thus zero) but still sent to the hardware causing an interrupt storm on rt2800pci hanging the system. Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c114
1 files changed, 64 insertions, 50 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index e3005ff5ae98..4b88909275a1 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -321,7 +321,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
321} 321}
322 322
323static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, 323static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
324 struct rt2x00lib_erp *erp) 324 struct rt2x00lib_erp *erp,
325 u32 changed)
325{ 326{
326 int preamble_mask; 327 int preamble_mask;
327 u32 reg; 328 u32 reg;
@@ -329,59 +330,72 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
329 /* 330 /*
330 * When short preamble is enabled, we should set bit 0x08 331 * When short preamble is enabled, we should set bit 0x08
331 */ 332 */
332 preamble_mask = erp->short_preamble << 3; 333 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
333 334 preamble_mask = erp->short_preamble << 3;
334 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg); 335
335 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff); 336 rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
336 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a); 337 rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, 0x1ff);
337 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); 338 rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME, 0x13a);
338 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1); 339 rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
339 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); 340 rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
340 341 rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
341 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg); 342
342 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00); 343 rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
343 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04); 344 rt2x00_set_field32(&reg, ARCSR2_SIGNAL, 0x00);
344 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); 345 rt2x00_set_field32(&reg, ARCSR2_SERVICE, 0x04);
345 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); 346 rt2x00_set_field32(&reg, ARCSR2_LENGTH,
346 347 GET_DURATION(ACK_SIZE, 10));
347 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg); 348 rt2x00pci_register_write(rt2x00dev, ARCSR2, reg);
348 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask); 349
349 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04); 350 rt2x00pci_register_read(rt2x00dev, ARCSR3, &reg);
350 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); 351 rt2x00_set_field32(&reg, ARCSR3_SIGNAL, 0x01 | preamble_mask);
351 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); 352 rt2x00_set_field32(&reg, ARCSR3_SERVICE, 0x04);
352 353 rt2x00_set_field32(&reg, ARCSR2_LENGTH,
353 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg); 354 GET_DURATION(ACK_SIZE, 20));
354 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask); 355 rt2x00pci_register_write(rt2x00dev, ARCSR3, reg);
355 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04); 356
356 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); 357 rt2x00pci_register_read(rt2x00dev, ARCSR4, &reg);
357 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); 358 rt2x00_set_field32(&reg, ARCSR4_SIGNAL, 0x02 | preamble_mask);
358 359 rt2x00_set_field32(&reg, ARCSR4_SERVICE, 0x04);
359 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg); 360 rt2x00_set_field32(&reg, ARCSR2_LENGTH,
360 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask); 361 GET_DURATION(ACK_SIZE, 55));
361 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); 362 rt2x00pci_register_write(rt2x00dev, ARCSR4, reg);
362 rt2x00_set_field32(&reg, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); 363
363 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); 364 rt2x00pci_register_read(rt2x00dev, ARCSR5, &reg);
364 365 rt2x00_set_field32(&reg, ARCSR5_SIGNAL, 0x03 | preamble_mask);
365 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); 366 rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
367 rt2x00_set_field32(&reg, ARCSR2_LENGTH,
368 GET_DURATION(ACK_SIZE, 110));
369 rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
370 }
366 371
367 rt2x00pci_register_read(rt2x00dev, CSR11, &reg); 372 if (changed & BSS_CHANGED_BASIC_RATES)
368 rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time); 373 rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates);
369 rt2x00pci_register_write(rt2x00dev, CSR11, reg);
370 374
371 rt2x00pci_register_read(rt2x00dev, CSR12, &reg); 375 if (changed & BSS_CHANGED_ERP_SLOT) {
372 rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); 376 rt2x00pci_register_read(rt2x00dev, CSR11, &reg);
373 rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); 377 rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
374 rt2x00pci_register_write(rt2x00dev, CSR12, reg); 378 rt2x00pci_register_write(rt2x00dev, CSR11, reg);
375 379
376 rt2x00pci_register_read(rt2x00dev, CSR18, &reg); 380 rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
377 rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs); 381 rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
378 rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs); 382 rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
379 rt2x00pci_register_write(rt2x00dev, CSR18, reg); 383 rt2x00pci_register_write(rt2x00dev, CSR18, reg);
380 384
381 rt2x00pci_register_read(rt2x00dev, CSR19, &reg); 385 rt2x00pci_register_read(rt2x00dev, CSR19, &reg);
382 rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs); 386 rt2x00_set_field32(&reg, CSR19_DIFS, erp->difs);
383 rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs); 387 rt2x00_set_field32(&reg, CSR19_EIFS, erp->eifs);
384 rt2x00pci_register_write(rt2x00dev, CSR19, reg); 388 rt2x00pci_register_write(rt2x00dev, CSR19, reg);
389 }
390
391 if (changed & BSS_CHANGED_BEACON_INT) {
392 rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
393 rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
394 erp->beacon_int * 16);
395 rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
396 erp->beacon_int * 16);
397 rt2x00pci_register_write(rt2x00dev, CSR12, reg);
398 }
385} 399}
386 400
387static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev, 401static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev,